· 9 years ago · Aug 30, 2017, 08:06 AM
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};
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)
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
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};
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};
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
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 = [],
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 });
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 {
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,
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
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 ) {
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
9214
9215
9216
9217
9218
9219
9220
9221
9222
9223
9224
9225
9226
9227
9228
9229
9230
9231
9232
9233
9234
9235
9236
9237
9238
9239
9240
9241
9242
9243
9244
9245
9246/*!
9247 * jScroll - jQuery Plugin for Infinite Scrolling / Auto-Paging
9248 * http://jscroll.com/
9249 *
9250 * Copyright 2011-2013, Philip Klauzinski
9251 * http://klauzinski.com/
9252 * Dual licensed under the MIT and GPL Version 2 licenses.
9253 * http://jscroll.com/#license
9254 * http://www.opensource.org/licenses/mit-license.php
9255 * http://www.gnu.org/licenses/gpl-2.0.html
9256 *
9257 * @author Philip Klauzinski
9258 * @version 2.3.4
9259 * @requires jQuery v1.4.3+
9260 * @preserve
9261 */
9262(function($) {
9263
9264 'use strict';
9265
9266 // Define the jscroll namespace and default settings
9267 $.jscroll = {
9268 defaults: {
9269 debug: false,
9270 autoTrigger: true,
9271 autoTriggerUntil: false,
9272 loadingHtml: '<small>Loading...</small>',
9273 padding: 0,
9274 nextSelector: 'a:last',
9275 contentSelector: '',
9276 pagingSelector: '',
9277 callback: false
9278 }
9279 };
9280
9281 // Constructor
9282 var jScroll = function($e, options) {
9283
9284 // Private vars and methods
9285 var _data = $e.data('jscroll'),
9286 _userOptions = (typeof options === 'function') ? { callback: options } : options,
9287 _options = $.extend({}, $.jscroll.defaults, _userOptions, _data || {}),
9288 _isWindow = ($e.css('overflow-y') === 'visible'),
9289 _$next = $e.find(_options.nextSelector).first(),
9290 _$window = $(window),
9291 _$body = $('body'),
9292 _$scroll = _isWindow ? _$window : $e,
9293 _nextHref = $.trim(_$next.attr('href') + ' ' + _options.contentSelector),
9294
9295 // Check if a loading image is defined and preload
9296 _preloadImage = function() {
9297 var src = $(_options.loadingHtml).filter('img').attr('src');
9298 if (src) {
9299 var image = new Image();
9300 image.src = src;
9301 }
9302 },
9303
9304 // Wrap inner content, if it isn't already
9305 _wrapInnerContent = function() {
9306 if (!$e.find('.jscroll-inner').length) {
9307 $e.contents().wrapAll('<div class="jscroll-inner" />');
9308 }
9309 },
9310
9311 // Find the next link's parent, or add one, and hide it
9312 _nextWrap = function($next) {
9313 var $parent;
9314 if (_options.pagingSelector) {
9315 $next.closest(_options.pagingSelector).hide();
9316 } else {
9317 $parent = $next.parent().not('.jscroll-inner,.jscroll-added').addClass('jscroll-next-parent').hide();
9318 if (!$parent.length) {
9319 $next.wrap('<div class="jscroll-next-parent" />').parent().hide();
9320 }
9321 }
9322 },
9323
9324 // Remove the jscroll behavior and data from an element
9325 _destroy = function() {
9326 return _$scroll.unbind('.jscroll')
9327 .removeData('jscroll')
9328 .find('.jscroll-inner').children().unwrap()
9329 .filter('.jscroll-added').children().unwrap();
9330 },
9331
9332 // Observe the scroll event for when to trigger the next load
9333 _observe = function() {
9334 _wrapInnerContent();
9335 var $inner = $e.find('div.jscroll-inner').first(),
9336 data = $e.data('jscroll'),
9337 borderTopWidth = parseInt($e.css('borderTopWidth'), 10),
9338 borderTopWidthInt = isNaN(borderTopWidth) ? 0 : borderTopWidth,
9339 iContainerTop = parseInt($e.css('paddingTop'), 10) + borderTopWidthInt,
9340 iTopHeight = _isWindow ? _$scroll.scrollTop() : $e.offset().top,
9341 innerTop = $inner.length ? $inner.offset().top : 0,
9342 iTotalHeight = Math.ceil(iTopHeight - innerTop + _$scroll.height() + iContainerTop);
9343
9344 if (!data.waiting && iTotalHeight + _options.padding >= $inner.outerHeight()) {
9345 //data.nextHref = $.trim(data.nextHref + ' ' + _options.contentSelector);
9346 _debug('info', 'jScroll:', $inner.outerHeight() - iTotalHeight, 'from bottom. Loading next request...');
9347 return _load();
9348 }
9349 },
9350
9351 // Check if the href for the next set of content has been set
9352 _checkNextHref = function(data) {
9353 data = data || $e.data('jscroll');
9354 if (!data || !data.nextHref) {
9355 _debug('warn', 'jScroll: nextSelector not found - destroying');
9356 _destroy();
9357 return false;
9358 } else {
9359 _setBindings();
9360 return true;
9361 }
9362 },
9363
9364 _setBindings = function() {
9365 var $next = $e.find(_options.nextSelector).first();
9366 if (!$next.length) {
9367 return;
9368 }
9369 if (_options.autoTrigger && (_options.autoTriggerUntil === false || _options.autoTriggerUntil > 0)) {
9370 _nextWrap($next);
9371 if (_$body.height() <= _$window.height()) {
9372 _observe();
9373 }
9374 _$scroll.unbind('.jscroll').bind('scroll.jscroll', function() {
9375 return _observe();
9376 });
9377 if (_options.autoTriggerUntil > 0) {
9378 _options.autoTriggerUntil--;
9379 }
9380 } else {
9381 _$scroll.unbind('.jscroll');
9382 $next.bind('click.jscroll', function() {
9383 _nextWrap($next);
9384 _load();
9385 return false;
9386 });
9387 }
9388 },
9389
9390 // Load the next set of content, if available
9391 _load = function() {
9392 var $inner = $e.find('div.jscroll-inner').first(),
9393 data = $e.data('jscroll');
9394
9395 data.waiting = true;
9396 $inner.append('<div class="jscroll-added" />')
9397 .children('.jscroll-added').last()
9398 .html('<div class="jscroll-loading">' + _options.loadingHtml + '</div>');
9399
9400 return $e.animate({scrollTop: $inner.outerHeight()}, 0, function() {
9401 $inner.find('div.jscroll-added').last().load(data.nextHref, function(r, status) {
9402 if (status === 'error') {
9403 return _destroy();
9404 }
9405 var $next = $(this).find(_options.nextSelector).first();
9406 data.waiting = false;
9407 data.nextHref = $next.attr('href') ? $.trim($next.attr('href') + ' ' + _options.contentSelector) : false;
9408 $('.jscroll-next-parent', $e).remove(); // Remove the previous next link now that we have a new one
9409 _checkNextHref();
9410 if (_options.callback) {
9411 _options.callback.call(this);
9412 }
9413 _debug('dir', data);
9414 });
9415 });
9416 },
9417
9418 // Safe console debug - http://klauzinski.com/javascript/safe-firebug-console-in-javascript
9419 _debug = function(m) {
9420 if (_options.debug && typeof console === 'object' && (typeof m === 'object' || typeof console[m] === 'function')) {
9421 if (typeof m === 'object') {
9422 var args = [];
9423 for (var sMethod in m) {
9424 if (typeof console[sMethod] === 'function') {
9425 args = (m[sMethod].length) ? m[sMethod] : [m[sMethod]];
9426 console[sMethod].apply(console, args);
9427 } else {
9428 console.log.apply(console, args);
9429 }
9430 }
9431 } else {
9432 console[m].apply(console, Array.prototype.slice.call(arguments, 1));
9433 }
9434 }
9435 };
9436
9437 // Initialization
9438 $e.data('jscroll', $.extend({}, _data, {initialized: true, waiting: false, nextHref: _nextHref}));
9439 _wrapInnerContent();
9440 _preloadImage();
9441 _setBindings();
9442
9443 // Expose API methods via the jQuery.jscroll namespace, e.g. $('sel').jscroll.method()
9444 $.extend($e.jscroll, {
9445 destroy: _destroy
9446 });
9447 return $e;
9448 };
9449
9450 // Define the jscroll plugin method and loop
9451 $.fn.jscroll = function(m) {
9452 return this.each(function() {
9453 var $this = $(this),
9454 data = $this.data('jscroll'), jscroll;
9455
9456 // Instantiate jScroll on this element if it hasn't been already
9457 if (data && data.initialized) {
9458 return;
9459 }
9460 jscroll = new jScroll($this, m);
9461 });
9462 };
9463
9464})(jQuery);
9465
9466
9467
9468$(document).ready(function() {
9469 $('#images-wall').jscroll();
9470});