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