PageSourceSearch

http://www.bmmotel.com/js/lightbox-plus-jquery.js

js bmmotel.com collected 2026-10-08 02:51:11 UTC 275,819 bytes, 9,734 lines download raw bytes

vendor: 39,106 bytes, lines 1-1393
1/*!
2 * jQuery JavaScript Library v2.1.4
3 * http://jquery.com/
4 *
5 * Includes Sizzle.js
6 * http://sizzlejs.com/
7 *
8 * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors
9 * Released under the MIT license
10 * http://jquery.org/license
11 *
12 * Date: 2015-04-28T16:01Z
13 */
14
15(function( global, factory ) {
16
17	if ( typeof module === "object" && typeof module.exports === "object" ) {
18		// For CommonJS and CommonJS-like environments where a proper `window`
19		// is present, execute the factory and get jQuery.
20		// For environments that do not have a `window` with a `document`
21		// (such as Node.js), expose a factory as module.exports.
22		// This accentuates the need for the creation of a real `window`.
23		// e.g. var jQuery = require("jquery")(window);
24		// See ticket #14549 for more info.
25		module.exports = global.document ?
26			factory( global, true ) :
27			function( w ) {
28				if ( !w.document ) {
29					throw new Error( "jQuery requires a window with a document" );
30				}
31				return factory( w );
32			};
33	} else {
34		factory( global );
35	}
36
37// Pass this if window is not defined yet
38}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
39
40// Support: Firefox 18+
41// Can't be in strict mode, several libs including ASP.NET trace
42// the stack via arguments.caller.callee and Firefox dies if
43// you try to trace through "use strict" call chains. (#13335)
44//
45
46var arr = [];
47
48var slice = arr.slice;
49
50var concat = arr.concat;
51
52var push = arr.push;
53
54var indexOf = arr.indexOf;
55
56var class2type = {};
57
58var toString = class2type.toString;
59
60var hasOwn = class2type.hasOwnProperty;
61
62var support = {};
63
64
65
66var
67	// Use the correct document accordingly with window argument (sandbox)
68	document = window.document,
69
70	version = "2.1.4",
71
72	// Define a local copy of jQuery
73	jQuery = function( selector, context ) {
74		// The jQuery object is actually just the init constructor 'enhanced'
75		// Need init if jQuery is called (just allow error to be thrown if not included)
76		return new jQuery.fn.init( selector, context );
77	},
78
79	// Support: Android<4.1
80	// Make sure we trim BOM and NBSP
81	rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
82
83	// Matches dashed string for camelizing
84	rmsPrefix = /^-ms-/,
85	rdashAlpha = /-([\da-z])/gi,
86
87	// Used by jQuery.camelCase as callback to replace()
88	fcamelCase = function( all, letter ) {
89		return letter.toUpperCase();
90	};
91
92jQuery.fn = jQuery.prototype = {
93	// The current version of jQuery being used
94	jquery: version,
95
96	constructor: jQuery,
97
98	// Start with an empty selector
99	selector: "",
100
101	// The default length of a jQuery object is 0
102	length: 0,
103
104	toArray: function() {
105		return slice.call( this );
106	},
107
108	// Get the Nth element in the matched element set OR
109	// Get the whole matched element set as a clean array
110	get: function( num ) {
111		return num != null ?
112
113			// Return just the one element from the set
114			( num < 0 ? this[ num + this.length ] : this[ num ] ) :
115
116			// Return all the elements in a clean array
117			slice.call( this );
118	},
119
120	// Take an array of elements and push it onto the stack
121	// (returning the new matched element set)
122	pushStack: function( elems ) {
123
124		// Build a new jQuery matched element set
125		var ret = jQuery.merge( this.constructor(), elems );
126
127		// Add the old object onto the stack (as a reference)
128		ret.prevObject = this;
129		ret.context = this.context;
130
131		// Return the newly-formed element set
132		return ret;
133	},
134
135	// Execute a callback for every element in the matched set.
136	// (You can seed the arguments with an array of args, but this is
137	// only used internally.)
138	each: function( callback, args ) {
139		return jQuery.each( this, callback, args );
140	},
141
142	map: function( callback ) {
143		return this.pushStack( jQuery.map(this, function( elem, i ) {
144			return callback.call( elem, i, elem );
145		}));
146	},
147
148	slice: function() {
149		return this.pushStack( slice.apply( this, arguments ) );
150	},
151
152	first: function() {
153		return this.eq( 0 );
154	},
155
156	last: function() {
157		return this.eq( -1 );
158	},
159
160	eq: function( i ) {
161		var len = this.length,
162			j = +i + ( i < 0 ? len : 0 );
163		return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );
164	},
165
166	end: function() {
167		return this.prevObject || this.constructor(null);
168	},
169
170	// For internal use only.
171	// Behaves like an Array's method, not like a jQuery method.
172	push: push,
173	sort: arr.sort,
174	splice: arr.splice
175};
176
177jQuery.extend = jQuery.fn.extend = function() {
178	var options, name, src, copy, copyIsArray, clone,
179		target = arguments[0] || {},
180		i = 1,
181		length = arguments.length,
182		deep = false;
183
184	// Handle a deep copy situation
185	if ( typeof target === "boolean" ) {
186		deep = target;
187
188		// Skip the boolean and the target
189		target = arguments[ i ] || {};
190		i++;
191	}
192
193	// Handle case when target is a string or something (possible in deep copy)
194	if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
195		target = {};
196	}
197
198	// Extend jQuery itself if only one argument is passed
199	if ( i === length ) {
200		target = this;
201		i--;
202	}
203
204	for ( ; i < length; i++ ) {
205		// Only deal with non-null/undefined values
206		if ( (options = arguments[ i ]) != null ) {
207			// Extend the base object
208			for ( name in options ) {
209				src = target[ name ];
210				copy = options[ name ];
211
212				// Prevent never-ending loop
213				if ( target === copy ) {
214					continue;
215				}
216
217				// Recurse if we're merging plain objects or arrays
218				if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
219					if ( copyIsArray ) {
220						copyIsArray = false;
221						clone = src && jQuery.isArray(src) ? src : [];
222
223					} else {
224						clone = src && jQuery.isPlainObject(src) ? src : {};
225					}
226
227					// Never move original objects, clone them
228					target[ name ] = jQuery.extend( deep, clone, copy );
229
230				// Don't bring in undefined values
231				} else if ( copy !== undefined ) {
232					target[ name ] = copy;
233				}
234			}
235		}
236	}
237
238	// Return the modified object
239	return target;
240};
241
242jQuery.extend({
243	// Unique for each copy of jQuery on the page
244	expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
245
246	// Assume jQuery is ready without the ready module
247	isReady: true,
248
249	error: function( msg ) {
250		throw new Error( msg );
251	},
252
253	noop: function() {},
254
255	isFunction: function( obj ) {
256		return jQuery.type(obj) === "function";
257	},
258
259	isArray: Array.isArray,
260
261	isWindow: function( obj ) {
262		return obj != null && obj === obj.window;
263	},
264
265	isNumeric: function( obj ) {
266		// parseFloat NaNs numeric-cast false positives (null|true|false|"")
267		// ...but misinterprets leading-number strings, particularly hex literals ("0x...")
268		// subtraction forces infinities to NaN
269		// adding 1 corrects loss of precision from parseFloat (#15100)
270		return !jQuery.isArray( obj ) && (obj - parseFloat( obj ) + 1) >= 0;
271	},
272
273	isPlainObject: function( obj ) {
274		// Not plain objects:
275		// - Any object or value whose internal [[Class]] property is not "[object Object]"
276		// - DOM nodes
277		// - window
278		if ( jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
279			return false;
280		}
281
282		if ( obj.constructor &&
283				!hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) {
284			return false;
285		}
286
287		// If the function hasn't returned already, we're confident that
288		// |obj| is a plain object, created by {} or constructed with new Object
289		return true;
290	},
291
292	isEmptyObject: function( obj ) {
293		var name;
294		for ( name in obj ) {
295			return false;
296		}
297		return true;
298	},
299
300	type: function( obj ) {
301		if ( obj == null ) {
302			return obj + "";
303		}
304		// Support: Android<4.0, iOS<6 (functionish RegExp)
305		return typeof obj === "object" || typeof obj === "function" ?
306			class2type[ toString.call(obj) ] || "object" :
307			typeof obj;
308	},
309
310	// Evaluates a script in a global context
311	globalEval: function( code ) {
312		var script,
313			indirect = eval;
314
315		code = jQuery.trim( code );
316
317		if ( code ) {
318			// If the code includes a valid, prologue position
319			// strict mode pragma, execute code by injecting a
320			// script tag into the document.
321			if ( code.indexOf("use strict") === 1 ) {
322				script = document.createElement("script");
323				script.text = code;
324				document.head.appendChild( script ).parentNode.removeChild( script );
325			} else {
326			// Otherwise, avoid the DOM node creation, insertion
327			// and removal by using an indirect global eval
328				indirect( code );
329			}
330		}
331	},
332
333	// Convert dashed to camelCase; used by the css and data modules
334	// Support: IE9-11+
335	// Microsoft forgot to hump their vendor prefix (#9572)
336	camelCase: function( string ) {
337		return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
338	},
339
340	nodeName: function( elem, name ) {
341		return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
342	},
343
344	// args is for internal usage only
345	each: function( obj, callback, args ) {
346		var value,
347			i = 0,
348			length = obj.length,
349			isArray = isArraylike( obj );
350
351		if ( args ) {
352			if ( isArray ) {
353				for ( ; i < length; i++ ) {
354					value = callback.apply( obj[ i ], args );
355
356					if ( value === false ) {
357						break;
358					}
359				}
360			} else {
361				for ( i in obj ) {
362					value = callback.apply( obj[ i ], args );
363
364					if ( value === false ) {
365						break;
366					}
367				}
368			}
369
370		// A special, fast, case for the most common use of each
371		} else {
372			if ( isArray ) {
373				for ( ; i < length; i++ ) {
374					value = callback.call( obj[ i ], i, obj[ i ] );
375
376					if ( value === false ) {
377						break;
378					}
379				}
380			} else {
381				for ( i in obj ) {
382					value = callback.call( obj[ i ], i, obj[ i ] );
383
384					if ( value === false ) {
385						break;
386					}
387				}
388			}
389		}
390
391		return obj;
392	},
393
394	// Support: Android<4.1
395	trim: function( text ) {
396		return text == null ?
397			"" :
398			( text + "" ).replace( rtrim, "" );
399	},
400
401	// results is for internal usage only
402	makeArray: function( arr, results ) {
403		var ret = results || [];
404
405		if ( arr != null ) {
406			if ( isArraylike( Object(arr) ) ) {
407				jQuery.merge( ret,
408					typeof arr === "string" ?
409					[ arr ] : arr
410				);
411			} else {
412				push.call( ret, arr );
413			}
414		}
415
416		return ret;
417	},
418
419	inArray: function( elem, arr, i ) {
420		return arr == null ? -1 : indexOf.call( arr, elem, i );
421	},
422
423	merge: function( first, second ) {
424		var len = +second.length,
425			j = 0,
426			i = first.length;
427
428		for ( ; j < len; j++ ) {
429			first[ i++ ] = second[ j ];
430		}
431
432		first.length = i;
433
434		return first;
435	},
436
437	grep: function( elems, callback, invert ) {
438		var callbackInverse,
439			matches = [],
440			i = 0,
441			length = elems.length,
442			callbackExpect = !invert;
443
444		// Go through the array, only saving the items
445		// that pass the validator function
446		for ( ; i < length; i++ ) {
447			callbackInverse = !callback( elems[ i ], i );
448			if ( callbackInverse !== callbackExpect ) {
449				matches.push( elems[ i ] );
450			}
451		}
452
453		return matches;
454	},
455
456	// arg is for internal usage only
457	map: function( elems, callback, arg ) {
458		var value,
459			i = 0,
460			length = elems.length,
461			isArray = isArraylike( elems ),
462			ret = [];
463
464		// Go through the array, translating each of the items to their new values
465		if ( isArray ) {
466			for ( ; i < length; i++ ) {
467				value = callback( elems[ i ], i, arg );
468
469				if ( value != null ) {
470					ret.push( value );
471				}
472			}
473
474		// Go through every key on the object,
475		} else {
476			for ( i in elems ) {
477				value = callback( elems[ i ], i, arg );
478
479				if ( value != null ) {
480					ret.push( value );
481				}
482			}
483		}
484
485		// Flatten any nested arrays
486		return concat.apply( [], ret );
487	},
488
489	// A global GUID counter for objects
490	guid: 1,
491
492	// Bind a function to a context, optionally partially applying any
493	// arguments.
494	proxy: function( fn, context ) {
495		var tmp, args, proxy;
496
497		if ( typeof context === "string" ) {
498			tmp = fn[ context ];
499			context = fn;
500			fn = tmp;
501		}
502
503		// Quick check to determine if target is callable, in the spec
504		// this throws a TypeError, but we will just return undefined.
505		if ( !jQuery.isFunction( fn ) ) {
506			return undefined;
507		}
508
509		// Simulated bind
510		args = slice.call( arguments, 2 );
511		proxy = function() {
512			return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
513		};
514
515		// Set the guid of unique handler to the same of original handler, so it can be removed
516		proxy.guid = fn.guid = fn.guid || jQuery.guid++;
517
518		return proxy;
519	},
520
521	now: Date.now,
522
523	// jQuery.support is not used in Core but other projects attach their
524	// properties to it so it needs to exist.
525	support: support
526});
527
528// Populate the class2type map
529jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {
530	class2type[ "[object " + name + "]" ] = name.toLowerCase();
531});
532
533function isArraylike( obj ) {
534
535	// Support: iOS 8.2 (not reproducible in simulator)
536	// `in` check used to prevent JIT error (gh-2145)
537	// hasOwn isn't used here due to false negatives
538	// regarding Nodelist length in IE
539	var length = "length" in obj && obj.length,
540		type = jQuery.type( obj );
541
542	if ( type === "function" || jQuery.isWindow( obj ) ) {
543		return false;
544	}
545
546	if ( obj.nodeType === 1 && length ) {
547		return true;
548	}
549
550	return type === "array" || length === 0 ||
551		typeof length === "number" && length > 0 && ( length - 1 ) in obj;
552}
553var Sizzle =
554/*!
555 * Sizzle CSS Selector Engine v2.2.0-pre
556 * http://sizzlejs.com/
557 *
558 * Copyright 2008, 2014 jQuery Foundation, Inc. and other contributors
559 * Released under the MIT license
560 * http://jquery.org/license
561 *
562 * Date: 2014-12-16
563 */
564(function( window ) {
565
566var i,
567	support,
568	Expr,
569	getText,
570	isXML,
571	tokenize,
572	compile,
573	select,
574	outermostContext,
575	sortInput,
576	hasDuplicate,
577
578	// Local document vars
579	setDocument,
580	document,
581	docElem,
582	documentIsHTML,
583	rbuggyQSA,
584	rbuggyMatches,
585	matches,
586	contains,
587
588	// Instance-specific data
589	expando = "sizzle" + 1 * new Date(),
590	preferredDoc = window.document,
591	dirruns = 0,
592	done = 0,
593	classCache = createCache(),
594	tokenCache = createCache(),
595	compilerCache = createCache(),
596	sortOrder = function( a, b ) {
597		if ( a === b ) {
598			hasDuplicate = true;
599		}
600		return 0;
601	},
602
603	// General-purpose constants
604	MAX_NEGATIVE = 1 << 31,
605
606	// Instance methods
607	hasOwn = ({}).hasOwnProperty,
608	arr = [],
609	pop = arr.pop,
610	push_native = arr.push,
611	push = arr.push,
612	slice = arr.slice,
613	// Use a stripped-down indexOf as it's faster than native
614	// http://jsperf.com/thor-indexof-vs-for/5
615	indexOf = function( list, elem ) {
616		var i = 0,
617			len = list.length;
618		for ( ; i < len; i++ ) {
619			if ( list[i] === elem ) {
620				return i;
621			}
622		}
623		return -1;
624	},
625
626	booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
627
628	// Regular expressions
629
630	// Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace
631	whitespace = "[\\x20\\t\\r\\n\\f]",
632	// http://www.w3.org/TR/css3-syntax/#characters
633	characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
634
635	// Loosely modeled on CSS identifier characters
636	// An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors
637	// Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
638	identifier = characterEncoding.replace( "w", "w#" ),
639
640	// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
641	attributes = "\\[" + whitespace + "*(" + characterEncoding + ")(?:" + whitespace +
642		// Operator (capture 2)
643		"*([*^$|!~]?=)" + whitespace +
644		// "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
645		"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
646		"*\\]",
647
648	pseudos = ":(" + characterEncoding + ")(?:\\((" +
649		// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
650		// 1. quoted (capture 3; capture 4 or capture 5)
651		"('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
652		// 2. simple (capture 6)
653		"((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
654		// 3. anything else (capture 2)
655		".*" +
656		")\\)|)",
657
658	// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
659	rwhitespace = new RegExp( whitespace + "+", "g" ),
660	rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
661
662	rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
663	rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
664
665	rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
666
667	rpseudo = new RegExp( pseudos ),
668	ridentifier = new RegExp( "^" + identifier + "$" ),
669
670	matchExpr = {
671		"ID": new RegExp( "^#(" + characterEncoding + ")" ),
672		"CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ),
673		"TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ),
674		"ATTR": new RegExp( "^" + attributes ),
675		"PSEUDO": new RegExp( "^" + pseudos ),
676		"CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
677			"*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
678			"*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
679		"bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
680		// For use in libraries implementing .is()
681		// We use this for POS matching in `select`
682		"needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
683			whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
684	},
685
686	rinputs = /^(?:input|select|textarea|button)$/i,
687	rheader = /^h\d$/i,
688
689	rnative = /^[^{]+\{\s*\[native \w/,
690
691	// Easily-parseable/retrievable ID or TAG or CLASS selectors
692	rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
693
694	rsibling = /[+~]/,
695	rescape = /'|\\/g,
696
697	// CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
698	runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
699	funescape = function( _, escaped, escapedWhitespace ) {
700		var high = "0x" + escaped - 0x10000;
701		// NaN means non-codepoint
702		// Support: Firefox<24
703		// Workaround erroneous numeric interpretation of +"0x"
704		return high !== high || escapedWhitespace ?
705			escaped :
706			high < 0 ?
707				// BMP codepoint
708				String.fromCharCode( high + 0x10000 ) :
709				// Supplemental Plane codepoint (surrogate pair)
710				String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
711	},
712
713	// Used for iframes
714	// See setDocument()
715	// Removing the function wrapper causes a "Permission Denied"
716	// error in IE
717	unloadHandler = function() {
718		setDocument();
719	};
720
721// Optimize for push.apply( _, NodeList )
722try {
723	push.apply(
724		(arr = slice.call( preferredDoc.childNodes )),
725		preferredDoc.childNodes
726	);
727	// Support: Android<4.0
728	// Detect silently failing push.apply
729	arr[ preferredDoc.childNodes.length ].nodeType;
730} catch ( e ) {
731	push = { apply: arr.length ?
732
733		// Leverage slice if possible
734		function( target, els ) {
735			push_native.apply( target, slice.call(els) );
736		} :
737
738		// Support: IE<9
739		// Otherwise append directly
740		function( target, els ) {
741			var j = target.length,
742				i = 0;
743			// Can't trust NodeList.length
744			while ( (target[j++] = els[i++]) ) {}
745			target.length = j - 1;
746		}
747	};
748}
749
750function Sizzle( selector, context, results, seed ) {
751	var match, elem, m, nodeType,
752		// QSA vars
753		i, groups, old, nid, newContext, newSelector;
754
755	if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
756		setDocument( context );
757	}
758
759	context = context || document;
760	results = results || [];
761	nodeType = context.nodeType;
762
763	if ( typeof selector !== "string" || !selector ||
764		nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
765
766		return results;
767	}
768
769	if ( !seed && documentIsHTML ) {
770
771		// Try to shortcut find operations when possible (e.g., not under DocumentFragment)
772		if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {
773			// Speed-up: Sizzle("#ID")
774			if ( (m = match[1]) ) {
775				if ( nodeType === 9 ) {
776					elem = context.getElementById( m );
777					// Check parentNode to catch when Blackberry 4.6 returns
778					// nodes that are no longer in the document (jQuery #6963)
779					if ( elem && elem.parentNode ) {
780						// Handle the case where IE, Opera, and Webkit return items
781						// by name instead of ID
782						if ( elem.id === m ) {
783							results.push( elem );
784							return results;
785						}
786					} else {
787						return results;
788					}
789				} else {
790					// Context is not a document
791					if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&
792						contains( context, elem ) && elem.id === m ) {
793						results.push( elem );
794						return results;
795					}
796				}
797
798			// Speed-up: Sizzle("TAG")
799			} else if ( match[2] ) {
800				push.apply( results, context.getElementsByTagName( selector ) );
801				return results;
802
803			// Speed-up: Sizzle(".CLASS")
804			} else if ( (m = match[3]) && support.getElementsByClassName ) {
805				push.apply( results, context.getElementsByClassName( m ) );
806				return results;
807			}
808		}
809
810		// QSA path
811		if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
812			nid = old = expando;
813			newContext = context;
814			newSelector = nodeType !== 1 && selector;
815
816			// qSA works strangely on Element-rooted queries
817			// We can work around this by specifying an extra ID on the root
818			// and working up from there (Thanks to Andrew Dupont for the technique)
819			// IE 8 doesn't work on object elements
820			if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
821				groups = tokenize( selector );
822
823				if ( (old = context.getAttribute("id")) ) {
824					nid = old.replace( rescape, "\\$&" );
825				} else {
826					context.setAttribute( "id", nid );
827				}
828				nid = "[id='" + nid + "'] ";
829
830				i = groups.length;
831				while ( i-- ) {
832					groups[i] = nid + toSelector( groups[i] );
833				}
834				newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context;
835				newSelector = groups.join(",");
836			}
837
838			if ( newSelector ) {
839				try {
840					push.apply( results,
841						newContext.querySelectorAll( newSelector )
842					);
843					return results;
844				} catch(qsaError) {
845				} finally {
846					if ( !old ) {
847						context.removeAttribute("id");
848					}
849				}
850			}
851		}
852	}
853
854	// All others
855	return select( selector.replace( rtrim, "$1" ), context, results, seed );
856}
857
858/**
859 * Create key-value caches of limited size
860 * @returns {Function(string, Object)} Returns the Object data after storing it on itself with
861 *	property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
862 *	deleting the oldest entry
863 */
864function createCache() {
865	var keys = [];
866
867	function cache( key, value ) {
868		// Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
869		if ( keys.push( key + " " ) > Expr.cacheLength ) {
870			// Only keep the most recent entries
871			delete cache[ keys.shift() ];
872		}
873		return (cache[ key + " " ] = value);
874	}
875	return cache;
876}
877
878/**
879 * Mark a function for special use by Sizzle
880 * @param {Function} fn The function to mark
881 */
882function markFunction( fn ) {
883	fn[ expando ] = true;
884	return fn;
885}
886
887/**
888 * Support testing using an element
889 * @param {Function} fn Passed the created div and expects a boolean result
890 */
891function assert( fn ) {
892	var div = document.createElement("div");
893
894	try {
895		return !!fn( div );
896	} catch (e) {
897		return false;
898	} finally {
899		// Remove from its parent by default
900		if ( div.parentNode ) {
901			div.parentNode.removeChild( div );
902		}
903		// release memory in IE
904		div = null;
905	}
906}
907
908/**
909 * Adds the same handler for all of the specified attrs
910 * @param {String} attrs Pipe-separated list of attributes
911 * @param {Function} handler The method that will be applied
912 */
913function addHandle( attrs, handler ) {
914	var arr = attrs.split("|"),
915		i = attrs.length;
916
917	while ( i-- ) {
918		Expr.attrHandle[ arr[i] ] = handler;
919	}
920}
921
922/**
923 * Checks document order of two siblings
924 * @param {Element} a
925 * @param {Element} b
926 * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
927 */
928function siblingCheck( a, b ) {
929	var cur = b && a,
930		diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
931			( ~b.sourceIndex || MAX_NEGATIVE ) -
932			( ~a.sourceIndex || MAX_NEGATIVE );
933
934	// Use IE sourceIndex if available on both nodes
935	if ( diff ) {
936		return diff;
937	}
938
939	// Check if b follows a
940	if ( cur ) {
941		while ( (cur = cur.nextSibling) ) {
942			if ( cur === b ) {
943				return -1;
944			}
945		}
946	}
947
948	return a ? 1 : -1;
949}
950
951/**
952 * Returns a function to use in pseudos for input types
953 * @param {String} type
954 */
955function createInputPseudo( type ) {
956	return function( elem ) {
957		var name = elem.nodeName.toLowerCase();
958		return name === "input" && elem.type === type;
959	};
960}
961
962/**
963 * Returns a function to use in pseudos for buttons
964 * @param {String} type
965 */
966function createButtonPseudo( type ) {
967	return function( elem ) {
968		var name = elem.nodeName.toLowerCase();
969		return (name === "input" || name === "button") && elem.type === type;
970	};
971}
972
973/**
974 * Returns a function to use in pseudos for positionals
975 * @param {Function} fn
976 */
977function createPositionalPseudo( fn ) {
978	return markFunction(function( argument ) {
979		argument = +argument;
980		return markFunction(function( seed, matches ) {
981			var j,
982				matchIndexes = fn( [], seed.length, argument ),
983				i = matchIndexes.length;
984
985			// Match elements found at the specified indexes
986			while ( i-- ) {
987				if ( seed[ (j = matchIndexes[i]) ] ) {
988					seed[j] = !(matches[j] = seed[j]);
989				}
990			}
991		});
992	});
993}
994
995/**
996 * Checks a node for validity as a Sizzle context
997 * @param {Element|Object=} context
998 * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
999 */
1000function testContext( context ) {
1001	return context && typeof context.getElementsByTagName !== "undefined" && context;
1002}
1003
1004// Expose support vars for convenience
1005support = Sizzle.support = {};
1006
1007/**
1008 * Detects XML nodes
1009 * @param {Element|Object} elem An element or a document
1010 * @returns {Boolean} True iff elem is a non-HTML XML node
1011 */
1012isXML = Sizzle.isXML = function( elem ) {
1013	// documentElement is verified for cases where it doesn't yet exist
1014	// (such as loading iframes in IE - #4833)
1015	var documentElement = elem && (elem.ownerDocument || elem).documentElement;
1016	return documentElement ? documentElement.nodeName !== "HTML" : false;
1017};
1018
1019/**
1020 * Sets document-related variables once based on the current document
1021 * @param {Element|Object} [doc] An element or document object to use to set the document
1022 * @returns {Object} Returns the current document
1023 */
1024setDocument = Sizzle.setDocument = function( node ) {
1025	var hasCompare, parent,
1026		doc = node ? node.ownerDocument || node : preferredDoc;
1027
1028	// If no document and documentElement is available, return
1029	if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
1030		return document;
1031	}
1032
1033	// Set our document
1034	document = doc;
1035	docElem = doc.documentElement;
1036	parent = doc.defaultView;
1037
1038	// Support: IE>8
1039	// If iframe document is assigned to "document" variable and if iframe has been reloaded,
1040	// IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936
1041	// IE6-8 do not support the defaultView property so parent will be undefined
1042	if ( parent && parent !== parent.top ) {
1043		// IE11 does not have attachEvent, so all must suffer
1044		if ( parent.addEventListener ) {
1045			parent.addEventListener( "unload", unloadHandler, false );
1046		} else if ( parent.attachEvent ) {
1047			parent.attachEvent( "onunload", unloadHandler );
1048		}
1049	}
1050
1051	/* Support tests
1052	---------------------------------------------------------------------- */
1053	documentIsHTML = !isXML( doc );
1054
1055	/* Attributes
1056	---------------------------------------------------------------------- */
1057
1058	// Support: IE<8
1059	// Verify that getAttribute really returns attributes and not properties
1060	// (excepting IE8 booleans)
1061	support.attributes = assert(function( div ) {
1062		div.className = "i";
1063		return !div.getAttribute("className");
1064	});
1065
1066	/* getElement(s)By*
1067	---------------------------------------------------------------------- */
1068
1069	// Check if getElementsByTagName("*") returns only elements
1070	support.getElementsByTagName = assert(function( div ) {
1071		div.appendChild( doc.createComment("") );
1072		return !div.getElementsByTagName("*").length;
1073	});
1074
1075	// Support: IE<9
1076	support.getElementsByClassName = rnative.test( doc.getElementsByClassName );
1077
1078	// Support: IE<10
1079	// Check if getElementById returns elements by name
1080	// The broken getElementById methods don't pick up programatically-set names,
1081	// so use a roundabout getElementsByName test
1082	support.getById = assert(function( div ) {
1083		docElem.appendChild( div ).id = expando;
1084		return !doc.getElementsByName || !doc.getElementsByName( expando ).length;
1085	});
1086
1087	// ID find and filter
1088	if ( support.getById ) {
1089		Expr.find["ID"] = function( id, context ) {
1090			if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
1091				var m = context.getElementById( id );
1092				// Check parentNode to catch when Blackberry 4.6 returns
1093				// nodes that are no longer in the document #6963
1094				return m && m.parentNode ? [ m ] : [];
1095			}
1096		};
1097		Expr.filter["ID"] = function( id ) {
1098			var attrId = id.replace( runescape, funescape );
1099			return function( elem ) {
1100				return elem.getAttribute("id") === attrId;
1101			};
1102		};
1103	} else {
1104		// Support: IE6/7
1105		// getElementById is not reliable as a find shortcut
1106		delete Expr.find["ID"];
1107
1108		Expr.filter["ID"] =  function( id ) {
1109			var attrId = id.replace( runescape, funescape );
1110			return function( elem ) {
1111				var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
1112				return node && node.value === attrId;
1113			};
1114		};
1115	}
1116
1117	// Tag
1118	Expr.find["TAG"] = support.getElementsByTagName ?
1119		function( tag, context ) {
1120			if ( typeof context.getElementsByTagName !== "undefined" ) {
1121				return context.getElementsByTagName( tag );
1122
1123			// DocumentFragment nodes don't have gEBTN
1124			} else if ( support.qsa ) {
1125				return context.querySelectorAll( tag );
1126			}
1127		} :
1128
1129		function( tag, context ) {
1130			var elem,
1131				tmp = [],
1132				i = 0,
1133				// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
1134				results = context.getElementsByTagName( tag );
1135
1136			// Filter out possible comments
1137			if ( tag === "*" ) {
1138				while ( (elem = results[i++]) ) {
1139					if ( elem.nodeType === 1 ) {
1140						tmp.push( elem );
1141					}
1142				}
1143
1144				return tmp;
1145			}
1146			return results;
1147		};
1148
1149	// Class
1150	Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
1151		if ( documentIsHTML ) {
1152			return context.getElementsByClassName( className );
1153		}
1154	};
1155
1156	/* QSA/matchesSelector
1157	---------------------------------------------------------------------- */
1158
1159	// QSA and matchesSelector support
1160
1161	// matchesSelector(:active) reports false when true (IE9/Opera 11.5)
1162	rbuggyMatches = [];
1163
1164	// qSa(:focus) reports false when true (Chrome 21)
1165	// We allow this because of a bug in IE8/9 that throws an error
1166	// whenever `document.activeElement` is accessed on an iframe
1167	// So, we allow :focus to pass through QSA all the time to avoid the IE error
1168	// See http://bugs.jquery.com/ticket/13378
1169	rbuggyQSA = [];
1170
1171	if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) {
1172		// Build QSA regex
1173		// Regex strategy adopted from Diego Perini
1174		assert(function( div ) {
1175			// Select is set to empty string on purpose
1176			// This is to test IE's treatment of not explicitly
1177			// setting a boolean content attribute,
1178			// since its presence should be enough
1179			// http://bugs.jquery.com/ticket/12359
1180			docElem.appendChild( div ).innerHTML = "<a id='" + expando + "'></a>" +
1181				"<select id='" + expando + "-\f]' msallowcapture=''>" +
1182				"<option selected=''></option></select>";
1183
1184			// Support: IE8, Opera 11-12.16
1185			// Nothing should be selected when empty strings follow ^= or $= or *=
1186			// The test attribute must be unknown in Opera but "safe" for WinRT
1187			// http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
1188			if ( div.querySelectorAll("[msallowcapture^='']").length ) {
1189				rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
1190			}
1191
1192			// Support: IE8
1193			// Boolean attributes and "value" are not treated correctly
1194			if ( !div.querySelectorAll("[selected]").length ) {
1195				rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
1196			}
1197
1198			// Support: Chrome<29, Android<4.2+, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.7+
1199			if ( !div.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
1200				rbuggyQSA.push("~=");
1201			}
1202
1203			// Webkit/Opera - :checked should return selected option elements
1204			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
1205			// IE8 throws error here and will not see later tests
1206			if ( !div.querySelectorAll(":checked").length ) {
1207				rbuggyQSA.push(":checked");
1208			}
1209
1210			// Support: Safari 8+, iOS 8+
1211			// https://bugs.webkit.org/show_bug.cgi?id=136851
1212			// In-page `selector#id sibing-combinator selector` fails
1213			if ( !div.querySelectorAll( "a#" + expando + "+*" ).length ) {
1214				rbuggyQSA.push(".#.+[+~]");
1215			}
1216		});
1217
1218		assert(function( div ) {
1219			// Support: Windows 8 Native Apps
1220			// The type and name attributes are restricted during .innerHTML assignment
1221			var input = doc.createElement("input");
1222			input.setAttribute( "type", "hidden" );
1223			div.appendChild( input ).setAttribute( "name", "D" );
1224
1225			// Support: IE8
1226			// Enforce case-sensitivity of name attribute
1227			if ( div.querySelectorAll("[name=d]").length ) {
1228				rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
1229			}
1230
1231			// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
1232			// IE8 throws error here and will not see later tests
1233			if ( !div.querySelectorAll(":enabled").length ) {
1234				rbuggyQSA.push( ":enabled", ":disabled" );
1235			}
1236
1237			// Opera 10-11 does not throw on post-comma invalid pseudos
1238			div.querySelectorAll("*,:x");
1239			rbuggyQSA.push(",.*:");
1240		});
1241	}
1242
1243	if ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||
1244		docElem.webkitMatchesSelector ||
1245		docElem.mozMatchesSelector ||
1246		docElem.oMatchesSelector ||
1247		docElem.msMatchesSelector) )) ) {
1248
1249		assert(function( div ) {
1250			// Check to see if it's possible to do matchesSelector
1251			// on a disconnected node (IE 9)
1252			support.disconnectedMatch = matches.call( div, "div" );
1253
1254			// This should fail with an exception
1255			// Gecko does not error, returns false instead
1256			matches.call( div, "[s!='']:x" );
1257			rbuggyMatches.push( "!=", pseudos );
1258		});
1259	}
1260
1261	rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
1262	rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
1263
1264	/* Contains
1265	---------------------------------------------------------------------- */
1266	hasCompare = rnative.test( docElem.compareDocumentPosition );
1267
1268	// Element contains another
1269	// Purposefully does not implement inclusive descendent
1270	// As in, an element does not contain itself
1271	contains = hasCompare || rnative.test( docElem.contains ) ?
1272		function( a, b ) {
1273			var adown = a.nodeType === 9 ? a.documentElement : a,
1274				bup = b && b.parentNode;
1275			return a === bup || !!( bup && bup.nodeType === 1 && (
1276				adown.contains ?
1277					adown.contains( bup ) :
1278					a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
1279			));
1280		} :
1281		function( a, b ) {
1282			if ( b ) {
1283				while ( (b = b.parentNode) ) {
1284					if ( b === a ) {
1285						return true;
1286					}
1287				}
1288			}
1289			return false;
1290		};
1291
1292	/* Sorting
1293	---------------------------------------------------------------------- */
1294
1295	// Document order sorting
1296	sortOrder = hasCompare ?
1297	function( a, b ) {
1298
1299		// Flag for duplicate removal
1300		if ( a === b ) {
1301			hasDuplicate = true;
1302			return 0;
1303		}
1304
1305		// Sort on method existence if only one input has compareDocumentPosition
1306		var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
1307		if ( compare ) {
1308			return compare;
1309		}
1310
1311		// Calculate position if both inputs belong to the same document
1312		compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
1313			a.compareDocumentPosition( b ) :
1314
1315			// Otherwise we know they are disconnected
1316			1;
1317
1318		// Disconnected nodes
1319		if ( compare & 1 ||
1320			(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
1321
1322			// Choose the first element that is related to our preferred document
1323			if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
1324				return -1;
1325			}
1326			if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
1327				return 1;
1328			}
1329
1330			// Maintain original order
1331			return sortInput ?
1332				( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
1333				0;
1334		}
1335
1336		return compare & 4 ? -1 : 1;
1337	} :
1338	function( a, b ) {
1339		// Exit early if the nodes are identical
1340		if ( a === b ) {
1341			hasDuplicate = true;
1342			return 0;
1343		}
1344
1345		var cur,
1346			i = 0,
1347			aup = a.parentNode,
1348			bup = b.parentNode,
1349			ap = [ a ],
1350			bp = [ b ];
1351
1352		// Parentless nodes are either documents or disconnected
1353		if ( !aup || !bup ) {
1354			return a === doc ? -1 :
1355				b === doc ? 1 :
1356				aup ? -1 :
1357				bup ? 1 :
1358				sortInput ?
1359				( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
1360				0;
1361
1362		// If the nodes are siblings, we can do a quick check
1363		} else if ( aup === bup ) {
1364			return siblingCheck( a, b );
1365		}
1366
1367		// Otherwise we need full lists of their ancestors for comparison
1368		cur = a;
1369		while ( (cur = cur.parentNode) ) {
1370			ap.unshift( cur );
1371		}
1372		cur = b;
1373		while ( (cur = cur.parentNode) ) {
1374			bp.unshift( cur );
1375		}
1376
1377		// Walk down the tree looking for a discrepancy
1378		while ( ap[i] === bp[i] ) {
1379			i++;
1380		}
1381
1382		return i ?
1383			// Do a sibling check if the nodes have a common ancestor
1384			siblingCheck( ap[i], bp[i] ) :
1385
1386			// Otherwise nodes in our document sort first
1387			ap[i] === preferredDoc ? -1 :
1388			bp[i] === preferredDoc ? 1 :
1389			0;
1390	};
1391
1392	return doc;
1393};
vendor: 4,484 bytes, lines 1394-1566
1394
1395Sizzle.matches = function( expr, elements ) {
1396	return Sizzle( expr, null, null, elements );
1397};
1398
1399Sizzle.matchesSelector = function( elem, expr ) {
1400	// Set document vars if needed
1401	if ( ( elem.ownerDocument || elem ) !== document ) {
1402		setDocument( elem );
1403	}
1404
1405	// Make sure that attribute selectors are quoted
1406	expr = expr.replace( rattributeQuotes, "='$1']" );
1407
1408	if ( support.matchesSelector && documentIsHTML &&
1409		( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
1410		( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {
1411
1412		try {
1413			var ret = matches.call( elem, expr );
1414
1415			// IE 9's matchesSelector returns false on disconnected nodes
1416			if ( ret || support.disconnectedMatch ||
1417					// As well, disconnected nodes are said to be in a document
1418					// fragment in IE 9
1419					elem.document && elem.document.nodeType !== 11 ) {
1420				return ret;
1421			}
1422		} catch (e) {}
1423	}
1424
1425	return Sizzle( expr, document, null, [ elem ] ).length > 0;
1426};
1427
1428Sizzle.contains = function( context, elem ) {
1429	// Set document vars if needed
1430	if ( ( context.ownerDocument || context ) !== document ) {
1431		setDocument( context );
1432	}
1433	return contains( context, elem );
1434};
1435
1436Sizzle.attr = function( elem, name ) {
1437	// Set document vars if needed
1438	if ( ( elem.ownerDocument || elem ) !== document ) {
1439		setDocument( elem );
1440	}
1441
1442	var fn = Expr.attrHandle[ name.toLowerCase() ],
1443		// Don't get fooled by Object.prototype properties (jQuery #13807)
1444		val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
1445			fn( elem, name, !documentIsHTML ) :
1446			undefined;
1447
1448	return val !== undefined ?
1449		val :
1450		support.attributes || !documentIsHTML ?
1451			elem.getAttribute( name ) :
1452			(val = elem.getAttributeNode(name)) && val.specified ?
1453				val.value :
1454				null;
1455};
1456
1457Sizzle.error = function( msg ) {
1458	throw new Error( "Syntax error, unrecognized expression: " + msg );
1459};
1460
1461/**
1462 * Document sorting and removing duplicates
1463 * @param {ArrayLike} results
1464 */
1465Sizzle.uniqueSort = function( results ) {
1466	var elem,
1467		duplicates = [],
1468		j = 0,
1469		i = 0;
1470
1471	// Unless we *know* we can detect duplicates, assume their presence
1472	hasDuplicate = !support.detectDuplicates;
1473	sortInput = !support.sortStable && results.slice( 0 );
1474	results.sort( sortOrder );
1475
1476	if ( hasDuplicate ) {
1477		while ( (elem = results[i++]) ) {
1478			if ( elem === results[ i ] ) {
1479				j = duplicates.push( i );
1480			}
1481		}
1482		while ( j-- ) {
1483			results.splice( duplicates[ j ], 1 );
1484		}
1485	}
1486
1487	// Clear input after sorting to release objects
1488	// See https://github.com/jquery/sizzle/pull/225
1489	sortInput = null;
1490
1491	return results;
1492};
1493
1494/**
1495 * Utility function for retrieving the text value of an array of DOM nodes
1496 * @param {Array|Element} elem
1497 */
1498getText = Sizzle.getText = function( elem ) {
1499	var node,
1500		ret = "",
1501		i = 0,
1502		nodeType = elem.nodeType;
1503
1504	if ( !nodeType ) {
1505		// If no nodeType, this is expected to be an array
1506		while ( (node = elem[i++]) ) {
1507			// Do not traverse comment nodes
1508			ret += getText( node );
1509		}
1510	} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
1511		// Use textContent for elements
1512		// innerText usage removed for consistency of new lines (jQuery #11153)
1513		if ( typeof elem.textContent === "string" ) {
1514			return elem.textContent;
1515		} else {
1516			// Traverse its children
1517			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
1518				ret += getText( elem );
1519			}
1520		}
1521	} else if ( nodeType === 3 || nodeType === 4 ) {
1522		return elem.nodeValue;
1523	}
1524	// Do not include comment or processing instruction nodes
1525
1526	return ret;
1527};
1528
1529Expr = Sizzle.selectors = {
1530
1531	// Can be adjusted by the user
1532	cacheLength: 50,
1533
1534	createPseudo: markFunction,
1535
1536	match: matchExpr,
1537
1538	attrHandle: {},
1539
1540	find: {},
1541
1542	relative: {
1543		">": { dir: "parentNode", first: true },
1544		" ": { dir: "parentNode" },
1545		"+": { dir: "previousSibling", first: true },
1546		"~": { dir: "previousSibling" }
1547	},
1548
1549	preFilter: {
1550		"ATTR": function( match ) {
1551			match[1] = match[1].replace( runescape, funescape );
1552
1553			// Move the given value to match[3] whether quoted or unquoted
1554			match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape );
1555
1556			if ( match[2] === "~=" ) {
1557				match[3] = " " + match[3] + " ";
1558			}
1559
1560			return match.slice( 0, 4 );
1561		},
1562
1563		"CHILD": function( match ) {
1564			/* matches from matchExpr["CHILD"]
1565				1 type (only|nth|...)
1566				2 what (child|of-type)
vendor: 10,120 bytes, lines 1567-1878
1567				3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
1568				4 xn-component of xn+y argument ([+-]?\d*n|)
1569				5 sign of xn-component
1570				6 x of xn-component
1571				7 sign of y-component
1572				8 y of y-component
1573			*/
1574			match[1] = match[1].toLowerCase();
1575
1576			if ( match[1].slice( 0, 3 ) === "nth" ) {
1577				// nth-* requires argument
1578				if ( !match[3] ) {
1579					Sizzle.error( match[0] );
1580				}
1581
1582				// numeric x and y parameters for Expr.filter.CHILD
1583				// remember that false/true cast respectively to 0/1
1584				match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
1585				match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
1586
1587			// other types prohibit arguments
1588			} else if ( match[3] ) {
1589				Sizzle.error( match[0] );
1590			}
1591
1592			return match;
1593		},
1594
1595		"PSEUDO": function( match ) {
1596			var excess,
1597				unquoted = !match[6] && match[2];
1598
1599			if ( matchExpr["CHILD"].test( match[0] ) ) {
1600				return null;
1601			}
1602
1603			// Accept quoted arguments as-is
1604			if ( match[3] ) {
1605				match[2] = match[4] || match[5] || "";
1606
1607			// Strip excess characters from unquoted arguments
1608			} else if ( unquoted && rpseudo.test( unquoted ) &&
1609				// Get excess from tokenize (recursively)
1610				(excess = tokenize( unquoted, true )) &&
1611				// advance to the next closing parenthesis
1612				(excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
1613
1614				// excess is a negative index
1615				match[0] = match[0].slice( 0, excess );
1616				match[2] = unquoted.slice( 0, excess );
1617			}
1618
1619			// Return only captures needed by the pseudo filter method (type and argument)
1620			return match.slice( 0, 3 );
1621		}
1622	},
1623
1624	filter: {
1625
1626		"TAG": function( nodeNameSelector ) {
1627			var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
1628			return nodeNameSelector === "*" ?
1629				function() { return true; } :
1630				function( elem ) {
1631					return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
1632				};
1633		},
1634
1635		"CLASS": function( className ) {
1636			var pattern = classCache[ className + " " ];
1637
1638			return pattern ||
1639				(pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
1640				classCache( className, function( elem ) {
1641					return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" );
1642				});
1643		},
1644
1645		"ATTR": function( name, operator, check ) {
1646			return function( elem ) {
1647				var result = Sizzle.attr( elem, name );
1648
1649				if ( result == null ) {
1650					return operator === "!=";
1651				}
1652				if ( !operator ) {
1653					return true;
1654				}
1655
1656				result += "";
1657
1658				return operator === "=" ? result === check :
1659					operator === "!=" ? result !== check :
1660					operator === "^=" ? check && result.indexOf( check ) === 0 :
1661					operator === "*=" ? check && result.indexOf( check ) > -1 :
1662					operator === "$=" ? check && result.slice( -check.length ) === check :
1663					operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :
1664					operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
1665					false;
1666			};
1667		},
1668
1669		"CHILD": function( type, what, argument, first, last ) {
1670			var simple = type.slice( 0, 3 ) !== "nth",
1671				forward = type.slice( -4 ) !== "last",
1672				ofType = what === "of-type";
1673
1674			return first === 1 && last === 0 ?
1675
1676				// Shortcut for :nth-*(n)
1677				function( elem ) {
1678					return !!elem.parentNode;
1679				} :
1680
1681				function( elem, context, xml ) {
1682					var cache, outerCache, node, diff, nodeIndex, start,
1683						dir = simple !== forward ? "nextSibling" : "previousSibling",
1684						parent = elem.parentNode,
1685						name = ofType && elem.nodeName.toLowerCase(),
1686						useCache = !xml && !ofType;
1687
1688					if ( parent ) {
1689
1690						// :(first|last|only)-(child|of-type)
1691						if ( simple ) {
1692							while ( dir ) {
1693								node = elem;
1694								while ( (node = node[ dir ]) ) {
1695									if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {
1696										return false;
1697									}
1698								}
1699								// Reverse direction for :only-* (if we haven't yet done so)
1700								start = dir = type === "only" && !start && "nextSibling";
1701							}
1702							return true;
1703						}
1704
1705						start = [ forward ? parent.firstChild : parent.lastChild ];
1706
1707						// non-xml :nth-child(...) stores cache data on `parent`
1708						if ( forward && useCache ) {
1709							// Seek `elem` from a previously-cached index
1710							outerCache = parent[ expando ] || (parent[ expando ] = {});
1711							cache = outerCache[ type ] || [];
1712							nodeIndex = cache[0] === dirruns && cache[1];
1713							diff = cache[0] === dirruns && cache[2];
1714							node = nodeIndex && parent.childNodes[ nodeIndex ];
1715
1716							while ( (node = ++nodeIndex && node && node[ dir ] ||
1717
1718								// Fallback to seeking `elem` from the start
1719								(diff = nodeIndex = 0) || start.pop()) ) {
1720
1721								// When found, cache indexes on `parent` and break
1722								if ( node.nodeType === 1 && ++diff && node === elem ) {
1723									outerCache[ type ] = [ dirruns, nodeIndex, diff ];
1724									break;
1725								}
1726							}
1727
1728						// Use previously-cached element index if available
1729						} else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) {
1730							diff = cache[1];
1731
1732						// xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...)
1733						} else {
1734							// Use the same loop as above to seek `elem` from the start
1735							while ( (node = ++nodeIndex && node && node[ dir ] ||
1736								(diff = nodeIndex = 0) || start.pop()) ) {
1737
1738								if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) {
1739									// Cache the index of each encountered element
1740									if ( useCache ) {
1741										(node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];
1742									}
1743
1744									if ( node === elem ) {
1745										break;
1746									}
1747								}
1748							}
1749						}
1750
1751						// Incorporate the offset, then check against cycle size
1752						diff -= last;
1753						return diff === first || ( diff % first === 0 && diff / first >= 0 );
1754					}
1755				};
1756		},
1757
1758		"PSEUDO": function( pseudo, argument ) {
1759			// pseudo-class names are case-insensitive
1760			// http://www.w3.org/TR/selectors/#pseudo-classes
1761			// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
1762			// Remember that setFilters inherits from pseudos
1763			var args,
1764				fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
1765					Sizzle.error( "unsupported pseudo: " + pseudo );
1766
1767			// The user may use createPseudo to indicate that
1768			// arguments are needed to create the filter function
1769			// just as Sizzle does
1770			if ( fn[ expando ] ) {
1771				return fn( argument );
1772			}
1773
1774			// But maintain support for old signatures
1775			if ( fn.length > 1 ) {
1776				args = [ pseudo, pseudo, "", argument ];
1777				return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
1778					markFunction(function( seed, matches ) {
1779						var idx,
1780							matched = fn( seed, argument ),
1781							i = matched.length;
1782						while ( i-- ) {
1783							idx = indexOf( seed, matched[i] );
1784							seed[ idx ] = !( matches[ idx ] = matched[i] );
1785						}
1786					}) :
1787					function( elem ) {
1788						return fn( elem, 0, args );
1789					};
1790			}
1791
1792			return fn;
1793		}
1794	},
1795
1796	pseudos: {
1797		// Potentially complex pseudos
1798		"not": markFunction(function( selector ) {
1799			// Trim the selector passed to compile
1800			// to avoid treating leading and trailing
1801			// spaces as combinators
1802			var input = [],
1803				results = [],
1804				matcher = compile( selector.replace( rtrim, "$1" ) );
1805
1806			return matcher[ expando ] ?
1807				markFunction(function( seed, matches, context, xml ) {
1808					var elem,
1809						unmatched = matcher( seed, null, xml, [] ),
1810						i = seed.length;
1811
1812					// Match elements unmatched by `matcher`
1813					while ( i-- ) {
1814						if ( (elem = unmatched[i]) ) {
1815							seed[i] = !(matches[i] = elem);
1816						}
1817					}
1818				}) :
1819				function( elem, context, xml ) {
1820					input[0] = elem;
1821					matcher( input, null, xml, results );
1822					// Don't keep the element (issue #299)
1823					input[0] = null;
1824					return !results.pop();
1825				};
1826		}),
1827
1828		"has": markFunction(function( selector ) {
1829			return function( elem ) {
1830				return Sizzle( selector, elem ).length > 0;
1831			};
1832		}),
1833
1834		"contains": markFunction(function( text ) {
1835			text = text.replace( runescape, funescape );
1836			return function( elem ) {
1837				return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
1838			};
1839		}),
1840
1841		// "Whether an element is represented by a :lang() selector
1842		// is based solely on the element's language value
1843		// being equal to the identifier C,
1844		// or beginning with the identifier C immediately followed by "-".
1845		// The matching of C against the element's language value is performed case-insensitively.
1846		// The identifier C does not have to be a valid language name."
1847		// http://www.w3.org/TR/selectors/#lang-pseudo
1848		"lang": markFunction( function( lang ) {
1849			// lang value must be a valid identifier
1850			if ( !ridentifier.test(lang || "") ) {
1851				Sizzle.error( "unsupported lang: " + lang );
1852			}
1853			lang = lang.replace( runescape, funescape ).toLowerCase();
1854			return function( elem ) {
1855				var elemLang;
1856				do {
1857					if ( (elemLang = documentIsHTML ?
1858						elem.lang :
1859						elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
1860
1861						elemLang = elemLang.toLowerCase();
1862						return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
1863					}
1864				} while ( (elem = elem.parentNode) && elem.nodeType === 1 );
1865				return false;
1866			};
1867		}),
1868
1869		// Miscellaneous
1870		"target": function( elem ) {
1871			var hash = window.location && window.location.hash;
1872			return hash && hash.slice( 1 ) === elem.id;
1873		},
1874
1875		"root": function( elem ) {
1876			return elem === docElem;
1877		},
1878
vendor: 5,418 bytes, lines 1879-2078
1879		"focus": function( elem ) {
1880			return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
1881		},
1882
1883		// Boolean properties
1884		"enabled": function( elem ) {
1885			return elem.disabled === false;
1886		},
1887
1888		"disabled": function( elem ) {
1889			return elem.disabled === true;
1890		},
1891
1892		"checked": function( elem ) {
1893			// In CSS3, :checked should return both checked and selected elements
1894			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
1895			var nodeName = elem.nodeName.toLowerCase();
1896			return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
1897		},
1898
1899		"selected": function( elem ) {
1900			// Accessing this property makes selected-by-default
1901			// options in Safari work properly
1902			if ( elem.parentNode ) {
1903				elem.parentNode.selectedIndex;
1904			}
1905
1906			return elem.selected === true;
1907		},
1908
1909		// Contents
1910		"empty": function( elem ) {
1911			// http://www.w3.org/TR/selectors/#empty-pseudo
1912			// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
1913			//   but not by others (comment: 8; processing instruction: 7; etc.)
1914			// nodeType < 6 works because attributes (2) do not appear as children
1915			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
1916				if ( elem.nodeType < 6 ) {
1917					return false;
1918				}
1919			}
1920			return true;
1921		},
1922
1923		"parent": function( elem ) {
1924			return !Expr.pseudos["empty"]( elem );
1925		},
1926
1927		// Element/input types
1928		"header": function( elem ) {
1929			return rheader.test( elem.nodeName );
1930		},
1931
1932		"input": function( elem ) {
1933			return rinputs.test( elem.nodeName );
1934		},
1935
1936		"button": function( elem ) {
1937			var name = elem.nodeName.toLowerCase();
1938			return name === "input" && elem.type === "button" || name === "button";
1939		},
1940
1941		"text": function( elem ) {
1942			var attr;
1943			return elem.nodeName.toLowerCase() === "input" &&
1944				elem.type === "text" &&
1945
1946				// Support: IE<8
1947				// New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
1948				( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
1949		},
1950
1951		// Position-in-collection
1952		"first": createPositionalPseudo(function() {
1953			return [ 0 ];
1954		}),
1955
1956		"last": createPositionalPseudo(function( matchIndexes, length ) {
1957			return [ length - 1 ];
1958		}),
1959
1960		"eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
1961			return [ argument < 0 ? argument + length : argument ];
1962		}),
1963
1964		"even": createPositionalPseudo(function( matchIndexes, length ) {
1965			var i = 0;
1966			for ( ; i < length; i += 2 ) {
1967				matchIndexes.push( i );
1968			}
1969			return matchIndexes;
1970		}),
1971
1972		"odd": createPositionalPseudo(function( matchIndexes, length ) {
1973			var i = 1;
1974			for ( ; i < length; i += 2 ) {
1975				matchIndexes.push( i );
1976			}
1977			return matchIndexes;
1978		}),
1979
1980		"lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
1981			var i = argument < 0 ? argument + length : argument;
1982			for ( ; --i >= 0; ) {
1983				matchIndexes.push( i );
1984			}
1985			return matchIndexes;
1986		}),
1987
1988		"gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
1989			var i = argument < 0 ? argument + length : argument;
1990			for ( ; ++i < length; ) {
1991				matchIndexes.push( i );
1992			}
1993			return matchIndexes;
1994		})
1995	}
1996};
1997
1998Expr.pseudos["nth"] = Expr.pseudos["eq"];
1999
2000// Add button/input type pseudos
2001for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
2002	Expr.pseudos[ i ] = createInputPseudo( i );
2003}
2004for ( i in { submit: true, reset: true } ) {
2005	Expr.pseudos[ i ] = createButtonPseudo( i );
2006}
2007
2008// Easy API for creating new setFilters
2009function setFilters() {}
2010setFilters.prototype = Expr.filters = Expr.pseudos;
2011Expr.setFilters = new setFilters();
2012
2013tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
2014	var matched, match, tokens, type,
2015		soFar, groups, preFilters,
2016		cached = tokenCache[ selector + " " ];
2017
2018	if ( cached ) {
2019		return parseOnly ? 0 : cached.slice( 0 );
2020	}
2021
2022	soFar = selector;
2023	groups = [];
2024	preFilters = Expr.preFilter;
2025
2026	while ( soFar ) {
2027
2028		// Comma and first run
2029		if ( !matched || (match = rcomma.exec( soFar )) ) {
2030			if ( match ) {
2031				// Don't consume trailing commas as valid
2032				soFar = soFar.slice( match[0].length ) || soFar;
2033			}
2034			groups.push( (tokens = []) );
2035		}
2036
2037		matched = false;
2038
2039		// Combinators
2040		if ( (match = rcombinators.exec( soFar )) ) {
2041			matched = match.shift();
2042			tokens.push({
2043				value: matched,
2044				// Cast descendant combinators to space
2045				type: match[0].replace( rtrim, " " )
2046			});
2047			soFar = soFar.slice( matched.length );
2048		}
2049
2050		// Filters
2051		for ( type in Expr.filter ) {
2052			if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
2053				(match = preFilters[ type ]( match ))) ) {
2054				matched = match.shift();
2055				tokens.push({
2056					value: matched,
2057					type: type,
2058					matches: match
2059				});
2060				soFar = soFar.slice( matched.length );
2061			}
2062		}
2063
2064		if ( !matched ) {
2065			break;
2066		}
2067	}
2068
2069	// Return the length of the invalid excess
2070	// if we're just parsing
2071	// Otherwise, throw an error or return tokens
2072	return parseOnly ?
2073		soFar.length :
2074		soFar ?
2075			Sizzle.error( selector ) :
2076			// Cache the tokens
2077			tokenCache( selector, groups ).slice( 0 );
2078};
vendor: 11,230 bytes, lines 2079-2465
2079
2080function toSelector( tokens ) {
2081	var i = 0,
2082		len = tokens.length,
2083		selector = "";
2084	for ( ; i < len; i++ ) {
2085		selector += tokens[i].value;
2086	}
2087	return selector;
2088}
2089
2090function addCombinator( matcher, combinator, base ) {
2091	var dir = combinator.dir,
2092		checkNonElements = base && dir === "parentNode",
2093		doneName = done++;
2094
2095	return combinator.first ?
2096		// Check against closest ancestor/preceding element
2097		function( elem, context, xml ) {
2098			while ( (elem = elem[ dir ]) ) {
2099				if ( elem.nodeType === 1 || checkNonElements ) {
2100					return matcher( elem, context, xml );
2101				}
2102			}
2103		} :
2104
2105		// Check against all ancestor/preceding elements
2106		function( elem, context, xml ) {
2107			var oldCache, outerCache,
2108				newCache = [ dirruns, doneName ];
2109
2110			// We can't set arbitrary data on XML nodes, so they don't benefit from dir caching
2111			if ( xml ) {
2112				while ( (elem = elem[ dir ]) ) {
2113					if ( elem.nodeType === 1 || checkNonElements ) {
2114						if ( matcher( elem, context, xml ) ) {
2115							return true;
2116						}
2117					}
2118				}
2119			} else {
2120				while ( (elem = elem[ dir ]) ) {
2121					if ( elem.nodeType === 1 || checkNonElements ) {
2122						outerCache = elem[ expando ] || (elem[ expando ] = {});
2123						if ( (oldCache = outerCache[ dir ]) &&
2124							oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
2125
2126							// Assign to newCache so results back-propagate to previous elements
2127							return (newCache[ 2 ] = oldCache[ 2 ]);
2128						} else {
2129							// Reuse newcache so results back-propagate to previous elements
2130							outerCache[ dir ] = newCache;
2131
2132							// A match means we're done; a fail means we have to keep checking
2133							if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
2134								return true;
2135							}
2136						}
2137					}
2138				}
2139			}
2140		};
2141}
2142
2143function elementMatcher( matchers ) {
2144	return matchers.length > 1 ?
2145		function( elem, context, xml ) {
2146			var i = matchers.length;
2147			while ( i-- ) {
2148				if ( !matchers[i]( elem, context, xml ) ) {
2149					return false;
2150				}
2151			}
2152			return true;
2153		} :
2154		matchers[0];
2155}
2156
2157function multipleContexts( selector, contexts, results ) {
2158	var i = 0,
2159		len = contexts.length;
2160	for ( ; i < len; i++ ) {
2161		Sizzle( selector, contexts[i], results );
2162	}
2163	return results;
2164}
2165
2166function condense( unmatched, map, filter, context, xml ) {
2167	var elem,
2168		newUnmatched = [],
2169		i = 0,
2170		len = unmatched.length,
2171		mapped = map != null;
2172
2173	for ( ; i < len; i++ ) {
2174		if ( (elem = unmatched[i]) ) {
2175			if ( !filter || filter( elem, context, xml ) ) {
2176				newUnmatched.push( elem );
2177				if ( mapped ) {
2178					map.push( i );
2179				}
2180			}
2181		}
2182	}
2183
2184	return newUnmatched;
2185}
2186
2187function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
2188	if ( postFilter && !postFilter[ expando ] ) {
2189		postFilter = setMatcher( postFilter );
2190	}
2191	if ( postFinder && !postFinder[ expando ] ) {
2192		postFinder = setMatcher( postFinder, postSelector );
2193	}
2194	return markFunction(function( seed, results, context, xml ) {
2195		var temp, i, elem,
2196			preMap = [],
2197			postMap = [],
2198			preexisting = results.length,
2199
2200			// Get initial elements from seed or context
2201			elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
2202
2203			// Prefilter to get matcher input, preserving a map for seed-results synchronization
2204			matcherIn = preFilter && ( seed || !selector ) ?
2205				condense( elems, preMap, preFilter, context, xml ) :
2206				elems,
2207
2208			matcherOut = matcher ?
2209				// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
2210				postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
2211
2212					// ...intermediate processing is necessary
2213					[] :
2214
2215					// ...otherwise use results directly
2216					results :
2217				matcherIn;
2218
2219		// Find primary matches
2220		if ( matcher ) {
2221			matcher( matcherIn, matcherOut, context, xml );
2222		}
2223
2224		// Apply postFilter
2225		if ( postFilter ) {
2226			temp = condense( matcherOut, postMap );
2227			postFilter( temp, [], context, xml );
2228
2229			// Un-match failing elements by moving them back to matcherIn
2230			i = temp.length;
2231			while ( i-- ) {
2232				if ( (elem = temp[i]) ) {
2233					matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
2234				}
2235			}
2236		}
2237
2238		if ( seed ) {
2239			if ( postFinder || preFilter ) {
2240				if ( postFinder ) {
2241					// Get the final matcherOut by condensing this intermediate into postFinder contexts
2242					temp = [];
2243					i = matcherOut.length;
2244					while ( i-- ) {
2245						if ( (elem = matcherOut[i]) ) {
2246							// Restore matcherIn since elem is not yet a final match
2247							temp.push( (matcherIn[i] = elem) );
2248						}
2249					}
2250					postFinder( null, (matcherOut = []), temp, xml );
2251				}
2252
2253				// Move matched elements from seed to results to keep them synchronized
2254				i = matcherOut.length;
2255				while ( i-- ) {
2256					if ( (elem = matcherOut[i]) &&
2257						(temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {
2258
2259						seed[temp] = !(results[temp] = elem);
2260					}
2261				}
2262			}
2263
2264		// Add elements to results, through postFinder if defined
2265		} else {
2266			matcherOut = condense(
2267				matcherOut === results ?
2268					matcherOut.splice( preexisting, matcherOut.length ) :
2269					matcherOut
2270			);
2271			if ( postFinder ) {
2272				postFinder( null, results, matcherOut, xml );
2273			} else {
2274				push.apply( results, matcherOut );
2275			}
2276		}
2277	});
2278}
2279
2280function matcherFromTokens( tokens ) {
2281	var checkContext, matcher, j,
2282		len = tokens.length,
2283		leadingRelative = Expr.relative[ tokens[0].type ],
2284		implicitRelative = leadingRelative || Expr.relative[" "],
2285		i = leadingRelative ? 1 : 0,
2286
2287		// The foundational matcher ensures that elements are reachable from top-level context(s)
2288		matchContext = addCombinator( function( elem ) {
2289			return elem === checkContext;
2290		}, implicitRelative, true ),
2291		matchAnyContext = addCombinator( function( elem ) {
2292			return indexOf( checkContext, elem ) > -1;
2293		}, implicitRelative, true ),
2294		matchers = [ function( elem, context, xml ) {
2295			var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
2296				(checkContext = context).nodeType ?
2297					matchContext( elem, context, xml ) :
2298					matchAnyContext( elem, context, xml ) );
2299			// Avoid hanging onto element (issue #299)
2300			checkContext = null;
2301			return ret;
2302		} ];
2303
2304	for ( ; i < len; i++ ) {
2305		if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
2306			matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
2307		} else {
2308			matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
2309
2310			// Return special upon seeing a positional matcher
2311			if ( matcher[ expando ] ) {
2312				// Find the next relative operator (if any) for proper handling
2313				j = ++i;
2314				for ( ; j < len; j++ ) {
2315					if ( Expr.relative[ tokens[j].type ] ) {
2316						break;
2317					}
2318				}
2319				return setMatcher(
2320					i > 1 && elementMatcher( matchers ),
2321					i > 1 && toSelector(
2322						// If the preceding token was a descendant combinator, insert an implicit any-element `*`
2323						tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
2324					).replace( rtrim, "$1" ),
2325					matcher,
2326					i < j && matcherFromTokens( tokens.slice( i, j ) ),
2327					j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
2328					j < len && toSelector( tokens )
2329				);
2330			}
2331			matchers.push( matcher );
2332		}
2333	}
2334
2335	return elementMatcher( matchers );
2336}
2337
2338function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
2339	var bySet = setMatchers.length > 0,
2340		byElement = elementMatchers.length > 0,
2341		superMatcher = function( seed, context, xml, results, outermost ) {
2342			var elem, j, matcher,
2343				matchedCount = 0,
2344				i = "0",
2345				unmatched = seed && [],
2346				setMatched = [],
2347				contextBackup = outermostContext,
2348				// We must always have either seed elements or outermost context
2349				elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
2350				// Use integer dirruns iff this is the outermost matcher
2351				dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
2352				len = elems.length;
2353
2354			if ( outermost ) {
2355				outermostContext = context !== document && context;
2356			}
2357
2358			// Add elements passing elementMatchers directly to results
2359			// Keep `i` a string if there are no elements so `matchedCount` will be "00" below
2360			// Support: IE<9, Safari
2361			// Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
2362			for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
2363				if ( byElement && elem ) {
2364					j = 0;
2365					while ( (matcher = elementMatchers[j++]) ) {
2366						if ( matcher( elem, context, xml ) ) {
2367							results.push( elem );
2368							break;
2369						}
2370					}
2371					if ( outermost ) {
2372						dirruns = dirrunsUnique;
2373					}
2374				}
2375
2376				// Track unmatched elements for set filters
2377				if ( bySet ) {
2378					// They will have gone through all possible matchers
2379					if ( (elem = !matcher && elem) ) {
2380						matchedCount--;
2381					}
2382
2383					// Lengthen the array for every element, matched or not
2384					if ( seed ) {
2385						unmatched.push( elem );
2386					}
2387				}
2388			}
2389
2390			// Apply set filters to unmatched elements
2391			matchedCount += i;
2392			if ( bySet && i !== matchedCount ) {
2393				j = 0;
2394				while ( (matcher = setMatchers[j++]) ) {
2395					matcher( unmatched, setMatched, context, xml );
2396				}
2397
2398				if ( seed ) {
2399					// Reintegrate element matches to eliminate the need for sorting
2400					if ( matchedCount > 0 ) {
2401						while ( i-- ) {
2402							if ( !(unmatched[i] || setMatched[i]) ) {
2403								setMatched[i] = pop.call( results );
2404							}
2405						}
2406					}
2407
2408					// Discard index placeholder values to get only actual matches
2409					setMatched = condense( setMatched );
2410				}
2411
2412				// Add matches to results
2413				push.apply( results, setMatched );
2414
2415				// Seedless set matches succeeding multiple successful matchers stipulate sorting
2416				if ( outermost && !seed && setMatched.length > 0 &&
2417					( matchedCount + setMatchers.length ) > 1 ) {
2418
2419					Sizzle.uniqueSort( results );
2420				}
2421			}
2422
2423			// Override manipulation of globals by nested matchers
2424			if ( outermost ) {
2425				dirruns = dirrunsUnique;
2426				outermostContext = contextBackup;
2427			}
2428
2429			return unmatched;
2430		};
2431
2432	return bySet ?
2433		markFunction( superMatcher ) :
2434		superMatcher;
2435}
2436
2437compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
2438	var i,
2439		setMatchers = [],
2440		elementMatchers = [],
2441		cached = compilerCache[ selector + " " ];
2442
2443	if ( !cached ) {
2444		// Generate a function of recursive functions that can be used to check each element
2445		if ( !match ) {
2446			match = tokenize( selector );
2447		}
2448		i = match.length;
2449		while ( i-- ) {
2450			cached = matcherFromTokens( match[i] );
2451			if ( cached[ expando ] ) {
2452				setMatchers.push( cached );
2453			} else {
2454				elementMatchers.push( cached );
2455			}
2456		}
2457
2458		// Cache the compiled function
2459		cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
2460
2461		// Save selector and tokenization
2462		cached.selector = selector;
2463	}
2464	return cached;
2465};
vendor: 4,109 bytes, lines 2466-2593
2466
2467/**
2468 * A low-level selection function that works with Sizzle's compiled
2469 *  selector functions
2470 * @param {String|Function} selector A selector or a pre-compiled
2471 *  selector function built with Sizzle.compile
2472 * @param {Element} context
2473 * @param {Array} [results]
2474 * @param {Array} [seed] A set of elements to match against
2475 */
2476select = Sizzle.select = function( selector, context, results, seed ) {
2477	var i, tokens, token, type, find,
2478		compiled = typeof selector === "function" && selector,
2479		match = !seed && tokenize( (selector = compiled.selector || selector) );
2480
2481	results = results || [];
2482
2483	// Try to minimize operations if there is no seed and only one group
2484	if ( match.length === 1 ) {
2485
2486		// Take a shortcut and set the context if the root selector is an ID
2487		tokens = match[0] = match[0].slice( 0 );
2488		if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
2489				support.getById && context.nodeType === 9 && documentIsHTML &&
2490				Expr.relative[ tokens[1].type ] ) {
2491
2492			context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
2493			if ( !context ) {
2494				return results;
2495
2496			// Precompiled matchers will still verify ancestry, so step up a level
2497			} else if ( compiled ) {
2498				context = context.parentNode;
2499			}
2500
2501			selector = selector.slice( tokens.shift().value.length );
2502		}
2503
2504		// Fetch a seed set for right-to-left matching
2505		i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
2506		while ( i-- ) {
2507			token = tokens[i];
2508
2509			// Abort if we hit a combinator
2510			if ( Expr.relative[ (type = token.type) ] ) {
2511				break;
2512			}
2513			if ( (find = Expr.find[ type ]) ) {
2514				// Search, expanding context for leading sibling combinators
2515				if ( (seed = find(
2516					token.matches[0].replace( runescape, funescape ),
2517					rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
2518				)) ) {
2519
2520					// If seed is empty or no tokens remain, we can return early
2521					tokens.splice( i, 1 );
2522					selector = seed.length && toSelector( tokens );
2523					if ( !selector ) {
2524						push.apply( results, seed );
2525						return results;
2526					}
2527
2528					break;
2529				}
2530			}
2531		}
2532	}
2533
2534	// Compile and execute a filtering function if one is not provided
2535	// Provide `match` to avoid retokenization if we modified the selector above
2536	( compiled || compile( selector, match ) )(
2537		seed,
2538		context,
2539		!documentIsHTML,
2540		results,
2541		rsibling.test( selector ) && testContext( context.parentNode ) || context
2542	);
2543	return results;
2544};
2545
2546// One-time assignments
2547
2548// Sort stability
2549support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
2550
2551// Support: Chrome 14-35+
2552// Always assume duplicates if they aren't passed to the comparison function
2553support.detectDuplicates = !!hasDuplicate;
2554
2555// Initialize against the default document
2556setDocument();
2557
2558// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
2559// Detached nodes confoundingly follow *each other*
2560support.sortDetached = assert(function( div1 ) {
2561	// Should return 1, but returns 4 (following)
2562	return div1.compareDocumentPosition( document.createElement("div") ) & 1;
2563});
2564
2565// Support: IE<8
2566// Prevent attribute/property "interpolation"
2567// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
2568if ( !assert(function( div ) {
2569	div.innerHTML = "<a href='#'></a>";
2570	return div.firstChild.getAttribute("href") === "#" ;
2571}) ) {
2572	addHandle( "type|href|height|width", function( elem, name, isXML ) {
2573		if ( !isXML ) {
2574			return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
2575		}
2576	});
2577}
2578
2579// Support: IE<9
2580// Use defaultValue in place of getAttribute("value")
2581if ( !support.attributes || !assert(function( div ) {
2582	div.innerHTML = "<input/>";
2583	div.firstChild.setAttribute( "value", "" );
2584	return div.firstChild.getAttribute( "value" ) === "";
2585}) ) {
2586	addHandle( "value", function( elem, name, isXML ) {
2587		if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
2588			return elem.defaultValue;
2589		}
2590	});
2591}
2592
2593// Support: IE<9
vendor: 13,056 bytes, lines 2594-3087
2594// Use getAttributeNode to fetch booleans when getAttribute lies
2595if ( !assert(function( div ) {
2596	return div.getAttribute("disabled") == null;
2597}) ) {
2598	addHandle( booleans, function( elem, name, isXML ) {
2599		var val;
2600		if ( !isXML ) {
2601			return elem[ name ] === true ? name.toLowerCase() :
2602					(val = elem.getAttributeNode( name )) && val.specified ?
2603					val.value :
2604				null;
2605		}
2606	});
2607}
2608
2609return Sizzle;
2610
2611})( window );
2612
2613
2614
2615jQuery.find = Sizzle;
2616jQuery.expr = Sizzle.selectors;
2617jQuery.expr[":"] = jQuery.expr.pseudos;
2618jQuery.unique = Sizzle.uniqueSort;
2619jQuery.text = Sizzle.getText;
2620jQuery.isXMLDoc = Sizzle.isXML;
2621jQuery.contains = Sizzle.contains;
2622
2623
2624
2625var rneedsContext = jQuery.expr.match.needsContext;
2626
2627var rsingleTag = (/^<(\w+)\s*\/?>(?:<\/\1>|)$/);
2628
2629
2630
2631var risSimple = /^.[^:#\[\.,]*$/;
2632
2633// Implement the identical functionality for filter and not
2634function winnow( elements, qualifier, not ) {
2635	if ( jQuery.isFunction( qualifier ) ) {
2636		return jQuery.grep( elements, function( elem, i ) {
2637			/* jshint -W018 */
2638			return !!qualifier.call( elem, i, elem ) !== not;
2639		});
2640
2641	}
2642
2643	if ( qualifier.nodeType ) {
2644		return jQuery.grep( elements, function( elem ) {
2645			return ( elem === qualifier ) !== not;
2646		});
2647
2648	}
2649
2650	if ( typeof qualifier === "string" ) {
2651		if ( risSimple.test( qualifier ) ) {
2652			return jQuery.filter( qualifier, elements, not );
2653		}
2654
2655		qualifier = jQuery.filter( qualifier, elements );
2656	}
2657
2658	return jQuery.grep( elements, function( elem ) {
2659		return ( indexOf.call( qualifier, elem ) >= 0 ) !== not;
2660	});
2661}
2662
2663jQuery.filter = function( expr, elems, not ) {
2664	var elem = elems[ 0 ];
2665
2666	if ( not ) {
2667		expr = ":not(" + expr + ")";
2668	}
2669
2670	return elems.length === 1 && elem.nodeType === 1 ?
2671		jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :
2672		jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
2673			return elem.nodeType === 1;
2674		}));
2675};
2676
2677jQuery.fn.extend({
2678	find: function( selector ) {
2679		var i,
2680			len = this.length,
2681			ret = [],
2682			self = this;
2683
2684		if ( typeof selector !== "string" ) {
2685			return this.pushStack( jQuery( selector ).filter(function() {
2686				for ( i = 0; i < len; i++ ) {
2687					if ( jQuery.contains( self[ i ], this ) ) {
2688						return true;
2689					}
2690				}
2691			}) );
2692		}
2693
2694		for ( i = 0; i < len; i++ ) {
2695			jQuery.find( selector, self[ i ], ret );
2696		}
2697
2698		// Needed because $( selector, context ) becomes $( context ).find( selector )
2699		ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );
2700		ret.selector = this.selector ? this.selector + " " + selector : selector;
2701		return ret;
2702	},
2703	filter: function( selector ) {
2704		return this.pushStack( winnow(this, selector || [], false) );
2705	},
2706	not: function( selector ) {
2707		return this.pushStack( winnow(this, selector || [], true) );
2708	},
2709	is: function( selector ) {
2710		return !!winnow(
2711			this,
2712
2713			// If this is a positional/relative selector, check membership in the returned set
2714			// so $("p:first").is("p:last") won't return true for a doc with two "p".
2715			typeof selector === "string" && rneedsContext.test( selector ) ?
2716				jQuery( selector ) :
2717				selector || [],
2718			false
2719		).length;
2720	}
2721});
2722
2723
2724// Initialize a jQuery object
2725
2726
2727// A central reference to the root jQuery(document)
2728var rootjQuery,
2729
2730	// A simple way to check for HTML strings
2731	// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
2732	// Strict HTML recognition (#11290: must start with <)
2733	rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
2734
2735	init = jQuery.fn.init = function( selector, context ) {
2736		var match, elem;
2737
2738		// HANDLE: $(""), $(null), $(undefined), $(false)
2739		if ( !selector ) {
2740			return this;
2741		}
2742
2743		// Handle HTML strings
2744		if ( typeof selector === "string" ) {
2745			if ( selector[0] === "<" && selector[ selector.length - 1 ] === ">" && selector.length >= 3 ) {
2746				// Assume that strings that start and end with <> are HTML and skip the regex check
2747				match = [ null, selector, null ];
2748
2749			} else {
2750				match = rquickExpr.exec( selector );
2751			}
2752
2753			// Match html or make sure no context is specified for #id
2754			if ( match && (match[1] || !context) ) {
2755
2756				// HANDLE: $(html) -> $(array)
2757				if ( match[1] ) {
2758					context = context instanceof jQuery ? context[0] : context;
2759
2760					// Option to run scripts is true for back-compat
2761					// Intentionally let the error be thrown if parseHTML is not present
2762					jQuery.merge( this, jQuery.parseHTML(
2763						match[1],
2764						context && context.nodeType ? context.ownerDocument || context : document,
2765						true
2766					) );
2767
2768					// HANDLE: $(html, props)
2769					if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {
2770						for ( match in context ) {
2771							// Properties of context are called as methods if possible
2772							if ( jQuery.isFunction( this[ match ] ) ) {
2773								this[ match ]( context[ match ] );
2774
2775							// ...and otherwise set as attributes
2776							} else {
2777								this.attr( match, context[ match ] );
2778							}
2779						}
2780					}
2781
2782					return this;
2783
2784				// HANDLE: $(#id)
2785				} else {
2786					elem = document.getElementById( match[2] );
2787
2788					// Support: Blackberry 4.6
2789					// gEBID returns nodes no longer in the document (#6963)
2790					if ( elem && elem.parentNode ) {
2791						// Inject the element directly into the jQuery object
2792						this.length = 1;
2793						this[0] = elem;
2794					}
2795
2796					this.context = document;
2797					this.selector = selector;
2798					return this;
2799				}
2800
2801			// HANDLE: $(expr, $(...))
2802			} else if ( !context || context.jquery ) {
2803				return ( context || rootjQuery ).find( selector );
2804
2805			// HANDLE: $(expr, context)
2806			// (which is just equivalent to: $(context).find(expr)
2807			} else {
2808				return this.constructor( context ).find( selector );
2809			}
2810
2811		// HANDLE: $(DOMElement)
2812		} else if ( selector.nodeType ) {
2813			this.context = this[0] = selector;
2814			this.length = 1;
2815			return this;
2816
2817		// HANDLE: $(function)
2818		// Shortcut for document ready
2819		} else if ( jQuery.isFunction( selector ) ) {
2820			return typeof rootjQuery.ready !== "undefined" ?
2821				rootjQuery.ready( selector ) :
2822				// Execute immediately if ready is not present
2823				selector( jQuery );
2824		}
2825
2826		if ( selector.selector !== undefined ) {
2827			this.selector = selector.selector;
2828			this.context = selector.context;
2829		}
2830
2831		return jQuery.makeArray( selector, this );
2832	};
2833
2834// Give the init function the jQuery prototype for later instantiation
2835init.prototype = jQuery.fn;
2836
2837// Initialize central reference
2838rootjQuery = jQuery( document );
2839
2840
2841var rparentsprev = /^(?:parents|prev(?:Until|All))/,
2842	// Methods guaranteed to produce a unique set when starting from a unique set
2843	guaranteedUnique = {
2844		children: true,
2845		contents: true,
2846		next: true,
2847		prev: true
2848	};
2849
2850jQuery.extend({
2851	dir: function( elem, dir, until ) {
2852		var matched = [],
2853			truncate = until !== undefined;
2854
2855		while ( (elem = elem[ dir ]) && elem.nodeType !== 9 ) {
2856			if ( elem.nodeType === 1 ) {
2857				if ( truncate && jQuery( elem ).is( until ) ) {
2858					break;
2859				}
2860				matched.push( elem );
2861			}
2862		}
2863		return matched;
2864	},
2865
2866	sibling: function( n, elem ) {
2867		var matched = [];
2868
2869		for ( ; n; n = n.nextSibling ) {
2870			if ( n.nodeType === 1 && n !== elem ) {
2871				matched.push( n );
2872			}
2873		}
2874
2875		return matched;
2876	}
2877});
2878
2879jQuery.fn.extend({
2880	has: function( target ) {
2881		var targets = jQuery( target, this ),
2882			l = targets.length;
2883
2884		return this.filter(function() {
2885			var i = 0;
2886			for ( ; i < l; i++ ) {
2887				if ( jQuery.contains( this, targets[i] ) ) {
2888					return true;
2889				}
2890			}
2891		});
2892	},
2893
2894	closest: function( selectors, context ) {
2895		var cur,
2896			i = 0,
2897			l = this.length,
2898			matched = [],
2899			pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
2900				jQuery( selectors, context || this.context ) :
2901				0;
2902
2903		for ( ; i < l; i++ ) {
2904			for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) {
2905				// Always skip document fragments
2906				if ( cur.nodeType < 11 && (pos ?
2907					pos.index(cur) > -1 :
2908
2909					// Don't pass non-elements to Sizzle
2910					cur.nodeType === 1 &&
2911						jQuery.find.matchesSelector(cur, selectors)) ) {
2912
2913					matched.push( cur );
2914					break;
2915				}
2916			}
2917		}
2918
2919		return this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched );
2920	},
2921
2922	// Determine the position of an element within the set
2923	index: function( elem ) {
2924
2925		// No argument, return index in parent
2926		if ( !elem ) {
2927			return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
2928		}
2929
2930		// Index in selector
2931		if ( typeof elem === "string" ) {
2932			return indexOf.call( jQuery( elem ), this[ 0 ] );
2933		}
2934
2935		// Locate the position of the desired element
2936		return indexOf.call( this,
2937
2938			// If it receives a jQuery object, the first element is used
2939			elem.jquery ? elem[ 0 ] : elem
2940		);
2941	},
2942
2943	add: function( selector, context ) {
2944		return this.pushStack(
2945			jQuery.unique(
2946				jQuery.merge( this.get(), jQuery( selector, context ) )
2947			)
2948		);
2949	},
2950
2951	addBack: function( selector ) {
2952		return this.add( selector == null ?
2953			this.prevObject : this.prevObject.filter(selector)
2954		);
2955	}
2956});
2957
2958function sibling( cur, dir ) {
2959	while ( (cur = cur[dir]) && cur.nodeType !== 1 ) {}
2960	return cur;
2961}
2962
2963jQuery.each({
2964	parent: function( elem ) {
2965		var parent = elem.parentNode;
2966		return parent && parent.nodeType !== 11 ? parent : null;
2967	},
2968	parents: function( elem ) {
2969		return jQuery.dir( elem, "parentNode" );
2970	},
2971	parentsUntil: function( elem, i, until ) {
2972		return jQuery.dir( elem, "parentNode", until );
2973	},
2974	next: function( elem ) {
2975		return sibling( elem, "nextSibling" );
2976	},
2977	prev: function( elem ) {
2978		return sibling( elem, "previousSibling" );
2979	},
2980	nextAll: function( elem ) {
2981		return jQuery.dir( elem, "nextSibling" );
2982	},
2983	prevAll: function( elem ) {
2984		return jQuery.dir( elem, "previousSibling" );
2985	},
2986	nextUntil: function( elem, i, until ) {
2987		return jQuery.dir( elem, "nextSibling", until );
2988	},
2989	prevUntil: function( elem, i, until ) {
2990		return jQuery.dir( elem, "previousSibling", until );
2991	},
2992	siblings: function( elem ) {
2993		return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );
2994	},
2995	children: function( elem ) {
2996		return jQuery.sibling( elem.firstChild );
2997	},
2998	contents: function( elem ) {
2999		return elem.contentDocument || jQuery.merge( [], elem.childNodes );
3000	}
3001}, function( name, fn ) {
3002	jQuery.fn[ name ] = function( until, selector ) {
3003		var matched = jQuery.map( this, fn, until );
3004
3005		if ( name.slice( -5 ) !== "Until" ) {
3006			selector = until;
3007		}
3008
3009		if ( selector && typeof selector === "string" ) {
3010			matched = jQuery.filter( selector, matched );
3011		}
3012
3013		if ( this.length > 1 ) {
3014			// Remove duplicates
3015			if ( !guaranteedUnique[ name ] ) {
3016				jQuery.unique( matched );
3017			}
3018
3019			// Reverse order for parents* and prev-derivatives
3020			if ( rparentsprev.test( name ) ) {
3021				matched.reverse();
3022			}
3023		}
3024
3025		return this.pushStack( matched );
3026	};
3027});
3028var rnotwhite = (/\S+/g);
3029
3030
3031
3032// String to Object options format cache
3033var optionsCache = {};
3034
3035// Convert String-formatted options into Object-formatted ones and store in cache
3036function createOptions( options ) {
3037	var object = optionsCache[ options ] = {};
3038	jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {
3039		object[ flag ] = true;
3040	});
3041	return object;
3042}
3043
3044/*
3045 * Create a callback list using the following parameters:
3046 *
3047 *	options: an optional list of space-separated options that will change how
3048 *			the callback list behaves or a more traditional option object
3049 *
3050 * By default a callback list will act like an event callback list and can be
3051 * "fired" multiple times.
3052 *
3053 * Possible options:
3054 *
3055 *	once:			will ensure the callback list can only be fired once (like a Deferred)
3056 *
3057 *	memory:			will keep track of previous values and will call any callback added
3058 *					after the list has been fired right away with the latest "memorized"
3059 *					values (like a Deferred)
3060 *
3061 *	unique:			will ensure a callback can only be added once (no duplicate in the list)
3062 *
3063 *	stopOnFalse:	interrupt callings when a callback returns false
3064 *
3065 */
3066jQuery.Callbacks = function( options ) {
3067
3068	// Convert options from String-formatted to Object-formatted if needed
3069	// (we check in cache first)
3070	options = typeof options === "string" ?
3071		( optionsCache[ options ] || createOptions( options ) ) :
3072		jQuery.extend( {}, options );
3073
3074	var // Last fire value (for non-forgettable lists)
3075		memory,
3076		// Flag to know if list was already fired
3077		fired,
3078		// Flag to know if list is currently firing
3079		firing,
3080		// First callback to fire (used internally by add and fireWith)
3081		firingStart,
3082		// End of the loop when firing
3083		firingLength,
3084		// Index of currently firing callback (modified by remove if needed)
3085		firingIndex,
3086		// Actual callback list
3087		list = [],
vendor: 5,061 bytes, lines 3088-3265
3088		// Stack of fire calls for repeatable lists
3089		stack = !options.once && [],
3090		// Fire callbacks
3091		fire = function( data ) {
3092			memory = options.memory && data;
3093			fired = true;
3094			firingIndex = firingStart || 0;
3095			firingStart = 0;
3096			firingLength = list.length;
3097			firing = true;
3098			for ( ; list && firingIndex < firingLength; firingIndex++ ) {
3099				if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {
3100					memory = false; // To prevent further calls using add
3101					break;
3102				}
3103			}
3104			firing = false;
3105			if ( list ) {
3106				if ( stack ) {
3107					if ( stack.length ) {
3108						fire( stack.shift() );
3109					}
3110				} else if ( memory ) {
3111					list = [];
3112				} else {
3113					self.disable();
3114				}
3115			}
3116		},
3117		// Actual Callbacks object
3118		self = {
3119			// Add a callback or a collection of callbacks to the list
3120			add: function() {
3121				if ( list ) {
3122					// First, we save the current length
3123					var start = list.length;
3124					(function add( args ) {
3125						jQuery.each( args, function( _, arg ) {
3126							var type = jQuery.type( arg );
3127							if ( type === "function" ) {
3128								if ( !options.unique || !self.has( arg ) ) {
3129									list.push( arg );
3130								}
3131							} else if ( arg && arg.length && type !== "string" ) {
3132								// Inspect recursively
3133								add( arg );
3134							}
3135						});
3136					})( arguments );
3137					// Do we need to add the callbacks to the
3138					// current firing batch?
3139					if ( firing ) {
3140						firingLength = list.length;
3141					// With memory, if we're not firing then
3142					// we should call right away
3143					} else if ( memory ) {
3144						firingStart = start;
3145						fire( memory );
3146					}
3147				}
3148				return this;
3149			},
3150			// Remove a callback from the list
3151			remove: function() {
3152				if ( list ) {
3153					jQuery.each( arguments, function( _, arg ) {
3154						var index;
3155						while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
3156							list.splice( index, 1 );
3157							// Handle firing indexes
3158							if ( firing ) {
3159								if ( index <= firingLength ) {
3160									firingLength--;
3161								}
3162								if ( index <= firingIndex ) {
3163									firingIndex--;
3164								}
3165							}
3166						}
3167					});
3168				}
3169				return this;
3170			},
3171			// Check if a given callback is in the list.
3172			// If no argument is given, return whether or not list has callbacks attached.
3173			has: function( fn ) {
3174				return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length );
3175			},
3176			// Remove all callbacks from the list
3177			empty: function() {
3178				list = [];
3179				firingLength = 0;
3180				return this;
3181			},
3182			// Have the list do nothing anymore
3183			disable: function() {
3184				list = stack = memory = undefined;
3185				return this;
3186			},
3187			// Is it disabled?
3188			disabled: function() {
3189				return !list;
3190			},
3191			// Lock the list in its current state
3192			lock: function() {
3193				stack = undefined;
3194				if ( !memory ) {
3195					self.disable();
3196				}
3197				return this;
3198			},
3199			// Is it locked?
3200			locked: function() {
3201				return !stack;
3202			},
3203			// Call all callbacks with the given context and arguments
3204			fireWith: function( context, args ) {
3205				if ( list && ( !fired || stack ) ) {
3206					args = args || [];
3207					args = [ context, args.slice ? args.slice() : args ];
3208					if ( firing ) {
3209						stack.push( args );
3210					} else {
3211						fire( args );
3212					}
3213				}
3214				return this;
3215			},
3216			// Call all the callbacks with the given arguments
3217			fire: function() {
3218				self.fireWith( this, arguments );
3219				return this;
3220			},
3221			// To know if the callbacks have already been called at least once
3222			fired: function() {
3223				return !!fired;
3224			}
3225		};
3226
3227	return self;
3228};
3229
3230
3231jQuery.extend({
3232
3233	Deferred: function( func ) {
3234		var tuples = [
3235				// action, add listener, listener list, final state
3236				[ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ],
3237				[ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ],
3238				[ "notify", "progress", jQuery.Callbacks("memory") ]
3239			],
3240			state = "pending",
3241			promise = {
3242				state: function() {
3243					return state;
3244				},
3245				always: function() {
3246					deferred.done( arguments ).fail( arguments );
3247					return this;
3248				},
3249				then: function( /* fnDone, fnFail, fnProgress */ ) {
3250					var fns = arguments;
3251					return jQuery.Deferred(function( newDefer ) {
3252						jQuery.each( tuples, function( i, tuple ) {
3253							var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];
3254							// deferred[ done | fail | progress ] for forwarding actions to newDefer
3255							deferred[ tuple[1] ](function() {
3256								var returned = fn && fn.apply( this, arguments );
3257								if ( returned && jQuery.isFunction( returned.promise ) ) {
3258									returned.promise()
3259										.done( newDefer.resolve )
3260										.fail( newDefer.reject )
3261										.progress( newDefer.notify );
3262								} else {
3263									newDefer[ tuple[ 0 ] + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments );
3264								}
3265							});
vendor: 122,876 bytes, lines 3266-7692
3266						});
3267						fns = null;
3268					}).promise();
3269				},
3270				// Get a promise for this deferred
3271				// If obj is provided, the promise aspect is added to the object
3272				promise: function( obj ) {
3273					return obj != null ? jQuery.extend( obj, promise ) : promise;
3274				}
3275			},
3276			deferred = {};
3277
3278		// Keep pipe for back-compat
3279		promise.pipe = promise.then;
3280
3281		// Add list-specific methods
3282		jQuery.each( tuples, function( i, tuple ) {
3283			var list = tuple[ 2 ],
3284				stateString = tuple[ 3 ];
3285
3286			// promise[ done | fail | progress ] = list.add
3287			promise[ tuple[1] ] = list.add;
3288
3289			// Handle state
3290			if ( stateString ) {
3291				list.add(function() {
3292					// state = [ resolved | rejected ]
3293					state = stateString;
3294
3295				// [ reject_list | resolve_list ].disable; progress_list.lock
3296				}, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );
3297			}
3298
3299			// deferred[ resolve | reject | notify ]
3300			deferred[ tuple[0] ] = function() {
3301				deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments );
3302				return this;
3303			};
3304			deferred[ tuple[0] + "With" ] = list.fireWith;
3305		});
3306
3307		// Make the deferred a promise
3308		promise.promise( deferred );
3309
3310		// Call given func if any
3311		if ( func ) {
3312			func.call( deferred, deferred );
3313		}
3314
3315		// All done!
3316		return deferred;
3317	},
3318
3319	// Deferred helper
3320	when: function( subordinate /* , ..., subordinateN */ ) {
3321		var i = 0,
3322			resolveValues = slice.call( arguments ),
3323			length = resolveValues.length,
3324
3325			// the count of uncompleted subordinates
3326			remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,
3327
3328			// the master Deferred. If resolveValues consist of only a single Deferred, just use that.
3329			deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
3330
3331			// Update function for both resolve and progress values
3332			updateFunc = function( i, contexts, values ) {
3333				return function( value ) {
3334					contexts[ i ] = this;
3335					values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
3336					if ( values === progressValues ) {
3337						deferred.notifyWith( contexts, values );
3338					} else if ( !( --remaining ) ) {
3339						deferred.resolveWith( contexts, values );
3340					}
3341				};
3342			},
3343
3344			progressValues, progressContexts, resolveContexts;
3345
3346		// Add listeners to Deferred subordinates; treat others as resolved
3347		if ( length > 1 ) {
3348			progressValues = new Array( length );
3349			progressContexts = new Array( length );
3350			resolveContexts = new Array( length );
3351			for ( ; i < length; i++ ) {
3352				if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
3353					resolveValues[ i ].promise()
3354						.done( updateFunc( i, resolveContexts, resolveValues ) )
3355						.fail( deferred.reject )
3356						.progress( updateFunc( i, progressContexts, progressValues ) );
3357				} else {
3358					--remaining;
3359				}
3360			}
3361		}
3362
3363		// If we're not waiting on anything, resolve the master
3364		if ( !remaining ) {
3365			deferred.resolveWith( resolveContexts, resolveValues );
3366		}
3367
3368		return deferred.promise();
3369	}
3370});
3371
3372
3373// The deferred used on DOM ready
3374var readyList;
3375
3376jQuery.fn.ready = function( fn ) {
3377	// Add the callback
3378	jQuery.ready.promise().done( fn );
3379
3380	return this;
3381};
3382
3383jQuery.extend({
3384	// Is the DOM ready to be used? Set to true once it occurs.
3385	isReady: false,
3386
3387	// A counter to track how many items to wait for before
3388	// the ready event fires. See #6781
3389	readyWait: 1,
3390
3391	// Hold (or release) the ready event
3392	holdReady: function( hold ) {
3393		if ( hold ) {
3394			jQuery.readyWait++;
3395		} else {
3396			jQuery.ready( true );
3397		}
3398	},
3399
3400	// Handle when the DOM is ready
3401	ready: function( wait ) {
3402
3403		// Abort if there are pending holds or we're already ready
3404		if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
3405			return;
3406		}
3407
3408		// Remember that the DOM is ready
3409		jQuery.isReady = true;
3410
3411		// If a normal DOM Ready event fired, decrement, and wait if need be
3412		if ( wait !== true && --jQuery.readyWait > 0 ) {
3413			return;
3414		}
3415
3416		// If there are functions bound, to execute
3417		readyList.resolveWith( document, [ jQuery ] );
3418
3419		// Trigger any bound ready events
3420		if ( jQuery.fn.triggerHandler ) {
3421			jQuery( document ).triggerHandler( "ready" );
3422			jQuery( document ).off( "ready" );
3423		}
3424	}
3425});
3426
3427/**
3428 * The ready event handler and self cleanup method
3429 */
3430function completed() {
3431	document.removeEventListener( "DOMContentLoaded", completed, false );
3432	window.removeEventListener( "load", completed, false );
3433	jQuery.ready();
3434}
3435
3436jQuery.ready.promise = function( obj ) {
3437	if ( !readyList ) {
3438
3439		readyList = jQuery.Deferred();
3440
3441		// Catch cases where $(document).ready() is called after the browser event has already occurred.
3442		// We once tried to use readyState "interactive" here, but it caused issues like the one
3443		// discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15
3444		if ( document.readyState === "complete" ) {
3445			// Handle it asynchronously to allow scripts the opportunity to delay ready
3446			setTimeout( jQuery.ready );
3447
3448		} else {
3449
3450			// Use the handy event callback
3451			document.addEventListener( "DOMContentLoaded", completed, false );
3452
3453			// A fallback to window.onload, that will always work
3454			window.addEventListener( "load", completed, false );
3455		}
3456	}
3457	return readyList.promise( obj );
3458};
3459
3460// Kick off the DOM ready check even if the user does not
3461jQuery.ready.promise();
3462
3463
3464
3465
3466// Multifunctional method to get and set values of a collection
3467// The value/s can optionally be executed if it's a function
3468var access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
3469	var i = 0,
3470		len = elems.length,
3471		bulk = key == null;
3472
3473	// Sets many values
3474	if ( jQuery.type( key ) === "object" ) {
3475		chainable = true;
3476		for ( i in key ) {
3477			jQuery.access( elems, fn, i, key[i], true, emptyGet, raw );
3478		}
3479
3480	// Sets one value
3481	} else if ( value !== undefined ) {
3482		chainable = true;
3483
3484		if ( !jQuery.isFunction( value ) ) {
3485			raw = true;
3486		}
3487
3488		if ( bulk ) {
3489			// Bulk operations run against the entire set
3490			if ( raw ) {
3491				fn.call( elems, value );
3492				fn = null;
3493
3494			// ...except when executing function values
3495			} else {
3496				bulk = fn;
3497				fn = function( elem, key, value ) {
3498					return bulk.call( jQuery( elem ), value );
3499				};
3500			}
3501		}
3502
3503		if ( fn ) {
3504			for ( ; i < len; i++ ) {
3505				fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) );
3506			}
3507		}
3508	}
3509
3510	return chainable ?
3511		elems :
3512
3513		// Gets
3514		bulk ?
3515			fn.call( elems ) :
3516			len ? fn( elems[0], key ) : emptyGet;
3517};
3518
3519
3520/**
3521 * Determines whether an object can have data
3522 */
3523jQuery.acceptData = function( owner ) {
3524	// Accepts only:
3525	//  - Node
3526	//    - Node.ELEMENT_NODE
3527	//    - Node.DOCUMENT_NODE
3528	//  - Object
3529	//    - Any
3530	/* jshint -W018 */
3531	return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
3532};
3533
3534
3535function Data() {
3536	// Support: Android<4,
3537	// Old WebKit does not have Object.preventExtensions/freeze method,
3538	// return new empty object instead with no [[set]] accessor
3539	Object.defineProperty( this.cache = {}, 0, {
3540		get: function() {
3541			return {};
3542		}
3543	});
3544
3545	this.expando = jQuery.expando + Data.uid++;
3546}
3547
3548Data.uid = 1;
3549Data.accepts = jQuery.acceptData;
3550
3551Data.prototype = {
3552	key: function( owner ) {
3553		// We can accept data for non-element nodes in modern browsers,
3554		// but we should not, see #8335.
3555		// Always return the key for a frozen object.
3556		if ( !Data.accepts( owner ) ) {
3557			return 0;
3558		}
3559
3560		var descriptor = {},
3561			// Check if the owner object already has a cache key
3562			unlock = owner[ this.expando ];
3563
3564		// If not, create one
3565		if ( !unlock ) {
3566			unlock = Data.uid++;
3567
3568			// Secure it in a non-enumerable, non-writable property
3569			try {
3570				descriptor[ this.expando ] = { value: unlock };
3571				Object.defineProperties( owner, descriptor );
3572
3573			// Support: Android<4
3574			// Fallback to a less secure definition
3575			} catch ( e ) {
3576				descriptor[ this.expando ] = unlock;
3577				jQuery.extend( owner, descriptor );
3578			}
3579		}
3580
3581		// Ensure the cache object
3582		if ( !this.cache[ unlock ] ) {
3583			this.cache[ unlock ] = {};
3584		}
3585
3586		return unlock;
3587	},
3588	set: function( owner, data, value ) {
3589		var prop,
3590			// There may be an unlock assigned to this node,
3591			// if there is no entry for this "owner", create one inline
3592			// and set the unlock as though an owner entry had always existed
3593			unlock = this.key( owner ),
3594			cache = this.cache[ unlock ];
3595
3596		// Handle: [ owner, key, value ] args
3597		if ( typeof data === "string" ) {
3598			cache[ data ] = value;
3599
3600		// Handle: [ owner, { properties } ] args
3601		} else {
3602			// Fresh assignments by object are shallow copied
3603			if ( jQuery.isEmptyObject( cache ) ) {
3604				jQuery.extend( this.cache[ unlock ], data );
3605			// Otherwise, copy the properties one-by-one to the cache object
3606			} else {
3607				for ( prop in data ) {
3608					cache[ prop ] = data[ prop ];
3609				}
3610			}
3611		}
3612		return cache;
3613	},
3614	get: function( owner, key ) {
3615		// Either a valid cache is found, or will be created.
3616		// New caches will be created and the unlock returned,
3617		// allowing direct access to the newly created
3618		// empty data object. A valid owner object must be provided.
3619		var cache = this.cache[ this.key( owner ) ];
3620
3621		return key === undefined ?
3622			cache : cache[ key ];
3623	},
3624	access: function( owner, key, value ) {
3625		var stored;
3626		// In cases where either:
3627		//
3628		//   1. No key was specified
3629		//   2. A string key was specified, but no value provided
3630		//
3631		// Take the "read" path and allow the get method to determine
3632		// which value to return, respectively either:
3633		//
3634		//   1. The entire cache object
3635		//   2. The data stored at the key
3636		//
3637		if ( key === undefined ||
3638				((key && typeof key === "string") && value === undefined) ) {
3639
3640			stored = this.get( owner, key );
3641
3642			return stored !== undefined ?
3643				stored : this.get( owner, jQuery.camelCase(key) );
3644		}
3645
3646		// [*]When the key is not a string, or both a key and value
3647		// are specified, set or extend (existing objects) with either:
3648		//
3649		//   1. An object of properties
3650		//   2. A key and value
3651		//
3652		this.set( owner, key, value );
3653
3654		// Since the "set" path can have two possible entry points
3655		// return the expected data based on which path was taken[*]
3656		return value !== undefined ? value : key;
3657	},
3658	remove: function( owner, key ) {
3659		var i, name, camel,
3660			unlock = this.key( owner ),
3661			cache = this.cache[ unlock ];
3662
3663		if ( key === undefined ) {
3664			this.cache[ unlock ] = {};
3665
3666		} else {
3667			// Support array or space separated string of keys
3668			if ( jQuery.isArray( key ) ) {
3669				// If "name" is an array of keys...
3670				// When data is initially created, via ("key", "val") signature,
3671				// keys will be converted to camelCase.
3672				// Since there is no way to tell _how_ a key was added, remove
3673				// both plain key and camelCase key. #12786
3674				// This will only penalize the array argument path.
3675				name = key.concat( key.map( jQuery.camelCase ) );
3676			} else {
3677				camel = jQuery.camelCase( key );
3678				// Try the string as a key before any manipulation
3679				if ( key in cache ) {
3680					name = [ key, camel ];
3681				} else {
3682					// If a key with the spaces exists, use it.
3683					// Otherwise, create an array by matching non-whitespace
3684					name = camel;
3685					name = name in cache ?
3686						[ name ] : ( name.match( rnotwhite ) || [] );
3687				}
3688			}
3689
3690			i = name.length;
3691			while ( i-- ) {
3692				delete cache[ name[ i ] ];
3693			}
3694		}
3695	},
3696	hasData: function( owner ) {
3697		return !jQuery.isEmptyObject(
3698			this.cache[ owner[ this.expando ] ] || {}
3699		);
3700	},
3701	discard: function( owner ) {
3702		if ( owner[ this.expando ] ) {
3703			delete this.cache[ owner[ this.expando ] ];
3704		}
3705	}
3706};
3707var data_priv = new Data();
3708
3709var data_user = new Data();
3710
3711
3712
3713//	Implementation Summary
3714//
3715//	1. Enforce API surface and semantic compatibility with 1.9.x branch
3716//	2. Improve the module's maintainability by reducing the storage
3717//		paths to a single mechanism.
3718//	3. Use the same single mechanism to support "private" and "user" data.
3719//	4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
3720//	5. Avoid exposing implementation details on user objects (eg. expando properties)
3721//	6. Provide a clear path for implementation upgrade to WeakMap in 2014
3722
3723var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
3724	rmultiDash = /([A-Z])/g;
3725
3726function dataAttr( elem, key, data ) {
3727	var name;
3728
3729	// If nothing was found internally, try to fetch any
3730	// data from the HTML5 data-* attribute
3731	if ( data === undefined && elem.nodeType === 1 ) {
3732		name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase();
3733		data = elem.getAttribute( name );
3734
3735		if ( typeof data === "string" ) {
3736			try {
3737				data = data === "true" ? true :
3738					data === "false" ? false :
3739					data === "null" ? null :
3740					// Only convert to a number if it doesn't change the string
3741					+data + "" === data ? +data :
3742					rbrace.test( data ) ? jQuery.parseJSON( data ) :
3743					data;
3744			} catch( e ) {}
3745
3746			// Make sure we set the data so it isn't changed later
3747			data_user.set( elem, key, data );
3748		} else {
3749			data = undefined;
3750		}
3751	}
3752	return data;
3753}
3754
3755jQuery.extend({
3756	hasData: function( elem ) {
3757		return data_user.hasData( elem ) || data_priv.hasData( elem );
3758	},
3759
3760	data: function( elem, name, data ) {
3761		return data_user.access( elem, name, data );
3762	},
3763
3764	removeData: function( elem, name ) {
3765		data_user.remove( elem, name );
3766	},
3767
3768	// TODO: Now that all calls to _data and _removeData have been replaced
3769	// with direct calls to data_priv methods, these can be deprecated.
3770	_data: function( elem, name, data ) {
3771		return data_priv.access( elem, name, data );
3772	},
3773
3774	_removeData: function( elem, name ) {
3775		data_priv.remove( elem, name );
3776	}
3777});
3778
3779jQuery.fn.extend({
3780	data: function( key, value ) {
3781		var i, name, data,
3782			elem = this[ 0 ],
3783			attrs = elem && elem.attributes;
3784
3785		// Gets all values
3786		if ( key === undefined ) {
3787			if ( this.length ) {
3788				data = data_user.get( elem );
3789
3790				if ( elem.nodeType === 1 && !data_priv.get( elem, "hasDataAttrs" ) ) {
3791					i = attrs.length;
3792					while ( i-- ) {
3793
3794						// Support: IE11+
3795						// The attrs elements can be null (#14894)
3796						if ( attrs[ i ] ) {
3797							name = attrs[ i ].name;
3798							if ( name.indexOf( "data-" ) === 0 ) {
3799								name = jQuery.camelCase( name.slice(5) );
3800								dataAttr( elem, name, data[ name ] );
3801							}
3802						}
3803					}
3804					data_priv.set( elem, "hasDataAttrs", true );
3805				}
3806			}
3807
3808			return data;
3809		}
3810
3811		// Sets multiple values
3812		if ( typeof key === "object" ) {
3813			return this.each(function() {
3814				data_user.set( this, key );
3815			});
3816		}
3817
3818		return access( this, function( value ) {
3819			var data,
3820				camelKey = jQuery.camelCase( key );
3821
3822			// The calling jQuery object (element matches) is not empty
3823			// (and therefore has an element appears at this[ 0 ]) and the
3824			// `value` parameter was not undefined. An empty jQuery object
3825			// will result in `undefined` for elem = this[ 0 ] which will
3826			// throw an exception if an attempt to read a data cache is made.
3827			if ( elem && value === undefined ) {
3828				// Attempt to get data from the cache
3829				// with the key as-is
3830				data = data_user.get( elem, key );
3831				if ( data !== undefined ) {
3832					return data;
3833				}
3834
3835				// Attempt to get data from the cache
3836				// with the key camelized
3837				data = data_user.get( elem, camelKey );
3838				if ( data !== undefined ) {
3839					return data;
3840				}
3841
3842				// Attempt to "discover" the data in
3843				// HTML5 custom data-* attrs
3844				data = dataAttr( elem, camelKey, undefined );
3845				if ( data !== undefined ) {
3846					return data;
3847				}
3848
3849				// We tried really hard, but the data doesn't exist.
3850				return;
3851			}
3852
3853			// Set the data...
3854			this.each(function() {
3855				// First, attempt to store a copy or reference of any
3856				// data that might've been store with a camelCased key.
3857				var data = data_user.get( this, camelKey );
3858
3859				// For HTML5 data-* attribute interop, we have to
3860				// store property names with dashes in a camelCase form.
3861				// This might not apply to all properties...*
3862				data_user.set( this, camelKey, value );
3863
3864				// *... In the case of properties that might _actually_
3865				// have dashes, we need to also store a copy of that
3866				// unchanged property.
3867				if ( key.indexOf("-") !== -1 && data !== undefined ) {
3868					data_user.set( this, key, value );
3869				}
3870			});
3871		}, null, value, arguments.length > 1, null, true );
3872	},
3873
3874	removeData: function( key ) {
3875		return this.each(function() {
3876			data_user.remove( this, key );
3877		});
3878	}
3879});
3880
3881
3882jQuery.extend({
3883	queue: function( elem, type, data ) {
3884		var queue;
3885
3886		if ( elem ) {
3887			type = ( type || "fx" ) + "queue";
3888			queue = data_priv.get( elem, type );
3889
3890			// Speed up dequeue by getting out quickly if this is just a lookup
3891			if ( data ) {
3892				if ( !queue || jQuery.isArray( data ) ) {
3893					queue = data_priv.access( elem, type, jQuery.makeArray(data) );
3894				} else {
3895					queue.push( data );
3896				}
3897			}
3898			return queue || [];
3899		}
3900	},
3901
3902	dequeue: function( elem, type ) {
3903		type = type || "fx";
3904
3905		var queue = jQuery.queue( elem, type ),
3906			startLength = queue.length,
3907			fn = queue.shift(),
3908			hooks = jQuery._queueHooks( elem, type ),
3909			next = function() {
3910				jQuery.dequeue( elem, type );
3911			};
3912
3913		// If the fx queue is dequeued, always remove the progress sentinel
3914		if ( fn === "inprogress" ) {
3915			fn = queue.shift();
3916			startLength--;
3917		}
3918
3919		if ( fn ) {
3920
3921			// Add a progress sentinel to prevent the fx queue from being
3922			// automatically dequeued
3923			if ( type === "fx" ) {
3924				queue.unshift( "inprogress" );
3925			}
3926
3927			// Clear up the last queue stop function
3928			delete hooks.stop;
3929			fn.call( elem, next, hooks );
3930		}
3931
3932		if ( !startLength && hooks ) {
3933			hooks.empty.fire();
3934		}
3935	},
3936
3937	// Not public - generate a queueHooks object, or return the current one
3938	_queueHooks: function( elem, type ) {
3939		var key = type + "queueHooks";
3940		return data_priv.get( elem, key ) || data_priv.access( elem, key, {
3941			empty: jQuery.Callbacks("once memory").add(function() {
3942				data_priv.remove( elem, [ type + "queue", key ] );
3943			})
3944		});
3945	}
3946});
3947
3948jQuery.fn.extend({
3949	queue: function( type, data ) {
3950		var setter = 2;
3951
3952		if ( typeof type !== "string" ) {
3953			data = type;
3954			type = "fx";
3955			setter--;
3956		}
3957
3958		if ( arguments.length < setter ) {
3959			return jQuery.queue( this[0], type );
3960		}
3961
3962		return data === undefined ?
3963			this :
3964			this.each(function() {
3965				var queue = jQuery.queue( this, type, data );
3966
3967				// Ensure a hooks for this queue
3968				jQuery._queueHooks( this, type );
3969
3970				if ( type === "fx" && queue[0] !== "inprogress" ) {
3971					jQuery.dequeue( this, type );
3972				}
3973			});
3974	},
3975	dequeue: function( type ) {
3976		return this.each(function() {
3977			jQuery.dequeue( this, type );
3978		});
3979	},
3980	clearQueue: function( type ) {
3981		return this.queue( type || "fx", [] );
3982	},
3983	// Get a promise resolved when queues of a certain type
3984	// are emptied (fx is the type by default)
3985	promise: function( type, obj ) {
3986		var tmp,
3987			count = 1,
3988			defer = jQuery.Deferred(),
3989			elements = this,
3990			i = this.length,
3991			resolve = function() {
3992				if ( !( --count ) ) {
3993					defer.resolveWith( elements, [ elements ] );
3994				}
3995			};
3996
3997		if ( typeof type !== "string" ) {
3998			obj = type;
3999			type = undefined;
4000		}
4001		type = type || "fx";
4002
4003		while ( i-- ) {
4004			tmp = data_priv.get( elements[ i ], type + "queueHooks" );
4005			if ( tmp && tmp.empty ) {
4006				count++;
4007				tmp.empty.add( resolve );
4008			}
4009		}
4010		resolve();
4011		return defer.promise( obj );
4012	}
4013});
4014var pnum = (/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/).source;
4015
4016var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
4017
4018var isHidden = function( elem, el ) {
4019		// isHidden might be called from jQuery#filter function;
4020		// in that case, element will be second argument
4021		elem = el || elem;
4022		return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem );
4023	};
4024
4025var rcheckableType = (/^(?:checkbox|radio)$/i);
4026
4027
4028
4029(function() {
4030	var fragment = document.createDocumentFragment(),
4031		div = fragment.appendChild( document.createElement( "div" ) ),
4032		input = document.createElement( "input" );
4033
4034	// Support: Safari<=5.1
4035	// Check state lost if the name is set (#11217)
4036	// Support: Windows Web Apps (WWA)
4037	// `name` and `type` must use .setAttribute for WWA (#14901)
4038	input.setAttribute( "type", "radio" );
4039	input.setAttribute( "checked", "checked" );
4040	input.setAttribute( "name", "t" );
4041
4042	div.appendChild( input );
4043
4044	// Support: Safari<=5.1, Android<4.2
4045	// Older WebKit doesn't clone checked state correctly in fragments
4046	support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
4047
4048	// Support: IE<=11+
4049	// Make sure textarea (and checkbox) defaultValue is properly cloned
4050	div.innerHTML = "<textarea>x</textarea>";
4051	support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
4052})();
4053var strundefined = typeof undefined;
4054
4055
4056
4057support.focusinBubbles = "onfocusin" in window;
4058
4059
4060var
4061	rkeyEvent = /^key/,
4062	rmouseEvent = /^(?:mouse|pointer|contextmenu)|click/,
4063	rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
4064	rtypenamespace = /^([^.]*)(?:\.(.+)|)$/;
4065
4066function returnTrue() {
4067	return true;
4068}
4069
4070function returnFalse() {
4071	return false;
4072}
4073
4074function safeActiveElement() {
4075	try {
4076		return document.activeElement;
4077	} catch ( err ) { }
4078}
4079
4080/*
4081 * Helper functions for managing events -- not part of the public interface.
4082 * Props to Dean Edwards' addEvent library for many of the ideas.
4083 */
4084jQuery.event = {
4085
4086	global: {},
4087
4088	add: function( elem, types, handler, data, selector ) {
4089
4090		var handleObjIn, eventHandle, tmp,
4091			events, t, handleObj,
4092			special, handlers, type, namespaces, origType,
4093			elemData = data_priv.get( elem );
4094
4095		// Don't attach events to noData or text/comment nodes (but allow plain objects)
4096		if ( !elemData ) {
4097			return;
4098		}
4099
4100		// Caller can pass in an object of custom data in lieu of the handler
4101		if ( handler.handler ) {
4102			handleObjIn = handler;
4103			handler = handleObjIn.handler;
4104			selector = handleObjIn.selector;
4105		}
4106
4107		// Make sure that the handler has a unique ID, used to find/remove it later
4108		if ( !handler.guid ) {
4109			handler.guid = jQuery.guid++;
4110		}
4111
4112		// Init the element's event structure and main handler, if this is the first
4113		if ( !(events = elemData.events) ) {
4114			events = elemData.events = {};
4115		}
4116		if ( !(eventHandle = elemData.handle) ) {
4117			eventHandle = elemData.handle = function( e ) {
4118				// Discard the second event of a jQuery.event.trigger() and
4119				// when an event is called after a page has unloaded
4120				return typeof jQuery !== strundefined && jQuery.event.triggered !== e.type ?
4121					jQuery.event.dispatch.apply( elem, arguments ) : undefined;
4122			};
4123		}
4124
4125		// Handle multiple events separated by a space
4126		types = ( types || "" ).match( rnotwhite ) || [ "" ];
4127		t = types.length;
4128		while ( t-- ) {
4129			tmp = rtypenamespace.exec( types[t] ) || [];
4130			type = origType = tmp[1];
4131			namespaces = ( tmp[2] || "" ).split( "." ).sort();
4132
4133			// There *must* be a type, no attaching namespace-only handlers
4134			if ( !type ) {
4135				continue;
4136			}
4137
4138			// If event changes its type, use the special event handlers for the changed type
4139			special = jQuery.event.special[ type ] || {};
4140
4141			// If selector defined, determine special event api type, otherwise given type
4142			type = ( selector ? special.delegateType : special.bindType ) || type;
4143
4144			// Update special based on newly reset type
4145			special = jQuery.event.special[ type ] || {};
4146
4147			// handleObj is passed to all event handlers
4148			handleObj = jQuery.extend({
4149				type: type,
4150				origType: origType,
4151				data: data,
4152				handler: handler,
4153				guid: handler.guid,
4154				selector: selector,
4155				needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
4156				namespace: namespaces.join(".")
4157			}, handleObjIn );
4158
4159			// Init the event handler queue if we're the first
4160			if ( !(handlers = events[ type ]) ) {
4161				handlers = events[ type ] = [];
4162				handlers.delegateCount = 0;
4163
4164				// Only use addEventListener if the special events handler returns false
4165				if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
4166					if ( elem.addEventListener ) {
4167						elem.addEventListener( type, eventHandle, false );
4168					}
4169				}
4170			}
4171
4172			if ( special.add ) {
4173				special.add.call( elem, handleObj );
4174
4175				if ( !handleObj.handler.guid ) {
4176					handleObj.handler.guid = handler.guid;
4177				}
4178			}
4179
4180			// Add to the element's handler list, delegates in front
4181			if ( selector ) {
4182				handlers.splice( handlers.delegateCount++, 0, handleObj );
4183			} else {
4184				handlers.push( handleObj );
4185			}
4186
4187			// Keep track of which events have ever been used, for event optimization
4188			jQuery.event.global[ type ] = true;
4189		}
4190
4191	},
4192
4193	// Detach an event or set of events from an element
4194	remove: function( elem, types, handler, selector, mappedTypes ) {
4195
4196		var j, origCount, tmp,
4197			events, t, handleObj,
4198			special, handlers, type, namespaces, origType,
4199			elemData = data_priv.hasData( elem ) && data_priv.get( elem );
4200
4201		if ( !elemData || !(events = elemData.events) ) {
4202			return;
4203		}
4204
4205		// Once for each type.namespace in types; type may be omitted
4206		types = ( types || "" ).match( rnotwhite ) || [ "" ];
4207		t = types.length;
4208		while ( t-- ) {
4209			tmp = rtypenamespace.exec( types[t] ) || [];
4210			type = origType = tmp[1];
4211			namespaces = ( tmp[2] || "" ).split( "." ).sort();
4212
4213			// Unbind all events (on this namespace, if provided) for the element
4214			if ( !type ) {
4215				for ( type in events ) {
4216					jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
4217				}
4218				continue;
4219			}
4220
4221			special = jQuery.event.special[ type ] || {};
4222			type = ( selector ? special.delegateType : special.bindType ) || type;
4223			handlers = events[ type ] || [];
4224			tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" );
4225
4226			// Remove matching events
4227			origCount = j = handlers.length;
4228			while ( j-- ) {
4229				handleObj = handlers[ j ];
4230
4231				if ( ( mappedTypes || origType === handleObj.origType ) &&
4232					( !handler || handler.guid === handleObj.guid ) &&
4233					( !tmp || tmp.test( handleObj.namespace ) ) &&
4234					( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) {
4235					handlers.splice( j, 1 );
4236
4237					if ( handleObj.selector ) {
4238						handlers.delegateCount--;
4239					}
4240					if ( special.remove ) {
4241						special.remove.call( elem, handleObj );
4242					}
4243				}
4244			}
4245
4246			// Remove generic event handler if we removed something and no more handlers exist
4247			// (avoids potential for endless recursion during removal of special event handlers)
4248			if ( origCount && !handlers.length ) {
4249				if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
4250					jQuery.removeEvent( elem, type, elemData.handle );
4251				}
4252
4253				delete events[ type ];
4254			}
4255		}
4256
4257		// Remove the expando if it's no longer used
4258		if ( jQuery.isEmptyObject( events ) ) {
4259			delete elemData.handle;
4260			data_priv.remove( elem, "events" );
4261		}
4262	},
4263
4264	trigger: function( event, data, elem, onlyHandlers ) {
4265
4266		var i, cur, tmp, bubbleType, ontype, handle, special,
4267			eventPath = [ elem || document ],
4268			type = hasOwn.call( event, "type" ) ? event.type : event,
4269			namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : [];
4270
4271		cur = tmp = elem = elem || document;
4272
4273		// Don't do events on text and comment nodes
4274		if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
4275			return;
4276		}
4277
4278		// focus/blur morphs to focusin/out; ensure we're not firing them right now
4279		if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
4280			return;
4281		}
4282
4283		if ( type.indexOf(".") >= 0 ) {
4284			// Namespaced trigger; create a regexp to match event type in handle()
4285			namespaces = type.split(".");
4286			type = namespaces.shift();
4287			namespaces.sort();
4288		}
4289		ontype = type.indexOf(":") < 0 && "on" + type;
4290
4291		// Caller can pass in a jQuery.Event object, Object, or just an event type string
4292		event = event[ jQuery.expando ] ?
4293			event :
4294			new jQuery.Event( type, typeof event === "object" && event );
4295
4296		// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
4297		event.isTrigger = onlyHandlers ? 2 : 3;
4298		event.namespace = namespaces.join(".");
4299		event.namespace_re = event.namespace ?
4300			new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) :
4301			null;
4302
4303		// Clean up the event in case it is being reused
4304		event.result = undefined;
4305		if ( !event.target ) {
4306			event.target = elem;
4307		}
4308
4309		// Clone any incoming data and prepend the event, creating the handler arg list
4310		data = data == null ?
4311			[ event ] :
4312			jQuery.makeArray( data, [ event ] );
4313
4314		// Allow special events to draw outside the lines
4315		special = jQuery.event.special[ type ] || {};
4316		if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
4317			return;
4318		}
4319
4320		// Determine event propagation path in advance, per W3C events spec (#9951)
4321		// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
4322		if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
4323
4324			bubbleType = special.delegateType || type;
4325			if ( !rfocusMorph.test( bubbleType + type ) ) {
4326				cur = cur.parentNode;
4327			}
4328			for ( ; cur; cur = cur.parentNode ) {
4329				eventPath.push( cur );
4330				tmp = cur;
4331			}
4332
4333			// Only add window if we got to document (e.g., not plain obj or detached DOM)
4334			if ( tmp === (elem.ownerDocument || document) ) {
4335				eventPath.push( tmp.defaultView || tmp.parentWindow || window );
4336			}
4337		}
4338
4339		// Fire handlers on the event path
4340		i = 0;
4341		while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) {
4342
4343			event.type = i > 1 ?
4344				bubbleType :
4345				special.bindType || type;
4346
4347			// jQuery handler
4348			handle = ( data_priv.get( cur, "events" ) || {} )[ event.type ] && data_priv.get( cur, "handle" );
4349			if ( handle ) {
4350				handle.apply( cur, data );
4351			}
4352
4353			// Native handler
4354			handle = ontype && cur[ ontype ];
4355			if ( handle && handle.apply && jQuery.acceptData( cur ) ) {
4356				event.result = handle.apply( cur, data );
4357				if ( event.result === false ) {
4358					event.preventDefault();
4359				}
4360			}
4361		}
4362		event.type = type;
4363
4364		// If nobody prevented the default action, do it now
4365		if ( !onlyHandlers && !event.isDefaultPrevented() ) {
4366
4367			if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) &&
4368				jQuery.acceptData( elem ) ) {
4369
4370				// Call a native DOM method on the target with the same name name as the event.
4371				// Don't do default actions on window, that's where global variables be (#6170)
4372				if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) {
4373
4374					// Don't re-trigger an onFOO event when we call its FOO() method
4375					tmp = elem[ ontype ];
4376
4377					if ( tmp ) {
4378						elem[ ontype ] = null;
4379					}
4380
4381					// Prevent re-triggering of the same event, since we already bubbled it above
4382					jQuery.event.triggered = type;
4383					elem[ type ]();
4384					jQuery.event.triggered = undefined;
4385
4386					if ( tmp ) {
4387						elem[ ontype ] = tmp;
4388					}
4389				}
4390			}
4391		}
4392
4393		return event.result;
4394	},
4395
4396	dispatch: function( event ) {
4397
4398		// Make a writable jQuery.Event from the native event object
4399		event = jQuery.event.fix( event );
4400
4401		var i, j, ret, matched, handleObj,
4402			handlerQueue = [],
4403			args = slice.call( arguments ),
4404			handlers = ( data_priv.get( this, "events" ) || {} )[ event.type ] || [],
4405			special = jQuery.event.special[ event.type ] || {};
4406
4407		// Use the fix-ed jQuery.Event rather than the (read-only) native event
4408		args[0] = event;
4409		event.delegateTarget = this;
4410
4411		// Call the preDispatch hook for the mapped type, and let it bail if desired
4412		if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
4413			return;
4414		}
4415
4416		// Determine handlers
4417		handlerQueue = jQuery.event.handlers.call( this, event, handlers );
4418
4419		// Run delegates first; they may want to stop propagation beneath us
4420		i = 0;
4421		while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) {
4422			event.currentTarget = matched.elem;
4423
4424			j = 0;
4425			while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) {
4426
4427				// Triggered event must either 1) have no namespace, or 2) have namespace(s)
4428				// a subset or equal to those in the bound event (both can have no namespace).
4429				if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) {
4430
4431					event.handleObj = handleObj;
4432					event.data = handleObj.data;
4433
4434					ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )
4435							.apply( matched.elem, args );
4436
4437					if ( ret !== undefined ) {
4438						if ( (event.result = ret) === false ) {
4439							event.preventDefault();
4440							event.stopPropagation();
4441						}
4442					}
4443				}
4444			}
4445		}
4446
4447		// Call the postDispatch hook for the mapped type
4448		if ( special.postDispatch ) {
4449			special.postDispatch.call( this, event );
4450		}
4451
4452		return event.result;
4453	},
4454
4455	handlers: function( event, handlers ) {
4456		var i, matches, sel, handleObj,
4457			handlerQueue = [],
4458			delegateCount = handlers.delegateCount,
4459			cur = event.target;
4460
4461		// Find delegate handlers
4462		// Black-hole SVG <use> instance trees (#13180)
4463		// Avoid non-left-click bubbling in Firefox (#3861)
4464		if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) {
4465
4466			for ( ; cur !== this; cur = cur.parentNode || this ) {
4467
4468				// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
4469				if ( cur.disabled !== true || event.type !== "click" ) {
4470					matches = [];
4471					for ( i = 0; i < delegateCount; i++ ) {
4472						handleObj = handlers[ i ];
4473
4474						// Don't conflict with Object.prototype properties (#13203)
4475						sel = handleObj.selector + " ";
4476
4477						if ( matches[ sel ] === undefined ) {
4478							matches[ sel ] = handleObj.needsContext ?
4479								jQuery( sel, this ).index( cur ) >= 0 :
4480								jQuery.find( sel, this, null, [ cur ] ).length;
4481						}
4482						if ( matches[ sel ] ) {
4483							matches.push( handleObj );
4484						}
4485					}
4486					if ( matches.length ) {
4487						handlerQueue.push({ elem: cur, handlers: matches });
4488					}
4489				}
4490			}
4491		}
4492
4493		// Add the remaining (directly-bound) handlers
4494		if ( delegateCount < handlers.length ) {
4495			handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) });
4496		}
4497
4498		return handlerQueue;
4499	},
4500
4501	// Includes some event props shared by KeyEvent and MouseEvent
4502	props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),
4503
4504	fixHooks: {},
4505
4506	keyHooks: {
4507		props: "char charCode key keyCode".split(" "),
4508		filter: function( event, original ) {
4509
4510			// Add which for key events
4511			if ( event.which == null ) {
4512				event.which = original.charCode != null ? original.charCode : original.keyCode;
4513			}
4514
4515			return event;
4516		}
4517	},
4518
4519	mouseHooks: {
4520		props: "button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "),
4521		filter: function( event, original ) {
4522			var eventDoc, doc, body,
4523				button = original.button;
4524
4525			// Calculate pageX/Y if missing and clientX/Y available
4526			if ( event.pageX == null && original.clientX != null ) {
4527				eventDoc = event.target.ownerDocument || document;
4528				doc = eventDoc.documentElement;
4529				body = eventDoc.body;
4530
4531				event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );
4532				event.pageY = original.clientY + ( doc && doc.scrollTop  || body && body.scrollTop  || 0 ) - ( doc && doc.clientTop  || body && body.clientTop  || 0 );
4533			}
4534
4535			// Add which for click: 1 === left; 2 === middle; 3 === right
4536			// Note: button is not normalized, so don't use it
4537			if ( !event.which && button !== undefined ) {
4538				event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
4539			}
4540
4541			return event;
4542		}
4543	},
4544
4545	fix: function( event ) {
4546		if ( event[ jQuery.expando ] ) {
4547			return event;
4548		}
4549
4550		// Create a writable copy of the event object and normalize some properties
4551		var i, prop, copy,
4552			type = event.type,
4553			originalEvent = event,
4554			fixHook = this.fixHooks[ type ];
4555
4556		if ( !fixHook ) {
4557			this.fixHooks[ type ] = fixHook =
4558				rmouseEvent.test( type ) ? this.mouseHooks :
4559				rkeyEvent.test( type ) ? this.keyHooks :
4560				{};
4561		}
4562		copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
4563
4564		event = new jQuery.Event( originalEvent );
4565
4566		i = copy.length;
4567		while ( i-- ) {
4568			prop = copy[ i ];
4569			event[ prop ] = originalEvent[ prop ];
4570		}
4571
4572		// Support: Cordova 2.5 (WebKit) (#13255)
4573		// All events should have a target; Cordova deviceready doesn't
4574		if ( !event.target ) {
4575			event.target = document;
4576		}
4577
4578		// Support: Safari 6.0+, Chrome<28
4579		// Target should not be a text node (#504, #13143)
4580		if ( event.target.nodeType === 3 ) {
4581			event.target = event.target.parentNode;
4582		}
4583
4584		return fixHook.filter ? fixHook.filter( event, originalEvent ) : event;
4585	},
4586
4587	special: {
4588		load: {
4589			// Prevent triggered image.load events from bubbling to window.load
4590			noBubble: true
4591		},
4592		focus: {
4593			// Fire native event if possible so blur/focus sequence is correct
4594			trigger: function() {
4595				if ( this !== safeActiveElement() && this.focus ) {
4596					this.focus();
4597					return false;
4598				}
4599			},
4600			delegateType: "focusin"
4601		},
4602		blur: {
4603			trigger: function() {
4604				if ( this === safeActiveElement() && this.blur ) {
4605					this.blur();
4606					return false;
4607				}
4608			},
4609			delegateType: "focusout"
4610		},
4611		click: {
4612			// For checkbox, fire native event so checked state will be right
4613			trigger: function() {
4614				if ( this.type === "checkbox" && this.click && jQuery.nodeName( this, "input" ) ) {
4615					this.click();
4616					return false;
4617				}
4618			},
4619
4620			// For cross-browser consistency, don't fire native .click() on links
4621			_default: function( event ) {
4622				return jQuery.nodeName( event.target, "a" );
4623			}
4624		},
4625
4626		beforeunload: {
4627			postDispatch: function( event ) {
4628
4629				// Support: Firefox 20+
4630				// Firefox doesn't alert if the returnValue field is not set.
4631				if ( event.result !== undefined && event.originalEvent ) {
4632					event.originalEvent.returnValue = event.result;
4633				}
4634			}
4635		}
4636	},
4637
4638	simulate: function( type, elem, event, bubble ) {
4639		// Piggyback on a donor event to simulate a different one.
4640		// Fake originalEvent to avoid donor's stopPropagation, but if the
4641		// simulated event prevents default then we do the same on the donor.
4642		var e = jQuery.extend(
4643			new jQuery.Event(),
4644			event,
4645			{
4646				type: type,
4647				isSimulated: true,
4648				originalEvent: {}
4649			}
4650		);
4651		if ( bubble ) {
4652			jQuery.event.trigger( e, null, elem );
4653		} else {
4654			jQuery.event.dispatch.call( elem, e );
4655		}
4656		if ( e.isDefaultPrevented() ) {
4657			event.preventDefault();
4658		}
4659	}
4660};
4661
4662jQuery.removeEvent = function( elem, type, handle ) {
4663	if ( elem.removeEventListener ) {
4664		elem.removeEventListener( type, handle, false );
4665	}
4666};
4667
4668jQuery.Event = function( src, props ) {
4669	// Allow instantiation without the 'new' keyword
4670	if ( !(this instanceof jQuery.Event) ) {
4671		return new jQuery.Event( src, props );
4672	}
4673
4674	// Event object
4675	if ( src && src.type ) {
4676		this.originalEvent = src;
4677		this.type = src.type;
4678
4679		// Events bubbling up the document may have been marked as prevented
4680		// by a handler lower down the tree; reflect the correct value.
4681		this.isDefaultPrevented = src.defaultPrevented ||
4682				src.defaultPrevented === undefined &&
4683				// Support: Android<4.0
4684				src.returnValue === false ?
4685			returnTrue :
4686			returnFalse;
4687
4688	// Event type
4689	} else {
4690		this.type = src;
4691	}
4692
4693	// Put explicitly provided properties onto the event object
4694	if ( props ) {
4695		jQuery.extend( this, props );
4696	}
4697
4698	// Create a timestamp if incoming event doesn't have one
4699	this.timeStamp = src && src.timeStamp || jQuery.now();
4700
4701	// Mark it as fixed
4702	this[ jQuery.expando ] = true;
4703};
4704
4705// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
4706// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
4707jQuery.Event.prototype = {
4708	isDefaultPrevented: returnFalse,
4709	isPropagationStopped: returnFalse,
4710	isImmediatePropagationStopped: returnFalse,
4711
4712	preventDefault: function() {
4713		var e = this.originalEvent;
4714
4715		this.isDefaultPrevented = returnTrue;
4716
4717		if ( e && e.preventDefault ) {
4718			e.preventDefault();
4719		}
4720	},
4721	stopPropagation: function() {
4722		var e = this.originalEvent;
4723
4724		this.isPropagationStopped = returnTrue;
4725
4726		if ( e && e.stopPropagation ) {
4727			e.stopPropagation();
4728		}
4729	},
4730	stopImmediatePropagation: function() {
4731		var e = this.originalEvent;
4732
4733		this.isImmediatePropagationStopped = returnTrue;
4734
4735		if ( e && e.stopImmediatePropagation ) {
4736			e.stopImmediatePropagation();
4737		}
4738
4739		this.stopPropagation();
4740	}
4741};
4742
4743// Create mouseenter/leave events using mouseover/out and event-time checks
4744// Support: Chrome 15+
4745jQuery.each({
4746	mouseenter: "mouseover",
4747	mouseleave: "mouseout",
4748	pointerenter: "pointerover",
4749	pointerleave: "pointerout"
4750}, function( orig, fix ) {
4751	jQuery.event.special[ orig ] = {
4752		delegateType: fix,
4753		bindType: fix,
4754
4755		handle: function( event ) {
4756			var ret,
4757				target = this,
4758				related = event.relatedTarget,
4759				handleObj = event.handleObj;
4760
4761			// For mousenter/leave call the handler if related is outside the target.
4762			// NB: No relatedTarget if the mouse left/entered the browser window
4763			if ( !related || (related !== target && !jQuery.contains( target, related )) ) {
4764				event.type = handleObj.origType;
4765				ret = handleObj.handler.apply( this, arguments );
4766				event.type = fix;
4767			}
4768			return ret;
4769		}
4770	};
4771});
4772
4773// Support: Firefox, Chrome, Safari
4774// Create "bubbling" focus and blur events
4775if ( !support.focusinBubbles ) {
4776	jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
4777
4778		// Attach a single capturing handler on the document while someone wants focusin/focusout
4779		var handler = function( event ) {
4780				jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );
4781			};
4782
4783		jQuery.event.special[ fix ] = {
4784			setup: function() {
4785				var doc = this.ownerDocument || this,
4786					attaches = data_priv.access( doc, fix );
4787
4788				if ( !attaches ) {
4789					doc.addEventListener( orig, handler, true );
4790				}
4791				data_priv.access( doc, fix, ( attaches || 0 ) + 1 );
4792			},
4793			teardown: function() {
4794				var doc = this.ownerDocument || this,
4795					attaches = data_priv.access( doc, fix ) - 1;
4796
4797				if ( !attaches ) {
4798					doc.removeEventListener( orig, handler, true );
4799					data_priv.remove( doc, fix );
4800
4801				} else {
4802					data_priv.access( doc, fix, attaches );
4803				}
4804			}
4805		};
4806	});
4807}
4808
4809jQuery.fn.extend({
4810
4811	on: function( types, selector, data, fn, /*INTERNAL*/ one ) {
4812		var origFn, type;
4813
4814		// Types can be a map of types/handlers
4815		if ( typeof types === "object" ) {
4816			// ( types-Object, selector, data )
4817			if ( typeof selector !== "string" ) {
4818				// ( types-Object, data )
4819				data = data || selector;
4820				selector = undefined;
4821			}
4822			for ( type in types ) {
4823				this.on( type, selector, data, types[ type ], one );
4824			}
4825			return this;
4826		}
4827
4828		if ( data == null && fn == null ) {
4829			// ( types, fn )
4830			fn = selector;
4831			data = selector = undefined;
4832		} else if ( fn == null ) {
4833			if ( typeof selector === "string" ) {
4834				// ( types, selector, fn )
4835				fn = data;
4836				data = undefined;
4837			} else {
4838				// ( types, data, fn )
4839				fn = data;
4840				data = selector;
4841				selector = undefined;
4842			}
4843		}
4844		if ( fn === false ) {
4845			fn = returnFalse;
4846		} else if ( !fn ) {
4847			return this;
4848		}
4849
4850		if ( one === 1 ) {
4851			origFn = fn;
4852			fn = function( event ) {
4853				// Can use an empty set, since event contains the info
4854				jQuery().off( event );
4855				return origFn.apply( this, arguments );
4856			};
4857			// Use same guid so caller can remove using origFn
4858			fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
4859		}
4860		return this.each( function() {
4861			jQuery.event.add( this, types, fn, data, selector );
4862		});
4863	},
4864	one: function( types, selector, data, fn ) {
4865		return this.on( types, selector, data, fn, 1 );
4866	},
4867	off: function( types, selector, fn ) {
4868		var handleObj, type;
4869		if ( types && types.preventDefault && types.handleObj ) {
4870			// ( event )  dispatched jQuery.Event
4871			handleObj = types.handleObj;
4872			jQuery( types.delegateTarget ).off(
4873				handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType,
4874				handleObj.selector,
4875				handleObj.handler
4876			);
4877			return this;
4878		}
4879		if ( typeof types === "object" ) {
4880			// ( types-object [, selector] )
4881			for ( type in types ) {
4882				this.off( type, selector, types[ type ] );
4883			}
4884			return this;
4885		}
4886		if ( selector === false || typeof selector === "function" ) {
4887			// ( types [, fn] )
4888			fn = selector;
4889			selector = undefined;
4890		}
4891		if ( fn === false ) {
4892			fn = returnFalse;
4893		}
4894		return this.each(function() {
4895			jQuery.event.remove( this, types, fn, selector );
4896		});
4897	},
4898
4899	trigger: function( type, data ) {
4900		return this.each(function() {
4901			jQuery.event.trigger( type, data, this );
4902		});
4903	},
4904	triggerHandler: function( type, data ) {
4905		var elem = this[0];
4906		if ( elem ) {
4907			return jQuery.event.trigger( type, data, elem, true );
4908		}
4909	}
4910});
4911
4912
4913var
4914	rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,
4915	rtagName = /<([\w:]+)/,
4916	rhtml = /<|&#?\w+;/,
4917	rnoInnerhtml = /<(?:script|style|link)/i,
4918	// checked="checked" or checked
4919	rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
4920	rscriptType = /^$|\/(?:java|ecma)script/i,
4921	rscriptTypeMasked = /^true\/(.*)/,
4922	rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,
4923
4924	// We have to close these tags to support XHTML (#13200)
4925	wrapMap = {
4926
4927		// Support: IE9
4928		option: [ 1, "<select multiple='multiple'>", "</select>" ],
4929
4930		thead: [ 1, "<table>", "</table>" ],
4931		col: [ 2, "<table><colgroup>", "</colgroup></table>" ],
4932		tr: [ 2, "<table><tbody>", "</tbody></table>" ],
4933		td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
4934
4935		_default: [ 0, "", "" ]
4936	};
4937
4938// Support: IE9
4939wrapMap.optgroup = wrapMap.option;
4940
4941wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
4942wrapMap.th = wrapMap.td;
4943
4944// Support: 1.x compatibility
4945// Manipulating tables requires a tbody
4946function manipulationTarget( elem, content ) {
4947	return jQuery.nodeName( elem, "table" ) &&
4948		jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ?
4949
4950		elem.getElementsByTagName("tbody")[0] ||
4951			elem.appendChild( elem.ownerDocument.createElement("tbody") ) :
4952		elem;
4953}
4954
4955// Replace/restore the type attribute of script elements for safe DOM manipulation
4956function disableScript( elem ) {
4957	elem.type = (elem.getAttribute("type") !== null) + "/" + elem.type;
4958	return elem;
4959}
4960function restoreScript( elem ) {
4961	var match = rscriptTypeMasked.exec( elem.type );
4962
4963	if ( match ) {
4964		elem.type = match[ 1 ];
4965	} else {
4966		elem.removeAttribute("type");
4967	}
4968
4969	return elem;
4970}
4971
4972// Mark scripts as having already been evaluated
4973function setGlobalEval( elems, refElements ) {
4974	var i = 0,
4975		l = elems.length;
4976
4977	for ( ; i < l; i++ ) {
4978		data_priv.set(
4979			elems[ i ], "globalEval", !refElements || data_priv.get( refElements[ i ], "globalEval" )
4980		);
4981	}
4982}
4983
4984function cloneCopyEvent( src, dest ) {
4985	var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;
4986
4987	if ( dest.nodeType !== 1 ) {
4988		return;
4989	}
4990
4991	// 1. Copy private data: events, handlers, etc.
4992	if ( data_priv.hasData( src ) ) {
4993		pdataOld = data_priv.access( src );
4994		pdataCur = data_priv.set( dest, pdataOld );
4995		events = pdataOld.events;
4996
4997		if ( events ) {
4998			delete pdataCur.handle;
4999			pdataCur.events = {};
5000
5001			for ( type in events ) {
5002				for ( i = 0, l = events[ type ].length; i < l; i++ ) {
5003					jQuery.event.add( dest, type, events[ type ][ i ] );
5004				}
5005			}
5006		}
5007	}
5008
5009	// 2. Copy user data
5010	if ( data_user.hasData( src ) ) {
5011		udataOld = data_user.access( src );
5012		udataCur = jQuery.extend( {}, udataOld );
5013
5014		data_user.set( dest, udataCur );
5015	}
5016}
5017
5018function getAll( context, tag ) {
5019	var ret = context.getElementsByTagName ? context.getElementsByTagName( tag || "*" ) :
5020			context.querySelectorAll ? context.querySelectorAll( tag || "*" ) :
5021			[];
5022
5023	return tag === undefined || tag && jQuery.nodeName( context, tag ) ?
5024		jQuery.merge( [ context ], ret ) :
5025		ret;
5026}
5027
5028// Fix IE bugs, see support tests
5029function fixInput( src, dest ) {
5030	var nodeName = dest.nodeName.toLowerCase();
5031
5032	// Fails to persist the checked state of a cloned checkbox or radio button.
5033	if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
5034		dest.checked = src.checked;
5035
5036	// Fails to return the selected option to the default selected state when cloning options
5037	} else if ( nodeName === "input" || nodeName === "textarea" ) {
5038		dest.defaultValue = src.defaultValue;
5039	}
5040}
5041
5042jQuery.extend({
5043	clone: function( elem, dataAndEvents, deepDataAndEvents ) {
5044		var i, l, srcElements, destElements,
5045			clone = elem.cloneNode( true ),
5046			inPage = jQuery.contains( elem.ownerDocument, elem );
5047
5048		// Fix IE cloning issues
5049		if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&
5050				!jQuery.isXMLDoc( elem ) ) {
5051
5052			// We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2
5053			destElements = getAll( clone );
5054			srcElements = getAll( elem );
5055
5056			for ( i = 0, l = srcElements.length; i < l; i++ ) {
5057				fixInput( srcElements[ i ], destElements[ i ] );
5058			}
5059		}
5060
5061		// Copy the events from the original to the clone
5062		if ( dataAndEvents ) {
5063			if ( deepDataAndEvents ) {
5064				srcElements = srcElements || getAll( elem );
5065				destElements = destElements || getAll( clone );
5066
5067				for ( i = 0, l = srcElements.length; i < l; i++ ) {
5068					cloneCopyEvent( srcElements[ i ], destElements[ i ] );
5069				}
5070			} else {
5071				cloneCopyEvent( elem, clone );
5072			}
5073		}
5074
5075		// Preserve script evaluation history
5076		destElements = getAll( clone, "script" );
5077		if ( destElements.length > 0 ) {
5078			setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
5079		}
5080
5081		// Return the cloned set
5082		return clone;
5083	},
5084
5085	buildFragment: function( elems, context, scripts, selection ) {
5086		var elem, tmp, tag, wrap, contains, j,
5087			fragment = context.createDocumentFragment(),
5088			nodes = [],
5089			i = 0,
5090			l = elems.length;
5091
5092		for ( ; i < l; i++ ) {
5093			elem = elems[ i ];
5094
5095			if ( elem || elem === 0 ) {
5096
5097				// Add nodes directly
5098				if ( jQuery.type( elem ) === "object" ) {
5099					// Support: QtWebKit, PhantomJS
5100					// push.apply(_, arraylike) throws on ancient WebKit
5101					jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
5102
5103				// Convert non-html into a text node
5104				} else if ( !rhtml.test( elem ) ) {
5105					nodes.push( context.createTextNode( elem ) );
5106
5107				// Convert html into DOM nodes
5108				} else {
5109					tmp = tmp || fragment.appendChild( context.createElement("div") );
5110
5111					// Deserialize a standard representation
5112					tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
5113					wrap = wrapMap[ tag ] || wrapMap._default;
5114					tmp.innerHTML = wrap[ 1 ] + elem.replace( rxhtmlTag, "<$1></$2>" ) + wrap[ 2 ];
5115
5116					// Descend through wrappers to the right content
5117					j = wrap[ 0 ];
5118					while ( j-- ) {
5119						tmp = tmp.lastChild;
5120					}
5121
5122					// Support: QtWebKit, PhantomJS
5123					// push.apply(_, arraylike) throws on ancient WebKit
5124					jQuery.merge( nodes, tmp.childNodes );
5125
5126					// Remember the top-level container
5127					tmp = fragment.firstChild;
5128
5129					// Ensure the created nodes are orphaned (#12392)
5130					tmp.textContent = "";
5131				}
5132			}
5133		}
5134
5135		// Remove wrapper from fragment
5136		fragment.textContent = "";
5137
5138		i = 0;
5139		while ( (elem = nodes[ i++ ]) ) {
5140
5141			// #4087 - If origin and destination elements are the same, and this is
5142			// that element, do not do anything
5143			if ( selection && jQuery.inArray( elem, selection ) !== -1 ) {
5144				continue;
5145			}
5146
5147			contains = jQuery.contains( elem.ownerDocument, elem );
5148
5149			// Append to fragment
5150			tmp = getAll( fragment.appendChild( elem ), "script" );
5151
5152			// Preserve script evaluation history
5153			if ( contains ) {
5154				setGlobalEval( tmp );
5155			}
5156
5157			// Capture executables
5158			if ( scripts ) {
5159				j = 0;
5160				while ( (elem = tmp[ j++ ]) ) {
5161					if ( rscriptType.test( elem.type || "" ) ) {
5162						scripts.push( elem );
5163					}
5164				}
5165			}
5166		}
5167
5168		return fragment;
5169	},
5170
5171	cleanData: function( elems ) {
5172		var data, elem, type, key,
5173			special = jQuery.event.special,
5174			i = 0;
5175
5176		for ( ; (elem = elems[ i ]) !== undefined; i++ ) {
5177			if ( jQuery.acceptData( elem ) ) {
5178				key = elem[ data_priv.expando ];
5179
5180				if ( key && (data = data_priv.cache[ key ]) ) {
5181					if ( data.events ) {
5182						for ( type in data.events ) {
5183							if ( special[ type ] ) {
5184								jQuery.event.remove( elem, type );
5185
5186							// This is a shortcut to avoid jQuery.event.remove's overhead
5187							} else {
5188								jQuery.removeEvent( elem, type, data.handle );
5189							}
5190						}
5191					}
5192					if ( data_priv.cache[ key ] ) {
5193						// Discard any remaining `private` data
5194						delete data_priv.cache[ key ];
5195					}
5196				}
5197			}
5198			// Discard any remaining `user` data
5199			delete data_user.cache[ elem[ data_user.expando ] ];
5200		}
5201	}
5202});
5203
5204jQuery.fn.extend({
5205	text: function( value ) {
5206		return access( this, function( value ) {
5207			return value === undefined ?
5208				jQuery.text( this ) :
5209				this.empty().each(function() {
5210					if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
5211						this.textContent = value;
5212					}
5213				});
5214		}, null, value, arguments.length );
5215	},
5216
5217	append: function() {
5218		return this.domManip( arguments, function( elem ) {
5219			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
5220				var target = manipulationTarget( this, elem );
5221				target.appendChild( elem );
5222			}
5223		});
5224	},
5225
5226	prepend: function() {
5227		return this.domManip( arguments, function( elem ) {
5228			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
5229				var target = manipulationTarget( this, elem );
5230				target.insertBefore( elem, target.firstChild );
5231			}
5232		});
5233	},
5234
5235	before: function() {
5236		return this.domManip( arguments, function( elem ) {
5237			if ( this.parentNode ) {
5238				this.parentNode.insertBefore( elem, this );
5239			}
5240		});
5241	},
5242
5243	after: function() {
5244		return this.domManip( arguments, function( elem ) {
5245			if ( this.parentNode ) {
5246				this.parentNode.insertBefore( elem, this.nextSibling );
5247			}
5248		});
5249	},
5250
5251	remove: function( selector, keepData /* Internal Use Only */ ) {
5252		var elem,
5253			elems = selector ? jQuery.filter( selector, this ) : this,
5254			i = 0;
5255
5256		for ( ; (elem = elems[i]) != null; i++ ) {
5257			if ( !keepData && elem.nodeType === 1 ) {
5258				jQuery.cleanData( getAll( elem ) );
5259			}
5260
5261			if ( elem.parentNode ) {
5262				if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) {
5263					setGlobalEval( getAll( elem, "script" ) );
5264				}
5265				elem.parentNode.removeChild( elem );
5266			}
5267		}
5268
5269		return this;
5270	},
5271
5272	empty: function() {
5273		var elem,
5274			i = 0;
5275
5276		for ( ; (elem = this[i]) != null; i++ ) {
5277			if ( elem.nodeType === 1 ) {
5278
5279				// Prevent memory leaks
5280				jQuery.cleanData( getAll( elem, false ) );
5281
5282				// Remove any remaining nodes
5283				elem.textContent = "";
5284			}
5285		}
5286
5287		return this;
5288	},
5289
5290	clone: function( dataAndEvents, deepDataAndEvents ) {
5291		dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
5292		deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
5293
5294		return this.map(function() {
5295			return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
5296		});
5297	},
5298
5299	html: function( value ) {
5300		return access( this, function( value ) {
5301			var elem = this[ 0 ] || {},
5302				i = 0,
5303				l = this.length;
5304
5305			if ( value === undefined && elem.nodeType === 1 ) {
5306				return elem.innerHTML;
5307			}
5308
5309			// See if we can take a shortcut and just use innerHTML
5310			if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
5311				!wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {
5312
5313				value = value.replace( rxhtmlTag, "<$1></$2>" );
5314
5315				try {
5316					for ( ; i < l; i++ ) {
5317						elem = this[ i ] || {};
5318
5319						// Remove element nodes and prevent memory leaks
5320						if ( elem.nodeType === 1 ) {
5321							jQuery.cleanData( getAll( elem, false ) );
5322							elem.innerHTML = value;
5323						}
5324					}
5325
5326					elem = 0;
5327
5328				// If using innerHTML throws an exception, use the fallback method
5329				} catch( e ) {}
5330			}
5331
5332			if ( elem ) {
5333				this.empty().append( value );
5334			}
5335		}, null, value, arguments.length );
5336	},
5337
5338	replaceWith: function() {
5339		var arg = arguments[ 0 ];
5340
5341		// Make the changes, replacing each context element with the new content
5342		this.domManip( arguments, function( elem ) {
5343			arg = this.parentNode;
5344
5345			jQuery.cleanData( getAll( this ) );
5346
5347			if ( arg ) {
5348				arg.replaceChild( elem, this );
5349			}
5350		});
5351
5352		// Force removal if there was no new content (e.g., from empty arguments)
5353		return arg && (arg.length || arg.nodeType) ? this : this.remove();
5354	},
5355
5356	detach: function( selector ) {
5357		return this.remove( selector, true );
5358	},
5359
5360	domManip: function( args, callback ) {
5361
5362		// Flatten any nested arrays
5363		args = concat.apply( [], args );
5364
5365		var fragment, first, scripts, hasScripts, node, doc,
5366			i = 0,
5367			l = this.length,
5368			set = this,
5369			iNoClone = l - 1,
5370			value = args[ 0 ],
5371			isFunction = jQuery.isFunction( value );
5372
5373		// We can't cloneNode fragments that contain checked, in WebKit
5374		if ( isFunction ||
5375				( l > 1 && typeof value === "string" &&
5376					!support.checkClone && rchecked.test( value ) ) ) {
5377			return this.each(function( index ) {
5378				var self = set.eq( index );
5379				if ( isFunction ) {
5380					args[ 0 ] = value.call( this, index, self.html() );
5381				}
5382				self.domManip( args, callback );
5383			});
5384		}
5385
5386		if ( l ) {
5387			fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this );
5388			first = fragment.firstChild;
5389
5390			if ( fragment.childNodes.length === 1 ) {
5391				fragment = first;
5392			}
5393
5394			if ( first ) {
5395				scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
5396				hasScripts = scripts.length;
5397
5398				// Use the original fragment for the last item instead of the first because it can end up
5399				// being emptied incorrectly in certain situations (#8070).
5400				for ( ; i < l; i++ ) {
5401					node = fragment;
5402
5403					if ( i !== iNoClone ) {
5404						node = jQuery.clone( node, true, true );
5405
5406						// Keep references to cloned scripts for later restoration
5407						if ( hasScripts ) {
5408							// Support: QtWebKit
5409							// jQuery.merge because push.apply(_, arraylike) throws
5410							jQuery.merge( scripts, getAll( node, "script" ) );
5411						}
5412					}
5413
5414					callback.call( this[ i ], node, i );
5415				}
5416
5417				if ( hasScripts ) {
5418					doc = scripts[ scripts.length - 1 ].ownerDocument;
5419
5420					// Reenable scripts
5421					jQuery.map( scripts, restoreScript );
5422
5423					// Evaluate executable scripts on first document insertion
5424					for ( i = 0; i < hasScripts; i++ ) {
5425						node = scripts[ i ];
5426						if ( rscriptType.test( node.type || "" ) &&
5427							!data_priv.access( node, "globalEval" ) && jQuery.contains( doc, node ) ) {
5428
5429							if ( node.src ) {
5430								// Optional AJAX dependency, but won't run scripts if not present
5431								if ( jQuery._evalUrl ) {
5432									jQuery._evalUrl( node.src );
5433								}
5434							} else {
5435								jQuery.globalEval( node.textContent.replace( rcleanScript, "" ) );
5436							}
5437						}
5438					}
5439				}
5440			}
5441		}
5442
5443		return this;
5444	}
5445});
5446
5447jQuery.each({
5448	appendTo: "append",
5449	prependTo: "prepend",
5450	insertBefore: "before",
5451	insertAfter: "after",
5452	replaceAll: "replaceWith"
5453}, function( name, original ) {
5454	jQuery.fn[ name ] = function( selector ) {
5455		var elems,
5456			ret = [],
5457			insert = jQuery( selector ),
5458			last = insert.length - 1,
5459			i = 0;
5460
5461		for ( ; i <= last; i++ ) {
5462			elems = i === last ? this : this.clone( true );
5463			jQuery( insert[ i ] )[ original ]( elems );
5464
5465			// Support: QtWebKit
5466			// .get() because push.apply(_, arraylike) throws
5467			push.apply( ret, elems.get() );
5468		}
5469
5470		return this.pushStack( ret );
5471	};
5472});
5473
5474
5475var iframe,
5476	elemdisplay = {};
5477
5478/**
5479 * Retrieve the actual display of a element
5480 * @param {String} name nodeName of the element
5481 * @param {Object} doc Document object
5482 */
5483// Called only from within defaultDisplay
5484function actualDisplay( name, doc ) {
5485	var style,
5486		elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),
5487
5488		// getDefaultComputedStyle might be reliably used only on attached element
5489		display = window.getDefaultComputedStyle && ( style = window.getDefaultComputedStyle( elem[ 0 ] ) ) ?
5490
5491			// Use of this method is a temporary fix (more like optimization) until something better comes along,
5492			// since it was removed from specification and supported only in FF
5493			style.display : jQuery.css( elem[ 0 ], "display" );
5494
5495	// We don't have any data stored on the element,
5496	// so use "detach" method as fast way to get rid of the element
5497	elem.detach();
5498
5499	return display;
5500}
5501
5502/**
5503 * Try to determine the default display value of an element
5504 * @param {String} nodeName
5505 */
5506function defaultDisplay( nodeName ) {
5507	var doc = document,
5508		display = elemdisplay[ nodeName ];
5509
5510	if ( !display ) {
5511		display = actualDisplay( nodeName, doc );
5512
5513		// If the simple way fails, read from inside an iframe
5514		if ( display === "none" || !display ) {
5515
5516			// Use the already-created iframe if possible
5517			iframe = (iframe || jQuery( "<iframe frameborder='0' width='0' height='0'/>" )).appendTo( doc.documentElement );
5518
5519			// Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse
5520			doc = iframe[ 0 ].contentDocument;
5521
5522			// Support: IE
5523			doc.write();
5524			doc.close();
5525
5526			display = actualDisplay( nodeName, doc );
5527			iframe.detach();
5528		}
5529
5530		// Store the correct default display
5531		elemdisplay[ nodeName ] = display;
5532	}
5533
5534	return display;
5535}
5536var rmargin = (/^margin/);
5537
5538var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
5539
5540var getStyles = function( elem ) {
5541		// Support: IE<=11+, Firefox<=30+ (#15098, #14150)
5542		// IE throws on elements created in popups
5543		// FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
5544		if ( elem.ownerDocument.defaultView.opener ) {
5545			return elem.ownerDocument.defaultView.getComputedStyle( elem, null );
5546		}
5547
5548		return window.getComputedStyle( elem, null );
5549	};
5550
5551
5552
5553function curCSS( elem, name, computed ) {
5554	var width, minWidth, maxWidth, ret,
5555		style = elem.style;
5556
5557	computed = computed || getStyles( elem );
5558
5559	// Support: IE9
5560	// getPropertyValue is only needed for .css('filter') (#12537)
5561	if ( computed ) {
5562		ret = computed.getPropertyValue( name ) || computed[ name ];
5563	}
5564
5565	if ( computed ) {
5566
5567		if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) {
5568			ret = jQuery.style( elem, name );
5569		}
5570
5571		// Support: iOS < 6
5572		// A tribute to the "awesome hack by Dean Edwards"
5573		// iOS < 6 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels
5574		// this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values
5575		if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) {
5576
5577			// Remember the original values
5578			width = style.width;
5579			minWidth = style.minWidth;
5580			maxWidth = style.maxWidth;
5581
5582			// Put in the new values to get a computed value out
5583			style.minWidth = style.maxWidth = style.width = ret;
5584			ret = computed.width;
5585
5586			// Revert the changed values
5587			style.width = width;
5588			style.minWidth = minWidth;
5589			style.maxWidth = maxWidth;
5590		}
5591	}
5592
5593	return ret !== undefined ?
5594		// Support: IE
5595		// IE returns zIndex value as an integer.
5596		ret + "" :
5597		ret;
5598}
5599
5600
5601function addGetHookIf( conditionFn, hookFn ) {
5602	// Define the hook, we'll check on the first run if it's really needed.
5603	return {
5604		get: function() {
5605			if ( conditionFn() ) {
5606				// Hook not needed (or it's not possible to use it due
5607				// to missing dependency), remove it.
5608				delete this.get;
5609				return;
5610			}
5611
5612			// Hook needed; redefine it so that the support test is not executed again.
5613			return (this.get = hookFn).apply( this, arguments );
5614		}
5615	};
5616}
5617
5618
5619(function() {
5620	var pixelPositionVal, boxSizingReliableVal,
5621		docElem = document.documentElement,
5622		container = document.createElement( "div" ),
5623		div = document.createElement( "div" );
5624
5625	if ( !div.style ) {
5626		return;
5627	}
5628
5629	// Support: IE9-11+
5630	// Style of cloned element affects source element cloned (#8908)
5631	div.style.backgroundClip = "content-box";
5632	div.cloneNode( true ).style.backgroundClip = "";
5633	support.clearCloneStyle = div.style.backgroundClip === "content-box";
5634
5635	container.style.cssText = "border:0;width:0;height:0;top:0;left:-9999px;margin-top:1px;" +
5636		"position:absolute";
5637	container.appendChild( div );
5638
5639	// Executing both pixelPosition & boxSizingReliable tests require only one layout
5640	// so they're executed at the same time to save the second computation.
5641	function computePixelPositionAndBoxSizingReliable() {
5642		div.style.cssText =
5643			// Support: Firefox<29, Android 2.3
5644			// Vendor-prefix box-sizing
5645			"-webkit-box-sizing:border-box;-moz-box-sizing:border-box;" +
5646			"box-sizing:border-box;display:block;margin-top:1%;top:1%;" +
5647			"border:1px;padding:1px;width:4px;position:absolute";
5648		div.innerHTML = "";
5649		docElem.appendChild( container );
5650
5651		var divStyle = window.getComputedStyle( div, null );
5652		pixelPositionVal = divStyle.top !== "1%";
5653		boxSizingReliableVal = divStyle.width === "4px";
5654
5655		docElem.removeChild( container );
5656	}
5657
5658	// Support: node.js jsdom
5659	// Don't assume that getComputedStyle is a property of the global object
5660	if ( window.getComputedStyle ) {
5661		jQuery.extend( support, {
5662			pixelPosition: function() {
5663
5664				// This test is executed only once but we still do memoizing
5665				// since we can use the boxSizingReliable pre-computing.
5666				// No need to check if the test was already performed, though.
5667				computePixelPositionAndBoxSizingReliable();
5668				return pixelPositionVal;
5669			},
5670			boxSizingReliable: function() {
5671				if ( boxSizingReliableVal == null ) {
5672					computePixelPositionAndBoxSizingReliable();
5673				}
5674				return boxSizingReliableVal;
5675			},
5676			reliableMarginRight: function() {
5677
5678				// Support: Android 2.3
5679				// Check if div with explicit width and no margin-right incorrectly
5680				// gets computed margin-right based on width of container. (#3333)
5681				// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
5682				// This support function is only executed once so no memoizing is needed.
5683				var ret,
5684					marginDiv = div.appendChild( document.createElement( "div" ) );
5685
5686				// Reset CSS: box-sizing; display; margin; border; padding
5687				marginDiv.style.cssText = div.style.cssText =
5688					// Support: Firefox<29, Android 2.3
5689					// Vendor-prefix box-sizing
5690					"-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" +
5691					"box-sizing:content-box;display:block;margin:0;border:0;padding:0";
5692				marginDiv.style.marginRight = marginDiv.style.width = "0";
5693				div.style.width = "1px";
5694				docElem.appendChild( container );
5695
5696				ret = !parseFloat( window.getComputedStyle( marginDiv, null ).marginRight );
5697
5698				docElem.removeChild( container );
5699				div.removeChild( marginDiv );
5700
5701				return ret;
5702			}
5703		});
5704	}
5705})();
5706
5707
5708// A method for quickly swapping in/out CSS properties to get correct calculations.
5709jQuery.swap = function( elem, options, callback, args ) {
5710	var ret, name,
5711		old = {};
5712
5713	// Remember the old values, and insert the new ones
5714	for ( name in options ) {
5715		old[ name ] = elem.style[ name ];
5716		elem.style[ name ] = options[ name ];
5717	}
5718
5719	ret = callback.apply( elem, args || [] );
5720
5721	// Revert the old values
5722	for ( name in options ) {
5723		elem.style[ name ] = old[ name ];
5724	}
5725
5726	return ret;
5727};
5728
5729
5730var
5731	// Swappable if display is none or starts with table except "table", "table-cell", or "table-caption"
5732	// See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
5733	rdisplayswap = /^(none|table(?!-c[ea]).+)/,
5734	rnumsplit = new RegExp( "^(" + pnum + ")(.*)$", "i" ),
5735	rrelNum = new RegExp( "^([+-])=(" + pnum + ")", "i" ),
5736
5737	cssShow = { position: "absolute", visibility: "hidden", display: "block" },
5738	cssNormalTransform = {
5739		letterSpacing: "0",
5740		fontWeight: "400"
5741	},
5742
5743	cssPrefixes = [ "Webkit", "O", "Moz", "ms" ];
5744
5745// Return a css property mapped to a potentially vendor prefixed property
5746function vendorPropName( style, name ) {
5747
5748	// Shortcut for names that are not vendor prefixed
5749	if ( name in style ) {
5750		return name;
5751	}
5752
5753	// Check for vendor prefixed names
5754	var capName = name[0].toUpperCase() + name.slice(1),
5755		origName = name,
5756		i = cssPrefixes.length;
5757
5758	while ( i-- ) {
5759		name = cssPrefixes[ i ] + capName;
5760		if ( name in style ) {
5761			return name;
5762		}
5763	}
5764
5765	return origName;
5766}
5767
5768function setPositiveNumber( elem, value, subtract ) {
5769	var matches = rnumsplit.exec( value );
5770	return matches ?
5771		// Guard against undefined "subtract", e.g., when used as in cssHooks
5772		Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) :
5773		value;
5774}
5775
5776function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
5777	var i = extra === ( isBorderBox ? "border" : "content" ) ?
5778		// If we already have the right measurement, avoid augmentation
5779		4 :
5780		// Otherwise initialize for horizontal or vertical properties
5781		name === "width" ? 1 : 0,
5782
5783		val = 0;
5784
5785	for ( ; i < 4; i += 2 ) {
5786		// Both box models exclude margin, so add it if we want it
5787		if ( extra === "margin" ) {
5788			val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
5789		}
5790
5791		if ( isBorderBox ) {
5792			// border-box includes padding, so remove it if we want content
5793			if ( extra === "content" ) {
5794				val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
5795			}
5796
5797			// At this point, extra isn't border nor margin, so remove border
5798			if ( extra !== "margin" ) {
5799				val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
5800			}
5801		} else {
5802			// At this point, extra isn't content, so add padding
5803			val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
5804
5805			// At this point, extra isn't content nor padding, so add border
5806			if ( extra !== "padding" ) {
5807				val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
5808			}
5809		}
5810	}
5811
5812	return val;
5813}
5814
5815function getWidthOrHeight( elem, name, extra ) {
5816
5817	// Start with offset property, which is equivalent to the border-box value
5818	var valueIsBorderBox = true,
5819		val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
5820		styles = getStyles( elem ),
5821		isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
5822
5823	// Some non-html elements return undefined for offsetWidth, so check for null/undefined
5824	// svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
5825	// MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
5826	if ( val <= 0 || val == null ) {
5827		// Fall back to computed then uncomputed css if necessary
5828		val = curCSS( elem, name, styles );
5829		if ( val < 0 || val == null ) {
5830			val = elem.style[ name ];
5831		}
5832
5833		// Computed unit is not pixels. Stop here and return.
5834		if ( rnumnonpx.test(val) ) {
5835			return val;
5836		}
5837
5838		// Check for style in case a browser which returns unreliable values
5839		// for getComputedStyle silently falls back to the reliable elem.style
5840		valueIsBorderBox = isBorderBox &&
5841			( support.boxSizingReliable() || val === elem.style[ name ] );
5842
5843		// Normalize "", auto, and prepare for extra
5844		val = parseFloat( val ) || 0;
5845	}
5846
5847	// Use the active box-sizing model to add/subtract irrelevant styles
5848	return ( val +
5849		augmentWidthOrHeight(
5850			elem,
5851			name,
5852			extra || ( isBorderBox ? "border" : "content" ),
5853			valueIsBorderBox,
5854			styles
5855		)
5856	) + "px";
5857}
5858
5859function showHide( elements, show ) {
5860	var display, elem, hidden,
5861		values = [],
5862		index = 0,
5863		length = elements.length;
5864
5865	for ( ; index < length; index++ ) {
5866		elem = elements[ index ];
5867		if ( !elem.style ) {
5868			continue;
5869		}
5870
5871		values[ index ] = data_priv.get( elem, "olddisplay" );
5872		display = elem.style.display;
5873		if ( show ) {
5874			// Reset the inline display of this element to learn if it is
5875			// being hidden by cascaded rules or not
5876			if ( !values[ index ] && display === "none" ) {
5877				elem.style.display = "";
5878			}
5879
5880			// Set elements which have been overridden with display: none
5881			// in a stylesheet to whatever the default browser style is
5882			// for such an element
5883			if ( elem.style.display === "" && isHidden( elem ) ) {
5884				values[ index ] = data_priv.access( elem, "olddisplay", defaultDisplay(elem.nodeName) );
5885			}
5886		} else {
5887			hidden = isHidden( elem );
5888
5889			if ( display !== "none" || !hidden ) {
5890				data_priv.set( elem, "olddisplay", hidden ? display : jQuery.css( elem, "display" ) );
5891			}
5892		}
5893	}
5894
5895	// Set the display of most of the elements in a second loop
5896	// to avoid the constant reflow
5897	for ( index = 0; index < length; index++ ) {
5898		elem = elements[ index ];
5899		if ( !elem.style ) {
5900			continue;
5901		}
5902		if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
5903			elem.style.display = show ? values[ index ] || "" : "none";
5904		}
5905	}
5906
5907	return elements;
5908}
5909
5910jQuery.extend({
5911
5912	// Add in style property hooks for overriding the default
5913	// behavior of getting and setting a style property
5914	cssHooks: {
5915		opacity: {
5916			get: function( elem, computed ) {
5917				if ( computed ) {
5918
5919					// We should always get a number back from opacity
5920					var ret = curCSS( elem, "opacity" );
5921					return ret === "" ? "1" : ret;
5922				}
5923			}
5924		}
5925	},
5926
5927	// Don't automatically add "px" to these possibly-unitless properties
5928	cssNumber: {
5929		"columnCount": true,
5930		"fillOpacity": true,
5931		"flexGrow": true,
5932		"flexShrink": true,
5933		"fontWeight": true,
5934		"lineHeight": true,
5935		"opacity": true,
5936		"order": true,
5937		"orphans": true,
5938		"widows": true,
5939		"zIndex": true,
5940		"zoom": true
5941	},
5942
5943	// Add in properties whose names you wish to fix before
5944	// setting or getting the value
5945	cssProps: {
5946		"float": "cssFloat"
5947	},
5948
5949	// Get and set the style property on a DOM Node
5950	style: function( elem, name, value, extra ) {
5951
5952		// Don't set styles on text and comment nodes
5953		if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
5954			return;
5955		}
5956
5957		// Make sure that we're working with the right name
5958		var ret, type, hooks,
5959			origName = jQuery.camelCase( name ),
5960			style = elem.style;
5961
5962		name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) );
5963
5964		// Gets hook for the prefixed version, then unprefixed version
5965		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
5966
5967		// Check if we're setting a value
5968		if ( value !== undefined ) {
5969			type = typeof value;
5970
5971			// Convert "+=" or "-=" to relative numbers (#7345)
5972			if ( type === "string" && (ret = rrelNum.exec( value )) ) {
5973				value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) );
5974				// Fixes bug #9237
5975				type = "number";
5976			}
5977
5978			// Make sure that null and NaN values aren't set (#7116)
5979			if ( value == null || value !== value ) {
5980				return;
5981			}
5982
5983			// If a number, add 'px' to the (except for certain CSS properties)
5984			if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
5985				value += "px";
5986			}
5987
5988			// Support: IE9-11+
5989			// background-* props affect original clone's values
5990			if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {
5991				style[ name ] = "inherit";
5992			}
5993
5994			// If a hook was provided, use that value, otherwise just set the specified value
5995			if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) {
5996				style[ name ] = value;
5997			}
5998
5999		} else {
6000			// If a hook was provided get the non-computed value from there
6001			if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
6002				return ret;
6003			}
6004
6005			// Otherwise just get the value from the style object
6006			return style[ name ];
6007		}
6008	},
6009
6010	css: function( elem, name, extra, styles ) {
6011		var val, num, hooks,
6012			origName = jQuery.camelCase( name );
6013
6014		// Make sure that we're working with the right name
6015		name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );
6016
6017		// Try prefixed name followed by the unprefixed name
6018		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
6019
6020		// If a hook was provided get the computed value from there
6021		if ( hooks && "get" in hooks ) {
6022			val = hooks.get( elem, true, extra );
6023		}
6024
6025		// Otherwise, if a way to get the computed value exists, use that
6026		if ( val === undefined ) {
6027			val = curCSS( elem, name, styles );
6028		}
6029
6030		// Convert "normal" to computed value
6031		if ( val === "normal" && name in cssNormalTransform ) {
6032			val = cssNormalTransform[ name ];
6033		}
6034
6035		// Make numeric if forced or a qualifier was provided and val looks numeric
6036		if ( extra === "" || extra ) {
6037			num = parseFloat( val );
6038			return extra === true || jQuery.isNumeric( num ) ? num || 0 : val;
6039		}
6040		return val;
6041	}
6042});
6043
6044jQuery.each([ "height", "width" ], function( i, name ) {
6045	jQuery.cssHooks[ name ] = {
6046		get: function( elem, computed, extra ) {
6047			if ( computed ) {
6048
6049				// Certain elements can have dimension info if we invisibly show them
6050				// but it must have a current display style that would benefit
6051				return rdisplayswap.test( jQuery.css( elem, "display" ) ) && elem.offsetWidth === 0 ?
6052					jQuery.swap( elem, cssShow, function() {
6053						return getWidthOrHeight( elem, name, extra );
6054					}) :
6055					getWidthOrHeight( elem, name, extra );
6056			}
6057		},
6058
6059		set: function( elem, value, extra ) {
6060			var styles = extra && getStyles( elem );
6061			return setPositiveNumber( elem, value, extra ?
6062				augmentWidthOrHeight(
6063					elem,
6064					name,
6065					extra,
6066					jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
6067					styles
6068				) : 0
6069			);
6070		}
6071	};
6072});
6073
6074// Support: Android 2.3
6075jQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight,
6076	function( elem, computed ) {
6077		if ( computed ) {
6078			return jQuery.swap( elem, { "display": "inline-block" },
6079				curCSS, [ elem, "marginRight" ] );
6080		}
6081	}
6082);
6083
6084// These hooks are used by animate to expand properties
6085jQuery.each({
6086	margin: "",
6087	padding: "",
6088	border: "Width"
6089}, function( prefix, suffix ) {
6090	jQuery.cssHooks[ prefix + suffix ] = {
6091		expand: function( value ) {
6092			var i = 0,
6093				expanded = {},
6094
6095				// Assumes a single number if not a string
6096				parts = typeof value === "string" ? value.split(" ") : [ value ];
6097
6098			for ( ; i < 4; i++ ) {
6099				expanded[ prefix + cssExpand[ i ] + suffix ] =
6100					parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
6101			}
6102
6103			return expanded;
6104		}
6105	};
6106
6107	if ( !rmargin.test( prefix ) ) {
6108		jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
6109	}
6110});
6111
6112jQuery.fn.extend({
6113	css: function( name, value ) {
6114		return access( this, function( elem, name, value ) {
6115			var styles, len,
6116				map = {},
6117				i = 0;
6118
6119			if ( jQuery.isArray( name ) ) {
6120				styles = getStyles( elem );
6121				len = name.length;
6122
6123				for ( ; i < len; i++ ) {
6124					map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
6125				}
6126
6127				return map;
6128			}
6129
6130			return value !== undefined ?
6131				jQuery.style( elem, name, value ) :
6132				jQuery.css( elem, name );
6133		}, name, value, arguments.length > 1 );
6134	},
6135	show: function() {
6136		return showHide( this, true );
6137	},
6138	hide: function() {
6139		return showHide( this );
6140	},
6141	toggle: function( state ) {
6142		if ( typeof state === "boolean" ) {
6143			return state ? this.show() : this.hide();
6144		}
6145
6146		return this.each(function() {
6147			if ( isHidden( this ) ) {
6148				jQuery( this ).show();
6149			} else {
6150				jQuery( this ).hide();
6151			}
6152		});
6153	}
6154});
6155
6156
6157function Tween( elem, options, prop, end, easing ) {
6158	return new Tween.prototype.init( elem, options, prop, end, easing );
6159}
6160jQuery.Tween = Tween;
6161
6162Tween.prototype = {
6163	constructor: Tween,
6164	init: function( elem, options, prop, end, easing, unit ) {
6165		this.elem = elem;
6166		this.prop = prop;
6167		this.easing = easing || "swing";
6168		this.options = options;
6169		this.start = this.now = this.cur();
6170		this.end = end;
6171		this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
6172	},
6173	cur: function() {
6174		var hooks = Tween.propHooks[ this.prop ];
6175
6176		return hooks && hooks.get ?
6177			hooks.get( this ) :
6178			Tween.propHooks._default.get( this );
6179	},
6180	run: function( percent ) {
6181		var eased,
6182			hooks = Tween.propHooks[ this.prop ];
6183
6184		if ( this.options.duration ) {
6185			this.pos = eased = jQuery.easing[ this.easing ](
6186				percent, this.options.duration * percent, 0, 1, this.options.duration
6187			);
6188		} else {
6189			this.pos = eased = percent;
6190		}
6191		this.now = ( this.end - this.start ) * eased + this.start;
6192
6193		if ( this.options.step ) {
6194			this.options.step.call( this.elem, this.now, this );
6195		}
6196
6197		if ( hooks && hooks.set ) {
6198			hooks.set( this );
6199		} else {
6200			Tween.propHooks._default.set( this );
6201		}
6202		return this;
6203	}
6204};
6205
6206Tween.prototype.init.prototype = Tween.prototype;
6207
6208Tween.propHooks = {
6209	_default: {
6210		get: function( tween ) {
6211			var result;
6212
6213			if ( tween.elem[ tween.prop ] != null &&
6214				(!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) {
6215				return tween.elem[ tween.prop ];
6216			}
6217
6218			// Passing an empty string as a 3rd parameter to .css will automatically
6219			// attempt a parseFloat and fallback to a string if the parse fails.
6220			// Simple values such as "10px" are parsed to Float;
6221			// complex values such as "rotate(1rad)" are returned as-is.
6222			result = jQuery.css( tween.elem, tween.prop, "" );
6223			// Empty strings, null, undefined and "auto" are converted to 0.
6224			return !result || result === "auto" ? 0 : result;
6225		},
6226		set: function( tween ) {
6227			// Use step hook for back compat.
6228			// Use cssHook if its there.
6229			// Use .style if available and use plain properties where available.
6230			if ( jQuery.fx.step[ tween.prop ] ) {
6231				jQuery.fx.step[ tween.prop ]( tween );
6232			} else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) {
6233				jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
6234			} else {
6235				tween.elem[ tween.prop ] = tween.now;
6236			}
6237		}
6238	}
6239};
6240
6241// Support: IE9
6242// Panic based approach to setting things on disconnected nodes
6243Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
6244	set: function( tween ) {
6245		if ( tween.elem.nodeType && tween.elem.parentNode ) {
6246			tween.elem[ tween.prop ] = tween.now;
6247		}
6248	}
6249};
6250
6251jQuery.easing = {
6252	linear: function( p ) {
6253		return p;
6254	},
6255	swing: function( p ) {
6256		return 0.5 - Math.cos( p * Math.PI ) / 2;
6257	}
6258};
6259
6260jQuery.fx = Tween.prototype.init;
6261
6262// Back Compat <1.8 extension point
6263jQuery.fx.step = {};
6264
6265
6266
6267
6268var
6269	fxNow, timerId,
6270	rfxtypes = /^(?:toggle|show|hide)$/,
6271	rfxnum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ),
6272	rrun = /queueHooks$/,
6273	animationPrefilters = [ defaultPrefilter ],
6274	tweeners = {
6275		"*": [ function( prop, value ) {
6276			var tween = this.createTween( prop, value ),
6277				target = tween.cur(),
6278				parts = rfxnum.exec( value ),
6279				unit = parts && parts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
6280
6281				// Starting value computation is required for potential unit mismatches
6282				start = ( jQuery.cssNumber[ prop ] || unit !== "px" && +target ) &&
6283					rfxnum.exec( jQuery.css( tween.elem, prop ) ),
6284				scale = 1,
6285				maxIterations = 20;
6286
6287			if ( start && start[ 3 ] !== unit ) {
6288				// Trust units reported by jQuery.css
6289				unit = unit || start[ 3 ];
6290
6291				// Make sure we update the tween properties later on
6292				parts = parts || [];
6293
6294				// Iteratively approximate from a nonzero starting point
6295				start = +target || 1;
6296
6297				do {
6298					// If previous iteration zeroed out, double until we get *something*.
6299					// Use string for doubling so we don't accidentally see scale as unchanged below
6300					scale = scale || ".5";
6301
6302					// Adjust and apply
6303					start = start / scale;
6304					jQuery.style( tween.elem, prop, start + unit );
6305
6306				// Update scale, tolerating zero or NaN from tween.cur(),
6307				// break the loop if scale is unchanged or perfect, or if we've just had enough
6308				} while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations );
6309			}
6310
6311			// Update tween properties
6312			if ( parts ) {
6313				start = tween.start = +start || +target || 0;
6314				tween.unit = unit;
6315				// If a +=/-= token was provided, we're doing a relative animation
6316				tween.end = parts[ 1 ] ?
6317					start + ( parts[ 1 ] + 1 ) * parts[ 2 ] :
6318					+parts[ 2 ];
6319			}
6320
6321			return tween;
6322		} ]
6323	};
6324
6325// Animations created synchronously will run synchronously
6326function createFxNow() {
6327	setTimeout(function() {
6328		fxNow = undefined;
6329	});
6330	return ( fxNow = jQuery.now() );
6331}
6332
6333// Generate parameters to create a standard animation
6334function genFx( type, includeWidth ) {
6335	var which,
6336		i = 0,
6337		attrs = { height: type };
6338
6339	// If we include width, step value is 1 to do all cssExpand values,
6340	// otherwise step value is 2 to skip over Left and Right
6341	includeWidth = includeWidth ? 1 : 0;
6342	for ( ; i < 4 ; i += 2 - includeWidth ) {
6343		which = cssExpand[ i ];
6344		attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
6345	}
6346
6347	if ( includeWidth ) {
6348		attrs.opacity = attrs.width = type;
6349	}
6350
6351	return attrs;
6352}
6353
6354function createTween( value, prop, animation ) {
6355	var tween,
6356		collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ),
6357		index = 0,
6358		length = collection.length;
6359	for ( ; index < length; index++ ) {
6360		if ( (tween = collection[ index ].call( animation, prop, value )) ) {
6361
6362			// We're done with this property
6363			return tween;
6364		}
6365	}
6366}
6367
6368function defaultPrefilter( elem, props, opts ) {
6369	/* jshint validthis: true */
6370	var prop, value, toggle, tween, hooks, oldfire, display, checkDisplay,
6371		anim = this,
6372		orig = {},
6373		style = elem.style,
6374		hidden = elem.nodeType && isHidden( elem ),
6375		dataShow = data_priv.get( elem, "fxshow" );
6376
6377	// Handle queue: false promises
6378	if ( !opts.queue ) {
6379		hooks = jQuery._queueHooks( elem, "fx" );
6380		if ( hooks.unqueued == null ) {
6381			hooks.unqueued = 0;
6382			oldfire = hooks.empty.fire;
6383			hooks.empty.fire = function() {
6384				if ( !hooks.unqueued ) {
6385					oldfire();
6386				}
6387			};
6388		}
6389		hooks.unqueued++;
6390
6391		anim.always(function() {
6392			// Ensure the complete handler is called before this completes
6393			anim.always(function() {
6394				hooks.unqueued--;
6395				if ( !jQuery.queue( elem, "fx" ).length ) {
6396					hooks.empty.fire();
6397				}
6398			});
6399		});
6400	}
6401
6402	// Height/width overflow pass
6403	if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) {
6404		// Make sure that nothing sneaks out
6405		// Record all 3 overflow attributes because IE9-10 do not
6406		// change the overflow attribute when overflowX and
6407		// overflowY are set to the same value
6408		opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
6409
6410		// Set display property to inline-block for height/width
6411		// animations on inline elements that are having width/height animated
6412		display = jQuery.css( elem, "display" );
6413
6414		// Test default display if display is currently "none"
6415		checkDisplay = display === "none" ?
6416			data_priv.get( elem, "olddisplay" ) || defaultDisplay( elem.nodeName ) : display;
6417
6418		if ( checkDisplay === "inline" && jQuery.css( elem, "float" ) === "none" ) {
6419			style.display = "inline-block";
6420		}
6421	}
6422
6423	if ( opts.overflow ) {
6424		style.overflow = "hidden";
6425		anim.always(function() {
6426			style.overflow = opts.overflow[ 0 ];
6427			style.overflowX = opts.overflow[ 1 ];
6428			style.overflowY = opts.overflow[ 2 ];
6429		});
6430	}
6431
6432	// show/hide pass
6433	for ( prop in props ) {
6434		value = props[ prop ];
6435		if ( rfxtypes.exec( value ) ) {
6436			delete props[ prop ];
6437			toggle = toggle || value === "toggle";
6438			if ( value === ( hidden ? "hide" : "show" ) ) {
6439
6440				// If there is dataShow left over from a stopped hide or show and we are going to proceed with show, we should pretend to be hidden
6441				if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
6442					hidden = true;
6443				} else {
6444					continue;
6445				}
6446			}
6447			orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
6448
6449		// Any non-fx value stops us from restoring the original display value
6450		} else {
6451			display = undefined;
6452		}
6453	}
6454
6455	if ( !jQuery.isEmptyObject( orig ) ) {
6456		if ( dataShow ) {
6457			if ( "hidden" in dataShow ) {
6458				hidden = dataShow.hidden;
6459			}
6460		} else {
6461			dataShow = data_priv.access( elem, "fxshow", {} );
6462		}
6463
6464		// Store state if its toggle - enables .stop().toggle() to "reverse"
6465		if ( toggle ) {
6466			dataShow.hidden = !hidden;
6467		}
6468		if ( hidden ) {
6469			jQuery( elem ).show();
6470		} else {
6471			anim.done(function() {
6472				jQuery( elem ).hide();
6473			});
6474		}
6475		anim.done(function() {
6476			var prop;
6477
6478			data_priv.remove( elem, "fxshow" );
6479			for ( prop in orig ) {
6480				jQuery.style( elem, prop, orig[ prop ] );
6481			}
6482		});
6483		for ( prop in orig ) {
6484			tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
6485
6486			if ( !( prop in dataShow ) ) {
6487				dataShow[ prop ] = tween.start;
6488				if ( hidden ) {
6489					tween.end = tween.start;
6490					tween.start = prop === "width" || prop === "height" ? 1 : 0;
6491				}
6492			}
6493		}
6494
6495	// If this is a noop like .hide().hide(), restore an overwritten display value
6496	} else if ( (display === "none" ? defaultDisplay( elem.nodeName ) : display) === "inline" ) {
6497		style.display = display;
6498	}
6499}
6500
6501function propFilter( props, specialEasing ) {
6502	var index, name, easing, value, hooks;
6503
6504	// camelCase, specialEasing and expand cssHook pass
6505	for ( index in props ) {
6506		name = jQuery.camelCase( index );
6507		easing = specialEasing[ name ];
6508		value = props[ index ];
6509		if ( jQuery.isArray( value ) ) {
6510			easing = value[ 1 ];
6511			value = props[ index ] = value[ 0 ];
6512		}
6513
6514		if ( index !== name ) {
6515			props[ name ] = value;
6516			delete props[ index ];
6517		}
6518
6519		hooks = jQuery.cssHooks[ name ];
6520		if ( hooks && "expand" in hooks ) {
6521			value = hooks.expand( value );
6522			delete props[ name ];
6523
6524			// Not quite $.extend, this won't overwrite existing keys.
6525			// Reusing 'index' because we have the correct "name"
6526			for ( index in value ) {
6527				if ( !( index in props ) ) {
6528					props[ index ] = value[ index ];
6529					specialEasing[ index ] = easing;
6530				}
6531			}
6532		} else {
6533			specialEasing[ name ] = easing;
6534		}
6535	}
6536}
6537
6538function Animation( elem, properties, options ) {
6539	var result,
6540		stopped,
6541		index = 0,
6542		length = animationPrefilters.length,
6543		deferred = jQuery.Deferred().always( function() {
6544			// Don't match elem in the :animated selector
6545			delete tick.elem;
6546		}),
6547		tick = function() {
6548			if ( stopped ) {
6549				return false;
6550			}
6551			var currentTime = fxNow || createFxNow(),
6552				remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
6553				// Support: Android 2.3
6554				// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)
6555				temp = remaining / animation.duration || 0,
6556				percent = 1 - temp,
6557				index = 0,
6558				length = animation.tweens.length;
6559
6560			for ( ; index < length ; index++ ) {
6561				animation.tweens[ index ].run( percent );
6562			}
6563
6564			deferred.notifyWith( elem, [ animation, percent, remaining ]);
6565
6566			if ( percent < 1 && length ) {
6567				return remaining;
6568			} else {
6569				deferred.resolveWith( elem, [ animation ] );
6570				return false;
6571			}
6572		},
6573		animation = deferred.promise({
6574			elem: elem,
6575			props: jQuery.extend( {}, properties ),
6576			opts: jQuery.extend( true, { specialEasing: {} }, options ),
6577			originalProperties: properties,
6578			originalOptions: options,
6579			startTime: fxNow || createFxNow(),
6580			duration: options.duration,
6581			tweens: [],
6582			createTween: function( prop, end ) {
6583				var tween = jQuery.Tween( elem, animation.opts, prop, end,
6584						animation.opts.specialEasing[ prop ] || animation.opts.easing );
6585				animation.tweens.push( tween );
6586				return tween;
6587			},
6588			stop: function( gotoEnd ) {
6589				var index = 0,
6590					// If we are going to the end, we want to run all the tweens
6591					// otherwise we skip this part
6592					length = gotoEnd ? animation.tweens.length : 0;
6593				if ( stopped ) {
6594					return this;
6595				}
6596				stopped = true;
6597				for ( ; index < length ; index++ ) {
6598					animation.tweens[ index ].run( 1 );
6599				}
6600
6601				// Resolve when we played the last frame; otherwise, reject
6602				if ( gotoEnd ) {
6603					deferred.resolveWith( elem, [ animation, gotoEnd ] );
6604				} else {
6605					deferred.rejectWith( elem, [ animation, gotoEnd ] );
6606				}
6607				return this;
6608			}
6609		}),
6610		props = animation.props;
6611
6612	propFilter( props, animation.opts.specialEasing );
6613
6614	for ( ; index < length ; index++ ) {
6615		result = animationPrefilters[ index ].call( animation, elem, props, animation.opts );
6616		if ( result ) {
6617			return result;
6618		}
6619	}
6620
6621	jQuery.map( props, createTween, animation );
6622
6623	if ( jQuery.isFunction( animation.opts.start ) ) {
6624		animation.opts.start.call( elem, animation );
6625	}
6626
6627	jQuery.fx.timer(
6628		jQuery.extend( tick, {
6629			elem: elem,
6630			anim: animation,
6631			queue: animation.opts.queue
6632		})
6633	);
6634
6635	// attach callbacks from options
6636	return animation.progress( animation.opts.progress )
6637		.done( animation.opts.done, animation.opts.complete )
6638		.fail( animation.opts.fail )
6639		.always( animation.opts.always );
6640}
6641
6642jQuery.Animation = jQuery.extend( Animation, {
6643
6644	tweener: function( props, callback ) {
6645		if ( jQuery.isFunction( props ) ) {
6646			callback = props;
6647			props = [ "*" ];
6648		} else {
6649			props = props.split(" ");
6650		}
6651
6652		var prop,
6653			index = 0,
6654			length = props.length;
6655
6656		for ( ; index < length ; index++ ) {
6657			prop = props[ index ];
6658			tweeners[ prop ] = tweeners[ prop ] || [];
6659			tweeners[ prop ].unshift( callback );
6660		}
6661	},
6662
6663	prefilter: function( callback, prepend ) {
6664		if ( prepend ) {
6665			animationPrefilters.unshift( callback );
6666		} else {
6667			animationPrefilters.push( callback );
6668		}
6669	}
6670});
6671
6672jQuery.speed = function( speed, easing, fn ) {
6673	var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
6674		complete: fn || !fn && easing ||
6675			jQuery.isFunction( speed ) && speed,
6676		duration: speed,
6677		easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
6678	};
6679
6680	opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
6681		opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
6682
6683	// Normalize opt.queue - true/undefined/null -> "fx"
6684	if ( opt.queue == null || opt.queue === true ) {
6685		opt.queue = "fx";
6686	}
6687
6688	// Queueing
6689	opt.old = opt.complete;
6690
6691	opt.complete = function() {
6692		if ( jQuery.isFunction( opt.old ) ) {
6693			opt.old.call( this );
6694		}
6695
6696		if ( opt.queue ) {
6697			jQuery.dequeue( this, opt.queue );
6698		}
6699	};
6700
6701	return opt;
6702};
6703
6704jQuery.fn.extend({
6705	fadeTo: function( speed, to, easing, callback ) {
6706
6707		// Show any hidden elements after setting opacity to 0
6708		return this.filter( isHidden ).css( "opacity", 0 ).show()
6709
6710			// Animate to the value specified
6711			.end().animate({ opacity: to }, speed, easing, callback );
6712	},
6713	animate: function( prop, speed, easing, callback ) {
6714		var empty = jQuery.isEmptyObject( prop ),
6715			optall = jQuery.speed( speed, easing, callback ),
6716			doAnimation = function() {
6717				// Operate on a copy of prop so per-property easing won't be lost
6718				var anim = Animation( this, jQuery.extend( {}, prop ), optall );
6719
6720				// Empty animations, or finishing resolves immediately
6721				if ( empty || data_priv.get( this, "finish" ) ) {
6722					anim.stop( true );
6723				}
6724			};
6725			doAnimation.finish = doAnimation;
6726
6727		return empty || optall.queue === false ?
6728			this.each( doAnimation ) :
6729			this.queue( optall.queue, doAnimation );
6730	},
6731	stop: function( type, clearQueue, gotoEnd ) {
6732		var stopQueue = function( hooks ) {
6733			var stop = hooks.stop;
6734			delete hooks.stop;
6735			stop( gotoEnd );
6736		};
6737
6738		if ( typeof type !== "string" ) {
6739			gotoEnd = clearQueue;
6740			clearQueue = type;
6741			type = undefined;
6742		}
6743		if ( clearQueue && type !== false ) {
6744			this.queue( type || "fx", [] );
6745		}
6746
6747		return this.each(function() {
6748			var dequeue = true,
6749				index = type != null && type + "queueHooks",
6750				timers = jQuery.timers,
6751				data = data_priv.get( this );
6752
6753			if ( index ) {
6754				if ( data[ index ] && data[ index ].stop ) {
6755					stopQueue( data[ index ] );
6756				}
6757			} else {
6758				for ( index in data ) {
6759					if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
6760						stopQueue( data[ index ] );
6761					}
6762				}
6763			}
6764
6765			for ( index = timers.length; index--; ) {
6766				if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {
6767					timers[ index ].anim.stop( gotoEnd );
6768					dequeue = false;
6769					timers.splice( index, 1 );
6770				}
6771			}
6772
6773			// Start the next in the queue if the last step wasn't forced.
6774			// Timers currently will call their complete callbacks, which
6775			// will dequeue but only if they were gotoEnd.
6776			if ( dequeue || !gotoEnd ) {
6777				jQuery.dequeue( this, type );
6778			}
6779		});
6780	},
6781	finish: function( type ) {
6782		if ( type !== false ) {
6783			type = type || "fx";
6784		}
6785		return this.each(function() {
6786			var index,
6787				data = data_priv.get( this ),
6788				queue = data[ type + "queue" ],
6789				hooks = data[ type + "queueHooks" ],
6790				timers = jQuery.timers,
6791				length = queue ? queue.length : 0;
6792
6793			// Enable finishing flag on private data
6794			data.finish = true;
6795
6796			// Empty the queue first
6797			jQuery.queue( this, type, [] );
6798
6799			if ( hooks && hooks.stop ) {
6800				hooks.stop.call( this, true );
6801			}
6802
6803			// Look for any active animations, and finish them
6804			for ( index = timers.length; index--; ) {
6805				if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
6806					timers[ index ].anim.stop( true );
6807					timers.splice( index, 1 );
6808				}
6809			}
6810
6811			// Look for any animations in the old queue and finish them
6812			for ( index = 0; index < length; index++ ) {
6813				if ( queue[ index ] && queue[ index ].finish ) {
6814					queue[ index ].finish.call( this );
6815				}
6816			}
6817
6818			// Turn off finishing flag
6819			delete data.finish;
6820		});
6821	}
6822});
6823
6824jQuery.each([ "toggle", "show", "hide" ], function( i, name ) {
6825	var cssFn = jQuery.fn[ name ];
6826	jQuery.fn[ name ] = function( speed, easing, callback ) {
6827		return speed == null || typeof speed === "boolean" ?
6828			cssFn.apply( this, arguments ) :
6829			this.animate( genFx( name, true ), speed, easing, callback );
6830	};
6831});
6832
6833// Generate shortcuts for custom animations
6834jQuery.each({
6835	slideDown: genFx("show"),
6836	slideUp: genFx("hide"),
6837	slideToggle: genFx("toggle"),
6838	fadeIn: { opacity: "show" },
6839	fadeOut: { opacity: "hide" },
6840	fadeToggle: { opacity: "toggle" }
6841}, function( name, props ) {
6842	jQuery.fn[ name ] = function( speed, easing, callback ) {
6843		return this.animate( props, speed, easing, callback );
6844	};
6845});
6846
6847jQuery.timers = [];
6848jQuery.fx.tick = function() {
6849	var timer,
6850		i = 0,
6851		timers = jQuery.timers;
6852
6853	fxNow = jQuery.now();
6854
6855	for ( ; i < timers.length; i++ ) {
6856		timer = timers[ i ];
6857		// Checks the timer has not already been removed
6858		if ( !timer() && timers[ i ] === timer ) {
6859			timers.splice( i--, 1 );
6860		}
6861	}
6862
6863	if ( !timers.length ) {
6864		jQuery.fx.stop();
6865	}
6866	fxNow = undefined;
6867};
6868
6869jQuery.fx.timer = function( timer ) {
6870	jQuery.timers.push( timer );
6871	if ( timer() ) {
6872		jQuery.fx.start();
6873	} else {
6874		jQuery.timers.pop();
6875	}
6876};
6877
6878jQuery.fx.interval = 13;
6879
6880jQuery.fx.start = function() {
6881	if ( !timerId ) {
6882		timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );
6883	}
6884};
6885
6886jQuery.fx.stop = function() {
6887	clearInterval( timerId );
6888	timerId = null;
6889};
6890
6891jQuery.fx.speeds = {
6892	slow: 600,
6893	fast: 200,
6894	// Default speed
6895	_default: 400
6896};
6897
6898
6899// Based off of the plugin by Clint Helfers, with permission.
6900// http://blindsignals.com/index.php/2009/07/jquery-delay/
6901jQuery.fn.delay = function( time, type ) {
6902	time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
6903	type = type || "fx";
6904
6905	return this.queue( type, function( next, hooks ) {
6906		var timeout = setTimeout( next, time );
6907		hooks.stop = function() {
6908			clearTimeout( timeout );
6909		};
6910	});
6911};
6912
6913
6914(function() {
6915	var input = document.createElement( "input" ),
6916		select = document.createElement( "select" ),
6917		opt = select.appendChild( document.createElement( "option" ) );
6918
6919	input.type = "checkbox";
6920
6921	// Support: iOS<=5.1, Android<=4.2+
6922	// Default value for a checkbox should be "on"
6923	support.checkOn = input.value !== "";
6924
6925	// Support: IE<=11+
6926	// Must access selectedIndex to make default options select
6927	support.optSelected = opt.selected;
6928
6929	// Support: Android<=2.3
6930	// Options inside disabled selects are incorrectly marked as disabled
6931	select.disabled = true;
6932	support.optDisabled = !opt.disabled;
6933
6934	// Support: IE<=11+
6935	// An input loses its value after becoming a radio
6936	input = document.createElement( "input" );
6937	input.value = "t";
6938	input.type = "radio";
6939	support.radioValue = input.value === "t";
6940})();
6941
6942
6943var nodeHook, boolHook,
6944	attrHandle = jQuery.expr.attrHandle;
6945
6946jQuery.fn.extend({
6947	attr: function( name, value ) {
6948		return access( this, jQuery.attr, name, value, arguments.length > 1 );
6949	},
6950
6951	removeAttr: function( name ) {
6952		return this.each(function() {
6953			jQuery.removeAttr( this, name );
6954		});
6955	}
6956});
6957
6958jQuery.extend({
6959	attr: function( elem, name, value ) {
6960		var hooks, ret,
6961			nType = elem.nodeType;
6962
6963		// don't get/set attributes on text, comment and attribute nodes
6964		if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
6965			return;
6966		}
6967
6968		// Fallback to prop when attributes are not supported
6969		if ( typeof elem.getAttribute === strundefined ) {
6970			return jQuery.prop( elem, name, value );
6971		}
6972
6973		// All attributes are lowercase
6974		// Grab necessary hook if one is defined
6975		if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
6976			name = name.toLowerCase();
6977			hooks = jQuery.attrHooks[ name ] ||
6978				( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook );
6979		}
6980
6981		if ( value !== undefined ) {
6982
6983			if ( value === null ) {
6984				jQuery.removeAttr( elem, name );
6985
6986			} else if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
6987				return ret;
6988
6989			} else {
6990				elem.setAttribute( name, value + "" );
6991				return value;
6992			}
6993
6994		} else if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
6995			return ret;
6996
6997		} else {
6998			ret = jQuery.find.attr( elem, name );
6999
7000			// Non-existent attributes return null, we normalize to undefined
7001			return ret == null ?
7002				undefined :
7003				ret;
7004		}
7005	},
7006
7007	removeAttr: function( elem, value ) {
7008		var name, propName,
7009			i = 0,
7010			attrNames = value && value.match( rnotwhite );
7011
7012		if ( attrNames && elem.nodeType === 1 ) {
7013			while ( (name = attrNames[i++]) ) {
7014				propName = jQuery.propFix[ name ] || name;
7015
7016				// Boolean attributes get special treatment (#10870)
7017				if ( jQuery.expr.match.bool.test( name ) ) {
7018					// Set corresponding property to false
7019					elem[ propName ] = false;
7020				}
7021
7022				elem.removeAttribute( name );
7023			}
7024		}
7025	},
7026
7027	attrHooks: {
7028		type: {
7029			set: function( elem, value ) {
7030				if ( !support.radioValue && value === "radio" &&
7031					jQuery.nodeName( elem, "input" ) ) {
7032					var val = elem.value;
7033					elem.setAttribute( "type", value );
7034					if ( val ) {
7035						elem.value = val;
7036					}
7037					return value;
7038				}
7039			}
7040		}
7041	}
7042});
7043
7044// Hooks for boolean attributes
7045boolHook = {
7046	set: function( elem, value, name ) {
7047		if ( value === false ) {
7048			// Remove boolean attributes when set to false
7049			jQuery.removeAttr( elem, name );
7050		} else {
7051			elem.setAttribute( name, name );
7052		}
7053		return name;
7054	}
7055};
7056jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
7057	var getter = attrHandle[ name ] || jQuery.find.attr;
7058
7059	attrHandle[ name ] = function( elem, name, isXML ) {
7060		var ret, handle;
7061		if ( !isXML ) {
7062			// Avoid an infinite loop by temporarily removing this function from the getter
7063			handle = attrHandle[ name ];
7064			attrHandle[ name ] = ret;
7065			ret = getter( elem, name, isXML ) != null ?
7066				name.toLowerCase() :
7067				null;
7068			attrHandle[ name ] = handle;
7069		}
7070		return ret;
7071	};
7072});
7073
7074
7075
7076
7077var rfocusable = /^(?:input|select|textarea|button)$/i;
7078
7079jQuery.fn.extend({
7080	prop: function( name, value ) {
7081		return access( this, jQuery.prop, name, value, arguments.length > 1 );
7082	},
7083
7084	removeProp: function( name ) {
7085		return this.each(function() {
7086			delete this[ jQuery.propFix[ name ] || name ];
7087		});
7088	}
7089});
7090
7091jQuery.extend({
7092	propFix: {
7093		"for": "htmlFor",
7094		"class": "className"
7095	},
7096
7097	prop: function( elem, name, value ) {
7098		var ret, hooks, notxml,
7099			nType = elem.nodeType;
7100
7101		// Don't get/set properties on text, comment and attribute nodes
7102		if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
7103			return;
7104		}
7105
7106		notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
7107
7108		if ( notxml ) {
7109			// Fix name and attach hooks
7110			name = jQuery.propFix[ name ] || name;
7111			hooks = jQuery.propHooks[ name ];
7112		}
7113
7114		if ( value !== undefined ) {
7115			return hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ?
7116				ret :
7117				( elem[ name ] = value );
7118
7119		} else {
7120			return hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ?
7121				ret :
7122				elem[ name ];
7123		}
7124	},
7125
7126	propHooks: {
7127		tabIndex: {
7128			get: function( elem ) {
7129				return elem.hasAttribute( "tabindex" ) || rfocusable.test( elem.nodeName ) || elem.href ?
7130					elem.tabIndex :
7131					-1;
7132			}
7133		}
7134	}
7135});
7136
7137if ( !support.optSelected ) {
7138	jQuery.propHooks.selected = {
7139		get: function( elem ) {
7140			var parent = elem.parentNode;
7141			if ( parent && parent.parentNode ) {
7142				parent.parentNode.selectedIndex;
7143			}
7144			return null;
7145		}
7146	};
7147}
7148
7149jQuery.each([
7150	"tabIndex",
7151	"readOnly",
7152	"maxLength",
7153	"cellSpacing",
7154	"cellPadding",
7155	"rowSpan",
7156	"colSpan",
7157	"useMap",
7158	"frameBorder",
7159	"contentEditable"
7160], function() {
7161	jQuery.propFix[ this.toLowerCase() ] = this;
7162});
7163
7164
7165
7166
7167var rclass = /[\t\r\n\f]/g;
7168
7169jQuery.fn.extend({
7170	addClass: function( value ) {
7171		var classes, elem, cur, clazz, j, finalValue,
7172			proceed = typeof value === "string" && value,
7173			i = 0,
7174			len = this.length;
7175
7176		if ( jQuery.isFunction( value ) ) {
7177			return this.each(function( j ) {
7178				jQuery( this ).addClass( value.call( this, j, this.className ) );
7179			});
7180		}
7181
7182		if ( proceed ) {
7183			// The disjunction here is for better compressibility (see removeClass)
7184			classes = ( value || "" ).match( rnotwhite ) || [];
7185
7186			for ( ; i < len; i++ ) {
7187				elem = this[ i ];
7188				cur = elem.nodeType === 1 && ( elem.className ?
7189					( " " + elem.className + " " ).replace( rclass, " " ) :
7190					" "
7191				);
7192
7193				if ( cur ) {
7194					j = 0;
7195					while ( (clazz = classes[j++]) ) {
7196						if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
7197							cur += clazz + " ";
7198						}
7199					}
7200
7201					// only assign if different to avoid unneeded rendering.
7202					finalValue = jQuery.trim( cur );
7203					if ( elem.className !== finalValue ) {
7204						elem.className = finalValue;
7205					}
7206				}
7207			}
7208		}
7209
7210		return this;
7211	},
7212
7213	removeClass: function( value ) {
7214		var classes, elem, cur, clazz, j, finalValue,
7215			proceed = arguments.length === 0 || typeof value === "string" && value,
7216			i = 0,
7217			len = this.length;
7218
7219		if ( jQuery.isFunction( value ) ) {
7220			return this.each(function( j ) {
7221				jQuery( this ).removeClass( value.call( this, j, this.className ) );
7222			});
7223		}
7224		if ( proceed ) {
7225			classes = ( value || "" ).match( rnotwhite ) || [];
7226
7227			for ( ; i < len; i++ ) {
7228				elem = this[ i ];
7229				// This expression is here for better compressibility (see addClass)
7230				cur = elem.nodeType === 1 && ( elem.className ?
7231					( " " + elem.className + " " ).replace( rclass, " " ) :
7232					""
7233				);
7234
7235				if ( cur ) {
7236					j = 0;
7237					while ( (clazz = classes[j++]) ) {
7238						// Remove *all* instances
7239						while ( cur.indexOf( " " + clazz + " " ) >= 0 ) {
7240							cur = cur.replace( " " + clazz + " ", " " );
7241						}
7242					}
7243
7244					// Only assign if different to avoid unneeded rendering.
7245					finalValue = value ? jQuery.trim( cur ) : "";
7246					if ( elem.className !== finalValue ) {
7247						elem.className = finalValue;
7248					}
7249				}
7250			}
7251		}
7252
7253		return this;
7254	},
7255
7256	toggleClass: function( value, stateVal ) {
7257		var type = typeof value;
7258
7259		if ( typeof stateVal === "boolean" && type === "string" ) {
7260			return stateVal ? this.addClass( value ) : this.removeClass( value );
7261		}
7262
7263		if ( jQuery.isFunction( value ) ) {
7264			return this.each(function( i ) {
7265				jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );
7266			});
7267		}
7268
7269		return this.each(function() {
7270			if ( type === "string" ) {
7271				// Toggle individual class names
7272				var className,
7273					i = 0,
7274					self = jQuery( this ),
7275					classNames = value.match( rnotwhite ) || [];
7276
7277				while ( (className = classNames[ i++ ]) ) {
7278					// Check each className given, space separated list
7279					if ( self.hasClass( className ) ) {
7280						self.removeClass( className );
7281					} else {
7282						self.addClass( className );
7283					}
7284				}
7285
7286			// Toggle whole class name
7287			} else if ( type === strundefined || type === "boolean" ) {
7288				if ( this.className ) {
7289					// store className if set
7290					data_priv.set( this, "__className__", this.className );
7291				}
7292
7293				// If the element has a class name or if we're passed `false`,
7294				// then remove the whole classname (if there was one, the above saved it).
7295				// Otherwise bring back whatever was previously saved (if anything),
7296				// falling back to the empty string if nothing was stored.
7297				this.className = this.className || value === false ? "" : data_priv.get( this, "__className__" ) || "";
7298			}
7299		});
7300	},
7301
7302	hasClass: function( selector ) {
7303		var className = " " + selector + " ",
7304			i = 0,
7305			l = this.length;
7306		for ( ; i < l; i++ ) {
7307			if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) {
7308				return true;
7309			}
7310		}
7311
7312		return false;
7313	}
7314});
7315
7316
7317
7318
7319var rreturn = /\r/g;
7320
7321jQuery.fn.extend({
7322	val: function( value ) {
7323		var hooks, ret, isFunction,
7324			elem = this[0];
7325
7326		if ( !arguments.length ) {
7327			if ( elem ) {
7328				hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];
7329
7330				if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
7331					return ret;
7332				}
7333
7334				ret = elem.value;
7335
7336				return typeof ret === "string" ?
7337					// Handle most common string cases
7338					ret.replace(rreturn, "") :
7339					// Handle cases where value is null/undef or number
7340					ret == null ? "" : ret;
7341			}
7342
7343			return;
7344		}
7345
7346		isFunction = jQuery.isFunction( value );
7347
7348		return this.each(function( i ) {
7349			var val;
7350
7351			if ( this.nodeType !== 1 ) {
7352				return;
7353			}
7354
7355			if ( isFunction ) {
7356				val = value.call( this, i, jQuery( this ).val() );
7357			} else {
7358				val = value;
7359			}
7360
7361			// Treat null/undefined as ""; convert numbers to string
7362			if ( val == null ) {
7363				val = "";
7364
7365			} else if ( typeof val === "number" ) {
7366				val += "";
7367
7368			} else if ( jQuery.isArray( val ) ) {
7369				val = jQuery.map( val, function( value ) {
7370					return value == null ? "" : value + "";
7371				});
7372			}
7373
7374			hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
7375
7376			// If set returns undefined, fall back to normal setting
7377			if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
7378				this.value = val;
7379			}
7380		});
7381	}
7382});
7383
7384jQuery.extend({
7385	valHooks: {
7386		option: {
7387			get: function( elem ) {
7388				var val = jQuery.find.attr( elem, "value" );
7389				return val != null ?
7390					val :
7391					// Support: IE10-11+
7392					// option.text throws exceptions (#14686, #14858)
7393					jQuery.trim( jQuery.text( elem ) );
7394			}
7395		},
7396		select: {
7397			get: function( elem ) {
7398				var value, option,
7399					options = elem.options,
7400					index = elem.selectedIndex,
7401					one = elem.type === "select-one" || index < 0,
7402					values = one ? null : [],
7403					max = one ? index + 1 : options.length,
7404					i = index < 0 ?
7405						max :
7406						one ? index : 0;
7407
7408				// Loop through all the selected options
7409				for ( ; i < max; i++ ) {
7410					option = options[ i ];
7411
7412					// IE6-9 doesn't update selected after form reset (#2551)
7413					if ( ( option.selected || i === index ) &&
7414							// Don't return options that are disabled or in a disabled optgroup
7415							( support.optDisabled ? !option.disabled : option.getAttribute( "disabled" ) === null ) &&
7416							( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) {
7417
7418						// Get the specific value for the option
7419						value = jQuery( option ).val();
7420
7421						// We don't need an array for one selects
7422						if ( one ) {
7423							return value;
7424						}
7425
7426						// Multi-Selects return an array
7427						values.push( value );
7428					}
7429				}
7430
7431				return values;
7432			},
7433
7434			set: function( elem, value ) {
7435				var optionSet, option,
7436					options = elem.options,
7437					values = jQuery.makeArray( value ),
7438					i = options.length;
7439
7440				while ( i-- ) {
7441					option = options[ i ];
7442					if ( (option.selected = jQuery.inArray( option.value, values ) >= 0) ) {
7443						optionSet = true;
7444					}
7445				}
7446
7447				// Force browsers to behave consistently when non-matching value is set
7448				if ( !optionSet ) {
7449					elem.selectedIndex = -1;
7450				}
7451				return values;
7452			}
7453		}
7454	}
7455});
7456
7457// Radios and checkboxes getter/setter
7458jQuery.each([ "radio", "checkbox" ], function() {
7459	jQuery.valHooks[ this ] = {
7460		set: function( elem, value ) {
7461			if ( jQuery.isArray( value ) ) {
7462				return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );
7463			}
7464		}
7465	};
7466	if ( !support.checkOn ) {
7467		jQuery.valHooks[ this ].get = function( elem ) {
7468			return elem.getAttribute("value") === null ? "on" : elem.value;
7469		};
7470	}
7471});
7472
7473
7474
7475
7476// Return jQuery for attributes-only inclusion
7477
7478
7479jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
7480	"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
7481	"change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) {
7482
7483	// Handle event binding
7484	jQuery.fn[ name ] = function( data, fn ) {
7485		return arguments.length > 0 ?
7486			this.on( name, null, data, fn ) :
7487			this.trigger( name );
7488	};
7489});
7490
7491jQuery.fn.extend({
7492	hover: function( fnOver, fnOut ) {
7493		return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
7494	},
7495
7496	bind: function( types, data, fn ) {
7497		return this.on( types, null, data, fn );
7498	},
7499	unbind: function( types, fn ) {
7500		return this.off( types, null, fn );
7501	},
7502
7503	delegate: function( selector, types, data, fn ) {
7504		return this.on( types, selector, data, fn );
7505	},
7506	undelegate: function( selector, types, fn ) {
7507		// ( namespace ) or ( selector, types [, fn] )
7508		return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn );
7509	}
7510});
7511
7512
7513var nonce = jQuery.now();
7514
7515var rquery = (/\?/);
7516
7517
7518
7519// Support: Android 2.3
7520// Workaround failure to string-cast null input
7521jQuery.parseJSON = function( data ) {
7522	return JSON.parse( data + "" );
7523};
7524
7525
7526// Cross-browser xml parsing
7527jQuery.parseXML = function( data ) {
7528	var xml, tmp;
7529	if ( !data || typeof data !== "string" ) {
7530		return null;
7531	}
7532
7533	// Support: IE9
7534	try {
7535		tmp = new DOMParser();
7536		xml = tmp.parseFromString( data, "text/xml" );
7537	} catch ( e ) {
7538		xml = undefined;
7539	}
7540
7541	if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) {
7542		jQuery.error( "Invalid XML: " + data );
7543	}
7544	return xml;
7545};
7546
7547
7548var
7549	rhash = /#.*$/,
7550	rts = /([?&])_=[^&]*/,
7551	rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
7552	// #7653, #8125, #8152: local protocol detection
7553	rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
7554	rnoContent = /^(?:GET|HEAD)$/,
7555	rprotocol = /^\/\//,
7556	rurl = /^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,
7557
7558	/* Prefilters
7559	 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
7560	 * 2) These are called:
7561	 *    - BEFORE asking for a transport
7562	 *    - AFTER param serialization (s.data is a string if s.processData is true)
7563	 * 3) key is the dataType
7564	 * 4) the catchall symbol "*" can be used
7565	 * 5) execution will start with transport dataType and THEN continue down to "*" if needed
7566	 */
7567	prefilters = {},
7568
7569	/* Transports bindings
7570	 * 1) key is the dataType
7571	 * 2) the catchall symbol "*" can be used
7572	 * 3) selection will start with transport dataType and THEN go to "*" if needed
7573	 */
7574	transports = {},
7575
7576	// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
7577	allTypes = "*/".concat( "*" ),
7578
7579	// Document location
7580	ajaxLocation = window.location.href,
7581
7582	// Segment location into parts
7583	ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
7584
7585// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
7586function addToPrefiltersOrTransports( structure ) {
7587
7588	// dataTypeExpression is optional and defaults to "*"
7589	return function( dataTypeExpression, func ) {
7590
7591		if ( typeof dataTypeExpression !== "string" ) {
7592			func = dataTypeExpression;
7593			dataTypeExpression = "*";
7594		}
7595
7596		var dataType,
7597			i = 0,
7598			dataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || [];
7599
7600		if ( jQuery.isFunction( func ) ) {
7601			// For each dataType in the dataTypeExpression
7602			while ( (dataType = dataTypes[i++]) ) {
7603				// Prepend if requested
7604				if ( dataType[0] === "+" ) {
7605					dataType = dataType.slice( 1 ) || "*";
7606					(structure[ dataType ] = structure[ dataType ] || []).unshift( func );
7607
7608				// Otherwise append
7609				} else {
7610					(structure[ dataType ] = structure[ dataType ] || []).push( func );
7611				}
7612			}
7613		}
7614	};
7615}
7616
7617// Base inspection function for prefilters and transports
7618function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
7619
7620	var inspected = {},
7621		seekingTransport = ( structure === transports );
7622
7623	function inspect( dataType ) {
7624		var selected;
7625		inspected[ dataType ] = true;
7626		jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
7627			var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
7628			if ( typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[ dataTypeOrTransport ] ) {
7629				options.dataTypes.unshift( dataTypeOrTransport );
7630				inspect( dataTypeOrTransport );
7631				return false;
7632			} else if ( seekingTransport ) {
7633				return !( selected = dataTypeOrTransport );
7634			}
7635		});
7636		return selected;
7637	}
7638
7639	return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
7640}
7641
7642// A special extend for ajax options
7643// that takes "flat" options (not to be deep extended)
7644// Fixes #9887
7645function ajaxExtend( target, src ) {
7646	var key, deep,
7647		flatOptions = jQuery.ajaxSettings.flatOptions || {};
7648
7649	for ( key in src ) {
7650		if ( src[ key ] !== undefined ) {
7651			( flatOptions[ key ] ? target : ( deep || (deep = {}) ) )[ key ] = src[ key ];
7652		}
7653	}
7654	if ( deep ) {
7655		jQuery.extend( true, target, deep );
7656	}
7657
7658	return target;
7659}
7660
7661/* Handles responses to an ajax request:
7662 * - finds the right dataType (mediates between content-type and expected dataType)
7663 * - returns the corresponding response
7664 */
7665function ajaxHandleResponses( s, jqXHR, responses ) {
7666
7667	var ct, type, finalDataType, firstDataType,
7668		contents = s.contents,
7669		dataTypes = s.dataTypes;
7670
7671	// Remove auto dataType and get content-type in the process
7672	while ( dataTypes[ 0 ] === "*" ) {
7673		dataTypes.shift();
7674		if ( ct === undefined ) {
7675			ct = s.mimeType || jqXHR.getResponseHeader("Content-Type");
7676		}
7677	}
7678
7679	// Check if we're dealing with a known content-type
7680	if ( ct ) {
7681		for ( type in contents ) {
7682			if ( contents[ type ] && contents[ type ].test( ct ) ) {
7683				dataTypes.unshift( type );
7684				break;
7685			}
7686		}
7687	}
7688
7689	// Check to see if we have a response for the expected dataType
7690	if ( dataTypes[ 0 ] in responses ) {
7691		finalDataType = dataTypes[ 0 ];
7692	} else {
vendor: 4,724 bytes, lines 7693-7883
7693		// Try convertible dataTypes
7694		for ( type in responses ) {
7695			if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {
7696				finalDataType = type;
7697				break;
7698			}
7699			if ( !firstDataType ) {
7700				firstDataType = type;
7701			}
7702		}
7703		// Or just use first one
7704		finalDataType = finalDataType || firstDataType;
7705	}
7706
7707	// If we found a dataType
7708	// We add the dataType to the list if needed
7709	// and return the corresponding response
7710	if ( finalDataType ) {
7711		if ( finalDataType !== dataTypes[ 0 ] ) {
7712			dataTypes.unshift( finalDataType );
7713		}
7714		return responses[ finalDataType ];
7715	}
7716}
7717
7718/* Chain conversions given the request and the original response
7719 * Also sets the responseXXX fields on the jqXHR instance
7720 */
7721function ajaxConvert( s, response, jqXHR, isSuccess ) {
7722	var conv2, current, conv, tmp, prev,
7723		converters = {},
7724		// Work with a copy of dataTypes in case we need to modify it for conversion
7725		dataTypes = s.dataTypes.slice();
7726
7727	// Create converters map with lowercased keys
7728	if ( dataTypes[ 1 ] ) {
7729		for ( conv in s.converters ) {
7730			converters[ conv.toLowerCase() ] = s.converters[ conv ];
7731		}
7732	}
7733
7734	current = dataTypes.shift();
7735
7736	// Convert to each sequential dataType
7737	while ( current ) {
7738
7739		if ( s.responseFields[ current ] ) {
7740			jqXHR[ s.responseFields[ current ] ] = response;
7741		}
7742
7743		// Apply the dataFilter if provided
7744		if ( !prev && isSuccess && s.dataFilter ) {
7745			response = s.dataFilter( response, s.dataType );
7746		}
7747
7748		prev = current;
7749		current = dataTypes.shift();
7750
7751		if ( current ) {
7752
7753		// There's only work to do if current dataType is non-auto
7754			if ( current === "*" ) {
7755
7756				current = prev;
7757
7758			// Convert response if prev dataType is non-auto and differs from current
7759			} else if ( prev !== "*" && prev !== current ) {
7760
7761				// Seek a direct converter
7762				conv = converters[ prev + " " + current ] || converters[ "* " + current ];
7763
7764				// If none found, seek a pair
7765				if ( !conv ) {
7766					for ( conv2 in converters ) {
7767
7768						// If conv2 outputs current
7769						tmp = conv2.split( " " );
7770						if ( tmp[ 1 ] === current ) {
7771
7772							// If prev can be converted to accepted input
7773							conv = converters[ prev + " " + tmp[ 0 ] ] ||
7774								converters[ "* " + tmp[ 0 ] ];
7775							if ( conv ) {
7776								// Condense equivalence converters
7777								if ( conv === true ) {
7778									conv = converters[ conv2 ];
7779
7780								// Otherwise, insert the intermediate dataType
7781								} else if ( converters[ conv2 ] !== true ) {
7782									current = tmp[ 0 ];
7783									dataTypes.unshift( tmp[ 1 ] );
7784								}
7785								break;
7786							}
7787						}
7788					}
7789				}
7790
7791				// Apply converter (if not an equivalence)
7792				if ( conv !== true ) {
7793
7794					// Unless errors are allowed to bubble, catch and return them
7795					if ( conv && s[ "throws" ] ) {
7796						response = conv( response );
7797					} else {
7798						try {
7799							response = conv( response );
7800						} catch ( e ) {
7801							return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current };
7802						}
7803					}
7804				}
7805			}
7806		}
7807	}
7808
7809	return { state: "success", data: response };
7810}
7811
7812jQuery.extend({
7813
7814	// Counter for holding the number of active queries
7815	active: 0,
7816
7817	// Last-Modified header cache for next request
7818	lastModified: {},
7819	etag: {},
7820
7821	ajaxSettings: {
7822		url: ajaxLocation,
7823		type: "GET",
7824		isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
7825		global: true,
7826		processData: true,
7827		async: true,
7828		contentType: "application/x-www-form-urlencoded; charset=UTF-8",
7829		/*
7830		timeout: 0,
7831		data: null,
7832		dataType: null,
7833		username: null,
7834		password: null,
7835		cache: null,
7836		throws: false,
7837		traditional: false,
7838		headers: {},
7839		*/
7840
7841		accepts: {
7842			"*": allTypes,
7843			text: "text/plain",
7844			html: "text/html",
7845			xml: "application/xml, text/xml",
7846			json: "application/json, text/javascript"
7847		},
7848
7849		contents: {
7850			xml: /xml/,
7851			html: /html/,
7852			json: /json/
7853		},
7854
7855		responseFields: {
7856			xml: "responseXML",
7857			text: "responseText",
7858			json: "responseJSON"
7859		},
7860
7861		// Data converters
7862		// Keys separate source (or catchall "*") and destination types with a single space
7863		converters: {
7864
7865			// Convert anything to text
7866			"* text": String,
7867
7868			// Text to html (true = no transformation)
7869			"text html": true,
7870
7871			// Evaluate text as a json expression
7872			"text json": jQuery.parseJSON,
7873
7874			// Parse text as xml
7875			"text xml": jQuery.parseXML
7876		},
7877
7878		// For options that shouldn't be deep extended:
7879		// you can add your own custom options here if
7880		// and when you create one that shouldn't be
7881		// deep extended (see ajaxExtend)
7882		flatOptions: {
7883			url: true,
vendor: 23,744 bytes, lines 7884-8749
7884			context: true
7885		}
7886	},
7887
7888	// Creates a full fledged settings object into target
7889	// with both ajaxSettings and settings fields.
7890	// If target is omitted, writes into ajaxSettings.
7891	ajaxSetup: function( target, settings ) {
7892		return settings ?
7893
7894			// Building a settings object
7895			ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
7896
7897			// Extending ajaxSettings
7898			ajaxExtend( jQuery.ajaxSettings, target );
7899	},
7900
7901	ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
7902	ajaxTransport: addToPrefiltersOrTransports( transports ),
7903
7904	// Main method
7905	ajax: function( url, options ) {
7906
7907		// If url is an object, simulate pre-1.5 signature
7908		if ( typeof url === "object" ) {
7909			options = url;
7910			url = undefined;
7911		}
7912
7913		// Force options to be an object
7914		options = options || {};
7915
7916		var transport,
7917			// URL without anti-cache param
7918			cacheURL,
7919			// Response headers
7920			responseHeadersString,
7921			responseHeaders,
7922			// timeout handle
7923			timeoutTimer,
7924			// Cross-domain detection vars
7925			parts,
7926			// To know if global events are to be dispatched
7927			fireGlobals,
7928			// Loop variable
7929			i,
7930			// Create the final options object
7931			s = jQuery.ajaxSetup( {}, options ),
7932			// Callbacks context
7933			callbackContext = s.context || s,
7934			// Context for global events is callbackContext if it is a DOM node or jQuery collection
7935			globalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ?
7936				jQuery( callbackContext ) :
7937				jQuery.event,
7938			// Deferreds
7939			deferred = jQuery.Deferred(),
7940			completeDeferred = jQuery.Callbacks("once memory"),
7941			// Status-dependent callbacks
7942			statusCode = s.statusCode || {},
7943			// Headers (they are sent all at once)
7944			requestHeaders = {},
7945			requestHeadersNames = {},
7946			// The jqXHR state
7947			state = 0,
7948			// Default abort message
7949			strAbort = "canceled",
7950			// Fake xhr
7951			jqXHR = {
7952				readyState: 0,
7953
7954				// Builds headers hashtable if needed
7955				getResponseHeader: function( key ) {
7956					var match;
7957					if ( state === 2 ) {
7958						if ( !responseHeaders ) {
7959							responseHeaders = {};
7960							while ( (match = rheaders.exec( responseHeadersString )) ) {
7961								responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
7962							}
7963						}
7964						match = responseHeaders[ key.toLowerCase() ];
7965					}
7966					return match == null ? null : match;
7967				},
7968
7969				// Raw string
7970				getAllResponseHeaders: function() {
7971					return state === 2 ? responseHeadersString : null;
7972				},
7973
7974				// Caches the header
7975				setRequestHeader: function( name, value ) {
7976					var lname = name.toLowerCase();
7977					if ( !state ) {
7978						name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
7979						requestHeaders[ name ] = value;
7980					}
7981					return this;
7982				},
7983
7984				// Overrides response content-type header
7985				overrideMimeType: function( type ) {
7986					if ( !state ) {
7987						s.mimeType = type;
7988					}
7989					return this;
7990				},
7991
7992				// Status-dependent callbacks
7993				statusCode: function( map ) {
7994					var code;
7995					if ( map ) {
7996						if ( state < 2 ) {
7997							for ( code in map ) {
7998								// Lazy-add the new callback in a way that preserves old ones
7999								statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
8000							}
8001						} else {
8002							// Execute the appropriate callbacks
8003							jqXHR.always( map[ jqXHR.status ] );
8004						}
8005					}
8006					return this;
8007				},
8008
8009				// Cancel the request
8010				abort: function( statusText ) {
8011					var finalText = statusText || strAbort;
8012					if ( transport ) {
8013						transport.abort( finalText );
8014					}
8015					done( 0, finalText );
8016					return this;
8017				}
8018			};
8019
8020		// Attach deferreds
8021		deferred.promise( jqXHR ).complete = completeDeferred.add;
8022		jqXHR.success = jqXHR.done;
8023		jqXHR.error = jqXHR.fail;
8024
8025		// Remove hash character (#7531: and string promotion)
8026		// Add protocol if not provided (prefilters might expect it)
8027		// Handle falsy url in the settings object (#10093: consistency with old signature)
8028		// We also use the url parameter if available
8029		s.url = ( ( url || s.url || ajaxLocation ) + "" ).replace( rhash, "" )
8030			.replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
8031
8032		// Alias method option to type as per ticket #12004
8033		s.type = options.method || options.type || s.method || s.type;
8034
8035		// Extract dataTypes list
8036		s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( rnotwhite ) || [ "" ];
8037
8038		// A cross-domain request is in order when we have a protocol:host:port mismatch
8039		if ( s.crossDomain == null ) {
8040			parts = rurl.exec( s.url.toLowerCase() );
8041			s.crossDomain = !!( parts &&
8042				( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||
8043					( parts[ 3 ] || ( parts[ 1 ] === "http:" ? "80" : "443" ) ) !==
8044						( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? "80" : "443" ) ) )
8045			);
8046		}
8047
8048		// Convert data if not already a string
8049		if ( s.data && s.processData && typeof s.data !== "string" ) {
8050			s.data = jQuery.param( s.data, s.traditional );
8051		}
8052
8053		// Apply prefilters
8054		inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
8055
8056		// If request was aborted inside a prefilter, stop there
8057		if ( state === 2 ) {
8058			return jqXHR;
8059		}
8060
8061		// We can fire global events as of now if asked to
8062		// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)
8063		fireGlobals = jQuery.event && s.global;
8064
8065		// Watch for a new set of requests
8066		if ( fireGlobals && jQuery.active++ === 0 ) {
8067			jQuery.event.trigger("ajaxStart");
8068		}
8069
8070		// Uppercase the type
8071		s.type = s.type.toUpperCase();
8072
8073		// Determine if request has content
8074		s.hasContent = !rnoContent.test( s.type );
8075
8076		// Save the URL in case we're toying with the If-Modified-Since
8077		// and/or If-None-Match header later on
8078		cacheURL = s.url;
8079
8080		// More options handling for requests with no content
8081		if ( !s.hasContent ) {
8082
8083			// If data is available, append data to url
8084			if ( s.data ) {
8085				cacheURL = ( s.url += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data );
8086				// #9682: remove data so that it's not used in an eventual retry
8087				delete s.data;
8088			}
8089
8090			// Add anti-cache in url if needed
8091			if ( s.cache === false ) {
8092				s.url = rts.test( cacheURL ) ?
8093
8094					// If there is already a '_' parameter, set its value
8095					cacheURL.replace( rts, "$1_=" + nonce++ ) :
8096
8097					// Otherwise add one to the end
8098					cacheURL + ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + nonce++;
8099			}
8100		}
8101
8102		// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
8103		if ( s.ifModified ) {
8104			if ( jQuery.lastModified[ cacheURL ] ) {
8105				jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
8106			}
8107			if ( jQuery.etag[ cacheURL ] ) {
8108				jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
8109			}
8110		}
8111
8112		// Set the correct header, if data is being sent
8113		if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
8114			jqXHR.setRequestHeader( "Content-Type", s.contentType );
8115		}
8116
8117		// Set the Accepts header for the server, depending on the dataType
8118		jqXHR.setRequestHeader(
8119			"Accept",
8120			s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?
8121				s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
8122				s.accepts[ "*" ]
8123		);
8124
8125		// Check for headers option
8126		for ( i in s.headers ) {
8127			jqXHR.setRequestHeader( i, s.headers[ i ] );
8128		}
8129
8130		// Allow custom headers/mimetypes and early abort
8131		if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
8132			// Abort if not done already and return
8133			return jqXHR.abort();
8134		}
8135
8136		// Aborting is no longer a cancellation
8137		strAbort = "abort";
8138
8139		// Install callbacks on deferreds
8140		for ( i in { success: 1, error: 1, complete: 1 } ) {
8141			jqXHR[ i ]( s[ i ] );
8142		}
8143
8144		// Get transport
8145		transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
8146
8147		// If no transport, we auto-abort
8148		if ( !transport ) {
8149			done( -1, "No Transport" );
8150		} else {
8151			jqXHR.readyState = 1;
8152
8153			// Send global event
8154			if ( fireGlobals ) {
8155				globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
8156			}
8157			// Timeout
8158			if ( s.async && s.timeout > 0 ) {
8159				timeoutTimer = setTimeout(function() {
8160					jqXHR.abort("timeout");
8161				}, s.timeout );
8162			}
8163
8164			try {
8165				state = 1;
8166				transport.send( requestHeaders, done );
8167			} catch ( e ) {
8168				// Propagate exception as error if not done
8169				if ( state < 2 ) {
8170					done( -1, e );
8171				// Simply rethrow otherwise
8172				} else {
8173					throw e;
8174				}
8175			}
8176		}
8177
8178		// Callback for when everything is done
8179		function done( status, nativeStatusText, responses, headers ) {
8180			var isSuccess, success, error, response, modified,
8181				statusText = nativeStatusText;
8182
8183			// Called once
8184			if ( state === 2 ) {
8185				return;
8186			}
8187
8188			// State is "done" now
8189			state = 2;
8190
8191			// Clear timeout if it exists
8192			if ( timeoutTimer ) {
8193				clearTimeout( timeoutTimer );
8194			}
8195
8196			// Dereference transport for early garbage collection
8197			// (no matter how long the jqXHR object will be used)
8198			transport = undefined;
8199
8200			// Cache response headers
8201			responseHeadersString = headers || "";
8202
8203			// Set readyState
8204			jqXHR.readyState = status > 0 ? 4 : 0;
8205
8206			// Determine if successful
8207			isSuccess = status >= 200 && status < 300 || status === 304;
8208
8209			// Get response data
8210			if ( responses ) {
8211				response = ajaxHandleResponses( s, jqXHR, responses );
8212			}
8213
8214			// Convert no matter what (that way responseXXX fields are always set)
8215			response = ajaxConvert( s, response, jqXHR, isSuccess );
8216
8217			// If successful, handle type chaining
8218			if ( isSuccess ) {
8219
8220				// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
8221				if ( s.ifModified ) {
8222					modified = jqXHR.getResponseHeader("Last-Modified");
8223					if ( modified ) {
8224						jQuery.lastModified[ cacheURL ] = modified;
8225					}
8226					modified = jqXHR.getResponseHeader("etag");
8227					if ( modified ) {
8228						jQuery.etag[ cacheURL ] = modified;
8229					}
8230				}
8231
8232				// if no content
8233				if ( status === 204 || s.type === "HEAD" ) {
8234					statusText = "nocontent";
8235
8236				// if not modified
8237				} else if ( status === 304 ) {
8238					statusText = "notmodified";
8239
8240				// If we have data, let's convert it
8241				} else {
8242					statusText = response.state;
8243					success = response.data;
8244					error = response.error;
8245					isSuccess = !error;
8246				}
8247			} else {
8248				// Extract error from statusText and normalize for non-aborts
8249				error = statusText;
8250				if ( status || !statusText ) {
8251					statusText = "error";
8252					if ( status < 0 ) {
8253						status = 0;
8254					}
8255				}
8256			}
8257
8258			// Set data for the fake xhr object
8259			jqXHR.status = status;
8260			jqXHR.statusText = ( nativeStatusText || statusText ) + "";
8261
8262			// Success/Error
8263			if ( isSuccess ) {
8264				deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
8265			} else {
8266				deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
8267			}
8268
8269			// Status-dependent callbacks
8270			jqXHR.statusCode( statusCode );
8271			statusCode = undefined;
8272
8273			if ( fireGlobals ) {
8274				globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
8275					[ jqXHR, s, isSuccess ? success : error ] );
8276			}
8277
8278			// Complete
8279			completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
8280
8281			if ( fireGlobals ) {
8282				globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
8283				// Handle the global AJAX counter
8284				if ( !( --jQuery.active ) ) {
8285					jQuery.event.trigger("ajaxStop");
8286				}
8287			}
8288		}
8289
8290		return jqXHR;
8291	},
8292
8293	getJSON: function( url, data, callback ) {
8294		return jQuery.get( url, data, callback, "json" );
8295	},
8296
8297	getScript: function( url, callback ) {
8298		return jQuery.get( url, undefined, callback, "script" );
8299	}
8300});
8301
8302jQuery.each( [ "get", "post" ], function( i, method ) {
8303	jQuery[ method ] = function( url, data, callback, type ) {
8304		// Shift arguments if data argument was omitted
8305		if ( jQuery.isFunction( data ) ) {
8306			type = type || callback;
8307			callback = data;
8308			data = undefined;
8309		}
8310
8311		return jQuery.ajax({
8312			url: url,
8313			type: method,
8314			dataType: type,
8315			data: data,
8316			success: callback
8317		});
8318	};
8319});
8320
8321
8322jQuery._evalUrl = function( url ) {
8323	return jQuery.ajax({
8324		url: url,
8325		type: "GET",
8326		dataType: "script",
8327		async: false,
8328		global: false,
8329		"throws": true
8330	});
8331};
8332
8333
8334jQuery.fn.extend({
8335	wrapAll: function( html ) {
8336		var wrap;
8337
8338		if ( jQuery.isFunction( html ) ) {
8339			return this.each(function( i ) {
8340				jQuery( this ).wrapAll( html.call(this, i) );
8341			});
8342		}
8343
8344		if ( this[ 0 ] ) {
8345
8346			// The elements to wrap the target around
8347			wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );
8348
8349			if ( this[ 0 ].parentNode ) {
8350				wrap.insertBefore( this[ 0 ] );
8351			}
8352
8353			wrap.map(function() {
8354				var elem = this;
8355
8356				while ( elem.firstElementChild ) {
8357					elem = elem.firstElementChild;
8358				}
8359
8360				return elem;
8361			}).append( this );
8362		}
8363
8364		return this;
8365	},
8366
8367	wrapInner: function( html ) {
8368		if ( jQuery.isFunction( html ) ) {
8369			return this.each(function( i ) {
8370				jQuery( this ).wrapInner( html.call(this, i) );
8371			});
8372		}
8373
8374		return this.each(function() {
8375			var self = jQuery( this ),
8376				contents = self.contents();
8377
8378			if ( contents.length ) {
8379				contents.wrapAll( html );
8380
8381			} else {
8382				self.append( html );
8383			}
8384		});
8385	},
8386
8387	wrap: function( html ) {
8388		var isFunction = jQuery.isFunction( html );
8389
8390		return this.each(function( i ) {
8391			jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html );
8392		});
8393	},
8394
8395	unwrap: function() {
8396		return this.parent().each(function() {
8397			if ( !jQuery.nodeName( this, "body" ) ) {
8398				jQuery( this ).replaceWith( this.childNodes );
8399			}
8400		}).end();
8401	}
8402});
8403
8404
8405jQuery.expr.filters.hidden = function( elem ) {
8406	// Support: Opera <= 12.12
8407	// Opera reports offsetWidths and offsetHeights less than zero on some elements
8408	return elem.offsetWidth <= 0 && elem.offsetHeight <= 0;
8409};
8410jQuery.expr.filters.visible = function( elem ) {
8411	return !jQuery.expr.filters.hidden( elem );
8412};
8413
8414
8415
8416
8417var r20 = /%20/g,
8418	rbracket = /\[\]$/,
8419	rCRLF = /\r?\n/g,
8420	rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
8421	rsubmittable = /^(?:input|select|textarea|keygen)/i;
8422
8423function buildParams( prefix, obj, traditional, add ) {
8424	var name;
8425
8426	if ( jQuery.isArray( obj ) ) {
8427		// Serialize array item.
8428		jQuery.each( obj, function( i, v ) {
8429			if ( traditional || rbracket.test( prefix ) ) {
8430				// Treat each array item as a scalar.
8431				add( prefix, v );
8432
8433			} else {
8434				// Item is non-scalar (array or object), encode its numeric index.
8435				buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add );
8436			}
8437		});
8438
8439	} else if ( !traditional && jQuery.type( obj ) === "object" ) {
8440		// Serialize object item.
8441		for ( name in obj ) {
8442			buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
8443		}
8444
8445	} else {
8446		// Serialize scalar item.
8447		add( prefix, obj );
8448	}
8449}
8450
8451// Serialize an array of form elements or a set of
8452// key/values into a query string
8453jQuery.param = function( a, traditional ) {
8454	var prefix,
8455		s = [],
8456		add = function( key, value ) {
8457			// If value is a function, invoke it and return its value
8458			value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value );
8459			s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
8460		};
8461
8462	// Set traditional to true for jQuery <= 1.3.2 behavior.
8463	if ( traditional === undefined ) {
8464		traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
8465	}
8466
8467	// If an array was passed in, assume that it is an array of form elements.
8468	if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
8469		// Serialize the form elements
8470		jQuery.each( a, function() {
8471			add( this.name, this.value );
8472		});
8473
8474	} else {
8475		// If traditional, encode the "old" way (the way 1.3.2 or older
8476		// did it), otherwise encode params recursively.
8477		for ( prefix in a ) {
8478			buildParams( prefix, a[ prefix ], traditional, add );
8479		}
8480	}
8481
8482	// Return the resulting serialization
8483	return s.join( "&" ).replace( r20, "+" );
8484};
8485
8486jQuery.fn.extend({
8487	serialize: function() {
8488		return jQuery.param( this.serializeArray() );
8489	},
8490	serializeArray: function() {
8491		return this.map(function() {
8492			// Can add propHook for "elements" to filter or add form elements
8493			var elements = jQuery.prop( this, "elements" );
8494			return elements ? jQuery.makeArray( elements ) : this;
8495		})
8496		.filter(function() {
8497			var type = this.type;
8498
8499			// Use .is( ":disabled" ) so that fieldset[disabled] works
8500			return this.name && !jQuery( this ).is( ":disabled" ) &&
8501				rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
8502				( this.checked || !rcheckableType.test( type ) );
8503		})
8504		.map(function( i, elem ) {
8505			var val = jQuery( this ).val();
8506
8507			return val == null ?
8508				null :
8509				jQuery.isArray( val ) ?
8510					jQuery.map( val, function( val ) {
8511						return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
8512					}) :
8513					{ name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
8514		}).get();
8515	}
8516});
8517
8518
8519jQuery.ajaxSettings.xhr = function() {
8520	try {
8521		return new XMLHttpRequest();
8522	} catch( e ) {}
8523};
8524
8525var xhrId = 0,
8526	xhrCallbacks = {},
8527	xhrSuccessStatus = {
8528		// file protocol always yields status code 0, assume 200
8529		0: 200,
8530		// Support: IE9
8531		// #1450: sometimes IE returns 1223 when it should be 204
8532		1223: 204
8533	},
8534	xhrSupported = jQuery.ajaxSettings.xhr();
8535
8536// Support: IE9
8537// Open requests must be manually aborted on unload (#5280)
8538// See https://support.microsoft.com/kb/2856746 for more info
8539if ( window.attachEvent ) {
8540	window.attachEvent( "onunload", function() {
8541		for ( var key in xhrCallbacks ) {
8542			xhrCallbacks[ key ]();
8543		}
8544	});
8545}
8546
8547support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
8548support.ajax = xhrSupported = !!xhrSupported;
8549
8550jQuery.ajaxTransport(function( options ) {
8551	var callback;
8552
8553	// Cross domain only allowed if supported through XMLHttpRequest
8554	if ( support.cors || xhrSupported && !options.crossDomain ) {
8555		return {
8556			send: function( headers, complete ) {
8557				var i,
8558					xhr = options.xhr(),
8559					id = ++xhrId;
8560
8561				xhr.open( options.type, options.url, options.async, options.username, options.password );
8562
8563				// Apply custom fields if provided
8564				if ( options.xhrFields ) {
8565					for ( i in options.xhrFields ) {
8566						xhr[ i ] = options.xhrFields[ i ];
8567					}
8568				}
8569
8570				// Override mime type if needed
8571				if ( options.mimeType && xhr.overrideMimeType ) {
8572					xhr.overrideMimeType( options.mimeType );
8573				}
8574
8575				// X-Requested-With header
8576				// For cross-domain requests, seeing as conditions for a preflight are
8577				// akin to a jigsaw puzzle, we simply never set it to be sure.
8578				// (it can always be set on a per-request basis or even using ajaxSetup)
8579				// For same-domain requests, won't change header if already provided.
8580				if ( !options.crossDomain && !headers["X-Requested-With"] ) {
8581					headers["X-Requested-With"] = "XMLHttpRequest";
8582				}
8583
8584				// Set headers
8585				for ( i in headers ) {
8586					xhr.setRequestHeader( i, headers[ i ] );
8587				}
8588
8589				// Callback
8590				callback = function( type ) {
8591					return function() {
8592						if ( callback ) {
8593							delete xhrCallbacks[ id ];
8594							callback = xhr.onload = xhr.onerror = null;
8595
8596							if ( type === "abort" ) {
8597								xhr.abort();
8598							} else if ( type === "error" ) {
8599								complete(
8600									// file: protocol always yields status 0; see #8605, #14207
8601									xhr.status,
8602									xhr.statusText
8603								);
8604							} else {
8605								complete(
8606									xhrSuccessStatus[ xhr.status ] || xhr.status,
8607									xhr.statusText,
8608									// Support: IE9
8609									// Accessing binary-data responseText throws an exception
8610									// (#11426)
8611									typeof xhr.responseText === "string" ? {
8612										text: xhr.responseText
8613									} : undefined,
8614									xhr.getAllResponseHeaders()
8615								);
8616							}
8617						}
8618					};
8619				};
8620
8621				// Listen to events
8622				xhr.onload = callback();
8623				xhr.onerror = callback("error");
8624
8625				// Create the abort callback
8626				callback = xhrCallbacks[ id ] = callback("abort");
8627
8628				try {
8629					// Do send the request (this may raise an exception)
8630					xhr.send( options.hasContent && options.data || null );
8631				} catch ( e ) {
8632					// #14683: Only rethrow if this hasn't been notified as an error yet
8633					if ( callback ) {
8634						throw e;
8635					}
8636				}
8637			},
8638
8639			abort: function() {
8640				if ( callback ) {
8641					callback();
8642				}
8643			}
8644		};
8645	}
8646});
8647
8648
8649
8650
8651// Install script dataType
8652jQuery.ajaxSetup({
8653	accepts: {
8654		script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
8655	},
8656	contents: {
8657		script: /(?:java|ecma)script/
8658	},
8659	converters: {
8660		"text script": function( text ) {
8661			jQuery.globalEval( text );
8662			return text;
8663		}
8664	}
8665});
8666
8667// Handle cache's special case and crossDomain
8668jQuery.ajaxPrefilter( "script", function( s ) {
8669	if ( s.cache === undefined ) {
8670		s.cache = false;
8671	}
8672	if ( s.crossDomain ) {
8673		s.type = "GET";
8674	}
8675});
8676
8677// Bind script tag hack transport
8678jQuery.ajaxTransport( "script", function( s ) {
8679	// This transport only deals with cross domain requests
8680	if ( s.crossDomain ) {
8681		var script, callback;
8682		return {
8683			send: function( _, complete ) {
8684				script = jQuery("<script>").prop({
8685					async: true,
8686					charset: s.scriptCharset,
8687					src: s.url
8688				}).on(
8689					"load error",
8690					callback = function( evt ) {
8691						script.remove();
8692						callback = null;
8693						if ( evt ) {
8694							complete( evt.type === "error" ? 404 : 200, evt.type );
8695						}
8696					}
8697				);
8698				document.head.appendChild( script[ 0 ] );
8699			},
8700			abort: function() {
8701				if ( callback ) {
8702					callback();
8703				}
8704			}
8705		};
8706	}
8707});
8708
8709
8710
8711
8712var oldCallbacks = [],
8713	rjsonp = /(=)\?(?=&|$)|\?\?/;
8714
8715// Default jsonp settings
8716jQuery.ajaxSetup({
8717	jsonp: "callback",
8718	jsonpCallback: function() {
8719		var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );
8720		this[ callback ] = true;
8721		return callback;
8722	}
8723});
8724
8725// Detect, normalize options and install callbacks for jsonp requests
8726jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
8727
8728	var callbackName, overwritten, responseContainer,
8729		jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
8730			"url" :
8731			typeof s.data === "string" && !( s.contentType || "" ).indexOf("application/x-www-form-urlencoded") && rjsonp.test( s.data ) && "data"
8732		);
8733
8734	// Handle iff the expected data type is "jsonp" or we have a parameter to set
8735	if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
8736
8737		// Get callback name, remembering preexisting value associated with it
8738		callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
8739			s.jsonpCallback() :
8740			s.jsonpCallback;
8741
8742		// Insert callback into url or form data
8743		if ( jsonProp ) {
8744			s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
8745		} else if ( s.jsonp !== false ) {
8746			s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
8747		}
8748
8749		// Use data converter to retrieve json after script execution
vendor: 1,849 bytes, lines 8750-8819
8750		s.converters["script json"] = function() {
8751			if ( !responseContainer ) {
8752				jQuery.error( callbackName + " was not called" );
8753			}
8754			return responseContainer[ 0 ];
8755		};
8756
8757		// force json dataType
8758		s.dataTypes[ 0 ] = "json";
8759
8760		// Install callback
8761		overwritten = window[ callbackName ];
8762		window[ callbackName ] = function() {
8763			responseContainer = arguments;
8764		};
8765
8766		// Clean-up function (fires after converters)
8767		jqXHR.always(function() {
8768			// Restore preexisting value
8769			window[ callbackName ] = overwritten;
8770
8771			// Save back as free
8772			if ( s[ callbackName ] ) {
8773				// make sure that re-using the options doesn't screw things around
8774				s.jsonpCallback = originalSettings.jsonpCallback;
8775
8776				// save the callback name for future use
8777				oldCallbacks.push( callbackName );
8778			}
8779
8780			// Call if it was a function and we have a response
8781			if ( responseContainer && jQuery.isFunction( overwritten ) ) {
8782				overwritten( responseContainer[ 0 ] );
8783			}
8784
8785			responseContainer = overwritten = undefined;
8786		});
8787
8788		// Delegate to script
8789		return "script";
8790	}
8791});
8792
8793
8794
8795
8796// data: string of html
8797// context (optional): If specified, the fragment will be created in this context, defaults to document
8798// keepScripts (optional): If true, will include scripts passed in the html string
8799jQuery.parseHTML = function( data, context, keepScripts ) {
8800	if ( !data || typeof data !== "string" ) {
8801		return null;
8802	}
8803	if ( typeof context === "boolean" ) {
8804		keepScripts = context;
8805		context = false;
8806	}
8807	context = context || document;
8808
8809	var parsed = rsingleTag.exec( data ),
8810		scripts = !keepScripts && [];
8811
8812	// Single tag
8813	if ( parsed ) {
8814		return [ context.createElement( parsed[1] ) ];
8815	}
8816
8817	parsed = jQuery.buildFragment( [ data ], context, scripts );
8818
8819	if ( scripts && scripts.length ) {
vendor: 12,763 bytes, lines 8820-9267
8820		jQuery( scripts ).remove();
8821	}
8822
8823	return jQuery.merge( [], parsed.childNodes );
8824};
8825
8826
8827// Keep a copy of the old load method
8828var _load = jQuery.fn.load;
8829
8830/**
8831 * Load a url into a page
8832 */
8833jQuery.fn.load = function( url, params, callback ) {
8834	if ( typeof url !== "string" && _load ) {
8835		return _load.apply( this, arguments );
8836	}
8837
8838	var selector, type, response,
8839		self = this,
8840		off = url.indexOf(" ");
8841
8842	if ( off >= 0 ) {
8843		selector = jQuery.trim( url.slice( off ) );
8844		url = url.slice( 0, off );
8845	}
8846
8847	// If it's a function
8848	if ( jQuery.isFunction( params ) ) {
8849
8850		// We assume that it's the callback
8851		callback = params;
8852		params = undefined;
8853
8854	// Otherwise, build a param string
8855	} else if ( params && typeof params === "object" ) {
8856		type = "POST";
8857	}
8858
8859	// If we have elements to modify, make the request
8860	if ( self.length > 0 ) {
8861		jQuery.ajax({
8862			url: url,
8863
8864			// if "type" variable is undefined, then "GET" method will be used
8865			type: type,
8866			dataType: "html",
8867			data: params
8868		}).done(function( responseText ) {
8869
8870			// Save response for use in complete callback
8871			response = arguments;
8872
8873			self.html( selector ?
8874
8875				// If a selector was specified, locate the right elements in a dummy div
8876				// Exclude scripts to avoid IE 'Permission Denied' errors
8877				jQuery("<div>").append( jQuery.parseHTML( responseText ) ).find( selector ) :
8878
8879				// Otherwise use the full result
8880				responseText );
8881
8882		}).complete( callback && function( jqXHR, status ) {
8883			self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );
8884		});
8885	}
8886
8887	return this;
8888};
8889
8890
8891
8892
8893// Attach a bunch of functions for handling common AJAX events
8894jQuery.each( [ "ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend" ], function( i, type ) {
8895	jQuery.fn[ type ] = function( fn ) {
8896		return this.on( type, fn );
8897	};
8898});
8899
8900
8901
8902
8903jQuery.expr.filters.animated = function( elem ) {
8904	return jQuery.grep(jQuery.timers, function( fn ) {
8905		return elem === fn.elem;
8906	}).length;
8907};
8908
8909
8910
8911
8912var docElem = window.document.documentElement;
8913
8914/**
8915 * Gets a window from an element
8916 */
8917function getWindow( elem ) {
8918	return jQuery.isWindow( elem ) ? elem : elem.nodeType === 9 && elem.defaultView;
8919}
8920
8921jQuery.offset = {
8922	setOffset: function( elem, options, i ) {
8923		var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
8924			position = jQuery.css( elem, "position" ),
8925			curElem = jQuery( elem ),
8926			props = {};
8927
8928		// Set position first, in-case top/left are set even on static elem
8929		if ( position === "static" ) {
8930			elem.style.position = "relative";
8931		}
8932
8933		curOffset = curElem.offset();
8934		curCSSTop = jQuery.css( elem, "top" );
8935		curCSSLeft = jQuery.css( elem, "left" );
8936		calculatePosition = ( position === "absolute" || position === "fixed" ) &&
8937			( curCSSTop + curCSSLeft ).indexOf("auto") > -1;
8938
8939		// Need to be able to calculate position if either
8940		// top or left is auto and position is either absolute or fixed
8941		if ( calculatePosition ) {
8942			curPosition = curElem.position();
8943			curTop = curPosition.top;
8944			curLeft = curPosition.left;
8945
8946		} else {
8947			curTop = parseFloat( curCSSTop ) || 0;
8948			curLeft = parseFloat( curCSSLeft ) || 0;
8949		}
8950
8951		if ( jQuery.isFunction( options ) ) {
8952			options = options.call( elem, i, curOffset );
8953		}
8954
8955		if ( options.top != null ) {
8956			props.top = ( options.top - curOffset.top ) + curTop;
8957		}
8958		if ( options.left != null ) {
8959			props.left = ( options.left - curOffset.left ) + curLeft;
8960		}
8961
8962		if ( "using" in options ) {
8963			options.using.call( elem, props );
8964
8965		} else {
8966			curElem.css( props );
8967		}
8968	}
8969};
8970
8971jQuery.fn.extend({
8972	offset: function( options ) {
8973		if ( arguments.length ) {
8974			return options === undefined ?
8975				this :
8976				this.each(function( i ) {
8977					jQuery.offset.setOffset( this, options, i );
8978				});
8979		}
8980
8981		var docElem, win,
8982			elem = this[ 0 ],
8983			box = { top: 0, left: 0 },
8984			doc = elem && elem.ownerDocument;
8985
8986		if ( !doc ) {
8987			return;
8988		}
8989
8990		docElem = doc.documentElement;
8991
8992		// Make sure it's not a disconnected DOM node
8993		if ( !jQuery.contains( docElem, elem ) ) {
8994			return box;
8995		}
8996
8997		// Support: BlackBerry 5, iOS 3 (original iPhone)
8998		// If we don't have gBCR, just use 0,0 rather than error
8999		if ( typeof elem.getBoundingClientRect !== strundefined ) {
9000			box = elem.getBoundingClientRect();
9001		}
9002		win = getWindow( doc );
9003		return {
9004			top: box.top + win.pageYOffset - docElem.clientTop,
9005			left: box.left + win.pageXOffset - docElem.clientLeft
9006		};
9007	},
9008
9009	position: function() {
9010		if ( !this[ 0 ] ) {
9011			return;
9012		}
9013
9014		var offsetParent, offset,
9015			elem = this[ 0 ],
9016			parentOffset = { top: 0, left: 0 };
9017
9018		// Fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is its only offset parent
9019		if ( jQuery.css( elem, "position" ) === "fixed" ) {
9020			// Assume getBoundingClientRect is there when computed position is fixed
9021			offset = elem.getBoundingClientRect();
9022
9023		} else {
9024			// Get *real* offsetParent
9025			offsetParent = this.offsetParent();
9026
9027			// Get correct offsets
9028			offset = this.offset();
9029			if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) {
9030				parentOffset = offsetParent.offset();
9031			}
9032
9033			// Add offsetParent borders
9034			parentOffset.top += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true );
9035			parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true );
9036		}
9037
9038		// Subtract parent offsets and element margins
9039		return {
9040			top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
9041			left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
9042		};
9043	},
9044
9045	offsetParent: function() {
9046		return this.map(function() {
9047			var offsetParent = this.offsetParent || docElem;
9048
9049			while ( offsetParent && ( !jQuery.nodeName( offsetParent, "html" ) && jQuery.css( offsetParent, "position" ) === "static" ) ) {
9050				offsetParent = offsetParent.offsetParent;
9051			}
9052
9053			return offsetParent || docElem;
9054		});
9055	}
9056});
9057
9058// Create scrollLeft and scrollTop methods
9059jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
9060	var top = "pageYOffset" === prop;
9061
9062	jQuery.fn[ method ] = function( val ) {
9063		return access( this, function( elem, method, val ) {
9064			var win = getWindow( elem );
9065
9066			if ( val === undefined ) {
9067				return win ? win[ prop ] : elem[ method ];
9068			}
9069
9070			if ( win ) {
9071				win.scrollTo(
9072					!top ? val : window.pageXOffset,
9073					top ? val : window.pageYOffset
9074				);
9075
9076			} else {
9077				elem[ method ] = val;
9078			}
9079		}, method, val, arguments.length, null );
9080	};
9081});
9082
9083// Support: Safari<7+, Chrome<37+
9084// Add the top/left cssHooks using jQuery.fn.position
9085// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
9086// Blink bug: https://code.google.com/p/chromium/issues/detail?id=229280
9087// getComputedStyle returns percent when specified for top/left/bottom/right;
9088// rather than make the css module depend on the offset module, just check for it here
9089jQuery.each( [ "top", "left" ], function( i, prop ) {
9090	jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
9091		function( elem, computed ) {
9092			if ( computed ) {
9093				computed = curCSS( elem, prop );
9094				// If curCSS returns percentage, fallback to offset
9095				return rnumnonpx.test( computed ) ?
9096					jQuery( elem ).position()[ prop ] + "px" :
9097					computed;
9098			}
9099		}
9100	);
9101});
9102
9103
9104// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
9105jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
9106	jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) {
9107		// Margin is only for outerHeight, outerWidth
9108		jQuery.fn[ funcName ] = function( margin, value ) {
9109			var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
9110				extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
9111
9112			return access( this, function( elem, type, value ) {
9113				var doc;
9114
9115				if ( jQuery.isWindow( elem ) ) {
9116					// As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there
9117					// isn't a whole lot we can do. See pull request at this URL for discussion:
9118					// https://github.com/jquery/jquery/pull/764
9119					return elem.document.documentElement[ "client" + name ];
9120				}
9121
9122				// Get document width or height
9123				if ( elem.nodeType === 9 ) {
9124					doc = elem.documentElement;
9125
9126					// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
9127					// whichever is greatest
9128					return Math.max(
9129						elem.body[ "scroll" + name ], doc[ "scroll" + name ],
9130						elem.body[ "offset" + name ], doc[ "offset" + name ],
9131						doc[ "client" + name ]
9132					);
9133				}
9134
9135				return value === undefined ?
9136					// Get width or height on the element, requesting but not forcing parseFloat
9137					jQuery.css( elem, type, extra ) :
9138
9139					// Set width or height on the element
9140					jQuery.style( elem, type, value, extra );
9141			}, type, chainable ? margin : undefined, chainable, null );
9142		};
9143	});
9144});
9145
9146
9147// The number of elements contained in the matched element set
9148jQuery.fn.size = function() {
9149	return this.length;
9150};
9151
9152jQuery.fn.andSelf = jQuery.fn.addBack;
9153
9154
9155
9156
9157// Register as a named AMD module, since jQuery can be concatenated with other
9158// files that may use define, but not via a proper concatenation script that
9159// understands anonymous AMD modules. A named AMD is safest and most robust
9160// way to register. Lowercase jquery is used because AMD module names are
9161// derived from file names, and jQuery is normally delivered in a lowercase
9162// file name. Do this after creating the global so that if an AMD module wants
9163// to call noConflict to hide this version of jQuery, it will work.
9164
9165// Note that for maximum portability, libraries that are not jQuery should
9166// declare themselves as anonymous modules, and avoid setting a global if an
9167// AMD loader is present. jQuery is a special case. For more information, see
9168// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
9169
9170if ( typeof define === "function" && define.amd ) {
9171	define( "jquery", [], function() {
9172		return jQuery;
9173	});
9174}
9175
9176
9177
9178
9179var
9180	// Map over jQuery in case of overwrite
9181	_jQuery = window.jQuery,
9182
9183	// Map over the $ in case of overwrite
9184	_$ = window.$;
9185
9186jQuery.noConflict = function( deep ) {
9187	if ( window.$ === jQuery ) {
9188		window.$ = _$;
9189	}
9190
9191	if ( deep && window.jQuery === jQuery ) {
9192		window.jQuery = _jQuery;
9193	}
9194
9195	return jQuery;
9196};
9197
9198// Expose jQuery and $ identifiers, even in AMD
9199// (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
9200// and CommonJS for browser emulators (#13566)
9201if ( typeof noGlobal === strundefined ) {
9202	window.jQuery = window.$ = jQuery;
9203}
9204
9205
9206
9207
9208return jQuery;
9209
9210}));
9211
9212/*!
9213 * Lightbox v2.9.0
9214 * by Lokesh Dhakar
9215 *
9216 * More info:
9217 * http://lokeshdhakar.com/projects/lightbox2/
9218 *
9219 * Copyright 2007, 2015 Lokesh Dhakar
9220 * Released under the MIT license
9221 * https://github.com/lokesh/lightbox2/blob/master/LICENSE
9222 */
9223
9224// Uses Node, AMD or browser globals to create a module.
9225(function (root, factory) {
9226    if (typeof define === 'function' && define.amd) {
9227        // AMD. Register as an anonymous module.
9228        define(['jquery'], factory);
9229    } else if (typeof exports === 'object') {
9230        // Node. Does not work with strict CommonJS, but
9231        // only CommonJS-like environments that support module.exports,
9232        // like Node.
9233        module.exports = factory(require('jquery'));
9234    } else {
9235        // Browser globals (root is window)
9236        root.lightbox = factory(root.jQuery);
9237    }
9238}(this, function ($) {
9239
9240  function Lightbox(options) {
9241    this.album = [];
9242    this.currentImageIndex = void 0;
9243    this.init();
9244
9245    // options
9246    this.options = $.extend({}, this.constructor.defaults);
9247    this.option(options);
9248  }
9249
9250  // Descriptions of all options available on the demo site:
9251  // http://lokeshdhakar.com/projects/lightbox2/index.html#options
9252  Lightbox.defaults = {
9253    albumLabel: 'Image %1 of %2',
9254    alwaysShowNavOnTouchDevices: false,
9255    fadeDuration: 600,
9256    fitImagesInViewport: true,
9257    imageFadeDuration: 600,
9258    // maxWidth: 800,
9259    // maxHeight: 600,
9260    positionFromTop: 50,
9261    resizeDuration: 700,
9262    showImageNumberLabel: true,
9263    wrapAround: false,
9264    disableScrolling: false,
9265    /*
9266    Sanitize Title
9267    If the caption data is trusted, for example you are hardcoding it in, then leave this to fal
vendor: 4,179 bytes, lines 9267-9368
9267se.
9268    This will free you to add html tags, such as links, in the caption.
9269
9270    If the caption data is user submitted or from some other untrusted source, then set this to true
9271    to prevent xss and other injection attacks.
9272     */
9273    sanitizeTitle: false
9274  };
9275
9276  Lightbox.prototype.option = function(options) {
9277    $.extend(this.options, options);
9278  };
9279
9280  Lightbox.prototype.imageCountLabel = function(currentImageNum, totalImages) {
9281    return this.options.albumLabel.replace(/%1/g, currentImageNum).replace(/%2/g, totalImages);
9282  };
9283
9284  Lightbox.prototype.init = function() {
9285    var self = this;
9286    // Both enable and build methods require the body tag to be in the DOM.
9287    $(document).ready(function() {
9288      self.enable();
9289      self.build();
9290    });
9291  };
9292
9293  // Loop through anchors and areamaps looking for either data-lightbox attributes or rel attributes
9294  // that contain 'lightbox'. When these are clicked, start lightbox.
9295  Lightbox.prototype.enable = function() {
9296    var self = this;
9297    $('body').on('click', 'a[rel^=lightbox], area[rel^=lightbox], a[data-lightbox], area[data-lightbox]', function(event) {
9298      self.start($(event.currentTarget));
9299      return false;
9300    });
9301  };
9302
9303  // Build html for the lightbox and the overlay.
9304  // Attach event handlers to the new DOM elements. click click click
9305  Lightbox.prototype.build = function() {
9306    var self = this;
9307    $('<div id="lightboxOverlay" class="lightboxOverlay"></div><div id="lightbox" class="lightbox"><div class="lb-outerContainer"><div class="lb-container"><img class="lb-image" src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==" /><div class="lb-nav"><a class="lb-prev" href="" ></a><a class="lb-next" href="" ></a></div><div class="lb-loader"><a class="lb-cancel"></a></div></div></div><div class="lb-dataContainer"><div class="lb-data"><div class="lb-details"><span class="lb-caption"></span><span class="lb-number"></span></div><div class="lb-closeContainer"><a class="lb-close"></a></div></div></div></div>').appendTo($('body'));
9308
9309    // Cache jQuery objects
9310    this.$lightbox       = $('#lightbox');
9311    this.$overlay        = $('#lightboxOverlay');
9312    this.$outerContainer = this.$lightbox.find('.lb-outerContainer');
9313    this.$container      = this.$lightbox.find('.lb-container');
9314    this.$image          = this.$lightbox.find('.lb-image');
9315    this.$nav            = this.$lightbox.find('.lb-nav');
9316
9317    // Store css values for future lookup
9318    this.containerPadding = {
9319      top: parseInt(this.$container.css('padding-top'), 10),
9320      right: parseInt(this.$container.css('padding-right'), 10),
9321      bottom: parseInt(this.$container.css('padding-bottom'), 10),
9322      left: parseInt(this.$container.css('padding-left'), 10)
9323    };
9324
9325    this.imageBorderWidth = {
9326      top: parseInt(this.$image.css('border-top-width'), 10),
9327      right: parseInt(this.$image.css('border-right-width'), 10),
9328      bottom: parseInt(this.$image.css('border-bottom-width'), 10),
9329      left: parseInt(this.$image.css('border-left-width'), 10)
9330    };
9331
9332    // Attach event handlers to the newly minted DOM elements
9333    this.$overlay.hide().on('click', function() {
9334      self.end();
9335      return false;
9336    });
9337
9338    this.$lightbox.hide().on('click', function(event) {
9339      if ($(event.target).attr('id') === 'lightbox') {
9340        self.end();
9341      }
9342      return false;
9343    });
9344
9345    this.$outerContainer.on('click', function(event) {
9346      if ($(event.target).attr('id') === 'lightbox') {
9347        self.end();
9348      }
9349      return false;
9350    });
9351
9352    this.$lightbox.find('.lb-prev').on('click', function() {
9353      if (self.currentImageIndex === 0) {
9354        self.changeImage(self.album.length - 1);
9355      } else {
9356        self.changeImage(self.currentImageIndex - 1);
9357      }
9358      return false;
9359    });
9360
9361    this.$lightbox.find('.lb-next').on('click', function() {
9362      if (self.currentImageIndex === self.album.length - 1) {
9363        self.changeImage(0);
9364      } else {
9365        self.changeImage(self.currentImageIndex + 1);
9366      }
9367      return false;
9368    });
9369
9370    /*
9371      Show context menu for image on right-click
9372
9373      There is a div containing the navigation that spans the entire image and lives above of it. If
9374      you right-click, you are right clicking this div and not the image. This prevents users from
9375      saving the image or using other context menu actions with the image.
9376
9377      To fix this, when we detect the right mouse button is pressed down, but not yet clicked, we
9378      set pointer-events to none on the nav div. This is so that the upcoming right-click event on
9379      the next mouseup will bubble down to the image. Once the right-click/contextmenu event occurs
9380      we set the pointer events back to auto for the nav div so it can capture hover and left-click
9381      events as usual.
9382     */
9383    this.$nav.on('mousedown', function(event) {
9384      if (event.which === 3) {
9385        self.$nav.css('pointer-events', 'none');
9386
9387        self.$lightbox.one('contextmenu', function() {
9388          setTimeout(function() {
9389              this.$nav.css('pointer-events', 'auto');
9390          }.bind(self), 0);
9391        });
9392      }
9393    });
9394
9395
9396    this.$lightbox.find('.lb-loader, .lb-close').on('click', function() {
9397      self.end();
9398      return false;
9399    });
9400  };
9401
9402  // Show overlay and lightbox. If the image is part of a set, add siblings to album array.
9403  Lightbox.prototype.start = function($link) {
9404    var self    = this;
9405    var $window = $(window);
9406
9407    $window.on('resize', $.proxy(this.sizeOverlay, this));
9408
9409    $('select, object, embed').css({
9410      visibility: 'hidden'
9411    });
9412
9413    this.sizeOverlay();
9414
9415    this.album = [];
9416    var imageNumber = 0;
9417
9418    function addToAlbum($link) {
9419      self.album.push({
9420        link: $link.attr('href'),
9421        title: $link.attr('data-title') || $link.attr('title')
9422      });
9423    }
9424
9425    // Support both data-lightbox attribute and rel attribute implementations
9426    var dataLightboxValue = $link.attr('data-lightbox');
9427    var $links;
9428
9429    if (dataLightboxValue) {
9430      $links = $($link.prop('tagName') + '[data-lightbox="' + dataLightboxValue + '"]');
9431      for (var i = 0; i < $links.length; i = ++i) {
9432        addToAlbum($($links[i]));
9433        if ($links[i] === $link[0]) {
9434          imageNumber = i;
9435        }
9436      }
9437    } else {
9438      if ($link.attr('rel') === 'lightbox') {
9439        // If image is not part of a set
9440        addToAlbum($link);
9441      } else {
9442        // If image is part of a set
9443        $links = $($link.prop('tagName') + '[rel="' + $link.attr('rel') + '"]');
9444        for (var j = 0; j < $links.length; j = ++j) {
9445          addToAlbum($($links[j]));
9446          if ($links[j] === $link[0]) {
9447            imageNumber = j;
9448          }
9449        }
9450      }
9451    }
9452
9453    // Position Lightbox
9454    var top  = $window.scrollTop() + this.options.positionFromTop;
9455    var left = $window.scrollLeft();
9456    this.$lightbox.css({
9457      top: top + 'px',
9458      left: left + 'px'
9459    }).fadeIn(this.options.fadeDuration);
9460
9461    // Disable scrolling of the page while open
9462    if (this.options.disableScrolling) {
9463      $('body').addClass('lb-disable-scrolling');
9464    }
9465
9466    this.changeImage(imageNumber);
9467  };
9468
9469  // Hide most UI elements in preparation for the animated resizing of the lightbox.
9470  Lightbox.prototype.changeImage = function(imageNumber) {
9471    var self = this;
9472
9473    this.disableKeyboardNav();
9474    var $image = this.$lightbox.find('.lb-image');
9475
9476    this.$overlay.fadeIn(this.options.fadeDuration);
9477
9478    $('.lb-loader').fadeIn('slow');
9479    this.$lightbox.find('.lb-image, .lb-nav, .lb-prev, .lb-next, .lb-dataContainer, .lb-numbers, .lb-caption').hide();
9480
9481    this.$outerContainer.addClass('animating');
9482
9483    // When image to show is preloaded, we send the width and height to sizeContainer()
9484    var preloader = new Image();
9485    preloader.onload = function() {
9486      var $preloader;
9487      var imageHeight;
9488      var imageWidth;
9489      var maxImageHeight;
9490      var maxImageWidth;
9491      var windowHeight;
9492      var windowWidth;
9493
9494      $image.attr('src', self.album[imageNumber].link);
9495
9496      $preloader = $(preloader);
9497
9498      $image.width(preloader.width);
9499      $image.height(preloader.height);
9500
9501      if (self.options.fitImagesInViewport) {
9502        // Fit image inside the viewport.
9503        // Take into account the border around the image and an additional 10px gutter on each side.
9504
9505        windowWidth    = $(window).width();
9506        windowHeight   = $(window).height();
9507        maxImageWidth  = windowWidth - self.containerPadding.left - self.containerPadding.right - self.imageBorderWidth.left - self.imageBorderWidth.right - 20;
9508        maxImageHeight = windowHeight - self.containerPadding.top - self.containerPadding.bottom - self.imageBorderWidth.top - self.imageBorderWidth.bottom - 120;
9509
9510        // Check if image size is larger then maxWidth|maxHeight in settings
9511        if (self.options.maxWidth && self.options.maxWidth < maxImageWidth) {
9512          maxImageWidth = self.options.maxWidth;
9513        }
9514        if (self.options.maxHeight && self.options.maxHeight < maxImageWidth) {
9515          maxImageHeight = self.options.maxHeight;
9516        }
9517
9518        // Is there a fitting issue?
9519        if ((preloader.width > maxImageWidth) || (preloader.height > maxImageHeight)) {
9520          if ((preloader.width / maxImageWidth) > (preloader.height / maxImageHeight)) {
9521            imageWidth  = maxImageWidth;
9522            imageHeight = parseInt(preloader.height / (preloader.width / imageWidth), 10);
9523            $image.width(imageWidth);
9524            $image.height(imageHeight);
9525          } else {
9526            imageHeight = maxImageHeight;
9527            imageWidth = parseInt(preloader.width / (preloader.height / imageHeight), 10);
9528            $image.width(imageWidth);
9529            $image.height(imageHeight);
9530          }
9531        }
9532      }
9533      self.sizeContainer($image.width(), $image.height());
9534    };
9535
9536    preloader.src          = this.album[imageNumber].link;
9537    this.currentImageIndex = imageNumber;
9538  };
9539
9540  // Stretch overlay to fit the viewport
9541  Lightbox.prototype.sizeOverlay = function() {
9542    this.$overlay
9543      .width($(document).width())
9544      .height($(document).height());
9545  };
9546
9547  // Animate the size of the lightbox to fit the image we are showing
9548  Lightbox.prototype.sizeContainer = function(imageWidth, imageHeight) {
9549    var self = this;
9550
9551    var oldWidth  = this.$outerContainer.outerWidth();
9552    var oldHeight = this.$outerContainer.outerHeight();
9553    var newWidth  = imageWidth + this.containerPadding.left + this.containerPadding.right + this.imageBorderWidth.left + this.imageBorderWidth.right;
9554    var newHeight = imageHeight + this.containerPadding.top + this.containerPadding.bottom + this.imageBorderWidth.top + this.imageBorderWidth.bottom;
9555
9556    function postResize() {
9557      self.$lightbox.find('.lb-dataContainer').width(newWidth);
9558      self.$lightbox.find('.lb-prevLink').height(newHeight);
9559      self.$lightbox.find('.lb-nextLink').height(newHeight);
9560      self.showImage();
9561    }
9562
9563    if (oldWidth !== newWidth || oldHeight !== newHeight) {
9564      this.$outerContainer.animate({
9565        width: newWidth,
9566        height: newHeight
9567      }, this.options.resizeDuration, 'swing', function() {
9568        postResize();
9569      });
9570    } else {
9571      postResize();
9572    }
9573  };
9574
9575  // Display the image and its details and begin preload neighboring images.
9576  Lightbox.prototype.showImage = function() {
9577    this.$lightbox.find('.lb-loader').stop(true).hide();
9578    this.$lightbox.find('.lb-image').fadeIn(this.options.imageFadeDuration);
9579
9580    this.updateNav();
9581    this.updateDetails();
9582    this.preloadNeighboringImages();
9583    this.enableKeyboardNav();
9584  };
9585
9586  // Display previous and next navigation if appropriate.
9587  Lightbox.prototype.updateNav = function() {
9588    // Check to see if the browser supports touch events. If so, we take the conservative approach
9589    // and assume that mouse hover events are not supported and always show prev/next navigation
9590    // arrows in image sets.
9591    var alwaysShowNav = false;
9592    try {
9593      document.createEvent('TouchEvent');
9594      alwaysShowNav = (this.options.alwaysShowNavOnTouchDevices) ? true : false;
9595    } catch (e) {}
9596
9597    this.$lightbox.find('.lb-nav').show();
9598
9599    if (this.album.length > 1) {
9600      if (this.options.wrapAround) {
9601        if (alwaysShowNav) {
9602          this.$lightbox.find('.lb-prev, .lb-next').css('opacity', '1');
9603        }
9604        this.$lightbox.find('.lb-prev, .lb-next').show();
9605      } else {
9606        if (this.currentImageIndex > 0) {
9607          this.$lightbox.find('.lb-prev').show();
9608          if (alwaysShowNav) {
9609            this.$lightbox.find('.lb-prev').css('opacity', '1');
9610          }
9611        }
9612        if (this.currentImageIndex < this.album.length - 1) {
9613          this.$lightbox.find('.lb-next').show();
9614          if (alwaysShowNav) {
9615            this.$lightbox.find('.lb-next').css('opacity', '1');
9616          }
9617        }
9618      }
9619    }
9620  };
9621
9622  // Display caption, image number, and closing button.
9623  Lightbox.prototype.updateDetails = function() {
9624    var self = this;
9625
9626    // Enable anchor clicks in the injected caption html.
9627    // Thanks Nate Wright for the fix. @https://github.com/NateWr
9628    if (typeof this.album[this.currentImageIndex].title !== 'undefined' &&
9629      this.album[this.currentImageIndex].title !== '') {
9630      var $caption = this.$lightbox.find('.lb-caption');
9631      if (this.options.sanitizeTitle) {
9632        $caption.text(this.album[this.currentImageIndex].title);
9633      } else {
9634        $caption.html(this.album[this.currentImageIndex].title);
9635      }
9636      $caption.fadeIn('fast')
9637        .find('a').on('click', function(event) {
9638          if ($(this).attr('target') !== undefined) {
9639            window.open($(this).attr('href'), $(this).attr('target'));
9640          } else {
9641            location.href = $(this).attr('href');
9642          }
9643        });
9644    }
9645
9646    if (this.album.length > 1 && this.options.showImageNumberLabel) {
9647      var labelText = this.imageCountLabel(this.currentImageIndex + 1, this.album.length);
9648      this.$lightbox.find('.lb-number').text(labelText).fadeIn('fast');
9649    } else {
9650      this.$lightbox.find('.lb-number').hide();
9651    }
9652
9653    this.$outerContainer.removeClass('animating');
9654
9655    this.$lightbox.find('.lb-dataContainer').fadeIn(this.options.resizeDuration, function() {
9656      return self.sizeOverlay();
9657    });
9658  };
9659
9660  // Preload previous and next images in set.
9661  Lightbox.prototype.preloadNeighboringImages = function() {
9662    if (this.album.length > this.currentImageIndex + 1) {
9663      var preloadNext = new Image();
9664      preloadNext.src = this.album[this.currentImageIndex + 1].link;
9665    }
9666    if (this.currentImageIndex > 0) {
9667      var preloadPrev = new Image();
9668      preloadPrev.src = this.album[this.currentImageIndex - 1].link;
9669    }
9670  };
9671
9672  Lightbox.prototype.enableKeyboardNav = function() {
9673    $(document).on('keyup.keyboard', $.proxy(this.keyboardAction, this));
9674  };
9675
9676  Lightbox.prototype.disableKeyboardNav = function() {
9677    $(document).off('.keyboard');
9678  };
9679
9680  Lightbox.prototype.keyboardAction = function(event) {
9681    var KEYCODE_ESC        = 27;
9682    var KEYCODE_LEFTARROW  = 37;
9683    var KEYCODE_RIGHTARROW = 39;
9684
9685    var keycode = event.keyCode;
9686    var key     = String.fromCharCode(keycode).toLowerCase();
9687    if (keycode === KEYCODE_ESC || key.match(/x|o|c/)) {
9688      this.end();
9689    } else if (key === 'p' || keycode === KEYCODE_LEFTARROW) {
9690      if (this.currentImageIndex !== 0) {
9691        this.changeImage(this.currentImageIndex - 1);
9692      } else if (this.options.wrapAround && this.album.length > 1) {
9693        this.changeImage(this.album.length - 1);
9694      }
9695    } else if (key === 'n' || keycode === KEYCODE_RIGHTARROW) {
9696      if (this.currentImageIndex !== this.album.length - 1) {
9697        this.changeImage(this.currentImageIndex + 1);
9698      } else if (this.options.wrapAround && this.album.length > 1) {
9699        this.changeImage(0);
9700      }
9701    }
9702  };
9703
9704  // Closing time. :-(
9705  Lightbox.prototype.end = function() {
9706    this.disableKeyboardNav();
9707    $(window).off('resize', this.sizeOverlay);
9708    this.$lightbox.fadeOut(this.options.fadeDuration);
9709    this.$overlay.fadeOut(this.options.fadeDuration);
9710    $('select, object, embed').css({
9711      visibility: 'visible'
9712    });
9713    if (this.options.disableScrolling) {
9714      $('body').removeClass('lb-disable-scrolling');
9715    }
9716  };
9717
9718  return new Lightbox();
9719  $( ".example-image-link" ).click(function() {
9720 if($(".lightboxOverlay").height() == $(window).height()) {
9721  $("body").css({
9722					   "overflow": "hidden"
9723				   }); 				   
9724 }
9725 if($("body").height() > $(window).height()) {
9726	 $( ".example-image-link" ).click(function() {
9727	 $(".lightboxOverlay").height() == $(window).height();
9728	 $(".lightbox").css({
9729					   "top": "0px"
9730				   });
9731   });
9732	 }
9733});
9734}));

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.