src/pyams_skin/resources/js/ext/tinymce/dev/classes/dom/Sizzle.js
changeset 566 a1707c607eec
parent 565 318533413200
child 567 bca1726b1d85
equal deleted inserted replaced
565:318533413200 566:a1707c607eec
     1 /**
       
     2  * Sizzle.js
       
     3  *
       
     4  * Copyright, Moxiecode Systems AB
       
     5  * Released under LGPL License.
       
     6  *
       
     7  * License: http://www.tinymce.com/license
       
     8  * Contributing: http://www.tinymce.com/contributing
       
     9  *
       
    10  * @ignore-file
       
    11  */
       
    12 
       
    13 /*jshint bitwise:false, expr:true, noempty:false, sub:true, eqnull:true, latedef:false, maxlen:255 */
       
    14 /*eslint dot-notation:0, no-empty:0, no-cond-assign:0, no-unused-expressions:0, new-cap:0 */
       
    15 /*eslint no-nested-ternary:0, func-style:0, no-bitwise:0, max-len:0, brace-style:0, no-return-assign:0, no-multi-spaces:0 */
       
    16 
       
    17 /**
       
    18  * Sizzle CSS Selector Engine v@VERSION
       
    19  * http://sizzlejs.com/
       
    20  *
       
    21  * Copyright 2008, 2014 jQuery Foundation, Inc. and other contributors
       
    22  * Released under the MIT license
       
    23  * http://jquery.org/license
       
    24  *
       
    25  * Date: @DATE
       
    26  */
       
    27 define("tinymce/dom/Sizzle", [], function() {
       
    28 var i,
       
    29 	support,
       
    30 	Expr,
       
    31 	getText,
       
    32 	isXML,
       
    33 	tokenize,
       
    34 	compile,
       
    35 	select,
       
    36 	outermostContext,
       
    37 	sortInput,
       
    38 	hasDuplicate,
       
    39 
       
    40 	// Local document vars
       
    41 	setDocument,
       
    42 	document,
       
    43 	docElem,
       
    44 	documentIsHTML,
       
    45 	rbuggyQSA,
       
    46 	rbuggyMatches,
       
    47 	matches,
       
    48 	contains,
       
    49 
       
    50 	// Instance-specific data
       
    51 	expando = "sizzle" + -(new Date()),
       
    52 	preferredDoc = window.document,
       
    53 	dirruns = 0,
       
    54 	done = 0,
       
    55 	classCache = createCache(),
       
    56 	tokenCache = createCache(),
       
    57 	compilerCache = createCache(),
       
    58 	sortOrder = function( a, b ) {
       
    59 		if ( a === b ) {
       
    60 			hasDuplicate = true;
       
    61 		}
       
    62 		return 0;
       
    63 	},
       
    64 
       
    65 	// General-purpose constants
       
    66 	strundefined = typeof undefined,
       
    67 	MAX_NEGATIVE = 1 << 31,
       
    68 
       
    69 	// Instance methods
       
    70 	hasOwn = ({}).hasOwnProperty,
       
    71 	arr = [],
       
    72 	pop = arr.pop,
       
    73 	push_native = arr.push,
       
    74 	push = arr.push,
       
    75 	slice = arr.slice,
       
    76 	// Use a stripped-down indexOf if we can't use a native one
       
    77 	indexOf = arr.indexOf || function( elem ) {
       
    78 		var i = 0,
       
    79 			len = this.length;
       
    80 		for ( ; i < len; i++ ) {
       
    81 			if ( this[i] === elem ) {
       
    82 				return i;
       
    83 			}
       
    84 		}
       
    85 		return -1;
       
    86 	},
       
    87 
       
    88 	booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
       
    89 
       
    90 	// Regular expressions
       
    91 
       
    92 	// http://www.w3.org/TR/css3-selectors/#whitespace
       
    93 	whitespace = "[\\x20\\t\\r\\n\\f]",
       
    94 
       
    95 	// http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
       
    96 	identifier = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
       
    97 
       
    98 	// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
       
    99 	attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
       
   100 		// Operator (capture 2)
       
   101 		"*([*^$|!~]?=)" + whitespace +
       
   102 		// "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
       
   103 		"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
       
   104 		"*\\]",
       
   105 
       
   106 	pseudos = ":(" + identifier + ")(?:\\((" +
       
   107 		// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
       
   108 		// 1. quoted (capture 3; capture 4 or capture 5)
       
   109 		"('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
       
   110 		// 2. simple (capture 6)
       
   111 		"((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
       
   112 		// 3. anything else (capture 2)
       
   113 		".*" +
       
   114 		")\\)|)",
       
   115 
       
   116 	// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
       
   117 	rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
       
   118 
       
   119 	rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
       
   120 	rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
       
   121 
       
   122 	rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
       
   123 
       
   124 	rpseudo = new RegExp( pseudos ),
       
   125 	ridentifier = new RegExp( "^" + identifier + "$" ),
       
   126 
       
   127 	matchExpr = {
       
   128 		"ID": new RegExp( "^#(" + identifier + ")" ),
       
   129 		"CLASS": new RegExp( "^\\.(" + identifier + ")" ),
       
   130 		"TAG": new RegExp( "^(" + identifier + "|[*])" ),
       
   131 		"ATTR": new RegExp( "^" + attributes ),
       
   132 		"PSEUDO": new RegExp( "^" + pseudos ),
       
   133 		"CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
       
   134 			"*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
       
   135 			"*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
       
   136 		"bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
       
   137 		// For use in libraries implementing .is()
       
   138 		// We use this for POS matching in `select`
       
   139 		"needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
       
   140 			whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
       
   141 	},
       
   142 
       
   143 	rinputs = /^(?:input|select|textarea|button)$/i,
       
   144 	rheader = /^h\d$/i,
       
   145 
       
   146 	rnative = /^[^{]+\{\s*\[native \w/,
       
   147 
       
   148 	// Easily-parseable/retrievable ID or TAG or CLASS selectors
       
   149 	rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
       
   150 
       
   151 	rsibling = /[+~]/,
       
   152 	rescape = /'|\\/g,
       
   153 
       
   154 	// CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
       
   155 	runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
       
   156 	funescape = function( _, escaped, escapedWhitespace ) {
       
   157 		var high = "0x" + escaped - 0x10000;
       
   158 		// NaN means non-codepoint
       
   159 		// Support: Firefox<24
       
   160 		// Workaround erroneous numeric interpretation of +"0x"
       
   161 		return high !== high || escapedWhitespace ?
       
   162 			escaped :
       
   163 			high < 0 ?
       
   164 				// BMP codepoint
       
   165 				String.fromCharCode( high + 0x10000 ) :
       
   166 				// Supplemental Plane codepoint (surrogate pair)
       
   167 				String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
       
   168 	};
       
   169 
       
   170 // Optimize for push.apply( _, NodeList )
       
   171 try {
       
   172 	push.apply(
       
   173 		(arr = slice.call( preferredDoc.childNodes )),
       
   174 		preferredDoc.childNodes
       
   175 	);
       
   176 	// Support: Android<4.0
       
   177 	// Detect silently failing push.apply
       
   178 	arr[ preferredDoc.childNodes.length ].nodeType;
       
   179 } catch ( e ) {
       
   180 	push = { apply: arr.length ?
       
   181 
       
   182 		// Leverage slice if possible
       
   183 		function( target, els ) {
       
   184 			push_native.apply( target, slice.call(els) );
       
   185 		} :
       
   186 
       
   187 		// Support: IE<9
       
   188 		// Otherwise append directly
       
   189 		function( target, els ) {
       
   190 			var j = target.length,
       
   191 				i = 0;
       
   192 			// Can't trust NodeList.length
       
   193 			while ( (target[j++] = els[i++]) ) {}
       
   194 			target.length = j - 1;
       
   195 		}
       
   196 	};
       
   197 }
       
   198 
       
   199 function Sizzle( selector, context, results, seed ) {
       
   200 	var match, elem, m, nodeType,
       
   201 		// QSA vars
       
   202 		i, groups, old, nid, newContext, newSelector;
       
   203 
       
   204 	if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
       
   205 		setDocument( context );
       
   206 	}
       
   207 
       
   208 	context = context || document;
       
   209 	results = results || [];
       
   210 
       
   211 	if ( !selector || typeof selector !== "string" ) {
       
   212 		return results;
       
   213 	}
       
   214 
       
   215 	if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) {
       
   216 		return [];
       
   217 	}
       
   218 
       
   219 	if ( documentIsHTML && !seed ) {
       
   220 
       
   221 		// Shortcuts
       
   222 		if ( (match = rquickExpr.exec( selector )) ) {
       
   223 			// Speed-up: Sizzle("#ID")
       
   224 			if ( (m = match[1]) ) {
       
   225 				if ( nodeType === 9 ) {
       
   226 					elem = context.getElementById( m );
       
   227 					// Check parentNode to catch when Blackberry 4.6 returns
       
   228 					// nodes that are no longer in the document (jQuery #6963)
       
   229 					if ( elem && elem.parentNode ) {
       
   230 						// Handle the case where IE, Opera, and Webkit return items
       
   231 						// by name instead of ID
       
   232 						if ( elem.id === m ) {
       
   233 							results.push( elem );
       
   234 							return results;
       
   235 						}
       
   236 					} else {
       
   237 						return results;
       
   238 					}
       
   239 				} else {
       
   240 					// Context is not a document
       
   241 					if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&
       
   242 						contains( context, elem ) && elem.id === m ) {
       
   243 						results.push( elem );
       
   244 						return results;
       
   245 					}
       
   246 				}
       
   247 
       
   248 			// Speed-up: Sizzle("TAG")
       
   249 			} else if ( match[2] ) {
       
   250 				push.apply( results, context.getElementsByTagName( selector ) );
       
   251 				return results;
       
   252 
       
   253 			// Speed-up: Sizzle(".CLASS")
       
   254 			} else if ( (m = match[3]) && support.getElementsByClassName ) {
       
   255 				push.apply( results, context.getElementsByClassName( m ) );
       
   256 				return results;
       
   257 			}
       
   258 		}
       
   259 
       
   260 		// QSA path
       
   261 		if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
       
   262 			nid = old = expando;
       
   263 			newContext = context;
       
   264 			newSelector = nodeType === 9 && selector;
       
   265 
       
   266 			// qSA works strangely on Element-rooted queries
       
   267 			// We can work around this by specifying an extra ID on the root
       
   268 			// and working up from there (Thanks to Andrew Dupont for the technique)
       
   269 			// IE 8 doesn't work on object elements
       
   270 			if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
       
   271 				groups = tokenize( selector );
       
   272 
       
   273 				if ( (old = context.getAttribute("id")) ) {
       
   274 					nid = old.replace( rescape, "\\$&" );
       
   275 				} else {
       
   276 					context.setAttribute( "id", nid );
       
   277 				}
       
   278 				nid = "[id='" + nid + "'] ";
       
   279 
       
   280 				i = groups.length;
       
   281 				while ( i-- ) {
       
   282 					groups[i] = nid + toSelector( groups[i] );
       
   283 				}
       
   284 				newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context;
       
   285 				newSelector = groups.join(",");
       
   286 			}
       
   287 
       
   288 			if ( newSelector ) {
       
   289 				try {
       
   290 					push.apply( results,
       
   291 						newContext.querySelectorAll( newSelector )
       
   292 					);
       
   293 					return results;
       
   294 				} catch(qsaError) {
       
   295 				} finally {
       
   296 					if ( !old ) {
       
   297 						context.removeAttribute("id");
       
   298 					}
       
   299 				}
       
   300 			}
       
   301 		}
       
   302 	}
       
   303 
       
   304 	// All others
       
   305 	return select( selector.replace( rtrim, "$1" ), context, results, seed );
       
   306 }
       
   307 
       
   308 /**
       
   309  * Create key-value caches of limited size
       
   310  * @returns {Function(string, Object)} Returns the Object data after storing it on itself with
       
   311  *	property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
       
   312  *	deleting the oldest entry
       
   313  */
       
   314 function createCache() {
       
   315 	var keys = [];
       
   316 
       
   317 	function cache( key, value ) {
       
   318 		// Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
       
   319 		if ( keys.push( key + " " ) > Expr.cacheLength ) {
       
   320 			// Only keep the most recent entries
       
   321 			delete cache[ keys.shift() ];
       
   322 		}
       
   323 		return (cache[ key + " " ] = value);
       
   324 	}
       
   325 	return cache;
       
   326 }
       
   327 
       
   328 /**
       
   329  * Mark a function for special use by Sizzle
       
   330  * @param {Function} fn The function to mark
       
   331  */
       
   332 function markFunction( fn ) {
       
   333 	fn[ expando ] = true;
       
   334 	return fn;
       
   335 }
       
   336 
       
   337 /**
       
   338  * Support testing using an element
       
   339  * @param {Function} fn Passed the created div and expects a boolean result
       
   340  */
       
   341 function assert( fn ) {
       
   342 	var div = document.createElement("div");
       
   343 
       
   344 	try {
       
   345 		return !!fn( div );
       
   346 	} catch (e) {
       
   347 		return false;
       
   348 	} finally {
       
   349 		// Remove from its parent by default
       
   350 		if ( div.parentNode ) {
       
   351 			div.parentNode.removeChild( div );
       
   352 		}
       
   353 		// release memory in IE
       
   354 		div = null;
       
   355 	}
       
   356 }
       
   357 
       
   358 /**
       
   359  * Adds the same handler for all of the specified attrs
       
   360  * @param {String} attrs Pipe-separated list of attributes
       
   361  * @param {Function} handler The method that will be applied
       
   362  */
       
   363 function addHandle( attrs, handler ) {
       
   364 	var arr = attrs.split("|"),
       
   365 		i = attrs.length;
       
   366 
       
   367 	while ( i-- ) {
       
   368 		Expr.attrHandle[ arr[i] ] = handler;
       
   369 	}
       
   370 }
       
   371 
       
   372 /**
       
   373  * Checks document order of two siblings
       
   374  * @param {Element} a
       
   375  * @param {Element} b
       
   376  * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
       
   377  */
       
   378 function siblingCheck( a, b ) {
       
   379 	var cur = b && a,
       
   380 		diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
       
   381 			( ~b.sourceIndex || MAX_NEGATIVE ) -
       
   382 			( ~a.sourceIndex || MAX_NEGATIVE );
       
   383 
       
   384 	// Use IE sourceIndex if available on both nodes
       
   385 	if ( diff ) {
       
   386 		return diff;
       
   387 	}
       
   388 
       
   389 	// Check if b follows a
       
   390 	if ( cur ) {
       
   391 		while ( (cur = cur.nextSibling) ) {
       
   392 			if ( cur === b ) {
       
   393 				return -1;
       
   394 			}
       
   395 		}
       
   396 	}
       
   397 
       
   398 	return a ? 1 : -1;
       
   399 }
       
   400 
       
   401 /**
       
   402  * Returns a function to use in pseudos for input types
       
   403  * @param {String} type
       
   404  */
       
   405 function createInputPseudo( type ) {
       
   406 	return function( elem ) {
       
   407 		var name = elem.nodeName.toLowerCase();
       
   408 		return name === "input" && elem.type === type;
       
   409 	};
       
   410 }
       
   411 
       
   412 /**
       
   413  * Returns a function to use in pseudos for buttons
       
   414  * @param {String} type
       
   415  */
       
   416 function createButtonPseudo( type ) {
       
   417 	return function( elem ) {
       
   418 		var name = elem.nodeName.toLowerCase();
       
   419 		return (name === "input" || name === "button") && elem.type === type;
       
   420 	};
       
   421 }
       
   422 
       
   423 /**
       
   424  * Returns a function to use in pseudos for positionals
       
   425  * @param {Function} fn
       
   426  */
       
   427 function createPositionalPseudo( fn ) {
       
   428 	return markFunction(function( argument ) {
       
   429 		argument = +argument;
       
   430 		return markFunction(function( seed, matches ) {
       
   431 			var j,
       
   432 				matchIndexes = fn( [], seed.length, argument ),
       
   433 				i = matchIndexes.length;
       
   434 
       
   435 			// Match elements found at the specified indexes
       
   436 			while ( i-- ) {
       
   437 				if ( seed[ (j = matchIndexes[i]) ] ) {
       
   438 					seed[j] = !(matches[j] = seed[j]);
       
   439 				}
       
   440 			}
       
   441 		});
       
   442 	});
       
   443 }
       
   444 
       
   445 /**
       
   446  * Checks a node for validity as a Sizzle context
       
   447  * @param {Element|Object=} context
       
   448  * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
       
   449  */
       
   450 function testContext( context ) {
       
   451 	return context && typeof context.getElementsByTagName !== strundefined && context;
       
   452 }
       
   453 
       
   454 // Expose support vars for convenience
       
   455 support = Sizzle.support = {};
       
   456 
       
   457 /**
       
   458  * Detects XML nodes
       
   459  * @param {Element|Object} elem An element or a document
       
   460  * @returns {Boolean} True iff elem is a non-HTML XML node
       
   461  */
       
   462 isXML = Sizzle.isXML = function( elem ) {
       
   463 	// documentElement is verified for cases where it doesn't yet exist
       
   464 	// (such as loading iframes in IE - #4833)
       
   465 	var documentElement = elem && (elem.ownerDocument || elem).documentElement;
       
   466 	return documentElement ? documentElement.nodeName !== "HTML" : false;
       
   467 };
       
   468 
       
   469 /**
       
   470  * Sets document-related variables once based on the current document
       
   471  * @param {Element|Object} [doc] An element or document object to use to set the document
       
   472  * @returns {Object} Returns the current document
       
   473  */
       
   474 setDocument = Sizzle.setDocument = function( node ) {
       
   475 	var hasCompare,
       
   476 		doc = node ? node.ownerDocument || node : preferredDoc,
       
   477 		parent = doc.defaultView;
       
   478 
       
   479 	// If no document and documentElement is available, return
       
   480 	if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
       
   481 		return document;
       
   482 	}
       
   483 
       
   484 	// Set our document
       
   485 	document = doc;
       
   486 	docElem = doc.documentElement;
       
   487 
       
   488 	// Support tests
       
   489 	documentIsHTML = !isXML( doc );
       
   490 
       
   491 	// Support: IE>8
       
   492 	// If iframe document is assigned to "document" variable and if iframe has been reloaded,
       
   493 	// IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936
       
   494 	// IE6-8 do not support the defaultView property so parent will be undefined
       
   495 	if ( parent && parent !== parent.top ) {
       
   496 		// IE11 does not have attachEvent, so all must suffer
       
   497 		if ( parent.addEventListener ) {
       
   498 			parent.addEventListener( "unload", function() {
       
   499 				setDocument();
       
   500 			}, false );
       
   501 		} else if ( parent.attachEvent ) {
       
   502 			parent.attachEvent( "onunload", function() {
       
   503 				setDocument();
       
   504 			});
       
   505 		}
       
   506 	}
       
   507 
       
   508 	/* Attributes
       
   509 	---------------------------------------------------------------------- */
       
   510 
       
   511 	// Support: IE<8
       
   512 	// Verify that getAttribute really returns attributes and not properties (excepting IE8 booleans)
       
   513 	support.attributes = assert(function( div ) {
       
   514 		div.className = "i";
       
   515 		return !div.getAttribute("className");
       
   516 	});
       
   517 
       
   518 	/* getElement(s)By*
       
   519 	---------------------------------------------------------------------- */
       
   520 
       
   521 	// Check if getElementsByTagName("*") returns only elements
       
   522 	support.getElementsByTagName = assert(function( div ) {
       
   523 		div.appendChild( doc.createComment("") );
       
   524 		return !div.getElementsByTagName("*").length;
       
   525 	});
       
   526 
       
   527 	// Support: IE<9
       
   528 	support.getElementsByClassName = rnative.test( doc.getElementsByClassName );
       
   529 
       
   530 	// Support: IE<10
       
   531 	// Check if getElementById returns elements by name
       
   532 	// The broken getElementById methods don't pick up programatically-set names,
       
   533 	// so use a roundabout getElementsByName test
       
   534 	support.getById = assert(function( div ) {
       
   535 		docElem.appendChild( div ).id = expando;
       
   536 		return !doc.getElementsByName || !doc.getElementsByName( expando ).length;
       
   537 	});
       
   538 
       
   539 	// ID find and filter
       
   540 	if ( support.getById ) {
       
   541 		Expr.find["ID"] = function( id, context ) {
       
   542 			if ( typeof context.getElementById !== strundefined && documentIsHTML ) {
       
   543 				var m = context.getElementById( id );
       
   544 				// Check parentNode to catch when Blackberry 4.6 returns
       
   545 				// nodes that are no longer in the document #6963
       
   546 				return m && m.parentNode ? [ m ] : [];
       
   547 			}
       
   548 		};
       
   549 		Expr.filter["ID"] = function( id ) {
       
   550 			var attrId = id.replace( runescape, funescape );
       
   551 			return function( elem ) {
       
   552 				return elem.getAttribute("id") === attrId;
       
   553 			};
       
   554 		};
       
   555 	} else {
       
   556 		// Support: IE6/7
       
   557 		// getElementById is not reliable as a find shortcut
       
   558 		delete Expr.find["ID"];
       
   559 
       
   560 		Expr.filter["ID"] =  function( id ) {
       
   561 			var attrId = id.replace( runescape, funescape );
       
   562 			return function( elem ) {
       
   563 				var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id");
       
   564 				return node && node.value === attrId;
       
   565 			};
       
   566 		};
       
   567 	}
       
   568 
       
   569 	// Tag
       
   570 	Expr.find["TAG"] = support.getElementsByTagName ?
       
   571 		function( tag, context ) {
       
   572 			if ( typeof context.getElementsByTagName !== strundefined ) {
       
   573 				return context.getElementsByTagName( tag );
       
   574 			}
       
   575 		} :
       
   576 		function( tag, context ) {
       
   577 			var elem,
       
   578 				tmp = [],
       
   579 				i = 0,
       
   580 				results = context.getElementsByTagName( tag );
       
   581 
       
   582 			// Filter out possible comments
       
   583 			if ( tag === "*" ) {
       
   584 				while ( (elem = results[i++]) ) {
       
   585 					if ( elem.nodeType === 1 ) {
       
   586 						tmp.push( elem );
       
   587 					}
       
   588 				}
       
   589 
       
   590 				return tmp;
       
   591 			}
       
   592 			return results;
       
   593 		};
       
   594 
       
   595 	// Class
       
   596 	Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
       
   597 		if ( documentIsHTML ) {
       
   598 			return context.getElementsByClassName( className );
       
   599 		}
       
   600 	};
       
   601 
       
   602 	/* QSA/matchesSelector
       
   603 	---------------------------------------------------------------------- */
       
   604 
       
   605 	// QSA and matchesSelector support
       
   606 
       
   607 	// matchesSelector(:active) reports false when true (IE9/Opera 11.5)
       
   608 	rbuggyMatches = [];
       
   609 
       
   610 	// qSa(:focus) reports false when true (Chrome 21)
       
   611 	// We allow this because of a bug in IE8/9 that throws an error
       
   612 	// whenever `document.activeElement` is accessed on an iframe
       
   613 	// So, we allow :focus to pass through QSA all the time to avoid the IE error
       
   614 	// See http://bugs.jquery.com/ticket/13378
       
   615 	rbuggyQSA = [];
       
   616 
       
   617 	if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) {
       
   618 		// Build QSA regex
       
   619 		// Regex strategy adopted from Diego Perini
       
   620 		assert(function( div ) {
       
   621 			// Select is set to empty string on purpose
       
   622 			// This is to test IE's treatment of not explicitly
       
   623 			// setting a boolean content attribute,
       
   624 			// since its presence should be enough
       
   625 			// http://bugs.jquery.com/ticket/12359
       
   626 			div.innerHTML = "<select msallowcapture=''><option selected=''></option></select>";
       
   627 
       
   628 			// Support: IE8, Opera 11-12.16
       
   629 			// Nothing should be selected when empty strings follow ^= or $= or *=
       
   630 			// The test attribute must be unknown in Opera but "safe" for WinRT
       
   631 			// http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
       
   632 			if ( div.querySelectorAll("[msallowcapture^='']").length ) {
       
   633 				rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
       
   634 			}
       
   635 
       
   636 			// Support: IE8
       
   637 			// Boolean attributes and "value" are not treated correctly
       
   638 			if ( !div.querySelectorAll("[selected]").length ) {
       
   639 				rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
       
   640 			}
       
   641 
       
   642 			// Webkit/Opera - :checked should return selected option elements
       
   643 			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
       
   644 			// IE8 throws error here and will not see later tests
       
   645 			if ( !div.querySelectorAll(":checked").length ) {
       
   646 				rbuggyQSA.push(":checked");
       
   647 			}
       
   648 		});
       
   649 
       
   650 		assert(function( div ) {
       
   651 			// Support: Windows 8 Native Apps
       
   652 			// The type and name attributes are restricted during .innerHTML assignment
       
   653 			var input = doc.createElement("input");
       
   654 			input.setAttribute( "type", "hidden" );
       
   655 			div.appendChild( input ).setAttribute( "name", "D" );
       
   656 
       
   657 			// Support: IE8
       
   658 			// Enforce case-sensitivity of name attribute
       
   659 			if ( div.querySelectorAll("[name=d]").length ) {
       
   660 				rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
       
   661 			}
       
   662 
       
   663 			// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
       
   664 			// IE8 throws error here and will not see later tests
       
   665 			if ( !div.querySelectorAll(":enabled").length ) {
       
   666 				rbuggyQSA.push( ":enabled", ":disabled" );
       
   667 			}
       
   668 
       
   669 			// Opera 10-11 does not throw on post-comma invalid pseudos
       
   670 			div.querySelectorAll("*,:x");
       
   671 			rbuggyQSA.push(",.*:");
       
   672 		});
       
   673 	}
       
   674 
       
   675 	if ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||
       
   676 		docElem.webkitMatchesSelector ||
       
   677 		docElem.mozMatchesSelector ||
       
   678 		docElem.oMatchesSelector ||
       
   679 		docElem.msMatchesSelector) )) ) {
       
   680 
       
   681 		assert(function( div ) {
       
   682 			// Check to see if it's possible to do matchesSelector
       
   683 			// on a disconnected node (IE 9)
       
   684 			support.disconnectedMatch = matches.call( div, "div" );
       
   685 
       
   686 			// This should fail with an exception
       
   687 			// Gecko does not error, returns false instead
       
   688 			matches.call( div, "[s!='']:x" );
       
   689 			rbuggyMatches.push( "!=", pseudos );
       
   690 		});
       
   691 	}
       
   692 
       
   693 	rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
       
   694 	rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
       
   695 
       
   696 	/* Contains
       
   697 	---------------------------------------------------------------------- */
       
   698 	hasCompare = rnative.test( docElem.compareDocumentPosition );
       
   699 
       
   700 	// Element contains another
       
   701 	// Purposefully does not implement inclusive descendent
       
   702 	// As in, an element does not contain itself
       
   703 	contains = hasCompare || rnative.test( docElem.contains ) ?
       
   704 		function( a, b ) {
       
   705 			var adown = a.nodeType === 9 ? a.documentElement : a,
       
   706 				bup = b && b.parentNode;
       
   707 			return a === bup || !!( bup && bup.nodeType === 1 && (
       
   708 				adown.contains ?
       
   709 					adown.contains( bup ) :
       
   710 					a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
       
   711 			));
       
   712 		} :
       
   713 		function( a, b ) {
       
   714 			if ( b ) {
       
   715 				while ( (b = b.parentNode) ) {
       
   716 					if ( b === a ) {
       
   717 						return true;
       
   718 					}
       
   719 				}
       
   720 			}
       
   721 			return false;
       
   722 		};
       
   723 
       
   724 	/* Sorting
       
   725 	---------------------------------------------------------------------- */
       
   726 
       
   727 	// Document order sorting
       
   728 	sortOrder = hasCompare ?
       
   729 	function( a, b ) {
       
   730 
       
   731 		// Flag for duplicate removal
       
   732 		if ( a === b ) {
       
   733 			hasDuplicate = true;
       
   734 			return 0;
       
   735 		}
       
   736 
       
   737 		// Sort on method existence if only one input has compareDocumentPosition
       
   738 		var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
       
   739 		if ( compare ) {
       
   740 			return compare;
       
   741 		}
       
   742 
       
   743 		// Calculate position if both inputs belong to the same document
       
   744 		compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
       
   745 			a.compareDocumentPosition( b ) :
       
   746 
       
   747 			// Otherwise we know they are disconnected
       
   748 			1;
       
   749 
       
   750 		// Disconnected nodes
       
   751 		if ( compare & 1 ||
       
   752 			(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
       
   753 
       
   754 			// Choose the first element that is related to our preferred document
       
   755 			if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
       
   756 				return -1;
       
   757 			}
       
   758 			if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
       
   759 				return 1;
       
   760 			}
       
   761 
       
   762 			// Maintain original order
       
   763 			return sortInput ?
       
   764 				( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
       
   765 				0;
       
   766 		}
       
   767 
       
   768 		return compare & 4 ? -1 : 1;
       
   769 	} :
       
   770 	function( a, b ) {
       
   771 		// Exit early if the nodes are identical
       
   772 		if ( a === b ) {
       
   773 			hasDuplicate = true;
       
   774 			return 0;
       
   775 		}
       
   776 
       
   777 		var cur,
       
   778 			i = 0,
       
   779 			aup = a.parentNode,
       
   780 			bup = b.parentNode,
       
   781 			ap = [ a ],
       
   782 			bp = [ b ];
       
   783 
       
   784 		// Parentless nodes are either documents or disconnected
       
   785 		if ( !aup || !bup ) {
       
   786 			return a === doc ? -1 :
       
   787 				b === doc ? 1 :
       
   788 				aup ? -1 :
       
   789 				bup ? 1 :
       
   790 				sortInput ?
       
   791 				( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
       
   792 				0;
       
   793 
       
   794 		// If the nodes are siblings, we can do a quick check
       
   795 		} else if ( aup === bup ) {
       
   796 			return siblingCheck( a, b );
       
   797 		}
       
   798 
       
   799 		// Otherwise we need full lists of their ancestors for comparison
       
   800 		cur = a;
       
   801 		while ( (cur = cur.parentNode) ) {
       
   802 			ap.unshift( cur );
       
   803 		}
       
   804 		cur = b;
       
   805 		while ( (cur = cur.parentNode) ) {
       
   806 			bp.unshift( cur );
       
   807 		}
       
   808 
       
   809 		// Walk down the tree looking for a discrepancy
       
   810 		while ( ap[i] === bp[i] ) {
       
   811 			i++;
       
   812 		}
       
   813 
       
   814 		return i ?
       
   815 			// Do a sibling check if the nodes have a common ancestor
       
   816 			siblingCheck( ap[i], bp[i] ) :
       
   817 
       
   818 			// Otherwise nodes in our document sort first
       
   819 			ap[i] === preferredDoc ? -1 :
       
   820 			bp[i] === preferredDoc ? 1 :
       
   821 			0;
       
   822 	};
       
   823 
       
   824 	return doc;
       
   825 };
       
   826 
       
   827 Sizzle.matches = function( expr, elements ) {
       
   828 	return Sizzle( expr, null, null, elements );
       
   829 };
       
   830 
       
   831 Sizzle.matchesSelector = function( elem, expr ) {
       
   832 	// Set document vars if needed
       
   833 	if ( ( elem.ownerDocument || elem ) !== document ) {
       
   834 		setDocument( elem );
       
   835 	}
       
   836 
       
   837 	// Make sure that attribute selectors are quoted
       
   838 	expr = expr.replace( rattributeQuotes, "='$1']" );
       
   839 
       
   840 	if ( support.matchesSelector && documentIsHTML &&
       
   841 		( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
       
   842 		( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {
       
   843 
       
   844 		try {
       
   845 			var ret = matches.call( elem, expr );
       
   846 
       
   847 			// IE 9's matchesSelector returns false on disconnected nodes
       
   848 			if ( ret || support.disconnectedMatch ||
       
   849 					// As well, disconnected nodes are said to be in a document
       
   850 					// fragment in IE 9
       
   851 					elem.document && elem.document.nodeType !== 11 ) {
       
   852 				return ret;
       
   853 			}
       
   854 		} catch(e) {}
       
   855 	}
       
   856 
       
   857 	return Sizzle( expr, document, null, [ elem ] ).length > 0;
       
   858 };
       
   859 
       
   860 Sizzle.contains = function( context, elem ) {
       
   861 	// Set document vars if needed
       
   862 	if ( ( context.ownerDocument || context ) !== document ) {
       
   863 		setDocument( context );
       
   864 	}
       
   865 	return contains( context, elem );
       
   866 };
       
   867 
       
   868 Sizzle.attr = function( elem, name ) {
       
   869 	// Set document vars if needed
       
   870 	if ( ( elem.ownerDocument || elem ) !== document ) {
       
   871 		setDocument( elem );
       
   872 	}
       
   873 
       
   874 	var fn = Expr.attrHandle[ name.toLowerCase() ],
       
   875 		// Don't get fooled by Object.prototype properties (jQuery #13807)
       
   876 		val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
       
   877 			fn( elem, name, !documentIsHTML ) :
       
   878 			undefined;
       
   879 
       
   880 	return val !== undefined ?
       
   881 		val :
       
   882 		support.attributes || !documentIsHTML ?
       
   883 			elem.getAttribute( name ) :
       
   884 			(val = elem.getAttributeNode(name)) && val.specified ?
       
   885 				val.value :
       
   886 				null;
       
   887 };
       
   888 
       
   889 Sizzle.error = function( msg ) {
       
   890 	throw new Error( "Syntax error, unrecognized expression: " + msg );
       
   891 };
       
   892 
       
   893 /**
       
   894  * Document sorting and removing duplicates
       
   895  * @param {ArrayLike} results
       
   896  */
       
   897 Sizzle.uniqueSort = function( results ) {
       
   898 	var elem,
       
   899 		duplicates = [],
       
   900 		j = 0,
       
   901 		i = 0;
       
   902 
       
   903 	// Unless we *know* we can detect duplicates, assume their presence
       
   904 	hasDuplicate = !support.detectDuplicates;
       
   905 	sortInput = !support.sortStable && results.slice( 0 );
       
   906 	results.sort( sortOrder );
       
   907 
       
   908 	if ( hasDuplicate ) {
       
   909 		while ( (elem = results[i++]) ) {
       
   910 			if ( elem === results[ i ] ) {
       
   911 				j = duplicates.push( i );
       
   912 			}
       
   913 		}
       
   914 		while ( j-- ) {
       
   915 			results.splice( duplicates[ j ], 1 );
       
   916 		}
       
   917 	}
       
   918 
       
   919 	// Clear input after sorting to release objects
       
   920 	// See https://github.com/jquery/sizzle/pull/225
       
   921 	sortInput = null;
       
   922 
       
   923 	return results;
       
   924 };
       
   925 
       
   926 /**
       
   927  * Utility function for retrieving the text value of an array of DOM nodes
       
   928  * @param {Array|Element} elem
       
   929  */
       
   930 getText = Sizzle.getText = function( elem ) {
       
   931 	var node,
       
   932 		ret = "",
       
   933 		i = 0,
       
   934 		nodeType = elem.nodeType;
       
   935 
       
   936 	if ( !nodeType ) {
       
   937 		// If no nodeType, this is expected to be an array
       
   938 		while ( (node = elem[i++]) ) {
       
   939 			// Do not traverse comment nodes
       
   940 			ret += getText( node );
       
   941 		}
       
   942 	} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
       
   943 		// Use textContent for elements
       
   944 		// innerText usage removed for consistency of new lines (jQuery #11153)
       
   945 		if ( typeof elem.textContent === "string" ) {
       
   946 			return elem.textContent;
       
   947 		} else {
       
   948 			// Traverse its children
       
   949 			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
       
   950 				ret += getText( elem );
       
   951 			}
       
   952 		}
       
   953 	} else if ( nodeType === 3 || nodeType === 4 ) {
       
   954 		return elem.nodeValue;
       
   955 	}
       
   956 	// Do not include comment or processing instruction nodes
       
   957 
       
   958 	return ret;
       
   959 };
       
   960 
       
   961 Expr = Sizzle.selectors = {
       
   962 
       
   963 	// Can be adjusted by the user
       
   964 	cacheLength: 50,
       
   965 
       
   966 	createPseudo: markFunction,
       
   967 
       
   968 	match: matchExpr,
       
   969 
       
   970 	attrHandle: {},
       
   971 
       
   972 	find: {},
       
   973 
       
   974 	relative: {
       
   975 		">": { dir: "parentNode", first: true },
       
   976 		" ": { dir: "parentNode" },
       
   977 		"+": { dir: "previousSibling", first: true },
       
   978 		"~": { dir: "previousSibling" }
       
   979 	},
       
   980 
       
   981 	preFilter: {
       
   982 		"ATTR": function( match ) {
       
   983 			match[1] = match[1].replace( runescape, funescape );
       
   984 
       
   985 			// Move the given value to match[3] whether quoted or unquoted
       
   986 			match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape );
       
   987 
       
   988 			if ( match[2] === "~=" ) {
       
   989 				match[3] = " " + match[3] + " ";
       
   990 			}
       
   991 
       
   992 			return match.slice( 0, 4 );
       
   993 		},
       
   994 
       
   995 		"CHILD": function( match ) {
       
   996 			/* matches from matchExpr["CHILD"]
       
   997 				1 type (only|nth|...)
       
   998 				2 what (child|of-type)
       
   999 				3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
       
  1000 				4 xn-component of xn+y argument ([+-]?\d*n|)
       
  1001 				5 sign of xn-component
       
  1002 				6 x of xn-component
       
  1003 				7 sign of y-component
       
  1004 				8 y of y-component
       
  1005 			*/
       
  1006 			match[1] = match[1].toLowerCase();
       
  1007 
       
  1008 			if ( match[1].slice( 0, 3 ) === "nth" ) {
       
  1009 				// nth-* requires argument
       
  1010 				if ( !match[3] ) {
       
  1011 					Sizzle.error( match[0] );
       
  1012 				}
       
  1013 
       
  1014 				// numeric x and y parameters for Expr.filter.CHILD
       
  1015 				// remember that false/true cast respectively to 0/1
       
  1016 				match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
       
  1017 				match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
       
  1018 
       
  1019 			// other types prohibit arguments
       
  1020 			} else if ( match[3] ) {
       
  1021 				Sizzle.error( match[0] );
       
  1022 			}
       
  1023 
       
  1024 			return match;
       
  1025 		},
       
  1026 
       
  1027 		"PSEUDO": function( match ) {
       
  1028 			var excess,
       
  1029 				unquoted = !match[6] && match[2];
       
  1030 
       
  1031 			if ( matchExpr["CHILD"].test( match[0] ) ) {
       
  1032 				return null;
       
  1033 			}
       
  1034 
       
  1035 			// Accept quoted arguments as-is
       
  1036 			if ( match[3] ) {
       
  1037 				match[2] = match[4] || match[5] || "";
       
  1038 
       
  1039 			// Strip excess characters from unquoted arguments
       
  1040 			} else if ( unquoted && rpseudo.test( unquoted ) &&
       
  1041 				// Get excess from tokenize (recursively)
       
  1042 				(excess = tokenize( unquoted, true )) &&
       
  1043 				// advance to the next closing parenthesis
       
  1044 				(excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
       
  1045 
       
  1046 				// excess is a negative index
       
  1047 				match[0] = match[0].slice( 0, excess );
       
  1048 				match[2] = unquoted.slice( 0, excess );
       
  1049 			}
       
  1050 
       
  1051 			// Return only captures needed by the pseudo filter method (type and argument)
       
  1052 			return match.slice( 0, 3 );
       
  1053 		}
       
  1054 	},
       
  1055 
       
  1056 	filter: {
       
  1057 
       
  1058 		"TAG": function( nodeNameSelector ) {
       
  1059 			var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
       
  1060 			return nodeNameSelector === "*" ?
       
  1061 				function() { return true; } :
       
  1062 				function( elem ) {
       
  1063 					return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
       
  1064 				};
       
  1065 		},
       
  1066 
       
  1067 		"CLASS": function( className ) {
       
  1068 			var pattern = classCache[ className + " " ];
       
  1069 
       
  1070 			return pattern ||
       
  1071 				(pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
       
  1072 				classCache( className, function( elem ) {
       
  1073 					return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute("class") || "" );
       
  1074 				});
       
  1075 		},
       
  1076 
       
  1077 		"ATTR": function( name, operator, check ) {
       
  1078 			return function( elem ) {
       
  1079 				var result = Sizzle.attr( elem, name );
       
  1080 
       
  1081 				if ( result == null ) {
       
  1082 					return operator === "!=";
       
  1083 				}
       
  1084 				if ( !operator ) {
       
  1085 					return true;
       
  1086 				}
       
  1087 
       
  1088 				result += "";
       
  1089 
       
  1090 				return operator === "=" ? result === check :
       
  1091 					operator === "!=" ? result !== check :
       
  1092 					operator === "^=" ? check && result.indexOf( check ) === 0 :
       
  1093 					operator === "*=" ? check && result.indexOf( check ) > -1 :
       
  1094 					operator === "$=" ? check && result.slice( -check.length ) === check :
       
  1095 					operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 :
       
  1096 					operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
       
  1097 					false;
       
  1098 			};
       
  1099 		},
       
  1100 
       
  1101 		"CHILD": function( type, what, argument, first, last ) {
       
  1102 			var simple = type.slice( 0, 3 ) !== "nth",
       
  1103 				forward = type.slice( -4 ) !== "last",
       
  1104 				ofType = what === "of-type";
       
  1105 
       
  1106 			return first === 1 && last === 0 ?
       
  1107 
       
  1108 				// Shortcut for :nth-*(n)
       
  1109 				function( elem ) {
       
  1110 					return !!elem.parentNode;
       
  1111 				} :
       
  1112 
       
  1113 				function( elem, context, xml ) {
       
  1114 					var cache, outerCache, node, diff, nodeIndex, start,
       
  1115 						dir = simple !== forward ? "nextSibling" : "previousSibling",
       
  1116 						parent = elem.parentNode,
       
  1117 						name = ofType && elem.nodeName.toLowerCase(),
       
  1118 						useCache = !xml && !ofType;
       
  1119 
       
  1120 					if ( parent ) {
       
  1121 
       
  1122 						// :(first|last|only)-(child|of-type)
       
  1123 						if ( simple ) {
       
  1124 							while ( dir ) {
       
  1125 								node = elem;
       
  1126 								while ( (node = node[ dir ]) ) {
       
  1127 									if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {
       
  1128 										return false;
       
  1129 									}
       
  1130 								}
       
  1131 								// Reverse direction for :only-* (if we haven't yet done so)
       
  1132 								start = dir = type === "only" && !start && "nextSibling";
       
  1133 							}
       
  1134 							return true;
       
  1135 						}
       
  1136 
       
  1137 						start = [ forward ? parent.firstChild : parent.lastChild ];
       
  1138 
       
  1139 						// non-xml :nth-child(...) stores cache data on `parent`
       
  1140 						if ( forward && useCache ) {
       
  1141 							// Seek `elem` from a previously-cached index
       
  1142 							outerCache = parent[ expando ] || (parent[ expando ] = {});
       
  1143 							cache = outerCache[ type ] || [];
       
  1144 							nodeIndex = cache[0] === dirruns && cache[1];
       
  1145 							diff = cache[0] === dirruns && cache[2];
       
  1146 							node = nodeIndex && parent.childNodes[ nodeIndex ];
       
  1147 
       
  1148 							while ( (node = ++nodeIndex && node && node[ dir ] ||
       
  1149 
       
  1150 								// Fallback to seeking `elem` from the start
       
  1151 								(diff = nodeIndex = 0) || start.pop()) ) {
       
  1152 
       
  1153 								// When found, cache indexes on `parent` and break
       
  1154 								if ( node.nodeType === 1 && ++diff && node === elem ) {
       
  1155 									outerCache[ type ] = [ dirruns, nodeIndex, diff ];
       
  1156 									break;
       
  1157 								}
       
  1158 							}
       
  1159 
       
  1160 						// Use previously-cached element index if available
       
  1161 						} else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) {
       
  1162 							diff = cache[1];
       
  1163 
       
  1164 						// xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...)
       
  1165 						} else {
       
  1166 							// Use the same loop as above to seek `elem` from the start
       
  1167 							while ( (node = ++nodeIndex && node && node[ dir ] ||
       
  1168 								(diff = nodeIndex = 0) || start.pop()) ) {
       
  1169 
       
  1170 								if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) {
       
  1171 									// Cache the index of each encountered element
       
  1172 									if ( useCache ) {
       
  1173 										(node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];
       
  1174 									}
       
  1175 
       
  1176 									if ( node === elem ) {
       
  1177 										break;
       
  1178 									}
       
  1179 								}
       
  1180 							}
       
  1181 						}
       
  1182 
       
  1183 						// Incorporate the offset, then check against cycle size
       
  1184 						diff -= last;
       
  1185 						return diff === first || ( diff % first === 0 && diff / first >= 0 );
       
  1186 					}
       
  1187 				};
       
  1188 		},
       
  1189 
       
  1190 		"PSEUDO": function( pseudo, argument ) {
       
  1191 			// pseudo-class names are case-insensitive
       
  1192 			// http://www.w3.org/TR/selectors/#pseudo-classes
       
  1193 			// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
       
  1194 			// Remember that setFilters inherits from pseudos
       
  1195 			var args,
       
  1196 				fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
       
  1197 					Sizzle.error( "unsupported pseudo: " + pseudo );
       
  1198 
       
  1199 			// The user may use createPseudo to indicate that
       
  1200 			// arguments are needed to create the filter function
       
  1201 			// just as Sizzle does
       
  1202 			if ( fn[ expando ] ) {
       
  1203 				return fn( argument );
       
  1204 			}
       
  1205 
       
  1206 			// But maintain support for old signatures
       
  1207 			if ( fn.length > 1 ) {
       
  1208 				args = [ pseudo, pseudo, "", argument ];
       
  1209 				return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
       
  1210 					markFunction(function( seed, matches ) {
       
  1211 						var idx,
       
  1212 							matched = fn( seed, argument ),
       
  1213 							i = matched.length;
       
  1214 						while ( i-- ) {
       
  1215 							idx = indexOf.call( seed, matched[i] );
       
  1216 							seed[ idx ] = !( matches[ idx ] = matched[i] );
       
  1217 						}
       
  1218 					}) :
       
  1219 					function( elem ) {
       
  1220 						return fn( elem, 0, args );
       
  1221 					};
       
  1222 			}
       
  1223 
       
  1224 			return fn;
       
  1225 		}
       
  1226 	},
       
  1227 
       
  1228 	pseudos: {
       
  1229 		// Potentially complex pseudos
       
  1230 		"not": markFunction(function( selector ) {
       
  1231 			// Trim the selector passed to compile
       
  1232 			// to avoid treating leading and trailing
       
  1233 			// spaces as combinators
       
  1234 			var input = [],
       
  1235 				results = [],
       
  1236 				matcher = compile( selector.replace( rtrim, "$1" ) );
       
  1237 
       
  1238 			return matcher[ expando ] ?
       
  1239 				markFunction(function( seed, matches, context, xml ) {
       
  1240 					var elem,
       
  1241 						unmatched = matcher( seed, null, xml, [] ),
       
  1242 						i = seed.length;
       
  1243 
       
  1244 					// Match elements unmatched by `matcher`
       
  1245 					while ( i-- ) {
       
  1246 						if ( (elem = unmatched[i]) ) {
       
  1247 							seed[i] = !(matches[i] = elem);
       
  1248 						}
       
  1249 					}
       
  1250 				}) :
       
  1251 				function( elem, context, xml ) {
       
  1252 					input[0] = elem;
       
  1253 					matcher( input, null, xml, results );
       
  1254 					return !results.pop();
       
  1255 				};
       
  1256 		}),
       
  1257 
       
  1258 		"has": markFunction(function( selector ) {
       
  1259 			return function( elem ) {
       
  1260 				return Sizzle( selector, elem ).length > 0;
       
  1261 			};
       
  1262 		}),
       
  1263 
       
  1264 		"contains": markFunction(function( text ) {
       
  1265 			text = text.replace( runescape, funescape );
       
  1266 			return function( elem ) {
       
  1267 				return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
       
  1268 			};
       
  1269 		}),
       
  1270 
       
  1271 		// "Whether an element is represented by a :lang() selector
       
  1272 		// is based solely on the element's language value
       
  1273 		// being equal to the identifier C,
       
  1274 		// or beginning with the identifier C immediately followed by "-".
       
  1275 		// The matching of C against the element's language value is performed case-insensitively.
       
  1276 		// The identifier C does not have to be a valid language name."
       
  1277 		// http://www.w3.org/TR/selectors/#lang-pseudo
       
  1278 		"lang": markFunction( function( lang ) {
       
  1279 			// lang value must be a valid identifier
       
  1280 			if ( !ridentifier.test(lang || "") ) {
       
  1281 				Sizzle.error( "unsupported lang: " + lang );
       
  1282 			}
       
  1283 			lang = lang.replace( runescape, funescape ).toLowerCase();
       
  1284 			return function( elem ) {
       
  1285 				var elemLang;
       
  1286 				do {
       
  1287 					if ( (elemLang = documentIsHTML ?
       
  1288 						elem.lang :
       
  1289 						elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
       
  1290 
       
  1291 						elemLang = elemLang.toLowerCase();
       
  1292 						return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
       
  1293 					}
       
  1294 				} while ( (elem = elem.parentNode) && elem.nodeType === 1 );
       
  1295 				return false;
       
  1296 			};
       
  1297 		}),
       
  1298 
       
  1299 		// Miscellaneous
       
  1300 		"target": function( elem ) {
       
  1301 			var hash = window.location && window.location.hash;
       
  1302 			return hash && hash.slice( 1 ) === elem.id;
       
  1303 		},
       
  1304 
       
  1305 		"root": function( elem ) {
       
  1306 			return elem === docElem;
       
  1307 		},
       
  1308 
       
  1309 		"focus": function( elem ) {
       
  1310 			return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
       
  1311 		},
       
  1312 
       
  1313 		// Boolean properties
       
  1314 		"enabled": function( elem ) {
       
  1315 			return elem.disabled === false;
       
  1316 		},
       
  1317 
       
  1318 		"disabled": function( elem ) {
       
  1319 			return elem.disabled === true;
       
  1320 		},
       
  1321 
       
  1322 		"checked": function( elem ) {
       
  1323 			// In CSS3, :checked should return both checked and selected elements
       
  1324 			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
       
  1325 			var nodeName = elem.nodeName.toLowerCase();
       
  1326 			return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
       
  1327 		},
       
  1328 
       
  1329 		"selected": function( elem ) {
       
  1330 			// Accessing this property makes selected-by-default
       
  1331 			// options in Safari work properly
       
  1332 			if ( elem.parentNode ) {
       
  1333 				elem.parentNode.selectedIndex;
       
  1334 			}
       
  1335 
       
  1336 			return elem.selected === true;
       
  1337 		},
       
  1338 
       
  1339 		// Contents
       
  1340 		"empty": function( elem ) {
       
  1341 			// http://www.w3.org/TR/selectors/#empty-pseudo
       
  1342 			// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
       
  1343 			//   but not by others (comment: 8; processing instruction: 7; etc.)
       
  1344 			// nodeType < 6 works because attributes (2) do not appear as children
       
  1345 			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
       
  1346 				if ( elem.nodeType < 6 ) {
       
  1347 					return false;
       
  1348 				}
       
  1349 			}
       
  1350 			return true;
       
  1351 		},
       
  1352 
       
  1353 		"parent": function( elem ) {
       
  1354 			return !Expr.pseudos["empty"]( elem );
       
  1355 		},
       
  1356 
       
  1357 		// Element/input types
       
  1358 		"header": function( elem ) {
       
  1359 			return rheader.test( elem.nodeName );
       
  1360 		},
       
  1361 
       
  1362 		"input": function( elem ) {
       
  1363 			return rinputs.test( elem.nodeName );
       
  1364 		},
       
  1365 
       
  1366 		"button": function( elem ) {
       
  1367 			var name = elem.nodeName.toLowerCase();
       
  1368 			return name === "input" && elem.type === "button" || name === "button";
       
  1369 		},
       
  1370 
       
  1371 		"text": function( elem ) {
       
  1372 			var attr;
       
  1373 			return elem.nodeName.toLowerCase() === "input" &&
       
  1374 				elem.type === "text" &&
       
  1375 
       
  1376 				// Support: IE<8
       
  1377 				// New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
       
  1378 				( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
       
  1379 		},
       
  1380 
       
  1381 		// Position-in-collection
       
  1382 		"first": createPositionalPseudo(function() {
       
  1383 			return [ 0 ];
       
  1384 		}),
       
  1385 
       
  1386 		"last": createPositionalPseudo(function( matchIndexes, length ) {
       
  1387 			return [ length - 1 ];
       
  1388 		}),
       
  1389 
       
  1390 		"eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
       
  1391 			return [ argument < 0 ? argument + length : argument ];
       
  1392 		}),
       
  1393 
       
  1394 		"even": createPositionalPseudo(function( matchIndexes, length ) {
       
  1395 			var i = 0;
       
  1396 			for ( ; i < length; i += 2 ) {
       
  1397 				matchIndexes.push( i );
       
  1398 			}
       
  1399 			return matchIndexes;
       
  1400 		}),
       
  1401 
       
  1402 		"odd": createPositionalPseudo(function( matchIndexes, length ) {
       
  1403 			var i = 1;
       
  1404 			for ( ; i < length; i += 2 ) {
       
  1405 				matchIndexes.push( i );
       
  1406 			}
       
  1407 			return matchIndexes;
       
  1408 		}),
       
  1409 
       
  1410 		"lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
       
  1411 			var i = argument < 0 ? argument + length : argument;
       
  1412 			for ( ; --i >= 0; ) {
       
  1413 				matchIndexes.push( i );
       
  1414 			}
       
  1415 			return matchIndexes;
       
  1416 		}),
       
  1417 
       
  1418 		"gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
       
  1419 			var i = argument < 0 ? argument + length : argument;
       
  1420 			for ( ; ++i < length; ) {
       
  1421 				matchIndexes.push( i );
       
  1422 			}
       
  1423 			return matchIndexes;
       
  1424 		})
       
  1425 	}
       
  1426 };
       
  1427 
       
  1428 Expr.pseudos["nth"] = Expr.pseudos["eq"];
       
  1429 
       
  1430 // Add button/input type pseudos
       
  1431 for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
       
  1432 	Expr.pseudos[ i ] = createInputPseudo( i );
       
  1433 }
       
  1434 for ( i in { submit: true, reset: true } ) {
       
  1435 	Expr.pseudos[ i ] = createButtonPseudo( i );
       
  1436 }
       
  1437 
       
  1438 // Easy API for creating new setFilters
       
  1439 function setFilters() {}
       
  1440 setFilters.prototype = Expr.filters = Expr.pseudos;
       
  1441 Expr.setFilters = new setFilters();
       
  1442 
       
  1443 tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
       
  1444 	var matched, match, tokens, type,
       
  1445 		soFar, groups, preFilters,
       
  1446 		cached = tokenCache[ selector + " " ];
       
  1447 
       
  1448 	if ( cached ) {
       
  1449 		return parseOnly ? 0 : cached.slice( 0 );
       
  1450 	}
       
  1451 
       
  1452 	soFar = selector;
       
  1453 	groups = [];
       
  1454 	preFilters = Expr.preFilter;
       
  1455 
       
  1456 	while ( soFar ) {
       
  1457 
       
  1458 		// Comma and first run
       
  1459 		if ( !matched || (match = rcomma.exec( soFar )) ) {
       
  1460 			if ( match ) {
       
  1461 				// Don't consume trailing commas as valid
       
  1462 				soFar = soFar.slice( match[0].length ) || soFar;
       
  1463 			}
       
  1464 			groups.push( (tokens = []) );
       
  1465 		}
       
  1466 
       
  1467 		matched = false;
       
  1468 
       
  1469 		// Combinators
       
  1470 		if ( (match = rcombinators.exec( soFar )) ) {
       
  1471 			matched = match.shift();
       
  1472 			tokens.push({
       
  1473 				value: matched,
       
  1474 				// Cast descendant combinators to space
       
  1475 				type: match[0].replace( rtrim, " " )
       
  1476 			});
       
  1477 			soFar = soFar.slice( matched.length );
       
  1478 		}
       
  1479 
       
  1480 		// Filters
       
  1481 		for ( type in Expr.filter ) {
       
  1482 			if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
       
  1483 				(match = preFilters[ type ]( match ))) ) {
       
  1484 				matched = match.shift();
       
  1485 				tokens.push({
       
  1486 					value: matched,
       
  1487 					type: type,
       
  1488 					matches: match
       
  1489 				});
       
  1490 				soFar = soFar.slice( matched.length );
       
  1491 			}
       
  1492 		}
       
  1493 
       
  1494 		if ( !matched ) {
       
  1495 			break;
       
  1496 		}
       
  1497 	}
       
  1498 
       
  1499 	// Return the length of the invalid excess
       
  1500 	// if we're just parsing
       
  1501 	// Otherwise, throw an error or return tokens
       
  1502 	return parseOnly ?
       
  1503 		soFar.length :
       
  1504 		soFar ?
       
  1505 			Sizzle.error( selector ) :
       
  1506 			// Cache the tokens
       
  1507 			tokenCache( selector, groups ).slice( 0 );
       
  1508 };
       
  1509 
       
  1510 function toSelector( tokens ) {
       
  1511 	var i = 0,
       
  1512 		len = tokens.length,
       
  1513 		selector = "";
       
  1514 	for ( ; i < len; i++ ) {
       
  1515 		selector += tokens[i].value;
       
  1516 	}
       
  1517 	return selector;
       
  1518 }
       
  1519 
       
  1520 function addCombinator( matcher, combinator, base ) {
       
  1521 	var dir = combinator.dir,
       
  1522 		checkNonElements = base && dir === "parentNode",
       
  1523 		doneName = done++;
       
  1524 
       
  1525 	return combinator.first ?
       
  1526 		// Check against closest ancestor/preceding element
       
  1527 		function( elem, context, xml ) {
       
  1528 			while ( (elem = elem[ dir ]) ) {
       
  1529 				if ( elem.nodeType === 1 || checkNonElements ) {
       
  1530 					return matcher( elem, context, xml );
       
  1531 				}
       
  1532 			}
       
  1533 		} :
       
  1534 
       
  1535 		// Check against all ancestor/preceding elements
       
  1536 		function( elem, context, xml ) {
       
  1537 			var oldCache, outerCache,
       
  1538 				newCache = [ dirruns, doneName ];
       
  1539 
       
  1540 			// We can't set arbitrary data on XML nodes, so they don't benefit from dir caching
       
  1541 			if ( xml ) {
       
  1542 				while ( (elem = elem[ dir ]) ) {
       
  1543 					if ( elem.nodeType === 1 || checkNonElements ) {
       
  1544 						if ( matcher( elem, context, xml ) ) {
       
  1545 							return true;
       
  1546 						}
       
  1547 					}
       
  1548 				}
       
  1549 			} else {
       
  1550 				while ( (elem = elem[ dir ]) ) {
       
  1551 					if ( elem.nodeType === 1 || checkNonElements ) {
       
  1552 						outerCache = elem[ expando ] || (elem[ expando ] = {});
       
  1553 						if ( (oldCache = outerCache[ dir ]) &&
       
  1554 							oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
       
  1555 
       
  1556 							// Assign to newCache so results back-propagate to previous elements
       
  1557 							return (newCache[ 2 ] = oldCache[ 2 ]);
       
  1558 						} else {
       
  1559 							// Reuse newcache so results back-propagate to previous elements
       
  1560 							outerCache[ dir ] = newCache;
       
  1561 
       
  1562 							// A match means we're done; a fail means we have to keep checking
       
  1563 							if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
       
  1564 								return true;
       
  1565 							}
       
  1566 						}
       
  1567 					}
       
  1568 				}
       
  1569 			}
       
  1570 		};
       
  1571 }
       
  1572 
       
  1573 function elementMatcher( matchers ) {
       
  1574 	return matchers.length > 1 ?
       
  1575 		function( elem, context, xml ) {
       
  1576 			var i = matchers.length;
       
  1577 			while ( i-- ) {
       
  1578 				if ( !matchers[i]( elem, context, xml ) ) {
       
  1579 					return false;
       
  1580 				}
       
  1581 			}
       
  1582 			return true;
       
  1583 		} :
       
  1584 		matchers[0];
       
  1585 }
       
  1586 
       
  1587 function multipleContexts( selector, contexts, results ) {
       
  1588 	var i = 0,
       
  1589 		len = contexts.length;
       
  1590 	for ( ; i < len; i++ ) {
       
  1591 		Sizzle( selector, contexts[i], results );
       
  1592 	}
       
  1593 	return results;
       
  1594 }
       
  1595 
       
  1596 function condense( unmatched, map, filter, context, xml ) {
       
  1597 	var elem,
       
  1598 		newUnmatched = [],
       
  1599 		i = 0,
       
  1600 		len = unmatched.length,
       
  1601 		mapped = map != null;
       
  1602 
       
  1603 	for ( ; i < len; i++ ) {
       
  1604 		if ( (elem = unmatched[i]) ) {
       
  1605 			if ( !filter || filter( elem, context, xml ) ) {
       
  1606 				newUnmatched.push( elem );
       
  1607 				if ( mapped ) {
       
  1608 					map.push( i );
       
  1609 				}
       
  1610 			}
       
  1611 		}
       
  1612 	}
       
  1613 
       
  1614 	return newUnmatched;
       
  1615 }
       
  1616 
       
  1617 function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
       
  1618 	if ( postFilter && !postFilter[ expando ] ) {
       
  1619 		postFilter = setMatcher( postFilter );
       
  1620 	}
       
  1621 	if ( postFinder && !postFinder[ expando ] ) {
       
  1622 		postFinder = setMatcher( postFinder, postSelector );
       
  1623 	}
       
  1624 	return markFunction(function( seed, results, context, xml ) {
       
  1625 		var temp, i, elem,
       
  1626 			preMap = [],
       
  1627 			postMap = [],
       
  1628 			preexisting = results.length,
       
  1629 
       
  1630 			// Get initial elements from seed or context
       
  1631 			elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
       
  1632 
       
  1633 			// Prefilter to get matcher input, preserving a map for seed-results synchronization
       
  1634 			matcherIn = preFilter && ( seed || !selector ) ?
       
  1635 				condense( elems, preMap, preFilter, context, xml ) :
       
  1636 				elems,
       
  1637 
       
  1638 			matcherOut = matcher ?
       
  1639 				// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
       
  1640 				postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
       
  1641 
       
  1642 					// ...intermediate processing is necessary
       
  1643 					[] :
       
  1644 
       
  1645 					// ...otherwise use results directly
       
  1646 					results :
       
  1647 				matcherIn;
       
  1648 
       
  1649 		// Find primary matches
       
  1650 		if ( matcher ) {
       
  1651 			matcher( matcherIn, matcherOut, context, xml );
       
  1652 		}
       
  1653 
       
  1654 		// Apply postFilter
       
  1655 		if ( postFilter ) {
       
  1656 			temp = condense( matcherOut, postMap );
       
  1657 			postFilter( temp, [], context, xml );
       
  1658 
       
  1659 			// Un-match failing elements by moving them back to matcherIn
       
  1660 			i = temp.length;
       
  1661 			while ( i-- ) {
       
  1662 				if ( (elem = temp[i]) ) {
       
  1663 					matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
       
  1664 				}
       
  1665 			}
       
  1666 		}
       
  1667 
       
  1668 		if ( seed ) {
       
  1669 			if ( postFinder || preFilter ) {
       
  1670 				if ( postFinder ) {
       
  1671 					// Get the final matcherOut by condensing this intermediate into postFinder contexts
       
  1672 					temp = [];
       
  1673 					i = matcherOut.length;
       
  1674 					while ( i-- ) {
       
  1675 						if ( (elem = matcherOut[i]) ) {
       
  1676 							// Restore matcherIn since elem is not yet a final match
       
  1677 							temp.push( (matcherIn[i] = elem) );
       
  1678 						}
       
  1679 					}
       
  1680 					postFinder( null, (matcherOut = []), temp, xml );
       
  1681 				}
       
  1682 
       
  1683 				// Move matched elements from seed to results to keep them synchronized
       
  1684 				i = matcherOut.length;
       
  1685 				while ( i-- ) {
       
  1686 					if ( (elem = matcherOut[i]) &&
       
  1687 						(temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) {
       
  1688 
       
  1689 						seed[temp] = !(results[temp] = elem);
       
  1690 					}
       
  1691 				}
       
  1692 			}
       
  1693 
       
  1694 		// Add elements to results, through postFinder if defined
       
  1695 		} else {
       
  1696 			matcherOut = condense(
       
  1697 				matcherOut === results ?
       
  1698 					matcherOut.splice( preexisting, matcherOut.length ) :
       
  1699 					matcherOut
       
  1700 			);
       
  1701 			if ( postFinder ) {
       
  1702 				postFinder( null, results, matcherOut, xml );
       
  1703 			} else {
       
  1704 				push.apply( results, matcherOut );
       
  1705 			}
       
  1706 		}
       
  1707 	});
       
  1708 }
       
  1709 
       
  1710 function matcherFromTokens( tokens ) {
       
  1711 	var checkContext, matcher, j,
       
  1712 		len = tokens.length,
       
  1713 		leadingRelative = Expr.relative[ tokens[0].type ],
       
  1714 		implicitRelative = leadingRelative || Expr.relative[" "],
       
  1715 		i = leadingRelative ? 1 : 0,
       
  1716 
       
  1717 		// The foundational matcher ensures that elements are reachable from top-level context(s)
       
  1718 		matchContext = addCombinator( function( elem ) {
       
  1719 			return elem === checkContext;
       
  1720 		}, implicitRelative, true ),
       
  1721 		matchAnyContext = addCombinator( function( elem ) {
       
  1722 			return indexOf.call( checkContext, elem ) > -1;
       
  1723 		}, implicitRelative, true ),
       
  1724 		matchers = [ function( elem, context, xml ) {
       
  1725 			return ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
       
  1726 				(checkContext = context).nodeType ?
       
  1727 					matchContext( elem, context, xml ) :
       
  1728 					matchAnyContext( elem, context, xml ) );
       
  1729 		} ];
       
  1730 
       
  1731 	for ( ; i < len; i++ ) {
       
  1732 		if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
       
  1733 			matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
       
  1734 		} else {
       
  1735 			matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
       
  1736 
       
  1737 			// Return special upon seeing a positional matcher
       
  1738 			if ( matcher[ expando ] ) {
       
  1739 				// Find the next relative operator (if any) for proper handling
       
  1740 				j = ++i;
       
  1741 				for ( ; j < len; j++ ) {
       
  1742 					if ( Expr.relative[ tokens[j].type ] ) {
       
  1743 						break;
       
  1744 					}
       
  1745 				}
       
  1746 				return setMatcher(
       
  1747 					i > 1 && elementMatcher( matchers ),
       
  1748 					i > 1 && toSelector(
       
  1749 						// If the preceding token was a descendant combinator, insert an implicit any-element `*`
       
  1750 						tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
       
  1751 					).replace( rtrim, "$1" ),
       
  1752 					matcher,
       
  1753 					i < j && matcherFromTokens( tokens.slice( i, j ) ),
       
  1754 					j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
       
  1755 					j < len && toSelector( tokens )
       
  1756 				);
       
  1757 			}
       
  1758 			matchers.push( matcher );
       
  1759 		}
       
  1760 	}
       
  1761 
       
  1762 	return elementMatcher( matchers );
       
  1763 }
       
  1764 
       
  1765 function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
       
  1766 	var bySet = setMatchers.length > 0,
       
  1767 		byElement = elementMatchers.length > 0,
       
  1768 		superMatcher = function( seed, context, xml, results, outermost ) {
       
  1769 			var elem, j, matcher,
       
  1770 				matchedCount = 0,
       
  1771 				i = "0",
       
  1772 				unmatched = seed && [],
       
  1773 				setMatched = [],
       
  1774 				contextBackup = outermostContext,
       
  1775 				// We must always have either seed elements or outermost context
       
  1776 				elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
       
  1777 				// Use integer dirruns iff this is the outermost matcher
       
  1778 				dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
       
  1779 				len = elems.length;
       
  1780 
       
  1781 			if ( outermost ) {
       
  1782 				outermostContext = context !== document && context;
       
  1783 			}
       
  1784 
       
  1785 			// Add elements passing elementMatchers directly to results
       
  1786 			// Keep `i` a string if there are no elements so `matchedCount` will be "00" below
       
  1787 			// Support: IE<9, Safari
       
  1788 			// Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
       
  1789 			for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
       
  1790 				if ( byElement && elem ) {
       
  1791 					j = 0;
       
  1792 					while ( (matcher = elementMatchers[j++]) ) {
       
  1793 						if ( matcher( elem, context, xml ) ) {
       
  1794 							results.push( elem );
       
  1795 							break;
       
  1796 						}
       
  1797 					}
       
  1798 					if ( outermost ) {
       
  1799 						dirruns = dirrunsUnique;
       
  1800 					}
       
  1801 				}
       
  1802 
       
  1803 				// Track unmatched elements for set filters
       
  1804 				if ( bySet ) {
       
  1805 					// They will have gone through all possible matchers
       
  1806 					if ( (elem = !matcher && elem) ) {
       
  1807 						matchedCount--;
       
  1808 					}
       
  1809 
       
  1810 					// Lengthen the array for every element, matched or not
       
  1811 					if ( seed ) {
       
  1812 						unmatched.push( elem );
       
  1813 					}
       
  1814 				}
       
  1815 			}
       
  1816 
       
  1817 			// Apply set filters to unmatched elements
       
  1818 			matchedCount += i;
       
  1819 			if ( bySet && i !== matchedCount ) {
       
  1820 				j = 0;
       
  1821 				while ( (matcher = setMatchers[j++]) ) {
       
  1822 					matcher( unmatched, setMatched, context, xml );
       
  1823 				}
       
  1824 
       
  1825 				if ( seed ) {
       
  1826 					// Reintegrate element matches to eliminate the need for sorting
       
  1827 					if ( matchedCount > 0 ) {
       
  1828 						while ( i-- ) {
       
  1829 							if ( !(unmatched[i] || setMatched[i]) ) {
       
  1830 								setMatched[i] = pop.call( results );
       
  1831 							}
       
  1832 						}
       
  1833 					}
       
  1834 
       
  1835 					// Discard index placeholder values to get only actual matches
       
  1836 					setMatched = condense( setMatched );
       
  1837 				}
       
  1838 
       
  1839 				// Add matches to results
       
  1840 				push.apply( results, setMatched );
       
  1841 
       
  1842 				// Seedless set matches succeeding multiple successful matchers stipulate sorting
       
  1843 				if ( outermost && !seed && setMatched.length > 0 &&
       
  1844 					( matchedCount + setMatchers.length ) > 1 ) {
       
  1845 
       
  1846 					Sizzle.uniqueSort( results );
       
  1847 				}
       
  1848 			}
       
  1849 
       
  1850 			// Override manipulation of globals by nested matchers
       
  1851 			if ( outermost ) {
       
  1852 				dirruns = dirrunsUnique;
       
  1853 				outermostContext = contextBackup;
       
  1854 			}
       
  1855 
       
  1856 			return unmatched;
       
  1857 		};
       
  1858 
       
  1859 	return bySet ?
       
  1860 		markFunction( superMatcher ) :
       
  1861 		superMatcher;
       
  1862 }
       
  1863 
       
  1864 compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
       
  1865 	var i,
       
  1866 		setMatchers = [],
       
  1867 		elementMatchers = [],
       
  1868 		cached = compilerCache[ selector + " " ];
       
  1869 
       
  1870 	if ( !cached ) {
       
  1871 		// Generate a function of recursive functions that can be used to check each element
       
  1872 		if ( !match ) {
       
  1873 			match = tokenize( selector );
       
  1874 		}
       
  1875 		i = match.length;
       
  1876 		while ( i-- ) {
       
  1877 			cached = matcherFromTokens( match[i] );
       
  1878 			if ( cached[ expando ] ) {
       
  1879 				setMatchers.push( cached );
       
  1880 			} else {
       
  1881 				elementMatchers.push( cached );
       
  1882 			}
       
  1883 		}
       
  1884 
       
  1885 		// Cache the compiled function
       
  1886 		cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
       
  1887 
       
  1888 		// Save selector and tokenization
       
  1889 		cached.selector = selector;
       
  1890 	}
       
  1891 	return cached;
       
  1892 };
       
  1893 
       
  1894 /**
       
  1895  * A low-level selection function that works with Sizzle's compiled
       
  1896  *  selector functions
       
  1897  * @param {String|Function} selector A selector or a pre-compiled
       
  1898  *  selector function built with Sizzle.compile
       
  1899  * @param {Element} context
       
  1900  * @param {Array} [results]
       
  1901  * @param {Array} [seed] A set of elements to match against
       
  1902  */
       
  1903 select = Sizzle.select = function( selector, context, results, seed ) {
       
  1904 	var i, tokens, token, type, find,
       
  1905 		compiled = typeof selector === "function" && selector,
       
  1906 		match = !seed && tokenize( (selector = compiled.selector || selector) );
       
  1907 
       
  1908 	results = results || [];
       
  1909 
       
  1910 	// Try to minimize operations if there is no seed and only one group
       
  1911 	if ( match.length === 1 ) {
       
  1912 
       
  1913 		// Take a shortcut and set the context if the root selector is an ID
       
  1914 		tokens = match[0] = match[0].slice( 0 );
       
  1915 		if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
       
  1916 				support.getById && context.nodeType === 9 && documentIsHTML &&
       
  1917 				Expr.relative[ tokens[1].type ] ) {
       
  1918 
       
  1919 			context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
       
  1920 			if ( !context ) {
       
  1921 				return results;
       
  1922 
       
  1923 			// Precompiled matchers will still verify ancestry, so step up a level
       
  1924 			} else if ( compiled ) {
       
  1925 				context = context.parentNode;
       
  1926 			}
       
  1927 
       
  1928 			selector = selector.slice( tokens.shift().value.length );
       
  1929 		}
       
  1930 
       
  1931 		// Fetch a seed set for right-to-left matching
       
  1932 		i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
       
  1933 		while ( i-- ) {
       
  1934 			token = tokens[i];
       
  1935 
       
  1936 			// Abort if we hit a combinator
       
  1937 			if ( Expr.relative[ (type = token.type) ] ) {
       
  1938 				break;
       
  1939 			}
       
  1940 			if ( (find = Expr.find[ type ]) ) {
       
  1941 				// Search, expanding context for leading sibling combinators
       
  1942 				if ( (seed = find(
       
  1943 					token.matches[0].replace( runescape, funescape ),
       
  1944 					rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
       
  1945 				)) ) {
       
  1946 
       
  1947 					// If seed is empty or no tokens remain, we can return early
       
  1948 					tokens.splice( i, 1 );
       
  1949 					selector = seed.length && toSelector( tokens );
       
  1950 					if ( !selector ) {
       
  1951 						push.apply( results, seed );
       
  1952 						return results;
       
  1953 					}
       
  1954 
       
  1955 					break;
       
  1956 				}
       
  1957 			}
       
  1958 		}
       
  1959 	}
       
  1960 
       
  1961 	// Compile and execute a filtering function if one is not provided
       
  1962 	// Provide `match` to avoid retokenization if we modified the selector above
       
  1963 	( compiled || compile( selector, match ) )(
       
  1964 		seed,
       
  1965 		context,
       
  1966 		!documentIsHTML,
       
  1967 		results,
       
  1968 		rsibling.test( selector ) && testContext( context.parentNode ) || context
       
  1969 	);
       
  1970 	return results;
       
  1971 };
       
  1972 
       
  1973 // One-time assignments
       
  1974 
       
  1975 // Sort stability
       
  1976 support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
       
  1977 
       
  1978 // Support: Chrome 14-35+
       
  1979 // Always assume duplicates if they aren't passed to the comparison function
       
  1980 support.detectDuplicates = !!hasDuplicate;
       
  1981 
       
  1982 // Initialize against the default document
       
  1983 setDocument();
       
  1984 
       
  1985 // Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
       
  1986 // Detached nodes confoundingly follow *each other*
       
  1987 support.sortDetached = assert(function( div1 ) {
       
  1988 	// Should return 1, but returns 4 (following)
       
  1989 	return div1.compareDocumentPosition( document.createElement("div") ) & 1;
       
  1990 });
       
  1991 
       
  1992 // Support: IE<8
       
  1993 // Prevent attribute/property "interpolation"
       
  1994 // http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
       
  1995 if ( !assert(function( div ) {
       
  1996 	div.innerHTML = "<a href='#'></a>";
       
  1997 	return div.firstChild.getAttribute("href") === "#" ;
       
  1998 }) ) {
       
  1999 	addHandle( "type|href|height|width", function( elem, name, isXML ) {
       
  2000 		if ( !isXML ) {
       
  2001 			return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
       
  2002 		}
       
  2003 	});
       
  2004 }
       
  2005 
       
  2006 // Support: IE<9
       
  2007 // Use defaultValue in place of getAttribute("value")
       
  2008 if ( !support.attributes || !assert(function( div ) {
       
  2009 	div.innerHTML = "<input/>";
       
  2010 	div.firstChild.setAttribute( "value", "" );
       
  2011 	return div.firstChild.getAttribute( "value" ) === "";
       
  2012 }) ) {
       
  2013 	addHandle( "value", function( elem, name, isXML ) {
       
  2014 		if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
       
  2015 			return elem.defaultValue;
       
  2016 		}
       
  2017 	});
       
  2018 }
       
  2019 
       
  2020 // Support: IE<9
       
  2021 // Use getAttributeNode to fetch booleans when getAttribute lies
       
  2022 if ( !assert(function( div ) {
       
  2023 	return div.getAttribute("disabled") == null;
       
  2024 }) ) {
       
  2025 	addHandle( booleans, function( elem, name, isXML ) {
       
  2026 		var val;
       
  2027 		if ( !isXML ) {
       
  2028 			return elem[ name ] === true ? name.toLowerCase() :
       
  2029 					(val = elem.getAttributeNode( name )) && val.specified ?
       
  2030 					val.value :
       
  2031 				null;
       
  2032 		}
       
  2033 	});
       
  2034 }
       
  2035 
       
  2036 // EXPOSE
       
  2037 return Sizzle;
       
  2038 });