Added: steve/trunk/pytest/www/htdocs/js/jquery.js
URL: 
http://svn.apache.org/viewvc/steve/trunk/pytest/www/htdocs/js/jquery.js?rev=1667718&view=auto
==============================================================================
--- steve/trunk/pytest/www/htdocs/js/jquery.js (added)
+++ steve/trunk/pytest/www/htdocs/js/jquery.js Thu Mar 19 12:11:36 2015
@@ -0,0 +1,8755 @@
+/*!
+ * jQuery JavaScript Library v2.0.0
+ * http://jquery.com/
+ *
+ * Includes Sizzle.js
+ * http://sizzlejs.com/
+ *
+ * Copyright 2005, 2013 jQuery Foundation, Inc. and other contributors
+ * Released under the MIT license
+ * http://jquery.org/license
+ *
+ * Date: 2013-04-18
+ */
+(function( window, undefined ) {
+
+// Can't do this because several apps including ASP.NET trace
+// the stack via arguments.caller.callee and Firefox dies if
+// you try to trace through "use strict" call chains. (#13335)
+// Support: Firefox 18+
+//"use strict";
+var
+    // A central reference to the root jQuery(document)
+    rootjQuery,
+
+    // The deferred used on DOM ready
+    readyList,
+
+    // Support: IE9
+    // For `typeof xmlNode.method` instead of `xmlNode.method !== undefined`
+    core_strundefined = typeof undefined,
+
+    // Use the correct document accordingly with window argument (sandbox)
+    location = window.location,
+    document = window.document,
+    docElem = document.documentElement,
+
+    // Map over jQuery in case of overwrite
+    _jQuery = window.jQuery,
+
+    // Map over the $ in case of overwrite
+    _$ = window.$,
+
+    // [[Class]] -> type pairs
+    class2type = {},
+
+    // List of deleted data cache ids, so we can reuse them
+    core_deletedIds = [],
+
+    core_version = "2.0.0",
+
+    // Save a reference to some core methods
+    core_concat = core_deletedIds.concat,
+    core_push = core_deletedIds.push,
+    core_slice = core_deletedIds.slice,
+    core_indexOf = core_deletedIds.indexOf,
+    core_toString = class2type.toString,
+    core_hasOwn = class2type.hasOwnProperty,
+    core_trim = core_version.trim,
+
+    // Define a local copy of jQuery
+    jQuery = function( selector, context ) {
+        // The jQuery object is actually just the init constructor 'enhanced'
+        return new jQuery.fn.init( selector, context, rootjQuery );
+    },
+
+    // Used for matching numbers
+    core_pnum = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,
+
+    // Used for splitting on whitespace
+    core_rnotwhite = /\S+/g,
+
+    // A simple way to check for HTML strings
+    // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
+    // Strict HTML recognition (#11290: must start with <)
+    rquickExpr = /^(?:(<[\w\W]+>)[^>]*|#([\w-]*))$/,
+
+    // Match a standalone tag
+    rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>|)$/,
+
+    // Matches dashed string for camelizing
+    rmsPrefix = /^-ms-/,
+    rdashAlpha = /-([\da-z])/gi,
+
+    // Used by jQuery.camelCase as callback to replace()
+    fcamelCase = function( all, letter ) {
+        return letter.toUpperCase();
+    },
+
+    // The ready event handler and self cleanup method
+    completed = function() {
+        document.removeEventListener( "DOMContentLoaded", completed, false );
+        window.removeEventListener( "load", completed, false );
+        jQuery.ready();
+    };
+
+jQuery.fn = jQuery.prototype = {
+    // The current version of jQuery being used
+    jquery: core_version,
+
+    constructor: jQuery,
+    init: function( selector, context, rootjQuery ) {
+        var match, elem;
+
+        // HANDLE: $(""), $(null), $(undefined), $(false)
+        if ( !selector ) {
+            return this;
+        }
+
+        // Handle HTML strings
+        if ( typeof selector === "string" ) {
+            if ( selector.charAt(0) === "<" && selector.charAt( 
selector.length - 1 ) === ">" && selector.length >= 3 ) {
+                // Assume that strings that start and end with <> are HTML and 
skip the regex check
+                match = [ null, selector, null ];
+
+            } else {
+                match = rquickExpr.exec( selector );
+            }
+
+            // Match html or make sure no context is specified for #id
+            if ( match && (match[1] || !context) ) {
+
+                // HANDLE: $(html) -> $(array)
+                if ( match[1] ) {
+                    context = context instanceof jQuery ? context[0] : context;
+
+                    // scripts is true for back-compat
+                    jQuery.merge( this, jQuery.parseHTML(
+                        match[1],
+                        context && context.nodeType ? context.ownerDocument || 
context : document,
+                        true
+                    ) );
+
+                    // HANDLE: $(html, props)
+                    if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( 
context ) ) {
+                        for ( match in context ) {
+                            // Properties of context are called as methods if 
possible
+                            if ( jQuery.isFunction( this[ match ] ) ) {
+                                this[ match ]( context[ match ] );
+
+                            // ...and otherwise set as attributes
+                            } else {
+                                this.attr( match, context[ match ] );
+                            }
+                        }
+                    }
+
+                    return this;
+
+                // HANDLE: $(#id)
+                } else {
+                    elem = document.getElementById( match[2] );
+
+                    // Check parentNode to catch when Blackberry 4.6 returns
+                    // nodes that are no longer in the document #6963
+                    if ( elem && elem.parentNode ) {
+                        // Inject the element directly into the jQuery object
+                        this.length = 1;
+                        this[0] = elem;
+                    }
+
+                    this.context = document;
+                    this.selector = selector;
+                    return this;
+                }
+
+            // HANDLE: $(expr, $(...))
+            } else if ( !context || context.jquery ) {
+                return ( context || rootjQuery ).find( selector );
+
+            // HANDLE: $(expr, context)
+            // (which is just equivalent to: $(context).find(expr)
+            } else {
+                return this.constructor( context ).find( selector );
+            }
+
+        // HANDLE: $(DOMElement)
+        } else if ( selector.nodeType ) {
+            this.context = this[0] = selector;
+            this.length = 1;
+            return this;
+
+        // HANDLE: $(function)
+        // Shortcut for document ready
+        } else if ( jQuery.isFunction( selector ) ) {
+            return rootjQuery.ready( selector );
+        }
+
+        if ( selector.selector !== undefined ) {
+            this.selector = selector.selector;
+            this.context = selector.context;
+        }
+
+        return jQuery.makeArray( selector, this );
+    },
+
+    // Start with an empty selector
+    selector: "",
+
+    // The default length of a jQuery object is 0
+    length: 0,
+
+    toArray: function() {
+        return core_slice.call( this );
+    },
+
+    // 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[ this.length + num ] : this[ num ] );
+    },
+
+    // Take an array of elements and push it onto the stack
+    // (returning the new matched element set)
+    pushStack: function( elems ) {
+
+        // Build a new jQuery matched element set
+        var ret = jQuery.merge( this.constructor(), elems );
+
+        // Add the old object onto the stack (as a reference)
+        ret.prevObject = this;
+        ret.context = this.context;
+
+        // Return the newly-formed element set
+        return ret;
+    },
+
+    // Execute a callback for every element in the matched set.
+    // (You can seed the arguments with an array of args, but this is
+    // only used internally.)
+    each: function( callback, args ) {
+        return jQuery.each( this, callback, args );
+    },
+
+    ready: function( fn ) {
+        // Add the callback
+        jQuery.ready.promise().done( fn );
+
+        return this;
+    },
+
+    slice: function() {
+        return this.pushStack( core_slice.apply( this, arguments ) );
+    },
+
+    first: function() {
+        return this.eq( 0 );
+    },
+
+    last: function() {
+        return this.eq( -1 );
+    },
+
+    eq: function( i ) {
+        var len = this.length,
+            j = +i + ( i < 0 ? len : 0 );
+        return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );
+    },
+
+    map: function( callback ) {
+        return this.pushStack( jQuery.map(this, function( elem, i ) {
+            return callback.call( elem, i, elem );
+        }));
+    },
+
+    end: function() {
+        return this.prevObject || this.constructor(null);
+    },
+
+    // For internal use only.
+    // Behaves like an Array's method, not like a jQuery method.
+    push: core_push,
+    sort: [].sort,
+    splice: [].splice
+};
+
+// Give the init function the jQuery prototype for later instantiation
+jQuery.fn.init.prototype = jQuery.fn;
+
+jQuery.extend = jQuery.fn.extend = function() {
+    var options, name, src, copy, copyIsArray, clone,
+        target = arguments[0] || {},
+        i = 1,
+        length = arguments.length,
+        deep = false;
+
+    // Handle a deep copy situation
+    if ( typeof target === "boolean" ) {
+        deep = target;
+        target = arguments[1] || {};
+        // skip the boolean and the target
+        i = 2;
+    }
+
+    // Handle case when target is a string or something (possible in deep copy)
+    if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
+        target = {};
+    }
+
+    // extend jQuery itself if only one argument is passed
+    if ( length === i ) {
+        target = this;
+        --i;
+    }
+
+    for ( ; i < length; i++ ) {
+        // Only deal with non-null/undefined values
+        if ( (options = arguments[ i ]) != null ) {
+            // Extend the base object
+            for ( name in options ) {
+                src = target[ name ];
+                copy = options[ name ];
+
+                // Prevent never-ending loop
+                if ( target === copy ) {
+                    continue;
+                }
+
+                // Recurse if we're merging plain objects or arrays
+                if ( deep && copy && ( jQuery.isPlainObject(copy) || 
(copyIsArray = jQuery.isArray(copy)) ) ) {
+                    if ( copyIsArray ) {
+                        copyIsArray = false;
+                        clone = src && jQuery.isArray(src) ? src : [];
+
+                    } else {
+                        clone = src && jQuery.isPlainObject(src) ? src : {};
+                    }
+
+                    // Never move original objects, clone them
+                    target[ name ] = jQuery.extend( deep, clone, copy );
+
+                // Don't bring in undefined values
+                } else if ( copy !== undefined ) {
+                    target[ name ] = copy;
+                }
+            }
+        }
+    }
+
+    // Return the modified object
+    return target;
+};
+
+jQuery.extend({
+    // Unique for each copy of jQuery on the page
+    expando: "jQuery" + ( core_version + Math.random() ).replace( /\D/g, "" ),
+
+    noConflict: function( deep ) {
+        if ( window.$ === jQuery ) {
+            window.$ = _$;
+        }
+
+        if ( deep && window.jQuery === jQuery ) {
+            window.jQuery = _jQuery;
+        }
+
+        return jQuery;
+    },
+
+    // Is the DOM ready to be used? Set to true once it occurs.
+    isReady: false,
+
+    // A counter to track how many items to wait for before
+    // the ready event fires. See #6781
+    readyWait: 1,
+
+    // Hold (or release) the ready event
+    holdReady: function( hold ) {
+        if ( hold ) {
+            jQuery.readyWait++;
+        } else {
+            jQuery.ready( true );
+        }
+    },
+
+    // Handle when the DOM is ready
+    ready: function( wait ) {
+
+        // Abort if there are pending holds or we're already ready
+        if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
+            return;
+        }
+
+        // Remember that the DOM is ready
+        jQuery.isReady = true;
+
+        // If a normal DOM Ready event fired, decrement, and wait if need be
+        if ( wait !== true && --jQuery.readyWait > 0 ) {
+            return;
+        }
+
+        // If there are functions bound, to execute
+        readyList.resolveWith( document, [ jQuery ] );
+
+        // Trigger any bound ready events
+        if ( jQuery.fn.trigger ) {
+            jQuery( document ).trigger("ready").off("ready");
+        }
+    },
+
+    // See test/unit/core.js for details concerning isFunction.
+    // Since version 1.3, DOM methods and functions like alert
+    // aren't supported. They return false on IE (#2968).
+    isFunction: function( obj ) {
+        return jQuery.type(obj) === "function";
+    },
+
+    isArray: Array.isArray,
+
+    isWindow: function( obj ) {
+        return obj != null && obj === obj.window;
+    },
+
+    isNumeric: function( obj ) {
+        return !isNaN( parseFloat(obj) ) && isFinite( obj );
+    },
+
+    type: function( obj ) {
+        if ( obj == null ) {
+            return String( obj );
+        }
+        // Support: Safari <= 5.1 (functionish RegExp)
+        return typeof obj === "object" || typeof obj === "function" ?
+            class2type[ core_toString.call(obj) ] || "object" :
+            typeof obj;
+    },
+
+    isPlainObject: function( obj ) {
+        // Not plain objects:
+        // - Any object or value whose internal [[Class]] property is not 
"[object Object]"
+        // - DOM nodes
+        // - window
+        if ( jQuery.type( obj ) !== "object" || obj.nodeType || 
jQuery.isWindow( obj ) ) {
+            return false;
+        }
+
+        // Support: Firefox <20
+        // The try/catch suppresses exceptions thrown when attempting to access
+        // the "constructor" property of certain host objects, ie. 
|window.location|
+        // https://bugzilla.mozilla.org/show_bug.cgi?id=814622
+        try {
+            if ( obj.constructor &&
+                    !core_hasOwn.call( obj.constructor.prototype, 
"isPrototypeOf" ) ) {
+                return false;
+            }
+        } catch ( e ) {
+            return false;
+        }
+
+        // If the function hasn't returned already, we're confident that
+        // |obj| is a plain object, created by {} or constructed with new 
Object
+        return true;
+    },
+
+    isEmptyObject: function( obj ) {
+        var name;
+        for ( name in obj ) {
+            return false;
+        }
+        return true;
+    },
+
+    error: function( msg ) {
+        throw new Error( msg );
+    },
+
+    // data: string of html
+    // context (optional): If specified, the fragment will be created in this 
context, defaults to document
+    // keepScripts (optional): If true, will include scripts passed in the 
html string
+    parseHTML: function( data, context, keepScripts ) {
+        if ( !data || typeof data !== "string" ) {
+            return null;
+        }
+        if ( typeof context === "boolean" ) {
+            keepScripts = context;
+            context = false;
+        }
+        context = context || document;
+
+        var parsed = rsingleTag.exec( data ),
+            scripts = !keepScripts && [];
+
+        // Single tag
+        if ( parsed ) {
+            return [ context.createElement( parsed[1] ) ];
+        }
+
+        parsed = jQuery.buildFragment( [ data ], context, scripts );
+
+        if ( scripts ) {
+            jQuery( scripts ).remove();
+        }
+
+        return jQuery.merge( [], parsed.childNodes );
+    },
+
+    parseJSON: JSON.parse,
+
+    // Cross-browser xml parsing
+    parseXML: function( data ) {
+        var xml, tmp;
+        if ( !data || typeof data !== "string" ) {
+            return null;
+        }
+
+        // Support: IE9
+        try {
+            tmp = new DOMParser();
+            xml = tmp.parseFromString( data , "text/xml" );
+        } catch ( e ) {
+            xml = undefined;
+        }
+
+        if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) {
+            jQuery.error( "Invalid XML: " + data );
+        }
+        return xml;
+    },
+
+    noop: function() {},
+
+    // Evaluates a script in a global context
+    globalEval: function( code ) {
+        var script,
+                indirect = eval;
+
+        code = jQuery.trim( code );
+
+        if ( code ) {
+            // If the code includes a valid, prologue position
+            // strict mode pragma, execute code by injecting a
+            // script tag into the document.
+            if ( code.indexOf("use strict") === 1 ) {
+                script = document.createElement("script");
+                script.text = code;
+                document.head.appendChild( script ).parentNode.removeChild( 
script );
+            } else {
+            // Otherwise, avoid the DOM node creation, insertion
+            // and removal by using an indirect global eval
+                indirect( code );
+            }
+        }
+    },
+
+    // Convert dashed to camelCase; used by the css and data modules
+    // Microsoft forgot to hump their vendor prefix (#9572)
+    camelCase: function( string ) {
+        return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, 
fcamelCase );
+    },
+
+    nodeName: function( elem, name ) {
+        return elem.nodeName && elem.nodeName.toLowerCase() === 
name.toLowerCase();
+    },
+
+    // args is for internal usage only
+    each: function( obj, callback, args ) {
+        var value,
+            i = 0,
+            length = obj.length,
+            isArray = isArraylike( obj );
+
+        if ( args ) {
+            if ( isArray ) {
+                for ( ; i < length; i++ ) {
+                    value = callback.apply( obj[ i ], args );
+
+                    if ( value === false ) {
+                        break;
+                    }
+                }
+            } else {
+                for ( i in obj ) {
+                    value = callback.apply( obj[ i ], args );
+
+                    if ( value === false ) {
+                        break;
+                    }
+                }
+            }
+
+        // A special, fast, case for the most common use of each
+        } else {
+            if ( isArray ) {
+                for ( ; i < length; i++ ) {
+                    value = callback.call( obj[ i ], i, obj[ i ] );
+
+                    if ( value === false ) {
+                        break;
+                    }
+                }
+            } else {
+                for ( i in obj ) {
+                    value = callback.call( obj[ i ], i, obj[ i ] );
+
+                    if ( value === false ) {
+                        break;
+                    }
+                }
+            }
+        }
+
+        return obj;
+    },
+
+    trim: function( text ) {
+        return text == null ? "" : core_trim.call( text );
+    },
+
+    // results is for internal usage only
+    makeArray: function( arr, results ) {
+        var ret = results || [];
+
+        if ( arr != null ) {
+            if ( isArraylike( Object(arr) ) ) {
+                jQuery.merge( ret,
+                    typeof arr === "string" ?
+                    [ arr ] : arr
+                );
+            } else {
+                core_push.call( ret, arr );
+            }
+        }
+
+        return ret;
+    },
+
+    inArray: function( elem, arr, i ) {
+        return arr == null ? -1 : core_indexOf.call( arr, elem, i );
+    },
+
+    merge: function( first, second ) {
+        var l = second.length,
+            i = first.length,
+            j = 0;
+
+        if ( typeof l === "number" ) {
+            for ( ; j < l; j++ ) {
+                first[ i++ ] = second[ j ];
+            }
+        } else {
+            while ( second[j] !== undefined ) {
+                first[ i++ ] = second[ j++ ];
+            }
+        }
+
+        first.length = i;
+
+        return first;
+    },
+
+    grep: function( elems, callback, inv ) {
+        var retVal,
+            ret = [],
+            i = 0,
+            length = elems.length;
+        inv = !!inv;
+
+        // Go through the array, only saving the items
+        // that pass the validator function
+        for ( ; i < length; i++ ) {
+            retVal = !!callback( elems[ i ], i );
+            if ( inv !== retVal ) {
+                ret.push( elems[ i ] );
+            }
+        }
+
+        return ret;
+    },
+
+    // arg is for internal usage only
+    map: function( elems, callback, arg ) {
+        var value,
+            i = 0,
+            length = elems.length,
+            isArray = isArraylike( elems ),
+            ret = [];
+
+        // Go through the array, translating each of the items to their
+        if ( isArray ) {
+            for ( ; i < length; i++ ) {
+                value = callback( elems[ i ], i, arg );
+
+                if ( value != null ) {
+                    ret[ ret.length ] = value;
+                }
+            }
+
+        // Go through every key on the object,
+        } else {
+            for ( i in elems ) {
+                value = callback( elems[ i ], i, arg );
+
+                if ( value != null ) {
+                    ret[ ret.length ] = value;
+                }
+            }
+        }
+
+        // Flatten any nested arrays
+        return core_concat.apply( [], ret );
+    },
+
+    // A global GUID counter for objects
+    guid: 1,
+
+    // Bind a function to a context, optionally partially applying any
+    // arguments.
+    proxy: function( fn, context ) {
+        var tmp, args, proxy;
+
+        if ( typeof context === "string" ) {
+            tmp = fn[ context ];
+            context = fn;
+            fn = tmp;
+        }
+
+        // Quick check to determine if target is callable, in the spec
+        // this throws a TypeError, but we will just return undefined.
+        if ( !jQuery.isFunction( fn ) ) {
+            return undefined;
+        }
+
+        // Simulated bind
+        args = core_slice.call( arguments, 2 );
+        proxy = function() {
+            return fn.apply( context || this, args.concat( core_slice.call( 
arguments ) ) );
+        };
+
+        // Set the guid of unique handler to the same of original handler, so 
it can be removed
+        proxy.guid = fn.guid = fn.guid || jQuery.guid++;
+
+        return proxy;
+    },
+
+    // Multifunctional method to get and set values of a collection
+    // The value/s can optionally be executed if it's a function
+    access: function( elems, fn, key, value, chainable, emptyGet, raw ) {
+        var i = 0,
+            length = elems.length,
+            bulk = key == null;
+
+        // Sets many values
+        if ( jQuery.type( key ) === "object" ) {
+            chainable = true;
+            for ( i in key ) {
+                jQuery.access( elems, fn, i, key[i], true, emptyGet, raw );
+            }
+
+        // Sets one value
+        } else if ( value !== undefined ) {
+            chainable = true;
+
+            if ( !jQuery.isFunction( value ) ) {
+                raw = true;
+            }
+
+            if ( bulk ) {
+                // Bulk operations run against the entire set
+                if ( raw ) {
+                    fn.call( elems, value );
+                    fn = null;
+
+                // ...except when executing function values
+                } else {
+                    bulk = fn;
+                    fn = function( elem, key, value ) {
+                        return bulk.call( jQuery( elem ), value );
+                    };
+                }
+            }
+
+            if ( fn ) {
+                for ( ; i < length; i++ ) {
+                    fn( elems[i], key, raw ? value : value.call( elems[i], i, 
fn( elems[i], key ) ) );
+                }
+            }
+        }
+
+        return chainable ?
+            elems :
+
+            // Gets
+            bulk ?
+                fn.call( elems ) :
+                length ? fn( elems[0], key ) : emptyGet;
+    },
+
+    now: Date.now,
+
+    // A method for quickly swapping in/out CSS properties to get correct 
calculations.
+    // Note: this method belongs to the css module but it's needed here for 
the support module.
+    // If support gets modularized, this method should be moved back to the 
css module.
+    swap: function( elem, options, callback, args ) {
+        var ret, name,
+            old = {};
+
+        // Remember the old values, and insert the new ones
+        for ( name in options ) {
+            old[ name ] = elem.style[ name ];
+            elem.style[ name ] = options[ name ];
+        }
+
+        ret = callback.apply( elem, args || [] );
+
+        // Revert the old values
+        for ( name in options ) {
+            elem.style[ name ] = old[ name ];
+        }
+
+        return ret;
+    }
+});
+
+jQuery.ready.promise = function( obj ) {
+    if ( !readyList ) {
+
+        readyList = jQuery.Deferred();
+
+        // Catch cases where $(document).ready() is called after the browser 
event has already occurred.
+        // we once tried to use readyState "interactive" here, but it caused 
issues like the one
+        // discovered by ChrisS here: 
http://bugs.jquery.com/ticket/12282#comment:15
+        if ( document.readyState === "complete" ) {
+            // Handle it asynchronously to allow scripts the opportunity to 
delay ready
+            setTimeout( jQuery.ready );
+
+        } else {
+
+            // Use the handy event callback
+            document.addEventListener( "DOMContentLoaded", completed, false );
+
+            // A fallback to window.onload, that will always work
+            window.addEventListener( "load", completed, false );
+        }
+    }
+    return readyList.promise( obj );
+};
+
+// Populate the class2type map
+jQuery.each("Boolean Number String Function Array Date RegExp Object 
Error".split(" "), function(i, name) {
+    class2type[ "[object " + name + "]" ] = name.toLowerCase();
+});
+
+function isArraylike( obj ) {
+    var length = obj.length,
+        type = jQuery.type( obj );
+
+    if ( jQuery.isWindow( obj ) ) {
+        return false;
+    }
+
+    if ( obj.nodeType === 1 && length ) {
+        return true;
+    }
+
+    return type === "array" || type !== "function" &&
+        ( length === 0 ||
+        typeof length === "number" && length > 0 && ( length - 1 ) in obj );
+}
+
+// All jQuery objects should point back to these
+rootjQuery = jQuery(document);
+/*!
+ * Sizzle CSS Selector Engine v1.9.2-pre
+ * http://sizzlejs.com/
+ *
+ * Copyright 2013 jQuery Foundation, Inc. and other contributors
+ * Released under the MIT license
+ * http://jquery.org/license
+ *
+ * Date: 2013-04-16
+ */
+(function( window, undefined ) {
+
+var i,
+    cachedruns,
+    Expr,
+    getText,
+    isXML,
+    compile,
+    outermostContext,
+    sortInput,
+
+    // Local document vars
+    setDocument,
+    document,
+    docElem,
+    documentIsHTML,
+    rbuggyQSA,
+    rbuggyMatches,
+    matches,
+    contains,
+
+    // Instance-specific data
+    expando = "sizzle" + -(new Date()),
+    preferredDoc = window.document,
+    support = {},
+    dirruns = 0,
+    done = 0,
+    classCache = createCache(),
+    tokenCache = createCache(),
+    compilerCache = createCache(),
+    hasDuplicate = false,
+    sortOrder = function() { return 0; },
+
+    // General-purpose constants
+    strundefined = typeof undefined,
+    MAX_NEGATIVE = 1 << 31,
+
+    // Array methods
+    arr = [],
+    pop = arr.pop,
+    push_native = arr.push,
+    push = arr.push,
+    slice = arr.slice,
+    // Use a stripped-down indexOf if we can't use a native one
+    indexOf = arr.indexOf || function( elem ) {
+        var i = 0,
+            len = this.length;
+        for ( ; i < len; i++ ) {
+            if ( this[i] === elem ) {
+                return i;
+            }
+        }
+        return -1;
+    },
+
+    booleans = 
"checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
+
+    // Regular expressions
+
+    // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace
+    whitespace = "[\\x20\\t\\r\\n\\f]",
+    // http://www.w3.org/TR/css3-syntax/#characters
+    characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
+
+    // Loosely modeled on CSS identifier characters
+    // An unquoted value should be a CSS identifier 
http://www.w3.org/TR/css3-selectors/#attribute-selectors
+    // Proper syntax: 
http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
+    identifier = characterEncoding.replace( "w", "w#" ),
+
+    // Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors
+    attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + 
whitespace +
+        "*(?:([*^$|!~]?=)" + whitespace + 
"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + 
"*\\]",
+
+    // Prefer arguments quoted,
+    //   then not containing pseudos/brackets,
+    //   then attribute selectors/non-parenthetical expressions,
+    //   then anything else
+    // These preferences are here to reduce the number of selectors
+    //   needing tokenize in the PSEUDO preFilter
+    pseudos = ":(" + characterEncoding + 
")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|" + 
attributes.replace( 3, 8 ) + ")*)|.*)\\)|)",
+
+    // Leading and non-escaped trailing whitespace, capturing some 
non-whitespace characters preceding the latter
+    rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + 
whitespace + "+$", "g" ),
+
+    rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
+    rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + 
")" + whitespace + "*" ),
+
+    rsibling = new RegExp( whitespace + "*[+~]" ),
+    rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*)" + 
whitespace + "*\\]", "g" ),
+
+    rpseudo = new RegExp( pseudos ),
+    ridentifier = new RegExp( "^" + identifier + "$" ),
+
+    matchExpr = {
+        "ID": new RegExp( "^#(" + characterEncoding + ")" ),
+        "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ),
+        "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" 
),
+        "ATTR": new RegExp( "^" + attributes ),
+        "PSEUDO": new RegExp( "^" + pseudos ),
+        "CHILD": new RegExp( 
"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
+            "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + 
whitespace +
+            "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
+        "boolean": new RegExp( "^(?:" + booleans + ")$", "i" ),
+        // For use in libraries implementing .is()
+        // We use this for POS matching in `select`
+        "needsContext": new RegExp( "^" + whitespace + 
"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
+            whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", 
"i" )
+    },
+
+    rnative = /^[^{]+\{\s*\[native \w/,
+
+    // Easily-parseable/retrievable ID or TAG or CLASS selectors
+    rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
+
+    rinputs = /^(?:input|select|textarea|button)$/i,
+    rheader = /^h\d$/i,
+
+    rescape = /'|\\/g,
+
+    // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
+    runescape = /\\([\da-fA-F]{1,6}[\x20\t\r\n\f]?|.)/g,
+    funescape = function( _, escaped ) {
+        var high = "0x" + escaped - 0x10000;
+        // NaN means non-codepoint
+        return high !== high ?
+            escaped :
+            // BMP codepoint
+            high < 0 ?
+                String.fromCharCode( high + 0x10000 ) :
+                // Supplemental Plane codepoint (surrogate pair)
+                String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 
0xDC00 );
+    };
+
+// Optimize for push.apply( _, NodeList )
+try {
+    push.apply(
+        (arr = slice.call( preferredDoc.childNodes )),
+        preferredDoc.childNodes
+    );
+    // Support: Android<4.0
+    // Detect silently failing push.apply
+    arr[ preferredDoc.childNodes.length ].nodeType;
+} catch ( e ) {
+    push = { apply: arr.length ?
+
+        // Leverage slice if possible
+        function( target, els ) {
+            push_native.apply( target, slice.call(els) );
+        } :
+
+        // Support: IE<9
+        // Otherwise append directly
+        function( target, els ) {
+            var j = target.length,
+                i = 0;
+            // Can't trust NodeList.length
+            while ( (target[j++] = els[i++]) ) {}
+            target.length = j - 1;
+        }
+    };
+}
+
+/**
+ * For feature detection
+ * @param {Function} fn The function to test for native support
+ */
+function isNative( fn ) {
+    return rnative.test( fn + "" );
+}
+
+/**
+ * Create key-value caches of limited size
+ * @returns {Function(string, Object)} Returns the Object data after storing 
it on itself with
+ *  property name the (space-suffixed) string and (if the cache is larger than 
Expr.cacheLength)
+ *  deleting the oldest entry
+ */
+function createCache() {
+    var cache,
+        keys = [];
+
+    return (cache = function( key, value ) {
+        // Use (key + " ") to avoid collision with native prototype properties 
(see Issue #157)
+        if ( keys.push( key += " " ) > Expr.cacheLength ) {
+            // Only keep the most recent entries
+            delete cache[ keys.shift() ];
+        }
+        return (cache[ key ] = value);
+    });
+}
+
+/**
+ * Mark a function for special use by Sizzle
+ * @param {Function} fn The function to mark
+ */
+function markFunction( fn ) {
+    fn[ expando ] = true;
+    return fn;
+}
+
+/**
+ * Support testing using an element
+ * @param {Function} fn Passed the created div and expects a boolean result
+ */
+function assert( fn ) {
+    var div = document.createElement("div");
+
+    try {
+        return !!fn( div );
+    } catch (e) {
+        return false;
+    } finally {
+        if ( div.parentNode ) {
+            div.parentNode.removeChild( div );
+        }
+        // release memory in IE
+        div = null;
+    }
+}
+
+function Sizzle( selector, context, results, seed ) {
+    var match, elem, m, nodeType,
+        // QSA vars
+        i, groups, old, nid, newContext, newSelector;
+
+    if ( ( context ? context.ownerDocument || context : preferredDoc ) !== 
document ) {
+        setDocument( context );
+    }
+
+    context = context || document;
+    results = results || [];
+
+    if ( !selector || typeof selector !== "string" ) {
+        return results;
+    }
+
+    if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) {
+        return [];
+    }
+
+    if ( documentIsHTML && !seed ) {
+
+        // Shortcuts
+        if ( (match = rquickExpr.exec( selector )) ) {
+            // Speed-up: Sizzle("#ID")
+            if ( (m = match[1]) ) {
+                if ( nodeType === 9 ) {
+                    elem = context.getElementById( m );
+                    // Check parentNode to catch when Blackberry 4.6 returns
+                    // nodes that are no longer in the document #6963
+                    if ( elem && elem.parentNode ) {
+                        // Handle the case where IE, Opera, and Webkit return 
items
+                        // by name instead of ID
+                        if ( elem.id === m ) {
+                            results.push( elem );
+                            return results;
+                        }
+                    } else {
+                        return results;
+                    }
+                } else {
+                    // Context is not a document
+                    if ( context.ownerDocument && (elem = 
context.ownerDocument.getElementById( m )) &&
+                        contains( context, elem ) && elem.id === m ) {
+                        results.push( elem );
+                        return results;
+                    }
+                }
+
+            // Speed-up: Sizzle("TAG")
+            } else if ( match[2] ) {
+                push.apply( results, context.getElementsByTagName( selector ) 
);
+                return results;
+
+            // Speed-up: Sizzle(".CLASS")
+            } else if ( (m = match[3]) && support.getElementsByClassName && 
context.getElementsByClassName ) {
+                push.apply( results, context.getElementsByClassName( m ) );
+                return results;
+            }
+        }
+
+        // QSA path
+        if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
+            nid = old = expando;
+            newContext = context;
+            newSelector = nodeType === 9 && selector;
+
+            // qSA works strangely on Element-rooted queries
+            // We can work around this by specifying an extra ID on the root
+            // and working up from there (Thanks to Andrew Dupont for the 
technique)
+            // IE 8 doesn't work on object elements
+            if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" 
) {
+                groups = tokenize( selector );
+
+                if ( (old = context.getAttribute("id")) ) {
+                    nid = old.replace( rescape, "\\$&" );
+                } else {
+                    context.setAttribute( "id", nid );
+                }
+                nid = "[id='" + nid + "'] ";
+
+                i = groups.length;
+                while ( i-- ) {
+                    groups[i] = nid + toSelector( groups[i] );
+                }
+                newContext = rsibling.test( selector ) && context.parentNode 
|| context;
+                newSelector = groups.join(",");
+            }
+
+            if ( newSelector ) {
+                try {
+                    push.apply( results,
+                        newContext.querySelectorAll( newSelector )
+                    );
+                    return results;
+                } catch(qsaError) {
+                } finally {
+                    if ( !old ) {
+                        context.removeAttribute("id");
+                    }
+                }
+            }
+        }
+    }
+
+    // All others
+    return select( selector.replace( rtrim, "$1" ), context, results, seed );
+}
+
+/**
+ * Detect xml
+ * @param {Element|Object} elem An element or a document
+ */
+isXML = Sizzle.isXML = function( elem ) {
+    // documentElement is verified for cases where it doesn't yet exist
+    // (such as loading iframes in IE - #4833)
+    var documentElement = elem && (elem.ownerDocument || elem).documentElement;
+    return documentElement ? documentElement.nodeName !== "HTML" : false;
+};
+
+/**
+ * Sets document-related variables once based on the current document
+ * @param {Element|Object} [doc] An element or document object to use to set 
the document
+ * @returns {Object} Returns the current document
+ */
+setDocument = Sizzle.setDocument = function( node ) {
+    var doc = node ? node.ownerDocument || node : preferredDoc;
+
+    // If no document and documentElement is available, return
+    if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
+        return document;
+    }
+
+    // Set our document
+    document = doc;
+    docElem = doc.documentElement;
+
+    // Support tests
+    documentIsHTML = !isXML( doc );
+
+    // Check if getElementsByTagName("*") returns only elements
+    support.getElementsByTagName = assert(function( div ) {
+        div.appendChild( doc.createComment("") );
+        return !div.getElementsByTagName("*").length;
+    });
+
+    // Support: IE<8
+    // Verify that getAttribute really returns attributes and not properties 
(excepting IE8 booleans)
+    support.attributes = assert(function( div ) {
+        div.className = "i";
+        return !div.getAttribute("className");
+    });
+
+    // Check if getElementsByClassName can be trusted
+    support.getElementsByClassName = assert(function( div ) {
+        div.innerHTML = "<div class='a'></div><div class='a i'></div>";
+
+        // Support: Safari<4
+        // Catch class over-caching
+        div.firstChild.className = "i";
+        // Support: Opera<10
+        // Catch gEBCN failure to find non-leading classes
+        return div.getElementsByClassName("i").length === 2;
+    });
+
+    // Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
+    // Detached nodes confoundingly follow *each other*
+    support.sortDetached = assert(function( div1 ) {
+        // Should return 1, but returns 4 (following)
+        return div1.compareDocumentPosition( document.createElement("div") ) & 
1;
+    });
+
+    // Support: IE<10
+    // Check if getElementById returns elements by name
+    // Support: Windows 8 Native Apps
+    // Assigning innerHTML with "name" attributes throws uncatchable exceptions
+    // (http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx)
+    // and the broken getElementById methods don't pick up programatically-set 
names,
+    // so use a roundabout getElementsByName test
+    support.getById = assert(function( div ) {
+        docElem.appendChild( div ).id = expando;
+        return !doc.getElementsByName || !doc.getElementsByName( expando 
).length;
+    });
+
+    // ID find and filter
+    if ( support.getById ) {
+        Expr.find["ID"] = function( id, context ) {
+            if ( typeof context.getElementById !== strundefined && 
documentIsHTML ) {
+                var m = context.getElementById( id );
+                // Check parentNode to catch when Blackberry 4.6 returns
+                // nodes that are no longer in the document #6963
+                return m && m.parentNode ? [m] : [];
+            }
+        };
+        Expr.filter["ID"] = function( id ) {
+            var attrId = id.replace( runescape, funescape );
+            return function( elem ) {
+                return elem.getAttribute("id") === attrId;
+            };
+        };
+    } else {
+        Expr.find["ID"] = function( id, context ) {
+            if ( typeof context.getElementById !== strundefined && 
documentIsHTML ) {
+                var m = context.getElementById( id );
+
+                return m ?
+                    m.id === id || typeof m.getAttributeNode !== strundefined 
&& m.getAttributeNode("id").value === id ?
+                        [m] :
+                        undefined :
+                    [];
+            }
+        };
+        Expr.filter["ID"] =  function( id ) {
+            var attrId = id.replace( runescape, funescape );
+            return function( elem ) {
+                var node = typeof elem.getAttributeNode !== strundefined && 
elem.getAttributeNode("id");
+                return node && node.value === attrId;
+            };
+        };
+    }
+
+    // Tag
+    Expr.find["TAG"] = support.getElementsByTagName ?
+        function( tag, context ) {
+            if ( typeof context.getElementsByTagName !== strundefined ) {
+                return context.getElementsByTagName( tag );
+            }
+        } :
+        function( tag, context ) {
+            var elem,
+                tmp = [],
+                i = 0,
+                results = context.getElementsByTagName( tag );
+
+            // Filter out possible comments
+            if ( tag === "*" ) {
+                while ( (elem = results[i++]) ) {
+                    if ( elem.nodeType === 1 ) {
+                        tmp.push( elem );
+                    }
+                }
+
+                return tmp;
+            }
+            return results;
+        };
+
+    // Class
+    Expr.find["CLASS"] = support.getElementsByClassName && function( 
className, context ) {
+        if ( typeof context.getElementsByClassName !== strundefined && 
documentIsHTML ) {
+            return context.getElementsByClassName( className );
+        }
+    };
+
+    // QSA and matchesSelector support
+
+    // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
+    rbuggyMatches = [];
+
+    // qSa(:focus) reports false when true (Chrome 21)
+    // We allow this because of a bug in IE8/9 that throws an error
+    // whenever `document.activeElement` is accessed on an iframe
+    // So, we allow :focus to pass through QSA all the time to avoid the IE 
error
+    // See http://bugs.jquery.com/ticket/13378
+    rbuggyQSA = [];
+
+    if ( (support.qsa = isNative(doc.querySelectorAll)) ) {
+        // Build QSA regex
+        // Regex strategy adopted from Diego Perini
+        assert(function( div ) {
+            // Select is set to empty string on purpose
+            // This is to test IE's treatment of not explicitly
+            // setting a boolean content attribute,
+            // since its presence should be enough
+            // http://bugs.jquery.com/ticket/12359
+            div.innerHTML = "<select><option selected=''></option></select>";
+
+            // Support: IE8
+            // Boolean attributes and "value" are not treated correctly
+            if ( !div.querySelectorAll("[selected]").length ) {
+                rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + 
")" );
+            }
+
+            // Webkit/Opera - :checked should return selected option elements
+            // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
+            // IE8 throws error here and will not see later tests
+            if ( !div.querySelectorAll(":checked").length ) {
+                rbuggyQSA.push(":checked");
+            }
+        });
+
+        assert(function( div ) {
+
+            // Support: Opera 10-12/IE8
+            // ^= $= *= and empty values
+            // Should not select anything
+            // Support: Windows 8 Native Apps
+            // The type attribute is restricted during .innerHTML assignment
+            var input = document.createElement("input");
+            input.setAttribute( "type", "hidden" );
+            div.appendChild( input ).setAttribute( "t", "" );
+
+            if ( div.querySelectorAll("[t^='']").length ) {
+                rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
+            }
+
+            // FF 3.5 - :enabled/:disabled and hidden elements (hidden 
elements are still enabled)
+            // IE8 throws error here and will not see later tests
+            if ( !div.querySelectorAll(":enabled").length ) {
+                rbuggyQSA.push( ":enabled", ":disabled" );
+            }
+
+            // Opera 10-11 does not throw on post-comma invalid pseudos
+            div.querySelectorAll("*,:x");
+            rbuggyQSA.push(",.*:");
+        });
+    }
+
+    if ( (support.matchesSelector = isNative( (matches = 
docElem.webkitMatchesSelector ||
+        docElem.mozMatchesSelector ||
+        docElem.oMatchesSelector ||
+        docElem.msMatchesSelector) )) ) {
+
+        assert(function( div ) {
+            // Check to see if it's possible to do matchesSelector
+            // on a disconnected node (IE 9)
+            support.disconnectedMatch = matches.call( div, "div" );
+
+            // This should fail with an exception
+            // Gecko does not error, returns false instead
+            matches.call( div, "[s!='']:x" );
+            rbuggyMatches.push( "!=", pseudos );
+        });
+    }
+
+    rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
+    rbuggyMatches = rbuggyMatches.length && new RegExp( 
rbuggyMatches.join("|") );
+
+    // Element contains another
+    // Purposefully does not implement inclusive descendent
+    // As in, an element does not contain itself
+    contains = isNative(docElem.contains) || docElem.compareDocumentPosition ?
+        function( a, b ) {
+            var adown = a.nodeType === 9 ? a.documentElement : a,
+                bup = b && b.parentNode;
+            return a === bup || !!( bup && bup.nodeType === 1 && (
+                adown.contains ?
+                    adown.contains( bup ) :
+                    a.compareDocumentPosition && a.compareDocumentPosition( 
bup ) & 16
+            ));
+        } :
+        function( a, b ) {
+            if ( b ) {
+                while ( (b = b.parentNode) ) {
+                    if ( b === a ) {
+                        return true;
+                    }
+                }
+            }
+            return false;
+        };
+
+    // Document order sorting
+    sortOrder = docElem.compareDocumentPosition ?
+    function( a, b ) {
+
+        // Flag for duplicate removal
+        if ( a === b ) {
+            hasDuplicate = true;
+            return 0;
+        }
+
+        var compare = b.compareDocumentPosition && a.compareDocumentPosition 
&& a.compareDocumentPosition( b );
+
+        if ( compare ) {
+            // Disconnected nodes
+            if ( compare & 1 ||
+                (!support.sortDetached && b.compareDocumentPosition( a ) === 
compare) ) {
+
+                // Choose the first element that is related to our preferred 
document
+                if ( a === doc || contains(preferredDoc, a) ) {
+                    return -1;
+                }
+                if ( b === doc || contains(preferredDoc, b) ) {
+                    return 1;
+                }
+
+                // Maintain original order
+                return sortInput ?
+                    ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, 
b ) ) :
+                    0;
+            }
+
+            return compare & 4 ? -1 : 1;
+        }
+
+        // Not directly comparable, sort on existence of method
+        return a.compareDocumentPosition ? -1 : 1;
+    } :
+    function( a, b ) {
+        var cur,
+            i = 0,
+            aup = a.parentNode,
+            bup = b.parentNode,
+            ap = [ a ],
+            bp = [ b ];
+
+        // Exit early if the nodes are identical
+        if ( a === b ) {
+            hasDuplicate = true;
+            return 0;
+
+        // Parentless nodes are either documents or disconnected
+        } else if ( !aup || !bup ) {
+            return a === doc ? -1 :
+                b === doc ? 1 :
+                aup ? -1 :
+                bup ? 1 :
+                sortInput ?
+                ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) 
) :
+                0;
+
+        // If the nodes are siblings, we can do a quick check
+        } else if ( aup === bup ) {
+            return siblingCheck( a, b );
+        }
+
+        // Otherwise we need full lists of their ancestors for comparison
+        cur = a;
+        while ( (cur = cur.parentNode) ) {
+            ap.unshift( cur );
+        }
+        cur = b;
+        while ( (cur = cur.parentNode) ) {
+            bp.unshift( cur );
+        }
+
+        // Walk down the tree looking for a discrepancy
+        while ( ap[i] === bp[i] ) {
+            i++;
+        }
+
+        return i ?
+            // Do a sibling check if the nodes have a common ancestor
+            siblingCheck( ap[i], bp[i] ) :
+
+            // Otherwise nodes in our document sort first
+            ap[i] === preferredDoc ? -1 :
+            bp[i] === preferredDoc ? 1 :
+            0;
+    };
+
+    return document;
+};
+
+Sizzle.matches = function( expr, elements ) {
+    return Sizzle( expr, null, null, elements );
+};
+
+Sizzle.matchesSelector = function( elem, expr ) {
+    // Set document vars if needed
+    if ( ( elem.ownerDocument || elem ) !== document ) {
+        setDocument( elem );
+    }
+
+    // Make sure that attribute selectors are quoted
+    expr = expr.replace( rattributeQuotes, "='$1']" );
+
+    // rbuggyQSA always contains :focus, so no need for an existence check
+    if ( support.matchesSelector && documentIsHTML &&
+        (!rbuggyMatches || !rbuggyMatches.test(expr)) &&
+        (!rbuggyQSA     || !rbuggyQSA.test(expr)) ) {
+
+        try {
+            var ret = matches.call( elem, expr );
+
+            // IE 9's matchesSelector returns false on disconnected nodes
+            if ( ret || support.disconnectedMatch ||
+                    // As well, disconnected nodes are said to be in a document
+                    // fragment in IE 9
+                    elem.document && elem.document.nodeType !== 11 ) {
+                return ret;
+            }
+        } catch(e) {}
+    }
+
+    return Sizzle( expr, document, null, [elem] ).length > 0;
+};
+
+Sizzle.contains = function( context, elem ) {
+    // Set document vars if needed
+    if ( ( context.ownerDocument || context ) !== document ) {
+        setDocument( context );
+    }
+    return contains( context, elem );
+};
+
+Sizzle.attr = function( elem, name ) {
+    // Set document vars if needed
+    if ( ( elem.ownerDocument || elem ) !== document ) {
+        setDocument( elem );
+    }
+
+    var fn = Expr.attrHandle[ name.toLowerCase() ],
+        val = fn && fn( elem, name, !documentIsHTML );
+
+    return val === undefined ?
+        support.attributes || !documentIsHTML ?
+            elem.getAttribute( name ) :
+            (val = elem.getAttributeNode(name)) && val.specified ?
+                val.value :
+                null :
+        val;
+};
+
+Sizzle.error = function( msg ) {
+    throw new Error( "Syntax error, unrecognized expression: " + msg );
+};
+
+// Document sorting and removing duplicates
+Sizzle.uniqueSort = function( results ) {
+    var elem,
+        duplicates = [],
+        j = 0,
+        i = 0;
+
+    // Unless we *know* we can detect duplicates, assume their presence
+    hasDuplicate = !support.detectDuplicates;
+    sortInput = !support.sortStable && results.slice( 0 );
+    results.sort( sortOrder );
+
+    if ( hasDuplicate ) {
+        while ( (elem = results[i++]) ) {
+            if ( elem === results[ i ] ) {
+                j = duplicates.push( i );
+            }
+        }
+        while ( j-- ) {
+            results.splice( duplicates[ j ], 1 );
+        }
+    }
+
+    return results;
+};
+
+/**
+ * Checks document order of two siblings
+ * @param {Element} a
+ * @param {Element} b
+ * @returns Returns -1 if a precedes b, 1 if a follows b
+ */
+function siblingCheck( a, b ) {
+    var cur = b && a,
+        diff = cur && ( ~b.sourceIndex || MAX_NEGATIVE ) - ( ~a.sourceIndex || 
MAX_NEGATIVE );
+
+    // Use IE sourceIndex if available on both nodes
+    if ( diff ) {
+        return diff;
+    }
+
+    // Check if b follows a
+    if ( cur ) {
+        while ( (cur = cur.nextSibling) ) {
+            if ( cur === b ) {
+                return -1;
+            }
+        }
+    }
+
+    return a ? 1 : -1;
+}
+
+// Fetches boolean attributes by node
+function boolHandler( elem, name, isXML ) {
+    var val;
+    return isXML ?
+        undefined :
+        (val = elem.getAttributeNode( name )) && val.specified ?
+            val.value :
+            elem[ name ] === true ? name.toLowerCase() : null;
+}
+
+// Fetches attributes without interpolation
+// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
+function interpolationHandler( elem, name, isXML ) {
+    var val;
+    return isXML ?
+        undefined :
+        (val = elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 
));
+}
+
+// Returns a function to use in pseudos for input types
+function createInputPseudo( type ) {
+    return function( elem ) {
+        var name = elem.nodeName.toLowerCase();
+        return name === "input" && elem.type === type;
+    };
+}
+
+// Returns a function to use in pseudos for buttons
+function createButtonPseudo( type ) {
+    return function( elem ) {
+        var name = elem.nodeName.toLowerCase();
+        return (name === "input" || name === "button") && elem.type === type;
+    };
+}
+
+// Returns a function to use in pseudos for positionals
+function createPositionalPseudo( fn ) {
+    return markFunction(function( argument ) {
+        argument = +argument;
+        return markFunction(function( seed, matches ) {
+            var j,
+                matchIndexes = fn( [], seed.length, argument ),
+                i = matchIndexes.length;
+
+            // Match elements found at the specified indexes
+            while ( i-- ) {
+                if ( seed[ (j = matchIndexes[i]) ] ) {
+                    seed[j] = !(matches[j] = seed[j]);
+                }
+            }
+        });
+    });
+}
+
+/**
+ * Utility function for retrieving the text value of an array of DOM nodes
+ * @param {Array|Element} elem
+ */
+getText = Sizzle.getText = function( elem ) {
+    var node,
+        ret = "",
+        i = 0,
+        nodeType = elem.nodeType;
+
+    if ( !nodeType ) {
+        // If no nodeType, this is expected to be an array
+        for ( ; (node = elem[i]); i++ ) {
+            // Do not traverse comment nodes
+            ret += getText( node );
+        }
+    } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
+        // Use textContent for elements
+        // innerText usage removed for consistency of new lines (see #11153)
+        if ( typeof elem.textContent === "string" ) {
+            return elem.textContent;
+        } else {
+            // Traverse its children
+            for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
+                ret += getText( elem );
+            }
+        }
+    } else if ( nodeType === 3 || nodeType === 4 ) {
+        return elem.nodeValue;
+    }
+    // Do not include comment or processing instruction nodes
+
+    return ret;
+};
+
+Expr = Sizzle.selectors = {
+
+    // Can be adjusted by the user
+    cacheLength: 50,
+
+    createPseudo: markFunction,
+
+    match: matchExpr,
+
+    attrHandle: {},
+
+    find: {},
+
+    relative: {
+        ">": { dir: "parentNode", first: true },
+        " ": { dir: "parentNode" },
+        "+": { dir: "previousSibling", first: true },
+        "~": { dir: "previousSibling" }
+    },
+
+    preFilter: {
+        "ATTR": function( match ) {
+            match[1] = match[1].replace( runescape, funescape );
+
+            // Move the given value to match[3] whether quoted or unquoted
+            match[3] = ( match[4] || match[5] || "" ).replace( runescape, 
funescape );
+
+            if ( match[2] === "~=" ) {
+                match[3] = " " + match[3] + " ";
+            }
+
+            return match.slice( 0, 4 );
+        },
+
+        "CHILD": function( match ) {
+            /* matches from matchExpr["CHILD"]
+                1 type (only|nth|...)
+                2 what (child|of-type)
+                3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
+                4 xn-component of xn+y argument ([+-]?\d*n|)
+                5 sign of xn-component
+                6 x of xn-component
+                7 sign of y-component
+                8 y of y-component
+            */
+            match[1] = match[1].toLowerCase();
+
+            if ( match[1].slice( 0, 3 ) === "nth" ) {
+                // nth-* requires argument
+                if ( !match[3] ) {
+                    Sizzle.error( match[0] );
+                }
+
+                // numeric x and y parameters for Expr.filter.CHILD
+                // remember that false/true cast respectively to 0/1
+                match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( 
match[3] === "even" || match[3] === "odd" ) );
+                match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
+
+            // other types prohibit arguments
+            } else if ( match[3] ) {
+                Sizzle.error( match[0] );
+            }
+
+            return match;
+        },
+
+        "PSEUDO": function( match ) {
+            var excess,
+                unquoted = !match[5] && match[2];
+
+            if ( matchExpr["CHILD"].test( match[0] ) ) {
+                return null;
+            }
+
+            // Accept quoted arguments as-is
+            if ( match[4] ) {
+                match[2] = match[4];
+
+            // Strip excess characters from unquoted arguments
+            } else if ( unquoted && rpseudo.test( unquoted ) &&
+                // Get excess from tokenize (recursively)
+                (excess = tokenize( unquoted, true )) &&
+                // advance to the next closing parenthesis
+                (excess = unquoted.indexOf( ")", unquoted.length - excess ) - 
unquoted.length) ) {
+
+                // excess is a negative index
+                match[0] = match[0].slice( 0, excess );
+                match[2] = unquoted.slice( 0, excess );
+            }
+
+            // Return only captures needed by the pseudo filter method (type 
and argument)
+            return match.slice( 0, 3 );
+        }
+    },
+
+    filter: {
+
+        "TAG": function( nodeNameSelector ) {
+            var nodeName = nodeNameSelector.replace( runescape, funescape 
).toLowerCase();
+            return nodeNameSelector === "*" ?
+                function() { return true; } :
+                function( elem ) {
+                    return elem.nodeName && elem.nodeName.toLowerCase() === 
nodeName;
+                };
+        },
+
+        "CLASS": function( className ) {
+            var pattern = classCache[ className + " " ];
+
+            return pattern ||
+                (pattern = new RegExp( "(^|" + whitespace + ")" + className + 
"(" + whitespace + "|$)" )) &&
+                classCache( className, function( elem ) {
+                    return pattern.test( typeof elem.className === "string" && 
elem.className || typeof elem.getAttribute !== strundefined && 
elem.getAttribute("class") || "" );
+                });
+        },
+
+        "ATTR": function( name, operator, check ) {
+            return function( elem ) {
+                var result = Sizzle.attr( elem, name );
+
+                if ( result == null ) {
+                    return operator === "!=";
+                }
+                if ( !operator ) {
+                    return true;
+                }
+
+                result += "";
+
+                return operator === "=" ? result === check :
+                    operator === "!=" ? result !== check :
+                    operator === "^=" ? check && result.indexOf( check ) === 0 
:
+                    operator === "*=" ? check && result.indexOf( check ) > -1 :
+                    operator === "$=" ? check && result.slice( -check.length ) 
=== check :
+                    operator === "~=" ? ( " " + result + " " ).indexOf( check 
) > -1 :
+                    operator === "|=" ? result === check || result.slice( 0, 
check.length + 1 ) === check + "-" :
+                    false;
+            };
+        },
+
+        "CHILD": function( type, what, argument, first, last ) {
+            var simple = type.slice( 0, 3 ) !== "nth",
+                forward = type.slice( -4 ) !== "last",
+                ofType = what === "of-type";
+
+            return first === 1 && last === 0 ?
+
+                // Shortcut for :nth-*(n)
+                function( elem ) {
+                    return !!elem.parentNode;
+                } :
+
+                function( elem, context, xml ) {
+                    var cache, outerCache, node, diff, nodeIndex, start,
+                        dir = simple !== forward ? "nextSibling" : 
"previousSibling",
+                        parent = elem.parentNode,
+                        name = ofType && elem.nodeName.toLowerCase(),
+                        useCache = !xml && !ofType;
+
+                    if ( parent ) {
+
+                        // :(first|last|only)-(child|of-type)
+                        if ( simple ) {
+                            while ( dir ) {
+                                node = elem;
+                                while ( (node = node[ dir ]) ) {
+                                    if ( ofType ? node.nodeName.toLowerCase() 
=== name : node.nodeType === 1 ) {
+                                        return false;
+                                    }
+                                }
+                                // Reverse direction for :only-* (if we 
haven't yet done so)
+                                start = dir = type === "only" && !start && 
"nextSibling";
+                            }
+                            return true;
+                        }
+
+                        start = [ forward ? parent.firstChild : 
parent.lastChild ];
+
+                        // non-xml :nth-child(...) stores cache data on 
`parent`
+                        if ( forward && useCache ) {
+                            // Seek `elem` from a previously-cached index
+                            outerCache = parent[ expando ] || (parent[ expando 
] = {});
+                            cache = outerCache[ type ] || [];
+                            nodeIndex = cache[0] === dirruns && cache[1];
+                            diff = cache[0] === dirruns && cache[2];
+                            node = nodeIndex && parent.childNodes[ nodeIndex ];
+
+                            while ( (node = ++nodeIndex && node && node[ dir ] 
||
+
+                                // Fallback to seeking `elem` from the start
+                                (diff = nodeIndex = 0) || start.pop()) ) {
+
+                                // When found, cache indexes on `parent` and 
break
+                                if ( node.nodeType === 1 && ++diff && node === 
elem ) {
+                                    outerCache[ type ] = [ dirruns, nodeIndex, 
diff ];
+                                    break;
+                                }
+                            }
+
+                        // Use previously-cached element index if available
+                        } else if ( useCache && (cache = (elem[ expando ] || 
(elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) {
+                            diff = cache[1];
+
+                        // xml :nth-child(...) or :nth-last-child(...) or 
:nth(-last)?-of-type(...)
+                        } else {
+                            // Use the same loop as above to seek `elem` from 
the start
+                            while ( (node = ++nodeIndex && node && node[ dir ] 
||
+                                (diff = nodeIndex = 0) || start.pop()) ) {
+
+                                if ( ( ofType ? node.nodeName.toLowerCase() 
=== name : node.nodeType === 1 ) && ++diff ) {
+                                    // Cache the index of each encountered 
element
+                                    if ( useCache ) {
+                                        (node[ expando ] || (node[ expando ] = 
{}))[ type ] = [ dirruns, diff ];
+                                    }
+
+                                    if ( node === elem ) {
+                                        break;
+                                    }
+                                }
+                            }
+                        }
+
+                        // Incorporate the offset, then check against cycle 
size
+                        diff -= last;
+                        return diff === first || ( diff % first === 0 && diff 
/ first >= 0 );
+                    }
+                };
+        },
+
+        "PSEUDO": function( pseudo, argument ) {
+            // pseudo-class names are case-insensitive
+            // http://www.w3.org/TR/selectors/#pseudo-classes
+            // Prioritize by case sensitivity in case custom pseudos are added 
with uppercase letters
+            // Remember that setFilters inherits from pseudos
+            var args,
+                fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ 
pseudo.toLowerCase() ] ||
+                    Sizzle.error( "unsupported pseudo: " + pseudo );
+
+            // The user may use createPseudo to indicate that
+            // arguments are needed to create the filter function
+            // just as Sizzle does
+            if ( fn[ expando ] ) {
+                return fn( argument );
+            }
+
+            // But maintain support for old signatures
+            if ( fn.length > 1 ) {
+                args = [ pseudo, pseudo, "", argument ];
+                return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
+                    markFunction(function( seed, matches ) {
+                        var idx,
+                            matched = fn( seed, argument ),
+                            i = matched.length;
+                        while ( i-- ) {
+                            idx = indexOf.call( seed, matched[i] );
+                            seed[ idx ] = !( matches[ idx ] = matched[i] );
+                        }
+                    }) :
+                    function( elem ) {
+                        return fn( elem, 0, args );
+                    };
+            }
+
+            return fn;
+        }
+    },
+
+    pseudos: {
+        // Potentially complex pseudos
+        "not": markFunction(function( selector ) {
+            // Trim the selector passed to compile
+            // to avoid treating leading and trailing
+            // spaces as combinators
+            var input = [],
+                results = [],
+                matcher = compile( selector.replace( rtrim, "$1" ) );
+
+            return matcher[ expando ] ?
+                markFunction(function( seed, matches, context, xml ) {
+                    var elem,
+                        unmatched = matcher( seed, null, xml, [] ),
+                        i = seed.length;
+
+                    // Match elements unmatched by `matcher`
+                    while ( i-- ) {
+                        if ( (elem = unmatched[i]) ) {
+                            seed[i] = !(matches[i] = elem);
+                        }
+                    }
+                }) :
+                function( elem, context, xml ) {
+                    input[0] = elem;
+                    matcher( input, null, xml, results );
+                    return !results.pop();
+                };
+        }),
+
+        "has": markFunction(function( selector ) {
+            return function( elem ) {
+                return Sizzle( selector, elem ).length > 0;
+            };
+        }),
+
+        "contains": markFunction(function( text ) {
+            return function( elem ) {
+                return ( elem.textContent || elem.innerText || getText( elem ) 
).indexOf( text ) > -1;
+            };
+        }),
+
+        // "Whether an element is represented by a :lang() selector
+        // is based solely on the element's language value
+        // being equal to the identifier C,
+        // or beginning with the identifier C immediately followed by "-".
+        // The matching of C against the element's language value is performed 
case-insensitively.
+        // The identifier C does not have to be a valid language name."
+        // http://www.w3.org/TR/selectors/#lang-pseudo
+        "lang": markFunction( function( lang ) {
+            // lang value must be a valid identifier
+            if ( !ridentifier.test(lang || "") ) {
+                Sizzle.error( "unsupported lang: " + lang );
+            }
+            lang = lang.replace( runescape, funescape ).toLowerCase();
+            return function( elem ) {
+                var elemLang;
+                do {
+                    if ( (elemLang = documentIsHTML ?
+                        elem.lang :
+                        elem.getAttribute("xml:lang") || 
elem.getAttribute("lang")) ) {
+
+                        elemLang = elemLang.toLowerCase();
+                        return elemLang === lang || elemLang.indexOf( lang + 
"-" ) === 0;
+                    }
+                } while ( (elem = elem.parentNode) && elem.nodeType === 1 );
+                return false;
+            };
+        }),
+
+        // Miscellaneous
+        "target": function( elem ) {
+            var hash = window.location && window.location.hash;
+            return hash && hash.slice( 1 ) === elem.id;
+        },
+
+        "root": function( elem ) {
+            return elem === docElem;
+        },
+
+        "focus": function( elem ) {
+            return elem === document.activeElement && (!document.hasFocus || 
document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
+        },
+
+        // Boolean properties
+        "enabled": function( elem ) {
+            return elem.disabled === false;
+        },
+
+        "disabled": function( elem ) {
+            return elem.disabled === true;
+        },
+
+        "checked": function( elem ) {
+            // In CSS3, :checked should return both checked and selected 
elements
+            // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
+            var nodeName = elem.nodeName.toLowerCase();
+            return (nodeName === "input" && !!elem.checked) || (nodeName === 
"option" && !!elem.selected);
+        },
+
+        "selected": function( elem ) {
+            // Accessing this property makes selected-by-default
+            // options in Safari work properly
+            if ( elem.parentNode ) {
+                elem.parentNode.selectedIndex;
+            }
+
+            return elem.selected === true;
+        },
+
+        // Contents
+        "empty": function( elem ) {
+            // http://www.w3.org/TR/selectors/#empty-pseudo
+            // :empty is only affected by element nodes and content 
nodes(including text(3), cdata(4)),
+            //   not comment, processing instructions, or others
+            // Thanks to Diego Perini for the nodeName shortcut
+            //   Greater than "@" means alpha characters (specifically not 
starting with "#" or "?")
+            for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
+                if ( elem.nodeName > "@" || elem.nodeType === 3 || 
elem.nodeType === 4 ) {
+                    return false;
+                }
+            }
+            return true;
+        },
+
+        "parent": function( elem ) {
+            return !Expr.pseudos["empty"]( elem );
+        },
+
+        // Element/input types
+        "header": function( elem ) {
+            return rheader.test( elem.nodeName );
+        },
+
+        "input": function( elem ) {
+            return rinputs.test( elem.nodeName );
+        },
+
+        "button": function( elem ) {
+            var name = elem.nodeName.toLowerCase();
+            return name === "input" && elem.type === "button" || name === 
"button";
+        },
+
+        "text": function( elem ) {
+            var attr;
+            // IE6 and 7 will map elem.type to 'text' for new HTML5 types 
(search, etc)
+            // use getAttribute instead to test this case
+            return elem.nodeName.toLowerCase() === "input" &&
+                elem.type === "text" &&
+                ( (attr = elem.getAttribute("type")) == null || 
attr.toLowerCase() === elem.type );
+        },
+
+        // Position-in-collection
+        "first": createPositionalPseudo(function() {
+            return [ 0 ];
+        }),
+
+        "last": createPositionalPseudo(function( matchIndexes, length ) {
+            return [ length - 1 ];
+        }),
+
+        "eq": createPositionalPseudo(function( matchIndexes, length, argument 
) {
+            return [ argument < 0 ? argument + length : argument ];
+        }),
+
+        "even": createPositionalPseudo(function( matchIndexes, length ) {
+            var i = 0;
+            for ( ; i < length; i += 2 ) {
+                matchIndexes.push( i );
+            }
+            return matchIndexes;
+        }),
+
+        "odd": createPositionalPseudo(function( matchIndexes, length ) {
+            var i = 1;
+            for ( ; i < length; i += 2 ) {
+                matchIndexes.push( i );
+            }
+            return matchIndexes;
+        }),
+
+        "lt": createPositionalPseudo(function( matchIndexes, length, argument 
) {
+            var i = argument < 0 ? argument + length : argument;
+            for ( ; --i >= 0; ) {
+                matchIndexes.push( i );
+            }
+            return matchIndexes;
+        }),
+
+        "gt": createPositionalPseudo(function( matchIndexes, length, argument 
) {
+            var i = argument < 0 ? argument + length : argument;
+            for ( ; ++i < length; ) {
+                matchIndexes.push( i );
+            }
+            return matchIndexes;
+        })
+    }
+};
+
+// Add button/input type pseudos
+for ( i in { radio: true, checkbox: true, file: true, password: true, image: 
true } ) {
+    Expr.pseudos[ i ] = createInputPseudo( i );
+}
+for ( i in { submit: true, reset: true } ) {
+    Expr.pseudos[ i ] = createButtonPseudo( i );
+}
+
+function tokenize( selector, parseOnly ) {
+    var matched, match, tokens, type,
+        soFar, groups, preFilters,
+        cached = tokenCache[ selector + " " ];
+
+    if ( cached ) {
+        return parseOnly ? 0 : cached.slice( 0 );
+    }
+
+    soFar = selector;
+    groups = [];
+    preFilters = Expr.preFilter;
+
+    while ( soFar ) {
+
+        // Comma and first run
+        if ( !matched || (match = rcomma.exec( soFar )) ) {
+            if ( match ) {
+                // Don't consume trailing commas as valid
+                soFar = soFar.slice( match[0].length ) || soFar;
+            }
+            groups.push( tokens = [] );
+        }
+
+        matched = false;
+
+        // Combinators
+        if ( (match = rcombinators.exec( soFar )) ) {
+            matched = match.shift();
+            tokens.push( {
+                value: matched,
+                // Cast descendant combinators to space
+                type: match[0].replace( rtrim, " " )
+            } );
+            soFar = soFar.slice( matched.length );
+        }
+
+        // Filters
+        for ( type in Expr.filter ) {
+            if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ 
type ] ||
+                (match = preFilters[ type ]( match ))) ) {
+                matched = match.shift();
+                tokens.push( {
+                    value: matched,
+                    type: type,
+                    matches: match
+                } );
+                soFar = soFar.slice( matched.length );
+            }
+        }
+
+        if ( !matched ) {
+            break;
+        }
+    }
+
+    // Return the length of the invalid excess
+    // if we're just parsing
+    // Otherwise, throw an error or return tokens
+    return parseOnly ?
+        soFar.length :
+        soFar ?
+            Sizzle.error( selector ) :
+            // Cache the tokens
+            tokenCache( selector, groups ).slice( 0 );
+}
+
+function toSelector( tokens ) {
+    var i = 0,
+        len = tokens.length,
+        selector = "";
+    for ( ; i < len; i++ ) {
+        selector += tokens[i].value;
+    }
+    return selector;
+}
+
+function addCombinator( matcher, combinator, base ) {
+    var dir = combinator.dir,
+        checkNonElements = base && dir === "parentNode",
+        doneName = done++;
+
+    return combinator.first ?
+        // Check against closest ancestor/preceding element
+        function( elem, context, xml ) {
+            while ( (elem = elem[ dir ]) ) {
+                if ( elem.nodeType === 1 || checkNonElements ) {
+                    return matcher( elem, context, xml );
+                }
+            }
+        } :
+
+        // Check against all ancestor/preceding elements
+        function( elem, context, xml ) {
+            var data, cache, outerCache,
+                dirkey = dirruns + " " + doneName;
+
+            // We can't set arbitrary data on XML nodes, so they don't benefit 
from dir caching
+            if ( xml ) {
+                while ( (elem = elem[ dir ]) ) {
+                    if ( elem.nodeType === 1 || checkNonElements ) {
+                        if ( matcher( elem, context, xml ) ) {
+                            return true;
+                        }
+                    }
+                }
+            } else {
+                while ( (elem = elem[ dir ]) ) {
+                    if ( elem.nodeType === 1 || checkNonElements ) {
+                        outerCache = elem[ expando ] || (elem[ expando ] = {});
+                        if ( (cache = outerCache[ dir ]) && cache[0] === 
dirkey ) {
+                            if ( (data = cache[1]) === true || data === 
cachedruns ) {
+                                return data === true;
+                            }
+                        } else {
+                            cache = outerCache[ dir ] = [ dirkey ];
+                            cache[1] = matcher( elem, context, xml ) || 
cachedruns;
+                            if ( cache[1] === true ) {
+                                return true;
+                            }
+                        }
+                    }
+                }
+            }
+        };
+}
+
+function elementMatcher( matchers ) {
+    return matchers.length > 1 ?
+        function( elem, context, xml ) {
+            var i = matchers.length;
+            while ( i-- ) {
+                if ( !matchers[i]( elem, context, xml ) ) {
+                    return false;
+                }
+            }
+            return true;
+        } :
+        matchers[0];
+}
+
+function condense( unmatched, map, filter, context, xml ) {
+    var elem,
+        newUnmatched = [],
+        i = 0,
+        len = unmatched.length,
+        mapped = map != null;
+
+    for ( ; i < len; i++ ) {
+        if ( (elem = unmatched[i]) ) {
+            if ( !filter || filter( elem, context, xml ) ) {
+                newUnmatched.push( elem );
+                if ( mapped ) {
+                    map.push( i );
+                }
+            }
+        }
+    }
+
+    return newUnmatched;
+}
+
+function setMatcher( preFilter, selector, matcher, postFilter, postFinder, 
postSelector ) {
+    if ( postFilter && !postFilter[ expando ] ) {
+        postFilter = setMatcher( postFilter );
+    }
+    if ( postFinder && !postFinder[ expando ] ) {
+        postFinder = setMatcher( postFinder, postSelector );
+    }
+    return markFunction(function( seed, results, context, xml ) {
+        var temp, i, elem,
+            preMap = [],
+            postMap = [],
+            preexisting = results.length,
+
+            // Get initial elements from seed or context
+            elems = seed || multipleContexts( selector || "*", 
context.nodeType ? [ context ] : context, [] ),
+
+            // Prefilter to get matcher input, preserving a map for 
seed-results synchronization
+            matcherIn = preFilter && ( seed || !selector ) ?
+                condense( elems, preMap, preFilter, context, xml ) :
+                elems,
+
+            matcherOut = matcher ?
+                // If we have a postFinder, or filtered seed, or non-seed 
postFilter or preexisting results,
+                postFinder || ( seed ? preFilter : preexisting || postFilter ) 
?
+
+                    // ...intermediate processing is necessary
+                    [] :
+
+                    // ...otherwise use results directly
+                    results :
+                matcherIn;
+
+        // Find primary matches
+        if ( matcher ) {
+            matcher( matcherIn, matcherOut, context, xml );
+        }
+
+        // Apply postFilter
+        if ( postFilter ) {
+            temp = condense( matcherOut, postMap );
+            postFilter( temp, [], context, xml );
+
+            // Un-match failing elements by moving them back to matcherIn
+            i = temp.length;
+            while ( i-- ) {
+                if ( (elem = temp[i]) ) {
+                    matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = 
elem);
+                }
+            }
+        }
+
+        if ( seed ) {
+            if ( postFinder || preFilter ) {
+                if ( postFinder ) {
+                    // Get the final matcherOut by condensing this 
intermediate into postFinder contexts
+                    temp = [];
+                    i = matcherOut.length;
+                    while ( i-- ) {
+                        if ( (elem = matcherOut[i]) ) {
+                            // Restore matcherIn since elem is not yet a final 
match
+                            temp.push( (matcherIn[i] = elem) );
+                        }
+                    }
+                    postFinder( null, (matcherOut = []), temp, xml );
+                }
+
+                // Move matched elements from seed to results to keep them 
synchronized
+                i = matcherOut.length;
+                while ( i-- ) {
+                    if ( (elem = matcherOut[i]) &&
+                        (temp = postFinder ? indexOf.call( seed, elem ) : 
preMap[i]) > -1 ) {
+
+                        seed[temp] = !(results[temp] = elem);
+                    }
+                }
+            }
+
+        // Add elements to results, through postFinder if defined
+        } else {
+            matcherOut = condense(
+                matcherOut === results ?
+                    matcherOut.splice( preexisting, matcherOut.length ) :
+                    matcherOut
+            );
+            if ( postFinder ) {
+                postFinder( null, results, matcherOut, xml );
+            } else {
+                push.apply( results, matcherOut );
+            }
+        }
+    });
+}
+
+function matcherFromTokens( tokens ) {
+    var checkContext, matcher, j,
+        len = tokens.length,
+        leadingRelative = Expr.relative[ tokens[0].type ],
+        implicitRelative = leadingRelative || Expr.relative[" "],
+        i = leadingRelative ? 1 : 0,
+
+        // The foundational matcher ensures that elements are reachable from 
top-level context(s)
+        matchContext = addCombinator( function( elem ) {
+            return elem === checkContext;
+        }, implicitRelative, true ),
+        matchAnyContext = addCombinator( function( elem ) {
+            return indexOf.call( checkContext, elem ) > -1;
+        }, implicitRelative, true ),
+        matchers = [ function( elem, context, xml ) {
+            return ( !leadingRelative && ( xml || context !== outermostContext 
) ) || (
+                (checkContext = context).nodeType ?
+                    matchContext( elem, context, xml ) :
+                    matchAnyContext( elem, context, xml ) );
+        } ];
+
+    for ( ; i < len; i++ ) {
+        if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
+            matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
+        } else {
+            matcher = Expr.filter[ tokens[i].type ].apply( null, 
tokens[i].matches );
+
+            // Return special upon seeing a positional matcher
+            if ( matcher[ expando ] ) {
+                // Find the next relative operator (if any) for proper handling
+                j = ++i;
+                for ( ; j < len; j++ ) {
+                    if ( Expr.relative[ tokens[j].type ] ) {
+                        break;
+                    }
+                }
+                return setMatcher(
+                    i > 1 && elementMatcher( matchers ),
+                    i > 1 && toSelector( tokens.slice( 0, i - 1 ) ).replace( 
rtrim, "$1" ),
+                    matcher,
+                    i < j && matcherFromTokens( tokens.slice( i, j ) ),
+                    j < len && matcherFromTokens( (tokens = tokens.slice( j )) 
),
+                    j < len && toSelector( tokens )
+                );
+            }
+            matchers.push( matcher );
+        }
+    }
+
+    return elementMatcher( matchers );
+}
+
+function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
+    // A counter to specify which element is currently being matched
+    var matcherCachedRuns = 0,
+        bySet = setMatchers.length > 0,
+        byElement = elementMatchers.length > 0,
+        superMatcher = function( seed, context, xml, results, expandContext ) {
+            var elem, j, matcher,
+                setMatched = [],
+                matchedCount = 0,
+                i = "0",
+                unmatched = seed && [],
+                outermost = expandContext != null,
+                contextBackup = outermostContext,
+                // We must always have either seed elements or context
+                elems = seed || byElement && Expr.find["TAG"]( "*", 
expandContext && context.parentNode || context ),
+                // Use integer dirruns iff this is the outermost matcher
+                dirrunsUnique = (dirruns += contextBackup == null ? 1 : 
Math.random() || 0.1);
+
+            if ( outermost ) {
+                outermostContext = context !== document && context;
+                cachedruns = matcherCachedRuns;
+            }
+
+            // Add elements passing elementMatchers directly to results
+            // Keep `i` a string if there are no elements so `matchedCount` 
will be "00" below
+            for ( ; (elem = elems[i]) != null; i++ ) {
+                if ( byElement && elem ) {
+                    j = 0;
+                    while ( (matcher = elementMatchers[j++]) ) {
+                        if ( matcher( elem, context, xml ) ) {
+                            results.push( elem );
+                            break;
+                        }
+                    }
+                    if ( outermost ) {
+                        dirruns = dirrunsUnique;

[... 6184 lines stripped ...]

Reply via email to