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