(function(win, undefined){
    var WCS = function(selector, context){
        return new WCS.fn.init(selector, context);
    }, document = window.document, push = Array.prototype.push, slice = Array.prototype.slice, toString = Object.prototype.toString;
    
    WCS.fn = WCS.prototype = {
        init: function(selector, context){
        
            if (!selector) {
                return this;
            }
            
            if (selector.nodeType) {
                this.context = this[0] = selector;
                this.length = 1;
                return this;
            }
            
            if (typeof selector === "string") {
                var ret = YAHOO.util.Selector.query(selector, context || document);
                //YAHOO.log( ret );
                ret = slice.call(ret);
                push.apply(this, ret);
                return this;
            }
            
            return WCS.makeArray(selector, this);
        },
        
        length: 0,
        
        attr: function(name, value){
            return access(this, name, value, WCS.attr);
        },
        
        // Get the Nth element in the matched element set OR
        // Get the whole matched element set as a clean array
        get: function(num){
            return num == null ?            // Return a 'clean' array
            this.toArray() :            // Return just the object
            (num < 0 ? this.slice(num)[0] : this[num]);
        },
        
        pushStack: function(elems, name, selector){
            // Build a new jQuery matched element set
            var ret = WCS();
            
            if (WCS.isArray(elems)) {
                push.apply(ret, elems);
                
            }
            else {
                WCS.merge(ret, elems);
            }
            
            // Add the old object onto the stack (as a reference)
            ret.prevObject = this;
            
            ret.context = this.context;
            
            if (name === "find") {
                ret.selector = this.selector + (this.selector ? " " : "") + selector;
            }
            else 
                if (name) {
                    ret.selector = this.selector + "." + name + "(" + selector + ")";
                }
            
            // Return the newly-formed element set
            return ret;
        },
        
        each: function(callback, args){
            return WCS.each(this, callback, args);
        },
        
        map: function(callback){
            return this.pushStack(WCS.map(this, function(elem, i){
                return callback.call(elem, i, elem);
            }));
        }
    };
    
    WCS.fn.init.prototype = WCS.fn;
    
    WCS.attr = function(elem, name, value){
        if (value === undefined) {
            return elem.getAttribute(name);
        }
        return elem.setAttribute(name, value);
    };
    
    WCS.each = function(object, callback, args){
        var name, i = 0, length = object.length, isObj = length === undefined || WCS.isFunction(object);
        
        if (args) {
            if (isObj) {
                for (name in object) {
                    if (callback.apply(object[name], args) === false) {
                        break;
                    }
                }
            }
            else {
                for (; i < length;) {
                    if (callback.apply(object[i++], args) === false) {
                        break;
                    }
                }
            }
            
            // A special, fast, case for the most common use of each
        }
        else {
            if (isObj) {
                for (name in object) {
                    if (callback.call(object[name], name, object[name]) === false) {
                        break;
                    }
                }
            }
            else {
                for (var value = object[0]; i < length && callback.call(value, i, value) !== false; value = object[++i]) {
                }
            }
        }
        
        return object;
    }
    
    WCS.makeArray = function(array, results){
        var ret = results || [];
        
        if (array != null) {
            // The window, strings (and functions) also have 'length'
            // The extra typeof function check is to prevent crashes
            // in Safari 2 (See: #3039)
            if (array.length == null || typeof array === "string" || WCS.isFunction(array) || (typeof array !== "function" && array.setInterval)) {
                push.call(ret, array);
            }
            else {
                WCS.merge(ret, array);
            }
        }
        
        return ret;
    }
    
    WCS.isFunction = function(obj){
        return YAHOO.lang.isFunction(obj);
    }
    
    WCS.isArray = function(obj){
        return YAHOO.lang.isArray(obj);
    }
    
    WCS.merge = function(first, second){
        var i = first.length, j = 0;
        
        if (typeof second.length === "number") {
            for (var l = second.length; j < l; j++) {
                first[i++] = second[j];
            }
            
        }
        else {
            while (second[j] !== undefined) {
                first[i++] = second[j++];
            }
        }
        
        first.length = i;
        
        return first;
    }
    
    WCS.map = function(elems, callback, arg){
        var ret = [], value;
        
        // Go through the array, translating each of the items to their
        // new value (or values).
        for (var i = 0, length = elems.length; i < length; i++) {
            value = callback(elems[i], i, arg);
            
            if (value != null) {
                ret[ret.length] = value;
            }
        }
        
        return ret.concat.apply([], ret);
    }
    
    //sizzle-jquery.js部分;
    var baseHasDuplicate = true;
    
    // Here we check if the JavaScript engine is using some sort of
    // optimization where it does not always call our comparision
    // function. If that is the case, discard the hasDuplicate value.
    //   Thus far that includes Google Chrome.
    [0, 0].sort(function(){
        baseHasDuplicate = false;
        return 0;
    });
    
    WCS.unique = function(results){
        if (sortOrder) {
            hasDuplicate = baseHasDuplicate;
            results.sort(sortOrder);
            
            if (hasDuplicate) {
                for (var i = 1; i < results.length; i++) {
                    if (results[i] === results[i - 1]) {
                        results.splice(i--, 1);
                    }
                }
            }
        }
        
        return results;
    }
    
    var sortOrder;
    
    if (document.documentElement.compareDocumentPosition) {
        sortOrder = function(a, b){
            if (!a.compareDocumentPosition || !b.compareDocumentPosition) {
                if (a == b) {
                    hasDuplicate = true;
                }
                return a.compareDocumentPosition ? -1 : 1;
            }
            
            var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
            if (ret === 0) {
                hasDuplicate = true;
            }
            return ret;
        };
    }
    else 
        if ("sourceIndex" in document.documentElement) {
            sortOrder = function(a, b){
                if (!a.sourceIndex || !b.sourceIndex) {
                    if (a == b) {
                        hasDuplicate = true;
                    }
                    return a.sourceIndex ? -1 : 1;
                }
                
                var ret = a.sourceIndex - b.sourceIndex;
                if (ret === 0) {
                    hasDuplicate = true;
                }
                return ret;
            };
        }
        else 
            if (document.createRange) {
                sortOrder = function(a, b){
                    if (!a.ownerDocument || !b.ownerDocument) {
                        if (a == b) {
                            hasDuplicate = true;
                        }
                        return a.ownerDocument ? -1 : 1;
                    }
                    
                    var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange();
                    aRange.setStart(a, 0);
                    aRange.setEnd(a, 0);
                    bRange.setStart(b, 0);
                    bRange.setEnd(b, 0);
                    var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
                    if (ret === 0) {
                        hasDuplicate = true;
                    }
                    return ret;
                };
            }
    //sizzle-jquery.js部分结束
    
    
    function access(elems, key, value, fn){
        var length = elems.length;
        
        if (value !== undefined) {
            for (var i = 0; i < length; i++) {
                fn(elems[i], key, value);
            }
            return elems;
        }
        
        return length ? fn(elems[0], key) : null;
    }
    
    win.$ = win.WCS = WCS;
    
    
    var runtil = /Until$/, rparentsprev = /^(?:parents|prevUntil|prevAll)/, // Note: This RegExp should be improved, or likely pulled from Sizzle
 rmultiselector = /,/;
    
    WCS.fn["parent"] = function(until, selector){
        var fn = function(elem){
            var parent = elem.parentNode;
            return parent && parent.nodeType !== 11 ? parent : null;
        }
        
        var ret = WCS.map(this, fn, until);
        
        if (!runtil.test(name)) {
            selector = until;
        }
        
        if (selector && typeof selector === "string") {
            ret = WCS.filter(selector, ret);
        }
        
        ret = this.length > 1 ? WCS.unique(ret) : ret;
        
        if ((this.length > 1 || rmultiselector.test(selector)) && rparentsprev.test(name)) {
            ret = ret.reverse();
        }
        
        return this.pushStack(ret, name, slice.call(arguments).join(","));
    };
    
    
})(window);

