Código fuente de WordPress - jquery (jquery-1.8.3.js)

1 /*!
2 * jQuery JavaScript Library v1.8.3
3 * http://jquery.com/
4 *
5 * Includes Sizzle.js
6 * http://sizzlejs.com/
7 *
8 * Copyright 2012 jQuery Foundation and other contributors
9 * Released under the MIT license
10 * http://jquery.org/license
11 *
12 * Date: Tue Nov 13 2012 08:20:33 GMT-0500 (Eastern Standard Time)
13 */
14 (function( window, undefined ) {
15 var
16 // A central reference to the root jQuery(document)
17 rootjQuery,
18
19 // The deferred used on DOM ready
20 readyList,
21
22 // Use the correct document accordingly with window argument (sandbox)
23 document = window.document,
24 location = window.location,
25 navigator = window.navigator,
26
27 // Map over jQuery in case of overwrite
28 _jQuery = window.jQuery,
29
30 // Map over the $ in case of overwrite
31 _$ = window.$,
32
33 // Save a reference to some core methods
34 core_push = Array.prototype.push,
35 core_slice = Array.prototype.slice,
36 core_indexOf = Array.prototype.indexOf,
37 core_toString = Object.prototype.toString,
38 core_hasOwn = Object.prototype.hasOwnProperty,
39 core_trim = String.prototype.trim,
40
41 // Define a local copy of jQuery
42 jQuery = function( selector, context ) {
43 // The jQuery object is actually just the init constructor 'enhanced'
44 return new jQuery.fn.init( selector, context, rootjQuery );
45 },
46
47 // Used for matching numbers
48 core_pnum = /[\-+]?(?:\d*\.|)\d+(?:[eE][\-+]?\d+|)/.source,
49
50 // Used for detecting and trimming whitespace
51 core_rnotwhite = /\S/,
52 core_rspace = /\s+/,
53
54 // Make sure we trim BOM and NBSP (here's looking at you, Safari 5.0 and IE)
55 rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
56
57 // A simple way to check for HTML strings
58 // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
59 rquickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,
60
61 // Match a standalone tag
62 rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>|)$/,
63
64 // JSON RegExp
65 rvalidchars = /^[\],:{}\s]*$/,
66 rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g,
67 rvalidescape = /\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,
68 rvalidtokens = /"[^"\\\r\n]*"|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g,
69
70 // Matches dashed string for camelizing
71 rmsPrefix = /^-ms-/,
72 rdashAlpha = /-([\da-z])/gi,
73
74 // Used by jQuery.camelCase as callback to replace()
75 fcamelCase = function( all, letter ) {
76 return ( letter + "" ).toUpperCase();
77 },
78
79 // The ready event handler and self cleanup method
80 DOMContentLoaded = function() {
81 if ( document.addEventListener ) {
82 document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
83 jQuery.ready();
84 } else if ( document.readyState === "complete" ) {
85 // we're here because readyState === "complete" in oldIE
86 // which is good enough for us to call the dom ready!
87 document.detachEvent( "onreadystatechange", DOMContentLoaded );
88 jQuery.ready();
89 }
90 },
91
92 // [[Class]] -> type pairs
93 class2type = {};
94
95 jQuery.fn = jQuery.prototype = {
96 constructor: jQuery,
97 init: function( selector, context, rootjQuery ) {
98 var match, elem, ret, doc;
99
100 // Handle $(""), $(null), $(undefined), $(false)
101 if ( !selector ) {
102 return this;
103 }
104
105 // Handle $(DOMElement)
106 if ( selector.nodeType ) {
107 this.context = this[0] = selector;
108 this.length = 1;
109 return this;
110 }
111
112 // Handle HTML strings
113 if ( typeof selector === "string" ) {
114 if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
115 // Assume that strings that start and end with <> are HTML and skip the regex check
116 match = [ null, selector, null ];
117
118 } else {
119 match = rquickExpr.exec( selector );
120 }
121
122 // Match html or make sure no context is specified for #id
123 if ( match && (match[1] || !context) ) {
124
125 // HANDLE: $(html) -> $(array)
126 if ( match[1] ) {
127 context = context instanceof jQuery ? context[0] : context;
128 doc = ( context && context.nodeType ? context.ownerDocument || context : document );
129
130 // scripts is true for back-compat
131 selector = jQuery.parseHTML( match[1], doc, true );
132 if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {
133 this.attr.call( selector, context, true );
134 }
135
136 return jQuery.merge( this, selector );
137
138 // HANDLE: $(#id)
139 } else {
140 elem = document.getElementById( match[2] );
141
142 // Check parentNode to catch when Blackberry 4.6 returns
143 // nodes that are no longer in the document #6963
144 if ( elem && elem.parentNode ) {
145 // Handle the case where IE and Opera return items
146 // by name instead of ID
147 if ( elem.id !== match[2] ) {
148 return rootjQuery.find( selector );
149 }
150
151 // Otherwise, we inject the element directly into the jQuery object
152 this.length = 1;
153 this[0] = elem;
154 }
155
156 this.context = document;
157 this.selector = selector;
158 return this;
159 }
160
161 // HANDLE: $(expr, $(...))
162 } else if ( !context || context.jquery ) {
163 return ( context || rootjQuery ).find( selector );
164
165 // HANDLE: $(expr, context)
166 // (which is just equivalent to: $(context).find(expr)
167 } else {
168 return this.constructor( context ).find( selector );
169 }
170
171 // HANDLE: $(function)
172 // Shortcut for document ready
173 } else if ( jQuery.isFunction( selector ) ) {
174 return rootjQuery.ready( selector );
175 }
176
177 if ( selector.selector !== undefined ) {
178 this.selector = selector.selector;
179 this.context = selector.context;
180 }
181
182 return jQuery.makeArray( selector, this );
183 },
184
185 // Start with an empty selector
186 selector: "",
187
188 // The current version of jQuery being used
189 jquery: "1.8.3",
190
191 // The default length of a jQuery object is 0
192 length: 0,
193
194 // The number of elements contained in the matched element set
195 size: function() {
196 return this.length;
197 },
198
199 toArray: function() {
200 return core_slice.call( this );
201 },
202
203 // Get the Nth element in the matched element set OR
204 // Get the whole matched element set as a clean array
205 get: function( num ) {
206 return num == null ?
207
208 // Return a 'clean' array
209 this.toArray() :
210
211 // Return just the object
212 ( num < 0 ? this[ this.length + num ] : this[ num ] );
213 },
214
215 // Take an array of elements and push it onto the stack
216 // (returning the new matched element set)
217 pushStack: function( elems, name, selector ) {
218
219 // Build a new jQuery matched element set
220 var ret = jQuery.merge( this.constructor(), elems );
221
222 // Add the old object onto the stack (as a reference)
223 ret.prevObject = this;
224
225 ret.context = this.context;
226
227 if ( name === "find" ) {
228 ret.selector = this.selector + ( this.selector ? " " : "" ) + selector;
229 } else if ( name ) {
230 ret.selector = this.selector + "." + name + "(" + selector + ")";
231 }
232
233 // Return the newly-formed element set
234 return ret;
235 },
236
237 // Execute a callback for every element in the matched set.
238 // (You can seed the arguments with an array of args, but this is
239 // only used internally.)
240 each: function( callback, args ) {
241 return jQuery.each( this, callback, args );
242 },
243
244 ready: function( fn ) {
245 // Add the callback
246 jQuery.ready.promise().done( fn );
247
248 return this;
249 },
250
251 eq: function( i ) {
252 i = +i;
253 return i === -1 ?
254 this.slice( i ) :
255 this.slice( i, i + 1 );
256 },
257
258 first: function() {
259 return this.eq( 0 );
260 },
261
262 last: function() {
263 return this.eq( -1 );
264 },
265
266 slice: function() {
267 return this.pushStack( core_slice.apply( this, arguments ),
268 "slice", core_slice.call(arguments).join(",") );
269 },
270
271 map: function( callback ) {
272 return this.pushStack( jQuery.map(this, function( elem, i ) {
273 return callback.call( elem, i, elem );
274 }));
275 },
276
277 end: function() {
278 return this.prevObject || this.constructor(null);
279 },
280
281 // For internal use only.
282 // Behaves like an Array's method, not like a jQuery method.
283 push: core_push,
284 sort: [].sort,
285 splice: [].splice
286 };
287
288 // Give the init function the jQuery prototype for later instantiation
289 jQuery.fn.init.prototype = jQuery.fn;
290
291 jQuery.extend = jQuery.fn.extend = function() {
292 var options, name, src, copy, copyIsArray, clone,
293 target = arguments[0] || {},
294 i = 1,
295 length = arguments.length,
296 deep = false;
297
298 // Handle a deep copy situation
299 if ( typeof target === "boolean" ) {
300 deep = target;
301 target = arguments[1] || {};
302 // skip the boolean and the target
303 i = 2;
304 }
305
306 // Handle case when target is a string or something (possible in deep copy)
307 if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
308 target = {};
309 }
310
311 // extend jQuery itself if only one argument is passed
312 if ( length === i ) {
313 target = this;
314 --i;
315 }
316
317 for ( ; i < length; i++ ) {
318 // Only deal with non-null/undefined values
319 if ( (options = arguments[ i ]) != null ) {
320 // Extend the base object
321 for ( name in options ) {
322 src = target[ name ];
323 copy = options[ name ];
324
325 // Prevent never-ending loop
326 if ( target === copy ) {
327 continue;
328 }
329
330 // Recurse if we're merging plain objects or arrays
331 if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
332 if ( copyIsArray ) {
333 copyIsArray = false;
334 clone = src && jQuery.isArray(src) ? src : [];
335
336 } else {
337 clone = src && jQuery.isPlainObject(src) ? src : {};
338 }
339
340 // Never move original objects, clone them
341 target[ name ] = jQuery.extend( deep, clone, copy );
342
343 // Don't bring in undefined values
344 } else if ( copy !== undefined ) {
345 target[ name ] = copy;
346 }
347 }
348 }
349 }
350
351 // Return the modified object
352 return target;
353 };
354
355 jQuery.extend({
356 noConflict: function( deep ) {
357 if ( window.$ === jQuery ) {
358 window.$ = _$;
359 }
360
361 if ( deep && window.jQuery === jQuery ) {
362 window.jQuery = _jQuery;
363 }
364
365 return jQuery;
366 },
367
368 // Is the DOM ready to be used? Set to true once it occurs.
369 isReady: false,
370
371 // A counter to track how many items to wait for before
372 // the ready event fires. See #6781
373 readyWait: 1,
374
375 // Hold (or release) the ready event
376 holdReady: function( hold ) {
377 if ( hold ) {
378 jQuery.readyWait++;
379 } else {
380 jQuery.ready( true );
381 }
382 },
383
384 // Handle when the DOM is ready
385 ready: function( wait ) {
386
387 // Abort if there are pending holds or we're already ready
388 if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
389 return;
390 }
391
392 // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
393 if ( !document.body ) {
394 return setTimeout( jQuery.ready, 1 );
395 }
396
397 // Remember that the DOM is ready
398 jQuery.isReady = true;
399
400 // If a normal DOM Ready event fired, decrement, and wait if need be
401 if ( wait !== true && --jQuery.readyWait > 0 ) {
402 return;
403 }
404
405 // If there are functions bound, to execute
406 readyList.resolveWith( document, [ jQuery ] );
407
408 // Trigger any bound ready events
409 if ( jQuery.fn.trigger ) {
410 jQuery( document ).trigger("ready").off("ready");
411 }
412 },
413
414 // See test/unit/core.js for details concerning isFunction.
415 // Since version 1.3, DOM methods and functions like alert
416 // aren't supported. They return false on IE (#2968).
417 isFunction: function( obj ) {
418 return jQuery.type(obj) === "function";
419 },
420
421 isArray: Array.isArray || function( obj ) {
422 return jQuery.type(obj) === "array";
423 },
424
425 isWindow: function( obj ) {
426 return obj != null && obj == obj.window;
427 },
428
429 isNumeric: function( obj ) {
430 return !isNaN( parseFloat(obj) ) && isFinite( obj );
431 },
432
433 type: function( obj ) {
434 return obj == null ?
435 String( obj ) :
436 class2type[ core_toString.call(obj) ] || "object";
437 },
438
439 isPlainObject: function( obj ) {
440 // Must be an Object.
441 // Because of IE, we also have to check the presence of the constructor property.
442 // Make sure that DOM nodes and window objects don't pass through, as well
443 if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
444 return false;
445 }
446
447 try {
448 // Not own constructor property must be Object
449 if ( obj.constructor &&
450 !core_hasOwn.call(obj, "constructor") &&
451 !core_hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
452 return false;
453 }
454 } catch ( e ) {
455 // IE8,9 Will throw exceptions on certain host objects #9897
456 return false;
457 }
458
459 // Own properties are enumerated firstly, so to speed up,
460 // if last one is own, then all properties are own.
461
462 var key;
463 for ( key in obj ) {}
464
465 return key === undefined || core_hasOwn.call( obj, key );
466 },
467
468 isEmptyObject: function( obj ) {
469 var name;
470 for ( name in obj ) {
471 return false;
472 }
473 return true;
474 },
475
476 error: function( msg ) {
477 throw new Error( msg );
478 },
479
480 // data: string of html
481 // context (optional): If specified, the fragment will be created in this context, defaults to document
482 // scripts (optional): If true, will include scripts passed in the html string
483 parseHTML: function( data, context, scripts ) {
484 var parsed;
485 if ( !data || typeof data !== "string" ) {
486 return null;
487 }
488 if ( typeof context === "boolean" ) {
489 scripts = context;
490 context = 0;
491 }
492 context = context || document;
493
494 // Single tag
495 if ( (parsed = rsingleTag.exec( data )) ) {
496 return [ context.createElement( parsed[1] ) ];
497 }
498
499 parsed = jQuery.buildFragment( [ data ], context, scripts ? null : [] );
500 return jQuery.merge( [],
501 (parsed.cacheable ? jQuery.clone( parsed.fragment ) : parsed.fragment).childNodes );
502 },
503
504 parseJSON: function( data ) {
505 if ( !data || typeof data !== "string") {
506 return null;
507 }
508
509 // Make sure leading/trailing whitespace is removed (IE can't handle it)
510 data = jQuery.trim( data );
511
512 // Attempt to parse using the native JSON parser first
513 if ( window.JSON && window.JSON.parse ) {
514 return window.JSON.parse( data );
515 }
516
517 // Make sure the incoming data is actual JSON
518 // Logic borrowed from http://json.org/json2.js
519 if ( rvalidchars.test( data.replace( rvalidescape, "@" )
520 .replace( rvalidtokens, "]" )
521 .replace( rvalidbraces, "")) ) {
522
523 return ( new Function( "return " + data ) )();
524
525 }
526 jQuery.error( "Invalid JSON: " + data );
527 },
528
529 // Cross-browser xml parsing
530 parseXML: function( data ) {
531 var xml, tmp;
532 if ( !data || typeof data !== "string" ) {
533 return null;
534 }
535 try {
536 if ( window.DOMParser ) { // Standard
537 tmp = new DOMParser();
538 xml = tmp.parseFromString( data , "text/xml" );
539 } else { // IE
540 xml = new ActiveXObject( "Microsoft.XMLDOM" );
541 xml.async = "false";
542 xml.loadXML( data );
543 }
544 } catch( e ) {
545 xml = undefined;
546 }
547 if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) {
548 jQuery.error( "Invalid XML: " + data );
549 }
550 return xml;
551 },
552
553 noop: function() {},
554
555 // Evaluates a script in a global context
556 // Workarounds based on findings by Jim Driscoll
557 // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
558 globalEval: function( data ) {
559 if ( data && core_rnotwhite.test( data ) ) {
560 // We use execScript on Internet Explorer
561 // We use an anonymous function so that context is window
562 // rather than jQuery in Firefox
563 ( window.execScript || function( data ) {
564 window[ "eval" ].call( window, data );
565 } )( data );
566 }
567 },
568
569 // Convert dashed to camelCase; used by the css and data modules
570 // Microsoft forgot to hump their vendor prefix (#9572)
571 camelCase: function( string ) {
572 return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
573 },
574
575 nodeName: function( elem, name ) {
576 return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
577 },
578
579 // args is for internal usage only
580 each: function( obj, callback, args ) {
581 var name,
582 i = 0,
583 length = obj.length,
584 isObj = length === undefined || jQuery.isFunction( obj );
585
586 if ( args ) {
587 if ( isObj ) {
588 for ( name in obj ) {
589 if ( callback.apply( obj[ name ], args ) === false ) {
590 break;
591 }
592 }
593 } else {
594 for ( ; i < length; ) {
595 if ( callback.apply( obj[ i++ ], args ) === false ) {
596 break;
597 }
598 }
599 }
600
601 // A special, fast, case for the most common use of each
602 } else {
603 if ( isObj ) {
604 for ( name in obj ) {
605 if ( callback.call( obj[ name ], name, obj[ name ] ) === false ) {
606 break;
607 }
608 }
609 } else {
610 for ( ; i < length; ) {
611 if ( callback.call( obj[ i ], i, obj[ i++ ] ) === false ) {
612 break;
613 }
614 }
615 }
616 }
617
618 return obj;
619 },
620
621 // Use native String.trim function wherever possible
622 trim: core_trim && !core_trim.call("\uFEFF\xA0") ?
623 function( text ) {
624 return text == null ?
625 "" :
626 core_trim.call( text );
627 } :
628
629 // Otherwise use our own trimming functionality
630 function( text ) {
631 return text == null ?
632 "" :
633 ( text + "" ).replace( rtrim, "" );
634 },
635
636 // results is for internal usage only
637 makeArray: function( arr, results ) {
638 var type,
639 ret = results || [];
640
641 if ( arr != null ) {
642 // The window, strings (and functions) also have 'length'
643 // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930
644 type = jQuery.type( arr );
645
646 if ( arr.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( arr ) ) {
647 core_push.call( ret, arr );
648 } else {
649 jQuery.merge( ret, arr );
650 }
651 }
652
653 return ret;
654 },
655
656 inArray: function( elem, arr, i ) {
657 var len;
658
659 if ( arr ) {
660 if ( core_indexOf ) {
661 return core_indexOf.call( arr, elem, i );
662 }
663
664 len = arr.length;
665 i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;
666
667 for ( ; i < len; i++ ) {
668 // Skip accessing in sparse arrays
669 if ( i in arr && arr[ i ] === elem ) {
670 return i;
671 }
672 }
673 }
674
675 return -1;
676 },
677
678 merge: function( first, second ) {
679 var l = second.length,
680 i = first.length,
681 j = 0;
682
683 if ( typeof l === "number" ) {
684 for ( ; j < l; j++ ) {
685 first[ i++ ] = second[ j ];
686 }
687
688 } else {
689 while ( second[j] !== undefined ) {
690 first[ i++ ] = second[ j++ ];
691 }
692 }
693
694 first.length = i;
695
696 return first;
697 },
698
699 grep: function( elems, callback, inv ) {
700 var retVal,
701 ret = [],
702 i = 0,
703 length = elems.length;
704 inv = !!inv;
705
706 // Go through the array, only saving the items
707 // that pass the validator function
708 for ( ; i < length; i++ ) {
709 retVal = !!callback( elems[ i ], i );
710 if ( inv !== retVal ) {
711 ret.push( elems[ i ] );
712 }
713 }
714
715 return ret;
716 },
717
718 // arg is for internal usage only
719 map: function( elems, callback, arg ) {
720 var value, key,
721 ret = [],
722 i = 0,
723 length = elems.length,
724 // jquery objects are treated as arrays
725 isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ;
726
727 // Go through the array, translating each of the items to their
728 if ( isArray ) {
729 for ( ; i < length; i++ ) {
730 value = callback( elems[ i ], i, arg );
731
732 if ( value != null ) {
733 ret[ ret.length ] = value;
734 }
735 }
736
737 // Go through every key on the object,
738 } else {
739 for ( key in elems ) {
740 value = callback( elems[ key ], key, arg );
741
742 if ( value != null ) {
743 ret[ ret.length ] = value;
744 }
745 }
746 }
747
748 // Flatten any nested arrays
749 return ret.concat.apply( [], ret );
750 },
751
752 // A global GUID counter for objects
753 guid: 1,
754
755 // Bind a function to a context, optionally partially applying any
756 // arguments.
757 proxy: function( fn, context ) {
758 var tmp, args, proxy;
759
760 if ( typeof context === "string" ) {
761 tmp = fn[ context ];
762 context = fn;
763 fn = tmp;
764 }
765
766 // Quick check to determine if target is callable, in the spec
767 // this throws a TypeError, but we will just return undefined.
768 if ( !jQuery.isFunction( fn ) ) {
769 return undefined;
770 }
771
772 // Simulated bind
773 args = core_slice.call( arguments, 2 );
774 proxy = function() {
775 return fn.apply( context, args.concat( core_slice.call( arguments ) ) );
776 };
777
778 // Set the guid of unique handler to the same of original handler, so it can be removed
779 proxy.guid = fn.guid = fn.guid || jQuery.guid++;
780
781 return proxy;
782 },
783
784 // Multifunctional method to get and set values of a collection
785 // The value/s can optionally be executed if it's a function
786 access: function( elems, fn, key, value, chainable, emptyGet, pass ) {
787 var exec,
788 bulk = key == null,
789 i = 0,
790 length = elems.length;
791
792 // Sets many values
793 if ( key && typeof key === "object" ) {
794 for ( i in key ) {
795 jQuery.access( elems, fn, i, key[i], 1, emptyGet, value );
796 }
797 chainable = 1;
798
799 // Sets one value
800 } else if ( value !== undefined ) {
801 // Optionally, function values get executed if exec is true
802 exec = pass === undefined && jQuery.isFunction( value );
803
804 if ( bulk ) {
805 // Bulk operations only iterate when executing function values
806 if ( exec ) {
807 exec = fn;
808 fn = function( elem, key, value ) {
809 return exec.call( jQuery( elem ), value );
810 };
811
812 // Otherwise they run against the entire set
813 } else {
814 fn.call( elems, value );
815 fn = null;
816 }
817 }
818
819 if ( fn ) {
820 for (; i < length; i++ ) {
821 fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
822 }
823 }
824
825 chainable = 1;
826 }
827
828 return chainable ?
829 elems :
830
831 // Gets
832 bulk ?
833 fn.call( elems ) :
834 length ? fn( elems[0], key ) : emptyGet;
835 },
836
837 now: function() {
838 return ( new Date() ).getTime();
839 }
840 });
841
842 jQuery.ready.promise = function( obj ) {
843 if ( !readyList ) {
844
845 readyList = jQuery.Deferred();
846
847 // Catch cases where $(document).ready() is called after the browser event has already occurred.
848 // we once tried to use readyState "interactive" here, but it caused issues like the one
849 // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15
850 if ( document.readyState === "complete" ) {
851 // Handle it asynchronously to allow scripts the opportunity to delay ready
852 setTimeout( jQuery.ready, 1 );
853
854 // Standards-based browsers support DOMContentLoaded
855 } else if ( document.addEventListener ) {
856 // Use the handy event callback
857 document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
858
859 // A fallback to window.onload, that will always work
860 window.addEventListener( "load", jQuery.ready, false );
861
862 // If IE event model is used
863 } else {
864 // Ensure firing before onload, maybe late but safe also for iframes
865 document.attachEvent( "onreadystatechange", DOMContentLoaded );
866
867 // A fallback to window.onload, that will always work
868 window.attachEvent( "onload", jQuery.ready );
869
870 // If IE and not a frame
871 // continually check to see if the document is ready
872 var top = false;
873
874 try {
875 top = window.frameElement == null && document.documentElement;
876 } catch(e) {}
877
878 if ( top && top.doScroll ) {
879 (function doScrollCheck() {
880 if ( !jQuery.isReady ) {
881
882 try {
883 // Use the trick by Diego Perini
884 // http://javascript.nwbox.com/IEContentLoaded/
885 top.doScroll("left");
886 } catch(e) {
887 return setTimeout( doScrollCheck, 50 );
888 }
889
890 // and execute any waiting functions
891 jQuery.ready();
892 }
893 })();
894 }
895 }
896 }
897 return readyList.promise( obj );
898 };
899
900 // Populate the class2type map
901 jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) {
902 class2type[ "[object " + name + "]" ] = name.toLowerCase();
903 });
904
905 // All jQuery objects should point back to these
906 rootjQuery = jQuery(document);
907 // String to Object options format cache
908 var optionsCache = {};
909
910 // Convert String-formatted options into Object-formatted ones and store in cache
911 function createOptions( options ) {
912 var object = optionsCache[ options ] = {};
913 jQuery.each( options.split( core_rspace ), function( _, flag ) {
914 object[ flag ] = true;
915 });
916 return object;
917 }
918
919 /*
920 * Create a callback list using the following parameters:
921 *
922 * options: an optional list of space-separated options that will change how
923 * the callback list behaves or a more traditional option object
924 *
925 * By default a callback list will act like an event callback list and can be
926 * "fired" multiple times.
927 *
928 * Possible options:
929 *
930 * once: will ensure the callback list can only be fired once (like a Deferred)
931 *
932 * memory: will keep track of previous values and will call any callback added
933 * after the list has been fired right away with the latest "memorized"
934 * values (like a Deferred)
935 *
936 * unique: will ensure a callback can only be added once (no duplicate in the list)
937 *
938 * stopOnFalse: interrupt callings when a callback returns false
939 *
940 */
941 jQuery.Callbacks = function( options ) {
942
943 // Convert options from String-formatted to Object-formatted if needed
944 // (we check in cache first)
945 options = typeof options === "string" ?
946 ( optionsCache[ options ] || createOptions( options ) ) :
947 jQuery.extend( {}, options );
948
949 var // Last fire value (for non-forgettable lists)
950 memory,
951 // Flag to know if list was already fired
952 fired,
953 // Flag to know if list is currently firing
954 firing,
955 // First callback to fire (used internally by add and fireWith)
956 firingStart,
957 // End of the loop when firing
958 firingLength,
959 // Index of currently firing callback (modified by remove if needed)
960 firingIndex,
961 // Actual callback list
962 list = [],
963 // Stack of fire calls for repeatable lists
964 stack = !options.once && [],
965 // Fire callbacks
966 fire = function( data ) {
967 memory = options.memory && data;
968 fired = true;
969 firingIndex = firingStart || 0;
970 firingStart = 0;
971 firingLength = list.length;
972 firing = true;
973 for ( ; list && firingIndex < firingLength; firingIndex++ ) {
974 if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {
975 memory = false; // To prevent further calls using add
976 break;
977 }
978 }
979 firing = false;
980 if ( list ) {
981 if ( stack ) {
982 if ( stack.length ) {
983 fire( stack.shift() );
984 }
985 } else if ( memory ) {
986 list = [];
987 } else {
988 self.disable();
989 }
990 }
991 },
992 // Actual Callbacks object
993 self = {
994 // Add a callback or a collection of callbacks to the list
995 add: function() {
996 if ( list ) {
997 // First, we save the current length
998 var start = list.length;
999 (function add( args ) {
1000 jQuery.each( args, function( _, arg ) {
1001 var type = jQuery.type( arg );
1002 if ( type === "function" ) {
1003 if ( !options.unique || !self.has( arg ) ) {
1004 list.push( arg );
1005 }
1006 } else if ( arg && arg.length && type !== "string" ) {
1007 // Inspect recursively
1008 add( arg );
1009 }
1010 });
1011 })( arguments );
1012 // Do we need to add the callbacks to the
1013 // current firing batch?
1014 if ( firing ) {
1015 firingLength = list.length;
1016 // With memory, if we're not firing then
1017 // we should call right away
1018 } else if ( memory ) {
1019 firingStart = start;
1020 fire( memory );
1021 }
1022 }
1023 return this;
1024 },
1025 // Remove a callback from the list
1026 remove: function() {
1027 if ( list ) {
1028 jQuery.each( arguments, function( _, arg ) {
1029 var index;
1030 while( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
1031 list.splice( index, 1 );
1032 // Handle firing indexes
1033 if ( firing ) {
1034 if ( index <= firingLength ) {
1035 firingLength--;
1036 }
1037 if ( index <= firingIndex ) {
1038 firingIndex--;
1039 }
1040 }
1041 }
1042 });
1043 }
1044 return this;
1045 },
1046 // Control if a given callback is in the list
1047 has: function( fn ) {
1048 return jQuery.inArray( fn, list ) > -1;
1049 },
1050 // Remove all callbacks from the list
1051 empty: function() {
1052 list = [];
1053 return this;
1054 },
1055 // Have the list do nothing anymore
1056 disable: function() {
1057 list = stack = memory = undefined;
1058 return this;
1059 },
1060 // Is it disabled?
1061 disabled: function() {
1062 return !list;
1063 },
1064 // Lock the list in its current state
1065 lock: function() {
1066 stack = undefined;
1067 if ( !memory ) {
1068 self.disable();
1069 }
1070 return this;
1071 },
1072 // Is it locked?
1073 locked: function() {
1074 return !stack;
1075 },
1076 // Call all callbacks with the given context and arguments
1077 fireWith: function( context, args ) {
1078 args = args || [];
1079 args = [ context, args.slice ? args.slice() : args ];
1080 if ( list && ( !fired || stack ) ) {
1081 if ( firing ) {
1082 stack.push( args );
1083 } else {
1084 fire( args );
1085 }
1086 }
1087 return this;
1088 },
1089 // Call all the callbacks with the given arguments
1090 fire: function() {
1091 self.fireWith( this, arguments );
1092 return this;
1093 },
1094 // To know if the callbacks have already been called at least once
1095 fired: function() {
1096 return !!fired;
1097 }
1098 };
1099
1100 return self;
1101 };
1102 jQuery.extend({
1103
1104 Deferred: function( func ) {
1105 var tuples = [
1106 // action, add listener, listener list, final state
1107 [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ],
1108 [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ],
1109 [ "notify", "progress", jQuery.Callbacks("memory") ]
1110 ],
1111 state = "pending",
1112 promise = {
1113 state: function() {
1114 return state;
1115 },
1116 always: function() {
1117 deferred.done( arguments ).fail( arguments );
1118 return this;
1119 },
1120 then: function( /* fnDone, fnFail, fnProgress */ ) {
1121 var fns = arguments;
1122 return jQuery.Deferred(function( newDefer ) {
1123 jQuery.each( tuples, function( i, tuple ) {
1124 var action = tuple[ 0 ],
1125 fn = fns[ i ];
1126 // deferred[ done | fail | progress ] for forwarding actions to newDefer
1127 deferred[ tuple[1] ]( jQuery.isFunction( fn ) ?
1128 function() {
1129 var returned = fn.apply( this, arguments );
1130 if ( returned && jQuery.isFunction( returned.promise ) ) {
1131 returned.promise()
1132 .done( newDefer.resolve )
1133 .fail( newDefer.reject )
1134 .progress( newDefer.notify );
1135 } else {
1136 newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] );
1137 }
1138 } :
1139 newDefer[ action ]
1140 );
1141 });
1142 fns = null;
1143 }).promise();
1144 },
1145 // Get a promise for this deferred
1146 // If obj is provided, the promise aspect is added to the object
1147 promise: function( obj ) {
1148 return obj != null ? jQuery.extend( obj, promise ) : promise;
1149 }
1150 },
1151 deferred = {};
1152
1153 // Keep pipe for back-compat
1154 promise.pipe = promise.then;
1155
1156 // Add list-specific methods
1157 jQuery.each( tuples, function( i, tuple ) {
1158 var list = tuple[ 2 ],
1159 stateString = tuple[ 3 ];
1160
1161 // promise[ done | fail | progress ] = list.add
1162 promise[ tuple[1] ] = list.add;
1163
1164 // Handle state
1165 if ( stateString ) {
1166 list.add(function() {
1167 // state = [ resolved | rejected ]
1168 state = stateString;
1169
1170 // [ reject_list | resolve_list ].disable; progress_list.lock
1171 }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );
1172 }
1173
1174 // deferred[ resolve | reject | notify ] = list.fire
1175 deferred[ tuple[0] ] = list.fire;
1176 deferred[ tuple[0] + "With" ] = list.fireWith;
1177 });
1178
1179 // Make the deferred a promise
1180 promise.promise( deferred );
1181
1182 // Call given func if any
1183 if ( func ) {
1184 func.call( deferred, deferred );
1185 }
1186
1187 // All done!
1188 return deferred;
1189 },
1190
1191 // Deferred helper
1192 when: function( subordinate /* , ..., subordinateN */ ) {
1193 var i = 0,
1194 resolveValues = core_slice.call( arguments ),
1195 length = resolveValues.length,
1196
1197 // the count of uncompleted subordinates
1198 remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,
1199
1200 // the master Deferred. If resolveValues consist of only a single Deferred, just use that.
1201 deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
1202
1203 // Update function for both resolve and progress values
1204 updateFunc = function( i, contexts, values ) {
1205 return function( value ) {
1206 contexts[ i ] = this;
1207 values[ i ] = arguments.length > 1 ? core_slice.call( arguments ) : value;
1208 if( values === progressValues ) {
1209 deferred.notifyWith( contexts, values );
1210 } else if ( !( --remaining ) ) {
1211 deferred.resolveWith( contexts, values );
1212 }
1213 };
1214 },
1215
1216 progressValues, progressContexts, resolveContexts;
1217
1218 // add listeners to Deferred subordinates; treat others as resolved
1219 if ( length > 1 ) {
1220 progressValues = new Array( length );
1221 progressContexts = new Array( length );
1222 resolveContexts = new Array( length );
1223 for ( ; i < length; i++ ) {
1224 if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
1225 resolveValues[ i ].promise()
1226 .done( updateFunc( i, resolveContexts, resolveValues ) )
1227 .fail( deferred.reject )
1228 .progress( updateFunc( i, progressContexts, progressValues ) );
1229 } else {
1230 --remaining;
1231 }
1232 }
1233 }
1234
1235 // if we're not waiting on anything, resolve the master
1236 if ( !remaining ) {
1237 deferred.resolveWith( resolveContexts, resolveValues );
1238 }
1239
1240 return deferred.promise();
1241 }
1242 });
1243 jQuery.support = (function() {
1244
1245 var support,
1246 all,
1247 a,
1248 select,
1249 opt,
1250 input,
1251 fragment,
1252 eventName,
1253 i,
1254 isSupported,
1255 clickFn,
1256 div = document.createElement("div");
1257
1258 // Setup
1259 div.setAttribute( "className", "t" );
1260 div.innerHTML = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
1261
1262 // Support tests won't run in some limited or non-browser environments
1263 all = div.getElementsByTagName("*");
1264 a = div.getElementsByTagName("a")[ 0 ];
1265 if ( !all || !a || !all.length ) {
1266 return {};
1267 }
1268
1269 // First batch of tests
1270 select = document.createElement("select");
1271 opt = select.appendChild( document.createElement("option") );
1272 input = div.getElementsByTagName("input")[ 0 ];
1273
1274 a.style.cssText = "top:1px;float:left;opacity:.5";
1275 support = {
1276 // IE strips leading whitespace when .innerHTML is used
1277 leadingWhitespace: ( div.firstChild.nodeType === 3 ),
1278
1279 // Make sure that tbody elements aren't automatically inserted
1280 // IE will insert them into empty tables
1281 tbody: !div.getElementsByTagName("tbody").length,
1282
1283 // Make sure that link elements get serialized correctly by innerHTML
1284 // This requires a wrapper element in IE
1285 htmlSerialize: !!div.getElementsByTagName("link").length,
1286
1287 // Get the style information from getAttribute
1288 // (IE uses .cssText instead)
1289 style: /top/.test( a.getAttribute("style") ),
1290
1291 // Make sure that URLs aren't manipulated
1292 // (IE normalizes it by default)
1293 hrefNormalized: ( a.getAttribute("href") === "/a" ),
1294
1295 // Make sure that element opacity exists
1296 // (IE uses filter instead)
1297 // Use a regex to work around a WebKit issue. See #5145
1298 opacity: /^0.5/.test( a.style.opacity ),
1299
1300 // Verify style float existence
1301 // (IE uses styleFloat instead of cssFloat)
1302 cssFloat: !!a.style.cssFloat,
1303
1304 // Make sure that if no value is specified for a checkbox
1305 // that it defaults to "on".
1306 // (WebKit defaults to "" instead)
1307 checkOn: ( input.value === "on" ),
1308
1309 // Make sure that a selected-by-default option has a working selected property.
1310 // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
1311 optSelected: opt.selected,
1312
1313 // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)
1314 getSetAttribute: div.className !== "t",
1315
1316 // Tests for enctype support on a form (#6743)
1317 enctype: !!document.createElement("form").enctype,
1318
1319 // Makes sure cloning an html5 element does not cause problems
1320 // Where outerHTML is undefined, this still works
1321 html5Clone: document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav></:nav>",
1322
1323 // jQuery.support.boxModel DEPRECATED in 1.8 since we don't support Quirks Mode
1324 boxModel: ( document.compatMode === "CSS1Compat" ),
1325
1326 // Will be defined later
1327 submitBubbles: true,
1328 changeBubbles: true,
1329 focusinBubbles: false,
1330 deleteExpando: true,
1331 noCloneEvent: true,
1332 inlineBlockNeedsLayout: false,
1333 shrinkWrapBlocks: false,
1334 reliableMarginRight: true,
1335 boxSizingReliable: true,
1336 pixelPosition: false
1337 };
1338
1339 // Make sure checked status is properly cloned
1340 input.checked = true;
1341 support.noCloneChecked = input.cloneNode( true ).checked;
1342
1343 // Make sure that the options inside disabled selects aren't marked as disabled
1344 // (WebKit marks them as disabled)
1345 select.disabled = true;
1346 support.optDisabled = !opt.disabled;
1347
1348 // Test to see if it's possible to delete an expando from an element
1349 // Fails in Internet Explorer
1350 try {
1351 delete div.test;
1352 } catch( e ) {
1353 support.deleteExpando = false;
1354 }
1355
1356 if ( !div.addEventListener && div.attachEvent && div.fireEvent ) {
1357 div.attachEvent( "onclick", clickFn = function() {
1358 // Cloning a node shouldn't copy over any
1359 // bound event handlers (IE does this)
1360 support.noCloneEvent = false;
1361 });
1362 div.cloneNode( true ).fireEvent("onclick");
1363 div.detachEvent( "onclick", clickFn );
1364 }
1365
1366 // Check if a radio maintains its value
1367 // after being appended to the DOM
1368 input = document.createElement("input");
1369 input.value = "t";
1370 input.setAttribute( "type", "radio" );
1371 support.radioValue = input.value === "t";
1372
1373 input.setAttribute( "checked", "checked" );
1374
1375 // #11217 - WebKit loses check when the name is after the checked attribute
1376 input.setAttribute( "name", "t" );
1377
1378 div.appendChild( input );
1379 fragment = document.createDocumentFragment();
1380 fragment.appendChild( div.lastChild );
1381
1382 // WebKit doesn't clone checked state correctly in fragments
1383 support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;
1384
1385 // Check if a disconnected checkbox will retain its checked
1386 // value of true after appended to the DOM (IE6/7)
1387 support.appendChecked = input.checked;
1388
1389 fragment.removeChild( input );
1390 fragment.appendChild( div );
1391
1392 // Technique from Juriy Zaytsev
1393 // http://perfectionkills.com/detecting-event-support-without-browser-sniffing/
1394 // We only care about the case where non-standard event systems
1395 // are used, namely in IE. Short-circuiting here helps us to
1396 // avoid an eval call (in setAttribute) which can cause CSP
1397 // to go haywire. See: https://developer.mozilla.org/en/Security/CSP
1398 if ( div.attachEvent ) {
1399 for ( i in {
1400 submit: true,
1401 change: true,
1402 focusin: true
1403 }) {
1404 eventName = "on" + i;
1405 isSupported = ( eventName in div );
1406 if ( !isSupported ) {
1407 div.setAttribute( eventName, "return;" );
1408 isSupported = ( typeof div[ eventName ] === "function" );
1409 }
1410 support[ i + "Bubbles" ] = isSupported;
1411 }
1412 }
1413
1414 // Run tests that need a body at doc ready
1415 jQuery(function() {
1416 var container, div, tds, marginDiv,
1417 divReset = "padding:0;margin:0;border:0;display:block;overflow:hidden;",
1418 body = document.getElementsByTagName("body")[0];
1419
1420 if ( !body ) {
1421 // Return for frameset docs that don't have a body
1422 return;
1423 }
1424
1425 container = document.createElement("div");
1426 container.style.cssText = "visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px";
1427 body.insertBefore( container, body.firstChild );
1428
1429 // Construct the test element
1430 div = document.createElement("div");
1431 container.appendChild( div );
1432
1433 // Check if table cells still have offsetWidth/Height when they are set
1434 // to display:none and there are still other visible table cells in a
1435 // table row; if so, offsetWidth/Height are not reliable for use when
1436 // determining if an element has been hidden directly using
1437 // display:none (it is still safe to use offsets if a parent element is
1438 // hidden; don safety goggles and see bug #4512 for more information).
1439 // (only IE 8 fails this test)
1440 div.innerHTML = "<table><tr><td></td><td>t</td></tr></table>";
1441 tds = div.getElementsByTagName("td");
1442 tds[ 0 ].style.cssText = "padding:0;margin:0;border:0;display:none";
1443 isSupported = ( tds[ 0 ].offsetHeight === 0 );
1444
1445 tds[ 0 ].style.display = "";
1446 tds[ 1 ].style.display = "none";
1447
1448 // Check if empty table cells still have offsetWidth/Height
1449 // (IE <= 8 fail this test)
1450 support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );
1451
1452 // Check box-sizing and margin behavior
1453 div.innerHTML = "";
1454 div.style.cssText = "box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;";
1455 support.boxSizing = ( div.offsetWidth === 4 );
1456 support.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== 1 );
1457
1458 // NOTE: To any future maintainer, we've window.getComputedStyle
1459 // because jsdom on node.js will break without it.
1460 if ( window.getComputedStyle ) {
1461 support.pixelPosition = ( window.getComputedStyle( div, null ) || {} ).top !== "1%";
1462 support.boxSizingReliable = ( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px";
1463
1464 // Check if div with explicit width and no margin-right incorrectly
1465 // gets computed margin-right based on width of container. For more
1466 // info see bug #3333
1467 // Fails in WebKit before Feb 2011 nightlies
1468 // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
1469 marginDiv = document.createElement("div");
1470 marginDiv.style.cssText = div.style.cssText = divReset;
1471 marginDiv.style.marginRight = marginDiv.style.width = "0";
1472 div.style.width = "1px";
1473 div.appendChild( marginDiv );
1474 support.reliableMarginRight =
1475 !parseFloat( ( window.getComputedStyle( marginDiv, null ) || {} ).marginRight );
1476 }
1477
1478 if ( typeof div.style.zoom !== "undefined" ) {
1479 // Check if natively block-level elements act like inline-block
1480 // elements when setting their display to 'inline' and giving
1481 // them layout
1482 // (IE < 8 does this)
1483 div.innerHTML = "";
1484 div.style.cssText = divReset + "width:1px;padding:1px;display:inline;zoom:1";
1485 support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 );
1486
1487 // Check if elements with layout shrink-wrap their children
1488 // (IE 6 does this)
1489 div.style.display = "block";
1490 div.style.overflow = "visible";
1491 div.innerHTML = "<div></div>";
1492 div.firstChild.style.width = "5px";
1493 support.shrinkWrapBlocks = ( div.offsetWidth !== 3 );
1494
1495 container.style.zoom = 1;
1496 }
1497
1498 // Null elements to avoid leaks in IE
1499 body.removeChild( container );
1500 container = div = tds = marginDiv = null;
1501 });
1502
1503 // Null elements to avoid leaks in IE
1504 fragment.removeChild( div );
1505 all = a = select = opt = input = fragment = div = null;
1506
1507 return support;
1508 })();
1509 var rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/,
1510 rmultiDash = /([A-Z])/g;
1511
1512 jQuery.extend({
1513 cache: {},
1514
1515 deletedIds: [],
1516
1517 // Remove at next major release (1.9/2.0)
1518 uuid: 0,
1519
1520 // Unique for each copy of jQuery on the page
1521 // Non-digits removed to match rinlinejQuery
1522 expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ),
1523
1524 // The following elements throw uncatchable exceptions if you
1525 // attempt to add expando properties to them.
1526 noData: {
1527 "embed": true,
1528 // Ban all objects except for Flash (which handle expandos)
1529 "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",
1530 "applet": true
1531 },
1532
1533 hasData: function( elem ) {
1534 elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];
1535 return !!elem && !isEmptyDataObject( elem );
1536 },
1537
1538 data: function( elem, name, data, pvt /* Internal Use Only */ ) {
1539 if ( !jQuery.acceptData( elem ) ) {
1540 return;
1541 }
1542
1543 var thisCache, ret,
1544 internalKey = jQuery.expando,
1545 getByName = typeof name === "string",
1546
1547 // We have to handle DOM nodes and JS objects differently because IE6-7
1548 // can't GC object references properly across the DOM-JS boundary
1549 isNode = elem.nodeType,
1550
1551 // Only DOM nodes need the global jQuery cache; JS object data is
1552 // attached directly to the object so GC can occur automatically
1553 cache = isNode ? jQuery.cache : elem,
1554
1555 // Only defining an ID for JS objects if its cache already exists allows
1556 // the code to shortcut on the same path as a DOM node with no cache
1557 id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey;
1558
1559 // Avoid doing any more work than we need to when trying to get data on an
1560 // object that has no data at all
1561 if ( (!id || !cache[id] || (!pvt && !cache[id].data)) && getByName && data === undefined ) {
1562 return;
1563 }
1564
1565 if ( !id ) {
1566 // Only DOM nodes need a new unique ID for each element since their data
1567 // ends up in the global cache
1568 if ( isNode ) {
1569 elem[ internalKey ] = id = jQuery.deletedIds.pop() || jQuery.guid++;
1570 } else {
1571 id = internalKey;
1572 }
1573 }
1574
1575 if ( !cache[ id ] ) {
1576 cache[ id ] = {};
1577
1578 // Avoids exposing jQuery metadata on plain JS objects when the object
1579 // is serialized using JSON.stringify
1580 if ( !isNode ) {
1581 cache[ id ].toJSON = jQuery.noop;
1582 }
1583 }
1584
1585 // An object can be passed to jQuery.data instead of a key/value pair; this gets
1586 // shallow copied over onto the existing cache
1587 if ( typeof name === "object" || typeof name === "function" ) {
1588 if ( pvt ) {
1589 cache[ id ] = jQuery.extend( cache[ id ], name );
1590 } else {
1591 cache[ id ].data = jQuery.extend( cache[ id ].data, name );
1592 }
1593 }
1594
1595 thisCache = cache[ id ];
1596
1597 // jQuery data() is stored in a separate object inside the object's internal data
1598 // cache in order to avoid key collisions between internal data and user-defined
1599 // data.
1600 if ( !pvt ) {
1601 if ( !thisCache.data ) {
1602 thisCache.data = {};
1603 }
1604
1605 thisCache = thisCache.data;
1606 }
1607
1608 if ( data !== undefined ) {
1609 thisCache[ jQuery.camelCase( name ) ] = data;
1610 }
1611
1612 // Check for both converted-to-camel and non-converted data property names
1613 // If a data property was specified
1614 if ( getByName ) {
1615
1616 // First Try to find as-is property data
1617 ret = thisCache[ name ];
1618
1619 // Test for null|undefined property data
1620 if ( ret == null ) {
1621
1622 // Try to find the camelCased property
1623 ret = thisCache[ jQuery.camelCase( name ) ];
1624 }
1625 } else {
1626 ret = thisCache;
1627 }
1628
1629 return ret;
1630 },
1631
1632 removeData: function( elem, name, pvt /* Internal Use Only */ ) {
1633 if ( !jQuery.acceptData( elem ) ) {
1634 return;
1635 }
1636
1637 var thisCache, i, l,
1638
1639 isNode = elem.nodeType,
1640
1641 // See jQuery.data for more information
1642 cache = isNode ? jQuery.cache : elem,
1643 id = isNode ? elem[ jQuery.expando ] : jQuery.expando;
1644
1645 // If there is already no cache entry for this object, there is no
1646 // purpose in continuing
1647 if ( !cache[ id ] ) {
1648 return;
1649 }
1650
1651 if ( name ) {
1652
1653 thisCache = pvt ? cache[ id ] : cache[ id ].data;
1654
1655 if ( thisCache ) {
1656
1657 // Support array or space separated string names for data keys
1658 if ( !jQuery.isArray( name ) ) {
1659
1660 // try the string as a key before any manipulation
1661 if ( name in thisCache ) {
1662 name = [ name ];
1663 } else {
1664
1665 // split the camel cased version by spaces unless a key with the spaces exists
1666 name = jQuery.camelCase( name );
1667 if ( name in thisCache ) {
1668 name = [ name ];
1669 } else {
1670 name = name.split(" ");
1671 }
1672 }
1673 }
1674
1675 for ( i = 0, l = name.length; i < l; i++ ) {
1676 delete thisCache[ name[i] ];
1677 }
1678
1679 // If there is no data left in the cache, we want to continue
1680 // and let the cache object itself get destroyed
1681 if ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) {
1682 return;
1683 }
1684 }
1685 }
1686
1687 // See jQuery.data for more information
1688 if ( !pvt ) {
1689 delete cache[ id ].data;
1690
1691 // Don't destroy the parent cache unless the internal data object
1692 // had been the only thing left in it
1693 if ( !isEmptyDataObject( cache[ id ] ) ) {
1694 return;
1695 }
1696 }
1697
1698 // Destroy the cache
1699 if ( isNode ) {
1700 jQuery.cleanData( [ elem ], true );
1701
1702 // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080)
1703 } else if ( jQuery.support.deleteExpando || cache != cache.window ) {
1704 delete cache[ id ];
1705
1706 // When all else fails, null
1707 } else {
1708 cache[ id ] = null;
1709 }
1710 },
1711
1712 // For internal use only.
1713 _data: function( elem, name, data ) {
1714 return jQuery.data( elem, name, data, true );
1715 },
1716
1717 // A method for determining if a DOM node can handle the data expando
1718 acceptData: function( elem ) {
1719 var noData = elem.nodeName && jQuery.noData[ elem.nodeName.toLowerCase() ];
1720
1721 // nodes accept data unless otherwise specified; rejection can be conditional
1722 return !noData || noData !== true && elem.getAttribute("classid") === noData;
1723 }
1724 });
1725
1726 jQuery.fn.extend({
1727 data: function( key, value ) {
1728 var parts, part, attr, name, l,
1729 elem = this[0],
1730 i = 0,
1731 data = null;
1732
1733 // Gets all values
1734 if ( key === undefined ) {
1735 if ( this.length ) {
1736 data = jQuery.data( elem );
1737
1738 if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) {
1739 attr = elem.attributes;
1740 for ( l = attr.length; i < l; i++ ) {
1741 name = attr[i].name;
1742
1743 if ( !name.indexOf( "data-" ) ) {
1744 name = jQuery.camelCase( name.substring(5) );
1745
1746 dataAttr( elem, name, data[ name ] );
1747 }
1748 }
1749 jQuery._data( elem, "parsedAttrs", true );
1750 }
1751 }
1752
1753 return data;
1754 }
1755
1756 // Sets multiple values
1757 if ( typeof key === "object" ) {
1758 return this.each(function() {
1759 jQuery.data( this, key );
1760 });
1761 }
1762
1763 parts = key.split( ".", 2 );
1764 parts[1] = parts[1] ? "." + parts[1] : "";
1765 part = parts[1] + "!";
1766
1767 return jQuery.access( this, function( value ) {
1768
1769 if ( value === undefined ) {
1770 data = this.triggerHandler( "getData" + part, [ parts[0] ] );
1771
1772 // Try to fetch any internally stored data first
1773 if ( data === undefined && elem ) {
1774 data = jQuery.data( elem, key );
1775 data = dataAttr( elem, key, data );
1776 }
1777
1778 return data === undefined && parts[1] ?
1779 this.data( parts[0] ) :
1780 data;
1781 }
1782
1783 parts[1] = value;
1784 this.each(function() {
1785 var self = jQuery( this );
1786
1787 self.triggerHandler( "setData" + part, parts );
1788 jQuery.data( this, key, value );
1789 self.triggerHandler( "changeData" + part, parts );
1790 });
1791 }, null, value, arguments.length > 1, null, false );
1792 },
1793
1794 removeData: function( key ) {
1795 return this.each(function() {
1796 jQuery.removeData( this, key );
1797 });
1798 }
1799 });
1800
1801 function dataAttr( elem, key, data ) {
1802 // If nothing was found internally, try to fetch any
1803 // data from the HTML5 data-* attribute
1804 if ( data === undefined && elem.nodeType === 1 ) {
1805
1806 var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase();
1807
1808 data = elem.getAttribute( name );
1809
1810 if ( typeof data === "string" ) {
1811 try {
1812 data = data === "true" ? true :
1813 data === "false" ? false :
1814 data === "null" ? null :
1815 // Only convert to a number if it doesn't change the string
1816 +data + "" === data ? +data :
1817 rbrace.test( data ) ? jQuery.parseJSON( data ) :
1818 data;
1819 } catch( e ) {}
1820
1821 // Make sure we set the data so it isn't changed later
1822 jQuery.data( elem, key, data );
1823
1824 } else {
1825 data = undefined;
1826 }
1827 }
1828
1829 return data;
1830 }
1831
1832 // checks a cache object for emptiness
1833 function isEmptyDataObject( obj ) {
1834 var name;
1835 for ( name in obj ) {
1836
1837 // if the public data object is empty, the private is still empty
1838 if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) {
1839 continue;
1840 }
1841 if ( name !== "toJSON" ) {
1842 return false;
1843 }
1844 }
1845
1846 return true;
1847 }
1848 jQuery.extend({
1849 queue: function( elem, type, data ) {
1850 var queue;
1851
1852 if ( elem ) {
1853 type = ( type || "fx" ) + "queue";
1854 queue = jQuery._data( elem, type );
1855
1856 // Speed up dequeue by getting out quickly if this is just a lookup
1857 if ( data ) {
1858 if ( !queue || jQuery.isArray(data) ) {
1859 queue = jQuery._data( elem, type, jQuery.makeArray(data) );
1860 } else {
1861 queue.push( data );
1862 }
1863 }
1864 return queue || [];
1865 }
1866 },
1867
1868 dequeue: function( elem, type ) {
1869 type = type || "fx";
1870
1871 var queue = jQuery.queue( elem, type ),
1872 startLength = queue.length,
1873 fn = queue.shift(),
1874 hooks = jQuery._queueHooks( elem, type ),
1875 next = function() {
1876 jQuery.dequeue( elem, type );
1877 };
1878
1879 // If the fx queue is dequeued, always remove the progress sentinel
1880 if ( fn === "inprogress" ) {
1881 fn = queue.shift();
1882 startLength--;
1883 }
1884
1885 if ( fn ) {
1886
1887 // Add a progress sentinel to prevent the fx queue from being
1888 // automatically dequeued
1889 if ( type === "fx" ) {
1890 queue.unshift( "inprogress" );
1891 }
1892
1893 // clear up the last queue stop function
1894 delete hooks.stop;
1895 fn.call( elem, next, hooks );
1896 }
1897
1898 if ( !startLength && hooks ) {
1899 hooks.empty.fire();
1900 }
1901 },
1902
1903 // not intended for public consumption - generates a queueHooks object, or returns the current one
1904 _queueHooks: function( elem, type ) {
1905 var key = type + "queueHooks";
1906 return jQuery._data( elem, key ) || jQuery._data( elem, key, {
1907 empty: jQuery.Callbacks("once memory").add(function() {
1908 jQuery.removeData( elem, type + "queue", true );
1909 jQuery.removeData( elem, key, true );
1910 })
1911 });
1912 }
1913 });
1914
1915 jQuery.fn.extend({
1916 queue: function( type, data ) {
1917 var setter = 2;
1918
1919 if ( typeof type !== "string" ) {
1920 data = type;
1921 type = "fx";
1922 setter--;
1923 }
1924
1925 if ( arguments.length < setter ) {
1926 return jQuery.queue( this[0], type );
1927 }
1928
1929 return data === undefined ?
1930 this :
1931 this.each(function() {
1932 var queue = jQuery.queue( this, type, data );
1933
1934 // ensure a hooks for this queue
1935 jQuery._queueHooks( this, type );
1936
1937 if ( type === "fx" && queue[0] !== "inprogress" ) {
1938 jQuery.dequeue( this, type );
1939 }
1940 });
1941 },
1942 dequeue: function( type ) {
1943 return this.each(function() {
1944 jQuery.dequeue( this, type );
1945 });
1946 },
1947 // Based off of the plugin by Clint Helfers, with permission.
1948 // http://blindsignals.com/index.php/2009/07/jquery-delay/
1949 delay: function( time, type ) {
1950 time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
1951 type = type || "fx";
1952
1953 return this.queue( type, function( next, hooks ) {
1954 var timeout = setTimeout( next, time );
1955 hooks.stop = function() {
1956 clearTimeout( timeout );
1957 };
1958 });
1959 },
1960 clearQueue: function( type ) {
1961 return this.queue( type || "fx", [] );
1962 },
1963 // Get a promise resolved when queues of a certain type
1964 // are emptied (fx is the type by default)
1965 promise: function( type, obj ) {
1966 var tmp,
1967 count = 1,
1968 defer = jQuery.Deferred(),
1969 elements = this,
1970 i = this.length,
1971 resolve = function() {
1972 if ( !( --count ) ) {
1973 defer.resolveWith( elements, [ elements ] );
1974 }
1975 };
1976
1977 if ( typeof type !== "string" ) {
1978 obj = type;
1979 type = undefined;
1980 }
1981 type = type || "fx";
1982
1983 while( i-- ) {
1984 tmp = jQuery._data( elements[ i ], type + "queueHooks" );
1985 if ( tmp && tmp.empty ) {
1986 count++;
1987 tmp.empty.add( resolve );
1988 }
1989 }
1990 resolve();
1991 return defer.promise( obj );
1992 }
1993 });
1994 var nodeHook, boolHook, fixSpecified,
1995 rclass = /[\t\r\n]/g,
1996 rreturn = /\r/g,
1997 rtype = /^(?:button|input)$/i,
1998 rfocusable = /^(?:button|input|object|select|textarea)$/i,
1999 rclickable = /^a(?:rea|)$/i,
2000 rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,
2001 getSetAttribute = jQuery.support.getSetAttribute;
2002
2003 jQuery.fn.extend({
2004 attr: function( name, value ) {
2005 return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 );
2006 },
2007
2008 removeAttr: function( name ) {
2009 return this.each(function() {
2010 jQuery.removeAttr( this, name );
2011 });
2012 },
2013
2014 prop: function( name, value ) {
2015 return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 );
2016 },
2017
2018 removeProp: function( name ) {
2019 name = jQuery.propFix[ name ] || name;
2020 return this.each(function() {
2021 // try/catch handles cases where IE balks (such as removing a property on window)
2022 try {
2023 this[ name ] = undefined;
2024 delete this[ name ];
2025 } catch( e ) {}
2026 });
2027 },
2028
2029 addClass: function( value ) {
2030 var classNames, i, l, elem,
2031 setClass, c, cl;
2032
2033 if ( jQuery.isFunction( value ) ) {
2034 return this.each(function( j ) {
2035 jQuery( this ).addClass( value.call(this, j, this.className) );
2036 });
2037 }
2038
2039 if ( value && typeof value === "string" ) {
2040 classNames = value.split( core_rspace );
2041
2042 for ( i = 0, l = this.length; i < l; i++ ) {
2043 elem = this[ i ];
2044
2045 if ( elem.nodeType === 1 ) {
2046 if ( !elem.className && classNames.length === 1 ) {
2047 elem.className = value;
2048
2049 } else {
2050 setClass = " " + elem.className + " ";
2051
2052 for ( c = 0, cl = classNames.length; c < cl; c++ ) {
2053 if ( setClass.indexOf( " " + classNames[ c ] + " " ) < 0 ) {
2054 setClass += classNames[ c ] + " ";
2055 }
2056 }
2057 elem.className = jQuery.trim( setClass );
2058 }
2059 }
2060 }
2061 }
2062
2063 return this;
2064 },
2065
2066 removeClass: function( value ) {
2067 var removes, className, elem, c, cl, i, l;
2068
2069 if ( jQuery.isFunction( value ) ) {
2070 return this.each(function( j ) {
2071 jQuery( this ).removeClass( value.call(this, j, this.className) );
2072 });
2073 }
2074 if ( (value && typeof value === "string") || value === undefined ) {
2075 removes = ( value || "" ).split( core_rspace );
2076
2077 for ( i = 0, l = this.length; i < l; i++ ) {
2078 elem = this[ i ];
2079 if ( elem.nodeType === 1 && elem.className ) {
2080
2081 className = (" " + elem.className + " ").replace( rclass, " " );
2082
2083 // loop over each item in the removal list
2084 for ( c = 0, cl = removes.length; c < cl; c++ ) {
2085 // Remove until there is nothing to remove,
2086 while ( className.indexOf(" " + removes[ c ] + " ") >= 0 ) {
2087 className = className.replace( " " + removes[ c ] + " " , " " );
2088 }
2089 }
2090 elem.className = value ? jQuery.trim( className ) : "";
2091 }
2092 }
2093 }
2094
2095 return this;
2096 },
2097
2098 toggleClass: function( value, stateVal ) {
2099 var type = typeof value,
2100 isBool = typeof stateVal === "boolean";
2101
2102 if ( jQuery.isFunction( value ) ) {
2103 return this.each(function( i ) {
2104 jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );
2105 });
2106 }
2107
2108 return this.each(function() {
2109 if ( type === "string" ) {
2110 // toggle individual class names
2111 var className,
2112 i = 0,
2113 self = jQuery( this ),
2114 state = stateVal,
2115 classNames = value.split( core_rspace );
2116
2117 while ( (className = classNames[ i++ ]) ) {
2118 // check each className given, space separated list
2119 state = isBool ? state : !self.hasClass( className );
2120 self[ state ? "addClass" : "removeClass" ]( className );
2121 }
2122
2123 } else if ( type === "undefined" || type === "boolean" ) {
2124 if ( this.className ) {
2125 // store className if set
2126 jQuery._data( this, "__className__", this.className );
2127 }
2128
2129 // toggle whole className
2130 this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || "";
2131 }
2132 });
2133 },
2134
2135 hasClass: function( selector ) {
2136 var className = " " + selector + " ",
2137 i = 0,
2138 l = this.length;
2139 for ( ; i < l; i++ ) {
2140 if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) {
2141 return true;
2142 }
2143 }
2144
2145 return false;
2146 },
2147
2148 val: function( value ) {
2149 var hooks, ret, isFunction,
2150 elem = this[0];
2151
2152 if ( !arguments.length ) {
2153 if ( elem ) {
2154 hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];
2155
2156 if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
2157 return ret;
2158 }
2159
2160 ret = elem.value;
2161
2162 return typeof ret === "string" ?
2163 // handle most common string cases
2164 ret.replace(rreturn, "") :
2165 // handle cases where value is null/undef or number
2166 ret == null ? "" : ret;
2167 }
2168
2169 return;
2170 }
2171
2172 isFunction = jQuery.isFunction( value );
2173
2174 return this.each(function( i ) {
2175 var val,
2176 self = jQuery(this);
2177
2178 if ( this.nodeType !== 1 ) {
2179 return;
2180 }
2181
2182 if ( isFunction ) {
2183 val = value.call( this, i, self.val() );
2184 } else {
2185 val = value;
2186 }
2187
2188 // Treat null/undefined as ""; convert numbers to string
2189 if ( val == null ) {
2190 val = "";
2191 } else if ( typeof val === "number" ) {
2192 val += "";
2193 } else if ( jQuery.isArray( val ) ) {
2194 val = jQuery.map(val, function ( value ) {
2195 return value == null ? "" : value + "";
2196 });
2197 }
2198
2199 hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
2200
2201 // If set returns undefined, fall back to normal setting
2202 if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
2203 this.value = val;
2204 }
2205 });
2206 }
2207 });
2208
2209 jQuery.extend({
2210 valHooks: {
2211 option: {
2212 get: function( elem ) {
2213 // attributes.value is undefined in Blackberry 4.7 but
2214 // uses .value. See #6932
2215 var val = elem.attributes.value;
2216 return !val || val.specified ? elem.value : elem.text;
2217 }
2218 },
2219 select: {
2220 get: function( elem ) {
2221 var value, option,
2222 options = elem.options,
2223 index = elem.selectedIndex,
2224 one = elem.type === "select-one" || index < 0,
2225 values = one ? null : [],
2226 max = one ? index + 1 : options.length,
2227 i = index < 0 ?
2228 max :
2229 one ? index : 0;
2230
2231 // Loop through all the selected options
2232 for ( ; i < max; i++ ) {
2233 option = options[ i ];
2234
2235 // oldIE doesn't update selected after form reset (#2551)
2236 if ( ( option.selected || i === index ) &&
2237 // Don't return options that are disabled or in a disabled optgroup
2238 ( jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null ) &&
2239 ( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) {
2240
2241 // Get the specific value for the option
2242 value = jQuery( option ).val();
2243
2244 // We don't need an array for one selects
2245 if ( one ) {
2246 return value;
2247 }
2248
2249 // Multi-Selects return an array
2250 values.push( value );
2251 }
2252 }
2253
2254 return values;
2255 },
2256
2257 set: function( elem, value ) {
2258 var values = jQuery.makeArray( value );
2259
2260 jQuery(elem).find("option").each(function() {
2261 this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
2262 });
2263
2264 if ( !values.length ) {
2265 elem.selectedIndex = -1;
2266 }
2267 return values;
2268 }
2269 }
2270 },
2271
2272 // Unused in 1.8, left in so attrFn-stabbers won't die; remove in 1.9
2273 attrFn: {},
2274
2275 attr: function( elem, name, value, pass ) {
2276 var ret, hooks, notxml,
2277 nType = elem.nodeType;
2278
2279 // don't get/set attributes on text, comment and attribute nodes
2280 if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
2281 return;
2282 }
2283
2284 if ( pass && jQuery.isFunction( jQuery.fn[ name ] ) ) {
2285 return jQuery( elem )[ name ]( value );
2286 }
2287
2288 // Fallback to prop when attributes are not supported
2289 if ( typeof elem.getAttribute === "undefined" ) {
2290 return jQuery.prop( elem, name, value );
2291 }
2292
2293 notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
2294
2295 // All attributes are lowercase
2296 // Grab necessary hook if one is defined
2297 if ( notxml ) {
2298 name = name.toLowerCase();
2299 hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook );
2300 }
2301
2302 if ( value !== undefined ) {
2303
2304 if ( value === null ) {
2305 jQuery.removeAttr( elem, name );
2306 return;
2307
2308 } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) {
2309 return ret;
2310
2311 } else {
2312 elem.setAttribute( name, value + "" );
2313 return value;
2314 }
2315
2316 } else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) {
2317 return ret;
2318
2319 } else {
2320
2321 ret = elem.getAttribute( name );
2322
2323 // Non-existent attributes return null, we normalize to undefined
2324 return ret === null ?
2325 undefined :
2326 ret;
2327 }
2328 },
2329
2330 removeAttr: function( elem, value ) {
2331 var propName, attrNames, name, isBool,
2332 i = 0;
2333
2334 if ( value && elem.nodeType === 1 ) {
2335
2336 attrNames = value.split( core_rspace );
2337
2338 for ( ; i < attrNames.length; i++ ) {
2339 name = attrNames[ i ];
2340
2341 if ( name ) {
2342 propName = jQuery.propFix[ name ] || name;
2343 isBool = rboolean.test( name );
2344
2345 // See #9699 for explanation of this approach (setting first, then removal)
2346 // Do not do this for boolean attributes (see #10870)
2347 if ( !isBool ) {
2348 jQuery.attr( elem, name, "" );
2349 }
2350 elem.removeAttribute( getSetAttribute ? name : propName );
2351
2352 // Set corresponding property to false for boolean attributes
2353 if ( isBool && propName in elem ) {
2354 elem[ propName ] = false;
2355 }
2356 }
2357 }
2358 }
2359 },
2360
2361 attrHooks: {
2362 type: {
2363 set: function( elem, value ) {
2364 // We can't allow the type property to be changed (since it causes problems in IE)
2365 if ( rtype.test( elem.nodeName ) && elem.parentNode ) {
2366 jQuery.error( "type property can't be changed" );
2367 } else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) {
2368 // Setting the type on a radio button after the value resets the value in IE6-9
2369 // Reset value to it's default in case type is set after value
2370 // This is for element creation
2371 var val = elem.value;
2372 elem.setAttribute( "type", value );
2373 if ( val ) {
2374 elem.value = val;
2375 }
2376 return value;
2377 }
2378 }
2379 },
2380 // Use the value property for back compat
2381 // Use the nodeHook for button elements in IE6/7 (#1954)
2382 value: {
2383 get: function( elem, name ) {
2384 if ( nodeHook && jQuery.nodeName( elem, "button" ) ) {
2385 return nodeHook.get( elem, name );
2386 }
2387 return name in elem ?
2388 elem.value :
2389 null;
2390 },
2391 set: function( elem, value, name ) {
2392 if ( nodeHook && jQuery.nodeName( elem, "button" ) ) {
2393 return nodeHook.set( elem, value, name );
2394 }
2395 // Does not return so that setAttribute is also used
2396 elem.value = value;
2397 }
2398 }
2399 },
2400
2401 propFix: {
2402 tabindex: "tabIndex",
2403 readonly: "readOnly",
2404 "for": "htmlFor",
2405 "class": "className",
2406 maxlength: "maxLength",
2407 cellspacing: "cellSpacing",
2408 cellpadding: "cellPadding",
2409 rowspan: "rowSpan",
2410 colspan: "colSpan",
2411 usemap: "useMap",
2412 frameborder: "frameBorder",
2413 contenteditable: "contentEditable"
2414 },
2415
2416 prop: function( elem, name, value ) {
2417 var ret, hooks, notxml,
2418 nType = elem.nodeType;
2419
2420 // don't get/set properties on text, comment and attribute nodes
2421 if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
2422 return;
2423 }
2424
2425 notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
2426
2427 if ( notxml ) {
2428 // Fix name and attach hooks
2429 name = jQuery.propFix[ name ] || name;
2430 hooks = jQuery.propHooks[ name ];
2431 }
2432
2433 if ( value !== undefined ) {
2434 if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
2435 return ret;
2436
2437 } else {
2438 return ( elem[ name ] = value );
2439 }
2440
2441 } else {
2442 if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
2443 return ret;
2444
2445 } else {
2446 return elem[ name ];
2447 }
2448 }
2449 },
2450
2451 propHooks: {
2452 tabIndex: {
2453 get: function( elem ) {
2454 // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
2455 // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
2456 var attributeNode = elem.getAttributeNode("tabindex");
2457
2458 return attributeNode && attributeNode.specified ?
2459 parseInt( attributeNode.value, 10 ) :
2460 rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
2461 0 :
2462 undefined;
2463 }
2464 }
2465 }
2466 });
2467
2468 // Hook for boolean attributes
2469 boolHook = {
2470 get: function( elem, name ) {
2471 // Align boolean attributes with corresponding properties
2472 // Fall back to attribute presence where some booleans are not supported
2473 var attrNode,
2474 property = jQuery.prop( elem, name );
2475 return property === true || typeof property !== "boolean" && ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ?
2476 name.toLowerCase() :
2477 undefined;
2478 },
2479 set: function( elem, value, name ) {
2480 var propName;
2481 if ( value === false ) {
2482 // Remove boolean attributes when set to false
2483 jQuery.removeAttr( elem, name );
2484 } else {
2485 // value is true since we know at this point it's type boolean and not false
2486 // Set boolean attributes to the same name and set the DOM property
2487 propName = jQuery.propFix[ name ] || name;
2488 if ( propName in elem ) {
2489 // Only set the IDL specifically if it already exists on the element
2490 elem[ propName ] = true;
2491 }
2492
2493 elem.setAttribute( name, name.toLowerCase() );
2494 }
2495 return name;
2496 }
2497 };
2498
2499 // IE6/7 do not support getting/setting some attributes with get/setAttribute
2500 if ( !getSetAttribute ) {
2501
2502 fixSpecified = {
2503 name: true,
2504 id: true,
2505 coords: true
2506 };
2507
2508 // Use this for any attribute in IE6/7
2509 // This fixes almost every IE6/7 issue
2510 nodeHook = jQuery.valHooks.button = {
2511 get: function( elem, name ) {
2512 var ret;
2513 ret = elem.getAttributeNode( name );
2514 return ret && ( fixSpecified[ name ] ? ret.value !== "" : ret.specified ) ?
2515 ret.value :
2516 undefined;
2517 },
2518 set: function( elem, value, name ) {
2519 // Set the existing or create a new attribute node
2520 var ret = elem.getAttributeNode( name );
2521 if ( !ret ) {
2522 ret = document.createAttribute( name );
2523 elem.setAttributeNode( ret );
2524 }
2525 return ( ret.value = value + "" );
2526 }
2527 };
2528
2529 // Set width and height to auto instead of 0 on empty string( Bug #8150 )
2530 // This is for removals
2531 jQuery.each([ "width", "height" ], function( i, name ) {
2532 jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
2533 set: function( elem, value ) {
2534 if ( value === "" ) {
2535 elem.setAttribute( name, "auto" );
2536 return value;
2537 }
2538 }
2539 });
2540 });
2541
2542 // Set contenteditable to false on removals(#10429)
2543 // Setting to empty string throws an error as an invalid value
2544 jQuery.attrHooks.contenteditable = {
2545 get: nodeHook.get,
2546 set: function( elem, value, name ) {
2547 if ( value === "" ) {
2548 value = "false";
2549 }
2550 nodeHook.set( elem, value, name );
2551 }
2552 };
2553 }
2554
2555
2556 // Some attributes require a special call on IE
2557 if ( !jQuery.support.hrefNormalized ) {
2558 jQuery.each([ "href", "src", "width", "height" ], function( i, name ) {
2559 jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
2560 get: function( elem ) {
2561 var ret = elem.getAttribute( name, 2 );
2562 return ret === null ? undefined : ret;
2563 }
2564 });
2565 });
2566 }
2567
2568 if ( !jQuery.support.style ) {
2569 jQuery.attrHooks.style = {
2570 get: function( elem ) {
2571 // Return undefined in the case of empty string
2572 // Normalize to lowercase since IE uppercases css property names
2573 return elem.style.cssText.toLowerCase() || undefined;
2574 },
2575 set: function( elem, value ) {
2576 return ( elem.style.cssText = value + "" );
2577 }
2578 };
2579 }
2580
2581 // Safari mis-reports the default selected property of an option
2582 // Accessing the parent's selectedIndex property fixes it
2583 if ( !jQuery.support.optSelected ) {
2584 jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, {
2585 get: function( elem ) {
2586 var parent = elem.parentNode;
2587
2588 if ( parent ) {
2589 parent.selectedIndex;
2590
2591 // Make sure that it also works with optgroups, see #5701
2592 if ( parent.parentNode ) {
2593 parent.parentNode.selectedIndex;
2594 }
2595 }
2596 return null;
2597 }
2598 });
2599 }
2600
2601 // IE6/7 call enctype encoding
2602 if ( !jQuery.support.enctype ) {
2603 jQuery.propFix.enctype = "encoding";
2604 }
2605
2606 // Radios and checkboxes getter/setter
2607 if ( !jQuery.support.checkOn ) {
2608 jQuery.each([ "radio", "checkbox" ], function() {
2609 jQuery.valHooks[ this ] = {
2610 get: function( elem ) {
2611 // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
2612 return elem.getAttribute("value") === null ? "on" : elem.value;
2613 }
2614 };
2615 });
2616 }
2617 jQuery.each([ "radio", "checkbox" ], function() {
2618 jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], {
2619 set: function( elem, value ) {
2620 if ( jQuery.isArray( value ) ) {
2621 return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );
2622 }
2623 }
2624 });
2625 });
2626 var rformElems = /^(?:textarea|input|select)$/i,
2627 rtypenamespace = /^([^\.]*|)(?:\.(.+)|)$/,
2628 rhoverHack = /(?:^|\s)hover(\.\S+|)\b/,
2629 rkeyEvent = /^key/,
2630 rmouseEvent = /^(?:mouse|contextmenu)|click/,
2631 rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
2632 hoverHack = function( events ) {
2633 return jQuery.event.special.hover ? events : events.replace( rhoverHack, "mouseenter$1 mouseleave$1" );
2634 };
2635
2636 /*
2637 * Helper functions for managing events -- not part of the public interface.
2638 * Props to Dean Edwards' addEvent library for many of the ideas.
2639 */
2640 jQuery.event = {
2641
2642 add: function( elem, types, handler, data, selector ) {
2643
2644 var elemData, eventHandle, events,
2645 t, tns, type, namespaces, handleObj,
2646 handleObjIn, handlers, special;
2647
2648 // Don't attach events to noData or text/comment nodes (allow plain objects tho)
2649 if ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = jQuery._data( elem )) ) {
2650 return;
2651 }
2652
2653 // Caller can pass in an object of custom data in lieu of the handler
2654 if ( handler.handler ) {
2655 handleObjIn = handler;
2656 handler = handleObjIn.handler;
2657 selector = handleObjIn.selector;
2658 }
2659
2660 // Make sure that the handler has a unique ID, used to find/remove it later
2661 if ( !handler.guid ) {
2662 handler.guid = jQuery.guid++;
2663 }
2664
2665 // Init the element's event structure and main handler, if this is the first
2666 events = elemData.events;
2667 if ( !events ) {
2668 elemData.events = events = {};
2669 }
2670 eventHandle = elemData.handle;
2671 if ( !eventHandle ) {
2672 elemData.handle = eventHandle = function( e ) {
2673 // Discard the second event of a jQuery.event.trigger() and
2674 // when an event is called after a page has unloaded
2675 return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ?
2676 jQuery.event.dispatch.apply( eventHandle.elem, arguments ) :
2677 undefined;
2678 };
2679 // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events
2680 eventHandle.elem = elem;
2681 }
2682
2683 // Handle multiple events separated by a space
2684 // jQuery(...).bind("mouseover mouseout", fn);
2685 types = jQuery.trim( hoverHack(types) ).split( " " );
2686 for ( t = 0; t < types.length; t++ ) {
2687
2688 tns = rtypenamespace.exec( types[t] ) || [];
2689 type = tns[1];
2690 namespaces = ( tns[2] || "" ).split( "." ).sort();
2691
2692 // If event changes its type, use the special event handlers for the changed type
2693 special = jQuery.event.special[ type ] || {};
2694
2695 // If selector defined, determine special event api type, otherwise given type
2696 type = ( selector ? special.delegateType : special.bindType ) || type;
2697
2698 // Update special based on newly reset type
2699 special = jQuery.event.special[ type ] || {};
2700
2701 // handleObj is passed to all event handlers
2702 handleObj = jQuery.extend({
2703 type: type,
2704 origType: tns[1],
2705 data: data,
2706 handler: handler,
2707 guid: handler.guid,
2708 selector: selector,
2709 needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
2710 namespace: namespaces.join(".")
2711 }, handleObjIn );
2712
2713 // Init the event handler queue if we're the first
2714 handlers = events[ type ];
2715 if ( !handlers ) {
2716 handlers = events[ type ] = [];
2717 handlers.delegateCount = 0;
2718
2719 // Only use addEventListener/attachEvent if the special events handler returns false
2720 if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
2721 // Bind the global event handler to the element
2722 if ( elem.addEventListener ) {
2723 elem.addEventListener( type, eventHandle, false );
2724
2725 } else if ( elem.attachEvent ) {
2726 elem.attachEvent( "on" + type, eventHandle );
2727 }
2728 }
2729 }
2730
2731 if ( special.add ) {
2732 special.add.call( elem, handleObj );
2733
2734 if ( !handleObj.handler.guid ) {
2735 handleObj.handler.guid = handler.guid;
2736 }
2737 }
2738
2739 // Add to the element's handler list, delegates in front
2740 if ( selector ) {
2741 handlers.splice( handlers.delegateCount++, 0, handleObj );
2742 } else {
2743 handlers.push( handleObj );
2744 }
2745
2746 // Keep track of which events have ever been used, for event optimization
2747 jQuery.event.global[ type ] = true;
2748 }
2749
2750 // Nullify elem to prevent memory leaks in IE
2751 elem = null;
2752 },
2753
2754 global: {},
2755
2756 // Detach an event or set of events from an element
2757 remove: function( elem, types, handler, selector, mappedTypes ) {
2758
2759 var t, tns, type, origType, namespaces, origCount,
2760 j, events, special, eventType, handleObj,
2761 elemData = jQuery.hasData( elem ) && jQuery._data( elem );
2762
2763 if ( !elemData || !(events = elemData.events) ) {
2764 return;
2765 }
2766
2767 // Once for each type.namespace in types; type may be omitted
2768 types = jQuery.trim( hoverHack( types || "" ) ).split(" ");
2769 for ( t = 0; t < types.length; t++ ) {
2770 tns = rtypenamespace.exec( types[t] ) || [];
2771 type = origType = tns[1];
2772 namespaces = tns[2];
2773
2774 // Unbind all events (on this namespace, if provided) for the element
2775 if ( !type ) {
2776 for ( type in events ) {
2777 jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
2778 }
2779 continue;
2780 }
2781
2782 special = jQuery.event.special[ type ] || {};
2783 type = ( selector? special.delegateType : special.bindType ) || type;
2784 eventType = events[ type ] || [];
2785 origCount = eventType.length;
2786 namespaces = namespaces ? new RegExp("(^|\\.)" + namespaces.split(".").sort().join("\\.(?:.*\\.|)") + "(\\.|$)") : null;
2787
2788 // Remove matching events
2789 for ( j = 0; j < eventType.length; j++ ) {
2790 handleObj = eventType[ j ];
2791
2792 if ( ( mappedTypes || origType === handleObj.origType ) &&
2793 ( !handler || handler.guid === handleObj.guid ) &&
2794 ( !namespaces || namespaces.test( handleObj.namespace ) ) &&
2795 ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) {
2796 eventType.splice( j--, 1 );
2797
2798 if ( handleObj.selector ) {
2799 eventType.delegateCount--;
2800 }
2801 if ( special.remove ) {
2802 special.remove.call( elem, handleObj );
2803 }
2804 }
2805 }
2806
2807 // Remove generic event handler if we removed something and no more handlers exist
2808 // (avoids potential for endless recursion during removal of special event handlers)
2809 if ( eventType.length === 0 && origCount !== eventType.length ) {
2810 if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
2811 jQuery.removeEvent( elem, type, elemData.handle );
2812 }
2813
2814 delete events[ type ];
2815 }
2816 }
2817
2818 // Remove the expando if it's no longer used
2819 if ( jQuery.isEmptyObject( events ) ) {
2820 delete elemData.handle;
2821
2822 // removeData also checks for emptiness and clears the expando if empty
2823 // so use it instead of delete
2824 jQuery.removeData( elem, "events", true );
2825 }
2826 },
2827
2828 // Events that are safe to short-circuit if no handlers are attached.
2829 // Native DOM events should not be added, they may have inline handlers.
2830 customEvent: {
2831 "getData": true,
2832 "setData": true,
2833 "changeData": true
2834 },
2835
2836 trigger: function( event, data, elem, onlyHandlers ) {
2837 // Don't do events on text and comment nodes
2838 if ( elem && (elem.nodeType === 3 || elem.nodeType === 8) ) {
2839 return;
2840 }
2841
2842 // Event object or event type
2843 var cache, exclusive, i, cur, old, ontype, special, handle, eventPath, bubbleType,
2844 type = event.type || event,
2845 namespaces = [];
2846
2847 // focus/blur morphs to focusin/out; ensure we're not firing them right now
2848 if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
2849 return;
2850 }
2851
2852 if ( type.indexOf( "!" ) >= 0 ) {
2853 // Exclusive events trigger only for the exact event (no namespaces)
2854 type = type.slice(0, -1);
2855 exclusive = true;
2856 }
2857
2858 if ( type.indexOf( "." ) >= 0 ) {
2859 // Namespaced trigger; create a regexp to match event type in handle()
2860 namespaces = type.split(".");
2861 type = namespaces.shift();
2862 namespaces.sort();
2863 }
2864
2865 if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) {
2866 // No jQuery handlers for this event type, and it can't have inline handlers
2867 return;
2868 }
2869
2870 // Caller can pass in an Event, Object, or just an event type string
2871 event = typeof event === "object" ?
2872 // jQuery.Event object
2873 event[ jQuery.expando ] ? event :
2874 // Object literal
2875 new jQuery.Event( type, event ) :
2876 // Just the event type (string)
2877 new jQuery.Event( type );
2878
2879 event.type = type;
2880 event.isTrigger = true;
2881 event.exclusive = exclusive;
2882 event.namespace = namespaces.join( "." );
2883 event.namespace_re = event.namespace? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)") : null;
2884 ontype = type.indexOf( ":" ) < 0 ? "on" + type : "";
2885
2886 // Handle a global trigger
2887 if ( !elem ) {
2888
2889 // TODO: Stop taunting the data cache; remove global events and always attach to document
2890 cache = jQuery.cache;
2891 for ( i in cache ) {
2892 if ( cache[ i ].events && cache[ i ].events[ type ] ) {
2893 jQuery.event.trigger( event, data, cache[ i ].handle.elem, true );
2894 }
2895 }
2896 return;
2897 }
2898
2899 // Clean up the event in case it is being reused
2900 event.result = undefined;
2901 if ( !event.target ) {
2902 event.target = elem;
2903 }
2904
2905 // Clone any incoming data and prepend the event, creating the handler arg list
2906 data = data != null ? jQuery.makeArray( data ) : [];
2907 data.unshift( event );
2908
2909 // Allow special events to draw outside the lines
2910 special = jQuery.event.special[ type ] || {};
2911 if ( special.trigger && special.trigger.apply( elem, data ) === false ) {
2912 return;
2913 }
2914
2915 // Determine event propagation path in advance, per W3C events spec (#9951)
2916 // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
2917 eventPath = [[ elem, special.bindType || type ]];
2918 if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
2919
2920 bubbleType = special.delegateType || type;
2921 cur = rfocusMorph.test( bubbleType + type ) ? elem : elem.parentNode;
2922 for ( old = elem; cur; cur = cur.parentNode ) {
2923 eventPath.push([ cur, bubbleType ]);
2924 old = cur;
2925 }
2926
2927 // Only add window if we got to document (e.g., not plain obj or detached DOM)
2928 if ( old === (elem.ownerDocument || document) ) {
2929 eventPath.push([ old.defaultView || old.parentWindow || window, bubbleType ]);
2930 }
2931 }
2932
2933 // Fire handlers on the event path
2934 for ( i = 0; i < eventPath.length && !event.isPropagationStopped(); i++ ) {
2935
2936 cur = eventPath[i][0];
2937 event.type = eventPath[i][1];
2938
2939 handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" );
2940 if ( handle ) {
2941 handle.apply( cur, data );
2942 }
2943 // Note that this is a bare JS function and not a jQuery handler
2944 handle = ontype && cur[ ontype ];
2945 if ( handle && jQuery.acceptData( cur ) && handle.apply && handle.apply( cur, data ) === false ) {
2946 event.preventDefault();
2947 }
2948 }
2949 event.type = type;
2950
2951 // If nobody prevented the default action, do it now
2952 if ( !onlyHandlers && !event.isDefaultPrevented() ) {
2953
2954 if ( (!special._default || special._default.apply( elem.ownerDocument, data ) === false) &&
2955 !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) {
2956
2957 // Call a native DOM method on the target with the same name name as the event.
2958 // Can't use an .isFunction() check here because IE6/7 fails that test.
2959 // Don't do default actions on window, that's where global variables be (#6170)
2960 // IE<9 dies on focus/blur to hidden element (#1486)
2961 if ( ontype && elem[ type ] && ((type !== "focus" && type !== "blur") || event.target.offsetWidth !== 0) && !jQuery.isWindow( elem ) ) {
2962
2963 // Don't re-trigger an onFOO event when we call its FOO() method
2964 old = elem[ ontype ];
2965
2966 if ( old ) {
2967 elem[ ontype ] = null;
2968 }
2969
2970 // Prevent re-triggering of the same event, since we already bubbled it above
2971 jQuery.event.triggered = type;
2972 elem[ type ]();
2973 jQuery.event.triggered = undefined;
2974
2975 if ( old ) {
2976 elem[ ontype ] = old;
2977 }
2978 }
2979 }
2980 }
2981
2982 return event.result;
2983 },
2984
2985 dispatch: function( event ) {
2986
2987 // Make a writable jQuery.Event from the native event object
2988 event = jQuery.event.fix( event || window.event );
2989
2990 var i, j, cur, ret, selMatch, matched, matches, handleObj, sel, related,
2991 handlers = ( (jQuery._data( this, "events" ) || {} )[ event.type ] || []),
2992 delegateCount = handlers.delegateCount,
2993 args = core_slice.call( arguments ),
2994 run_all = !event.exclusive && !event.namespace,
2995 special = jQuery.event.special[ event.type ] || {},
2996 handlerQueue = [];
2997
2998 // Use the fix-ed jQuery.Event rather than the (read-only) native event
2999 args[0] = event;
3000 event.delegateTarget = this;
3001
3002 // Call the preDispatch hook for the mapped type, and let it bail if desired
3003 if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
3004 return;
3005 }
3006
3007 // Determine handlers that should run if there are delegated events
3008 // Avoid non-left-click bubbling in Firefox (#3861)
3009 if ( delegateCount && !(event.button && event.type === "click") ) {
3010
3011 for ( cur = event.target; cur != this; cur = cur.parentNode || this ) {
3012
3013 // Don't process clicks (ONLY) on disabled elements (#6911, #8165, #11382, #11764)
3014 if ( cur.disabled !== true || event.type !== "click" ) {
3015 selMatch = {};
3016 matches = [];
3017 for ( i = 0; i < delegateCount; i++ ) {
3018 handleObj = handlers[ i ];
3019 sel = handleObj.selector;
3020
3021 if ( selMatch[ sel ] === undefined ) {
3022 selMatch[ sel ] = handleObj.needsContext ?
3023 jQuery( sel, this ).index( cur ) >= 0 :
3024 jQuery.find( sel, this, null, [ cur ] ).length;
3025 }
3026 if ( selMatch[ sel ] ) {
3027 matches.push( handleObj );
3028 }
3029 }
3030 if ( matches.length ) {
3031 handlerQueue.push({ elem: cur, matches: matches });
3032 }
3033 }
3034 }
3035 }
3036
3037 // Add the remaining (directly-bound) handlers
3038 if ( handlers.length > delegateCount ) {
3039 handlerQueue.push({ elem: this, matches: handlers.slice( delegateCount ) });
3040 }
3041
3042 // Run delegates first; they may want to stop propagation beneath us
3043 for ( i = 0; i < handlerQueue.length && !event.isPropagationStopped(); i++ ) {
3044 matched = handlerQueue[ i ];
3045 event.currentTarget = matched.elem;
3046
3047 for ( j = 0; j < matched.matches.length && !event.isImmediatePropagationStopped(); j++ ) {
3048 handleObj = matched.matches[ j ];
3049
3050 // Triggered event must either 1) be non-exclusive and have no namespace, or
3051 // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).
3052 if ( run_all || (!event.namespace && !handleObj.namespace) || event.namespace_re && event.namespace_re.test( handleObj.namespace ) ) {
3053
3054 event.data = handleObj.data;
3055 event.handleObj = handleObj;
3056
3057 ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )
3058 .apply( matched.elem, args );
3059
3060 if ( ret !== undefined ) {
3061 event.result = ret;
3062 if ( ret === false ) {
3063 event.preventDefault();
3064 event.stopPropagation();
3065 }
3066 }
3067 }
3068 }
3069 }
3070
3071 // Call the postDispatch hook for the mapped type
3072 if ( special.postDispatch ) {
3073 special.postDispatch.call( this, event );
3074 }
3075
3076 return event.result;
3077 },
3078
3079 // Includes some event props shared by KeyEvent and MouseEvent
3080 // *** attrChange attrName relatedNode srcElement are not normalized, non-W3C, deprecated, will be removed in 1.8 ***
3081 props: "attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),
3082
3083 fixHooks: {},
3084
3085 keyHooks: {
3086 props: "char charCode key keyCode".split(" "),
3087 filter: function( event, original ) {
3088
3089 // Add which for key events
3090 if ( event.which == null ) {
3091 event.which = original.charCode != null ? original.charCode : original.keyCode;
3092 }
3093
3094 return event;
3095 }
3096 },
3097
3098 mouseHooks: {
3099 props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),
3100 filter: function( event, original ) {
3101 var eventDoc, doc, body,
3102 button = original.button,
3103 fromElement = original.fromElement;
3104
3105 // Calculate pageX/Y if missing and clientX/Y available
3106 if ( event.pageX == null && original.clientX != null ) {
3107 eventDoc = event.target.ownerDocument || document;
3108 doc = eventDoc.documentElement;
3109 body = eventDoc.body;
3110
3111 event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );
3112 event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 );
3113 }
3114
3115 // Add relatedTarget, if necessary
3116 if ( !event.relatedTarget && fromElement ) {
3117 event.relatedTarget = fromElement === event.target ? original.toElement : fromElement;
3118 }
3119
3120 // Add which for click: 1 === left; 2 === middle; 3 === right
3121 // Note: button is not normalized, so don't use it
3122 if ( !event.which && button !== undefined ) {
3123 event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
3124 }
3125
3126 return event;
3127 }
3128 },
3129
3130 fix: function( event ) {
3131 if ( event[ jQuery.expando ] ) {
3132 return event;
3133 }
3134
3135 // Create a writable copy of the event object and normalize some properties
3136 var i, prop,
3137 originalEvent = event,
3138 fixHook = jQuery.event.fixHooks[ event.type ] || {},
3139 copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
3140
3141 event = jQuery.Event( originalEvent );
3142
3143 for ( i = copy.length; i; ) {
3144 prop = copy[ --i ];
3145 event[ prop ] = originalEvent[ prop ];
3146 }
3147
3148 // Fix target property, if necessary (#1925, IE 6/7/8 & Safari2)
3149 if ( !event.target ) {
3150 event.target = originalEvent.srcElement || document;
3151 }
3152
3153 // Target should not be a text node (#504, Safari)
3154 if ( event.target.nodeType === 3 ) {
3155 event.target = event.target.parentNode;
3156 }
3157
3158 // For mouse/key events, metaKey==false if it's undefined (#3368, #11328; IE6/7/8)
3159 event.metaKey = !!event.metaKey;
3160
3161 return fixHook.filter? fixHook.filter( event, originalEvent ) : event;
3162 },
3163
3164 special: {
3165 load: {
3166 // Prevent triggered image.load events from bubbling to window.load
3167 noBubble: true
3168 },
3169
3170 focus: {
3171 delegateType: "focusin"
3172 },
3173 blur: {
3174 delegateType: "focusout"
3175 },
3176
3177 beforeunload: {
3178 setup: function( data, namespaces, eventHandle ) {
3179 // We only want to do this special case on windows
3180 if ( jQuery.isWindow( this ) ) {
3181 this.onbeforeunload = eventHandle;
3182 }
3183 },
3184
3185 teardown: function( namespaces, eventHandle ) {
3186 if ( this.onbeforeunload === eventHandle ) {
3187 this.onbeforeunload = null;
3188 }
3189 }
3190 }
3191 },
3192
3193 simulate: function( type, elem, event, bubble ) {
3194 // Piggyback on a donor event to simulate a different one.
3195 // Fake originalEvent to avoid donor's stopPropagation, but if the
3196 // simulated event prevents default then we do the same on the donor.
3197 var e = jQuery.extend(
3198 new jQuery.Event(),
3199 event,
3200 { type: type,
3201 isSimulated: true,
3202 originalEvent: {}
3203 }
3204 );
3205 if ( bubble ) {
3206 jQuery.event.trigger( e, null, elem );
3207 } else {
3208 jQuery.event.dispatch.call( elem, e );
3209 }
3210 if ( e.isDefaultPrevented() ) {
3211 event.preventDefault();
3212 }
3213 }
3214 };
3215
3216 // Some plugins are using, but it's undocumented/deprecated and will be removed.
3217 // The 1.7 special event interface should provide all the hooks needed now.
3218 jQuery.event.handle = jQuery.event.dispatch;
3219
3220 jQuery.removeEvent = document.removeEventListener ?
3221 function( elem, type, handle ) {
3222 if ( elem.removeEventListener ) {
3223 elem.removeEventListener( type, handle, false );
3224 }
3225 } :
3226 function( elem, type, handle ) {
3227 var name = "on" + type;
3228
3229 if ( elem.detachEvent ) {
3230
3231 // #8545, #7054, preventing memory leaks for custom events in IE6-8
3232 // detachEvent needed property on element, by name of that event, to properly expose it to GC
3233 if ( typeof elem[ name ] === "undefined" ) {
3234 elem[ name ] = null;
3235 }
3236
3237 elem.detachEvent( name, handle );
3238 }
3239 };
3240
3241 jQuery.Event = function( src, props ) {
3242 // Allow instantiation without the 'new' keyword
3243 if ( !(this instanceof jQuery.Event) ) {
3244 return new jQuery.Event( src, props );
3245 }
3246
3247 // Event object
3248 if ( src && src.type ) {
3249 this.originalEvent = src;
3250 this.type = src.type;
3251
3252 // Events bubbling up the document may have been marked as prevented
3253 // by a handler lower down the tree; reflect the correct value.
3254 this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false ||
3255 src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse;
3256
3257 // Event type
3258 } else {
3259 this.type = src;
3260 }
3261
3262 // Put explicitly provided properties onto the event object
3263 if ( props ) {
3264 jQuery.extend( this, props );
3265 }
3266
3267 // Create a timestamp if incoming event doesn't have one
3268 this.timeStamp = src && src.timeStamp || jQuery.now();
3269
3270 // Mark it as fixed
3271 this[ jQuery.expando ] = true;
3272 };
3273
3274 function returnFalse() {
3275 return false;
3276 }
3277 function returnTrue() {
3278 return true;
3279 }
3280
3281 // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
3282 // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
3283 jQuery.Event.prototype = {
3284 preventDefault: function() {
3285 this.isDefaultPrevented = returnTrue;
3286
3287 var e = this.originalEvent;
3288 if ( !e ) {
3289 return;
3290 }
3291
3292 // if preventDefault exists run it on the original event
3293 if ( e.preventDefault ) {
3294 e.preventDefault();
3295
3296 // otherwise set the returnValue property of the original event to false (IE)
3297 } else {
3298 e.returnValue = false;
3299 }
3300 },
3301 stopPropagation: function() {
3302 this.isPropagationStopped = returnTrue;
3303
3304 var e = this.originalEvent;
3305 if ( !e ) {
3306 return;
3307 }
3308 // if stopPropagation exists run it on the original event
3309 if ( e.stopPropagation ) {
3310 e.stopPropagation();
3311 }
3312 // otherwise set the cancelBubble property of the original event to true (IE)
3313 e.cancelBubble = true;
3314 },
3315 stopImmediatePropagation: function() {
3316 this.isImmediatePropagationStopped = returnTrue;
3317 this.stopPropagation();
3318 },
3319 isDefaultPrevented: returnFalse,
3320 isPropagationStopped: returnFalse,
3321 isImmediatePropagationStopped: returnFalse
3322 };
3323
3324 // Create mouseenter/leave events using mouseover/out and event-time checks
3325 jQuery.each({
3326 mouseenter: "mouseover",
3327 mouseleave: "mouseout"
3328 }, function( orig, fix ) {
3329 jQuery.event.special[ orig ] = {
3330 delegateType: fix,
3331 bindType: fix,
3332
3333 handle: function( event ) {
3334 var ret,
3335 target = this,
3336 related = event.relatedTarget,
3337 handleObj = event.handleObj,
3338 selector = handleObj.selector;
3339
3340 // For mousenter/leave call the handler if related is outside the target.
3341 // NB: No relatedTarget if the mouse left/entered the browser window
3342 if ( !related || (related !== target && !jQuery.contains( target, related )) ) {
3343 event.type = handleObj.origType;
3344 ret = handleObj.handler.apply( this, arguments );
3345 event.type = fix;
3346 }
3347 return ret;
3348 }
3349 };
3350 });
3351
3352 // IE submit delegation
3353 if ( !jQuery.support.submitBubbles ) {
3354
3355 jQuery.event.special.submit = {
3356 setup: function() {
3357 // Only need this for delegated form submit events
3358 if ( jQuery.nodeName( this, "form" ) ) {
3359 return false;
3360 }
3361
3362 // Lazy-add a submit handler when a descendant form may potentially be submitted
3363 jQuery.event.add( this, "click._submit keypress._submit", function( e ) {
3364 // Node name check avoids a VML-related crash in IE (#9807)
3365 var elem = e.target,
3366 form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined;
3367 if ( form && !jQuery._data( form, "_submit_attached" ) ) {
3368 jQuery.event.add( form, "submit._submit", function( event ) {
3369 event._submit_bubble = true;
3370 });
3371 jQuery._data( form, "_submit_attached", true );
3372 }
3373 });
3374 // return undefined since we don't need an event listener
3375 },
3376
3377 postDispatch: function( event ) {
3378 // If form was submitted by the user, bubble the event up the tree
3379 if ( event._submit_bubble ) {
3380 delete event._submit_bubble;
3381 if ( this.parentNode && !event.isTrigger ) {
3382 jQuery.event.simulate( "submit", this.parentNode, event, true );
3383 }
3384 }
3385 },
3386
3387 teardown: function() {
3388 // Only need this for delegated form submit events
3389 if ( jQuery.nodeName( this, "form" ) ) {
3390 return false;
3391 }
3392
3393 // Remove delegated handlers; cleanData eventually reaps submit handlers attached above
3394 jQuery.event.remove( this, "._submit" );
3395 }
3396 };
3397 }
3398
3399 // IE change delegation and checkbox/radio fix
3400 if ( !jQuery.support.changeBubbles ) {
3401
3402 jQuery.event.special.change = {
3403
3404 setup: function() {
3405
3406 if ( rformElems.test( this.nodeName ) ) {
3407 // IE doesn't fire change on a check/radio until blur; trigger it on click
3408 // after a propertychange. Eat the blur-change in special.change.handle.
3409 // This still fires onchange a second time for check/radio after blur.
3410 if ( this.type === "checkbox" || this.type === "radio" ) {
3411 jQuery.event.add( this, "propertychange._change", function( event ) {
3412 if ( event.originalEvent.propertyName === "checked" ) {
3413 this._just_changed = true;
3414 }
3415 });
3416 jQuery.event.add( this, "click._change", function( event ) {
3417 if ( this._just_changed && !event.isTrigger ) {
3418 this._just_changed = false;
3419 }
3420 // Allow triggered, simulated change events (#11500)
3421 jQuery.event.simulate( "change", this, event, true );
3422 });
3423 }
3424 return false;
3425 }
3426 // Delegated event; lazy-add a change handler on descendant inputs
3427 jQuery.event.add( this, "beforeactivate._change", function( e ) {
3428 var elem = e.target;
3429
3430 if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "_change_attached" ) ) {
3431 jQuery.event.add( elem, "change._change", function( event ) {
3432 if ( this.parentNode && !event.isSimulated && !event.isTrigger ) {
3433 jQuery.event.simulate( "change", this.parentNode, event, true );
3434 }
3435 });
3436 jQuery._data( elem, "_change_attached", true );
3437 }
3438 });
3439 },
3440
3441 handle: function( event ) {
3442 var elem = event.target;
3443
3444 // Swallow native change events from checkbox/radio, we already triggered them above
3445 if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) {
3446 return event.handleObj.handler.apply( this, arguments );
3447 }
3448 },
3449
3450 teardown: function() {
3451 jQuery.event.remove( this, "._change" );
3452
3453 return !rformElems.test( this.nodeName );
3454 }
3455 };
3456 }
3457
3458 // Create "bubbling" focus and blur events
3459 if ( !jQuery.support.focusinBubbles ) {
3460 jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
3461
3462 // Attach a single capturing handler while someone wants focusin/focusout
3463 var attaches = 0,
3464 handler = function( event ) {
3465 jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );
3466 };
3467
3468 jQuery.event.special[ fix ] = {
3469 setup: function() {
3470 if ( attaches++ === 0 ) {
3471 document.addEventListener( orig, handler, true );
3472 }
3473 },
3474 teardown: function() {
3475 if ( --attaches === 0 ) {
3476 document.removeEventListener( orig, handler, true );
3477 }
3478 }
3479 };
3480 });
3481 }
3482
3483 jQuery.fn.extend({
3484
3485 on: function( types, selector, data, fn, /*INTERNAL*/ one ) {
3486 var origFn, type;
3487
3488 // Types can be a map of types/handlers
3489 if ( typeof types === "object" ) {
3490 // ( types-Object, selector, data )
3491 if ( typeof selector !== "string" ) { // && selector != null
3492 // ( types-Object, data )
3493 data = data || selector;
3494 selector = undefined;
3495 }
3496 for ( type in types ) {
3497 this.on( type, selector, data, types[ type ], one );
3498 }
3499 return this;
3500 }
3501
3502 if ( data == null && fn == null ) {
3503 // ( types, fn )
3504 fn = selector;
3505 data = selector = undefined;
3506 } else if ( fn == null ) {
3507 if ( typeof selector === "string" ) {
3508 // ( types, selector, fn )
3509 fn = data;
3510 data = undefined;
3511 } else {
3512 // ( types, data, fn )
3513 fn = data;
3514 data = selector;
3515 selector = undefined;
3516 }
3517 }
3518 if ( fn === false ) {
3519 fn = returnFalse;
3520 } else if ( !fn ) {
3521 return this;
3522 }
3523
3524 if ( one === 1 ) {
3525 origFn = fn;
3526 fn = function( event ) {
3527 // Can use an empty set, since event contains the info
3528 jQuery().off( event );
3529 return origFn.apply( this, arguments );
3530 };
3531 // Use same guid so caller can remove using origFn
3532 fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
3533 }
3534 return this.each( function() {
3535 jQuery.event.add( this, types, fn, data, selector );
3536 });
3537 },
3538 one: function( types, selector, data, fn ) {
3539 return this.on( types, selector, data, fn, 1 );
3540 },
3541 off: function( types, selector, fn ) {
3542 var handleObj, type;
3543 if ( types && types.preventDefault && types.handleObj ) {
3544 // ( event ) dispatched jQuery.Event
3545 handleObj = types.handleObj;
3546 jQuery( types.delegateTarget ).off(
3547 handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType,
3548 handleObj.selector,
3549 handleObj.handler
3550 );
3551 return this;
3552 }
3553 if ( typeof types === "object" ) {
3554 // ( types-object [, selector] )
3555 for ( type in types ) {
3556 this.off( type, selector, types[ type ] );
3557 }
3558 return this;
3559 }
3560 if ( selector === false || typeof selector === "function" ) {
3561 // ( types [, fn] )
3562 fn = selector;
3563 selector = undefined;
3564 }
3565 if ( fn === false ) {
3566 fn = returnFalse;
3567 }
3568 return this.each(function() {
3569 jQuery.event.remove( this, types, fn, selector );
3570 });
3571 },
3572
3573 bind: function( types, data, fn ) {
3574 return this.on( types, null, data, fn );
3575 },
3576 unbind: function( types, fn ) {
3577 return this.off( types, null, fn );
3578 },
3579
3580 live: function( types, data, fn ) {
3581 jQuery( this.context ).on( types, this.selector, data, fn );
3582 return this;
3583 },
3584 die: function( types, fn ) {
3585 jQuery( this.context ).off( types, this.selector || "**", fn );
3586 return this;
3587 },
3588
3589 delegate: function( selector, types, data, fn ) {
3590 return this.on( types, selector, data, fn );
3591 },
3592 undelegate: function( selector, types, fn ) {
3593 // ( namespace ) or ( selector, types [, fn] )
3594 return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn );
3595 },
3596
3597 trigger: function( type, data ) {
3598 return this.each(function() {
3599 jQuery.event.trigger( type, data, this );
3600 });
3601 },
3602 triggerHandler: function( type, data ) {
3603 if ( this[0] ) {
3604 return jQuery.event.trigger( type, data, this[0], true );
3605 }
3606 },
3607
3608 toggle: function( fn ) {
3609 // Save reference to arguments for access in closure
3610 var args = arguments,
3611 guid = fn.guid || jQuery.guid++,
3612 i = 0,
3613 toggler = function( event ) {
3614 // Figure out which function to execute
3615 var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i;
3616 jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 );
3617
3618 // Make sure that clicks stop
3619 event.preventDefault();
3620
3621 // and execute the function
3622 return args[ lastToggle ].apply( this, arguments ) || false;
3623 };
3624
3625 // link all the functions, so any of them can unbind this click handler
3626 toggler.guid = guid;
3627 while ( i < args.length ) {
3628 args[ i++ ].guid = guid;
3629 }
3630
3631 return this.click( toggler );
3632 },
3633
3634 hover: function( fnOver, fnOut ) {
3635 return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
3636 }
3637 });
3638
3639 jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
3640 "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
3641 "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) {
3642
3643 // Handle event binding
3644 jQuery.fn[ name ] = function( data, fn ) {
3645 if ( fn == null ) {
3646 fn = data;
3647 data = null;
3648 }
3649
3650 return arguments.length > 0 ?
3651 this.on( name, null, data, fn ) :
3652 this.trigger( name );
3653 };
3654
3655 if ( rkeyEvent.test( name ) ) {
3656 jQuery.event.fixHooks[ name ] = jQuery.event.keyHooks;
3657 }
3658
3659 if ( rmouseEvent.test( name ) ) {
3660 jQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks;
3661 }
3662 });
3663 /*!
3664 * Sizzle CSS Selector Engine
3665 * Copyright 2012 jQuery Foundation and other contributors
3666 * Released under the MIT license
3667 * http://sizzlejs.com/
3668 */
3669 (function( window, undefined ) {
3670
3671 var cachedruns,
3672 assertGetIdNotName,
3673 Expr,
3674 getText,
3675 isXML,
3676 contains,
3677 compile,
3678 sortOrder,
3679 hasDuplicate,
3680 outermostContext,
3681
3682 baseHasDuplicate = true,
3683 strundefined = "undefined",
3684
3685 expando = ( "sizcache" + Math.random() ).replace( ".", "" ),
3686
3687 Token = String,
3688 document = window.document,
3689 docElem = document.documentElement,
3690 dirruns = 0,
3691 done = 0,
3692 pop = [].pop,
3693 push = [].push,
3694 slice = [].slice,
3695 // Use a stripped-down indexOf if a native one is unavailable
3696 indexOf = [].indexOf || function( elem ) {
3697 var i = 0,
3698 len = this.length;
3699 for ( ; i < len; i++ ) {
3700 if ( this[i] === elem ) {
3701 return i;
3702 }
3703 }
3704 return -1;
3705 },
3706
3707 // Augment a function for special use by Sizzle
3708 markFunction = function( fn, value ) {
3709 fn[ expando ] = value == null || value;
3710 return fn;
3711 },
3712
3713 createCache = function() {
3714 var cache = {},
3715 keys = [];
3716
3717 return markFunction(function( key, value ) {
3718 // Only keep the most recent entries
3719 if ( keys.push( key ) > Expr.cacheLength ) {
3720 delete cache[ keys.shift() ];
3721 }
3722
3723 // Retrieve with (key + " ") to avoid collision with native Object.prototype properties (see Issue #157)
3724 return (cache[ key + " " ] = value);
3725 }, cache );
3726 },
3727
3728 classCache = createCache(),
3729 tokenCache = createCache(),
3730 compilerCache = createCache(),
3731
3732 // Regex
3733
3734 // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace
3735 whitespace = "[\\x20\\t\\r\\n\\f]",
3736 // http://www.w3.org/TR/css3-syntax/#characters
3737 characterEncoding = "(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+",
3738
3739 // Loosely modeled on CSS identifier characters
3740 // An unquoted value should be a CSS identifier (http://www.w3.org/TR/css3-selectors/#attribute-selectors)
3741 // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
3742 identifier = characterEncoding.replace( "w", "w#" ),
3743
3744 // Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors
3745 operators = "([*^$|!~]?=)",
3746 attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace +
3747 "*(?:" + operators + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]",
3748
3749 // Prefer arguments not in parens/brackets,
3750 // then attribute selectors and non-pseudos (denoted by :),
3751 // then anything else
3752 // These preferences are here to reduce the number of selectors
3753 // needing tokenize in the PSEUDO preFilter
3754 pseudos = ":(" + characterEncoding + ")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:" + attributes + ")|[^:]|\\\\.)*|.*))\\)|)",
3755
3756 // For matchExpr.POS and matchExpr.needsContext
3757 pos = ":(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace +
3758 "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)",
3759
3760 // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
3761 rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
3762
3763 rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
3764 rcombinators = new RegExp( "^" + whitespace + "*([\\x20\\t\\r\\n\\f>+~])" + whitespace + "*" ),
3765 rpseudo = new RegExp( pseudos ),
3766
3767 // Easily-parseable/retrievable ID or TAG or CLASS selectors
3768 rquickExpr = /^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,
3769
3770 rnot = /^:not/,
3771 rsibling = /[\x20\t\r\n\f]*[+~]/,
3772 rendsWithNot = /:not\($/,
3773
3774 rheader = /h\d/i,
3775 rinputs = /input|select|textarea|button/i,
3776
3777 rbackslash = /\\(?!\\)/g,
3778
3779 matchExpr = {
3780 "ID": new RegExp( "^#(" + characterEncoding + ")" ),
3781 "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ),
3782 "NAME": new RegExp( "^\\[name=['\"]?(" + characterEncoding + ")['\"]?\\]" ),
3783 "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ),
3784 "ATTR": new RegExp( "^" + attributes ),
3785 "PSEUDO": new RegExp( "^" + pseudos ),
3786 "POS": new RegExp( pos, "i" ),
3787 "CHILD": new RegExp( "^:(only|nth|first|last)-child(?:\\(" + whitespace +
3788 "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
3789 "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
3790 // For use in libraries implementing .is()
3791 "needsContext": new RegExp( "^" + whitespace + "*[>+~]|" + pos, "i" )
3792 },
3793
3794 // Support
3795
3796 // Used for testing something on an element
3797 assert = function( fn ) {
3798 var div = document.createElement("div");
3799
3800 try {
3801 return fn( div );
3802 } catch (e) {
3803 return false;
3804 } finally {
3805 // release memory in IE
3806 div = null;
3807 }
3808 },
3809
3810 // Check if getElementsByTagName("*") returns only elements
3811 assertTagNameNoComments = assert(function( div ) {
3812 div.appendChild( document.createComment("") );
3813 return !div.getElementsByTagName("*").length;
3814 }),
3815
3816 // Check if getAttribute returns normalized href attributes
3817 assertHrefNotNormalized = assert(function( div ) {
3818 div.innerHTML = "<a href='#'></a>";
3819 return div.firstChild && typeof div.firstChild.getAttribute !== strundefined &&
3820 div.firstChild.getAttribute("href") === "#";
3821 }),
3822
3823 // Check if attributes should be retrieved by attribute nodes
3824 assertAttributes = assert(function( div ) {
3825 div.innerHTML = "<select></select>";
3826 var type = typeof div.lastChild.getAttribute("multiple");
3827 // IE8 returns a string for some attributes even when not present
3828 return type !== "boolean" && type !== "string";
3829 }),
3830
3831 // Check if getElementsByClassName can be trusted
3832 assertUsableClassName = assert(function( div ) {
3833 // Opera can't find a second classname (in 9.6)
3834 div.innerHTML = "<div class='hidden e'></div><div class='hidden'></div>";
3835 if ( !div.getElementsByClassName || !div.getElementsByClassName("e").length ) {
3836 return false;
3837 }
3838
3839 // Safari 3.2 caches class attributes and doesn't catch changes
3840 div.lastChild.className = "e";
3841 return div.getElementsByClassName("e").length === 2;
3842 }),
3843
3844 // Check if getElementById returns elements by name
3845 // Check if getElementsByName privileges form controls or returns elements by ID
3846 assertUsableName = assert(function( div ) {
3847 // Inject content
3848 div.id = expando + 0;
3849 div.innerHTML = "<a name='" + expando + "'></a><div name='" + expando + "'></div>";
3850 docElem.insertBefore( div, docElem.firstChild );
3851
3852 // Test
3853 var pass = document.getElementsByName &&
3854 // buggy browsers will return fewer than the correct 2
3855 document.getElementsByName( expando ).length === 2 +
3856 // buggy browsers will return more than the correct 0
3857 document.getElementsByName( expando + 0 ).length;
3858 assertGetIdNotName = !document.getElementById( expando );
3859
3860 // Cleanup
3861 docElem.removeChild( div );
3862
3863 return pass;
3864 });
3865
3866 // If slice is not available, provide a backup
3867 try {
3868 slice.call( docElem.childNodes, 0 )[0].nodeType;
3869 } catch ( e ) {
3870 slice = function( i ) {
3871 var elem,
3872 results = [];
3873 for ( ; (elem = this[i]); i++ ) {
3874 results.push( elem );
3875 }
3876 return results;
3877 };
3878 }
3879
3880 function Sizzle( selector, context, results, seed ) {
3881 results = results || [];
3882 context = context || document;
3883 var match, elem, xml, m,
3884 nodeType = context.nodeType;
3885
3886 if ( !selector || typeof selector !== "string" ) {
3887 return results;
3888 }
3889
3890 if ( nodeType !== 1 && nodeType !== 9 ) {
3891 return [];
3892 }
3893
3894 xml = isXML( context );
3895
3896 if ( !xml && !seed ) {
3897 if ( (match = rquickExpr.exec( selector )) ) {
3898 // Speed-up: Sizzle("#ID")
3899 if ( (m = match[1]) ) {
3900 if ( nodeType === 9 ) {
3901 elem = context.getElementById( m );
3902 // Check parentNode to catch when Blackberry 4.6 returns
3903 // nodes that are no longer in the document #6963
3904 if ( elem && elem.parentNode ) {
3905 // Handle the case where IE, Opera, and Webkit return items
3906 // by name instead of ID
3907 if ( elem.id === m ) {
3908 results.push( elem );
3909 return results;
3910 }
3911 } else {
3912 return results;
3913 }
3914 } else {
3915 // Context is not a document
3916 if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&
3917 contains( context, elem ) && elem.id === m ) {
3918 results.push( elem );
3919 return results;
3920 }
3921 }
3922
3923 // Speed-up: Sizzle("TAG")
3924 } else if ( match[2] ) {
3925 push.apply( results, slice.call(context.getElementsByTagName( selector ), 0) );
3926 return results;
3927
3928 // Speed-up: Sizzle(".CLASS")
3929 } else if ( (m = match[3]) && assertUsableClassName && context.getElementsByClassName ) {
3930 push.apply( results, slice.call(context.getElementsByClassName( m ), 0) );
3931 return results;
3932 }
3933 }
3934 }
3935
3936 // All others
3937 return select( selector.replace( rtrim, "$1" ), context, results, seed, xml );
3938 }
3939
3940 Sizzle.matches = function( expr, elements ) {
3941 return Sizzle( expr, null, null, elements );
3942 };
3943
3944 Sizzle.matchesSelector = function( elem, expr ) {
3945 return Sizzle( expr, null, null, [ elem ] ).length > 0;
3946 };
3947
3948 // Returns a function to use in pseudos for input types
3949 function createInputPseudo( type ) {
3950 return function( elem ) {
3951 var name = elem.nodeName.toLowerCase();
3952 return name === "input" && elem.type === type;
3953 };
3954 }
3955
3956 // Returns a function to use in pseudos for buttons
3957 function createButtonPseudo( type ) {
3958 return function( elem ) {
3959 var name = elem.nodeName.toLowerCase();
3960 return (name === "input" || name === "button") && elem.type === type;
3961 };
3962 }
3963
3964 // Returns a function to use in pseudos for positionals
3965 function createPositionalPseudo( fn ) {
3966 return markFunction(function( argument ) {
3967 argument = +argument;
3968 return markFunction(function( seed, matches ) {
3969 var j,
3970 matchIndexes = fn( [], seed.length, argument ),
3971 i = matchIndexes.length;
3972
3973 // Match elements found at the specified indexes
3974 while ( i-- ) {
3975 if ( seed[ (j = matchIndexes[i]) ] ) {
3976 seed[j] = !(matches[j] = seed[j]);
3977 }
3978 }
3979 });
3980 });
3981 }
3982
3983 /**
3984 * Utility function for retrieving the text value of an array of DOM nodes
3985 * @param {Array|Element} elem
3986 */
3987 getText = Sizzle.getText = function( elem ) {
3988 var node,
3989 ret = "",
3990 i = 0,
3991 nodeType = elem.nodeType;
3992
3993 if ( nodeType ) {
3994 if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
3995 // Use textContent for elements
3996 // innerText usage removed for consistency of new lines (see #11153)
3997 if ( typeof elem.textContent === "string" ) {
3998 return elem.textContent;
3999 } else {
4000 // Traverse its children
4001 for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
4002 ret += getText( elem );
4003 }
4004 }
4005 } else if ( nodeType === 3 || nodeType === 4 ) {
4006 return elem.nodeValue;
4007 }
4008 // Do not include comment or processing instruction nodes
4009 } else {
4010
4011 // If no nodeType, this is expected to be an array
4012 for ( ; (node = elem[i]); i++ ) {
4013 // Do not traverse comment nodes
4014 ret += getText( node );
4015 }
4016 }
4017 return ret;
4018 };
4019
4020 isXML = Sizzle.isXML = function( elem ) {
4021 // documentElement is verified for cases where it doesn't yet exist
4022 // (such as loading iframes in IE - #4833)
4023 var documentElement = elem && (elem.ownerDocument || elem).documentElement;
4024 return documentElement ? documentElement.nodeName !== "HTML" : false;
4025 };
4026
4027 // Element contains another
4028 contains = Sizzle.contains = docElem.contains ?
4029 function( a, b ) {
4030 var adown = a.nodeType === 9 ? a.documentElement : a,
4031 bup = b && b.parentNode;
4032 return a === bup || !!( bup && bup.nodeType === 1 && adown.contains && adown.contains(bup) );
4033 } :
4034 docElem.compareDocumentPosition ?
4035 function( a, b ) {
4036 return b && !!( a.compareDocumentPosition( b ) & 16 );
4037 } :
4038 function( a, b ) {
4039 while ( (b = b.parentNode) ) {
4040 if ( b === a ) {
4041 return true;
4042 }
4043 }
4044 return false;
4045 };
4046
4047 Sizzle.attr = function( elem, name ) {
4048 var val,
4049 xml = isXML( elem );
4050
4051 if ( !xml ) {
4052 name = name.toLowerCase();
4053 }
4054 if ( (val = Expr.attrHandle[ name ]) ) {
4055 return val( elem );
4056 }
4057 if ( xml || assertAttributes ) {
4058 return elem.getAttribute( name );
4059 }
4060 val = elem.getAttributeNode( name );
4061 return val ?
4062 typeof elem[ name ] === "boolean" ?
4063 elem[ name ] ? name : null :
4064 val.specified ? val.value : null :
4065 null;
4066 };
4067
4068 Expr = Sizzle.selectors = {
4069
4070 // Can be adjusted by the user
4071 cacheLength: 50,
4072
4073 createPseudo: markFunction,
4074
4075 match: matchExpr,
4076
4077 // IE6/7 return a modified href
4078 attrHandle: assertHrefNotNormalized ?
4079 {} :
4080 {
4081 "href": function( elem ) {
4082 return elem.getAttribute( "href", 2 );
4083 },
4084 "type": function( elem ) {
4085 return elem.getAttribute("type");
4086 }
4087 },
4088
4089 find: {
4090 "ID": assertGetIdNotName ?
4091 function( id, context, xml ) {
4092 if ( typeof context.getElementById !== strundefined && !xml ) {
4093 var m = context.getElementById( id );
4094 // Check parentNode to catch when Blackberry 4.6 returns
4095 // nodes that are no longer in the document #6963
4096 return m && m.parentNode ? [m] : [];
4097 }
4098 } :
4099 function( id, context, xml ) {
4100 if ( typeof context.getElementById !== strundefined && !xml ) {
4101 var m = context.getElementById( id );
4102
4103 return m ?
4104 m.id === id || typeof m.getAttributeNode !== strundefined && m.getAttributeNode("id").value === id ?
4105 [m] :
4106 undefined :
4107 [];
4108 }
4109 },
4110
4111 "TAG": assertTagNameNoComments ?
4112 function( tag, context ) {
4113 if ( typeof context.getElementsByTagName !== strundefined ) {
4114 return context.getElementsByTagName( tag );
4115 }
4116 } :
4117 function( tag, context ) {
4118 var results = context.getElementsByTagName( tag );
4119
4120 // Filter out possible comments
4121 if ( tag === "*" ) {
4122 var elem,
4123 tmp = [],
4124 i = 0;
4125
4126 for ( ; (elem = results[i]); i++ ) {
4127 if ( elem.nodeType === 1 ) {
4128 tmp.push( elem );
4129 }
4130 }
4131
4132 return tmp;
4133 }
4134 return results;
4135 },
4136
4137 "NAME": assertUsableName && function( tag, context ) {
4138 if ( typeof context.getElementsByName !== strundefined ) {
4139 return context.getElementsByName( name );
4140 }
4141 },
4142
4143 "CLASS": assertUsableClassName && function( className, context, xml ) {
4144 if ( typeof context.getElementsByClassName !== strundefined && !xml ) {
4145 return context.getElementsByClassName( className );
4146 }
4147 }
4148 },
4149
4150 relative: {
4151 ">": { dir: "parentNode", first: true },
4152 " ": { dir: "parentNode" },
4153 "+": { dir: "previousSibling", first: true },
4154 "~": { dir: "previousSibling" }
4155 },
4156
4157 preFilter: {
4158 "ATTR": function( match ) {
4159 match[1] = match[1].replace( rbackslash, "" );
4160
4161 // Move the given value to match[3] whether quoted or unquoted
4162 match[3] = ( match[4] || match[5] || "" ).replace( rbackslash, "" );
4163
4164 if ( match[2] === "~=" ) {
4165 match[3] = " " + match[3] + " ";
4166 }
4167
4168 return match.slice( 0, 4 );
4169 },
4170
4171 "CHILD": function( match ) {
4172 /* matches from matchExpr["CHILD"]
4173 1 type (only|nth|...)
4174 2 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
4175 3 xn-component of xn+y argument ([+-]?\d*n|)
4176 4 sign of xn-component
4177 5 x of xn-component
4178 6 sign of y-component
4179 7 y of y-component
4180 */
4181 match[1] = match[1].toLowerCase();
4182
4183 if ( match[1] === "nth" ) {
4184 // nth-child requires argument
4185 if ( !match[2] ) {
4186 Sizzle.error( match[0] );
4187 }
4188
4189 // numeric x and y parameters for Expr.filter.CHILD
4190 // remember that false/true cast respectively to 0/1
4191 match[3] = +( match[3] ? match[4] + (match[5] || 1) : 2 * ( match[2] === "even" || match[2] === "odd" ) );
4192 match[4] = +( ( match[6] + match[7] ) || match[2] === "odd" );
4193
4194 // other types prohibit arguments
4195 } else if ( match[2] ) {
4196 Sizzle.error( match[0] );
4197 }
4198
4199 return match;
4200 },
4201
4202 "PSEUDO": function( match ) {
4203 var unquoted, excess;
4204 if ( matchExpr["CHILD"].test( match[0] ) ) {
4205 return null;
4206 }
4207
4208 if ( match[3] ) {
4209 match[2] = match[3];
4210 } else if ( (unquoted = match[4]) ) {
4211 // Only check arguments that contain a pseudo
4212 if ( rpseudo.test(unquoted) &&
4213 // Get excess from tokenize (recursively)
4214 (excess = tokenize( unquoted, true )) &&
4215 // advance to the next closing parenthesis
4216 (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
4217
4218 // excess is a negative index
4219 unquoted = unquoted.slice( 0, excess );
4220 match[0] = match[0].slice( 0, excess );
4221 }
4222 match[2] = unquoted;
4223 }
4224
4225 // Return only captures needed by the pseudo filter method (type and argument)
4226 return match.slice( 0, 3 );
4227 }
4228 },
4229
4230 filter: {
4231 "ID": assertGetIdNotName ?
4232 function( id ) {
4233 id = id.replace( rbackslash, "" );
4234 return function( elem ) {
4235 return elem.getAttribute("id") === id;
4236 };
4237 } :
4238 function( id ) {
4239 id = id.replace( rbackslash, "" );
4240 return function( elem ) {
4241 var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id");
4242 return node && node.value === id;
4243 };
4244 },
4245
4246 "TAG": function( nodeName ) {
4247 if ( nodeName === "*" ) {
4248 return function() { return true; };
4249 }
4250 nodeName = nodeName.replace( rbackslash, "" ).toLowerCase();
4251
4252 return function( elem ) {
4253 return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
4254 };
4255 },
4256
4257 "CLASS": function( className ) {
4258 var pattern = classCache[ expando ][ className + " " ];
4259
4260 return pattern ||
4261 (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
4262 classCache( className, function( elem ) {
4263 return pattern.test( elem.className || (typeof elem.getAttribute !== strundefined && elem.getAttribute("class")) || "" );
4264 });
4265 },
4266
4267 "ATTR": function( name, operator, check ) {
4268 return function( elem, context ) {
4269 var result = Sizzle.attr( elem, name );
4270
4271 if ( result == null ) {
4272 return operator === "!=";
4273 }
4274 if ( !operator ) {
4275 return true;
4276 }
4277
4278 result += "";
4279
4280 return operator === "=" ? result === check :
4281 operator === "!=" ? result !== check :
4282 operator === "^=" ? check && result.indexOf( check ) === 0 :
4283 operator === "*=" ? check && result.indexOf( check ) > -1 :
4284 operator === "$=" ? check && result.substr( result.length - check.length ) === check :
4285 operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 :
4286 operator === "|=" ? result === check || result.substr( 0, check.length + 1 ) === check + "-" :
4287 false;
4288 };
4289 },
4290
4291 "CHILD": function( type, argument, first, last ) {
4292
4293 if ( type === "nth" ) {
4294 return function( elem ) {
4295 var node, diff,
4296 parent = elem.parentNode;
4297
4298 if ( first === 1 && last === 0 ) {
4299 return true;
4300 }
4301
4302 if ( parent ) {
4303 diff = 0;
4304 for ( node = parent.firstChild; node; node = node.nextSibling ) {
4305 if ( node.nodeType === 1 ) {
4306 diff++;
4307 if ( elem === node ) {
4308 break;
4309 }
4310 }
4311 }
4312 }
4313
4314 // Incorporate the offset (or cast to NaN), then check against cycle size
4315 diff -= last;
4316 return diff === first || ( diff % first === 0 && diff / first >= 0 );
4317 };
4318 }
4319
4320 return function( elem ) {
4321 var node = elem;
4322
4323 switch ( type ) {
4324 case "only":
4325 case "first":
4326 while ( (node = node.previousSibling) ) {
4327 if ( node.nodeType === 1 ) {
4328 return false;
4329 }
4330 }
4331
4332 if ( type === "first" ) {
4333 return true;
4334 }
4335
4336 node = elem;
4337
4338 /* falls through */
4339 case "last":
4340 while ( (node = node.nextSibling) ) {
4341 if ( node.nodeType === 1 ) {
4342 return false;
4343 }
4344 }
4345
4346 return true;
4347 }
4348 };
4349 },
4350
4351 "PSEUDO": function( pseudo, argument ) {
4352 // pseudo-class names are case-insensitive
4353 // http://www.w3.org/TR/selectors/#pseudo-classes
4354 // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
4355 // Remember that setFilters inherits from pseudos
4356 var args,
4357 fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
4358 Sizzle.error( "unsupported pseudo: " + pseudo );
4359
4360 // The user may use createPseudo to indicate that
4361 // arguments are needed to create the filter function
4362 // just as Sizzle does
4363 if ( fn[ expando ] ) {
4364 return fn( argument );
4365 }
4366
4367 // But maintain support for old signatures
4368 if ( fn.length > 1 ) {
4369 args = [ pseudo, pseudo, "", argument ];
4370 return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
4371 markFunction(function( seed, matches ) {
4372 var idx,
4373 matched = fn( seed, argument ),
4374 i = matched.length;
4375 while ( i-- ) {
4376 idx = indexOf.call( seed, matched[i] );
4377 seed[ idx ] = !( matches[ idx ] = matched[i] );
4378 }
4379 }) :
4380 function( elem ) {
4381 return fn( elem, 0, args );
4382 };
4383 }
4384
4385 return fn;
4386 }
4387 },
4388
4389 pseudos: {
4390 "not": markFunction(function( selector ) {
4391 // Trim the selector passed to compile
4392 // to avoid treating leading and trailing
4393 // spaces as combinators
4394 var input = [],
4395 results = [],
4396 matcher = compile( selector.replace( rtrim, "$1" ) );
4397
4398 return matcher[ expando ] ?
4399 markFunction(function( seed, matches, context, xml ) {
4400 var elem,
4401 unmatched = matcher( seed, null, xml, [] ),
4402 i = seed.length;
4403
4404 // Match elements unmatched by `matcher`
4405 while ( i-- ) {
4406 if ( (elem = unmatched[i]) ) {
4407 seed[i] = !(matches[i] = elem);
4408 }
4409 }
4410 }) :
4411 function( elem, context, xml ) {
4412 input[0] = elem;
4413 matcher( input, null, xml, results );
4414 return !results.pop();
4415 };
4416 }),
4417
4418 "has": markFunction(function( selector ) {
4419 return function( elem ) {
4420 return Sizzle( selector, elem ).length > 0;
4421 };
4422 }),
4423
4424 "contains": markFunction(function( text ) {
4425 return function( elem ) {
4426 return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
4427 };
4428 }),
4429
4430 "enabled": function( elem ) {
4431 return elem.disabled === false;
4432 },
4433
4434 "disabled": function( elem ) {
4435 return elem.disabled === true;
4436 },
4437
4438 "checked": function( elem ) {
4439 // In CSS3, :checked should return both checked and selected elements
4440 // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
4441 var nodeName = elem.nodeName.toLowerCase();
4442 return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
4443 },
4444
4445 "selected": function( elem ) {
4446 // Accessing this property makes selected-by-default
4447 // options in Safari work properly
4448 if ( elem.parentNode ) {
4449 elem.parentNode.selectedIndex;
4450 }
4451
4452 return elem.selected === true;
4453 },
4454
4455 "parent": function( elem ) {
4456 return !Expr.pseudos["empty"]( elem );
4457 },
4458
4459 "empty": function( elem ) {
4460 // http://www.w3.org/TR/selectors/#empty-pseudo
4461 // :empty is only affected by element nodes and content nodes(including text(3), cdata(4)),
4462 // not comment, processing instructions, or others
4463 // Thanks to Diego Perini for the nodeName shortcut
4464 // Greater than "@" means alpha characters (specifically not starting with "#" or "?")
4465 var nodeType;
4466 elem = elem.firstChild;
4467 while ( elem ) {
4468 if ( elem.nodeName > "@" || (nodeType = elem.nodeType) === 3 || nodeType === 4 ) {
4469 return false;
4470 }
4471 elem = elem.nextSibling;
4472 }
4473 return true;
4474 },
4475
4476 "header": function( elem ) {
4477 return rheader.test( elem.nodeName );
4478 },
4479
4480 "text": function( elem ) {
4481 var type, attr;
4482 // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)
4483 // use getAttribute instead to test this case
4484 return elem.nodeName.toLowerCase() === "input" &&
4485 (type = elem.type) === "text" &&
4486 ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === type );
4487 },
4488
4489 // Input types
4490 "radio": createInputPseudo("radio"),
4491 "checkbox": createInputPseudo("checkbox"),
4492 "file": createInputPseudo("file"),
4493 "password": createInputPseudo("password"),
4494 "image": createInputPseudo("image"),
4495
4496 "submit": createButtonPseudo("submit"),
4497 "reset": createButtonPseudo("reset"),
4498
4499 "button": function( elem ) {
4500 var name = elem.nodeName.toLowerCase();
4501 return name === "input" && elem.type === "button" || name === "button";
4502 },
4503
4504 "input": function( elem ) {
4505 return rinputs.test( elem.nodeName );
4506 },
4507
4508 "focus": function( elem ) {
4509 var doc = elem.ownerDocument;
4510 return elem === doc.activeElement && (!doc.hasFocus || doc.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
4511 },
4512
4513 "active": function( elem ) {
4514 return elem === elem.ownerDocument.activeElement;
4515 },
4516
4517 // Positional types
4518 "first": createPositionalPseudo(function() {
4519 return [ 0 ];
4520 }),
4521
4522 "last": createPositionalPseudo(function( matchIndexes, length ) {
4523 return [ length - 1 ];
4524 }),
4525
4526 "eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
4527 return [ argument < 0 ? argument + length : argument ];
4528 }),
4529
4530 "even": createPositionalPseudo(function( matchIndexes, length ) {
4531 for ( var i = 0; i < length; i += 2 ) {
4532 matchIndexes.push( i );
4533 }
4534 return matchIndexes;
4535 }),
4536
4537 "odd": createPositionalPseudo(function( matchIndexes, length ) {
4538 for ( var i = 1; i < length; i += 2 ) {
4539 matchIndexes.push( i );
4540 }
4541 return matchIndexes;
4542 }),
4543
4544 "lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
4545 for ( var i = argument < 0 ? argument + length : argument; --i >= 0; ) {
4546 matchIndexes.push( i );
4547 }
4548 return matchIndexes;
4549 }),
4550
4551 "gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
4552 for ( var i = argument < 0 ? argument + length : argument; ++i < length; ) {
4553 matchIndexes.push( i );
4554 }
4555 return matchIndexes;
4556 })
4557 }
4558 };
4559
4560 function siblingCheck( a, b, ret ) {
4561 if ( a === b ) {
4562 return ret;
4563 }
4564
4565 var cur = a.nextSibling;
4566
4567 while ( cur ) {
4568 if ( cur === b ) {
4569 return -1;
4570 }
4571
4572 cur = cur.nextSibling;
4573 }
4574
4575 return 1;
4576 }
4577
4578 sortOrder = docElem.compareDocumentPosition ?
4579 function( a, b ) {
4580 if ( a === b ) {
4581 hasDuplicate = true;
4582 return 0;
4583 }
4584
4585 return ( !a.compareDocumentPosition || !b.compareDocumentPosition ?
4586 a.compareDocumentPosition :
4587 a.compareDocumentPosition(b) & 4
4588 ) ? -1 : 1;
4589 } :
4590 function( a, b ) {
4591 // The nodes are identical, we can exit early
4592 if ( a === b ) {
4593 hasDuplicate = true;
4594 return 0;
4595
4596 // Fallback to using sourceIndex (in IE) if it's available on both nodes
4597 } else if ( a.sourceIndex && b.sourceIndex ) {
4598 return a.sourceIndex - b.sourceIndex;
4599 }
4600
4601 var al, bl,
4602 ap = [],
4603 bp = [],
4604 aup = a.parentNode,
4605 bup = b.parentNode,
4606 cur = aup;
4607
4608 // If the nodes are siblings (or identical) we can do a quick check
4609 if ( aup === bup ) {
4610 return siblingCheck( a, b );
4611
4612 // If no parents were found then the nodes are disconnected
4613 } else if ( !aup ) {
4614 return -1;
4615
4616 } else if ( !bup ) {
4617 return 1;
4618 }
4619
4620 // Otherwise they're somewhere else in the tree so we need
4621 // to build up a full list of the parentNodes for comparison
4622 while ( cur ) {
4623 ap.unshift( cur );
4624 cur = cur.parentNode;
4625 }
4626
4627 cur = bup;
4628
4629 while ( cur ) {
4630 bp.unshift( cur );
4631 cur = cur.parentNode;
4632 }
4633
4634 al = ap.length;
4635 bl = bp.length;
4636
4637 // Start walking down the tree looking for a discrepancy
4638 for ( var i = 0; i < al && i < bl; i++ ) {
4639 if ( ap[i] !== bp[i] ) {
4640 return siblingCheck( ap[i], bp[i] );
4641 }
4642 }
4643
4644 // We ended someplace up the tree so do a sibling check
4645 return i === al ?
4646 siblingCheck( a, bp[i], -1 ) :
4647 siblingCheck( ap[i], b, 1 );
4648 };
4649
4650 // Always assume the presence of duplicates if sort doesn't
4651 // pass them to our comparison function (as in Google Chrome).
4652 [0, 0].sort( sortOrder );
4653 baseHasDuplicate = !hasDuplicate;
4654
4655 // Document sorting and removing duplicates
4656 Sizzle.uniqueSort = function( results ) {
4657 var elem,
4658 duplicates = [],
4659 i = 1,
4660 j = 0;
4661
4662 hasDuplicate = baseHasDuplicate;
4663 results.sort( sortOrder );
4664
4665 if ( hasDuplicate ) {
4666 for ( ; (elem = results[i]); i++ ) {
4667 if ( elem === results[ i - 1 ] ) {
4668 j = duplicates.push( i );
4669 }
4670 }
4671 while ( j-- ) {
4672 results.splice( duplicates[ j ], 1 );
4673 }
4674 }
4675
4676 return results;
4677 };
4678
4679 Sizzle.error = function( msg ) {
4680 throw new Error( "Syntax error, unrecognized expression: " + msg );
4681 };
4682
4683 function tokenize( selector, parseOnly ) {
4684 var matched, match, tokens, type,
4685 soFar, groups, preFilters,
4686 cached = tokenCache[ expando ][ selector + " " ];
4687
4688 if ( cached ) {
4689 return parseOnly ? 0 : cached.slice( 0 );
4690 }
4691
4692 soFar = selector;
4693 groups = [];
4694 preFilters = Expr.preFilter;
4695
4696 while ( soFar ) {
4697
4698 // Comma and first run
4699 if ( !matched || (match = rcomma.exec( soFar )) ) {
4700 if ( match ) {
4701 // Don't consume trailing commas as valid
4702 soFar = soFar.slice( match[0].length ) || soFar;
4703 }
4704 groups.push( tokens = [] );
4705 }
4706
4707 matched = false;
4708
4709 // Combinators
4710 if ( (match = rcombinators.exec( soFar )) ) {
4711 tokens.push( matched = new Token( match.shift() ) );
4712 soFar = soFar.slice( matched.length );
4713
4714 // Cast descendant combinators to space
4715 matched.type = match[0].replace( rtrim, " " );
4716 }
4717
4718 // Filters
4719 for ( type in Expr.filter ) {
4720 if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
4721 (match = preFilters[ type ]( match ))) ) {
4722
4723 tokens.push( matched = new Token( match.shift() ) );
4724 soFar = soFar.slice( matched.length );
4725 matched.type = type;
4726 matched.matches = match;
4727 }
4728 }
4729
4730 if ( !matched ) {
4731 break;
4732 }
4733 }
4734
4735 // Return the length of the invalid excess
4736 // if we're just parsing
4737 // Otherwise, throw an error or return tokens
4738 return parseOnly ?
4739 soFar.length :
4740 soFar ?
4741 Sizzle.error( selector ) :
4742 // Cache the tokens
4743 tokenCache( selector, groups ).slice( 0 );
4744 }
4745
4746 function addCombinator( matcher, combinator, base ) {
4747 var dir = combinator.dir,
4748 checkNonElements = base && combinator.dir === "parentNode",
4749 doneName = done++;
4750
4751 return combinator.first ?
4752 // Check against closest ancestor/preceding element
4753 function( elem, context, xml ) {
4754 while ( (elem = elem[ dir ]) ) {
4755 if ( checkNonElements || elem.nodeType === 1 ) {
4756 return matcher( elem, context, xml );
4757 }
4758 }
4759 } :
4760
4761 // Check against all ancestor/preceding elements
4762 function( elem, context, xml ) {
4763 // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching
4764 if ( !xml ) {
4765 var cache,
4766 dirkey = dirruns + " " + doneName + " ",
4767 cachedkey = dirkey + cachedruns;
4768 while ( (elem = elem[ dir ]) ) {
4769 if ( checkNonElements || elem.nodeType === 1 ) {
4770 if ( (cache = elem[ expando ]) === cachedkey ) {
4771 return elem.sizset;
4772 } else if ( typeof cache === "string" && cache.indexOf(dirkey) === 0 ) {
4773 if ( elem.sizset ) {
4774 return elem;
4775 }
4776 } else {
4777 elem[ expando ] = cachedkey;
4778 if ( matcher( elem, context, xml ) ) {
4779 elem.sizset = true;
4780 return elem;
4781 }
4782 elem.sizset = false;
4783 }
4784 }
4785 }
4786 } else {
4787 while ( (elem = elem[ dir ]) ) {
4788 if ( checkNonElements || elem.nodeType === 1 ) {
4789 if ( matcher( elem, context, xml ) ) {
4790 return elem;
4791 }
4792 }
4793 }
4794 }
4795 };
4796 }
4797
4798 function elementMatcher( matchers ) {
4799 return matchers.length > 1 ?
4800 function( elem, context, xml ) {
4801 var i = matchers.length;
4802 while ( i-- ) {
4803 if ( !matchers[i]( elem, context, xml ) ) {
4804 return false;
4805 }
4806 }
4807 return true;
4808 } :
4809 matchers[0];
4810 }
4811
4812 function condense( unmatched, map, filter, context, xml ) {
4813 var elem,
4814 newUnmatched = [],
4815 i = 0,
4816 len = unmatched.length,
4817 mapped = map != null;
4818
4819 for ( ; i < len; i++ ) {
4820 if ( (elem = unmatched[i]) ) {
4821 if ( !filter || filter( elem, context, xml ) ) {
4822 newUnmatched.push( elem );
4823 if ( mapped ) {
4824 map.push( i );
4825 }
4826 }
4827 }
4828 }
4829
4830 return newUnmatched;
4831 }
4832
4833 function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
4834 if ( postFilter && !postFilter[ expando ] ) {
4835 postFilter = setMatcher( postFilter );
4836 }
4837 if ( postFinder && !postFinder[ expando ] ) {
4838 postFinder = setMatcher( postFinder, postSelector );
4839 }
4840 return markFunction(function( seed, results, context, xml ) {
4841 var temp, i, elem,
4842 preMap = [],
4843 postMap = [],
4844 preexisting = results.length,
4845
4846 // Get initial elements from seed or context
4847 elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
4848
4849 // Prefilter to get matcher input, preserving a map for seed-results synchronization
4850 matcherIn = preFilter && ( seed || !selector ) ?
4851 condense( elems, preMap, preFilter, context, xml ) :
4852 elems,
4853
4854 matcherOut = matcher ?
4855 // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
4856 postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
4857
4858 // ...intermediate processing is necessary
4859 [] :
4860
4861 // ...otherwise use results directly
4862 results :
4863 matcherIn;
4864
4865 // Find primary matches
4866 if ( matcher ) {
4867 matcher( matcherIn, matcherOut, context, xml );
4868 }
4869
4870 // Apply postFilter
4871 if ( postFilter ) {
4872 temp = condense( matcherOut, postMap );
4873 postFilter( temp, [], context, xml );
4874
4875 // Un-match failing elements by moving them back to matcherIn
4876 i = temp.length;
4877 while ( i-- ) {
4878 if ( (elem = temp[i]) ) {
4879 matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
4880 }
4881 }
4882 }
4883
4884 if ( seed ) {
4885 if ( postFinder || preFilter ) {
4886 if ( postFinder ) {
4887 // Get the final matcherOut by condensing this intermediate into postFinder contexts
4888 temp = [];
4889 i = matcherOut.length;
4890 while ( i-- ) {
4891 if ( (elem = matcherOut[i]) ) {
4892 // Restore matcherIn since elem is not yet a final match
4893 temp.push( (matcherIn[i] = elem) );
4894 }
4895 }
4896 postFinder( null, (matcherOut = []), temp, xml );
4897 }
4898
4899 // Move matched elements from seed to results to keep them synchronized
4900 i = matcherOut.length;
4901 while ( i-- ) {
4902 if ( (elem = matcherOut[i]) &&
4903 (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) {
4904
4905 seed[temp] = !(results[temp] = elem);
4906 }
4907 }
4908 }
4909
4910 // Add elements to results, through postFinder if defined
4911 } else {
4912 matcherOut = condense(
4913 matcherOut === results ?
4914 matcherOut.splice( preexisting, matcherOut.length ) :
4915 matcherOut
4916 );
4917 if ( postFinder ) {
4918 postFinder( null, results, matcherOut, xml );
4919 } else {
4920 push.apply( results, matcherOut );
4921 }
4922 }
4923 });
4924 }
4925
4926 function matcherFromTokens( tokens ) {
4927 var checkContext, matcher, j,
4928 len = tokens.length,
4929 leadingRelative = Expr.relative[ tokens[0].type ],
4930 implicitRelative = leadingRelative || Expr.relative[" "],
4931 i = leadingRelative ? 1 : 0,
4932
4933 // The foundational matcher ensures that elements are reachable from top-level context(s)
4934 matchContext = addCombinator( function( elem ) {
4935 return elem === checkContext;
4936 }, implicitRelative, true ),
4937 matchAnyContext = addCombinator( function( elem ) {
4938 return indexOf.call( checkContext, elem ) > -1;
4939 }, implicitRelative, true ),
4940 matchers = [ function( elem, context, xml ) {
4941 return ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
4942 (checkContext = context).nodeType ?
4943 matchContext( elem, context, xml ) :
4944 matchAnyContext( elem, context, xml ) );
4945 } ];
4946
4947 for ( ; i < len; i++ ) {
4948 if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
4949 matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ];
4950 } else {
4951 matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
4952
4953 // Return special upon seeing a positional matcher
4954 if ( matcher[ expando ] ) {
4955 // Find the next relative operator (if any) for proper handling
4956 j = ++i;
4957 for ( ; j < len; j++ ) {
4958 if ( Expr.relative[ tokens[j].type ] ) {
4959 break;
4960 }
4961 }
4962 return setMatcher(
4963 i > 1 && elementMatcher( matchers ),
4964 i > 1 && tokens.slice( 0, i - 1 ).join("").replace( rtrim, "$1" ),
4965 matcher,
4966 i < j && matcherFromTokens( tokens.slice( i, j ) ),
4967 j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
4968 j < len && tokens.join("")
4969 );
4970 }
4971 matchers.push( matcher );
4972 }
4973 }
4974
4975 return elementMatcher( matchers );
4976 }
4977
4978 function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
4979 var bySet = setMatchers.length > 0,
4980 byElement = elementMatchers.length > 0,
4981 superMatcher = function( seed, context, xml, results, expandContext ) {
4982 var elem, j, matcher,
4983 setMatched = [],
4984 matchedCount = 0,
4985 i = "0",
4986 unmatched = seed && [],
4987 outermost = expandContext != null,
4988 contextBackup = outermostContext,
4989 // We must always have either seed elements or context
4990 elems = seed || byElement && Expr.find["TAG"]( "*", expandContext && context.parentNode || context ),
4991 // Nested matchers should use non-integer dirruns
4992 dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.E);
4993
4994 if ( outermost ) {
4995 outermostContext = context !== document && context;
4996 cachedruns = superMatcher.el;
4997 }
4998
4999 // Add elements passing elementMatchers directly to results
5000 for ( ; (elem = elems[i]) != null; i++ ) {
5001 if ( byElement && elem ) {
5002 for ( j = 0; (matcher = elementMatchers[j]); j++ ) {
5003 if ( matcher( elem, context, xml ) ) {
5004 results.push( elem );
5005 break;
5006 }
5007 }
5008 if ( outermost ) {
5009 dirruns = dirrunsUnique;
5010 cachedruns = ++superMatcher.el;
5011 }
5012 }
5013
5014 // Track unmatched elements for set filters
5015 if ( bySet ) {
5016 // They will have gone through all possible matchers
5017 if ( (elem = !matcher && elem) ) {
5018 matchedCount--;
5019 }
5020
5021 // Lengthen the array for every element, matched or not
5022 if ( seed ) {
5023 unmatched.push( elem );
5024 }
5025 }
5026 }
5027
5028 // Apply set filters to unmatched elements
5029 matchedCount += i;
5030 if ( bySet && i !== matchedCount ) {
5031 for ( j = 0; (matcher = setMatchers[j]); j++ ) {
5032 matcher( unmatched, setMatched, context, xml );
5033 }
5034
5035 if ( seed ) {
5036 // Reintegrate element matches to eliminate the need for sorting
5037 if ( matchedCount > 0 ) {
5038 while ( i-- ) {
5039 if ( !(unmatched[i] || setMatched[i]) ) {
5040 setMatched[i] = pop.call( results );
5041 }
5042 }
5043 }
5044
5045 // Discard index placeholder values to get only actual matches
5046 setMatched = condense( setMatched );
5047 }
5048
5049 // Add matches to results
5050 push.apply( results, setMatched );
5051
5052 // Seedless set matches succeeding multiple successful matchers stipulate sorting
5053 if ( outermost && !seed && setMatched.length > 0 &&
5054 ( matchedCount + setMatchers.length ) > 1 ) {
5055
5056 Sizzle.uniqueSort( results );
5057 }
5058 }
5059
5060 // Override manipulation of globals by nested matchers
5061 if ( outermost ) {
5062 dirruns = dirrunsUnique;
5063 outermostContext = contextBackup;
5064 }
5065
5066 return unmatched;
5067 };
5068
5069 superMatcher.el = 0;
5070 return bySet ?
5071 markFunction( superMatcher ) :
5072 superMatcher;
5073 }
5074
5075 compile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) {
5076 var i,
5077 setMatchers = [],
5078 elementMatchers = [],
5079 cached = compilerCache[ expando ][ selector + " " ];
5080
5081 if ( !cached ) {
5082 // Generate a function of recursive functions that can be used to check each element
5083 if ( !group ) {
5084 group = tokenize( selector );
5085 }
5086 i = group.length;
5087 while ( i-- ) {
5088 cached = matcherFromTokens( group[i] );
5089 if ( cached[ expando ] ) {
5090 setMatchers.push( cached );
5091 } else {
5092 elementMatchers.push( cached );
5093 }
5094 }
5095
5096 // Cache the compiled function
5097 cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
5098 }
5099 return cached;
5100 };
5101
5102 function multipleContexts( selector, contexts, results ) {
5103 var i = 0,
5104 len = contexts.length;
5105 for ( ; i < len; i++ ) {
5106 Sizzle( selector, contexts[i], results );
5107 }
5108 return results;
5109 }
5110
5111 function select( selector, context, results, seed, xml ) {
5112 var i, tokens, token, type, find,
5113 match = tokenize( selector ),
5114 j = match.length;
5115
5116 if ( !seed ) {
5117 // Try to minimize operations if there is only one group
5118 if ( match.length === 1 ) {
5119
5120 // Take a shortcut and set the context if the root selector is an ID
5121 tokens = match[0] = match[0].slice( 0 );
5122 if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
5123 context.nodeType === 9 && !xml &&
5124 Expr.relative[ tokens[1].type ] ) {
5125
5126 context = Expr.find["ID"]( token.matches[0].replace( rbackslash, "" ), context, xml )[0];
5127 if ( !context ) {
5128 return results;
5129 }
5130
5131 selector = selector.slice( tokens.shift().length );
5132 }
5133
5134 // Fetch a seed set for right-to-left matching
5135 for ( i = matchExpr["POS"].test( selector ) ? -1 : tokens.length - 1; i >= 0; i-- ) {
5136 token = tokens[i];
5137
5138 // Abort if we hit a combinator
5139 if ( Expr.relative[ (type = token.type) ] ) {
5140 break;
5141 }
5142 if ( (find = Expr.find[ type ]) ) {
5143 // Search, expanding context for leading sibling combinators
5144 if ( (seed = find(
5145 token.matches[0].replace( rbackslash, "" ),
5146 rsibling.test( tokens[0].type ) && context.parentNode || context,
5147 xml
5148 )) ) {
5149
5150 // If seed is empty or no tokens remain, we can return early
5151 tokens.splice( i, 1 );
5152 selector = seed.length && tokens.join("");
5153 if ( !selector ) {
5154 push.apply( results, slice.call( seed, 0 ) );
5155 return results;
5156 }
5157
5158 break;
5159 }
5160 }
5161 }
5162 }
5163 }
5164
5165 // Compile and execute a filtering function
5166 // Provide `match` to avoid retokenization if we modified the selector above
5167 compile( selector, match )(
5168 seed,
5169 context,
5170 xml,
5171 results,
5172 rsibling.test( selector )
5173 );
5174 return results;
5175 }
5176
5177 if ( document.querySelectorAll ) {
5178 (function() {
5179 var disconnectedMatch,
5180 oldSelect = select,
5181 rescape = /'|\\/g,
5182 rattributeQuotes = /\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,
5183
5184 // qSa(:focus) reports false when true (Chrome 21), no need to also add to buggyMatches since matches checks buggyQSA
5185 // A support test would require too much code (would include document ready)
5186 rbuggyQSA = [ ":focus" ],
5187
5188 // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
5189 // A support test would require too much code (would include document ready)
5190 // just skip matchesSelector for :active
5191 rbuggyMatches = [ ":active" ],
5192 matches = docElem.matchesSelector ||
5193 docElem.mozMatchesSelector ||
5194 docElem.webkitMatchesSelector ||
5195 docElem.oMatchesSelector ||
5196 docElem.msMatchesSelector;
5197
5198 // Build QSA regex
5199 // Regex strategy adopted from Diego Perini
5200 assert(function( div ) {
5201 // Select is set to empty string on purpose
5202 // This is to test IE's treatment of not explictly
5203 // setting a boolean content attribute,
5204 // since its presence should be enough
5205 // http://bugs.jquery.com/ticket/12359
5206 div.innerHTML = "<select><option selected=''></option></select>";
5207
5208 // IE8 - Some boolean attributes are not treated correctly
5209 if ( !div.querySelectorAll("[selected]").length ) {
5210 rbuggyQSA.push( "\\[" + whitespace + "*(?:checked|disabled|ismap|multiple|readonly|selected|value)" );
5211 }
5212
5213 // Webkit/Opera - :checked should return selected option elements
5214 // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
5215 // IE8 throws error here (do not put tests after this one)
5216 if ( !div.querySelectorAll(":checked").length ) {
5217 rbuggyQSA.push(":checked");
5218 }
5219 });
5220
5221 assert(function( div ) {
5222
5223 // Opera 10-12/IE9 - ^= $= *= and empty values
5224 // Should not select anything
5225 div.innerHTML = "<p test=''></p>";
5226 if ( div.querySelectorAll("[test^='']").length ) {
5227 rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:\"\"|'')" );
5228 }
5229
5230 // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
5231 // IE8 throws error here (do not put tests after this one)
5232 div.innerHTML = "<input type='hidden'/>";
5233 if ( !div.querySelectorAll(":enabled").length ) {
5234 rbuggyQSA.push(":enabled", ":disabled");
5235 }
5236 });
5237
5238 // rbuggyQSA always contains :focus, so no need for a length check
5239 rbuggyQSA = /* rbuggyQSA.length && */ new RegExp( rbuggyQSA.join("|") );
5240
5241 select = function( selector, context, results, seed, xml ) {
5242 // Only use querySelectorAll when not filtering,
5243 // when this is not xml,
5244 // and when no QSA bugs apply
5245 if ( !seed && !xml && !rbuggyQSA.test( selector ) ) {
5246 var groups, i,
5247 old = true,
5248 nid = expando,
5249 newContext = context,
5250 newSelector = context.nodeType === 9 && selector;
5251
5252 // qSA works strangely on Element-rooted queries
5253 // We can work around this by specifying an extra ID on the root
5254 // and working up from there (Thanks to Andrew Dupont for the technique)
5255 // IE 8 doesn't work on object elements
5256 if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
5257 groups = tokenize( selector );
5258
5259 if ( (old = context.getAttribute("id")) ) {
5260 nid = old.replace( rescape, "\\$&" );
5261 } else {
5262 context.setAttribute( "id", nid );
5263 }
5264 nid = "[id='" + nid + "'] ";
5265
5266 i = groups.length;
5267 while ( i-- ) {
5268 groups[i] = nid + groups[i].join("");
5269 }
5270 newContext = rsibling.test( selector ) && context.parentNode || context;
5271 newSelector = groups.join(",");
5272 }
5273
5274 if ( newSelector ) {
5275 try {
5276 push.apply( results, slice.call( newContext.querySelectorAll(
5277 newSelector
5278 ), 0 ) );
5279 return results;
5280 } catch(qsaError) {
5281 } finally {
5282 if ( !old ) {
5283 context.removeAttribute("id");
5284 }
5285 }
5286 }
5287 }
5288
5289 return oldSelect( selector, context, results, seed, xml );
5290 };
5291
5292 if ( matches ) {
5293 assert(function( div ) {
5294 // Check to see if it's possible to do matchesSelector
5295 // on a disconnected node (IE 9)
5296 disconnectedMatch = matches.call( div, "div" );
5297
5298 // This should fail with an exception
5299 // Gecko does not error, returns false instead
5300 try {
5301 matches.call( div, "[test!='']:sizzle" );
5302 rbuggyMatches.push( "!=", pseudos );
5303 } catch ( e ) {}
5304 });
5305
5306 // rbuggyMatches always contains :active and :focus, so no need for a length check
5307 rbuggyMatches = /* rbuggyMatches.length && */ new RegExp( rbuggyMatches.join("|") );
5308
5309 Sizzle.matchesSelector = function( elem, expr ) {
5310 // Make sure that attribute selectors are quoted
5311 expr = expr.replace( rattributeQuotes, "='$1']" );
5312
5313 // rbuggyMatches always contains :active, so no need for an existence check
5314 if ( !isXML( elem ) && !rbuggyMatches.test( expr ) && !rbuggyQSA.test( expr ) ) {
5315 try {
5316 var ret = matches.call( elem, expr );
5317
5318 // IE 9's matchesSelector returns false on disconnected nodes
5319 if ( ret || disconnectedMatch ||
5320 // As well, disconnected nodes are said to be in a document
5321 // fragment in IE 9
5322 elem.document && elem.document.nodeType !== 11 ) {
5323 return ret;
5324 }
5325 } catch(e) {}
5326 }
5327
5328 return Sizzle( expr, null, null, [ elem ] ).length > 0;
5329 };
5330 }
5331 })();
5332 }
5333
5334 // Deprecated
5335 Expr.pseudos["nth"] = Expr.pseudos["eq"];
5336
5337 // Back-compat
5338 function setFilters() {}
5339 Expr.filters = setFilters.prototype = Expr.pseudos;
5340 Expr.setFilters = new setFilters();
5341
5342 // Override sizzle attribute retrieval
5343 Sizzle.attr = jQuery.attr;
5344 jQuery.find = Sizzle;
5345 jQuery.expr = Sizzle.selectors;
5346 jQuery.expr[":"] = jQuery.expr.pseudos;
5347 jQuery.unique = Sizzle.uniqueSort;
5348 jQuery.text = Sizzle.getText;
5349 jQuery.isXMLDoc = Sizzle.isXML;
5350 jQuery.contains = Sizzle.contains;
5351
5352
5353 })( window );
5354 var runtil = /Until$/,
5355 rparentsprev = /^(?:parents|prev(?:Until|All))/,
5356 isSimple = /^.[^:#\[\.,]*$/,
5357 rneedsContext = jQuery.expr.match.needsContext,
5358 // methods guaranteed to produce a unique set when starting from a unique set
5359 guaranteedUnique = {
5360 children: true,
5361 contents: true,
5362 next: true,
5363 prev: true
5364 };
5365
5366 jQuery.fn.extend({
5367 find: function( selector ) {
5368 var i, l, length, n, r, ret,
5369 self = this;
5370
5371 if ( typeof selector !== "string" ) {
5372 return jQuery( selector ).filter(function() {
5373 for ( i = 0, l = self.length; i < l; i++ ) {
5374 if ( jQuery.contains( self[ i ], this ) ) {
5375 return true;
5376 }
5377 }
5378 });
5379 }
5380
5381 ret = this.pushStack( "", "find", selector );
5382
5383 for ( i = 0, l = this.length; i < l; i++ ) {
5384 length = ret.length;
5385 jQuery.find( selector, this[i], ret );
5386
5387 if ( i > 0 ) {
5388 // Make sure that the results are unique
5389 for ( n = length; n < ret.length; n++ ) {
5390 for ( r = 0; r < length; r++ ) {
5391 if ( ret[r] === ret[n] ) {
5392 ret.splice(n--, 1);
5393 break;
5394 }
5395 }
5396 }
5397 }
5398 }
5399
5400 return ret;
5401 },
5402
5403 has: function( target ) {
5404 var i,
5405 targets = jQuery( target, this ),
5406 len = targets.length;
5407
5408 return this.filter(function() {
5409 for ( i = 0; i < len; i++ ) {
5410 if ( jQuery.contains( this, targets[i] ) ) {
5411 return true;
5412 }
5413 }
5414 });
5415 },
5416
5417 not: function( selector ) {
5418 return this.pushStack( winnow(this, selector, false), "not", selector);
5419 },
5420
5421 filter: function( selector ) {
5422 return this.pushStack( winnow(this, selector, true), "filter", selector );
5423 },
5424
5425 is: function( selector ) {
5426 return !!selector && (
5427 typeof selector === "string" ?
5428 // If this is a positional/relative selector, check membership in the returned set
5429 // so $("p:first").is("p:last") won't return true for a doc with two "p".
5430 rneedsContext.test( selector ) ?
5431 jQuery( selector, this.context ).index( this[0] ) >= 0 :
5432 jQuery.filter( selector, this ).length > 0 :
5433 this.filter( selector ).length > 0 );
5434 },
5435
5436 closest: function( selectors, context ) {
5437 var cur,
5438 i = 0,
5439 l = this.length,
5440 ret = [],
5441 pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
5442 jQuery( selectors, context || this.context ) :
5443 0;
5444
5445 for ( ; i < l; i++ ) {
5446 cur = this[i];
5447
5448 while ( cur && cur.ownerDocument && cur !== context && cur.nodeType !== 11 ) {
5449 if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {
5450 ret.push( cur );
5451 break;
5452 }
5453 cur = cur.parentNode;
5454 }
5455 }
5456
5457 ret = ret.length > 1 ? jQuery.unique( ret ) : ret;
5458
5459 return this.pushStack( ret, "closest", selectors );
5460 },
5461
5462 // Determine the position of an element within
5463 // the matched set of elements
5464 index: function( elem ) {
5465
5466 // No argument, return index in parent
5467 if ( !elem ) {
5468 return ( this[0] && this[0].parentNode ) ? this.prevAll().length : -1;
5469 }
5470
5471 // index in selector
5472 if ( typeof elem === "string" ) {
5473 return jQuery.inArray( this[0], jQuery( elem ) );
5474 }
5475
5476 // Locate the position of the desired element
5477 return jQuery.inArray(
5478 // If it receives a jQuery object, the first element is used
5479 elem.jquery ? elem[0] : elem, this );
5480 },
5481
5482 add: function( selector, context ) {
5483 var set = typeof selector === "string" ?
5484 jQuery( selector, context ) :
5485 jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ),
5486 all = jQuery.merge( this.get(), set );
5487
5488 return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?
5489 all :
5490 jQuery.unique( all ) );
5491 },
5492
5493 addBack: function( selector ) {
5494 return this.add( selector == null ?
5495 this.prevObject : this.prevObject.filter(selector)
5496 );
5497 }
5498 });
5499
5500 jQuery.fn.andSelf = jQuery.fn.addBack;
5501
5502 // A painfully simple check to see if an element is disconnected
5503 // from a document (should be improved, where feasible).
5504 function isDisconnected( node ) {
5505 return !node || !node.parentNode || node.parentNode.nodeType === 11;
5506 }
5507
5508 function sibling( cur, dir ) {
5509 do {
5510 cur = cur[ dir ];
5511 } while ( cur && cur.nodeType !== 1 );
5512
5513 return cur;
5514 }
5515
5516 jQuery.each({
5517 parent: function( elem ) {
5518 var parent = elem.parentNode;
5519 return parent && parent.nodeType !== 11 ? parent : null;
5520 },
5521 parents: function( elem ) {
5522 return jQuery.dir( elem, "parentNode" );
5523 },
5524 parentsUntil: function( elem, i, until ) {
5525 return jQuery.dir( elem, "parentNode", until );
5526 },
5527 next: function( elem ) {
5528 return sibling( elem, "nextSibling" );
5529 },
5530 prev: function( elem ) {
5531 return sibling( elem, "previousSibling" );
5532 },
5533 nextAll: function( elem ) {
5534 return jQuery.dir( elem, "nextSibling" );
5535 },
5536 prevAll: function( elem ) {
5537 return jQuery.dir( elem, "previousSibling" );
5538 },
5539 nextUntil: function( elem, i, until ) {
5540 return jQuery.dir( elem, "nextSibling", until );
5541 },
5542 prevUntil: function( elem, i, until ) {
5543 return jQuery.dir( elem, "previousSibling", until );
5544 },
5545 siblings: function( elem ) {
5546 return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );
5547 },
5548 children: function( elem ) {
5549 return jQuery.sibling( elem.firstChild );
5550 },
5551 contents: function( elem ) {
5552 return jQuery.nodeName( elem, "iframe" ) ?
5553 elem.contentDocument || elem.contentWindow.document :
5554 jQuery.merge( [], elem.childNodes );
5555 }
5556 }, function( name, fn ) {
5557 jQuery.fn[ name ] = function( until, selector ) {
5558 var ret = jQuery.map( this, fn, until );
5559
5560 if ( !runtil.test( name ) ) {
5561 selector = until;
5562 }
5563
5564 if ( selector && typeof selector === "string" ) {
5565 ret = jQuery.filter( selector, ret );
5566 }
5567
5568 ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret;
5569
5570 if ( this.length > 1 && rparentsprev.test( name ) ) {
5571 ret = ret.reverse();
5572 }
5573
5574 return this.pushStack( ret, name, core_slice.call( arguments ).join(",") );
5575 };
5576 });
5577
5578 jQuery.extend({
5579 filter: function( expr, elems, not ) {
5580 if ( not ) {
5581 expr = ":not(" + expr + ")";
5582 }
5583
5584 return elems.length === 1 ?
5585 jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :
5586 jQuery.find.matches(expr, elems);
5587 },
5588
5589 dir: function( elem, dir, until ) {
5590 var matched = [],
5591 cur = elem[ dir ];
5592
5593 while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
5594 if ( cur.nodeType === 1 ) {
5595 matched.push( cur );
5596 }
5597 cur = cur[dir];
5598 }
5599 return matched;
5600 },
5601
5602 sibling: function( n, elem ) {
5603 var r = [];
5604
5605 for ( ; n; n = n.nextSibling ) {
5606 if ( n.nodeType === 1 && n !== elem ) {
5607 r.push( n );
5608 }
5609 }
5610
5611 return r;
5612 }
5613 });
5614
5615 // Implement the identical functionality for filter and not
5616 function winnow( elements, qualifier, keep ) {
5617
5618 // Can't pass null or undefined to indexOf in Firefox 4
5619 // Set to 0 to skip string check
5620 qualifier = qualifier || 0;
5621
5622 if ( jQuery.isFunction( qualifier ) ) {
5623 return jQuery.grep(elements, function( elem, i ) {
5624 var retVal = !!qualifier.call( elem, i, elem );
5625 return retVal === keep;
5626 });
5627
5628 } else if ( qualifier.nodeType ) {
5629 return jQuery.grep(elements, function( elem, i ) {
5630 return ( elem === qualifier ) === keep;
5631 });
5632
5633 } else if ( typeof qualifier === "string" ) {
5634 var filtered = jQuery.grep(elements, function( elem ) {
5635 return elem.nodeType === 1;
5636 });
5637
5638 if ( isSimple.test( qualifier ) ) {
5639 return jQuery.filter(qualifier, filtered, !keep);
5640 } else {
5641 qualifier = jQuery.filter( qualifier, filtered );
5642 }
5643 }
5644
5645 return jQuery.grep(elements, function( elem, i ) {
5646 return ( jQuery.inArray( elem, qualifier ) >= 0 ) === keep;
5647 });
5648 }
5649 function createSafeFragment( document ) {
5650 var list = nodeNames.split( "|" ),
5651 safeFrag = document.createDocumentFragment();
5652
5653 if ( safeFrag.createElement ) {
5654 while ( list.length ) {
5655 safeFrag.createElement(
5656 list.pop()
5657 );
5658 }
5659 }
5660 return safeFrag;
5661 }
5662
5663 var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" +
5664 "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",
5665 rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g,
5666 rleadingWhitespace = /^\s+/,
5667 rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,
5668 rtagName = /<([\w:]+)/,
5669 rtbody = /<tbody/i,
5670 rhtml = /<|&#?\w+;/,
5671 rnoInnerhtml = /<(?:script|style|link)/i,
5672 rnocache = /<(?:script|object|embed|option|style)/i,
5673 rnoshimcache = new RegExp("<(?:" + nodeNames + ")[\\s/>]", "i"),
5674 rcheckableType = /^(?:checkbox|radio)$/,
5675 // checked="checked" or checked
5676 rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
5677 rscriptType = /\/(java|ecma)script/i,
5678 rcleanScript = /^\s*<!(?:\[CDATA\[|\-\-)|[\]\-]{2}>\s*$/g,
5679 wrapMap = {
5680 option: [ 1, "<select multiple='multiple'>", "</select>" ],
5681 legend: [ 1, "<fieldset>", "</fieldset>" ],
5682 thead: [ 1, "<table>", "</table>" ],
5683 tr: [ 2, "<table><tbody>", "</tbody></table>" ],
5684 td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
5685 col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
5686 area: [ 1, "<map>", "</map>" ],
5687 _default: [ 0, "", "" ]
5688 },
5689 safeFragment = createSafeFragment( document ),
5690 fragmentDiv = safeFragment.appendChild( document.createElement("div") );
5691
5692 wrapMap.optgroup = wrapMap.option;
5693 wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
5694 wrapMap.th = wrapMap.td;
5695
5696 // IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags,
5697 // unless wrapped in a div with non-breaking characters in front of it.
5698 if ( !jQuery.support.htmlSerialize ) {
5699 wrapMap._default = [ 1, "X<div>", "</div>" ];
5700 }
5701
5702 jQuery.fn.extend({
5703 text: function( value ) {
5704 return jQuery.access( this, function( value ) {
5705 return value === undefined ?
5706 jQuery.text( this ) :
5707 this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) );
5708 }, null, value, arguments.length );
5709 },
5710
5711 wrapAll: function( html ) {
5712 if ( jQuery.isFunction( html ) ) {
5713 return this.each(function(i) {
5714 jQuery(this).wrapAll( html.call(this, i) );
5715 });
5716 }
5717
5718 if ( this[0] ) {
5719 // The elements to wrap the target around
5720 var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
5721
5722 if ( this[0].parentNode ) {
5723 wrap.insertBefore( this[0] );
5724 }
5725
5726 wrap.map(function() {
5727 var elem = this;
5728
5729 while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
5730 elem = elem.firstChild;
5731 }
5732
5733 return elem;
5734 }).append( this );
5735 }
5736
5737 return this;
5738 },
5739
5740 wrapInner: function( html ) {
5741 if ( jQuery.isFunction( html ) ) {
5742 return this.each(function(i) {
5743 jQuery(this).wrapInner( html.call(this, i) );
5744 });
5745 }
5746
5747 return this.each(function() {
5748 var self = jQuery( this ),
5749 contents = self.contents();
5750
5751 if ( contents.length ) {
5752 contents.wrapAll( html );
5753
5754 } else {
5755 self.append( html );
5756 }
5757 });
5758 },
5759
5760 wrap: function( html ) {
5761 var isFunction = jQuery.isFunction( html );
5762
5763 return this.each(function(i) {
5764 jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html );
5765 });
5766 },
5767
5768 unwrap: function() {
5769 return this.parent().each(function() {
5770 if ( !jQuery.nodeName( this, "body" ) ) {
5771 jQuery( this ).replaceWith( this.childNodes );
5772 }
5773 }).end();
5774 },
5775
5776 append: function() {
5777 return this.domManip(arguments, true, function( elem ) {
5778 if ( this.nodeType === 1 || this.nodeType === 11 ) {
5779 this.appendChild( elem );
5780 }
5781 });
5782 },
5783
5784 prepend: function() {
5785 return this.domManip(arguments, true, function( elem ) {
5786 if ( this.nodeType === 1 || this.nodeType === 11 ) {
5787 this.insertBefore( elem, this.firstChild );
5788 }
5789 });
5790 },
5791
5792 before: function() {
5793 if ( !isDisconnected( this[0] ) ) {
5794 return this.domManip(arguments, false, function( elem ) {
5795 this.parentNode.insertBefore( elem, this );
5796 });
5797 }
5798
5799 if ( arguments.length ) {
5800 var set = jQuery.clean( arguments );
5801 return this.pushStack( jQuery.merge( set, this ), "before", this.selector );
5802 }
5803 },
5804
5805 after: function() {
5806 if ( !isDisconnected( this[0] ) ) {
5807 return this.domManip(arguments, false, function( elem ) {
5808 this.parentNode.insertBefore( elem, this.nextSibling );
5809 });
5810 }
5811
5812 if ( arguments.length ) {
5813 var set = jQuery.clean( arguments );
5814 return this.pushStack( jQuery.merge( this, set ), "after", this.selector );
5815 }
5816 },
5817
5818 // keepData is for internal use only--do not document
5819 remove: function( selector, keepData ) {
5820 var elem,
5821 i = 0;
5822
5823 for ( ; (elem = this[i]) != null; i++ ) {
5824 if ( !selector || jQuery.filter( selector, [ elem ] ).length ) {
5825 if ( !keepData && elem.nodeType === 1 ) {
5826 jQuery.cleanData( elem.getElementsByTagName("*") );
5827 jQuery.cleanData( [ elem ] );
5828 }
5829
5830 if ( elem.parentNode ) {
5831 elem.parentNode.removeChild( elem );
5832 }
5833 }
5834 }
5835
5836 return this;
5837 },
5838
5839 empty: function() {
5840 var elem,
5841 i = 0;
5842
5843 for ( ; (elem = this[i]) != null; i++ ) {
5844 // Remove element nodes and prevent memory leaks
5845 if ( elem.nodeType === 1 ) {
5846 jQuery.cleanData( elem.getElementsByTagName("*") );
5847 }
5848
5849 // Remove any remaining nodes
5850 while ( elem.firstChild ) {
5851 elem.removeChild( elem.firstChild );
5852 }
5853 }
5854
5855 return this;
5856 },
5857
5858 clone: function( dataAndEvents, deepDataAndEvents ) {
5859 dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
5860 deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
5861
5862 return this.map( function () {
5863 return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
5864 });
5865 },
5866
5867 html: function( value ) {
5868 return jQuery.access( this, function( value ) {
5869 var elem = this[0] || {},
5870 i = 0,
5871 l = this.length;
5872
5873 if ( value === undefined ) {
5874 return elem.nodeType === 1 ?
5875 elem.innerHTML.replace( rinlinejQuery, "" ) :
5876 undefined;
5877 }
5878
5879 // See if we can take a shortcut and just use innerHTML
5880 if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
5881 ( jQuery.support.htmlSerialize || !rnoshimcache.test( value ) ) &&
5882 ( jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value ) ) &&
5883 !wrapMap[ ( rtagName.exec( value ) || ["", ""] )[1].toLowerCase() ] ) {
5884
5885 value = value.replace( rxhtmlTag, "<$1></$2>" );
5886
5887 try {
5888 for (; i < l; i++ ) {
5889 // Remove element nodes and prevent memory leaks
5890 elem = this[i] || {};
5891 if ( elem.nodeType === 1 ) {
5892 jQuery.cleanData( elem.getElementsByTagName( "*" ) );
5893 elem.innerHTML = value;
5894 }
5895 }
5896
5897 elem = 0;
5898
5899 // If using innerHTML throws an exception, use the fallback method
5900 } catch(e) {}
5901 }
5902
5903 if ( elem ) {
5904 this.empty().append( value );
5905 }
5906 }, null, value, arguments.length );
5907 },
5908
5909 replaceWith: function( value ) {
5910 if ( !isDisconnected( this[0] ) ) {
5911 // Make sure that the elements are removed from the DOM before they are inserted
5912 // this can help fix replacing a parent with child elements
5913 if ( jQuery.isFunction( value ) ) {
5914 return this.each(function(i) {
5915 var self = jQuery(this), old = self.html();
5916 self.replaceWith( value.call( this, i, old ) );
5917 });
5918 }
5919
5920 if ( typeof value !== "string" ) {
5921 value = jQuery( value ).detach();
5922 }
5923
5924 return this.each(function() {
5925 var next = this.nextSibling,
5926 parent = this.parentNode;
5927
5928 jQuery( this ).remove();
5929
5930 if ( next ) {
5931 jQuery(next).before( value );
5932 } else {
5933 jQuery(parent).append( value );
5934 }
5935 });
5936 }
5937
5938 return this.length ?
5939 this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value ) :
5940 this;
5941 },
5942
5943 detach: function( selector ) {
5944 return this.remove( selector, true );
5945 },
5946
5947 domManip: function( args, table, callback ) {
5948
5949 // Flatten any nested arrays
5950 args = [].concat.apply( [], args );
5951
5952 var results, first, fragment, iNoClone,
5953 i = 0,
5954 value = args[0],
5955 scripts = [],
5956 l = this.length;
5957
5958 // We can't cloneNode fragments that contain checked, in WebKit
5959 if ( !jQuery.support.checkClone && l > 1 && typeof value === "string" && rchecked.test( value ) ) {
5960 return this.each(function() {
5961 jQuery(this).domManip( args, table, callback );
5962 });
5963 }
5964
5965 if ( jQuery.isFunction(value) ) {
5966 return this.each(function(i) {
5967 var self = jQuery(this);
5968 args[0] = value.call( this, i, table ? self.html() : undefined );
5969 self.domManip( args, table, callback );
5970 });
5971 }
5972
5973 if ( this[0] ) {
5974 results = jQuery.buildFragment( args, this, scripts );
5975 fragment = results.fragment;
5976 first = fragment.firstChild;
5977
5978 if ( fragment.childNodes.length === 1 ) {
5979 fragment = first;
5980 }
5981
5982 if ( first ) {
5983 table = table && jQuery.nodeName( first, "tr" );
5984
5985 // Use the original fragment for the last item instead of the first because it can end up
5986 // being emptied incorrectly in certain situations (#8070).
5987 // Fragments from the fragment cache must always be cloned and never used in place.
5988 for ( iNoClone = results.cacheable || l - 1; i < l; i++ ) {
5989 callback.call(
5990 table && jQuery.nodeName( this[i], "table" ) ?
5991 findOrAppend( this[i], "tbody" ) :
5992 this[i],
5993 i === iNoClone ?
5994 fragment :
5995 jQuery.clone( fragment, true, true )
5996 );
5997 }
5998 }
5999
6000 // Fix #11809: Avoid leaking memory
6001 fragment = first = null;
6002
6003 if ( scripts.length ) {
6004 jQuery.each( scripts, function( i, elem ) {
6005 if ( elem.src ) {
6006 if ( jQuery.ajax ) {
6007 jQuery.ajax({
6008 url: elem.src,
6009 type: "GET",
6010 dataType: "script",
6011 async: false,
6012 global: false,
6013 "throws": true
6014 });
6015 } else {
6016 jQuery.error("no ajax");
6017 }
6018 } else {
6019 jQuery.globalEval( ( elem.text || elem.textContent || elem.innerHTML || "" ).replace( rcleanScript, "" ) );
6020 }
6021
6022 if ( elem.parentNode ) {
6023 elem.parentNode.removeChild( elem );
6024 }
6025 });
6026 }
6027 }
6028
6029 return this;
6030 }
6031 });
6032
6033 function findOrAppend( elem, tag ) {
6034 return elem.getElementsByTagName( tag )[0] || elem.appendChild( elem.ownerDocument.createElement( tag ) );
6035 }
6036
6037 function cloneCopyEvent( src, dest ) {
6038
6039 if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {
6040 return;
6041 }
6042
6043 var type, i, l,
6044 oldData = jQuery._data( src ),
6045 curData = jQuery._data( dest, oldData ),
6046 events = oldData.events;
6047
6048 if ( events ) {
6049 delete curData.handle;
6050 curData.events = {};
6051
6052 for ( type in events ) {
6053 for ( i = 0, l = events[ type ].length; i < l; i++ ) {
6054 jQuery.event.add( dest, type, events[ type ][ i ] );
6055 }
6056 }
6057 }
6058
6059 // make the cloned public data object a copy from the original
6060 if ( curData.data ) {
6061 curData.data = jQuery.extend( {}, curData.data );
6062 }
6063 }
6064
6065 function cloneFixAttributes( src, dest ) {
6066 var nodeName;
6067
6068 // We do not need to do anything for non-Elements
6069 if ( dest.nodeType !== 1 ) {
6070 return;
6071 }
6072
6073 // clearAttributes removes the attributes, which we don't want,
6074 // but also removes the attachEvent events, which we *do* want
6075 if ( dest.clearAttributes ) {
6076 dest.clearAttributes();
6077 }
6078
6079 // mergeAttributes, in contrast, only merges back on the
6080 // original attributes, not the events
6081 if ( dest.mergeAttributes ) {
6082 dest.mergeAttributes( src );
6083 }
6084
6085 nodeName = dest.nodeName.toLowerCase();
6086
6087 if ( nodeName === "object" ) {
6088 // IE6-10 improperly clones children of object elements using classid.
6089 // IE10 throws NoModificationAllowedError if parent is null, #12132.
6090 if ( dest.parentNode ) {
6091 dest.outerHTML = src.outerHTML;
6092 }
6093
6094 // This path appears unavoidable for IE9. When cloning an object
6095 // element in IE9, the outerHTML strategy above is not sufficient.
6096 // If the src has innerHTML and the destination does not,
6097 // copy the src.innerHTML into the dest.innerHTML. #10324
6098 if ( jQuery.support.html5Clone && (src.innerHTML && !jQuery.trim(dest.innerHTML)) ) {
6099 dest.innerHTML = src.innerHTML;
6100 }
6101
6102 } else if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
6103 // IE6-8 fails to persist the checked state of a cloned checkbox
6104 // or radio button. Worse, IE6-7 fail to give the cloned element
6105 // a checked appearance if the defaultChecked value isn't also set
6106
6107 dest.defaultChecked = dest.checked = src.checked;
6108
6109 // IE6-7 get confused and end up setting the value of a cloned
6110 // checkbox/radio button to an empty string instead of "on"
6111 if ( dest.value !== src.value ) {
6112 dest.value = src.value;
6113 }
6114
6115 // IE6-8 fails to return the selected option to the default selected
6116 // state when cloning options
6117 } else if ( nodeName === "option" ) {
6118 dest.selected = src.defaultSelected;
6119
6120 // IE6-8 fails to set the defaultValue to the correct value when
6121 // cloning other types of input fields
6122 } else if ( nodeName === "input" || nodeName === "textarea" ) {
6123 dest.defaultValue = src.defaultValue;
6124
6125 // IE blanks contents when cloning scripts
6126 } else if ( nodeName === "script" && dest.text !== src.text ) {
6127 dest.text = src.text;
6128 }
6129
6130 // Event data gets referenced instead of copied if the expando
6131 // gets copied too
6132 dest.removeAttribute( jQuery.expando );
6133 }
6134
6135 jQuery.buildFragment = function( args, context, scripts ) {
6136 var fragment, cacheable, cachehit,
6137 first = args[ 0 ];
6138
6139 // Set context from what may come in as undefined or a jQuery collection or a node
6140 // Updated to fix #12266 where accessing context[0] could throw an exception in IE9/10 &
6141 // also doubles as fix for #8950 where plain objects caused createDocumentFragment exception
6142 context = context || document;
6143 context = !context.nodeType && context[0] || context;
6144 context = context.ownerDocument || context;
6145
6146 // Only cache "small" (1/2 KB) HTML strings that are associated with the main document
6147 // Cloning options loses the selected state, so don't cache them
6148 // IE 6 doesn't like it when you put <object> or <embed> elements in a fragment
6149 // Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache
6150 // Lastly, IE6,7,8 will not correctly reuse cached fragments that were created from unknown elems #10501
6151 if ( args.length === 1 && typeof first === "string" && first.length < 512 && context === document &&
6152 first.charAt(0) === "<" && !rnocache.test( first ) &&
6153 (jQuery.support.checkClone || !rchecked.test( first )) &&
6154 (jQuery.support.html5Clone || !rnoshimcache.test( first )) ) {
6155
6156 // Mark cacheable and look for a hit
6157 cacheable = true;
6158 fragment = jQuery.fragments[ first ];
6159 cachehit = fragment !== undefined;
6160 }
6161
6162 if ( !fragment ) {
6163 fragment = context.createDocumentFragment();
6164 jQuery.clean( args, context, fragment, scripts );
6165
6166 // Update the cache, but only store false
6167 // unless this is a second parsing of the same content
6168 if ( cacheable ) {
6169 jQuery.fragments[ first ] = cachehit && fragment;
6170 }
6171 }
6172
6173 return { fragment: fragment, cacheable: cacheable };
6174 };
6175
6176 jQuery.fragments = {};
6177
6178 jQuery.each({
6179 appendTo: "append",
6180 prependTo: "prepend",
6181 insertBefore: "before",
6182 insertAfter: "after",
6183 replaceAll: "replaceWith"
6184 }, function( name, original ) {
6185 jQuery.fn[ name ] = function( selector ) {
6186 var elems,
6187 i = 0,
6188 ret = [],
6189 insert = jQuery( selector ),
6190 l = insert.length,
6191 parent = this.length === 1 && this[0].parentNode;
6192
6193 if ( (parent == null || parent && parent.nodeType === 11 && parent.childNodes.length === 1) && l === 1 ) {
6194 insert[ original ]( this[0] );
6195 return this;
6196 } else {
6197 for ( ; i < l; i++ ) {
6198 elems = ( i > 0 ? this.clone(true) : this ).get();
6199 jQuery( insert[i] )[ original ]( elems );
6200 ret = ret.concat( elems );
6201 }
6202
6203 return this.pushStack( ret, name, insert.selector );
6204 }
6205 };
6206 });
6207
6208 function getAll( elem ) {
6209 if ( typeof elem.getElementsByTagName !== "undefined" ) {
6210 return elem.getElementsByTagName( "*" );
6211
6212 } else if ( typeof elem.querySelectorAll !== "undefined" ) {
6213 return elem.querySelectorAll( "*" );
6214
6215 } else {
6216 return [];
6217 }
6218 }
6219
6220 // Used in clean, fixes the defaultChecked property
6221 function fixDefaultChecked( elem ) {
6222 if ( rcheckableType.test( elem.type ) ) {
6223 elem.defaultChecked = elem.checked;
6224 }
6225 }
6226
6227 jQuery.extend({
6228 clone: function( elem, dataAndEvents, deepDataAndEvents ) {
6229 var srcElements,
6230 destElements,
6231 i,
6232 clone;
6233
6234 if ( jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) {
6235 clone = elem.cloneNode( true );
6236
6237 // IE<=8 does not properly clone detached, unknown element nodes
6238 } else {
6239 fragmentDiv.innerHTML = elem.outerHTML;
6240 fragmentDiv.removeChild( clone = fragmentDiv.firstChild );
6241 }
6242
6243 if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) &&
6244 (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {
6245 // IE copies events bound via attachEvent when using cloneNode.
6246 // Calling detachEvent on the clone will also remove the events
6247 // from the original. In order to get around this, we use some
6248 // proprietary methods to clear the events. Thanks to MooTools
6249 // guys for this hotness.
6250
6251 cloneFixAttributes( elem, clone );
6252
6253 // Using Sizzle here is crazy slow, so we use getElementsByTagName instead
6254 srcElements = getAll( elem );
6255 destElements = getAll( clone );
6256
6257 // Weird iteration because IE will replace the length property
6258 // with an element if you are cloning the body and one of the
6259 // elements on the page has a name or id of "length"
6260 for ( i = 0; srcElements[i]; ++i ) {
6261 // Ensure that the destination node is not null; Fixes #9587
6262 if ( destElements[i] ) {
6263 cloneFixAttributes( srcElements[i], destElements[i] );
6264 }
6265 }
6266 }
6267
6268 // Copy the events from the original to the clone
6269 if ( dataAndEvents ) {
6270 cloneCopyEvent( elem, clone );
6271
6272 if ( deepDataAndEvents ) {
6273 srcElements = getAll( elem );
6274 destElements = getAll( clone );
6275
6276 for ( i = 0; srcElements[i]; ++i ) {
6277 cloneCopyEvent( srcElements[i], destElements[i] );
6278 }
6279 }
6280 }
6281
6282 srcElements = destElements = null;
6283
6284 // Return the cloned set
6285 return clone;
6286 },
6287
6288 clean: function( elems, context, fragment, scripts ) {
6289 var i, j, elem, tag, wrap, depth, div, hasBody, tbody, len, handleScript, jsTags,
6290 safe = context === document && safeFragment,
6291 ret = [];
6292
6293 // Ensure that context is a document
6294 if ( !context || typeof context.createDocumentFragment === "undefined" ) {
6295 context = document;
6296 }
6297
6298 // Use the already-created safe fragment if context permits
6299 for ( i = 0; (elem = elems[i]) != null; i++ ) {
6300 if ( typeof elem === "number" ) {
6301 elem += "";
6302 }
6303
6304 if ( !elem ) {
6305 continue;
6306 }
6307
6308 // Convert html string into DOM nodes
6309 if ( typeof elem === "string" ) {
6310 if ( !rhtml.test( elem ) ) {
6311 elem = context.createTextNode( elem );
6312 } else {
6313 // Ensure a safe container in which to render the html
6314 safe = safe || createSafeFragment( context );
6315 div = context.createElement("div");
6316 safe.appendChild( div );
6317
6318 // Fix "XHTML"-style tags in all browsers
6319 elem = elem.replace(rxhtmlTag, "<$1></$2>");
6320
6321 // Go to html and back, then peel off extra wrappers
6322 tag = ( rtagName.exec( elem ) || ["", ""] )[1].toLowerCase();
6323 wrap = wrapMap[ tag ] || wrapMap._default;
6324 depth = wrap[0];
6325 div.innerHTML = wrap[1] + elem + wrap[2];
6326
6327 // Move to the right depth
6328 while ( depth-- ) {
6329 div = div.lastChild;
6330 }
6331
6332 // Remove IE's autoinserted <tbody> from table fragments
6333 if ( !jQuery.support.tbody ) {
6334
6335 // String was a <table>, *may* have spurious <tbody>
6336 hasBody = rtbody.test(elem);
6337 tbody = tag === "table" && !hasBody ?
6338 div.firstChild && div.firstChild.childNodes :
6339
6340 // String was a bare <thead> or <tfoot>
6341 wrap[1] === "<table>" && !hasBody ?
6342 div.childNodes :
6343 [];
6344
6345 for ( j = tbody.length - 1; j >= 0 ; --j ) {
6346 if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) {
6347 tbody[ j ].parentNode.removeChild( tbody[ j ] );
6348 }
6349 }
6350 }
6351
6352 // IE completely kills leading whitespace when innerHTML is used
6353 if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
6354 div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );
6355 }
6356
6357 elem = div.childNodes;
6358
6359 // Take out of fragment container (we need a fresh div each time)
6360 div.parentNode.removeChild( div );
6361 }
6362 }
6363
6364 if ( elem.nodeType ) {
6365 ret.push( elem );
6366 } else {
6367 jQuery.merge( ret, elem );
6368 }
6369 }
6370
6371 // Fix #11356: Clear elements from safeFragment
6372 if ( div ) {
6373 elem = div = safe = null;
6374 }
6375
6376 // Reset defaultChecked for any radios and checkboxes
6377 // about to be appended to the DOM in IE 6/7 (#8060)
6378 if ( !jQuery.support.appendChecked ) {
6379 for ( i = 0; (elem = ret[i]) != null; i++ ) {
6380 if ( jQuery.nodeName( elem, "input" ) ) {
6381 fixDefaultChecked( elem );
6382 } else if ( typeof elem.getElementsByTagName !== "undefined" ) {
6383 jQuery.grep( elem.getElementsByTagName("input"), fixDefaultChecked );
6384 }
6385 }
6386 }
6387
6388 // Append elements to a provided document fragment
6389 if ( fragment ) {
6390 // Special handling of each script element
6391 handleScript = function( elem ) {
6392 // Check if we consider it executable
6393 if ( !elem.type || rscriptType.test( elem.type ) ) {
6394 // Detach the script and store it in the scripts array (if provided) or the fragment
6395 // Return truthy to indicate that it has been handled
6396 return scripts ?
6397 scripts.push( elem.parentNode ? elem.parentNode.removeChild( elem ) : elem ) :
6398 fragment.appendChild( elem );
6399 }
6400 };
6401
6402 for ( i = 0; (elem = ret[i]) != null; i++ ) {
6403 // Check if we're done after handling an executable script
6404 if ( !( jQuery.nodeName( elem, "script" ) && handleScript( elem ) ) ) {
6405 // Append to fragment and handle embedded scripts
6406 fragment.appendChild( elem );
6407 if ( typeof elem.getElementsByTagName !== "undefined" ) {
6408 // handleScript alters the DOM, so use jQuery.merge to ensure snapshot iteration
6409 jsTags = jQuery.grep( jQuery.merge( [], elem.getElementsByTagName("script") ), handleScript );
6410
6411 // Splice the scripts into ret after their former ancestor and advance our index beyond them
6412 ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) );
6413 i += jsTags.length;
6414 }
6415 }
6416 }
6417 }
6418
6419 return ret;
6420 },
6421
6422 cleanData: function( elems, /* internal */ acceptData ) {
6423 var data, id, elem, type,
6424 i = 0,
6425 internalKey = jQuery.expando,
6426 cache = jQuery.cache,
6427 deleteExpando = jQuery.support.deleteExpando,
6428 special = jQuery.event.special;
6429
6430 for ( ; (elem = elems[i]) != null; i++ ) {
6431
6432 if ( acceptData || jQuery.acceptData( elem ) ) {
6433
6434 id = elem[ internalKey ];
6435 data = id && cache[ id ];
6436
6437 if ( data ) {
6438 if ( data.events ) {
6439 for ( type in data.events ) {
6440 if ( special[ type ] ) {
6441 jQuery.event.remove( elem, type );
6442
6443 // This is a shortcut to avoid jQuery.event.remove's overhead
6444 } else {
6445 jQuery.removeEvent( elem, type, data.handle );
6446 }
6447 }
6448 }
6449
6450 // Remove cache only if it was not already removed by jQuery.event.remove
6451 if ( cache[ id ] ) {
6452
6453 delete cache[ id ];
6454
6455 // IE does not allow us to delete expando properties from nodes,
6456 // nor does it have a removeAttribute function on Document nodes;
6457 // we must handle all of these cases
6458 if ( deleteExpando ) {
6459 delete elem[ internalKey ];
6460
6461 } else if ( elem.removeAttribute ) {
6462 elem.removeAttribute( internalKey );
6463
6464 } else {
6465 elem[ internalKey ] = null;
6466 }
6467
6468 jQuery.deletedIds.push( id );
6469 }
6470 }
6471 }
6472 }
6473 }
6474 });
6475 // Limit scope pollution from any deprecated API
6476 (function() {
6477
6478 var matched, browser;
6479
6480 // Use of jQuery.browser is frowned upon.
6481 // More details: http://api.jquery.com/jQuery.browser
6482 // jQuery.uaMatch maintained for back-compat
6483 jQuery.uaMatch = function( ua ) {
6484 ua = ua.toLowerCase();
6485
6486 var match = /(chrome)[ \/]([\w.]+)/.exec( ua ) ||
6487 /(webkit)[ \/]([\w.]+)/.exec( ua ) ||
6488 /(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) ||
6489 /(msie) ([\w.]+)/.exec( ua ) ||
6490 ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) ||
6491 [];
6492
6493 return {
6494 browser: match[ 1 ] || "",
6495 version: match[ 2 ] || "0"
6496 };
6497 };
6498
6499 matched = jQuery.uaMatch( navigator.userAgent );
6500 browser = {};
6501
6502 if ( matched.browser ) {
6503 browser[ matched.browser ] = true;
6504 browser.version = matched.version;
6505 }
6506
6507 // Chrome is Webkit, but Webkit is also Safari.
6508 if ( browser.chrome ) {
6509 browser.webkit = true;
6510 } else if ( browser.webkit ) {
6511 browser.safari = true;
6512 }
6513
6514 jQuery.browser = browser;
6515
6516 jQuery.sub = function() {
6517 function jQuerySub( selector, context ) {
6518 return new jQuerySub.fn.init( selector, context );
6519 }
6520 jQuery.extend( true, jQuerySub, this );
6521 jQuerySub.superclass = this;
6522 jQuerySub.fn = jQuerySub.prototype = this();
6523 jQuerySub.fn.constructor = jQuerySub;
6524 jQuerySub.sub = this.sub;
6525 jQuerySub.fn.init = function init( selector, context ) {
6526 if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) {
6527 context = jQuerySub( context );
6528 }
6529
6530 return jQuery.fn.init.call( this, selector, context, rootjQuerySub );
6531 };
6532 jQuerySub.fn.init.prototype = jQuerySub.fn;
6533 var rootjQuerySub = jQuerySub(document);
6534 return jQuerySub;
6535 };
6536
6537 })();
6538 var curCSS, iframe, iframeDoc,
6539 ralpha = /alpha\([^)]*\)/i,
6540 ropacity = /opacity=([^)]*)/,
6541 rposition = /^(top|right|bottom|left)$/,
6542 // swappable if display is none or starts with table except "table", "table-cell", or "table-caption"
6543 // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
6544 rdisplayswap = /^(none|table(?!-c[ea]).+)/,
6545 rmargin = /^margin/,
6546 rnumsplit = new RegExp( "^(" + core_pnum + ")(.*)$", "i" ),
6547 rnumnonpx = new RegExp( "^(" + core_pnum + ")(?!px)[a-z%]+$", "i" ),
6548 rrelNum = new RegExp( "^([-+])=(" + core_pnum + ")", "i" ),
6549 elemdisplay = { BODY: "block" },
6550
6551 cssShow = { position: "absolute", visibility: "hidden", display: "block" },
6552 cssNormalTransform = {
6553 letterSpacing: 0,
6554 fontWeight: 400
6555 },
6556
6557 cssExpand = [ "Top", "Right", "Bottom", "Left" ],
6558 cssPrefixes = [ "Webkit", "O", "Moz", "ms" ],
6559
6560 eventsToggle = jQuery.fn.toggle;
6561
6562 // return a css property mapped to a potentially vendor prefixed property
6563 function vendorPropName( style, name ) {
6564
6565 // shortcut for names that are not vendor prefixed
6566 if ( name in style ) {
6567 return name;
6568 }
6569
6570 // check for vendor prefixed names
6571 var capName = name.charAt(0).toUpperCase() + name.slice(1),
6572 origName = name,
6573 i = cssPrefixes.length;
6574
6575 while ( i-- ) {
6576 name = cssPrefixes[ i ] + capName;
6577 if ( name in style ) {
6578 return name;
6579 }
6580 }
6581
6582 return origName;
6583 }
6584
6585 function isHidden( elem, el ) {
6586 elem = el || elem;
6587 return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem );
6588 }
6589
6590 function showHide( elements, show ) {
6591 var elem, display,
6592 values = [],
6593 index = 0,
6594 length = elements.length;
6595
6596 for ( ; index < length; index++ ) {
6597 elem = elements[ index ];
6598 if ( !elem.style ) {
6599 continue;
6600 }
6601 values[ index ] = jQuery._data( elem, "olddisplay" );
6602 if ( show ) {
6603 // Reset the inline display of this element to learn if it is
6604 // being hidden by cascaded rules or not
6605 if ( !values[ index ] && elem.style.display === "none" ) {
6606 elem.style.display = "";
6607 }
6608
6609 // Set elements which have been overridden with display: none
6610 // in a stylesheet to whatever the default browser style is
6611 // for such an element
6612 if ( elem.style.display === "" && isHidden( elem ) ) {
6613 values[ index ] = jQuery._data( elem, "olddisplay", css_defaultDisplay(elem.nodeName) );
6614 }
6615 } else {
6616 display = curCSS( elem, "display" );
6617
6618 if ( !values[ index ] && display !== "none" ) {
6619 jQuery._data( elem, "olddisplay", display );
6620 }
6621 }
6622 }
6623
6624 // Set the display of most of the elements in a second loop
6625 // to avoid the constant reflow
6626 for ( index = 0; index < length; index++ ) {
6627 elem = elements[ index ];
6628 if ( !elem.style ) {
6629 continue;
6630 }
6631 if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
6632 elem.style.display = show ? values[ index ] || "" : "none";
6633 }
6634 }
6635
6636 return elements;
6637 }
6638
6639 jQuery.fn.extend({
6640 css: function( name, value ) {
6641 return jQuery.access( this, function( elem, name, value ) {
6642 return value !== undefined ?
6643 jQuery.style( elem, name, value ) :
6644 jQuery.css( elem, name );
6645 }, name, value, arguments.length > 1 );
6646 },
6647 show: function() {
6648 return showHide( this, true );
6649 },
6650 hide: function() {
6651 return showHide( this );
6652 },
6653 toggle: function( state, fn2 ) {
6654 var bool = typeof state === "boolean";
6655
6656 if ( jQuery.isFunction( state ) && jQuery.isFunction( fn2 ) ) {
6657 return eventsToggle.apply( this, arguments );
6658 }
6659
6660 return this.each(function() {
6661 if ( bool ? state : isHidden( this ) ) {
6662 jQuery( this ).show();
6663 } else {
6664 jQuery( this ).hide();
6665 }
6666 });
6667 }
6668 });
6669
6670 jQuery.extend({
6671 // Add in style property hooks for overriding the default
6672 // behavior of getting and setting a style property
6673 cssHooks: {
6674 opacity: {
6675 get: function( elem, computed ) {
6676 if ( computed ) {
6677 // We should always get a number back from opacity
6678 var ret = curCSS( elem, "opacity" );
6679 return ret === "" ? "1" : ret;
6680
6681 }
6682 }
6683 }
6684 },
6685
6686 // Exclude the following css properties to add px
6687 cssNumber: {
6688 "fillOpacity": true,
6689 "fontWeight": true,
6690 "lineHeight": true,
6691 "opacity": true,
6692 "orphans": true,
6693 "widows": true,
6694 "zIndex": true,
6695 "zoom": true
6696 },
6697
6698 // Add in properties whose names you wish to fix before
6699 // setting or getting the value
6700 cssProps: {
6701 // normalize float css property
6702 "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat"
6703 },
6704
6705 // Get and set the style property on a DOM Node
6706 style: function( elem, name, value, extra ) {
6707 // Don't set styles on text and comment nodes
6708 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
6709 return;
6710 }
6711
6712 // Make sure that we're working with the right name
6713 var ret, type, hooks,
6714 origName = jQuery.camelCase( name ),
6715 style = elem.style;
6716
6717 name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) );
6718
6719 // gets hook for the prefixed version
6720 // followed by the unprefixed version
6721 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
6722
6723 // Check if we're setting a value
6724 if ( value !== undefined ) {
6725 type = typeof value;
6726
6727 // convert relative number strings (+= or -=) to relative numbers. #7345
6728 if ( type === "string" && (ret = rrelNum.exec( value )) ) {
6729 value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) );
6730 // Fixes bug #9237
6731 type = "number";
6732 }
6733
6734 // Make sure that NaN and null values aren't set. See: #7116
6735 if ( value == null || type === "number" && isNaN( value ) ) {
6736 return;
6737 }
6738
6739 // If a number was passed in, add 'px' to the (except for certain CSS properties)
6740 if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
6741 value += "px";
6742 }
6743
6744 // If a hook was provided, use that value, otherwise just set the specified value
6745 if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) {
6746 // Wrapped to prevent IE from throwing errors when 'invalid' values are provided
6747 // Fixes bug #5509
6748 try {
6749 style[ name ] = value;
6750 } catch(e) {}
6751 }
6752
6753 } else {
6754 // If a hook was provided get the non-computed value from there
6755 if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
6756 return ret;
6757 }
6758
6759 // Otherwise just get the value from the style object
6760 return style[ name ];
6761 }
6762 },
6763
6764 css: function( elem, name, numeric, extra ) {
6765 var val, num, hooks,
6766 origName = jQuery.camelCase( name );
6767
6768 // Make sure that we're working with the right name
6769 name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );
6770
6771 // gets hook for the prefixed version
6772 // followed by the unprefixed version
6773 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
6774
6775 // If a hook was provided get the computed value from there
6776 if ( hooks && "get" in hooks ) {
6777 val = hooks.get( elem, true, extra );
6778 }
6779
6780 // Otherwise, if a way to get the computed value exists, use that
6781 if ( val === undefined ) {
6782 val = curCSS( elem, name );
6783 }
6784
6785 //convert "normal" to computed value
6786 if ( val === "normal" && name in cssNormalTransform ) {
6787 val = cssNormalTransform[ name ];
6788 }
6789
6790 // Return, converting to number if forced or a qualifier was provided and val looks numeric
6791 if ( numeric || extra !== undefined ) {
6792 num = parseFloat( val );
6793 return numeric || jQuery.isNumeric( num ) ? num || 0 : val;
6794 }
6795 return val;
6796 },
6797
6798 // A method for quickly swapping in/out CSS properties to get correct calculations
6799 swap: function( elem, options, callback ) {
6800 var ret, name,
6801 old = {};
6802
6803 // Remember the old values, and insert the new ones
6804 for ( name in options ) {
6805 old[ name ] = elem.style[ name ];
6806 elem.style[ name ] = options[ name ];
6807 }
6808
6809 ret = callback.call( elem );
6810
6811 // Revert the old values
6812 for ( name in options ) {
6813 elem.style[ name ] = old[ name ];
6814 }
6815
6816 return ret;
6817 }
6818 });
6819
6820 // NOTE: To any future maintainer, we've window.getComputedStyle
6821 // because jsdom on node.js will break without it.
6822 if ( window.getComputedStyle ) {
6823 curCSS = function( elem, name ) {
6824 var ret, width, minWidth, maxWidth,
6825 computed = window.getComputedStyle( elem, null ),
6826 style = elem.style;
6827
6828 if ( computed ) {
6829
6830 // getPropertyValue is only needed for .css('filter') in IE9, see #12537
6831 ret = computed.getPropertyValue( name ) || computed[ name ];
6832
6833 if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) {
6834 ret = jQuery.style( elem, name );
6835 }
6836
6837 // A tribute to the "awesome hack by Dean Edwards"
6838 // Chrome < 17 and Safari 5.0 uses "computed value" instead of "used value" for margin-right
6839 // Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels
6840 // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values
6841 if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) {
6842 width = style.width;
6843 minWidth = style.minWidth;
6844 maxWidth = style.maxWidth;
6845
6846 style.minWidth = style.maxWidth = style.width = ret;
6847 ret = computed.width;
6848
6849 style.width = width;
6850 style.minWidth = minWidth;
6851 style.maxWidth = maxWidth;
6852 }
6853 }
6854
6855 return ret;
6856 };
6857 } else if ( document.documentElement.currentStyle ) {
6858 curCSS = function( elem, name ) {
6859 var left, rsLeft,
6860 ret = elem.currentStyle && elem.currentStyle[ name ],
6861 style = elem.style;
6862
6863 // Avoid setting ret to empty string here
6864 // so we don't default to auto
6865 if ( ret == null && style && style[ name ] ) {
6866 ret = style[ name ];
6867 }
6868
6869 // From the awesome hack by Dean Edwards
6870 // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
6871
6872 // If we're not dealing with a regular pixel number
6873 // but a number that has a weird ending, we need to convert it to pixels
6874 // but not position css attributes, as those are proportional to the parent element instead
6875 // and we can't measure the parent instead because it might trigger a "stacking dolls" problem
6876 if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) {
6877
6878 // Remember the original values
6879 left = style.left;
6880 rsLeft = elem.runtimeStyle && elem.runtimeStyle.left;
6881
6882 // Put in the new values to get a computed value out
6883 if ( rsLeft ) {
6884 elem.runtimeStyle.left = elem.currentStyle.left;
6885 }
6886 style.left = name === "fontSize" ? "1em" : ret;
6887 ret = style.pixelLeft + "px";
6888
6889 // Revert the changed values
6890 style.left = left;
6891 if ( rsLeft ) {
6892 elem.runtimeStyle.left = rsLeft;
6893 }
6894 }
6895
6896 return ret === "" ? "auto" : ret;
6897 };
6898 }
6899
6900 function setPositiveNumber( elem, value, subtract ) {
6901 var matches = rnumsplit.exec( value );
6902 return matches ?
6903 Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) :
6904 value;
6905 }
6906
6907 function augmentWidthOrHeight( elem, name, extra, isBorderBox ) {
6908 var i = extra === ( isBorderBox ? "border" : "content" ) ?
6909 // If we already have the right measurement, avoid augmentation
6910 4 :
6911 // Otherwise initialize for horizontal or vertical properties
6912 name === "width" ? 1 : 0,
6913
6914 val = 0;
6915
6916 for ( ; i < 4; i += 2 ) {
6917 // both box models exclude margin, so add it if we want it
6918 if ( extra === "margin" ) {
6919 // we use jQuery.css instead of curCSS here
6920 // because of the reliableMarginRight CSS hook!
6921 val += jQuery.css( elem, extra + cssExpand[ i ], true );
6922 }
6923
6924 // From this point on we use curCSS for maximum performance (relevant in animations)
6925 if ( isBorderBox ) {
6926 // border-box includes padding, so remove it if we want content
6927 if ( extra === "content" ) {
6928 val -= parseFloat( curCSS( elem, "padding" + cssExpand[ i ] ) ) || 0;
6929 }
6930
6931 // at this point, extra isn't border nor margin, so remove border
6932 if ( extra !== "margin" ) {
6933 val -= parseFloat( curCSS( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0;
6934 }
6935 } else {
6936 // at this point, extra isn't content, so add padding
6937 val += parseFloat( curCSS( elem, "padding" + cssExpand[ i ] ) ) || 0;
6938
6939 // at this point, extra isn't content nor padding, so add border
6940 if ( extra !== "padding" ) {
6941 val += parseFloat( curCSS( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0;
6942 }
6943 }
6944 }
6945
6946 return val;
6947 }
6948
6949 function getWidthOrHeight( elem, name, extra ) {
6950
6951 // Start with offset property, which is equivalent to the border-box value
6952 var val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
6953 valueIsBorderBox = true,
6954 isBorderBox = jQuery.support.boxSizing && jQuery.css( elem, "boxSizing" ) === "border-box";
6955
6956 // some non-html elements return undefined for offsetWidth, so check for null/undefined
6957 // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
6958 // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
6959 if ( val <= 0 || val == null ) {
6960 // Fall back to computed then uncomputed css if necessary
6961 val = curCSS( elem, name );
6962 if ( val < 0 || val == null ) {
6963 val = elem.style[ name ];
6964 }
6965
6966 // Computed unit is not pixels. Stop here and return.
6967 if ( rnumnonpx.test(val) ) {
6968 return val;
6969 }
6970
6971 // we need the check for style in case a browser which returns unreliable values
6972 // for getComputedStyle silently falls back to the reliable elem.style
6973 valueIsBorderBox = isBorderBox && ( jQuery.support.boxSizingReliable || val === elem.style[ name ] );
6974
6975 // Normalize "", auto, and prepare for extra
6976 val = parseFloat( val ) || 0;
6977 }
6978
6979 // use the active box-sizing model to add/subtract irrelevant styles
6980 return ( val +
6981 augmentWidthOrHeight(
6982 elem,
6983 name,
6984 extra || ( isBorderBox ? "border" : "content" ),
6985 valueIsBorderBox
6986 )
6987 ) + "px";
6988 }
6989
6990
6991 // Try to determine the default display value of an element
6992 function css_defaultDisplay( nodeName ) {
6993 if ( elemdisplay[ nodeName ] ) {
6994 return elemdisplay[ nodeName ];
6995 }
6996
6997 var elem = jQuery( "<" + nodeName + ">" ).appendTo( document.body ),
6998 display = elem.css("display");
6999 elem.remove();
7000
7001 // If the simple way fails,
7002 // get element's real default display by attaching it to a temp iframe
7003 if ( display === "none" || display === "" ) {
7004 // Use the already-created iframe if possible
7005 iframe = document.body.appendChild(
7006 iframe || jQuery.extend( document.createElement("iframe"), {
7007 frameBorder: 0,
7008 width: 0,
7009 height: 0
7010 })
7011 );
7012
7013 // Create a cacheable copy of the iframe document on first call.
7014 // IE and Opera will allow us to reuse the iframeDoc without re-writing the fake HTML
7015 // document to it; WebKit & Firefox won't allow reusing the iframe document.
7016 if ( !iframeDoc || !iframe.createElement ) {
7017 iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document;
7018 iframeDoc.write("<!doctype html><html><body>");
7019 iframeDoc.close();
7020 }
7021
7022 elem = iframeDoc.body.appendChild( iframeDoc.createElement(nodeName) );
7023
7024 display = curCSS( elem, "display" );
7025 document.body.removeChild( iframe );
7026 }
7027
7028 // Store the correct default display
7029 elemdisplay[ nodeName ] = display;
7030
7031 return display;
7032 }
7033
7034 jQuery.each([ "height", "width" ], function( i, name ) {
7035 jQuery.cssHooks[ name ] = {
7036 get: function( elem, computed, extra ) {
7037 if ( computed ) {
7038 // certain elements can have dimension info if we invisibly show them
7039 // however, it must have a current display style that would benefit from this
7040 if ( elem.offsetWidth === 0 && rdisplayswap.test( curCSS( elem, "display" ) ) ) {
7041 return jQuery.swap( elem, cssShow, function() {
7042 return getWidthOrHeight( elem, name, extra );
7043 });
7044 } else {
7045 return getWidthOrHeight( elem, name, extra );
7046 }
7047 }
7048 },
7049
7050 set: function( elem, value, extra ) {
7051 return setPositiveNumber( elem, value, extra ?
7052 augmentWidthOrHeight(
7053 elem,
7054 name,
7055 extra,
7056 jQuery.support.boxSizing && jQuery.css( elem, "boxSizing" ) === "border-box"
7057 ) : 0
7058 );
7059 }
7060 };
7061 });
7062
7063 if ( !jQuery.support.opacity ) {
7064 jQuery.cssHooks.opacity = {
7065 get: function( elem, computed ) {
7066 // IE uses filters for opacity
7067 return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ?
7068 ( 0.01 * parseFloat( RegExp.$1 ) ) + "" :
7069 computed ? "1" : "";
7070 },
7071
7072 set: function( elem, value ) {
7073 var style = elem.style,
7074 currentStyle = elem.currentStyle,
7075 opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "",
7076 filter = currentStyle && currentStyle.filter || style.filter || "";
7077
7078 // IE has trouble with opacity if it does not have layout
7079 // Force it by setting the zoom level
7080 style.zoom = 1;
7081
7082 // if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652
7083 if ( value >= 1 && jQuery.trim( filter.replace( ralpha, "" ) ) === "" &&
7084 style.removeAttribute ) {
7085
7086 // Setting style.filter to null, "" & " " still leave "filter:" in the cssText
7087 // if "filter:" is present at all, clearType is disabled, we want to avoid this
7088 // style.removeAttribute is IE Only, but so apparently is this code path...
7089 style.removeAttribute( "filter" );
7090
7091 // if there there is no filter style applied in a css rule, we are done
7092 if ( currentStyle && !currentStyle.filter ) {
7093 return;
7094 }
7095 }
7096
7097 // otherwise, set new filter values
7098 style.filter = ralpha.test( filter ) ?
7099 filter.replace( ralpha, opacity ) :
7100 filter + " " + opacity;
7101 }
7102 };
7103 }
7104
7105 // These hooks cannot be added until DOM ready because the support test
7106 // for it is not run until after DOM ready
7107 jQuery(function() {
7108 if ( !jQuery.support.reliableMarginRight ) {
7109 jQuery.cssHooks.marginRight = {
7110 get: function( elem, computed ) {
7111 // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
7112 // Work around by temporarily setting element display to inline-block
7113 return jQuery.swap( elem, { "display": "inline-block" }, function() {
7114 if ( computed ) {
7115 return curCSS( elem, "marginRight" );
7116 }
7117 });
7118 }
7119 };
7120 }
7121
7122 // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
7123 // getComputedStyle returns percent when specified for top/left/bottom/right
7124 // rather than make the css module depend on the offset module, we just check for it here
7125 if ( !jQuery.support.pixelPosition && jQuery.fn.position ) {
7126 jQuery.each( [ "top", "left" ], function( i, prop ) {
7127 jQuery.cssHooks[ prop ] = {
7128 get: function( elem, computed ) {
7129 if ( computed ) {
7130 var ret = curCSS( elem, prop );
7131 // if curCSS returns percentage, fallback to offset
7132 return rnumnonpx.test( ret ) ? jQuery( elem ).position()[ prop ] + "px" : ret;
7133 }
7134 }
7135 };
7136 });
7137 }
7138
7139 });
7140
7141 if ( jQuery.expr && jQuery.expr.filters ) {
7142 jQuery.expr.filters.hidden = function( elem ) {
7143 return ( elem.offsetWidth === 0 && elem.offsetHeight === 0 ) || (!jQuery.support.reliableHiddenOffsets && ((elem.style && elem.style.display) || curCSS( elem, "display" )) === "none");
7144 };
7145
7146 jQuery.expr.filters.visible = function( elem ) {
7147 return !jQuery.expr.filters.hidden( elem );
7148 };
7149 }
7150
7151 // These hooks are used by animate to expand properties
7152 jQuery.each({
7153 margin: "",
7154 padding: "",
7155 border: "Width"
7156 }, function( prefix, suffix ) {
7157 jQuery.cssHooks[ prefix + suffix ] = {
7158 expand: function( value ) {
7159 var i,
7160
7161 // assumes a single number if not a string
7162 parts = typeof value === "string" ? value.split(" ") : [ value ],
7163 expanded = {};
7164
7165 for ( i = 0; i < 4; i++ ) {
7166 expanded[ prefix + cssExpand[ i ] + suffix ] =
7167 parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
7168 }
7169
7170 return expanded;
7171 }
7172 };
7173
7174 if ( !rmargin.test( prefix ) ) {
7175 jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
7176 }
7177 });
7178 var r20 = /%20/g,
7179 rbracket = /\[\]$/,
7180 rCRLF = /\r?\n/g,
7181 rinput = /^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,
7182 rselectTextarea = /^(?:select|textarea)/i;
7183
7184 jQuery.fn.extend({
7185 serialize: function() {
7186 return jQuery.param( this.serializeArray() );
7187 },
7188 serializeArray: function() {
7189 return this.map(function(){
7190 return this.elements ? jQuery.makeArray( this.elements ) : this;
7191 })
7192 .filter(function(){
7193 return this.name && !this.disabled &&
7194 ( this.checked || rselectTextarea.test( this.nodeName ) ||
7195 rinput.test( this.type ) );
7196 })
7197 .map(function( i, elem ){
7198 var val = jQuery( this ).val();
7199
7200 return val == null ?
7201 null :
7202 jQuery.isArray( val ) ?
7203 jQuery.map( val, function( val, i ){
7204 return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
7205 }) :
7206 { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
7207 }).get();
7208 }
7209 });
7210
7211 //Serialize an array of form elements or a set of
7212 //key/values into a query string
7213 jQuery.param = function( a, traditional ) {
7214 var prefix,
7215 s = [],
7216 add = function( key, value ) {
7217 // If value is a function, invoke it and return its value
7218 value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value );
7219 s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
7220 };
7221
7222 // Set traditional to true for jQuery <= 1.3.2 behavior.
7223 if ( traditional === undefined ) {
7224 traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
7225 }
7226
7227 // If an array was passed in, assume that it is an array of form elements.
7228 if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
7229 // Serialize the form elements
7230 jQuery.each( a, function() {
7231 add( this.name, this.value );
7232 });
7233
7234 } else {
7235 // If traditional, encode the "old" way (the way 1.3.2 or older
7236 // did it), otherwise encode params recursively.
7237 for ( prefix in a ) {
7238 buildParams( prefix, a[ prefix ], traditional, add );
7239 }
7240 }
7241
7242 // Return the resulting serialization
7243 return s.join( "&" ).replace( r20, "+" );
7244 };
7245
7246 function buildParams( prefix, obj, traditional, add ) {
7247 var name;
7248
7249 if ( jQuery.isArray( obj ) ) {
7250 // Serialize array item.
7251 jQuery.each( obj, function( i, v ) {
7252 if ( traditional || rbracket.test( prefix ) ) {
7253 // Treat each array item as a scalar.
7254 add( prefix, v );
7255
7256 } else {
7257 // If array item is non-scalar (array or object), encode its
7258 // numeric index to resolve deserialization ambiguity issues.
7259 // Note that rack (as of 1.0.0) can't currently deserialize
7260 // nested arrays properly, and attempting to do so may cause
7261 // a server error. Possible fixes are to modify rack's
7262 // deserialization algorithm or to provide an option or flag
7263 // to force array serialization to be shallow.
7264 buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add );
7265 }
7266 });
7267
7268 } else if ( !traditional && jQuery.type( obj ) === "object" ) {
7269 // Serialize object item.
7270 for ( name in obj ) {
7271 buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
7272 }
7273
7274 } else {
7275 // Serialize scalar item.
7276 add( prefix, obj );
7277 }
7278 }
7279 var
7280 // Document location
7281 ajaxLocParts,
7282 ajaxLocation,
7283
7284 rhash = /#.*$/,
7285 rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL
7286 // #7653, #8125, #8152: local protocol detection
7287 rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,
7288 rnoContent = /^(?:GET|HEAD)$/,
7289 rprotocol = /^\/\//,
7290 rquery = /\?/,
7291 rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
7292 rts = /([?&])_=[^&]*/,
7293 rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,
7294
7295 // Keep a copy of the old load method
7296 _load = jQuery.fn.load,
7297
7298 /* Prefilters
7299 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
7300 * 2) These are called:
7301 * - BEFORE asking for a transport
7302 * - AFTER param serialization (s.data is a string if s.processData is true)
7303 * 3) key is the dataType
7304 * 4) the catchall symbol "*" can be used
7305 * 5) execution will start with transport dataType and THEN continue down to "*" if needed
7306 */
7307 prefilters = {},
7308
7309 /* Transports bindings
7310 * 1) key is the dataType
7311 * 2) the catchall symbol "*" can be used
7312 * 3) selection will start with transport dataType and THEN go to "*" if needed
7313 */
7314 transports = {},
7315
7316 // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
7317 allTypes = ["*/"] + ["*"];
7318
7319 // #8138, IE may throw an exception when accessing
7320 // a field from window.location if document.domain has been set
7321 try {
7322 ajaxLocation = location.href;
7323 } catch( e ) {
7324 // Use the href attribute of an A element
7325 // since IE will modify it given document.location
7326 ajaxLocation = document.createElement( "a" );
7327 ajaxLocation.href = "";
7328 ajaxLocation = ajaxLocation.href;
7329 }
7330
7331 // Segment location into parts
7332 ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
7333
7334 // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
7335 function addToPrefiltersOrTransports( structure ) {
7336
7337 // dataTypeExpression is optional and defaults to "*"
7338 return function( dataTypeExpression, func ) {
7339
7340 if ( typeof dataTypeExpression !== "string" ) {
7341 func = dataTypeExpression;
7342 dataTypeExpression = "*";
7343 }
7344
7345 var dataType, list, placeBefore,
7346 dataTypes = dataTypeExpression.toLowerCase().split( core_rspace ),
7347 i = 0,
7348 length = dataTypes.length;
7349
7350 if ( jQuery.isFunction( func ) ) {
7351 // For each dataType in the dataTypeExpression
7352 for ( ; i < length; i++ ) {
7353 dataType = dataTypes[ i ];
7354 // We control if we're asked to add before
7355 // any existing element
7356 placeBefore = /^\+/.test( dataType );
7357 if ( placeBefore ) {
7358 dataType = dataType.substr( 1 ) || "*";
7359 }
7360 list = structure[ dataType ] = structure[ dataType ] || [];
7361 // then we add to the structure accordingly
7362 list[ placeBefore ? "unshift" : "push" ]( func );
7363 }
7364 }
7365 };
7366 }
7367
7368 // Base inspection function for prefilters and transports
7369 function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR,
7370 dataType /* internal */, inspected /* internal */ ) {
7371
7372 dataType = dataType || options.dataTypes[ 0 ];
7373 inspected = inspected || {};
7374
7375 inspected[ dataType ] = true;
7376
7377 var selection,
7378 list = structure[ dataType ],
7379 i = 0,
7380 length = list ? list.length : 0,
7381 executeOnly = ( structure === prefilters );
7382
7383 for ( ; i < length && ( executeOnly || !selection ); i++ ) {
7384 selection = list[ i ]( options, originalOptions, jqXHR );
7385 // If we got redirected to another dataType
7386 // we try there if executing only and not done already
7387 if ( typeof selection === "string" ) {
7388 if ( !executeOnly || inspected[ selection ] ) {
7389 selection = undefined;
7390 } else {
7391 options.dataTypes.unshift( selection );
7392 selection = inspectPrefiltersOrTransports(
7393 structure, options, originalOptions, jqXHR, selection, inspected );
7394 }
7395 }
7396 }
7397 // If we're only executing or nothing was selected
7398 // we try the catchall dataType if not done already
7399 if ( ( executeOnly || !selection ) && !inspected[ "*" ] ) {
7400 selection = inspectPrefiltersOrTransports(
7401 structure, options, originalOptions, jqXHR, "*", inspected );
7402 }
7403 // unnecessary when only executing (prefilters)
7404 // but it'll be ignored by the caller in that case
7405 return selection;
7406 }
7407
7408 // A special extend for ajax options
7409 // that takes "flat" options (not to be deep extended)
7410 // Fixes #9887
7411 function ajaxExtend( target, src ) {
7412 var key, deep,
7413 flatOptions = jQuery.ajaxSettings.flatOptions || {};
7414 for ( key in src ) {
7415 if ( src[ key ] !== undefined ) {
7416 ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
7417 }
7418 }
7419 if ( deep ) {
7420 jQuery.extend( true, target, deep );
7421 }
7422 }
7423
7424 jQuery.fn.load = function( url, params, callback ) {
7425 if ( typeof url !== "string" && _load ) {
7426 return _load.apply( this, arguments );
7427 }
7428
7429 // Don't do a request if no elements are being requested
7430 if ( !this.length ) {
7431 return this;
7432 }
7433
7434 var selector, type, response,
7435 self = this,
7436 off = url.indexOf(" ");
7437
7438 if ( off >= 0 ) {
7439 selector = url.slice( off, url.length );
7440 url = url.slice( 0, off );
7441 }
7442
7443 // If it's a function
7444 if ( jQuery.isFunction( params ) ) {
7445
7446 // We assume that it's the callback
7447 callback = params;
7448 params = undefined;
7449
7450 // Otherwise, build a param string
7451 } else if ( params && typeof params === "object" ) {
7452 type = "POST";
7453 }
7454
7455 // Request the remote document
7456 jQuery.ajax({
7457 url: url,
7458
7459 // if "type" variable is undefined, then "GET" method will be used
7460 type: type,
7461 dataType: "html",
7462 data: params,
7463 complete: function( jqXHR, status ) {
7464 if ( callback ) {
7465 self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );
7466 }
7467 }
7468 }).done(function( responseText ) {
7469
7470 // Save response for use in complete callback
7471 response = arguments;
7472
7473 // See if a selector was specified
7474 self.html( selector ?
7475
7476 // Create a dummy div to hold the results
7477 jQuery("<div>")
7478
7479 // inject the contents of the document in, removing the scripts
7480 // to avoid any 'Permission Denied' errors in IE
7481 .append( responseText.replace( rscript, "" ) )
7482
7483 // Locate the specified elements
7484 .find( selector ) :
7485
7486 // If not, just inject the full result
7487 responseText );
7488
7489 });
7490
7491 return this;
7492 };
7493
7494 // Attach a bunch of functions for handling common AJAX events
7495 jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split( " " ), function( i, o ){
7496 jQuery.fn[ o ] = function( f ){
7497 return this.on( o, f );
7498 };
7499 });
7500
7501 jQuery.each( [ "get", "post" ], function( i, method ) {
7502 jQuery[ method ] = function( url, data, callback, type ) {
7503 // shift arguments if data argument was omitted
7504 if ( jQuery.isFunction( data ) ) {
7505 type = type || callback;
7506 callback = data;
7507 data = undefined;
7508 }
7509
7510 return jQuery.ajax({
7511 type: method,
7512 url: url,
7513 data: data,
7514 success: callback,
7515 dataType: type
7516 });
7517 };
7518 });
7519
7520 jQuery.extend({
7521
7522 getScript: function( url, callback ) {
7523 return jQuery.get( url, undefined, callback, "script" );
7524 },
7525
7526 getJSON: function( url, data, callback ) {
7527 return jQuery.get( url, data, callback, "json" );
7528 },
7529
7530 // Creates a full fledged settings object into target
7531 // with both ajaxSettings and settings fields.
7532 // If target is omitted, writes into ajaxSettings.
7533 ajaxSetup: function( target, settings ) {
7534 if ( settings ) {
7535 // Building a settings object
7536 ajaxExtend( target, jQuery.ajaxSettings );
7537 } else {
7538 // Extending ajaxSettings
7539 settings = target;
7540 target = jQuery.ajaxSettings;
7541 }
7542 ajaxExtend( target, settings );
7543 return target;
7544 },
7545
7546 ajaxSettings: {
7547 url: ajaxLocation,
7548 isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
7549 global: true,
7550 type: "GET",
7551 contentType: "application/x-www-form-urlencoded; charset=UTF-8",
7552 processData: true,
7553 async: true,
7554 /*
7555 timeout: 0,
7556 data: null,
7557 dataType: null,
7558 username: null,
7559 password: null,
7560 cache: null,
7561 throws: false,
7562 traditional: false,
7563 headers: {},
7564 */
7565
7566 accepts: {
7567 xml: "application/xml, text/xml",
7568 html: "text/html",
7569 text: "text/plain",
7570 json: "application/json, text/javascript",
7571 "*": allTypes
7572 },
7573
7574 contents: {
7575 xml: /xml/,
7576 html: /html/,
7577 json: /json/
7578 },
7579
7580 responseFields: {
7581 xml: "responseXML",
7582 text: "responseText"
7583 },
7584
7585 // List of data converters
7586 // 1) key format is "source_type destination_type" (a single space in-between)
7587 // 2) the catchall symbol "*" can be used for source_type
7588 converters: {
7589
7590 // Convert anything to text
7591 "* text": window.String,
7592
7593 // Text to html (true = no transformation)
7594 "text html": true,
7595
7596 // Evaluate text as a json expression
7597 "text json": jQuery.parseJSON,
7598
7599 // Parse text as xml
7600 "text xml": jQuery.parseXML
7601 },
7602
7603 // For options that shouldn't be deep extended:
7604 // you can add your own custom options here if
7605 // and when you create one that shouldn't be
7606 // deep extended (see ajaxExtend)
7607 flatOptions: {
7608 context: true,
7609 url: true
7610 }
7611 },
7612
7613 ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
7614 ajaxTransport: addToPrefiltersOrTransports( transports ),
7615
7616 // Main method
7617 ajax: function( url, options ) {
7618
7619 // If url is an object, simulate pre-1.5 signature
7620 if ( typeof url === "object" ) {
7621 options = url;
7622 url = undefined;
7623 }
7624
7625 // Force options to be an object
7626 options = options || {};
7627
7628 var // ifModified key
7629 ifModifiedKey,
7630 // Response headers
7631 responseHeadersString,
7632 responseHeaders,
7633 // transport
7634 transport,
7635 // timeout handle
7636 timeoutTimer,
7637 // Cross-domain detection vars
7638 parts,
7639 // To know if global events are to be dispatched
7640 fireGlobals,
7641 // Loop variable
7642 i,
7643 // Create the final options object
7644 s = jQuery.ajaxSetup( {}, options ),
7645 // Callbacks context
7646 callbackContext = s.context || s,
7647 // Context for global events
7648 // It's the callbackContext if one was provided in the options
7649 // and if it's a DOM node or a jQuery collection
7650 globalEventContext = callbackContext !== s &&
7651 ( callbackContext.nodeType || callbackContext instanceof jQuery ) ?
7652 jQuery( callbackContext ) : jQuery.event,
7653 // Deferreds
7654 deferred = jQuery.Deferred(),
7655 completeDeferred = jQuery.Callbacks( "once memory" ),
7656 // Status-dependent callbacks
7657 statusCode = s.statusCode || {},
7658 // Headers (they are sent all at once)
7659 requestHeaders = {},
7660 requestHeadersNames = {},
7661 // The jqXHR state
7662 state = 0,
7663 // Default abort message
7664 strAbort = "canceled",
7665 // Fake xhr
7666 jqXHR = {
7667
7668 readyState: 0,
7669
7670 // Caches the header
7671 setRequestHeader: function( name, value ) {
7672 if ( !state ) {
7673 var lname = name.toLowerCase();
7674 name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
7675 requestHeaders[ name ] = value;
7676 }
7677 return this;
7678 },
7679
7680 // Raw string
7681 getAllResponseHeaders: function() {
7682 return state === 2 ? responseHeadersString : null;
7683 },
7684
7685 // Builds headers hashtable if needed
7686 getResponseHeader: function( key ) {
7687 var match;
7688 if ( state === 2 ) {
7689 if ( !responseHeaders ) {
7690 responseHeaders = {};
7691 while( ( match = rheaders.exec( responseHeadersString ) ) ) {
7692 responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
7693 }
7694 }
7695 match = responseHeaders[ key.toLowerCase() ];
7696 }
7697 return match === undefined ? null : match;
7698 },
7699
7700 // Overrides response content-type header
7701 overrideMimeType: function( type ) {
7702 if ( !state ) {
7703 s.mimeType = type;
7704 }
7705 return this;
7706 },
7707
7708 // Cancel the request
7709 abort: function( statusText ) {
7710 statusText = statusText || strAbort;
7711 if ( transport ) {
7712 transport.abort( statusText );
7713 }
7714 done( 0, statusText );
7715 return this;
7716 }
7717 };
7718
7719 // Callback for when everything is done
7720 // It is defined here because jslint complains if it is declared
7721 // at the end of the function (which would be more logical and readable)
7722 function done( status, nativeStatusText, responses, headers ) {
7723 var isSuccess, success, error, response, modified,
7724 statusText = nativeStatusText;
7725
7726 // Called once
7727 if ( state === 2 ) {
7728 return;
7729 }
7730
7731 // State is "done" now
7732 state = 2;
7733
7734 // Clear timeout if it exists
7735 if ( timeoutTimer ) {
7736 clearTimeout( timeoutTimer );
7737 }
7738
7739 // Dereference transport for early garbage collection
7740 // (no matter how long the jqXHR object will be used)
7741 transport = undefined;
7742
7743 // Cache response headers
7744 responseHeadersString = headers || "";
7745
7746 // Set readyState
7747 jqXHR.readyState = status > 0 ? 4 : 0;
7748
7749 // Get response data
7750 if ( responses ) {
7751 response = ajaxHandleResponses( s, jqXHR, responses );
7752 }
7753
7754 // If successful, handle type chaining
7755 if ( status >= 200 && status < 300 || status === 304 ) {
7756
7757 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
7758 if ( s.ifModified ) {
7759
7760 modified = jqXHR.getResponseHeader("Last-Modified");
7761 if ( modified ) {
7762 jQuery.lastModified[ ifModifiedKey ] = modified;
7763 }
7764 modified = jqXHR.getResponseHeader("Etag");
7765 if ( modified ) {
7766 jQuery.etag[ ifModifiedKey ] = modified;
7767 }
7768 }
7769
7770 // If not modified
7771 if ( status === 304 ) {
7772
7773 statusText = "notmodified";
7774 isSuccess = true;
7775
7776 // If we have data
7777 } else {
7778
7779 isSuccess = ajaxConvert( s, response );
7780 statusText = isSuccess.state;
7781 success = isSuccess.data;
7782 error = isSuccess.error;
7783 isSuccess = !error;
7784 }
7785 } else {
7786 // We extract error from statusText
7787 // then normalize statusText and status for non-aborts
7788 error = statusText;
7789 if ( !statusText || status ) {
7790 statusText = "error";
7791 if ( status < 0 ) {
7792 status = 0;
7793 }
7794 }
7795 }
7796
7797 // Set data for the fake xhr object
7798 jqXHR.status = status;
7799 jqXHR.statusText = ( nativeStatusText || statusText ) + "";
7800
7801 // Success/Error
7802 if ( isSuccess ) {
7803 deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
7804 } else {
7805 deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
7806 }
7807
7808 // Status-dependent callbacks
7809 jqXHR.statusCode( statusCode );
7810 statusCode = undefined;
7811
7812 if ( fireGlobals ) {
7813 globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ),
7814 [ jqXHR, s, isSuccess ? success : error ] );
7815 }
7816
7817 // Complete
7818 completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
7819
7820 if ( fireGlobals ) {
7821 globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
7822 // Handle the global AJAX counter
7823 if ( !( --jQuery.active ) ) {
7824 jQuery.event.trigger( "ajaxStop" );
7825 }
7826 }
7827 }
7828
7829 // Attach deferreds
7830 deferred.promise( jqXHR );
7831 jqXHR.success = jqXHR.done;
7832 jqXHR.error = jqXHR.fail;
7833 jqXHR.complete = completeDeferred.add;
7834
7835 // Status-dependent callbacks
7836 jqXHR.statusCode = function( map ) {
7837 if ( map ) {
7838 var tmp;
7839 if ( state < 2 ) {
7840 for ( tmp in map ) {
7841 statusCode[ tmp ] = [ statusCode[tmp], map[tmp] ];
7842 }
7843 } else {
7844 tmp = map[ jqXHR.status ];
7845 jqXHR.always( tmp );
7846 }
7847 }
7848 return this;
7849 };
7850
7851 // Remove hash character (#7531: and string promotion)
7852 // Add protocol if not provided (#5866: IE7 issue with protocol-less urls)
7853 // We also use the url parameter if available
7854 s.url = ( ( url || s.url ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
7855
7856 // Extract dataTypes list
7857 s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( core_rspace );
7858
7859 // A cross-domain request is in order when we have a protocol:host:port mismatch
7860 if ( s.crossDomain == null ) {
7861 parts = rurl.exec( s.url.toLowerCase() );
7862 s.crossDomain = !!( parts &&
7863 ( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||
7864 ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? 80 : 443 ) ) !=
7865 ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? 80 : 443 ) ) )
7866 );
7867 }
7868
7869 // Convert data if not already a string
7870 if ( s.data && s.processData && typeof s.data !== "string" ) {
7871 s.data = jQuery.param( s.data, s.traditional );
7872 }
7873
7874 // Apply prefilters
7875 inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
7876
7877 // If request was aborted inside a prefilter, stop there
7878 if ( state === 2 ) {
7879 return jqXHR;
7880 }
7881
7882 // We can fire global events as of now if asked to
7883 fireGlobals = s.global;
7884
7885 // Uppercase the type
7886 s.type = s.type.toUpperCase();
7887
7888 // Determine if request has content
7889 s.hasContent = !rnoContent.test( s.type );
7890
7891 // Watch for a new set of requests
7892 if ( fireGlobals && jQuery.active++ === 0 ) {
7893 jQuery.event.trigger( "ajaxStart" );
7894 }
7895
7896 // More options handling for requests with no content
7897 if ( !s.hasContent ) {
7898
7899 // If data is available, append data to url
7900 if ( s.data ) {
7901 s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data;
7902 // #9682: remove data so that it's not used in an eventual retry
7903 delete s.data;
7904 }
7905
7906 // Get ifModifiedKey before adding the anti-cache parameter
7907 ifModifiedKey = s.url;
7908
7909 // Add anti-cache in url if needed
7910 if ( s.cache === false ) {
7911
7912 var ts = jQuery.now(),
7913 // try replacing _= if it is there
7914 ret = s.url.replace( rts, "$1_=" + ts );
7915
7916 // if nothing was replaced, add timestamp to the end
7917 s.url = ret + ( ( ret === s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : "" );
7918 }
7919 }
7920
7921 // Set the correct header, if data is being sent
7922 if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
7923 jqXHR.setRequestHeader( "Content-Type", s.contentType );
7924 }
7925
7926 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
7927 if ( s.ifModified ) {
7928 ifModifiedKey = ifModifiedKey || s.url;
7929 if ( jQuery.lastModified[ ifModifiedKey ] ) {
7930 jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ ifModifiedKey ] );
7931 }
7932 if ( jQuery.etag[ ifModifiedKey ] ) {
7933 jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ ifModifiedKey ] );
7934 }
7935 }
7936
7937 // Set the Accepts header for the server, depending on the dataType
7938 jqXHR.setRequestHeader(
7939 "Accept",
7940 s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?
7941 s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
7942 s.accepts[ "*" ]
7943 );
7944
7945 // Check for headers option
7946 for ( i in s.headers ) {
7947 jqXHR.setRequestHeader( i, s.headers[ i ] );
7948 }
7949
7950 // Allow custom headers/mimetypes and early abort
7951 if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
7952 // Abort if not done already and return
7953 return jqXHR.abort();
7954
7955 }
7956
7957 // aborting is no longer a cancellation
7958 strAbort = "abort";
7959
7960 // Install callbacks on deferreds
7961 for ( i in { success: 1, error: 1, complete: 1 } ) {
7962 jqXHR[ i ]( s[ i ] );
7963 }
7964
7965 // Get transport
7966 transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
7967
7968 // If no transport, we auto-abort
7969 if ( !transport ) {
7970 done( -1, "No Transport" );
7971 } else {
7972 jqXHR.readyState = 1;
7973 // Send global event
7974 if ( fireGlobals ) {
7975 globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
7976 }
7977 // Timeout
7978 if ( s.async && s.timeout > 0 ) {
7979 timeoutTimer = setTimeout( function(){
7980 jqXHR.abort( "timeout" );
7981 }, s.timeout );
7982 }
7983
7984 try {
7985 state = 1;
7986 transport.send( requestHeaders, done );
7987 } catch (e) {
7988 // Propagate exception as error if not done
7989 if ( state < 2 ) {
7990 done( -1, e );
7991 // Simply rethrow otherwise
7992 } else {
7993 throw e;
7994 }
7995 }
7996 }
7997
7998 return jqXHR;
7999 },
8000
8001 // Counter for holding the number of active queries
8002 active: 0,
8003
8004 // Last-Modified header cache for next request
8005 lastModified: {},
8006 etag: {}
8007
8008 });
8009
8010 /* Handles responses to an ajax request:
8011 * - sets all responseXXX fields accordingly
8012 * - finds the right dataType (mediates between content-type and expected dataType)
8013 * - returns the corresponding response
8014 */
8015 function ajaxHandleResponses( s, jqXHR, responses ) {
8016
8017 var ct, type, finalDataType, firstDataType,
8018 contents = s.contents,
8019 dataTypes = s.dataTypes,
8020 responseFields = s.responseFields;
8021
8022 // Fill responseXXX fields
8023 for ( type in responseFields ) {
8024 if ( type in responses ) {
8025 jqXHR[ responseFields[type] ] = responses[ type ];
8026 }
8027 }
8028
8029 // Remove auto dataType and get content-type in the process
8030 while( dataTypes[ 0 ] === "*" ) {
8031 dataTypes.shift();
8032 if ( ct === undefined ) {
8033 ct = s.mimeType || jqXHR.getResponseHeader( "content-type" );
8034 }
8035 }
8036
8037 // Check if we're dealing with a known content-type
8038 if ( ct ) {
8039 for ( type in contents ) {
8040 if ( contents[ type ] && contents[ type ].test( ct ) ) {
8041 dataTypes.unshift( type );
8042 break;
8043 }
8044 }
8045 }
8046
8047 // Check to see if we have a response for the expected dataType
8048 if ( dataTypes[ 0 ] in responses ) {
8049 finalDataType = dataTypes[ 0 ];
8050 } else {
8051 // Try convertible dataTypes
8052 for ( type in responses ) {
8053 if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {
8054 finalDataType = type;
8055 break;
8056 }
8057 if ( !firstDataType ) {
8058 firstDataType = type;
8059 }
8060 }
8061 // Or just use first one
8062 finalDataType = finalDataType || firstDataType;
8063 }
8064
8065 // If we found a dataType
8066 // We add the dataType to the list if needed
8067 // and return the corresponding response
8068 if ( finalDataType ) {
8069 if ( finalDataType !== dataTypes[ 0 ] ) {
8070 dataTypes.unshift( finalDataType );
8071 }
8072 return responses[ finalDataType ];
8073 }
8074 }
8075
8076 // Chain conversions given the request and the original response
8077 function ajaxConvert( s, response ) {
8078
8079 var conv, conv2, current, tmp,
8080 // Work with a copy of dataTypes in case we need to modify it for conversion
8081 dataTypes = s.dataTypes.slice(),
8082 prev = dataTypes[ 0 ],
8083 converters = {},
8084 i = 0;
8085
8086 // Apply the dataFilter if provided
8087 if ( s.dataFilter ) {
8088 response = s.dataFilter( response, s.dataType );
8089 }
8090
8091 // Create converters map with lowercased keys
8092 if ( dataTypes[ 1 ] ) {
8093 for ( conv in s.converters ) {
8094 converters[ conv.toLowerCase() ] = s.converters[ conv ];
8095 }
8096 }
8097
8098 // Convert to each sequential dataType, tolerating list modification
8099 for ( ; (current = dataTypes[++i]); ) {
8100
8101 // There's only work to do if current dataType is non-auto
8102 if ( current !== "*" ) {
8103
8104 // Convert response if prev dataType is non-auto and differs from current
8105 if ( prev !== "*" && prev !== current ) {
8106
8107 // Seek a direct converter
8108 conv = converters[ prev + " " + current ] || converters[ "* " + current ];
8109
8110 // If none found, seek a pair
8111 if ( !conv ) {
8112 for ( conv2 in converters ) {
8113
8114 // If conv2 outputs current
8115 tmp = conv2.split(" ");
8116 if ( tmp[ 1 ] === current ) {
8117
8118 // If prev can be converted to accepted input
8119 conv = converters[ prev + " " + tmp[ 0 ] ] ||
8120 converters[ "* " + tmp[ 0 ] ];
8121 if ( conv ) {
8122 // Condense equivalence converters
8123 if ( conv === true ) {
8124 conv = converters[ conv2 ];
8125
8126 // Otherwise, insert the intermediate dataType
8127 } else if ( converters[ conv2 ] !== true ) {
8128 current = tmp[ 0 ];
8129 dataTypes.splice( i--, 0, current );
8130 }
8131
8132 break;
8133 }
8134 }
8135 }
8136 }
8137
8138 // Apply converter (if not an equivalence)
8139 if ( conv !== true ) {
8140
8141 // Unless errors are allowed to bubble, catch and return them
8142 if ( conv && s["throws"] ) {
8143 response = conv( response );
8144 } else {
8145 try {
8146 response = conv( response );
8147 } catch ( e ) {
8148 return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current };
8149 }
8150 }
8151 }
8152 }
8153
8154 // Update prev for next iteration
8155 prev = current;
8156 }
8157 }
8158
8159 return { state: "success", data: response };
8160 }
8161 var oldCallbacks = [],
8162 rquestion = /\?/,
8163 rjsonp = /(=)\?(?=&|$)|\?\?/,
8164 nonce = jQuery.now();
8165
8166 // Default jsonp settings
8167 jQuery.ajaxSetup({
8168 jsonp: "callback",
8169 jsonpCallback: function() {
8170 var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );
8171 this[ callback ] = true;
8172 return callback;
8173 }
8174 });
8175
8176 // Detect, normalize options and install callbacks for jsonp requests
8177 jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
8178
8179 var callbackName, overwritten, responseContainer,
8180 data = s.data,
8181 url = s.url,
8182 hasCallback = s.jsonp !== false,
8183 replaceInUrl = hasCallback && rjsonp.test( url ),
8184 replaceInData = hasCallback && !replaceInUrl && typeof data === "string" &&
8185 !( s.contentType || "" ).indexOf("application/x-www-form-urlencoded") &&
8186 rjsonp.test( data );
8187
8188 // Handle iff the expected data type is "jsonp" or we have a parameter to set
8189 if ( s.dataTypes[ 0 ] === "jsonp" || replaceInUrl || replaceInData ) {
8190
8191 // Get callback name, remembering preexisting value associated with it
8192 callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
8193 s.jsonpCallback() :
8194 s.jsonpCallback;
8195 overwritten = window[ callbackName ];
8196
8197 // Insert callback into url or form data
8198 if ( replaceInUrl ) {
8199 s.url = url.replace( rjsonp, "$1" + callbackName );
8200 } else if ( replaceInData ) {
8201 s.data = data.replace( rjsonp, "$1" + callbackName );
8202 } else if ( hasCallback ) {
8203 s.url += ( rquestion.test( url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
8204 }
8205
8206 // Use data converter to retrieve json after script execution
8207 s.converters["script json"] = function() {
8208 if ( !responseContainer ) {
8209 jQuery.error( callbackName + " was not called" );
8210 }
8211 return responseContainer[ 0 ];
8212 };
8213
8214 // force json dataType
8215 s.dataTypes[ 0 ] = "json";
8216
8217 // Install callback
8218 window[ callbackName ] = function() {
8219 responseContainer = arguments;
8220 };
8221
8222 // Clean-up function (fires after converters)
8223 jqXHR.always(function() {
8224 // Restore preexisting value
8225 window[ callbackName ] = overwritten;
8226
8227 // Save back as free
8228 if ( s[ callbackName ] ) {
8229 // make sure that re-using the options doesn't screw things around
8230 s.jsonpCallback = originalSettings.jsonpCallback;
8231
8232 // save the callback name for future use
8233 oldCallbacks.push( callbackName );
8234 }
8235
8236 // Call if it was a function and we have a response
8237 if ( responseContainer && jQuery.isFunction( overwritten ) ) {
8238 overwritten( responseContainer[ 0 ] );
8239 }
8240
8241 responseContainer = overwritten = undefined;
8242 });
8243
8244 // Delegate to script
8245 return "script";
8246 }
8247 });
8248 // Install script dataType
8249 jQuery.ajaxSetup({
8250 accepts: {
8251 script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
8252 },
8253 contents: {
8254 script: /javascript|ecmascript/
8255 },
8256 converters: {
8257 "text script": function( text ) {
8258 jQuery.globalEval( text );
8259 return text;
8260 }
8261 }
8262 });
8263
8264 // Handle cache's special case and global
8265 jQuery.ajaxPrefilter( "script", function( s ) {
8266 if ( s.cache === undefined ) {
8267 s.cache = false;
8268 }
8269 if ( s.crossDomain ) {
8270 s.type = "GET";
8271 s.global = false;
8272 }
8273 });
8274
8275 // Bind script tag hack transport
8276 jQuery.ajaxTransport( "script", function(s) {
8277
8278 // This transport only deals with cross domain requests
8279 if ( s.crossDomain ) {
8280
8281 var script,
8282 head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement;
8283
8284 return {
8285
8286 send: function( _, callback ) {
8287
8288 script = document.createElement( "script" );
8289
8290 script.async = "async";
8291
8292 if ( s.scriptCharset ) {
8293 script.charset = s.scriptCharset;
8294 }
8295
8296 script.src = s.url;
8297
8298 // Attach handlers for all browsers
8299 script.onload = script.onreadystatechange = function( _, isAbort ) {
8300
8301 if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {
8302
8303 // Handle memory leak in IE
8304 script.onload = script.onreadystatechange = null;
8305
8306 // Remove the script
8307 if ( head && script.parentNode ) {
8308 head.removeChild( script );
8309 }
8310
8311 // Dereference the script
8312 script = undefined;
8313
8314 // Callback if not abort
8315 if ( !isAbort ) {
8316 callback( 200, "success" );
8317 }
8318 }
8319 };
8320 // Use insertBefore instead of appendChild to circumvent an IE6 bug.
8321 // This arises when a base node is used (#2709 and #4378).
8322 head.insertBefore( script, head.firstChild );
8323 },
8324
8325 abort: function() {
8326 if ( script ) {
8327 script.onload( 0, 1 );
8328 }
8329 }
8330 };
8331 }
8332 });
8333 var xhrCallbacks,
8334 // #5280: Internet Explorer will keep connections alive if we don't abort on unload
8335 xhrOnUnloadAbort = window.ActiveXObject ? function() {
8336 // Abort all pending requests
8337 for ( var key in xhrCallbacks ) {
8338 xhrCallbacks[ key ]( 0, 1 );
8339 }
8340 } : false,
8341 xhrId = 0;
8342
8343 // Functions to create xhrs
8344 function createStandardXHR() {
8345 try {
8346 return new window.XMLHttpRequest();
8347 } catch( e ) {}
8348 }
8349
8350 function createActiveXHR() {
8351 try {
8352 return new window.ActiveXObject( "Microsoft.XMLHTTP" );
8353 } catch( e ) {}
8354 }
8355
8356 // Create the request object
8357 // (This is still attached to ajaxSettings for backward compatibility)
8358 jQuery.ajaxSettings.xhr = window.ActiveXObject ?
8359 /* Microsoft failed to properly
8360 * implement the XMLHttpRequest in IE7 (can't request local files),
8361 * so we use the ActiveXObject when it is available
8362 * Additionally XMLHttpRequest can be disabled in IE7/IE8 so
8363 * we need a fallback.
8364 */
8365 function() {
8366 return !this.isLocal && createStandardXHR() || createActiveXHR();
8367 } :
8368 // For all other browsers, use the standard XMLHttpRequest object
8369 createStandardXHR;
8370
8371 // Determine support properties
8372 (function( xhr ) {
8373 jQuery.extend( jQuery.support, {
8374 ajax: !!xhr,
8375 cors: !!xhr && ( "withCredentials" in xhr )
8376 });
8377 })( jQuery.ajaxSettings.xhr() );
8378
8379 // Create transport if the browser can provide an xhr
8380 if ( jQuery.support.ajax ) {
8381
8382 jQuery.ajaxTransport(function( s ) {
8383 // Cross domain only allowed if supported through XMLHttpRequest
8384 if ( !s.crossDomain || jQuery.support.cors ) {
8385
8386 var callback;
8387
8388 return {
8389 send: function( headers, complete ) {
8390
8391 // Get a new xhr
8392 var handle, i,
8393 xhr = s.xhr();
8394
8395 // Open the socket
8396 // Passing null username, generates a login popup on Opera (#2865)
8397 if ( s.username ) {
8398 xhr.open( s.type, s.url, s.async, s.username, s.password );
8399 } else {
8400 xhr.open( s.type, s.url, s.async );
8401 }
8402
8403 // Apply custom fields if provided
8404 if ( s.xhrFields ) {
8405 for ( i in s.xhrFields ) {
8406 xhr[ i ] = s.xhrFields[ i ];
8407 }
8408 }
8409
8410 // Override mime type if needed
8411 if ( s.mimeType && xhr.overrideMimeType ) {
8412 xhr.overrideMimeType( s.mimeType );
8413 }
8414
8415 // X-Requested-With header
8416 // For cross-domain requests, seeing as conditions for a preflight are
8417 // akin to a jigsaw puzzle, we simply never set it to be sure.
8418 // (it can always be set on a per-request basis or even using ajaxSetup)
8419 // For same-domain requests, won't change header if already provided.
8420 if ( !s.crossDomain && !headers["X-Requested-With"] ) {
8421 headers[ "X-Requested-With" ] = "XMLHttpRequest";
8422 }
8423
8424 // Need an extra try/catch for cross domain requests in Firefox 3
8425 try {
8426 for ( i in headers ) {
8427 xhr.setRequestHeader( i, headers[ i ] );
8428 }
8429 } catch( _ ) {}
8430
8431 // Do send the request
8432 // This may raise an exception which is actually
8433 // handled in jQuery.ajax (so no try/catch here)
8434 xhr.send( ( s.hasContent && s.data ) || null );
8435
8436 // Listener
8437 callback = function( _, isAbort ) {
8438
8439 var status,
8440 statusText,
8441 responseHeaders,
8442 responses,
8443 xml;
8444
8445 // Firefox throws exceptions when accessing properties
8446 // of an xhr when a network error occurred
8447 // http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE)
8448 try {
8449
8450 // Was never called and is aborted or complete
8451 if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
8452
8453 // Only called once
8454 callback = undefined;
8455
8456 // Do not keep as active anymore
8457 if ( handle ) {
8458 xhr.onreadystatechange = jQuery.noop;
8459 if ( xhrOnUnloadAbort ) {
8460 delete xhrCallbacks[ handle ];
8461 }
8462 }
8463
8464 // If it's an abort
8465 if ( isAbort ) {
8466 // Abort it manually if needed
8467 if ( xhr.readyState !== 4 ) {
8468 xhr.abort();
8469 }
8470 } else {
8471 status = xhr.status;
8472 responseHeaders = xhr.getAllResponseHeaders();
8473 responses = {};
8474 xml = xhr.responseXML;
8475
8476 // Construct response list
8477 if ( xml && xml.documentElement /* #4958 */ ) {
8478 responses.xml = xml;
8479 }
8480
8481 // When requesting binary data, IE6-9 will throw an exception
8482 // on any attempt to access responseText (#11426)
8483 try {
8484 responses.text = xhr.responseText;
8485 } catch( e ) {
8486 }
8487
8488 // Firefox throws an exception when accessing
8489 // statusText for faulty cross-domain requests
8490 try {
8491 statusText = xhr.statusText;
8492 } catch( e ) {
8493 // We normalize with Webkit giving an empty statusText
8494 statusText = "";
8495 }
8496
8497 // Filter status for non standard behaviors
8498
8499 // If the request is local and we have data: assume a success
8500 // (success with no data won't get notified, that's the best we
8501 // can do given current implementations)
8502 if ( !status && s.isLocal && !s.crossDomain ) {
8503 status = responses.text ? 200 : 404;
8504 // IE - #1450: sometimes returns 1223 when it should be 204
8505 } else if ( status === 1223 ) {
8506 status = 204;
8507 }
8508 }
8509 }
8510 } catch( firefoxAccessException ) {
8511 if ( !isAbort ) {
8512 complete( -1, firefoxAccessException );
8513 }
8514 }
8515
8516 // Call complete if needed
8517 if ( responses ) {
8518 complete( status, statusText, responses, responseHeaders );
8519 }
8520 };
8521
8522 if ( !s.async ) {
8523 // if we're in sync mode we fire the callback
8524 callback();
8525 } else if ( xhr.readyState === 4 ) {
8526 // (IE6 & IE7) if it's in cache and has been
8527 // retrieved directly we need to fire the callback
8528 setTimeout( callback, 0 );
8529 } else {
8530 handle = ++xhrId;
8531 if ( xhrOnUnloadAbort ) {
8532 // Create the active xhrs callbacks list if needed
8533 // and attach the unload handler
8534 if ( !xhrCallbacks ) {
8535 xhrCallbacks = {};
8536 jQuery( window ).unload( xhrOnUnloadAbort );
8537 }
8538 // Add to list of active xhrs callbacks
8539 xhrCallbacks[ handle ] = callback;
8540 }
8541 xhr.onreadystatechange = callback;
8542 }
8543 },
8544
8545 abort: function() {
8546 if ( callback ) {
8547 callback(0,1);
8548 }
8549 }
8550 };
8551 }
8552 });
8553 }
8554 var fxNow, timerId,
8555 rfxtypes = /^(?:toggle|show|hide)$/,
8556 rfxnum = new RegExp( "^(?:([-+])=|)(" + core_pnum + ")([a-z%]*)$", "i" ),
8557 rrun = /queueHooks$/,
8558 animationPrefilters = [ defaultPrefilter ],
8559 tweeners = {
8560 "*": [function( prop, value ) {
8561 var end, unit,
8562 tween = this.createTween( prop, value ),
8563 parts = rfxnum.exec( value ),
8564 target = tween.cur(),
8565 start = +target || 0,
8566 scale = 1,
8567 maxIterations = 20;
8568
8569 if ( parts ) {
8570 end = +parts[2];
8571 unit = parts[3] || ( jQuery.cssNumber[ prop ] ? "" : "px" );
8572
8573 // We need to compute starting value
8574 if ( unit !== "px" && start ) {
8575 // Iteratively approximate from a nonzero starting point
8576 // Prefer the current property, because this process will be trivial if it uses the same units
8577 // Fallback to end or a simple constant
8578 start = jQuery.css( tween.elem, prop, true ) || end || 1;
8579
8580 do {
8581 // If previous iteration zeroed out, double until we get *something*
8582 // Use a string for doubling factor so we don't accidentally see scale as unchanged below
8583 scale = scale || ".5";
8584
8585 // Adjust and apply
8586 start = start / scale;
8587 jQuery.style( tween.elem, prop, start + unit );
8588
8589 // Update scale, tolerating zero or NaN from tween.cur()
8590 // And breaking the loop if scale is unchanged or perfect, or if we've just had enough
8591 } while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations );
8592 }
8593
8594 tween.unit = unit;
8595 tween.start = start;
8596 // If a +=/-= token was provided, we're doing a relative animation
8597 tween.end = parts[1] ? start + ( parts[1] + 1 ) * end : end;
8598 }
8599 return tween;
8600 }]
8601 };
8602
8603 // Animations created synchronously will run synchronously
8604 function createFxNow() {
8605 setTimeout(function() {
8606 fxNow = undefined;
8607 }, 0 );
8608 return ( fxNow = jQuery.now() );
8609 }
8610
8611 function createTweens( animation, props ) {
8612 jQuery.each( props, function( prop, value ) {
8613 var collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ),
8614 index = 0,
8615 length = collection.length;
8616 for ( ; index < length; index++ ) {
8617 if ( collection[ index ].call( animation, prop, value ) ) {
8618
8619 // we're done with this property
8620 return;
8621 }
8622 }
8623 });
8624 }
8625
8626 function Animation( elem, properties, options ) {
8627 var result,
8628 index = 0,
8629 tweenerIndex = 0,
8630 length = animationPrefilters.length,
8631 deferred = jQuery.Deferred().always( function() {
8632 // don't match elem in the :animated selector
8633 delete tick.elem;
8634 }),
8635 tick = function() {
8636 var currentTime = fxNow || createFxNow(),
8637 remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
8638 // archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497)
8639 temp = remaining / animation.duration || 0,
8640 percent = 1 - temp,
8641 index = 0,
8642 length = animation.tweens.length;
8643
8644 for ( ; index < length ; index++ ) {
8645 animation.tweens[ index ].run( percent );
8646 }
8647
8648 deferred.notifyWith( elem, [ animation, percent, remaining ]);
8649
8650 if ( percent < 1 && length ) {
8651 return remaining;
8652 } else {
8653 deferred.resolveWith( elem, [ animation ] );
8654 return false;
8655 }
8656 },
8657 animation = deferred.promise({
8658 elem: elem,
8659 props: jQuery.extend( {}, properties ),
8660 opts: jQuery.extend( true, { specialEasing: {} }, options ),
8661 originalProperties: properties,
8662 originalOptions: options,
8663 startTime: fxNow || createFxNow(),
8664 duration: options.duration,
8665 tweens: [],
8666 createTween: function( prop, end, easing ) {
8667 var tween = jQuery.Tween( elem, animation.opts, prop, end,
8668 animation.opts.specialEasing[ prop ] || animation.opts.easing );
8669 animation.tweens.push( tween );
8670 return tween;
8671 },
8672 stop: function( gotoEnd ) {
8673 var index = 0,
8674 // if we are going to the end, we want to run all the tweens
8675 // otherwise we skip this part
8676 length = gotoEnd ? animation.tweens.length : 0;
8677
8678 for ( ; index < length ; index++ ) {
8679 animation.tweens[ index ].run( 1 );
8680 }
8681
8682 // resolve when we played the last frame
8683 // otherwise, reject
8684 if ( gotoEnd ) {
8685 deferred.resolveWith( elem, [ animation, gotoEnd ] );
8686 } else {
8687 deferred.rejectWith( elem, [ animation, gotoEnd ] );
8688 }
8689 return this;
8690 }
8691 }),
8692 props = animation.props;
8693
8694 propFilter( props, animation.opts.specialEasing );
8695
8696 for ( ; index < length ; index++ ) {
8697 result = animationPrefilters[ index ].call( animation, elem, props, animation.opts );
8698 if ( result ) {
8699 return result;
8700 }
8701 }
8702
8703 createTweens( animation, props );
8704
8705 if ( jQuery.isFunction( animation.opts.start ) ) {
8706 animation.opts.start.call( elem, animation );
8707 }
8708
8709 jQuery.fx.timer(
8710 jQuery.extend( tick, {
8711 anim: animation,
8712 queue: animation.opts.queue,
8713 elem: elem
8714 })
8715 );
8716
8717 // attach callbacks from options
8718 return animation.progress( animation.opts.progress )
8719 .done( animation.opts.done, animation.opts.complete )
8720 .fail( animation.opts.fail )
8721 .always( animation.opts.always );
8722 }
8723
8724 function propFilter( props, specialEasing ) {
8725 var index, name, easing, value, hooks;
8726
8727 // camelCase, specialEasing and expand cssHook pass
8728 for ( index in props ) {
8729 name = jQuery.camelCase( index );
8730 easing = specialEasing[ name ];
8731 value = props[ index ];
8732 if ( jQuery.isArray( value ) ) {
8733 easing = value[ 1 ];
8734 value = props[ index ] = value[ 0 ];
8735 }
8736
8737 if ( index !== name ) {
8738 props[ name ] = value;
8739 delete props[ index ];
8740 }
8741
8742 hooks = jQuery.cssHooks[ name ];
8743 if ( hooks && "expand" in hooks ) {
8744 value = hooks.expand( value );
8745 delete props[ name ];
8746
8747 // not quite $.extend, this wont overwrite keys already present.
8748 // also - reusing 'index' from above because we have the correct "name"
8749 for ( index in value ) {
8750 if ( !( index in props ) ) {
8751 props[ index ] = value[ index ];
8752 specialEasing[ index ] = easing;
8753 }
8754 }
8755 } else {
8756 specialEasing[ name ] = easing;
8757 }
8758 }
8759 }
8760
8761 jQuery.Animation = jQuery.extend( Animation, {
8762
8763 tweener: function( props, callback ) {
8764 if ( jQuery.isFunction( props ) ) {
8765 callback = props;
8766 props = [ "*" ];
8767 } else {
8768 props = props.split(" ");
8769 }
8770
8771 var prop,
8772 index = 0,
8773 length = props.length;
8774
8775 for ( ; index < length ; index++ ) {
8776 prop = props[ index ];
8777 tweeners[ prop ] = tweeners[ prop ] || [];
8778 tweeners[ prop ].unshift( callback );
8779 }
8780 },
8781
8782 prefilter: function( callback, prepend ) {
8783 if ( prepend ) {
8784 animationPrefilters.unshift( callback );
8785 } else {
8786 animationPrefilters.push( callback );
8787 }
8788 }
8789 });
8790
8791 function defaultPrefilter( elem, props, opts ) {
8792 var index, prop, value, length, dataShow, toggle, tween, hooks, oldfire,
8793 anim = this,
8794 style = elem.style,
8795 orig = {},
8796 handled = [],
8797 hidden = elem.nodeType && isHidden( elem );
8798
8799 // handle queue: false promises
8800 if ( !opts.queue ) {
8801 hooks = jQuery._queueHooks( elem, "fx" );
8802 if ( hooks.unqueued == null ) {
8803 hooks.unqueued = 0;
8804 oldfire = hooks.empty.fire;
8805 hooks.empty.fire = function() {
8806 if ( !hooks.unqueued ) {
8807 oldfire();
8808 }
8809 };
8810 }
8811 hooks.unqueued++;
8812
8813 anim.always(function() {
8814 // doing this makes sure that the complete handler will be called
8815 // before this completes
8816 anim.always(function() {
8817 hooks.unqueued--;
8818 if ( !jQuery.queue( elem, "fx" ).length ) {
8819 hooks.empty.fire();
8820 }
8821 });
8822 });
8823 }
8824
8825 // height/width overflow pass
8826 if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) {
8827 // Make sure that nothing sneaks out
8828 // Record all 3 overflow attributes because IE does not
8829 // change the overflow attribute when overflowX and
8830 // overflowY are set to the same value
8831 opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
8832
8833 // Set display property to inline-block for height/width
8834 // animations on inline elements that are having width/height animated
8835 if ( jQuery.css( elem, "display" ) === "inline" &&
8836 jQuery.css( elem, "float" ) === "none" ) {
8837
8838 // inline-level elements accept inline-block;
8839 // block-level elements need to be inline with layout
8840 if ( !jQuery.support.inlineBlockNeedsLayout || css_defaultDisplay( elem.nodeName ) === "inline" ) {
8841 style.display = "inline-block";
8842
8843 } else {
8844 style.zoom = 1;
8845 }
8846 }
8847 }
8848
8849 if ( opts.overflow ) {
8850 style.overflow = "hidden";
8851 if ( !jQuery.support.shrinkWrapBlocks ) {
8852 anim.done(function() {
8853 style.overflow = opts.overflow[ 0 ];
8854 style.overflowX = opts.overflow[ 1 ];
8855 style.overflowY = opts.overflow[ 2 ];
8856 });
8857 }
8858 }
8859
8860
8861 // show/hide pass
8862 for ( index in props ) {
8863 value = props[ index ];
8864 if ( rfxtypes.exec( value ) ) {
8865 delete props[ index ];
8866 toggle = toggle || value === "toggle";
8867 if ( value === ( hidden ? "hide" : "show" ) ) {
8868 continue;
8869 }
8870 handled.push( index );
8871 }
8872 }
8873
8874 length = handled.length;
8875 if ( length ) {
8876 dataShow = jQuery._data( elem, "fxshow" ) || jQuery._data( elem, "fxshow", {} );
8877 if ( "hidden" in dataShow ) {
8878 hidden = dataShow.hidden;
8879 }
8880
8881 // store state if its toggle - enables .stop().toggle() to "reverse"
8882 if ( toggle ) {
8883 dataShow.hidden = !hidden;
8884 }
8885 if ( hidden ) {
8886 jQuery( elem ).show();
8887 } else {
8888 anim.done(function() {
8889 jQuery( elem ).hide();
8890 });
8891 }
8892 anim.done(function() {
8893 var prop;
8894 jQuery.removeData( elem, "fxshow", true );
8895 for ( prop in orig ) {
8896 jQuery.style( elem, prop, orig[ prop ] );
8897 }
8898 });
8899 for ( index = 0 ; index < length ; index++ ) {
8900 prop = handled[ index ];
8901 tween = anim.createTween( prop, hidden ? dataShow[ prop ] : 0 );
8902 orig[ prop ] = dataShow[ prop ] || jQuery.style( elem, prop );
8903
8904 if ( !( prop in dataShow ) ) {
8905 dataShow[ prop ] = tween.start;
8906 if ( hidden ) {
8907 tween.end = tween.start;
8908 tween.start = prop === "width" || prop === "height" ? 1 : 0;
8909 }
8910 }
8911 }
8912 }
8913 }
8914
8915 function Tween( elem, options, prop, end, easing ) {
8916 return new Tween.prototype.init( elem, options, prop, end, easing );
8917 }
8918 jQuery.Tween = Tween;
8919
8920 Tween.prototype = {
8921 constructor: Tween,
8922 init: function( elem, options, prop, end, easing, unit ) {
8923 this.elem = elem;
8924 this.prop = prop;
8925 this.easing = easing || "swing";
8926 this.options = options;
8927 this.start = this.now = this.cur();
8928 this.end = end;
8929 this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
8930 },
8931 cur: function() {
8932 var hooks = Tween.propHooks[ this.prop ];
8933
8934 return hooks && hooks.get ?
8935 hooks.get( this ) :
8936 Tween.propHooks._default.get( this );
8937 },
8938 run: function( percent ) {
8939 var eased,
8940 hooks = Tween.propHooks[ this.prop ];
8941
8942 if ( this.options.duration ) {
8943 this.pos = eased = jQuery.easing[ this.easing ](
8944 percent, this.options.duration * percent, 0, 1, this.options.duration
8945 );
8946 } else {
8947 this.pos = eased = percent;
8948 }
8949 this.now = ( this.end - this.start ) * eased + this.start;
8950
8951 if ( this.options.step ) {
8952 this.options.step.call( this.elem, this.now, this );
8953 }
8954
8955 if ( hooks && hooks.set ) {
8956 hooks.set( this );
8957 } else {
8958 Tween.propHooks._default.set( this );
8959 }
8960 return this;
8961 }
8962 };
8963
8964 Tween.prototype.init.prototype = Tween.prototype;
8965
8966 Tween.propHooks = {
8967 _default: {
8968 get: function( tween ) {
8969 var result;
8970
8971 if ( tween.elem[ tween.prop ] != null &&
8972 (!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) {
8973 return tween.elem[ tween.prop ];
8974 }
8975
8976 // passing any value as a 4th parameter to .css will automatically
8977 // attempt a parseFloat and fallback to a string if the parse fails
8978 // so, simple values such as "10px" are parsed to Float.
8979 // complex values such as "rotate(1rad)" are returned as is.
8980 result = jQuery.css( tween.elem, tween.prop, false, "" );
8981 // Empty strings, null, undefined and "auto" are converted to 0.
8982 return !result || result === "auto" ? 0 : result;
8983 },
8984 set: function( tween ) {
8985 // use step hook for back compat - use cssHook if its there - use .style if its
8986 // available and use plain properties where available
8987 if ( jQuery.fx.step[ tween.prop ] ) {
8988 jQuery.fx.step[ tween.prop ]( tween );
8989 } else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) {
8990 jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
8991 } else {
8992 tween.elem[ tween.prop ] = tween.now;
8993 }
8994 }
8995 }
8996 };
8997
8998 // Remove in 2.0 - this supports IE8's panic based approach
8999 // to setting things on disconnected nodes
9000
9001 Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
9002 set: function( tween ) {
9003 if ( tween.elem.nodeType && tween.elem.parentNode ) {
9004 tween.elem[ tween.prop ] = tween.now;
9005 }
9006 }
9007 };
9008
9009 jQuery.each([ "toggle", "show", "hide" ], function( i, name ) {
9010 var cssFn = jQuery.fn[ name ];
9011 jQuery.fn[ name ] = function( speed, easing, callback ) {
9012 return speed == null || typeof speed === "boolean" ||
9013 // special check for .toggle( handler, handler, ... )
9014 ( !i && jQuery.isFunction( speed ) && jQuery.isFunction( easing ) ) ?
9015 cssFn.apply( this, arguments ) :
9016 this.animate( genFx( name, true ), speed, easing, callback );
9017 };
9018 });
9019
9020 jQuery.fn.extend({
9021 fadeTo: function( speed, to, easing, callback ) {
9022
9023 // show any hidden elements after setting opacity to 0
9024 return this.filter( isHidden ).css( "opacity", 0 ).show()
9025
9026 // animate to the value specified
9027 .end().animate({ opacity: to }, speed, easing, callback );
9028 },
9029 animate: function( prop, speed, easing, callback ) {
9030 var empty = jQuery.isEmptyObject( prop ),
9031 optall = jQuery.speed( speed, easing, callback ),
9032 doAnimation = function() {
9033 // Operate on a copy of prop so per-property easing won't be lost
9034 var anim = Animation( this, jQuery.extend( {}, prop ), optall );
9035
9036 // Empty animations resolve immediately
9037 if ( empty ) {
9038 anim.stop( true );
9039 }
9040 };
9041
9042 return empty || optall.queue === false ?
9043 this.each( doAnimation ) :
9044 this.queue( optall.queue, doAnimation );
9045 },
9046 stop: function( type, clearQueue, gotoEnd ) {
9047 var stopQueue = function( hooks ) {
9048 var stop = hooks.stop;
9049 delete hooks.stop;
9050 stop( gotoEnd );
9051 };
9052
9053 if ( typeof type !== "string" ) {
9054 gotoEnd = clearQueue;
9055 clearQueue = type;
9056 type = undefined;
9057 }
9058 if ( clearQueue && type !== false ) {
9059 this.queue( type || "fx", [] );
9060 }
9061
9062 return this.each(function() {
9063 var dequeue = true,
9064 index = type != null && type + "queueHooks",
9065 timers = jQuery.timers,
9066 data = jQuery._data( this );
9067
9068 if ( index ) {
9069 if ( data[ index ] && data[ index ].stop ) {
9070 stopQueue( data[ index ] );
9071 }
9072 } else {
9073 for ( index in data ) {
9074 if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
9075 stopQueue( data[ index ] );
9076 }
9077 }
9078 }
9079
9080 for ( index = timers.length; index--; ) {
9081 if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {
9082 timers[ index ].anim.stop( gotoEnd );
9083 dequeue = false;
9084 timers.splice( index, 1 );
9085 }
9086 }
9087
9088 // start the next in the queue if the last step wasn't forced
9089 // timers currently will call their complete callbacks, which will dequeue
9090 // but only if they were gotoEnd
9091 if ( dequeue || !gotoEnd ) {
9092 jQuery.dequeue( this, type );
9093 }
9094 });
9095 }
9096 });
9097
9098 // Generate parameters to create a standard animation
9099 function genFx( type, includeWidth ) {
9100 var which,
9101 attrs = { height: type },
9102 i = 0;
9103
9104 // if we include width, step value is 1 to do all cssExpand values,
9105 // if we don't include width, step value is 2 to skip over Left and Right
9106 includeWidth = includeWidth? 1 : 0;
9107 for( ; i < 4 ; i += 2 - includeWidth ) {
9108 which = cssExpand[ i ];
9109 attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
9110 }
9111
9112 if ( includeWidth ) {
9113 attrs.opacity = attrs.width = type;
9114 }
9115
9116 return attrs;
9117 }
9118
9119 // Generate shortcuts for custom animations
9120 jQuery.each({
9121 slideDown: genFx("show"),
9122 slideUp: genFx("hide"),
9123 slideToggle: genFx("toggle"),
9124 fadeIn: { opacity: "show" },
9125 fadeOut: { opacity: "hide" },
9126 fadeToggle: { opacity: "toggle" }
9127 }, function( name, props ) {
9128 jQuery.fn[ name ] = function( speed, easing, callback ) {
9129 return this.animate( props, speed, easing, callback );
9130 };
9131 });
9132
9133 jQuery.speed = function( speed, easing, fn ) {
9134 var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
9135 complete: fn || !fn && easing ||
9136 jQuery.isFunction( speed ) && speed,
9137 duration: speed,
9138 easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
9139 };
9140
9141 opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
9142 opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
9143
9144 // normalize opt.queue - true/undefined/null -> "fx"
9145 if ( opt.queue == null || opt.queue === true ) {
9146 opt.queue = "fx";
9147 }
9148
9149 // Queueing
9150 opt.old = opt.complete;
9151
9152 opt.complete = function() {
9153 if ( jQuery.isFunction( opt.old ) ) {
9154 opt.old.call( this );
9155 }
9156
9157 if ( opt.queue ) {
9158 jQuery.dequeue( this, opt.queue );
9159 }
9160 };
9161
9162 return opt;
9163 };
9164
9165 jQuery.easing = {
9166 linear: function( p ) {
9167 return p;
9168 },
9169 swing: function( p ) {
9170 return 0.5 - Math.cos( p*Math.PI ) / 2;
9171 }
9172 };
9173
9174 jQuery.timers = [];
9175 jQuery.fx = Tween.prototype.init;
9176 jQuery.fx.tick = function() {
9177 var timer,
9178 timers = jQuery.timers,
9179 i = 0;
9180
9181 fxNow = jQuery.now();
9182
9183 for ( ; i < timers.length; i++ ) {
9184 timer = timers[ i ];
9185 // Checks the timer has not already been removed
9186 if ( !timer() && timers[ i ] === timer ) {
9187 timers.splice( i--, 1 );
9188 }
9189 }
9190
9191 if ( !timers.length ) {
9192 jQuery.fx.stop();
9193 }
9194 fxNow = undefined;
9195 };
9196
9197 jQuery.fx.timer = function( timer ) {
9198 if ( timer() && jQuery.timers.push( timer ) && !timerId ) {
9199 timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );
9200 }
9201 };
9202
9203 jQuery.fx.interval = 13;
9204
9205 jQuery.fx.stop = function() {
9206 clearInterval( timerId );
9207 timerId = null;
9208 };
9209
9210 jQuery.fx.speeds = {
9211 slow: 600,
9212 fast: 200,
9213 // Default speed
9214 _default: 400
9215 };
9216
9217 // Back Compat <1.8 extension point
9218 jQuery.fx.step = {};
9219
9220 if ( jQuery.expr && jQuery.expr.filters ) {
9221 jQuery.expr.filters.animated = function( elem ) {
9222 return jQuery.grep(jQuery.timers, function( fn ) {
9223 return elem === fn.elem;
9224 }).length;
9225 };
9226 }
9227 var rroot = /^(?:body|html)$/i;
9228
9229 jQuery.fn.offset = function( options ) {
9230 if ( arguments.length ) {
9231 return options === undefined ?
9232 this :
9233 this.each(function( i ) {
9234 jQuery.offset.setOffset( this, options, i );
9235 });
9236 }
9237
9238 var docElem, body, win, clientTop, clientLeft, scrollTop, scrollLeft,
9239 box = { top: 0, left: 0 },
9240 elem = this[ 0 ],
9241 doc = elem && elem.ownerDocument;
9242
9243 if ( !doc ) {
9244 return;
9245 }
9246
9247 if ( (body = doc.body) === elem ) {
9248 return jQuery.offset.bodyOffset( elem );
9249 }
9250
9251 docElem = doc.documentElement;
9252
9253 // Make sure it's not a disconnected DOM node
9254 if ( !jQuery.contains( docElem, elem ) ) {
9255 return box;
9256 }
9257
9258 // If we don't have gBCR, just use 0,0 rather than error
9259 // BlackBerry 5, iOS 3 (original iPhone)
9260 if ( typeof elem.getBoundingClientRect !== "undefined" ) {
9261 box = elem.getBoundingClientRect();
9262 }
9263 win = getWindow( doc );
9264 clientTop = docElem.clientTop || body.clientTop || 0;
9265 clientLeft = docElem.clientLeft || body.clientLeft || 0;
9266 scrollTop = win.pageYOffset || docElem.scrollTop;
9267 scrollLeft = win.pageXOffset || docElem.scrollLeft;
9268 return {
9269 top: box.top + scrollTop - clientTop,
9270 left: box.left + scrollLeft - clientLeft
9271 };
9272 };
9273
9274 jQuery.offset = {
9275
9276 bodyOffset: function( body ) {
9277 var top = body.offsetTop,
9278 left = body.offsetLeft;
9279
9280 if ( jQuery.support.doesNotIncludeMarginInBodyOffset ) {
9281 top += parseFloat( jQuery.css(body, "marginTop") ) || 0;
9282 left += parseFloat( jQuery.css(body, "marginLeft") ) || 0;
9283 }
9284
9285 return { top: top, left: left };
9286 },
9287
9288 setOffset: function( elem, options, i ) {
9289 var position = jQuery.css( elem, "position" );
9290
9291 // set position first, in-case top/left are set even on static elem
9292 if ( position === "static" ) {
9293 elem.style.position = "relative";
9294 }
9295
9296 var curElem = jQuery( elem ),
9297 curOffset = curElem.offset(),
9298 curCSSTop = jQuery.css( elem, "top" ),
9299 curCSSLeft = jQuery.css( elem, "left" ),
9300 calculatePosition = ( position === "absolute" || position === "fixed" ) && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1,
9301 props = {}, curPosition = {}, curTop, curLeft;
9302
9303 // need to be able to calculate position if either top or left is auto and position is either absolute or fixed
9304 if ( calculatePosition ) {
9305 curPosition = curElem.position();
9306 curTop = curPosition.top;
9307 curLeft = curPosition.left;
9308 } else {
9309 curTop = parseFloat( curCSSTop ) || 0;
9310 curLeft = parseFloat( curCSSLeft ) || 0;
9311 }
9312
9313 if ( jQuery.isFunction( options ) ) {
9314 options = options.call( elem, i, curOffset );
9315 }
9316
9317 if ( options.top != null ) {
9318 props.top = ( options.top - curOffset.top ) + curTop;
9319 }
9320 if ( options.left != null ) {
9321 props.left = ( options.left - curOffset.left ) + curLeft;
9322 }
9323
9324 if ( "using" in options ) {
9325 options.using.call( elem, props );
9326 } else {
9327 curElem.css( props );
9328 }
9329 }
9330 };
9331
9332
9333 jQuery.fn.extend({
9334
9335 position: function() {
9336 if ( !this[0] ) {
9337 return;
9338 }
9339
9340 var elem = this[0],
9341
9342 // Get *real* offsetParent
9343 offsetParent = this.offsetParent(),
9344
9345 // Get correct offsets
9346 offset = this.offset(),
9347 parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();
9348
9349 // Subtract element margins
9350 // note: when an element has margin: auto the offsetLeft and marginLeft
9351 // are the same in Safari causing offset.left to incorrectly be 0
9352 offset.top -= parseFloat( jQuery.css(elem, "marginTop") ) || 0;
9353 offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0;
9354
9355 // Add offsetParent borders
9356 parentOffset.top += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0;
9357 parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0;
9358
9359 // Subtract the two offsets
9360 return {
9361 top: offset.top - parentOffset.top,
9362 left: offset.left - parentOffset.left
9363 };
9364 },
9365
9366 offsetParent: function() {
9367 return this.map(function() {
9368 var offsetParent = this.offsetParent || document.body;
9369 while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) {
9370 offsetParent = offsetParent.offsetParent;
9371 }
9372 return offsetParent || document.body;
9373 });
9374 }
9375 });
9376
9377
9378 // Create scrollLeft and scrollTop methods
9379 jQuery.each( {scrollLeft: "pageXOffset", scrollTop: "pageYOffset"}, function( method, prop ) {
9380 var top = /Y/.test( prop );
9381
9382 jQuery.fn[ method ] = function( val ) {
9383 return jQuery.access( this, function( elem, method, val ) {
9384 var win = getWindow( elem );
9385
9386 if ( val === undefined ) {
9387 return win ? (prop in win) ? win[ prop ] :
9388 win.document.documentElement[ method ] :
9389 elem[ method ];
9390 }
9391
9392 if ( win ) {
9393 win.scrollTo(
9394 !top ? val : jQuery( win ).scrollLeft(),
9395 top ? val : jQuery( win ).scrollTop()
9396 );
9397
9398 } else {
9399 elem[ method ] = val;
9400 }
9401 }, method, val, arguments.length, null );
9402 };
9403 });
9404
9405 function getWindow( elem ) {
9406 return jQuery.isWindow( elem ) ?
9407 elem :
9408 elem.nodeType === 9 ?
9409 elem.defaultView || elem.parentWindow :
9410 false;
9411 }
9412 // Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
9413 jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
9414 jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) {
9415 // margin is only for outerHeight, outerWidth
9416 jQuery.fn[ funcName ] = function( margin, value ) {
9417 var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
9418 extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
9419
9420 return jQuery.access( this, function( elem, type, value ) {
9421 var doc;
9422
9423 if ( jQuery.isWindow( elem ) ) {
9424 // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there
9425 // isn't a whole lot we can do. See pull request at this URL for discussion:
9426 // https://github.com/jquery/jquery/pull/764
9427 return elem.document.documentElement[ "client" + name ];
9428 }
9429
9430 // Get document width or height
9431 if ( elem.nodeType === 9 ) {
9432 doc = elem.documentElement;
9433
9434 // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], whichever is greatest
9435 // unfortunately, this causes bug #3838 in IE6/8 only, but there is currently no good, small way to fix it.
9436 return Math.max(
9437 elem.body[ "scroll" + name ], doc[ "scroll" + name ],
9438 elem.body[ "offset" + name ], doc[ "offset" + name ],
9439 doc[ "client" + name ]
9440 );
9441 }
9442
9443 return value === undefined ?
9444 // Get width or height on the element, requesting but not forcing parseFloat
9445 jQuery.css( elem, type, value, extra ) :
9446
9447 // Set width or height on the element
9448 jQuery.style( elem, type, value, extra );
9449 }, type, chainable ? margin : undefined, chainable, null );
9450 };
9451 });
9452 });
9453 // Expose jQuery to the global object
9454 window.jQuery = window.$ = jQuery;
9455
9456 // Expose jQuery as an AMD module, but only for AMD loaders that
9457 // understand the issues with loading multiple versions of jQuery
9458 // in a page that all might call define(). The loader will indicate
9459 // they have special allowances for multiple jQuery versions by
9460 // specifying define.amd.jQuery = true. Register as a named module,
9461 // since jQuery can be concatenated with other files that may use define,
9462 // but not use a proper concatenation script that understands anonymous
9463 // AMD modules. A named AMD is safest and most robust way to register.
9464 // Lowercase jquery is used because AMD module names are derived from
9465 // file names, and jQuery is normally delivered in a lowercase file name.
9466 // Do this after creating the global so that if an AMD module wants to call
9467 // noConflict to hide this version of jQuery, it will work.
9468 if ( typeof define === "function" && define.amd && define.amd.jQuery ) {
9469 define( "jquery", [], function () { return jQuery; } );
9470 }
9471
9472 })( window );
1  /*!
2   * jQuery JavaScript Library v1.8.3
3   * http://jquery.com/
4   *
5   * Includes Sizzle.js
6   * http://sizzlejs.com/
7   *
8   * Copyright 2012 jQuery Foundation and other contributors
9   * Released under the MIT license
10   * http://jquery.org/license
11   *
12   * Date: Tue Nov 13 2012 08:20:33 GMT-0500 (Eastern Standard Time)
13   */
14  (function( window, undefined ) {
15  var
16          // A central reference to the root jQuery(document)
17          rootjQuery,
18  
19          // The deferred used on DOM ready
20          readyList,
21  
22          // Use the correct document accordingly with window argument (sandbox)
23          document = window.document,
24          location = window.location,
25          navigator = window.navigator,
26  
27          // Map over jQuery in case of overwrite
28          _jQuery = window.jQuery,
29  
30          // Map over the $ in case of overwrite
31          _$ = window.$,
32  
33          // Save a reference to some core methods
34          core_push = Array.prototype.push,
35          core_slice = Array.prototype.slice,
36          core_indexOf = Array.prototype.indexOf,
37          core_toString = Object.prototype.toString,
38          core_hasOwn = Object.prototype.hasOwnProperty,
39          core_trim = String.prototype.trim,
40  
41          // Define a local copy of jQuery
42          jQuery = function( selector, context ) {
43                  // The jQuery object is actually just the init constructor 'enhanced'
44                  return new jQuery.fn.init( selector, context, rootjQuery );
45          },
46  
47          // Used for matching numbers
48          core_pnum = /[\-+]?(?:\d*\.|)\d+(?:[eE][\-+]?\d+|)/.source,
49  
50          // Used for detecting and trimming whitespace
51          core_rnotwhite = /\S/,
52          core_rspace = /\s+/,
53  
54          // Make sure we trim BOM and NBSP (here's looking at you, Safari 5.0 and IE)
55          rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
56  
57          // A simple way to check for HTML strings
58          // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
59          rquickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,
60  
61          // Match a standalone tag
62          rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>|)$/,
63  
64          // JSON RegExp
65          rvalidchars = /^[\],:{}\s]*$/,
66          rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g,
67          rvalidescape = /\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,
68          rvalidtokens = /"[^"\\\r\n]*"|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g,
69  
70          // Matches dashed string for camelizing
71          rmsPrefix = /^-ms-/,
72          rdashAlpha = /-([\da-z])/gi,
73  
74          // Used by jQuery.camelCase as callback to replace()
75          fcamelCase = function( all, letter ) {
76                  return ( letter + "" ).toUpperCase();
77          },
78  
79          // The ready event handler and self cleanup method
80          DOMContentLoaded = function() {
81                  if ( document.addEventListener ) {
82                          document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
83                          jQuery.ready();
84                  } else if ( document.readyState === "complete" ) {
85                          // we're here because readyState === "complete" in oldIE
86                          // which is good enough for us to call the dom ready!
87                          document.detachEvent( "onreadystatechange", DOMContentLoaded );
88                          jQuery.ready();
89                  }
90          },
91  
92          // [[Class]] -> type pairs
93          class2type = {};
94  
95  jQuery.fn = jQuery.prototype = {
96          constructor: jQuery,
97          init: function( selector, context, rootjQuery ) {
98                  var match, elem, ret, doc;
99  
100                  // Handle $(""), $(null), $(undefined), $(false)
101                  if ( !selector ) {
102                          return this;
103                  }
104  
105                  // Handle $(DOMElement)
106                  if ( selector.nodeType ) {
107                          this.context = this[0] = selector;
108                          this.length = 1;
109                          return this;
110                  }
111  
112                  // Handle HTML strings
113                  if ( typeof selector === "string" ) {
114                          if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
115                                  // Assume that strings that start and end with <> are HTML and skip the regex check
116                                  match = [ null, selector, null ];
117  
118                          } else {
119                                  match = rquickExpr.exec( selector );
120                          }
121  
122                          // Match html or make sure no context is specified for #id
123                          if ( match && (match[1] || !context) ) {
124  
125                                  // HANDLE: $(html) -> $(array)
126                                  if ( match[1] ) {
127                                          context = context instanceof jQuery ? context[0] : context;
128                                          doc = ( context && context.nodeType ? context.ownerDocument || context : document );
129  
130                                          // scripts is true for back-compat
131                                          selector = jQuery.parseHTML( match[1], doc, true );
132                                          if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {
133                                                  this.attr.call( selector, context, true );
134                                          }
135  
136                                          return jQuery.merge( this, selector );
137  
138                                  // HANDLE: $(#id)
139                                  } else {
140                                          elem = document.getElementById( match[2] );
141  
142                                          // Check parentNode to catch when Blackberry 4.6 returns
143                                          // nodes that are no longer in the document #6963
144                                          if ( elem && elem.parentNode ) {
145                                                  // Handle the case where IE and Opera return items
146                                                  // by name instead of ID
147                                                  if ( elem.id !== match[2] ) {
148                                                          return rootjQuery.find( selector );
149                                                  }
150  
151                                                  // Otherwise, we inject the element directly into the jQuery object
152                                                  this.length = 1;
153                                                  this[0] = elem;
154                                          }
155  
156                                          this.context = document;
157                                          this.selector = selector;
158                                          return this;
159                                  }
160  
161                          // HANDLE: $(expr, $(...))
162                          } else if ( !context || context.jquery ) {
163                                  return ( context || rootjQuery ).find( selector );
164  
165                          // HANDLE: $(expr, context)
166                          // (which is just equivalent to: $(context).find(expr)
167                          } else {
168                                  return this.constructor( context ).find( selector );
169                          }
170  
171                  // HANDLE: $(function)
172                  // Shortcut for document ready
173                  } else if ( jQuery.isFunction( selector ) ) {
174                          return rootjQuery.ready( selector );
175                  }
176  
177                  if ( selector.selector !== undefined ) {
178                          this.selector = selector.selector;
179                          this.context = selector.context;
180                  }
181  
182                  return jQuery.makeArray( selector, this );
183          },
184  
185          // Start with an empty selector
186          selector: "",
187  
188          // The current version of jQuery being used
189          jquery: "1.8.3",
190  
191          // The default length of a jQuery object is 0
192          length: 0,
193  
194          // The number of elements contained in the matched element set
195          size: function() {
196                  return this.length;
197          },
198  
199          toArray: function() {
200                  return core_slice.call( this );
201          },
202  
203          // Get the Nth element in the matched element set OR
204          // Get the whole matched element set as a clean array
205          get: function( num ) {
206                  return num == null ?
207  
208                          // Return a 'clean' array
209                          this.toArray() :
210  
211                          // Return just the object
212                          ( num < 0 ? this[ this.length + num ] : this[ num ] );
213          },
214  
215          // Take an array of elements and push it onto the stack
216          // (returning the new matched element set)
217          pushStack: function( elems, name, selector ) {
218  
219                  // Build a new jQuery matched element set
220                  var ret = jQuery.merge( this.constructor(), elems );
221  
222                  // Add the old object onto the stack (as a reference)
223                  ret.prevObject = this;
224  
225                  ret.context = this.context;
226  
227                  if ( name === "find" ) {
228                          ret.selector = this.selector + ( this.selector ? " " : "" ) + selector;
229                  } else if ( name ) {
230                          ret.selector = this.selector + "." + name + "(" + selector + ")";
231                  }
232  
233                  // Return the newly-formed element set
234                  return ret;
235          },
236  
237          // Execute a callback for every element in the matched set.
238          // (You can seed the arguments with an array of args, but this is
239          // only used internally.)
240          each: function( callback, args ) {
241                  return jQuery.each( this, callback, args );
242          },
243  
244          ready: function( fn ) {
245                  // Add the callback
246                  jQuery.ready.promise().done( fn );
247  
248                  return this;
249          },
250  
251          eq: function( i ) {
252                  i = +i;
253                  return i === -1 ?
254                          this.slice( i ) :
255                          this.slice( i, i + 1 );
256          },
257  
258          first: function() {
259                  return this.eq( 0 );
260          },
261  
262          last: function() {
263                  return this.eq( -1 );
264          },
265  
266          slice: function() {
267                  return this.pushStack( core_slice.apply( this, arguments ),
268                          "slice", core_slice.call(arguments).join(",") );
269          },
270  
271          map: function( callback ) {
272                  return this.pushStack( jQuery.map(this, function( elem, i ) {
273                          return callback.call( elem, i, elem );
274                  }));
275          },
276  
277          end: function() {
278                  return this.prevObject || this.constructor(null);
279          },
280  
281          // For internal use only.
282          // Behaves like an Array's method, not like a jQuery method.
283          push: core_push,
284          sort: [].sort,
285          splice: [].splice
286  };
287  
288  // Give the init function the jQuery prototype for later instantiation
289  jQuery.fn.init.prototype = jQuery.fn;
290  
291  jQuery.extend = jQuery.fn.extend = function() {
292          var options, name, src, copy, copyIsArray, clone,
293                  target = arguments[0] || {},
294                  i = 1,
295                  length = arguments.length,
296                  deep = false;
297  
298          // Handle a deep copy situation
299          if ( typeof target === "boolean" ) {
300                  deep = target;
301                  target = arguments[1] || {};
302                  // skip the boolean and the target
303                  i = 2;
304          }
305  
306          // Handle case when target is a string or something (possible in deep copy)
307          if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
308                  target = {};
309          }
310  
311          // extend jQuery itself if only one argument is passed
312          if ( length === i ) {
313                  target = this;
314                  --i;
315          }
316  
317          for ( ; i < length; i++ ) {
318                  // Only deal with non-null/undefined values
319                  if ( (options = arguments[ i ]) != null ) {
320                          // Extend the base object
321                          for ( name in options ) {
322                                  src = target[ name ];
323                                  copy = options[ name ];
324  
325                                  // Prevent never-ending loop
326                                  if ( target === copy ) {
327                                          continue;
328                                  }
329  
330                                  // Recurse if we're merging plain objects or arrays
331                                  if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
332                                          if ( copyIsArray ) {
333                                                  copyIsArray = false;
334                                                  clone = src && jQuery.isArray(src) ? src : [];
335  
336                                          } else {
337                                                  clone = src && jQuery.isPlainObject(src) ? src : {};
338                                          }
339  
340                                          // Never move original objects, clone them
341                                          target[ name ] = jQuery.extend( deep, clone, copy );
342  
343                                  // Don't bring in undefined values
344                                  } else if ( copy !== undefined ) {
345                                          target[ name ] = copy;
346                                  }
347                          }
348                  }
349          }
350  
351          // Return the modified object
352          return target;
353  };
354  
355  jQuery.extend({
356          noConflict: function( deep ) {
357                  if ( window.$ === jQuery ) {
358                          window.$ = _$;
359                  }
360  
361                  if ( deep && window.jQuery === jQuery ) {
362                          window.jQuery = _jQuery;
363                  }
364  
365                  return jQuery;
366          },
367  
368          // Is the DOM ready to be used? Set to true once it occurs.
369          isReady: false,
370  
371          // A counter to track how many items to wait for before
372          // the ready event fires. See #6781
373          readyWait: 1,
374  
375          // Hold (or release) the ready event
376          holdReady: function( hold ) {
377                  if ( hold ) {
378                          jQuery.readyWait++;
379                  } else {
380                          jQuery.ready( true );
381                  }
382          },
383  
384          // Handle when the DOM is ready
385          ready: function( wait ) {
386  
387                  // Abort if there are pending holds or we're already ready
388                  if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
389                          return;
390                  }
391  
392                  // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
393                  if ( !document.body ) {
394                          return setTimeout( jQuery.ready, 1 );
395                  }
396  
397                  // Remember that the DOM is ready
398                  jQuery.isReady = true;
399  
400                  // If a normal DOM Ready event fired, decrement, and wait if need be
401                  if ( wait !== true && --jQuery.readyWait > 0 ) {
402                          return;
403                  }
404  
405                  // If there are functions bound, to execute
406                  readyList.resolveWith( document, [ jQuery ] );
407  
408                  // Trigger any bound ready events
409                  if ( jQuery.fn.trigger ) {
410                          jQuery( document ).trigger("ready").off("ready");
411                  }
412          },
413  
414          // See test/unit/core.js for details concerning isFunction.
415          // Since version 1.3, DOM methods and functions like alert
416          // aren't supported. They return false on IE (#2968).
417          isFunction: function( obj ) {
418                  return jQuery.type(obj) === "function";
419          },
420  
421          isArray: Array.isArray || function( obj ) {
422                  return jQuery.type(obj) === "array";
423          },
424  
425          isWindow: function( obj ) {
426                  return obj != null && obj == obj.window;
427          },
428  
429          isNumeric: function( obj ) {
430                  return !isNaN( parseFloat(obj) ) && isFinite( obj );
431          },
432  
433          type: function( obj ) {
434                  return obj == null ?
435                          String( obj ) :
436                          class2type[ core_toString.call(obj) ] || "object";
437          },
438  
439          isPlainObject: function( obj ) {
440                  // Must be an Object.
441                  // Because of IE, we also have to check the presence of the constructor property.
442                  // Make sure that DOM nodes and window objects don't pass through, as well
443                  if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
444                          return false;
445                  }
446  
447                  try {
448                          // Not own constructor property must be Object
449                          if ( obj.constructor &&
450                                  !core_hasOwn.call(obj, "constructor") &&
451                                  !core_hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
452                                  return false;
453                          }
454                  } catch ( e ) {
455                          // IE8,9 Will throw exceptions on certain host objects #9897
456                          return false;
457                  }
458  
459                  // Own properties are enumerated firstly, so to speed up,
460                  // if last one is own, then all properties are own.
461  
462                  var key;
463                  for ( key in obj ) {}
464  
465                  return key === undefined || core_hasOwn.call( obj, key );
466          },
467  
468          isEmptyObject: function( obj ) {
469                  var name;
470                  for ( name in obj ) {
471                          return false;
472                  }
473                  return true;
474          },
475  
476          error: function( msg ) {
477                  throw new Error( msg );
478          },
479  
480          // data: string of html
481          // context (optional): If specified, the fragment will be created in this context, defaults to document
482          // scripts (optional): If true, will include scripts passed in the html string
483          parseHTML: function( data, context, scripts ) {
484                  var parsed;
485                  if ( !data || typeof data !== "string" ) {
486                          return null;
487                  }
488                  if ( typeof context === "boolean" ) {
489                          scripts = context;
490                          context = 0;
491                  }
492                  context = context || document;
493  
494                  // Single tag
495                  if ( (parsed = rsingleTag.exec( data )) ) {
496                          return [ context.createElement( parsed[1] ) ];
497                  }
498  
499                  parsed = jQuery.buildFragment( [ data ], context, scripts ? null : [] );
500                  return jQuery.merge( [],
501                          (parsed.cacheable ? jQuery.clone( parsed.fragment ) : parsed.fragment).childNodes );
502          },
503  
504          parseJSON: function( data ) {
505                  if ( !data || typeof data !== "string") {
506                          return null;
507                  }
508  
509                  // Make sure leading/trailing whitespace is removed (IE can't handle it)
510                  data = jQuery.trim( data );
511  
512                  // Attempt to parse using the native JSON parser first
513                  if ( window.JSON && window.JSON.parse ) {
514                          return window.JSON.parse( data );
515                  }
516  
517                  // Make sure the incoming data is actual JSON
518                  // Logic borrowed from http://json.org/json2.js
519                  if ( rvalidchars.test( data.replace( rvalidescape, "@" )
520                          .replace( rvalidtokens, "]" )
521                          .replace( rvalidbraces, "")) ) {
522  
523                          return ( new Function( "return " + data ) )();
524  
525                  }
526                  jQuery.error( "Invalid JSON: " + data );
527          },
528  
529          // Cross-browser xml parsing
530          parseXML: function( data ) {
531                  var xml, tmp;
532                  if ( !data || typeof data !== "string" ) {
533                          return null;
534                  }
535                  try {
536                          if ( window.DOMParser ) { // Standard
537                                  tmp = new DOMParser();
538                                  xml = tmp.parseFromString( data , "text/xml" );
539                          } else { // IE
540                                  xml = new ActiveXObject( "Microsoft.XMLDOM" );
541                                  xml.async = "false";
542                                  xml.loadXML( data );
543                          }
544                  } catch( e ) {
545                          xml = undefined;
546                  }
547                  if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) {
548                          jQuery.error( "Invalid XML: " + data );
549                  }
550                  return xml;
551          },
552  
553          noop: function() {},
554  
555          // Evaluates a script in a global context
556          // Workarounds based on findings by Jim Driscoll
557          // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
558          globalEval: function( data ) {
559                  if ( data && core_rnotwhite.test( data ) ) {
560                          // We use execScript on Internet Explorer
561                          // We use an anonymous function so that context is window
562                          // rather than jQuery in Firefox
563                          ( window.execScript || function( data ) {
564                                  window[ "eval" ].call( window, data );
565                          } )( data );
566                  }
567          },
568  
569          // Convert dashed to camelCase; used by the css and data modules
570          // Microsoft forgot to hump their vendor prefix (#9572)
571          camelCase: function( string ) {
572                  return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
573          },
574  
575          nodeName: function( elem, name ) {
576                  return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
577          },
578  
579          // args is for internal usage only
580          each: function( obj, callback, args ) {
581                  var name,
582                          i = 0,
583                          length = obj.length,
584                          isObj = length === undefined || jQuery.isFunction( obj );
585  
586                  if ( args ) {
587                          if ( isObj ) {
588                                  for ( name in obj ) {
589                                          if ( callback.apply( obj[ name ], args ) === false ) {
590                                                  break;
591                                          }
592                                  }
593                          } else {
594                                  for ( ; i < length; ) {
595                                          if ( callback.apply( obj[ i++ ], args ) === false ) {
596                                                  break;
597                                          }
598                                  }
599                          }
600  
601                  // A special, fast, case for the most common use of each
602                  } else {
603                          if ( isObj ) {
604                                  for ( name in obj ) {
605                                          if ( callback.call( obj[ name ], name, obj[ name ] ) === false ) {
606                                                  break;
607                                          }
608                                  }
609                          } else {
610                                  for ( ; i < length; ) {
611                                          if ( callback.call( obj[ i ], i, obj[ i++ ] ) === false ) {
612                                                  break;
613                                          }
614                                  }
615                          }
616                  }
617  
618                  return obj;
619          },
620  
621          // Use native String.trim function wherever possible
622          trim: core_trim && !core_trim.call("\uFEFF\xA0") ?
623                  function( text ) {
624                          return text == null ?
625                                  "" :
626                                  core_trim.call( text );
627                  } :
628  
629                  // Otherwise use our own trimming functionality
630                  function( text ) {
631                          return text == null ?
632                                  "" :
633                                  ( text + "" ).replace( rtrim, "" );
634                  },
635  
636          // results is for internal usage only
637          makeArray: function( arr, results ) {
638                  var type,
639                          ret = results || [];
640  
641                  if ( arr != null ) {
642                          // The window, strings (and functions) also have 'length'
643                          // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930
644                          type = jQuery.type( arr );
645  
646                          if ( arr.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( arr ) ) {
647                                  core_push.call( ret, arr );
648                          } else {
649                                  jQuery.merge( ret, arr );
650                          }
651                  }
652  
653                  return ret;
654          },
655  
656          inArray: function( elem, arr, i ) {
657                  var len;
658  
659                  if ( arr ) {
660                          if ( core_indexOf ) {
661                                  return core_indexOf.call( arr, elem, i );
662                          }
663  
664                          len = arr.length;
665                          i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;
666  
667                          for ( ; i < len; i++ ) {
668                                  // Skip accessing in sparse arrays
669                                  if ( i in arr && arr[ i ] === elem ) {
670                                          return i;
671                                  }
672                          }
673                  }
674  
675                  return -1;
676          },
677  
678          merge: function( first, second ) {
679                  var l = second.length,
680                          i = first.length,
681                          j = 0;
682  
683                  if ( typeof l === "number" ) {
684                          for ( ; j < l; j++ ) {
685                                  first[ i++ ] = second[ j ];
686                          }
687  
688                  } else {
689                          while ( second[j] !== undefined ) {
690                                  first[ i++ ] = second[ j++ ];
691                          }
692                  }
693  
694                  first.length = i;
695  
696                  return first;
697          },
698  
699          grep: function( elems, callback, inv ) {
700                  var retVal,
701                          ret = [],
702                          i = 0,
703                          length = elems.length;
704                  inv = !!inv;
705  
706                  // Go through the array, only saving the items
707                  // that pass the validator function
708                  for ( ; i < length; i++ ) {
709                          retVal = !!callback( elems[ i ], i );
710                          if ( inv !== retVal ) {
711                                  ret.push( elems[ i ] );
712                          }
713                  }
714  
715                  return ret;
716          },
717  
718          // arg is for internal usage only
719          map: function( elems, callback, arg ) {
720                  var value, key,
721                          ret = [],
722                          i = 0,
723                          length = elems.length,
724                          // jquery objects are treated as arrays
725                          isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ;
726  
727                  // Go through the array, translating each of the items to their
728                  if ( isArray ) {
729                          for ( ; i < length; i++ ) {
730                                  value = callback( elems[ i ], i, arg );
731  
732                                  if ( value != null ) {
733                                          ret[ ret.length ] = value;
734                                  }
735                          }
736  
737                  // Go through every key on the object,
738                  } else {
739                          for ( key in elems ) {
740                                  value = callback( elems[ key ], key, arg );
741  
742                                  if ( value != null ) {
743                                          ret[ ret.length ] = value;
744                                  }
745                          }
746                  }
747  
748                  // Flatten any nested arrays
749                  return ret.concat.apply( [], ret );
750          },
751  
752          // A global GUID counter for objects
753          guid: 1,
754  
755          // Bind a function to a context, optionally partially applying any
756          // arguments.
757          proxy: function( fn, context ) {
758                  var tmp, args, proxy;
759  
760                  if ( typeof context === "string" ) {
761                          tmp = fn[ context ];
762                          context = fn;
763                          fn = tmp;
764                  }
765  
766                  // Quick check to determine if target is callable, in the spec
767                  // this throws a TypeError, but we will just return undefined.
768                  if ( !jQuery.isFunction( fn ) ) {
769                          return undefined;
770                  }
771  
772                  // Simulated bind
773                  args = core_slice.call( arguments, 2 );
774                  proxy = function() {
775                          return fn.apply( context, args.concat( core_slice.call( arguments ) ) );
776                  };
777  
778                  // Set the guid of unique handler to the same of original handler, so it can be removed
779                  proxy.guid = fn.guid = fn.guid || jQuery.guid++;
780  
781                  return proxy;
782          },
783  
784          // Multifunctional method to get and set values of a collection
785          // The value/s can optionally be executed if it's a function
786          access: function( elems, fn, key, value, chainable, emptyGet, pass ) {
787                  var exec,
788                          bulk = key == null,
789                          i = 0,
790                          length = elems.length;
791  
792                  // Sets many values
793                  if ( key && typeof key === "object" ) {
794                          for ( i in key ) {
795                                  jQuery.access( elems, fn, i, key[i], 1, emptyGet, value );
796                          }
797                          chainable = 1;
798  
799                  // Sets one value
800                  } else if ( value !== undefined ) {
801                          // Optionally, function values get executed if exec is true
802                          exec = pass === undefined && jQuery.isFunction( value );
803  
804                          if ( bulk ) {
805                                  // Bulk operations only iterate when executing function values
806                                  if ( exec ) {
807                                          exec = fn;
808                                          fn = function( elem, key, value ) {
809                                                  return exec.call( jQuery( elem ), value );
810                                          };
811  
812                                  // Otherwise they run against the entire set
813                                  } else {
814                                          fn.call( elems, value );
815                                          fn = null;
816                                  }
817                          }
818  
819                          if ( fn ) {
820                                  for (; i < length; i++ ) {
821                                          fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
822                                  }
823                          }
824  
825                          chainable = 1;
826                  }
827  
828                  return chainable ?
829                          elems :
830  
831                          // Gets
832                          bulk ?
833                                  fn.call( elems ) :
834                                  length ? fn( elems[0], key ) : emptyGet;
835          },
836  
837          now: function() {
838                  return ( new Date() ).getTime();
839          }
840  });
841  
842  jQuery.ready.promise = function( obj ) {
843          if ( !readyList ) {
844  
845                  readyList = jQuery.Deferred();
846  
847                  // Catch cases where $(document).ready() is called after the browser event has already occurred.
848                  // we once tried to use readyState "interactive" here, but it caused issues like the one
849                  // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15
850                  if ( document.readyState === "complete" ) {
851                          // Handle it asynchronously to allow scripts the opportunity to delay ready
852                          setTimeout( jQuery.ready, 1 );
853  
854                  // Standards-based browsers support DOMContentLoaded
855                  } else if ( document.addEventListener ) {
856                          // Use the handy event callback
857                          document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
858  
859                          // A fallback to window.onload, that will always work
860                          window.addEventListener( "load", jQuery.ready, false );
861  
862                  // If IE event model is used
863                  } else {
864                          // Ensure firing before onload, maybe late but safe also for iframes
865                          document.attachEvent( "onreadystatechange", DOMContentLoaded );
866  
867                          // A fallback to window.onload, that will always work
868                          window.attachEvent( "onload", jQuery.ready );
869  
870                          // If IE and not a frame
871                          // continually check to see if the document is ready
872                          var top = false;
873  
874                          try {
875                                  top = window.frameElement == null && document.documentElement;
876                          } catch(e) {}
877  
878                          if ( top && top.doScroll ) {
879                                  (function doScrollCheck() {
880                                          if ( !jQuery.isReady ) {
881  
882                                                  try {
883                                                          // Use the trick by Diego Perini
884                                                          // http://javascript.nwbox.com/IEContentLoaded/
885                                                          top.doScroll("left");
886                                                  } catch(e) {
887                                                          return setTimeout( doScrollCheck, 50 );
888                                                  }
889  
890                                                  // and execute any waiting functions
891                                                  jQuery.ready();
892                                          }
893                                  })();
894                          }
895                  }
896          }
897          return readyList.promise( obj );
898  };
899  
900  // Populate the class2type map
901  jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) {
902          class2type[ "[object " + name + "]" ] = name.toLowerCase();
903  });
904  
905  // All jQuery objects should point back to these
906  rootjQuery = jQuery(document);
907  // String to Object options format cache
908  var optionsCache = {};
909  
910  // Convert String-formatted options into Object-formatted ones and store in cache
911  function createOptions( options ) {
912          var object = optionsCache[ options ] = {};
913          jQuery.each( options.split( core_rspace ), function( _, flag ) {
914                  object[ flag ] = true;
915          });
916          return object;
917  }
918  
919  /*
920   * Create a callback list using the following parameters:
921   *
922   *      options: an optional list of space-separated options that will change how
923   *                      the callback list behaves or a more traditional option object
924   *
925   * By default a callback list will act like an event callback list and can be
926   * "fired" multiple times.
927   *
928   * Possible options:
929   *
930   *      once:                   will ensure the callback list can only be fired once (like a Deferred)
931   *
932   *      memory:                 will keep track of previous values and will call any callback added
933   *                                      after the list has been fired right away with the latest "memorized"
934   *                                      values (like a Deferred)
935   *
936   *      unique:                 will ensure a callback can only be added once (no duplicate in the list)
937   *
938   *      stopOnFalse:    interrupt callings when a callback returns false
939   *
940   */
941  jQuery.Callbacks = function( options ) {
942  
943          // Convert options from String-formatted to Object-formatted if needed
944          // (we check in cache first)
945          options = typeof options === "string" ?
946                  ( optionsCache[ options ] || createOptions( options ) ) :
947                  jQuery.extend( {}, options );
948  
949          var // Last fire value (for non-forgettable lists)
950                  memory,
951                  // Flag to know if list was already fired
952                  fired,
953                  // Flag to know if list is currently firing
954                  firing,
955                  // First callback to fire (used internally by add and fireWith)
956                  firingStart,
957                  // End of the loop when firing
958                  firingLength,
959                  // Index of currently firing callback (modified by remove if needed)
960                  firingIndex,
961                  // Actual callback list
962                  list = [],
963                  // Stack of fire calls for repeatable lists
964                  stack = !options.once && [],
965                  // Fire callbacks
966                  fire = function( data ) {
967                          memory = options.memory && data;
968                          fired = true;
969                          firingIndex = firingStart || 0;
970                          firingStart = 0;
971                          firingLength = list.length;
972                          firing = true;
973                          for ( ; list && firingIndex < firingLength; firingIndex++ ) {
974                                  if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {
975                                          memory = false; // To prevent further calls using add
976                                          break;
977                                  }
978                          }
979                          firing = false;
980                          if ( list ) {
981                                  if ( stack ) {
982                                          if ( stack.length ) {
983                                                  fire( stack.shift() );
984                                          }
985                                  } else if ( memory ) {
986                                          list = [];
987                                  } else {
988                                          self.disable();
989                                  }
990                          }
991                  },
992                  // Actual Callbacks object
993                  self = {
994                          // Add a callback or a collection of callbacks to the list
995                          add: function() {
996                                  if ( list ) {
997                                          // First, we save the current length
998                                          var start = list.length;
999                                          (function add( args ) {
1000                                                  jQuery.each( args, function( _, arg ) {
1001                                                          var type = jQuery.type( arg );
1002                                                          if ( type === "function" ) {
1003                                                                  if ( !options.unique || !self.has( arg ) ) {
1004                                                                          list.push( arg );
1005                                                                  }
1006                                                          } else if ( arg && arg.length && type !== "string" ) {
1007                                                                  // Inspect recursively
1008                                                                  add( arg );
1009                                                          }
1010                                                  });
1011                                          })( arguments );
1012                                          // Do we need to add the callbacks to the
1013                                          // current firing batch?
1014                                          if ( firing ) {
1015                                                  firingLength = list.length;
1016                                          // With memory, if we're not firing then
1017                                          // we should call right away
1018                                          } else if ( memory ) {
1019                                                  firingStart = start;
1020                                                  fire( memory );
1021                                          }
1022                                  }
1023                                  return this;
1024                          },
1025                          // Remove a callback from the list
1026                          remove: function() {
1027                                  if ( list ) {
1028                                          jQuery.each( arguments, function( _, arg ) {
1029                                                  var index;
1030                                                  while( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
1031                                                          list.splice( index, 1 );
1032                                                          // Handle firing indexes
1033                                                          if ( firing ) {
1034                                                                  if ( index <= firingLength ) {
1035                                                                          firingLength--;
1036                                                                  }
1037                                                                  if ( index <= firingIndex ) {
1038                                                                          firingIndex--;
1039                                                                  }
1040                                                          }
1041                                                  }
1042                                          });
1043                                  }
1044                                  return this;
1045                          },
1046                          // Control if a given callback is in the list
1047                          has: function( fn ) {
1048                                  return jQuery.inArray( fn, list ) > -1;
1049                          },
1050                          // Remove all callbacks from the list
1051                          empty: function() {
1052                                  list = [];
1053                                  return this;
1054                          },
1055                          // Have the list do nothing anymore
1056                          disable: function() {
1057                                  list = stack = memory = undefined;
1058                                  return this;
1059                          },
1060                          // Is it disabled?
1061                          disabled: function() {
1062                                  return !list;
1063                          },
1064                          // Lock the list in its current state
1065                          lock: function() {
1066                                  stack = undefined;
1067                                  if ( !memory ) {
1068                                          self.disable();
1069                                  }
1070                                  return this;
1071                          },
1072                          // Is it locked?
1073                          locked: function() {
1074                                  return !stack;
1075                          },
1076                          // Call all callbacks with the given context and arguments
1077                          fireWith: function( context, args ) {
1078                                  args = args || [];
1079                                  args = [ context, args.slice ? args.slice() : args ];
1080                                  if ( list && ( !fired || stack ) ) {
1081                                          if ( firing ) {
1082                                                  stack.push( args );
1083                                          } else {
1084                                                  fire( args );
1085                                          }
1086                                  }
1087                                  return this;
1088                          },
1089                          // Call all the callbacks with the given arguments
1090                          fire: function() {
1091                                  self.fireWith( this, arguments );
1092                                  return this;
1093                          },
1094                          // To know if the callbacks have already been called at least once
1095                          fired: function() {
1096                                  return !!fired;
1097                          }
1098                  };
1099  
1100          return self;
1101  };
1102  jQuery.extend({
1103  
1104          Deferred: function( func ) {
1105                  var tuples = [
1106                                  // action, add listener, listener list, final state
1107                                  [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ],
1108                                  [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ],
1109                                  [ "notify", "progress", jQuery.Callbacks("memory") ]
1110                          ],
1111                          state = "pending",
1112                          promise = {
1113                                  state: function() {
1114                                          return state;
1115                                  },
1116                                  always: function() {
1117                                          deferred.done( arguments ).fail( arguments );
1118                                          return this;
1119                                  },
1120                                  then: function( /* fnDone, fnFail, fnProgress */ ) {
1121                                          var fns = arguments;
1122                                          return jQuery.Deferred(function( newDefer ) {
1123                                                  jQuery.each( tuples, function( i, tuple ) {
1124                                                          var action = tuple[ 0 ],
1125                                                                  fn = fns[ i ];
1126                                                          // deferred[ done | fail | progress ] for forwarding actions to newDefer
1127                                                          deferred[ tuple[1] ]( jQuery.isFunction( fn ) ?
1128                                                                  function() {
1129                                                                          var returned = fn.apply( this, arguments );
1130                                                                          if ( returned && jQuery.isFunction( returned.promise ) ) {
1131                                                                                  returned.promise()
1132                                                                                          .done( newDefer.resolve )
1133                                                                                          .fail( newDefer.reject )
1134                                                                                          .progress( newDefer.notify );
1135                                                                          } else {
1136                                                                                  newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] );
1137                                                                          }
1138                                                                  } :
1139                                                                  newDefer[ action ]
1140                                                          );
1141                                                  });
1142                                                  fns = null;
1143                                          }).promise();
1144                                  },
1145                                  // Get a promise for this deferred
1146                                  // If obj is provided, the promise aspect is added to the object
1147                                  promise: function( obj ) {
1148                                          return obj != null ? jQuery.extend( obj, promise ) : promise;
1149                                  }
1150                          },
1151                          deferred = {};
1152  
1153                  // Keep pipe for back-compat
1154                  promise.pipe = promise.then;
1155  
1156                  // Add list-specific methods
1157                  jQuery.each( tuples, function( i, tuple ) {
1158                          var list = tuple[ 2 ],
1159                                  stateString = tuple[ 3 ];
1160  
1161                          // promise[ done | fail | progress ] = list.add
1162                          promise[ tuple[1] ] = list.add;
1163  
1164                          // Handle state
1165                          if ( stateString ) {
1166                                  list.add(function() {
1167                                          // state = [ resolved | rejected ]
1168                                          state = stateString;
1169  
1170                                  // [ reject_list | resolve_list ].disable; progress_list.lock
1171                                  }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );
1172                          }
1173  
1174                          // deferred[ resolve | reject | notify ] = list.fire
1175                          deferred[ tuple[0] ] = list.fire;
1176                          deferred[ tuple[0] + "With" ] = list.fireWith;
1177                  });
1178  
1179                  // Make the deferred a promise
1180                  promise.promise( deferred );
1181  
1182                  // Call given func if any
1183                  if ( func ) {
1184                          func.call( deferred, deferred );
1185                  }
1186  
1187                  // All done!
1188                  return deferred;
1189          },
1190  
1191          // Deferred helper
1192          when: function( subordinate /* , ..., subordinateN */ ) {
1193                  var i = 0,
1194                          resolveValues = core_slice.call( arguments ),
1195                          length = resolveValues.length,
1196  
1197                          // the count of uncompleted subordinates
1198                          remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,
1199  
1200                          // the master Deferred. If resolveValues consist of only a single Deferred, just use that.
1201                          deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
1202  
1203                          // Update function for both resolve and progress values
1204                          updateFunc = function( i, contexts, values ) {
1205                                  return function( value ) {
1206                                          contexts[ i ] = this;
1207                                          values[ i ] = arguments.length > 1 ? core_slice.call( arguments ) : value;
1208                                          if( values === progressValues ) {
1209                                                  deferred.notifyWith( contexts, values );
1210                                          } else if ( !( --remaining ) ) {
1211                                                  deferred.resolveWith( contexts, values );
1212                                          }
1213                                  };
1214                          },
1215  
1216                          progressValues, progressContexts, resolveContexts;
1217  
1218                  // add listeners to Deferred subordinates; treat others as resolved
1219                  if ( length > 1 ) {
1220                          progressValues = new Array( length );
1221                          progressContexts = new Array( length );
1222                          resolveContexts = new Array( length );
1223                          for ( ; i < length; i++ ) {
1224                                  if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
1225                                          resolveValues[ i ].promise()
1226                                                  .done( updateFunc( i, resolveContexts, resolveValues ) )
1227                                                  .fail( deferred.reject )
1228                                                  .progress( updateFunc( i, progressContexts, progressValues ) );
1229                                  } else {
1230                                          --remaining;
1231                                  }
1232                          }
1233                  }
1234  
1235                  // if we're not waiting on anything, resolve the master
1236                  if ( !remaining ) {
1237                          deferred.resolveWith( resolveContexts, resolveValues );
1238                  }
1239  
1240                  return deferred.promise();
1241          }
1242  });
1243  jQuery.support = (function() {
1244  
1245          var support,
1246                  all,
1247                  a,
1248                  select,
1249                  opt,
1250                  input,
1251                  fragment,
1252                  eventName,
1253                  i,
1254                  isSupported,
1255                  clickFn,
1256                  div = document.createElement("div");
1257  
1258          // Setup
1259          div.setAttribute( "className", "t" );
1260          div.innerHTML = "  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
1261  
1262          // Support tests won't run in some limited or non-browser environments
1263          all = div.getElementsByTagName("*");
1264          a = div.getElementsByTagName("a")[ 0 ];
1265          if ( !all || !a || !all.length ) {
1266                  return {};
1267          }
1268  
1269          // First batch of tests
1270          select = document.createElement("select");
1271          opt = select.appendChild( document.createElement("option") );
1272          input = div.getElementsByTagName("input")[ 0 ];
1273  
1274          a.style.cssText = "top:1px;float:left;opacity:.5";
1275          support = {
1276                  // IE strips leading whitespace when .innerHTML is used
1277                  leadingWhitespace: ( div.firstChild.nodeType === 3 ),
1278  
1279                  // Make sure that tbody elements aren't automatically inserted
1280                  // IE will insert them into empty tables
1281                  tbody: !div.getElementsByTagName("tbody").length,
1282  
1283                  // Make sure that link elements get serialized correctly by innerHTML
1284                  // This requires a wrapper element in IE
1285                  htmlSerialize: !!div.getElementsByTagName("link").length,
1286  
1287                  // Get the style information from getAttribute
1288                  // (IE uses .cssText instead)
1289                  style: /top/.test( a.getAttribute("style") ),
1290  
1291                  // Make sure that URLs aren't manipulated
1292                  // (IE normalizes it by default)
1293                  hrefNormalized: ( a.getAttribute("href") === "/a" ),
1294  
1295                  // Make sure that element opacity exists
1296                  // (IE uses filter instead)
1297                  // Use a regex to work around a WebKit issue. See #5145
1298                  opacity: /^0.5/.test( a.style.opacity ),
1299  
1300                  // Verify style float existence
1301                  // (IE uses styleFloat instead of cssFloat)
1302                  cssFloat: !!a.style.cssFloat,
1303  
1304                  // Make sure that if no value is specified for a checkbox
1305                  // that it defaults to "on".
1306                  // (WebKit defaults to "" instead)
1307                  checkOn: ( input.value === "on" ),
1308  
1309                  // Make sure that a selected-by-default option has a working selected property.
1310                  // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
1311                  optSelected: opt.selected,
1312  
1313                  // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)
1314                  getSetAttribute: div.className !== "t",
1315  
1316                  // Tests for enctype support on a form (#6743)
1317                  enctype: !!document.createElement("form").enctype,
1318  
1319                  // Makes sure cloning an html5 element does not cause problems
1320                  // Where outerHTML is undefined, this still works
1321                  html5Clone: document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav></:nav>",
1322  
1323                  // jQuery.support.boxModel DEPRECATED in 1.8 since we don't support Quirks Mode
1324                  boxModel: ( document.compatMode === "CSS1Compat" ),
1325  
1326                  // Will be defined later
1327                  submitBubbles: true,
1328                  changeBubbles: true,
1329                  focusinBubbles: false,
1330                  deleteExpando: true,
1331                  noCloneEvent: true,
1332                  inlineBlockNeedsLayout: false,
1333                  shrinkWrapBlocks: false,
1334                  reliableMarginRight: true,
1335                  boxSizingReliable: true,
1336                  pixelPosition: false
1337          };
1338  
1339          // Make sure checked status is properly cloned
1340          input.checked = true;
1341          support.noCloneChecked = input.cloneNode( true ).checked;
1342  
1343          // Make sure that the options inside disabled selects aren't marked as disabled
1344          // (WebKit marks them as disabled)
1345          select.disabled = true;
1346          support.optDisabled = !opt.disabled;
1347  
1348          // Test to see if it's possible to delete an expando from an element
1349          // Fails in Internet Explorer
1350          try {
1351                  delete div.test;
1352          } catch( e ) {
1353                  support.deleteExpando = false;
1354          }
1355  
1356          if ( !div.addEventListener && div.attachEvent && div.fireEvent ) {
1357                  div.attachEvent( "onclick", clickFn = function() {
1358                          // Cloning a node shouldn't copy over any
1359                          // bound event handlers (IE does this)
1360                          support.noCloneEvent = false;
1361                  });
1362                  div.cloneNode( true ).fireEvent("onclick");
1363                  div.detachEvent( "onclick", clickFn );
1364          }
1365  
1366          // Check if a radio maintains its value
1367          // after being appended to the DOM
1368          input = document.createElement("input");
1369          input.value = "t";
1370          input.setAttribute( "type", "radio" );
1371          support.radioValue = input.value === "t";
1372  
1373          input.setAttribute( "checked", "checked" );
1374  
1375          // #11217 - WebKit loses check when the name is after the checked attribute
1376          input.setAttribute( "name", "t" );
1377  
1378          div.appendChild( input );
1379          fragment = document.createDocumentFragment();
1380          fragment.appendChild( div.lastChild );
1381  
1382          // WebKit doesn't clone checked state correctly in fragments
1383          support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;
1384  
1385          // Check if a disconnected checkbox will retain its checked
1386          // value of true after appended to the DOM (IE6/7)
1387          support.appendChecked = input.checked;
1388  
1389          fragment.removeChild( input );
1390          fragment.appendChild( div );
1391  
1392          // Technique from Juriy Zaytsev
1393          // http://perfectionkills.com/detecting-event-support-without-browser-sniffing/
1394          // We only care about the case where non-standard event systems
1395          // are used, namely in IE. Short-circuiting here helps us to
1396          // avoid an eval call (in setAttribute) which can cause CSP
1397          // to go haywire. See: https://developer.mozilla.org/en/Security/CSP
1398          if ( div.attachEvent ) {
1399                  for ( i in {
1400                          submit: true,
1401                          change: true,
1402                          focusin: true
1403                  }) {
1404                          eventName = "on" + i;
1405                          isSupported = ( eventName in div );
1406                          if ( !isSupported ) {
1407                                  div.setAttribute( eventName, "return;" );
1408                                  isSupported = ( typeof div[ eventName ] === "function" );
1409                          }
1410                          support[ i + "Bubbles" ] = isSupported;
1411                  }
1412          }
1413  
1414          // Run tests that need a body at doc ready
1415          jQuery(function() {
1416                  var container, div, tds, marginDiv,
1417                          divReset = "padding:0;margin:0;border:0;display:block;overflow:hidden;",
1418                          body = document.getElementsByTagName("body")[0];
1419  
1420                  if ( !body ) {
1421                          // Return for frameset docs that don't have a body
1422                          return;
1423                  }
1424  
1425                  container = document.createElement("div");
1426                  container.style.cssText = "visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px";
1427                  body.insertBefore( container, body.firstChild );
1428  
1429                  // Construct the test element
1430                  div = document.createElement("div");
1431                  container.appendChild( div );
1432  
1433                  // Check if table cells still have offsetWidth/Height when they are set
1434                  // to display:none and there are still other visible table cells in a
1435                  // table row; if so, offsetWidth/Height are not reliable for use when
1436                  // determining if an element has been hidden directly using
1437                  // display:none (it is still safe to use offsets if a parent element is
1438                  // hidden; don safety goggles and see bug #4512 for more information).
1439                  // (only IE 8 fails this test)
1440                  div.innerHTML = "<table><tr><td></td><td>t</td></tr></table>";
1441                  tds = div.getElementsByTagName("td");
1442                  tds[ 0 ].style.cssText = "padding:0;margin:0;border:0;display:none";
1443                  isSupported = ( tds[ 0 ].offsetHeight === 0 );
1444  
1445                  tds[ 0 ].style.display = "";
1446                  tds[ 1 ].style.display = "none";
1447  
1448                  // Check if empty table cells still have offsetWidth/Height
1449                  // (IE <= 8 fail this test)
1450                  support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );
1451  
1452                  // Check box-sizing and margin behavior
1453                  div.innerHTML = "";
1454                  div.style.cssText = "box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;";
1455                  support.boxSizing = ( div.offsetWidth === 4 );
1456                  support.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== 1 );
1457  
1458                  // NOTE: To any future maintainer, we've window.getComputedStyle
1459                  // because jsdom on node.js will break without it.
1460                  if ( window.getComputedStyle ) {
1461                          support.pixelPosition = ( window.getComputedStyle( div, null ) || {} ).top !== "1%";
1462                          support.boxSizingReliable = ( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px";
1463  
1464                          // Check if div with explicit width and no margin-right incorrectly
1465                          // gets computed margin-right based on width of container. For more
1466                          // info see bug #3333
1467                          // Fails in WebKit before Feb 2011 nightlies
1468                          // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
1469                          marginDiv = document.createElement("div");
1470                          marginDiv.style.cssText = div.style.cssText = divReset;
1471                          marginDiv.style.marginRight = marginDiv.style.width = "0";
1472                          div.style.width = "1px";
1473                          div.appendChild( marginDiv );
1474                          support.reliableMarginRight =
1475                                  !parseFloat( ( window.getComputedStyle( marginDiv, null ) || {} ).marginRight );
1476                  }
1477  
1478                  if ( typeof div.style.zoom !== "undefined" ) {
1479                          // Check if natively block-level elements act like inline-block
1480                          // elements when setting their display to 'inline' and giving
1481                          // them layout
1482                          // (IE < 8 does this)
1483                          div.innerHTML = "";
1484                          div.style.cssText = divReset + "width:1px;padding:1px;display:inline;zoom:1";
1485                          support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 );
1486  
1487                          // Check if elements with layout shrink-wrap their children
1488                          // (IE 6 does this)
1489                          div.style.display = "block";
1490                          div.style.overflow = "visible";
1491                          div.innerHTML = "<div></div>";
1492                          div.firstChild.style.width = "5px";
1493                          support.shrinkWrapBlocks = ( div.offsetWidth !== 3 );
1494  
1495                          container.style.zoom = 1;
1496                  }
1497  
1498                  // Null elements to avoid leaks in IE
1499                  body.removeChild( container );
1500                  container = div = tds = marginDiv = null;
1501          });
1502  
1503          // Null elements to avoid leaks in IE
1504          fragment.removeChild( div );
1505          all = a = select = opt = input = fragment = div = null;
1506  
1507          return support;
1508  })();
1509  var rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/,
1510          rmultiDash = /([A-Z])/g;
1511  
1512  jQuery.extend({
1513          cache: {},
1514  
1515          deletedIds: [],
1516  
1517          // Remove at next major release (1.9/2.0)
1518          uuid: 0,
1519  
1520          // Unique for each copy of jQuery on the page
1521          // Non-digits removed to match rinlinejQuery
1522          expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ),
1523  
1524          // The following elements throw uncatchable exceptions if you
1525          // attempt to add expando properties to them.
1526          noData: {
1527                  "embed": true,
1528                  // Ban all objects except for Flash (which handle expandos)
1529                  "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",
1530                  "applet": true
1531          },
1532  
1533          hasData: function( elem ) {
1534                  elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];
1535                  return !!elem && !isEmptyDataObject( elem );
1536          },
1537  
1538          data: function( elem, name, data, pvt /* Internal Use Only */ ) {
1539                  if ( !jQuery.acceptData( elem ) ) {
1540                          return;
1541                  }
1542  
1543                  var thisCache, ret,
1544                          internalKey = jQuery.expando,
1545                          getByName = typeof name === "string",
1546  
1547                          // We have to handle DOM nodes and JS objects differently because IE6-7
1548                          // can't GC object references properly across the DOM-JS boundary
1549                          isNode = elem.nodeType,
1550  
1551                          // Only DOM nodes need the global jQuery cache; JS object data is
1552                          // attached directly to the object so GC can occur automatically
1553                          cache = isNode ? jQuery.cache : elem,
1554  
1555                          // Only defining an ID for JS objects if its cache already exists allows
1556                          // the code to shortcut on the same path as a DOM node with no cache
1557                          id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey;
1558  
1559                  // Avoid doing any more work than we need to when trying to get data on an
1560                  // object that has no data at all
1561                  if ( (!id || !cache[id] || (!pvt && !cache[id].data)) && getByName && data === undefined ) {
1562                          return;
1563                  }
1564  
1565                  if ( !id ) {
1566                          // Only DOM nodes need a new unique ID for each element since their data
1567                          // ends up in the global cache
1568                          if ( isNode ) {
1569                                  elem[ internalKey ] = id = jQuery.deletedIds.pop() || jQuery.guid++;
1570                          } else {
1571                                  id = internalKey;
1572                          }
1573                  }
1574  
1575                  if ( !cache[ id ] ) {
1576                          cache[ id ] = {};
1577  
1578                          // Avoids exposing jQuery metadata on plain JS objects when the object
1579                          // is serialized using JSON.stringify
1580                          if ( !isNode ) {
1581                                  cache[ id ].toJSON = jQuery.noop;
1582                          }
1583                  }
1584  
1585                  // An object can be passed to jQuery.data instead of a key/value pair; this gets
1586                  // shallow copied over onto the existing cache
1587                  if ( typeof name === "object" || typeof name === "function" ) {
1588                          if ( pvt ) {
1589                                  cache[ id ] = jQuery.extend( cache[ id ], name );
1590                          } else {
1591                                  cache[ id ].data = jQuery.extend( cache[ id ].data, name );
1592                          }
1593                  }
1594  
1595                  thisCache = cache[ id ];
1596  
1597                  // jQuery data() is stored in a separate object inside the object's internal data
1598                  // cache in order to avoid key collisions between internal data and user-defined
1599                  // data.
1600                  if ( !pvt ) {
1601                          if ( !thisCache.data ) {
1602                                  thisCache.data = {};
1603                          }
1604  
1605                          thisCache = thisCache.data;
1606                  }
1607  
1608                  if ( data !== undefined ) {
1609                          thisCache[ jQuery.camelCase( name ) ] = data;
1610                  }
1611  
1612                  // Check for both converted-to-camel and non-converted data property names
1613                  // If a data property was specified
1614                  if ( getByName ) {
1615  
1616                          // First Try to find as-is property data
1617                          ret = thisCache[ name ];
1618  
1619                          // Test for null|undefined property data
1620                          if ( ret == null ) {
1621  
1622                                  // Try to find the camelCased property
1623                                  ret = thisCache[ jQuery.camelCase( name ) ];
1624                          }
1625                  } else {
1626                          ret = thisCache;
1627                  }
1628  
1629                  return ret;
1630          },
1631  
1632          removeData: function( elem, name, pvt /* Internal Use Only */ ) {
1633                  if ( !jQuery.acceptData( elem ) ) {
1634                          return;
1635                  }
1636  
1637                  var thisCache, i, l,
1638  
1639                          isNode = elem.nodeType,
1640  
1641                          // See jQuery.data for more information
1642                          cache = isNode ? jQuery.cache : elem,
1643                          id = isNode ? elem[ jQuery.expando ] : jQuery.expando;
1644  
1645                  // If there is already no cache entry for this object, there is no
1646                  // purpose in continuing
1647                  if ( !cache[ id ] ) {
1648                          return;
1649                  }
1650  
1651                  if ( name ) {
1652  
1653                          thisCache = pvt ? cache[ id ] : cache[ id ].data;
1654  
1655                          if ( thisCache ) {
1656  
1657                                  // Support array or space separated string names for data keys
1658                                  if ( !jQuery.isArray( name ) ) {
1659  
1660                                          // try the string as a key before any manipulation
1661                                          if ( name in thisCache ) {
1662                                                  name = [ name ];
1663                                          } else {
1664  
1665                                                  // split the camel cased version by spaces unless a key with the spaces exists
1666                                                  name = jQuery.camelCase( name );
1667                                                  if ( name in thisCache ) {
1668                                                          name = [ name ];
1669                                                  } else {
1670                                                          name = name.split(" ");
1671                                                  }
1672                                          }
1673                                  }
1674  
1675                                  for ( i = 0, l = name.length; i < l; i++ ) {
1676                                          delete thisCache[ name[i] ];
1677                                  }
1678  
1679                                  // If there is no data left in the cache, we want to continue
1680                                  // and let the cache object itself get destroyed
1681                                  if ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) {
1682                                          return;
1683                                  }
1684                          }
1685                  }
1686  
1687                  // See jQuery.data for more information
1688                  if ( !pvt ) {
1689                          delete cache[ id ].data;
1690  
1691                          // Don't destroy the parent cache unless the internal data object
1692                          // had been the only thing left in it
1693                          if ( !isEmptyDataObject( cache[ id ] ) ) {
1694                                  return;
1695                          }
1696                  }
1697  
1698                  // Destroy the cache
1699                  if ( isNode ) {
1700                          jQuery.cleanData( [ elem ], true );
1701  
1702                  // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080)
1703                  } else if ( jQuery.support.deleteExpando || cache != cache.window ) {
1704                          delete cache[ id ];
1705  
1706                  // When all else fails, null
1707                  } else {
1708                          cache[ id ] = null;
1709                  }
1710          },
1711  
1712          // For internal use only.
1713          _data: function( elem, name, data ) {
1714                  return jQuery.data( elem, name, data, true );
1715          },
1716  
1717          // A method for determining if a DOM node can handle the data expando
1718          acceptData: function( elem ) {
1719                  var noData = elem.nodeName && jQuery.noData[ elem.nodeName.toLowerCase() ];
1720  
1721                  // nodes accept data unless otherwise specified; rejection can be conditional
1722                  return !noData || noData !== true && elem.getAttribute("classid") === noData;
1723          }
1724  });
1725  
1726  jQuery.fn.extend({
1727          data: function( key, value ) {
1728                  var parts, part, attr, name, l,
1729                          elem = this[0],
1730                          i = 0,
1731                          data = null;
1732  
1733                  // Gets all values
1734                  if ( key === undefined ) {
1735                          if ( this.length ) {
1736                                  data = jQuery.data( elem );
1737  
1738                                  if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) {
1739                                          attr = elem.attributes;
1740                                          for ( l = attr.length; i < l; i++ ) {
1741                                                  name = attr[i].name;
1742  
1743                                                  if ( !name.indexOf( "data-" ) ) {
1744                                                          name = jQuery.camelCase( name.substring(5) );
1745  
1746                                                          dataAttr( elem, name, data[ name ] );
1747                                                  }
1748                                          }
1749                                          jQuery._data( elem, "parsedAttrs", true );
1750                                  }
1751                          }
1752  
1753                          return data;
1754                  }
1755  
1756                  // Sets multiple values
1757                  if ( typeof key === "object" ) {
1758                          return this.each(function() {
1759                                  jQuery.data( this, key );
1760                          });
1761                  }
1762  
1763                  parts = key.split( ".", 2 );
1764                  parts[1] = parts[1] ? "." + parts[1] : "";
1765                  part = parts[1] + "!";
1766  
1767                  return jQuery.access( this, function( value ) {
1768  
1769                          if ( value === undefined ) {
1770                                  data = this.triggerHandler( "getData" + part, [ parts[0] ] );
1771  
1772                                  // Try to fetch any internally stored data first
1773                                  if ( data === undefined && elem ) {
1774                                          data = jQuery.data( elem, key );
1775                                          data = dataAttr( elem, key, data );
1776                                  }
1777  
1778                                  return data === undefined && parts[1] ?
1779                                          this.data( parts[0] ) :
1780                                          data;
1781                          }
1782  
1783                          parts[1] = value;
1784                          this.each(function() {
1785                                  var self = jQuery( this );
1786  
1787                                  self.triggerHandler( "setData" + part, parts );
1788                                  jQuery.data( this, key, value );
1789                                  self.triggerHandler( "changeData" + part, parts );
1790                          });
1791                  }, null, value, arguments.length > 1, null, false );
1792          },
1793  
1794          removeData: function( key ) {
1795                  return this.each(function() {
1796                          jQuery.removeData( this, key );
1797                  });
1798          }
1799  });
1800  
1801  function dataAttr( elem, key, data ) {
1802          // If nothing was found internally, try to fetch any
1803          // data from the HTML5 data-* attribute
1804          if ( data === undefined && elem.nodeType === 1 ) {
1805  
1806                  var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase();
1807  
1808                  data = elem.getAttribute( name );
1809  
1810                  if ( typeof data === "string" ) {
1811                          try {
1812                                  data = data === "true" ? true :
1813                                  data === "false" ? false :
1814                                  data === "null" ? null :
1815                                  // Only convert to a number if it doesn't change the string
1816                                  +data + "" === data ? +data :
1817                                  rbrace.test( data ) ? jQuery.parseJSON( data ) :
1818                                          data;
1819                          } catch( e ) {}
1820  
1821                          // Make sure we set the data so it isn't changed later
1822                          jQuery.data( elem, key, data );
1823  
1824                  } else {
1825                          data = undefined;
1826                  }
1827          }
1828  
1829          return data;
1830  }
1831  
1832  // checks a cache object for emptiness
1833  function isEmptyDataObject( obj ) {
1834          var name;
1835          for ( name in obj ) {
1836  
1837                  // if the public data object is empty, the private is still empty
1838                  if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) {
1839                          continue;
1840                  }
1841                  if ( name !== "toJSON" ) {
1842                          return false;
1843                  }
1844          }
1845  
1846          return true;
1847  }
1848  jQuery.extend({
1849          queue: function( elem, type, data ) {
1850                  var queue;
1851  
1852                  if ( elem ) {
1853                          type = ( type || "fx" ) + "queue";
1854                          queue = jQuery._data( elem, type );
1855  
1856                          // Speed up dequeue by getting out quickly if this is just a lookup
1857                          if ( data ) {
1858                                  if ( !queue || jQuery.isArray(data) ) {
1859                                          queue = jQuery._data( elem, type, jQuery.makeArray(data) );
1860                                  } else {
1861                                          queue.push( data );
1862                                  }
1863                          }
1864                          return queue || [];
1865                  }
1866          },
1867  
1868          dequeue: function( elem, type ) {
1869                  type = type || "fx";
1870  
1871                  var queue = jQuery.queue( elem, type ),
1872                          startLength = queue.length,
1873                          fn = queue.shift(),
1874                          hooks = jQuery._queueHooks( elem, type ),
1875                          next = function() {
1876                                  jQuery.dequeue( elem, type );
1877                          };
1878  
1879                  // If the fx queue is dequeued, always remove the progress sentinel
1880                  if ( fn === "inprogress" ) {
1881                          fn = queue.shift();
1882                          startLength--;
1883                  }
1884  
1885                  if ( fn ) {
1886  
1887                          // Add a progress sentinel to prevent the fx queue from being
1888                          // automatically dequeued
1889                          if ( type === "fx" ) {
1890                                  queue.unshift( "inprogress" );
1891                          }
1892  
1893                          // clear up the last queue stop function
1894                          delete hooks.stop;
1895                          fn.call( elem, next, hooks );
1896                  }
1897  
1898                  if ( !startLength && hooks ) {
1899                          hooks.empty.fire();
1900                  }
1901          },
1902  
1903          // not intended for public consumption - generates a queueHooks object, or returns the current one
1904          _queueHooks: function( elem, type ) {
1905                  var key = type + "queueHooks";
1906                  return jQuery._data( elem, key ) || jQuery._data( elem, key, {
1907                          empty: jQuery.Callbacks("once memory").add(function() {
1908                                  jQuery.removeData( elem, type + "queue", true );
1909                                  jQuery.removeData( elem, key, true );
1910                          })
1911                  });
1912          }
1913  });
1914  
1915  jQuery.fn.extend({
1916          queue: function( type, data ) {
1917                  var setter = 2;
1918  
1919                  if ( typeof type !== "string" ) {
1920                          data = type;
1921                          type = "fx";
1922                          setter--;
1923                  }
1924  
1925                  if ( arguments.length < setter ) {
1926                          return jQuery.queue( this[0], type );
1927                  }
1928  
1929                  return data === undefined ?
1930                          this :
1931                          this.each(function() {
1932                                  var queue = jQuery.queue( this, type, data );
1933  
1934                                  // ensure a hooks for this queue
1935                                  jQuery._queueHooks( this, type );
1936  
1937                                  if ( type === "fx" && queue[0] !== "inprogress" ) {
1938                                          jQuery.dequeue( this, type );
1939                                  }
1940                          });
1941          },
1942          dequeue: function( type ) {
1943                  return this.each(function() {
1944                          jQuery.dequeue( this, type );
1945                  });
1946          },
1947          // Based off of the plugin by Clint Helfers, with permission.
1948          // http://blindsignals.com/index.php/2009/07/jquery-delay/
1949          delay: function( time, type ) {
1950                  time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
1951                  type = type || "fx";
1952  
1953                  return this.queue( type, function( next, hooks ) {
1954                          var timeout = setTimeout( next, time );
1955                          hooks.stop = function() {
1956                                  clearTimeout( timeout );
1957                          };
1958                  });
1959          },
1960          clearQueue: function( type ) {
1961                  return this.queue( type || "fx", [] );
1962          },
1963          // Get a promise resolved when queues of a certain type
1964          // are emptied (fx is the type by default)
1965          promise: function( type, obj ) {
1966                  var tmp,
1967                          count = 1,
1968                          defer = jQuery.Deferred(),
1969                          elements = this,
1970                          i = this.length,
1971                          resolve = function() {
1972                                  if ( !( --count ) ) {
1973                                          defer.resolveWith( elements, [ elements ] );
1974                                  }
1975                          };
1976  
1977                  if ( typeof type !== "string" ) {
1978                          obj = type;
1979                          type = undefined;
1980                  }
1981                  type = type || "fx";
1982  
1983                  while( i-- ) {
1984                          tmp = jQuery._data( elements[ i ], type + "queueHooks" );
1985                          if ( tmp && tmp.empty ) {
1986                                  count++;
1987                                  tmp.empty.add( resolve );
1988                          }
1989                  }
1990                  resolve();
1991                  return defer.promise( obj );
1992          }
1993  });
1994  var nodeHook, boolHook, fixSpecified,
1995          rclass = /[\t\r\n]/g,
1996          rreturn = /\r/g,
1997          rtype = /^(?:button|input)$/i,
1998          rfocusable = /^(?:button|input|object|select|textarea)$/i,
1999          rclickable = /^a(?:rea|)$/i,
2000          rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,
2001          getSetAttribute = jQuery.support.getSetAttribute;
2002  
2003  jQuery.fn.extend({
2004          attr: function( name, value ) {
2005                  return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 );
2006          },
2007  
2008          removeAttr: function( name ) {
2009                  return this.each(function() {
2010                          jQuery.removeAttr( this, name );
2011                  });
2012          },
2013  
2014          prop: function( name, value ) {
2015                  return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 );
2016          },
2017  
2018          removeProp: function( name ) {
2019                  name = jQuery.propFix[ name ] || name;
2020                  return this.each(function() {
2021                          // try/catch handles cases where IE balks (such as removing a property on window)
2022                          try {
2023                                  this[ name ] = undefined;
2024                                  delete this[ name ];
2025                          } catch( e ) {}
2026                  });
2027          },
2028  
2029          addClass: function( value ) {
2030                  var classNames, i, l, elem,
2031                          setClass, c, cl;
2032  
2033                  if ( jQuery.isFunction( value ) ) {
2034                          return this.each(function( j ) {
2035                                  jQuery( this ).addClass( value.call(this, j, this.className) );
2036                          });
2037                  }
2038  
2039                  if ( value && typeof value === "string" ) {
2040                          classNames = value.split( core_rspace );
2041  
2042                          for ( i = 0, l = this.length; i < l; i++ ) {
2043                                  elem = this[ i ];
2044  
2045                                  if ( elem.nodeType === 1 ) {
2046                                          if ( !elem.className && classNames.length === 1 ) {
2047                                                  elem.className = value;
2048  
2049                                          } else {
2050                                                  setClass = " " + elem.className + " ";
2051  
2052                                                  for ( c = 0, cl = classNames.length; c < cl; c++ ) {
2053                                                          if ( setClass.indexOf( " " + classNames[ c ] + " " ) < 0 ) {
2054                                                                  setClass += classNames[ c ] + " ";
2055                                                          }
2056                                                  }
2057                                                  elem.className = jQuery.trim( setClass );
2058                                          }
2059                                  }
2060                          }
2061                  }
2062  
2063                  return this;
2064          },
2065  
2066          removeClass: function( value ) {
2067                  var removes, className, elem, c, cl, i, l;
2068  
2069                  if ( jQuery.isFunction( value ) ) {
2070                          return this.each(function( j ) {
2071                                  jQuery( this ).removeClass( value.call(this, j, this.className) );
2072                          });
2073                  }
2074                  if ( (value && typeof value === "string") || value === undefined ) {
2075                          removes = ( value || "" ).split( core_rspace );
2076  
2077                          for ( i = 0, l = this.length; i < l; i++ ) {
2078                                  elem = this[ i ];
2079                                  if ( elem.nodeType === 1 && elem.className ) {
2080  
2081                                          className = (" " + elem.className + " ").replace( rclass, " " );
2082  
2083                                          // loop over each item in the removal list
2084                                          for ( c = 0, cl = removes.length; c < cl; c++ ) {
2085                                                  // Remove until there is nothing to remove,
2086                                                  while ( className.indexOf(" " + removes[ c ] + " ") >= 0 ) {
2087                                                          className = className.replace( " " + removes[ c ] + " " , " " );
2088                                                  }
2089                                          }
2090                                          elem.className = value ? jQuery.trim( className ) : "";
2091                                  }
2092                          }
2093                  }
2094  
2095                  return this;
2096          },
2097  
2098          toggleClass: function( value, stateVal ) {
2099                  var type = typeof value,
2100                          isBool = typeof stateVal === "boolean";
2101  
2102                  if ( jQuery.isFunction( value ) ) {
2103                          return this.each(function( i ) {
2104                                  jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );
2105                          });
2106                  }
2107  
2108                  return this.each(function() {
2109                          if ( type === "string" ) {
2110                                  // toggle individual class names
2111                                  var className,
2112                                          i = 0,
2113                                          self = jQuery( this ),
2114                                          state = stateVal,
2115                                          classNames = value.split( core_rspace );
2116  
2117                                  while ( (className = classNames[ i++ ]) ) {
2118                                          // check each className given, space separated list
2119                                          state = isBool ? state : !self.hasClass( className );
2120                                          self[ state ? "addClass" : "removeClass" ]( className );
2121                                  }
2122  
2123                          } else if ( type === "undefined" || type === "boolean" ) {
2124                                  if ( this.className ) {
2125                                          // store className if set
2126                                          jQuery._data( this, "__className__", this.className );
2127                                  }
2128  
2129                                  // toggle whole className
2130                                  this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || "";
2131                          }
2132                  });
2133          },
2134  
2135          hasClass: function( selector ) {
2136                  var className = " " + selector + " ",
2137                          i = 0,
2138                          l = this.length;
2139                  for ( ; i < l; i++ ) {
2140                          if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) {
2141                                  return true;
2142                          }
2143                  }
2144  
2145                  return false;
2146          },
2147  
2148          val: function( value ) {
2149                  var hooks, ret, isFunction,
2150                          elem = this[0];
2151  
2152                  if ( !arguments.length ) {
2153                          if ( elem ) {
2154                                  hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];
2155  
2156                                  if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
2157                                          return ret;
2158                                  }
2159  
2160                                  ret = elem.value;
2161  
2162                                  return typeof ret === "string" ?
2163                                          // handle most common string cases
2164                                          ret.replace(rreturn, "") :
2165                                          // handle cases where value is null/undef or number
2166                                          ret == null ? "" : ret;
2167                          }
2168  
2169                          return;
2170                  }
2171  
2172                  isFunction = jQuery.isFunction( value );
2173  
2174                  return this.each(function( i ) {
2175                          var val,
2176                                  self = jQuery(this);
2177  
2178                          if ( this.nodeType !== 1 ) {
2179                                  return;
2180                          }
2181  
2182                          if ( isFunction ) {
2183                                  val = value.call( this, i, self.val() );
2184                          } else {
2185                                  val = value;
2186                          }
2187  
2188                          // Treat null/undefined as ""; convert numbers to string
2189                          if ( val == null ) {
2190                                  val = "";
2191                          } else if ( typeof val === "number" ) {
2192                                  val += "";
2193                          } else if ( jQuery.isArray( val ) ) {
2194                                  val = jQuery.map(val, function ( value ) {
2195                                          return value == null ? "" : value + "";
2196                                  });
2197                          }
2198  
2199                          hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
2200  
2201                          // If set returns undefined, fall back to normal setting
2202                          if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
2203                                  this.value = val;
2204                          }
2205                  });
2206          }
2207  });
2208  
2209  jQuery.extend({
2210          valHooks: {
2211                  option: {
2212                          get: function( elem ) {
2213                                  // attributes.value is undefined in Blackberry 4.7 but
2214                                  // uses .value. See #6932
2215                                  var val = elem.attributes.value;
2216                                  return !val || val.specified ? elem.value : elem.text;
2217                          }
2218                  },
2219                  select: {
2220                          get: function( elem ) {
2221                                  var value, option,
2222                                          options = elem.options,
2223                                          index = elem.selectedIndex,
2224                                          one = elem.type === "select-one" || index < 0,
2225                                          values = one ? null : [],
2226                                          max = one ? index + 1 : options.length,
2227                                          i = index < 0 ?
2228                                                  max :
2229                                                  one ? index : 0;
2230  
2231                                  // Loop through all the selected options
2232                                  for ( ; i < max; i++ ) {
2233                                          option = options[ i ];
2234  
2235                                          // oldIE doesn't update selected after form reset (#2551)
2236                                          if ( ( option.selected || i === index ) &&
2237                                                          // Don't return options that are disabled or in a disabled optgroup
2238                                                          ( jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null ) &&
2239                                                          ( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) {
2240  
2241                                                  // Get the specific value for the option
2242                                                  value = jQuery( option ).val();
2243  
2244                                                  // We don't need an array for one selects
2245                                                  if ( one ) {
2246                                                          return value;
2247                                                  }
2248  
2249                                                  // Multi-Selects return an array
2250                                                  values.push( value );
2251                                          }
2252                                  }
2253  
2254                                  return values;
2255                          },
2256  
2257                          set: function( elem, value ) {
2258                                  var values = jQuery.makeArray( value );
2259  
2260                                  jQuery(elem).find("option").each(function() {
2261                                          this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
2262                                  });
2263  
2264                                  if ( !values.length ) {
2265                                          elem.selectedIndex = -1;
2266                                  }
2267                                  return values;
2268                          }
2269                  }
2270          },
2271  
2272          // Unused in 1.8, left in so attrFn-stabbers won't die; remove in 1.9
2273          attrFn: {},
2274  
2275          attr: function( elem, name, value, pass ) {
2276                  var ret, hooks, notxml,
2277                          nType = elem.nodeType;
2278  
2279                  // don't get/set attributes on text, comment and attribute nodes
2280                  if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
2281                          return;
2282                  }
2283  
2284                  if ( pass && jQuery.isFunction( jQuery.fn[ name ] ) ) {
2285                          return jQuery( elem )[ name ]( value );
2286                  }
2287  
2288                  // Fallback to prop when attributes are not supported
2289                  if ( typeof elem.getAttribute === "undefined" ) {
2290                          return jQuery.prop( elem, name, value );
2291                  }
2292  
2293                  notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
2294  
2295                  // All attributes are lowercase
2296                  // Grab necessary hook if one is defined
2297                  if ( notxml ) {
2298                          name = name.toLowerCase();
2299                          hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook );
2300                  }
2301  
2302                  if ( value !== undefined ) {
2303  
2304                          if ( value === null ) {
2305                                  jQuery.removeAttr( elem, name );
2306                                  return;
2307  
2308                          } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) {
2309                                  return ret;
2310  
2311                          } else {
2312                                  elem.setAttribute( name, value + "" );
2313                                  return value;
2314                          }
2315  
2316                  } else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) {
2317                          return ret;
2318  
2319                  } else {
2320  
2321                          ret = elem.getAttribute( name );
2322  
2323                          // Non-existent attributes return null, we normalize to undefined
2324                          return ret === null ?
2325                                  undefined :
2326                                  ret;
2327                  }
2328          },
2329  
2330          removeAttr: function( elem, value ) {
2331                  var propName, attrNames, name, isBool,
2332                          i = 0;
2333  
2334                  if ( value && elem.nodeType === 1 ) {
2335  
2336                          attrNames = value.split( core_rspace );
2337  
2338                          for ( ; i < attrNames.length; i++ ) {
2339                                  name = attrNames[ i ];
2340  
2341                                  if ( name ) {
2342                                          propName = jQuery.propFix[ name ] || name;
2343                                          isBool = rboolean.test( name );
2344  
2345                                          // See #9699 for explanation of this approach (setting first, then removal)
2346                                          // Do not do this for boolean attributes (see #10870)
2347                                          if ( !isBool ) {
2348                                                  jQuery.attr( elem, name, "" );
2349                                          }
2350                                          elem.removeAttribute( getSetAttribute ? name : propName );
2351  
2352                                          // Set corresponding property to false for boolean attributes
2353                                          if ( isBool && propName in elem ) {
2354                                                  elem[ propName ] = false;
2355                                          }
2356                                  }
2357                          }
2358                  }
2359          },
2360  
2361          attrHooks: {
2362                  type: {
2363                          set: function( elem, value ) {
2364                                  // We can't allow the type property to be changed (since it causes problems in IE)
2365                                  if ( rtype.test( elem.nodeName ) && elem.parentNode ) {
2366                                          jQuery.error( "type property can't be changed" );
2367                                  } else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) {
2368                                          // Setting the type on a radio button after the value resets the value in IE6-9
2369                                          // Reset value to it's default in case type is set after value
2370                                          // This is for element creation
2371                                          var val = elem.value;
2372                                          elem.setAttribute( "type", value );
2373                                          if ( val ) {
2374                                                  elem.value = val;
2375                                          }
2376                                          return value;
2377                                  }
2378                          }
2379                  },
2380                  // Use the value property for back compat
2381                  // Use the nodeHook for button elements in IE6/7 (#1954)
2382                  value: {
2383                          get: function( elem, name ) {
2384                                  if ( nodeHook && jQuery.nodeName( elem, "button" ) ) {
2385                                          return nodeHook.get( elem, name );
2386                                  }
2387                                  return name in elem ?
2388                                          elem.value :
2389                                          null;
2390                          },
2391                          set: function( elem, value, name ) {
2392                                  if ( nodeHook && jQuery.nodeName( elem, "button" ) ) {
2393                                          return nodeHook.set( elem, value, name );
2394                                  }
2395                                  // Does not return so that setAttribute is also used
2396                                  elem.value = value;
2397                          }
2398                  }
2399          },
2400  
2401          propFix: {
2402                  tabindex: "tabIndex",
2403                  readonly: "readOnly",
2404                  "for": "htmlFor",
2405                  "class": "className",
2406                  maxlength: "maxLength",
2407                  cellspacing: "cellSpacing",
2408                  cellpadding: "cellPadding",
2409                  rowspan: "rowSpan",
2410                  colspan: "colSpan",
2411                  usemap: "useMap",
2412                  frameborder: "frameBorder",
2413                  contenteditable: "contentEditable"
2414          },
2415  
2416          prop: function( elem, name, value ) {
2417                  var ret, hooks, notxml,
2418                          nType = elem.nodeType;
2419  
2420                  // don't get/set properties on text, comment and attribute nodes
2421                  if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
2422                          return;
2423                  }
2424  
2425                  notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
2426  
2427                  if ( notxml ) {
2428                          // Fix name and attach hooks
2429                          name = jQuery.propFix[ name ] || name;
2430                          hooks = jQuery.propHooks[ name ];
2431                  }
2432  
2433                  if ( value !== undefined ) {
2434                          if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
2435                                  return ret;
2436  
2437                          } else {
2438                                  return ( elem[ name ] = value );
2439                          }
2440  
2441                  } else {
2442                          if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
2443                                  return ret;
2444  
2445                          } else {
2446                                  return elem[ name ];
2447                          }
2448                  }
2449          },
2450  
2451          propHooks: {
2452                  tabIndex: {
2453                          get: function( elem ) {
2454                                  // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
2455                                  // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
2456                                  var attributeNode = elem.getAttributeNode("tabindex");
2457  
2458                                  return attributeNode && attributeNode.specified ?
2459                                          parseInt( attributeNode.value, 10 ) :
2460                                          rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
2461                                                  0 :
2462                                                  undefined;
2463                          }
2464                  }
2465          }
2466  });
2467  
2468  // Hook for boolean attributes
2469  boolHook = {
2470          get: function( elem, name ) {
2471                  // Align boolean attributes with corresponding properties
2472                  // Fall back to attribute presence where some booleans are not supported
2473                  var attrNode,
2474                          property = jQuery.prop( elem, name );
2475                  return property === true || typeof property !== "boolean" && ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ?
2476                          name.toLowerCase() :
2477                          undefined;
2478          },
2479          set: function( elem, value, name ) {
2480                  var propName;
2481                  if ( value === false ) {
2482                          // Remove boolean attributes when set to false
2483                          jQuery.removeAttr( elem, name );
2484                  } else {
2485                          // value is true since we know at this point it's type boolean and not false
2486                          // Set boolean attributes to the same name and set the DOM property
2487                          propName = jQuery.propFix[ name ] || name;
2488                          if ( propName in elem ) {
2489                                  // Only set the IDL specifically if it already exists on the element
2490                                  elem[ propName ] = true;
2491                          }
2492  
2493                          elem.setAttribute( name, name.toLowerCase() );
2494                  }
2495                  return name;
2496          }
2497  };
2498  
2499  // IE6/7 do not support getting/setting some attributes with get/setAttribute
2500  if ( !getSetAttribute ) {
2501  
2502          fixSpecified = {
2503                  name: true,
2504                  id: true,
2505                  coords: true
2506          };
2507  
2508          // Use this for any attribute in IE6/7
2509          // This fixes almost every IE6/7 issue
2510          nodeHook = jQuery.valHooks.button = {
2511                  get: function( elem, name ) {
2512                          var ret;
2513                          ret = elem.getAttributeNode( name );
2514                          return ret && ( fixSpecified[ name ] ? ret.value !== "" : ret.specified ) ?
2515                                  ret.value :
2516                                  undefined;
2517                  },
2518                  set: function( elem, value, name ) {
2519                          // Set the existing or create a new attribute node
2520                          var ret = elem.getAttributeNode( name );
2521                          if ( !ret ) {
2522                                  ret = document.createAttribute( name );
2523                                  elem.setAttributeNode( ret );
2524                          }
2525                          return ( ret.value = value + "" );
2526                  }
2527          };
2528  
2529          // Set width and height to auto instead of 0 on empty string( Bug #8150 )
2530          // This is for removals
2531          jQuery.each([ "width", "height" ], function( i, name ) {
2532                  jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
2533                          set: function( elem, value ) {
2534                                  if ( value === "" ) {
2535                                          elem.setAttribute( name, "auto" );
2536                                          return value;
2537                                  }
2538                          }
2539                  });
2540          });
2541  
2542          // Set contenteditable to false on removals(#10429)
2543          // Setting to empty string throws an error as an invalid value
2544          jQuery.attrHooks.contenteditable = {
2545                  get: nodeHook.get,
2546                  set: function( elem, value, name ) {
2547                          if ( value === "" ) {
2548                                  value = "false";
2549                          }
2550                          nodeHook.set( elem, value, name );
2551                  }
2552          };
2553  }
2554  
2555  
2556  // Some attributes require a special call on IE
2557  if ( !jQuery.support.hrefNormalized ) {
2558          jQuery.each([ "href", "src", "width", "height" ], function( i, name ) {
2559                  jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
2560                          get: function( elem ) {
2561                                  var ret = elem.getAttribute( name, 2 );
2562                                  return ret === null ? undefined : ret;
2563                          }
2564                  });
2565          });
2566  }
2567  
2568  if ( !jQuery.support.style ) {
2569          jQuery.attrHooks.style = {
2570                  get: function( elem ) {
2571                          // Return undefined in the case of empty string
2572                          // Normalize to lowercase since IE uppercases css property names
2573                          return elem.style.cssText.toLowerCase() || undefined;
2574                  },
2575                  set: function( elem, value ) {
2576                          return ( elem.style.cssText = value + "" );
2577                  }
2578          };
2579  }
2580  
2581  // Safari mis-reports the default selected property of an option
2582  // Accessing the parent's selectedIndex property fixes it
2583  if ( !jQuery.support.optSelected ) {
2584          jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, {
2585                  get: function( elem ) {
2586                          var parent = elem.parentNode;
2587  
2588                          if ( parent ) {
2589                                  parent.selectedIndex;
2590  
2591                                  // Make sure that it also works with optgroups, see #5701
2592                                  if ( parent.parentNode ) {
2593                                          parent.parentNode.selectedIndex;
2594                                  }
2595                          }
2596                          return null;
2597                  }
2598          });
2599  }
2600  
2601  // IE6/7 call enctype encoding
2602  if ( !jQuery.support.enctype ) {
2603          jQuery.propFix.enctype = "encoding";
2604  }
2605  
2606  // Radios and checkboxes getter/setter
2607  if ( !jQuery.support.checkOn ) {
2608          jQuery.each([ "radio", "checkbox" ], function() {
2609                  jQuery.valHooks[ this ] = {
2610                          get: function( elem ) {
2611                                  // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
2612                                  return elem.getAttribute("value") === null ? "on" : elem.value;
2613                          }
2614                  };
2615          });
2616  }
2617  jQuery.each([ "radio", "checkbox" ], function() {
2618          jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], {
2619                  set: function( elem, value ) {
2620                          if ( jQuery.isArray( value ) ) {
2621                                  return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );
2622                          }
2623                  }
2624          });
2625  });
2626  var rformElems = /^(?:textarea|input|select)$/i,
2627          rtypenamespace = /^([^\.]*|)(?:\.(.+)|)$/,
2628          rhoverHack = /(?:^|\s)hover(\.\S+|)\b/,
2629          rkeyEvent = /^key/,
2630          rmouseEvent = /^(?:mouse|contextmenu)|click/,
2631          rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
2632          hoverHack = function( events ) {
2633                  return jQuery.event.special.hover ? events : events.replace( rhoverHack, "mouseenter$1 mouseleave$1" );
2634          };
2635  
2636  /*
2637   * Helper functions for managing events -- not part of the public interface.
2638   * Props to Dean Edwards' addEvent library for many of the ideas.
2639   */
2640  jQuery.event = {
2641  
2642          add: function( elem, types, handler, data, selector ) {
2643  
2644                  var elemData, eventHandle, events,
2645                          t, tns, type, namespaces, handleObj,
2646                          handleObjIn, handlers, special;
2647  
2648                  // Don't attach events to noData or text/comment nodes (allow plain objects tho)
2649                  if ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = jQuery._data( elem )) ) {
2650                          return;
2651                  }
2652  
2653                  // Caller can pass in an object of custom data in lieu of the handler
2654                  if ( handler.handler ) {
2655                          handleObjIn = handler;
2656                          handler = handleObjIn.handler;
2657                          selector = handleObjIn.selector;
2658                  }
2659  
2660                  // Make sure that the handler has a unique ID, used to find/remove it later
2661                  if ( !handler.guid ) {
2662                          handler.guid = jQuery.guid++;
2663                  }
2664  
2665                  // Init the element's event structure and main handler, if this is the first
2666                  events = elemData.events;
2667                  if ( !events ) {
2668                          elemData.events = events = {};
2669                  }
2670                  eventHandle = elemData.handle;
2671                  if ( !eventHandle ) {
2672                          elemData.handle = eventHandle = function( e ) {
2673                                  // Discard the second event of a jQuery.event.trigger() and
2674                                  // when an event is called after a page has unloaded
2675                                  return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ?
2676                                          jQuery.event.dispatch.apply( eventHandle.elem, arguments ) :
2677                                          undefined;
2678                          };
2679                          // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events
2680                          eventHandle.elem = elem;
2681                  }
2682  
2683                  // Handle multiple events separated by a space
2684                  // jQuery(...).bind("mouseover mouseout", fn);
2685                  types = jQuery.trim( hoverHack(types) ).split( " " );
2686                  for ( t = 0; t < types.length; t++ ) {
2687  
2688                          tns = rtypenamespace.exec( types[t] ) || [];
2689                          type = tns[1];
2690                          namespaces = ( tns[2] || "" ).split( "." ).sort();
2691  
2692                          // If event changes its type, use the special event handlers for the changed type
2693                          special = jQuery.event.special[ type ] || {};
2694  
2695                          // If selector defined, determine special event api type, otherwise given type
2696                          type = ( selector ? special.delegateType : special.bindType ) || type;
2697  
2698                          // Update special based on newly reset type
2699                          special = jQuery.event.special[ type ] || {};
2700  
2701                          // handleObj is passed to all event handlers
2702                          handleObj = jQuery.extend({
2703                                  type: type,
2704                                  origType: tns[1],
2705                                  data: data,
2706                                  handler: handler,
2707                                  guid: handler.guid,
2708                                  selector: selector,
2709                                  needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
2710                                  namespace: namespaces.join(".")
2711                          }, handleObjIn );
2712  
2713                          // Init the event handler queue if we're the first
2714                          handlers = events[ type ];
2715                          if ( !handlers ) {
2716                                  handlers = events[ type ] = [];
2717                                  handlers.delegateCount = 0;
2718  
2719                                  // Only use addEventListener/attachEvent if the special events handler returns false
2720                                  if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
2721                                          // Bind the global event handler to the element
2722                                          if ( elem.addEventListener ) {
2723                                                  elem.addEventListener( type, eventHandle, false );
2724  
2725                                          } else if ( elem.attachEvent ) {
2726                                                  elem.attachEvent( "on" + type, eventHandle );
2727                                          }
2728                                  }
2729                          }
2730  
2731                          if ( special.add ) {
2732                                  special.add.call( elem, handleObj );
2733  
2734                                  if ( !handleObj.handler.guid ) {
2735                                          handleObj.handler.guid = handler.guid;
2736                                  }
2737                          }
2738  
2739                          // Add to the element's handler list, delegates in front
2740                          if ( selector ) {
2741                                  handlers.splice( handlers.delegateCount++, 0, handleObj );
2742                          } else {
2743                                  handlers.push( handleObj );
2744                          }
2745  
2746                          // Keep track of which events have ever been used, for event optimization
2747                          jQuery.event.global[ type ] = true;
2748                  }
2749  
2750                  // Nullify elem to prevent memory leaks in IE
2751                  elem = null;
2752          },
2753  
2754          global: {},
2755  
2756          // Detach an event or set of events from an element
2757          remove: function( elem, types, handler, selector, mappedTypes ) {
2758  
2759                  var t, tns, type, origType, namespaces, origCount,
2760                          j, events, special, eventType, handleObj,
2761                          elemData = jQuery.hasData( elem ) && jQuery._data( elem );
2762  
2763                  if ( !elemData || !(events = elemData.events) ) {
2764                          return;
2765                  }
2766  
2767                  // Once for each type.namespace in types; type may be omitted
2768                  types = jQuery.trim( hoverHack( types || "" ) ).split(" ");
2769                  for ( t = 0; t < types.length; t++ ) {
2770                          tns = rtypenamespace.exec( types[t] ) || [];
2771                          type = origType = tns[1];
2772                          namespaces = tns[2];
2773  
2774                          // Unbind all events (on this namespace, if provided) for the element
2775                          if ( !type ) {
2776                                  for ( type in events ) {
2777                                          jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
2778                                  }
2779                                  continue;
2780                          }
2781  
2782                          special = jQuery.event.special[ type ] || {};
2783                          type = ( selector? special.delegateType : special.bindType ) || type;
2784                          eventType = events[ type ] || [];
2785                          origCount = eventType.length;
2786                          namespaces = namespaces ? new RegExp("(^|\\.)" + namespaces.split(".").sort().join("\\.(?:.*\\.|)") + "(\\.|$)") : null;
2787  
2788                          // Remove matching events
2789                          for ( j = 0; j < eventType.length; j++ ) {
2790                                  handleObj = eventType[ j ];
2791  
2792                                  if ( ( mappedTypes || origType === handleObj.origType ) &&
2793                                           ( !handler || handler.guid === handleObj.guid ) &&
2794                                           ( !namespaces || namespaces.test( handleObj.namespace ) ) &&
2795                                           ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) {
2796                                          eventType.splice( j--, 1 );
2797  
2798                                          if ( handleObj.selector ) {
2799                                                  eventType.delegateCount--;
2800                                          }
2801                                          if ( special.remove ) {
2802                                                  special.remove.call( elem, handleObj );
2803                                          }
2804                                  }
2805                          }
2806  
2807                          // Remove generic event handler if we removed something and no more handlers exist
2808                          // (avoids potential for endless recursion during removal of special event handlers)
2809                          if ( eventType.length === 0 && origCount !== eventType.length ) {
2810                                  if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
2811                                          jQuery.removeEvent( elem, type, elemData.handle );
2812                                  }
2813  
2814                                  delete events[ type ];
2815                          }
2816                  }
2817  
2818                  // Remove the expando if it's no longer used
2819                  if ( jQuery.isEmptyObject( events ) ) {
2820                          delete elemData.handle;
2821  
2822                          // removeData also checks for emptiness and clears the expando if empty
2823                          // so use it instead of delete
2824                          jQuery.removeData( elem, "events", true );
2825                  }
2826          },
2827  
2828          // Events that are safe to short-circuit if no handlers are attached.
2829          // Native DOM events should not be added, they may have inline handlers.
2830          customEvent: {
2831                  "getData": true,
2832                  "setData": true,
2833                  "changeData": true
2834          },
2835  
2836          trigger: function( event, data, elem, onlyHandlers ) {
2837                  // Don't do events on text and comment nodes
2838                  if ( elem && (elem.nodeType === 3 || elem.nodeType === 8) ) {
2839                          return;
2840                  }
2841  
2842                  // Event object or event type
2843                  var cache, exclusive, i, cur, old, ontype, special, handle, eventPath, bubbleType,
2844                          type = event.type || event,
2845                          namespaces = [];
2846  
2847                  // focus/blur morphs to focusin/out; ensure we're not firing them right now
2848                  if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
2849                          return;
2850                  }
2851  
2852                  if ( type.indexOf( "!" ) >= 0 ) {
2853                          // Exclusive events trigger only for the exact event (no namespaces)
2854                          type = type.slice(0, -1);
2855                          exclusive = true;
2856                  }
2857  
2858                  if ( type.indexOf( "." ) >= 0 ) {
2859                          // Namespaced trigger; create a regexp to match event type in handle()
2860                          namespaces = type.split(".");
2861                          type = namespaces.shift();
2862                          namespaces.sort();
2863                  }
2864  
2865                  if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) {
2866                          // No jQuery handlers for this event type, and it can't have inline handlers
2867                          return;
2868                  }
2869  
2870                  // Caller can pass in an Event, Object, or just an event type string
2871                  event = typeof event === "object" ?
2872                          // jQuery.Event object
2873                          event[ jQuery.expando ] ? event :
2874                          // Object literal
2875                          new jQuery.Event( type, event ) :
2876                          // Just the event type (string)
2877                          new jQuery.Event( type );
2878  
2879                  event.type = type;
2880                  event.isTrigger = true;
2881                  event.exclusive = exclusive;
2882                  event.namespace = namespaces.join( "." );
2883                  event.namespace_re = event.namespace? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)") : null;
2884                  ontype = type.indexOf( ":" ) < 0 ? "on" + type : "";
2885  
2886                  // Handle a global trigger
2887                  if ( !elem ) {
2888  
2889                          // TODO: Stop taunting the data cache; remove global events and always attach to document
2890                          cache = jQuery.cache;
2891                          for ( i in cache ) {
2892                                  if ( cache[ i ].events && cache[ i ].events[ type ] ) {
2893                                          jQuery.event.trigger( event, data, cache[ i ].handle.elem, true );
2894                                  }
2895                          }
2896                          return;
2897                  }
2898  
2899                  // Clean up the event in case it is being reused
2900                  event.result = undefined;
2901                  if ( !event.target ) {
2902                          event.target = elem;
2903                  }
2904  
2905                  // Clone any incoming data and prepend the event, creating the handler arg list
2906                  data = data != null ? jQuery.makeArray( data ) : [];
2907                  data.unshift( event );
2908  
2909                  // Allow special events to draw outside the lines
2910                  special = jQuery.event.special[ type ] || {};
2911                  if ( special.trigger && special.trigger.apply( elem, data ) === false ) {
2912                          return;
2913                  }
2914  
2915                  // Determine event propagation path in advance, per W3C events spec (#9951)
2916                  // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
2917                  eventPath = [[ elem, special.bindType || type ]];
2918                  if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
2919  
2920                          bubbleType = special.delegateType || type;
2921                          cur = rfocusMorph.test( bubbleType + type ) ? elem : elem.parentNode;
2922                          for ( old = elem; cur; cur = cur.parentNode ) {
2923                                  eventPath.push([ cur, bubbleType ]);
2924                                  old = cur;
2925                          }
2926  
2927                          // Only add window if we got to document (e.g., not plain obj or detached DOM)
2928                          if ( old === (elem.ownerDocument || document) ) {
2929                                  eventPath.push([ old.defaultView || old.parentWindow || window, bubbleType ]);
2930                          }
2931                  }
2932  
2933                  // Fire handlers on the event path
2934                  for ( i = 0; i < eventPath.length && !event.isPropagationStopped(); i++ ) {
2935  
2936                          cur = eventPath[i][0];
2937                          event.type = eventPath[i][1];
2938  
2939                          handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" );
2940                          if ( handle ) {
2941                                  handle.apply( cur, data );
2942                          }
2943                          // Note that this is a bare JS function and not a jQuery handler
2944                          handle = ontype && cur[ ontype ];
2945                          if ( handle && jQuery.acceptData( cur ) && handle.apply && handle.apply( cur, data ) === false ) {
2946                                  event.preventDefault();
2947                          }
2948                  }
2949                  event.type = type;
2950  
2951                  // If nobody prevented the default action, do it now
2952                  if ( !onlyHandlers && !event.isDefaultPrevented() ) {
2953  
2954                          if ( (!special._default || special._default.apply( elem.ownerDocument, data ) === false) &&
2955                                  !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) {
2956  
2957                                  // Call a native DOM method on the target with the same name name as the event.
2958                                  // Can't use an .isFunction() check here because IE6/7 fails that test.
2959                                  // Don't do default actions on window, that's where global variables be (#6170)
2960                                  // IE<9 dies on focus/blur to hidden element (#1486)
2961                                  if ( ontype && elem[ type ] && ((type !== "focus" && type !== "blur") || event.target.offsetWidth !== 0) && !jQuery.isWindow( elem ) ) {
2962  
2963                                          // Don't re-trigger an onFOO event when we call its FOO() method
2964                                          old = elem[ ontype ];
2965  
2966                                          if ( old ) {
2967                                                  elem[ ontype ] = null;
2968                                          }
2969  
2970                                          // Prevent re-triggering of the same event, since we already bubbled it above
2971                                          jQuery.event.triggered = type;
2972                                          elem[ type ]();
2973                                          jQuery.event.triggered = undefined;
2974  
2975                                          if ( old ) {
2976                                                  elem[ ontype ] = old;
2977                                          }
2978                                  }
2979                          }
2980                  }
2981  
2982                  return event.result;
2983          },
2984  
2985          dispatch: function( event ) {
2986  
2987                  // Make a writable jQuery.Event from the native event object
2988                  event = jQuery.event.fix( event || window.event );
2989  
2990                  var i, j, cur, ret, selMatch, matched, matches, handleObj, sel, related,
2991                          handlers = ( (jQuery._data( this, "events" ) || {} )[ event.type ] || []),
2992                          delegateCount = handlers.delegateCount,
2993                          args = core_slice.call( arguments ),
2994                          run_all = !event.exclusive && !event.namespace,
2995                          special = jQuery.event.special[ event.type ] || {},
2996                          handlerQueue = [];
2997  
2998                  // Use the fix-ed jQuery.Event rather than the (read-only) native event
2999                  args[0] = event;
3000                  event.delegateTarget = this;
3001  
3002                  // Call the preDispatch hook for the mapped type, and let it bail if desired
3003                  if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
3004                          return;
3005                  }
3006  
3007                  // Determine handlers that should run if there are delegated events
3008                  // Avoid non-left-click bubbling in Firefox (#3861)
3009                  if ( delegateCount && !(event.button && event.type === "click") ) {
3010  
3011                          for ( cur = event.target; cur != this; cur = cur.parentNode || this ) {
3012  
3013                                  // Don't process clicks (ONLY) on disabled elements (#6911, #8165, #11382, #11764)
3014                                  if ( cur.disabled !== true || event.type !== "click" ) {
3015                                          selMatch = {};
3016                                          matches = [];
3017                                          for ( i = 0; i < delegateCount; i++ ) {
3018                                                  handleObj = handlers[ i ];
3019                                                  sel = handleObj.selector;
3020  
3021                                                  if ( selMatch[ sel ] === undefined ) {
3022                                                          selMatch[ sel ] = handleObj.needsContext ?
3023                                                                  jQuery( sel, this ).index( cur ) >= 0 :
3024                                                                  jQuery.find( sel, this, null, [ cur ] ).length;
3025                                                  }
3026                                                  if ( selMatch[ sel ] ) {
3027                                                          matches.push( handleObj );
3028                                                  }
3029                                          }
3030                                          if ( matches.length ) {
3031                                                  handlerQueue.push({ elem: cur, matches: matches });
3032                                          }
3033                                  }
3034                          }
3035                  }
3036  
3037                  // Add the remaining (directly-bound) handlers
3038                  if ( handlers.length > delegateCount ) {
3039                          handlerQueue.push({ elem: this, matches: handlers.slice( delegateCount ) });
3040                  }
3041  
3042                  // Run delegates first; they may want to stop propagation beneath us
3043                  for ( i = 0; i < handlerQueue.length && !event.isPropagationStopped(); i++ ) {
3044                          matched = handlerQueue[ i ];
3045                          event.currentTarget = matched.elem;
3046  
3047                          for ( j = 0; j < matched.matches.length && !event.isImmediatePropagationStopped(); j++ ) {
3048                                  handleObj = matched.matches[ j ];
3049  
3050                                  // Triggered event must either 1) be non-exclusive and have no namespace, or
3051                                  // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).
3052                                  if ( run_all || (!event.namespace && !handleObj.namespace) || event.namespace_re && event.namespace_re.test( handleObj.namespace ) ) {
3053  
3054                                          event.data = handleObj.data;
3055                                          event.handleObj = handleObj;
3056  
3057                                          ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )
3058                                                          .apply( matched.elem, args );
3059  
3060                                          if ( ret !== undefined ) {
3061                                                  event.result = ret;
3062                                                  if ( ret === false ) {
3063                                                          event.preventDefault();
3064                                                          event.stopPropagation();
3065                                                  }
3066                                          }
3067                                  }
3068                          }
3069                  }
3070  
3071                  // Call the postDispatch hook for the mapped type
3072                  if ( special.postDispatch ) {
3073                          special.postDispatch.call( this, event );
3074                  }
3075  
3076                  return event.result;
3077          },
3078  
3079          // Includes some event props shared by KeyEvent and MouseEvent
3080          // *** attrChange attrName relatedNode srcElement  are not normalized, non-W3C, deprecated, will be removed in 1.8 ***
3081          props: "attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),
3082  
3083          fixHooks: {},
3084  
3085          keyHooks: {
3086                  props: "char charCode key keyCode".split(" "),
3087                  filter: function( event, original ) {
3088  
3089                          // Add which for key events
3090                          if ( event.which == null ) {
3091                                  event.which = original.charCode != null ? original.charCode : original.keyCode;
3092                          }
3093  
3094                          return event;
3095                  }
3096          },
3097  
3098          mouseHooks: {
3099                  props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),
3100                  filter: function( event, original ) {
3101                          var eventDoc, doc, body,
3102                                  button = original.button,
3103                                  fromElement = original.fromElement;
3104  
3105                          // Calculate pageX/Y if missing and clientX/Y available
3106                          if ( event.pageX == null && original.clientX != null ) {
3107                                  eventDoc = event.target.ownerDocument || document;
3108                                  doc = eventDoc.documentElement;
3109                                  body = eventDoc.body;
3110  
3111                                  event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );
3112                                  event.pageY = original.clientY + ( doc && doc.scrollTop  || body && body.scrollTop  || 0 ) - ( doc && doc.clientTop  || body && body.clientTop  || 0 );
3113                          }
3114  
3115                          // Add relatedTarget, if necessary
3116                          if ( !event.relatedTarget && fromElement ) {
3117                                  event.relatedTarget = fromElement === event.target ? original.toElement : fromElement;
3118                          }
3119  
3120                          // Add which for click: 1 === left; 2 === middle; 3 === right
3121                          // Note: button is not normalized, so don't use it
3122                          if ( !event.which && button !== undefined ) {
3123                                  event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
3124                          }
3125  
3126                          return event;
3127                  }
3128          },
3129  
3130          fix: function( event ) {
3131                  if ( event[ jQuery.expando ] ) {
3132                          return event;
3133                  }
3134  
3135                  // Create a writable copy of the event object and normalize some properties
3136                  var i, prop,
3137                          originalEvent = event,
3138                          fixHook = jQuery.event.fixHooks[ event.type ] || {},
3139                          copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
3140  
3141                  event = jQuery.Event( originalEvent );
3142  
3143                  for ( i = copy.length; i; ) {
3144                          prop = copy[ --i ];
3145                          event[ prop ] = originalEvent[ prop ];
3146                  }
3147  
3148                  // Fix target property, if necessary (#1925, IE 6/7/8 & Safari2)
3149                  if ( !event.target ) {
3150                          event.target = originalEvent.srcElement || document;
3151                  }
3152  
3153                  // Target should not be a text node (#504, Safari)
3154                  if ( event.target.nodeType === 3 ) {
3155                          event.target = event.target.parentNode;
3156                  }
3157  
3158                  // For mouse/key events, metaKey==false if it's undefined (#3368, #11328; IE6/7/8)
3159                  event.metaKey = !!event.metaKey;
3160  
3161                  return fixHook.filter? fixHook.filter( event, originalEvent ) : event;
3162          },
3163  
3164          special: {
3165                  load: {
3166                          // Prevent triggered image.load events from bubbling to window.load
3167                          noBubble: true
3168                  },
3169  
3170                  focus: {
3171                          delegateType: "focusin"
3172                  },
3173                  blur: {
3174                          delegateType: "focusout"
3175                  },
3176  
3177                  beforeunload: {
3178                          setup: function( data, namespaces, eventHandle ) {
3179                                  // We only want to do this special case on windows
3180                                  if ( jQuery.isWindow( this ) ) {
3181                                          this.onbeforeunload = eventHandle;
3182                                  }
3183                          },
3184  
3185                          teardown: function( namespaces, eventHandle ) {
3186                                  if ( this.onbeforeunload === eventHandle ) {
3187                                          this.onbeforeunload = null;
3188                                  }
3189                          }
3190                  }
3191          },
3192  
3193          simulate: function( type, elem, event, bubble ) {
3194                  // Piggyback on a donor event to simulate a different one.
3195                  // Fake originalEvent to avoid donor's stopPropagation, but if the
3196                  // simulated event prevents default then we do the same on the donor.
3197                  var e = jQuery.extend(
3198                          new jQuery.Event(),
3199                          event,
3200                          { type: type,
3201                                  isSimulated: true,
3202                                  originalEvent: {}
3203                          }
3204                  );
3205                  if ( bubble ) {
3206                          jQuery.event.trigger( e, null, elem );
3207                  } else {
3208                          jQuery.event.dispatch.call( elem, e );
3209                  }
3210                  if ( e.isDefaultPrevented() ) {
3211                          event.preventDefault();
3212                  }
3213          }
3214  };
3215  
3216  // Some plugins are using, but it's undocumented/deprecated and will be removed.
3217  // The 1.7 special event interface should provide all the hooks needed now.
3218  jQuery.event.handle = jQuery.event.dispatch;
3219  
3220  jQuery.removeEvent = document.removeEventListener ?
3221          function( elem, type, handle ) {
3222                  if ( elem.removeEventListener ) {
3223                          elem.removeEventListener( type, handle, false );
3224                  }
3225          } :
3226          function( elem, type, handle ) {
3227                  var name = "on" + type;
3228  
3229                  if ( elem.detachEvent ) {
3230  
3231                          // #8545, #7054, preventing memory leaks for custom events in IE6-8
3232                          // detachEvent needed property on element, by name of that event, to properly expose it to GC
3233                          if ( typeof elem[ name ] === "undefined" ) {
3234                                  elem[ name ] = null;
3235                          }
3236  
3237                          elem.detachEvent( name, handle );
3238                  }
3239          };
3240  
3241  jQuery.Event = function( src, props ) {
3242          // Allow instantiation without the 'new' keyword
3243          if ( !(this instanceof jQuery.Event) ) {
3244                  return new jQuery.Event( src, props );
3245          }
3246  
3247          // Event object
3248          if ( src && src.type ) {
3249                  this.originalEvent = src;
3250                  this.type = src.type;
3251  
3252                  // Events bubbling up the document may have been marked as prevented
3253                  // by a handler lower down the tree; reflect the correct value.
3254                  this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false ||
3255                          src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse;
3256  
3257          // Event type
3258          } else {
3259                  this.type = src;
3260          }
3261  
3262          // Put explicitly provided properties onto the event object
3263          if ( props ) {
3264                  jQuery.extend( this, props );
3265          }
3266  
3267          // Create a timestamp if incoming event doesn't have one
3268          this.timeStamp = src && src.timeStamp || jQuery.now();
3269  
3270          // Mark it as fixed
3271          this[ jQuery.expando ] = true;
3272  };
3273  
3274  function returnFalse() {
3275          return false;
3276  }
3277  function returnTrue() {
3278          return true;
3279  }
3280  
3281  // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
3282  // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
3283  jQuery.Event.prototype = {
3284          preventDefault: function() {
3285                  this.isDefaultPrevented = returnTrue;
3286  
3287                  var e = this.originalEvent;
3288                  if ( !e ) {
3289                          return;
3290                  }
3291  
3292                  // if preventDefault exists run it on the original event
3293                  if ( e.preventDefault ) {
3294                          e.preventDefault();
3295  
3296                  // otherwise set the returnValue property of the original event to false (IE)
3297                  } else {
3298                          e.returnValue = false;
3299                  }
3300          },
3301          stopPropagation: function() {
3302                  this.isPropagationStopped = returnTrue;
3303  
3304                  var e = this.originalEvent;
3305                  if ( !e ) {
3306                          return;
3307                  }
3308                  // if stopPropagation exists run it on the original event
3309                  if ( e.stopPropagation ) {
3310                          e.stopPropagation();
3311                  }
3312                  // otherwise set the cancelBubble property of the original event to true (IE)
3313                  e.cancelBubble = true;
3314          },
3315          stopImmediatePropagation: function() {
3316                  this.isImmediatePropagationStopped = returnTrue;
3317                  this.stopPropagation();
3318          },
3319          isDefaultPrevented: returnFalse,
3320          isPropagationStopped: returnFalse,
3321          isImmediatePropagationStopped: returnFalse
3322  };
3323  
3324  // Create mouseenter/leave events using mouseover/out and event-time checks
3325  jQuery.each({
3326          mouseenter: "mouseover",
3327          mouseleave: "mouseout"
3328  }, function( orig, fix ) {
3329          jQuery.event.special[ orig ] = {
3330                  delegateType: fix,
3331                  bindType: fix,
3332  
3333                  handle: function( event ) {
3334                          var ret,
3335                                  target = this,
3336                                  related = event.relatedTarget,
3337                                  handleObj = event.handleObj,
3338                                  selector = handleObj.selector;
3339  
3340                          // For mousenter/leave call the handler if related is outside the target.
3341                          // NB: No relatedTarget if the mouse left/entered the browser window
3342                          if ( !related || (related !== target && !jQuery.contains( target, related )) ) {
3343                                  event.type = handleObj.origType;
3344                                  ret = handleObj.handler.apply( this, arguments );
3345                                  event.type = fix;
3346                          }
3347                          return ret;
3348                  }
3349          };
3350  });
3351  
3352  // IE submit delegation
3353  if ( !jQuery.support.submitBubbles ) {
3354  
3355          jQuery.event.special.submit = {
3356                  setup: function() {
3357                          // Only need this for delegated form submit events
3358                          if ( jQuery.nodeName( this, "form" ) ) {
3359                                  return false;
3360                          }
3361  
3362                          // Lazy-add a submit handler when a descendant form may potentially be submitted
3363                          jQuery.event.add( this, "click._submit keypress._submit", function( e ) {
3364                                  // Node name check avoids a VML-related crash in IE (#9807)
3365                                  var elem = e.target,
3366                                          form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined;
3367                                  if ( form && !jQuery._data( form, "_submit_attached" ) ) {
3368                                          jQuery.event.add( form, "submit._submit", function( event ) {
3369                                                  event._submit_bubble = true;
3370                                          });
3371                                          jQuery._data( form, "_submit_attached", true );
3372                                  }
3373                          });
3374                          // return undefined since we don't need an event listener
3375                  },
3376  
3377                  postDispatch: function( event ) {
3378                          // If form was submitted by the user, bubble the event up the tree
3379                          if ( event._submit_bubble ) {
3380                                  delete event._submit_bubble;
3381                                  if ( this.parentNode && !event.isTrigger ) {
3382                                          jQuery.event.simulate( "submit", this.parentNode, event, true );
3383                                  }
3384                          }
3385                  },
3386  
3387                  teardown: function() {
3388                          // Only need this for delegated form submit events
3389                          if ( jQuery.nodeName( this, "form" ) ) {
3390                                  return false;
3391                          }
3392  
3393                          // Remove delegated handlers; cleanData eventually reaps submit handlers attached above
3394                          jQuery.event.remove( this, "._submit" );
3395                  }
3396          };
3397  }
3398  
3399  // IE change delegation and checkbox/radio fix
3400  if ( !jQuery.support.changeBubbles ) {
3401  
3402          jQuery.event.special.change = {
3403  
3404                  setup: function() {
3405  
3406                          if ( rformElems.test( this.nodeName ) ) {
3407                                  // IE doesn't fire change on a check/radio until blur; trigger it on click
3408                                  // after a propertychange. Eat the blur-change in special.change.handle.
3409                                  // This still fires onchange a second time for check/radio after blur.
3410                                  if ( this.type === "checkbox" || this.type === "radio" ) {
3411                                          jQuery.event.add( this, "propertychange._change", function( event ) {
3412                                                  if ( event.originalEvent.propertyName === "checked" ) {
3413                                                          this._just_changed = true;
3414                                                  }
3415                                          });
3416                                          jQuery.event.add( this, "click._change", function( event ) {
3417                                                  if ( this._just_changed && !event.isTrigger ) {
3418                                                          this._just_changed = false;
3419                                                  }
3420                                                  // Allow triggered, simulated change events (#11500)
3421                                                  jQuery.event.simulate( "change", this, event, true );
3422                                          });
3423                                  }
3424                                  return false;
3425                          }
3426                          // Delegated event; lazy-add a change handler on descendant inputs
3427                          jQuery.event.add( this, "beforeactivate._change", function( e ) {
3428                                  var elem = e.target;
3429  
3430                                  if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "_change_attached" ) ) {
3431                                          jQuery.event.add( elem, "change._change", function( event ) {
3432                                                  if ( this.parentNode && !event.isSimulated && !event.isTrigger ) {
3433                                                          jQuery.event.simulate( "change", this.parentNode, event, true );
3434                                                  }
3435                                          });
3436                                          jQuery._data( elem, "_change_attached", true );
3437                                  }
3438                          });
3439                  },
3440  
3441                  handle: function( event ) {
3442                          var elem = event.target;
3443  
3444                          // Swallow native change events from checkbox/radio, we already triggered them above
3445                          if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) {
3446                                  return event.handleObj.handler.apply( this, arguments );
3447                          }
3448                  },
3449  
3450                  teardown: function() {
3451                          jQuery.event.remove( this, "._change" );
3452  
3453                          return !rformElems.test( this.nodeName );
3454                  }
3455          };
3456  }
3457  
3458  // Create "bubbling" focus and blur events
3459  if ( !jQuery.support.focusinBubbles ) {
3460          jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
3461  
3462                  // Attach a single capturing handler while someone wants focusin/focusout
3463                  var attaches = 0,
3464                          handler = function( event ) {
3465                                  jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );
3466                          };
3467  
3468                  jQuery.event.special[ fix ] = {
3469                          setup: function() {
3470                                  if ( attaches++ === 0 ) {
3471                                          document.addEventListener( orig, handler, true );
3472                                  }
3473                          },
3474                          teardown: function() {
3475                                  if ( --attaches === 0 ) {
3476                                          document.removeEventListener( orig, handler, true );
3477                                  }
3478                          }
3479                  };
3480          });
3481  }
3482  
3483  jQuery.fn.extend({
3484  
3485          on: function( types, selector, data, fn, /*INTERNAL*/ one ) {
3486                  var origFn, type;
3487  
3488                  // Types can be a map of types/handlers
3489                  if ( typeof types === "object" ) {
3490                          // ( types-Object, selector, data )
3491                          if ( typeof selector !== "string" ) { // && selector != null
3492                                  // ( types-Object, data )
3493                                  data = data || selector;
3494                                  selector = undefined;
3495                          }
3496                          for ( type in types ) {
3497                                  this.on( type, selector, data, types[ type ], one );
3498                          }
3499                          return this;
3500                  }
3501  
3502                  if ( data == null && fn == null ) {
3503                          // ( types, fn )
3504                          fn = selector;
3505                          data = selector = undefined;
3506                  } else if ( fn == null ) {
3507                          if ( typeof selector === "string" ) {
3508                                  // ( types, selector, fn )
3509                                  fn = data;
3510                                  data = undefined;
3511                          } else {
3512                                  // ( types, data, fn )
3513                                  fn = data;
3514                                  data = selector;
3515                                  selector = undefined;
3516                          }
3517                  }
3518                  if ( fn === false ) {
3519                          fn = returnFalse;
3520                  } else if ( !fn ) {
3521                          return this;
3522                  }
3523  
3524                  if ( one === 1 ) {
3525                          origFn = fn;
3526                          fn = function( event ) {
3527                                  // Can use an empty set, since event contains the info
3528                                  jQuery().off( event );
3529                                  return origFn.apply( this, arguments );
3530                          };
3531                          // Use same guid so caller can remove using origFn
3532                          fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
3533                  }
3534                  return this.each( function() {
3535                          jQuery.event.add( this, types, fn, data, selector );
3536                  });
3537          },
3538          one: function( types, selector, data, fn ) {
3539                  return this.on( types, selector, data, fn, 1 );
3540          },
3541          off: function( types, selector, fn ) {
3542                  var handleObj, type;
3543                  if ( types && types.preventDefault && types.handleObj ) {
3544                          // ( event )  dispatched jQuery.Event
3545                          handleObj = types.handleObj;
3546                          jQuery( types.delegateTarget ).off(
3547                                  handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType,
3548                                  handleObj.selector,
3549                                  handleObj.handler
3550                          );
3551                          return this;
3552                  }
3553                  if ( typeof types === "object" ) {
3554                          // ( types-object [, selector] )
3555                          for ( type in types ) {
3556                                  this.off( type, selector, types[ type ] );
3557                          }
3558                          return this;
3559                  }
3560                  if ( selector === false || typeof selector === "function" ) {
3561                          // ( types [, fn] )
3562                          fn = selector;
3563                          selector = undefined;
3564                  }
3565                  if ( fn === false ) {
3566                          fn = returnFalse;
3567                  }
3568                  return this.each(function() {
3569                          jQuery.event.remove( this, types, fn, selector );
3570                  });
3571          },
3572  
3573          bind: function( types, data, fn ) {
3574                  return this.on( types, null, data, fn );
3575          },
3576          unbind: function( types, fn ) {
3577                  return this.off( types, null, fn );
3578          },
3579  
3580          live: function( types, data, fn ) {
3581                  jQuery( this.context ).on( types, this.selector, data, fn );
3582                  return this;
3583          },
3584          die: function( types, fn ) {
3585                  jQuery( this.context ).off( types, this.selector || "**", fn );
3586                  return this;
3587          },
3588  
3589          delegate: function( selector, types, data, fn ) {
3590                  return this.on( types, selector, data, fn );
3591          },
3592          undelegate: function( selector, types, fn ) {
3593                  // ( namespace ) or ( selector, types [, fn] )
3594                  return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn );
3595          },
3596  
3597          trigger: function( type, data ) {
3598                  return this.each(function() {
3599                          jQuery.event.trigger( type, data, this );
3600                  });
3601          },
3602          triggerHandler: function( type, data ) {
3603                  if ( this[0] ) {
3604                          return jQuery.event.trigger( type, data, this[0], true );
3605                  }
3606          },
3607  
3608          toggle: function( fn ) {
3609                  // Save reference to arguments for access in closure
3610                  var args = arguments,
3611                          guid = fn.guid || jQuery.guid++,
3612                          i = 0,
3613                          toggler = function( event ) {
3614                                  // Figure out which function to execute
3615                                  var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i;
3616                                  jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 );
3617  
3618                                  // Make sure that clicks stop
3619                                  event.preventDefault();
3620  
3621                                  // and execute the function
3622                                  return args[ lastToggle ].apply( this, arguments ) || false;
3623                          };
3624  
3625                  // link all the functions, so any of them can unbind this click handler
3626                  toggler.guid = guid;
3627                  while ( i < args.length ) {
3628                          args[ i++ ].guid = guid;
3629                  }
3630  
3631                  return this.click( toggler );
3632          },
3633  
3634          hover: function( fnOver, fnOut ) {
3635                  return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
3636          }
3637  });
3638  
3639  jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
3640          "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
3641          "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) {
3642  
3643          // Handle event binding
3644          jQuery.fn[ name ] = function( data, fn ) {
3645                  if ( fn == null ) {
3646                          fn = data;
3647                          data = null;
3648                  }
3649  
3650                  return arguments.length > 0 ?
3651                          this.on( name, null, data, fn ) :
3652                          this.trigger( name );
3653          };
3654  
3655          if ( rkeyEvent.test( name ) ) {
3656                  jQuery.event.fixHooks[ name ] = jQuery.event.keyHooks;
3657          }
3658  
3659          if ( rmouseEvent.test( name ) ) {
3660                  jQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks;
3661          }
3662  });
3663  /*!
3664   * Sizzle CSS Selector Engine
3665   * Copyright 2012 jQuery Foundation and other contributors
3666   * Released under the MIT license
3667   * http://sizzlejs.com/
3668   */
3669  (function( window, undefined ) {
3670  
3671  var cachedruns,
3672          assertGetIdNotName,
3673          Expr,
3674          getText,
3675          isXML,
3676          contains,
3677          compile,
3678          sortOrder,
3679          hasDuplicate,
3680          outermostContext,
3681  
3682          baseHasDuplicate = true,
3683          strundefined = "undefined",
3684  
3685          expando = ( "sizcache" + Math.random() ).replace( ".", "" ),
3686  
3687          Token = String,
3688          document = window.document,
3689          docElem = document.documentElement,
3690          dirruns = 0,
3691          done = 0,
3692          pop = [].pop,
3693          push = [].push,
3694          slice = [].slice,
3695          // Use a stripped-down indexOf if a native one is unavailable
3696          indexOf = [].indexOf || function( elem ) {
3697                  var i = 0,
3698                          len = this.length;
3699                  for ( ; i < len; i++ ) {
3700                          if ( this[i] === elem ) {
3701                                  return i;
3702                          }
3703                  }
3704                  return -1;
3705          },
3706  
3707          // Augment a function for special use by Sizzle
3708          markFunction = function( fn, value ) {
3709                  fn[ expando ] = value == null || value;
3710                  return fn;
3711          },
3712  
3713          createCache = function() {
3714                  var cache = {},
3715                          keys = [];
3716  
3717                  return markFunction(function( key, value ) {
3718                          // Only keep the most recent entries
3719                          if ( keys.push( key ) > Expr.cacheLength ) {
3720                                  delete cache[ keys.shift() ];
3721                          }
3722  
3723                          // Retrieve with (key + " ") to avoid collision with native Object.prototype properties (see Issue #157)
3724                          return (cache[ key + " " ] = value);
3725                  }, cache );
3726          },
3727  
3728          classCache = createCache(),
3729          tokenCache = createCache(),
3730          compilerCache = createCache(),
3731  
3732          // Regex
3733  
3734          // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace
3735          whitespace = "[\\x20\\t\\r\\n\\f]",
3736          // http://www.w3.org/TR/css3-syntax/#characters
3737          characterEncoding = "(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+",
3738  
3739          // Loosely modeled on CSS identifier characters
3740          // An unquoted value should be a CSS identifier (http://www.w3.org/TR/css3-selectors/#attribute-selectors)
3741          // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
3742          identifier = characterEncoding.replace( "w", "w#" ),
3743  
3744          // Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors
3745          operators = "([*^$|!~]?=)",
3746          attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace +
3747                  "*(?:" + operators + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]",
3748  
3749          // Prefer arguments not in parens/brackets,
3750          //   then attribute selectors and non-pseudos (denoted by :),
3751          //   then anything else
3752          // These preferences are here to reduce the number of selectors
3753          //   needing tokenize in the PSEUDO preFilter
3754          pseudos = ":(" + characterEncoding + ")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:" + attributes + ")|[^:]|\\\\.)*|.*))\\)|)",
3755  
3756          // For matchExpr.POS and matchExpr.needsContext
3757          pos = ":(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace +
3758                  "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)",
3759  
3760          // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
3761          rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
3762  
3763          rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
3764          rcombinators = new RegExp( "^" + whitespace + "*([\\x20\\t\\r\\n\\f>+~])" + whitespace + "*" ),
3765          rpseudo = new RegExp( pseudos ),
3766  
3767          // Easily-parseable/retrievable ID or TAG or CLASS selectors
3768          rquickExpr = /^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,
3769  
3770          rnot = /^:not/,
3771          rsibling = /[\x20\t\r\n\f]*[+~]/,
3772          rendsWithNot = /:not\($/,
3773  
3774          rheader = /h\d/i,
3775          rinputs = /input|select|textarea|button/i,
3776  
3777          rbackslash = /\\(?!\\)/g,
3778  
3779          matchExpr = {
3780                  "ID": new RegExp( "^#(" + characterEncoding + ")" ),
3781                  "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ),
3782                  "NAME": new RegExp( "^\\[name=['\"]?(" + characterEncoding + ")['\"]?\\]" ),
3783                  "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ),
3784                  "ATTR": new RegExp( "^" + attributes ),
3785                  "PSEUDO": new RegExp( "^" + pseudos ),
3786                  "POS": new RegExp( pos, "i" ),
3787                  "CHILD": new RegExp( "^:(only|nth|first|last)-child(?:\\(" + whitespace +
3788                          "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
3789                          "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
3790                  // For use in libraries implementing .is()
3791                  "needsContext": new RegExp( "^" + whitespace + "*[>+~]|" + pos, "i" )
3792          },
3793  
3794          // Support
3795  
3796          // Used for testing something on an element
3797          assert = function( fn ) {
3798                  var div = document.createElement("div");
3799  
3800                  try {
3801                          return fn( div );
3802                  } catch (e) {
3803                          return false;
3804                  } finally {
3805                          // release memory in IE
3806                          div = null;
3807                  }
3808          },
3809  
3810          // Check if getElementsByTagName("*") returns only elements
3811          assertTagNameNoComments = assert(function( div ) {
3812                  div.appendChild( document.createComment("") );
3813                  return !div.getElementsByTagName("*").length;
3814          }),
3815  
3816          // Check if getAttribute returns normalized href attributes
3817          assertHrefNotNormalized = assert(function( div ) {
3818                  div.innerHTML = "<a href='#'></a>";
3819                  return div.firstChild && typeof div.firstChild.getAttribute !== strundefined &&
3820                          div.firstChild.getAttribute("href") === "#";
3821          }),
3822  
3823          // Check if attributes should be retrieved by attribute nodes
3824          assertAttributes = assert(function( div ) {
3825                  div.innerHTML = "<select></select>";
3826                  var type = typeof div.lastChild.getAttribute("multiple");
3827                  // IE8 returns a string for some attributes even when not present
3828                  return type !== "boolean" && type !== "string";
3829          }),
3830  
3831          // Check if getElementsByClassName can be trusted
3832          assertUsableClassName = assert(function( div ) {
3833                  // Opera can't find a second classname (in 9.6)
3834                  div.innerHTML = "<div class='hidden e'></div><div class='hidden'></div>";
3835                  if ( !div.getElementsByClassName || !div.getElementsByClassName("e").length ) {
3836                          return false;
3837                  }
3838  
3839                  // Safari 3.2 caches class attributes and doesn't catch changes
3840                  div.lastChild.className = "e";
3841                  return div.getElementsByClassName("e").length === 2;
3842          }),
3843  
3844          // Check if getElementById returns elements by name
3845          // Check if getElementsByName privileges form controls or returns elements by ID
3846          assertUsableName = assert(function( div ) {
3847                  // Inject content
3848                  div.id = expando + 0;
3849                  div.innerHTML = "<a name='" + expando + "'></a><div name='" + expando + "'></div>";
3850                  docElem.insertBefore( div, docElem.firstChild );
3851  
3852                  // Test
3853                  var pass = document.getElementsByName &&
3854                          // buggy browsers will return fewer than the correct 2
3855                          document.getElementsByName( expando ).length === 2 +
3856                          // buggy browsers will return more than the correct 0
3857                          document.getElementsByName( expando + 0 ).length;
3858                  assertGetIdNotName = !document.getElementById( expando );
3859  
3860                  // Cleanup
3861                  docElem.removeChild( div );
3862  
3863                  return pass;
3864          });
3865  
3866  // If slice is not available, provide a backup
3867  try {
3868          slice.call( docElem.childNodes, 0 )[0].nodeType;
3869  } catch ( e ) {
3870          slice = function( i ) {
3871                  var elem,
3872                          results = [];
3873                  for ( ; (elem = this[i]); i++ ) {
3874                          results.push( elem );
3875                  }
3876                  return results;
3877          };
3878  }
3879  
3880  function Sizzle( selector, context, results, seed ) {
3881          results = results || [];
3882          context = context || document;
3883          var match, elem, xml, m,
3884                  nodeType = context.nodeType;
3885  
3886          if ( !selector || typeof selector !== "string" ) {
3887                  return results;
3888          }
3889  
3890          if ( nodeType !== 1 && nodeType !== 9 ) {
3891                  return [];
3892          }
3893  
3894          xml = isXML( context );
3895  
3896          if ( !xml && !seed ) {
3897                  if ( (match = rquickExpr.exec( selector )) ) {
3898                          // Speed-up: Sizzle("#ID")
3899                          if ( (m = match[1]) ) {
3900                                  if ( nodeType === 9 ) {
3901                                          elem = context.getElementById( m );
3902                                          // Check parentNode to catch when Blackberry 4.6 returns
3903                                          // nodes that are no longer in the document #6963
3904                                          if ( elem && elem.parentNode ) {
3905                                                  // Handle the case where IE, Opera, and Webkit return items
3906                                                  // by name instead of ID
3907                                                  if ( elem.id === m ) {
3908                                                          results.push( elem );
3909                                                          return results;
3910                                                  }
3911                                          } else {
3912                                                  return results;
3913                                          }
3914                                  } else {
3915                                          // Context is not a document
3916                                          if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&
3917                                                  contains( context, elem ) && elem.id === m ) {
3918                                                  results.push( elem );
3919                                                  return results;
3920                                          }
3921                                  }
3922  
3923                          // Speed-up: Sizzle("TAG")
3924                          } else if ( match[2] ) {
3925                                  push.apply( results, slice.call(context.getElementsByTagName( selector ), 0) );
3926                                  return results;
3927  
3928                          // Speed-up: Sizzle(".CLASS")
3929                          } else if ( (m = match[3]) && assertUsableClassName && context.getElementsByClassName ) {
3930                                  push.apply( results, slice.call(context.getElementsByClassName( m ), 0) );
3931                                  return results;
3932                          }
3933                  }
3934          }
3935  
3936          // All others
3937          return select( selector.replace( rtrim, "$1" ), context, results, seed, xml );
3938  }
3939  
3940  Sizzle.matches = function( expr, elements ) {
3941          return Sizzle( expr, null, null, elements );
3942  };
3943  
3944  Sizzle.matchesSelector = function( elem, expr ) {
3945          return Sizzle( expr, null, null, [ elem ] ).length > 0;
3946  };
3947  
3948  // Returns a function to use in pseudos for input types
3949  function createInputPseudo( type ) {
3950          return function( elem ) {
3951                  var name = elem.nodeName.toLowerCase();
3952                  return name === "input" && elem.type === type;
3953          };
3954  }
3955  
3956  // Returns a function to use in pseudos for buttons
3957  function createButtonPseudo( type ) {
3958          return function( elem ) {
3959                  var name = elem.nodeName.toLowerCase();
3960                  return (name === "input" || name === "button") && elem.type === type;
3961          };
3962  }
3963  
3964  // Returns a function to use in pseudos for positionals
3965  function createPositionalPseudo( fn ) {
3966          return markFunction(function( argument ) {
3967                  argument = +argument;
3968                  return markFunction(function( seed, matches ) {
3969                          var j,
3970                                  matchIndexes = fn( [], seed.length, argument ),
3971                                  i = matchIndexes.length;
3972  
3973                          // Match elements found at the specified indexes
3974                          while ( i-- ) {
3975                                  if ( seed[ (j = matchIndexes[i]) ] ) {
3976                                          seed[j] = !(matches[j] = seed[j]);
3977                                  }
3978                          }
3979                  });
3980          });
3981  }
3982  
3983  /**
3984   * Utility function for retrieving the text value of an array of DOM nodes
3985   * @param {Array|Element} elem
3986   */
3987  getText = Sizzle.getText = function( elem ) {
3988          var node,
3989                  ret = "",
3990                  i = 0,
3991                  nodeType = elem.nodeType;
3992  
3993          if ( nodeType ) {
3994                  if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
3995                          // Use textContent for elements
3996                          // innerText usage removed for consistency of new lines (see #11153)
3997                          if ( typeof elem.textContent === "string" ) {
3998                                  return elem.textContent;
3999                          } else {
4000                                  // Traverse its children
4001                                  for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
4002                                          ret += getText( elem );
4003                                  }
4004                          }
4005                  } else if ( nodeType === 3 || nodeType === 4 ) {
4006                          return elem.nodeValue;
4007                  }
4008                  // Do not include comment or processing instruction nodes
4009          } else {
4010  
4011                  // If no nodeType, this is expected to be an array
4012                  for ( ; (node = elem[i]); i++ ) {
4013                          // Do not traverse comment nodes
4014                          ret += getText( node );
4015                  }
4016          }
4017          return ret;
4018  };
4019  
4020  isXML = Sizzle.isXML = function( elem ) {
4021          // documentElement is verified for cases where it doesn't yet exist
4022          // (such as loading iframes in IE - #4833)
4023          var documentElement = elem && (elem.ownerDocument || elem).documentElement;
4024          return documentElement ? documentElement.nodeName !== "HTML" : false;
4025  };
4026  
4027  // Element contains another
4028  contains = Sizzle.contains = docElem.contains ?
4029          function( a, b ) {
4030                  var adown = a.nodeType === 9 ? a.documentElement : a,
4031                          bup = b && b.parentNode;
4032                  return a === bup || !!( bup && bup.nodeType === 1 && adown.contains && adown.contains(bup) );
4033          } :
4034          docElem.compareDocumentPosition ?
4035          function( a, b ) {
4036                  return b && !!( a.compareDocumentPosition( b ) & 16 );
4037          } :
4038          function( a, b ) {
4039                  while ( (b = b.parentNode) ) {
4040                          if ( b === a ) {
4041                                  return true;
4042                          }
4043                  }
4044                  return false;
4045          };
4046  
4047  Sizzle.attr = function( elem, name ) {
4048          var val,
4049                  xml = isXML( elem );
4050  
4051          if ( !xml ) {
4052                  name = name.toLowerCase();
4053          }
4054          if ( (val = Expr.attrHandle[ name ]) ) {
4055                  return val( elem );
4056          }
4057          if ( xml || assertAttributes ) {
4058                  return elem.getAttribute( name );
4059          }
4060          val = elem.getAttributeNode( name );
4061          return val ?
4062                  typeof elem[ name ] === "boolean" ?
4063                          elem[ name ] ? name : null :
4064                          val.specified ? val.value : null :
4065                  null;
4066  };
4067  
4068  Expr = Sizzle.selectors = {
4069  
4070          // Can be adjusted by the user
4071          cacheLength: 50,
4072  
4073          createPseudo: markFunction,
4074  
4075          match: matchExpr,
4076  
4077          // IE6/7 return a modified href
4078          attrHandle: assertHrefNotNormalized ?
4079                  {} :
4080                  {
4081                          "href": function( elem ) {
4082                                  return elem.getAttribute( "href", 2 );
4083                          },
4084                          "type": function( elem ) {
4085                                  return elem.getAttribute("type");
4086                          }
4087                  },
4088  
4089          find: {
4090                  "ID": assertGetIdNotName ?
4091                          function( id, context, xml ) {
4092                                  if ( typeof context.getElementById !== strundefined && !xml ) {
4093                                          var m = context.getElementById( id );
4094                                          // Check parentNode to catch when Blackberry 4.6 returns
4095                                          // nodes that are no longer in the document #6963
4096                                          return m && m.parentNode ? [m] : [];
4097                                  }
4098                          } :
4099                          function( id, context, xml ) {
4100                                  if ( typeof context.getElementById !== strundefined && !xml ) {
4101                                          var m = context.getElementById( id );
4102  
4103                                          return m ?
4104                                                  m.id === id || typeof m.getAttributeNode !== strundefined && m.getAttributeNode("id").value === id ?
4105                                                          [m] :
4106                                                          undefined :
4107                                                  [];
4108                                  }
4109                          },
4110  
4111                  "TAG": assertTagNameNoComments ?
4112                          function( tag, context ) {
4113                                  if ( typeof context.getElementsByTagName !== strundefined ) {
4114                                          return context.getElementsByTagName( tag );
4115                                  }
4116                          } :
4117                          function( tag, context ) {
4118                                  var results = context.getElementsByTagName( tag );
4119  
4120                                  // Filter out possible comments
4121                                  if ( tag === "*" ) {
4122                                          var elem,
4123                                                  tmp = [],
4124                                                  i = 0;
4125  
4126                                          for ( ; (elem = results[i]); i++ ) {
4127                                                  if ( elem.nodeType === 1 ) {
4128                                                          tmp.push( elem );
4129                                                  }
4130                                          }
4131  
4132                                          return tmp;
4133                                  }
4134                                  return results;
4135                          },
4136  
4137                  "NAME": assertUsableName && function( tag, context ) {
4138                          if ( typeof context.getElementsByName !== strundefined ) {
4139                                  return context.getElementsByName( name );
4140                          }
4141                  },
4142  
4143                  "CLASS": assertUsableClassName && function( className, context, xml ) {
4144                          if ( typeof context.getElementsByClassName !== strundefined && !xml ) {
4145                                  return context.getElementsByClassName( className );
4146                          }
4147                  }
4148          },
4149  
4150          relative: {
4151                  ">": { dir: "parentNode", first: true },
4152                  " ": { dir: "parentNode" },
4153                  "+": { dir: "previousSibling", first: true },
4154                  "~": { dir: "previousSibling" }
4155          },
4156  
4157          preFilter: {
4158                  "ATTR": function( match ) {
4159                          match[1] = match[1].replace( rbackslash, "" );
4160  
4161                          // Move the given value to match[3] whether quoted or unquoted
4162                          match[3] = ( match[4] || match[5] || "" ).replace( rbackslash, "" );
4163  
4164                          if ( match[2] === "~=" ) {
4165                                  match[3] = " " + match[3] + " ";
4166                          }
4167  
4168                          return match.slice( 0, 4 );
4169                  },
4170  
4171                  "CHILD": function( match ) {
4172                          /* matches from matchExpr["CHILD"]
4173                                  1 type (only|nth|...)
4174                                  2 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
4175                                  3 xn-component of xn+y argument ([+-]?\d*n|)
4176                                  4 sign of xn-component
4177                                  5 x of xn-component
4178                                  6 sign of y-component
4179                                  7 y of y-component
4180                          */
4181                          match[1] = match[1].toLowerCase();
4182  
4183                          if ( match[1] === "nth" ) {
4184                                  // nth-child requires argument
4185                                  if ( !match[2] ) {
4186                                          Sizzle.error( match[0] );
4187                                  }
4188  
4189                                  // numeric x and y parameters for Expr.filter.CHILD
4190                                  // remember that false/true cast respectively to 0/1
4191                                  match[3] = +( match[3] ? match[4] + (match[5] || 1) : 2 * ( match[2] === "even" || match[2] === "odd" ) );
4192                                  match[4] = +( ( match[6] + match[7] ) || match[2] === "odd" );
4193  
4194                          // other types prohibit arguments
4195                          } else if ( match[2] ) {
4196                                  Sizzle.error( match[0] );
4197                          }
4198  
4199                          return match;
4200                  },
4201  
4202                  "PSEUDO": function( match ) {
4203                          var unquoted, excess;
4204                          if ( matchExpr["CHILD"].test( match[0] ) ) {
4205                                  return null;
4206                          }
4207  
4208                          if ( match[3] ) {
4209                                  match[2] = match[3];
4210                          } else if ( (unquoted = match[4]) ) {
4211                                  // Only check arguments that contain a pseudo
4212                                  if ( rpseudo.test(unquoted) &&
4213                                          // Get excess from tokenize (recursively)
4214                                          (excess = tokenize( unquoted, true )) &&
4215                                          // advance to the next closing parenthesis
4216                                          (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
4217  
4218                                          // excess is a negative index
4219                                          unquoted = unquoted.slice( 0, excess );
4220                                          match[0] = match[0].slice( 0, excess );
4221                                  }
4222                                  match[2] = unquoted;
4223                          }
4224  
4225                          // Return only captures needed by the pseudo filter method (type and argument)
4226                          return match.slice( 0, 3 );
4227                  }
4228          },
4229  
4230          filter: {
4231                  "ID": assertGetIdNotName ?
4232                          function( id ) {
4233                                  id = id.replace( rbackslash, "" );
4234                                  return function( elem ) {
4235                                          return elem.getAttribute("id") === id;
4236                                  };
4237                          } :
4238                          function( id ) {
4239                                  id = id.replace( rbackslash, "" );
4240                                  return function( elem ) {
4241                                          var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id");
4242                                          return node && node.value === id;
4243                                  };
4244                          },
4245  
4246                  "TAG": function( nodeName ) {
4247                          if ( nodeName === "*" ) {
4248                                  return function() { return true; };
4249                          }
4250                          nodeName = nodeName.replace( rbackslash, "" ).toLowerCase();
4251  
4252                          return function( elem ) {
4253                                  return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
4254                          };
4255                  },
4256  
4257                  "CLASS": function( className ) {
4258                          var pattern = classCache[ expando ][ className + " " ];
4259  
4260                          return pattern ||
4261                                  (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
4262                                  classCache( className, function( elem ) {
4263                                          return pattern.test( elem.className || (typeof elem.getAttribute !== strundefined && elem.getAttribute("class")) || "" );
4264                                  });
4265                  },
4266  
4267                  "ATTR": function( name, operator, check ) {
4268                          return function( elem, context ) {
4269                                  var result = Sizzle.attr( elem, name );
4270  
4271                                  if ( result == null ) {
4272                                          return operator === "!=";
4273                                  }
4274                                  if ( !operator ) {
4275                                          return true;
4276                                  }
4277  
4278                                  result += "";
4279  
4280                                  return operator === "=" ? result === check :
4281                                          operator === "!=" ? result !== check :
4282                                          operator === "^=" ? check && result.indexOf( check ) === 0 :
4283                                          operator === "*=" ? check && result.indexOf( check ) > -1 :
4284                                          operator === "$=" ? check && result.substr( result.length - check.length ) === check :
4285                                          operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 :
4286                                          operator === "|=" ? result === check || result.substr( 0, check.length + 1 ) === check + "-" :
4287                                          false;
4288                          };
4289                  },
4290  
4291                  "CHILD": function( type, argument, first, last ) {
4292  
4293                          if ( type === "nth" ) {
4294                                  return function( elem ) {
4295                                          var node, diff,
4296                                                  parent = elem.parentNode;
4297  
4298                                          if ( first === 1 && last === 0 ) {
4299                                                  return true;
4300                                          }
4301  
4302                                          if ( parent ) {
4303                                                  diff = 0;
4304                                                  for ( node = parent.firstChild; node; node = node.nextSibling ) {
4305                                                          if ( node.nodeType === 1 ) {
4306                                                                  diff++;
4307                                                                  if ( elem === node ) {
4308                                                                          break;
4309                                                                  }
4310                                                          }
4311                                                  }
4312                                          }
4313  
4314                                          // Incorporate the offset (or cast to NaN), then check against cycle size
4315                                          diff -= last;
4316                                          return diff === first || ( diff % first === 0 && diff / first >= 0 );
4317                                  };
4318                          }
4319  
4320                          return function( elem ) {
4321                                  var node = elem;
4322  
4323                                  switch ( type ) {
4324                                          case "only":
4325                                          case "first":
4326                                                  while ( (node = node.previousSibling) ) {
4327                                                          if ( node.nodeType === 1 ) {
4328                                                                  return false;
4329                                                          }
4330                                                  }
4331  
4332                                                  if ( type === "first" ) {
4333                                                          return true;
4334                                                  }
4335  
4336                                                  node = elem;
4337  
4338                                                  /* falls through */
4339                                          case "last":
4340                                                  while ( (node = node.nextSibling) ) {
4341                                                          if ( node.nodeType === 1 ) {
4342                                                                  return false;
4343                                                          }
4344                                                  }
4345  
4346                                                  return true;
4347                                  }
4348                          };
4349                  },
4350  
4351                  "PSEUDO": function( pseudo, argument ) {
4352                          // pseudo-class names are case-insensitive
4353                          // http://www.w3.org/TR/selectors/#pseudo-classes
4354                          // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
4355                          // Remember that setFilters inherits from pseudos
4356                          var args,
4357                                  fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
4358                                          Sizzle.error( "unsupported pseudo: " + pseudo );
4359  
4360                          // The user may use createPseudo to indicate that
4361                          // arguments are needed to create the filter function
4362                          // just as Sizzle does
4363                          if ( fn[ expando ] ) {
4364                                  return fn( argument );
4365                          }
4366  
4367                          // But maintain support for old signatures
4368                          if ( fn.length > 1 ) {
4369                                  args = [ pseudo, pseudo, "", argument ];
4370                                  return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
4371                                          markFunction(function( seed, matches ) {
4372                                                  var idx,
4373                                                          matched = fn( seed, argument ),
4374                                                          i = matched.length;
4375                                                  while ( i-- ) {
4376                                                          idx = indexOf.call( seed, matched[i] );
4377                                                          seed[ idx ] = !( matches[ idx ] = matched[i] );
4378                                                  }
4379                                          }) :
4380                                          function( elem ) {
4381                                                  return fn( elem, 0, args );
4382                                          };
4383                          }
4384  
4385                          return fn;
4386                  }
4387          },
4388  
4389          pseudos: {
4390                  "not": markFunction(function( selector ) {
4391                          // Trim the selector passed to compile
4392                          // to avoid treating leading and trailing
4393                          // spaces as combinators
4394                          var input = [],
4395                                  results = [],
4396                                  matcher = compile( selector.replace( rtrim, "$1" ) );
4397  
4398                          return matcher[ expando ] ?
4399                                  markFunction(function( seed, matches, context, xml ) {
4400                                          var elem,
4401                                                  unmatched = matcher( seed, null, xml, [] ),
4402                                                  i = seed.length;
4403  
4404                                          // Match elements unmatched by `matcher`
4405                                          while ( i-- ) {
4406                                                  if ( (elem = unmatched[i]) ) {
4407                                                          seed[i] = !(matches[i] = elem);
4408                                                  }
4409                                          }
4410                                  }) :
4411                                  function( elem, context, xml ) {
4412                                          input[0] = elem;
4413                                          matcher( input, null, xml, results );
4414                                          return !results.pop();
4415                                  };
4416                  }),
4417  
4418                  "has": markFunction(function( selector ) {
4419                          return function( elem ) {
4420                                  return Sizzle( selector, elem ).length > 0;
4421                          };
4422                  }),
4423  
4424                  "contains": markFunction(function( text ) {
4425                          return function( elem ) {
4426                                  return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
4427                          };
4428                  }),
4429  
4430                  "enabled": function( elem ) {
4431                          return elem.disabled === false;
4432                  },
4433  
4434                  "disabled": function( elem ) {
4435                          return elem.disabled === true;
4436                  },
4437  
4438                  "checked": function( elem ) {
4439                          // In CSS3, :checked should return both checked and selected elements
4440                          // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
4441                          var nodeName = elem.nodeName.toLowerCase();
4442                          return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
4443                  },
4444  
4445                  "selected": function( elem ) {
4446                          // Accessing this property makes selected-by-default
4447                          // options in Safari work properly
4448                          if ( elem.parentNode ) {
4449                                  elem.parentNode.selectedIndex;
4450                          }
4451  
4452                          return elem.selected === true;
4453                  },
4454  
4455                  "parent": function( elem ) {
4456                          return !Expr.pseudos["empty"]( elem );
4457                  },
4458  
4459                  "empty": function( elem ) {
4460                          // http://www.w3.org/TR/selectors/#empty-pseudo
4461                          // :empty is only affected by element nodes and content nodes(including text(3), cdata(4)),
4462                          //   not comment, processing instructions, or others
4463                          // Thanks to Diego Perini for the nodeName shortcut
4464                          //   Greater than "@" means alpha characters (specifically not starting with "#" or "?")
4465                          var nodeType;
4466                          elem = elem.firstChild;
4467                          while ( elem ) {
4468                                  if ( elem.nodeName > "@" || (nodeType = elem.nodeType) === 3 || nodeType === 4 ) {
4469                                          return false;
4470                                  }
4471                                  elem = elem.nextSibling;
4472                          }
4473                          return true;
4474                  },
4475  
4476                  "header": function( elem ) {
4477                          return rheader.test( elem.nodeName );
4478                  },
4479  
4480                  "text": function( elem ) {
4481                          var type, attr;
4482                          // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)
4483                          // use getAttribute instead to test this case
4484                          return elem.nodeName.toLowerCase() === "input" &&
4485                                  (type = elem.type) === "text" &&
4486                                  ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === type );
4487                  },
4488  
4489                  // Input types
4490                  "radio": createInputPseudo("radio"),
4491                  "checkbox": createInputPseudo("checkbox"),
4492                  "file": createInputPseudo("file"),
4493                  "password": createInputPseudo("password"),
4494                  "image": createInputPseudo("image"),
4495  
4496                  "submit": createButtonPseudo("submit"),
4497                  "reset": createButtonPseudo("reset"),
4498  
4499                  "button": function( elem ) {
4500                          var name = elem.nodeName.toLowerCase();
4501                          return name === "input" && elem.type === "button" || name === "button";
4502                  },
4503  
4504                  "input": function( elem ) {
4505                          return rinputs.test( elem.nodeName );
4506                  },
4507  
4508                  "focus": function( elem ) {
4509                          var doc = elem.ownerDocument;
4510                          return elem === doc.activeElement && (!doc.hasFocus || doc.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
4511                  },
4512  
4513                  "active": function( elem ) {
4514                          return elem === elem.ownerDocument.activeElement;
4515                  },
4516  
4517                  // Positional types
4518                  "first": createPositionalPseudo(function() {
4519                          return [ 0 ];
4520                  }),
4521  
4522                  "last": createPositionalPseudo(function( matchIndexes, length ) {
4523                          return [ length - 1 ];
4524                  }),
4525  
4526                  "eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
4527                          return [ argument < 0 ? argument + length : argument ];
4528                  }),
4529  
4530                  "even": createPositionalPseudo(function( matchIndexes, length ) {
4531                          for ( var i = 0; i < length; i += 2 ) {
4532                                  matchIndexes.push( i );
4533                          }
4534                          return matchIndexes;
4535                  }),
4536  
4537                  "odd": createPositionalPseudo(function( matchIndexes, length ) {
4538                          for ( var i = 1; i < length; i += 2 ) {
4539                                  matchIndexes.push( i );
4540                          }
4541                          return matchIndexes;
4542                  }),
4543  
4544                  "lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
4545                          for ( var i = argument < 0 ? argument + length : argument; --i >= 0; ) {
4546                                  matchIndexes.push( i );
4547                          }
4548                          return matchIndexes;
4549                  }),
4550  
4551                  "gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
4552                          for ( var i = argument < 0 ? argument + length : argument; ++i < length; ) {
4553                                  matchIndexes.push( i );
4554                          }
4555                          return matchIndexes;
4556                  })
4557          }
4558  };
4559  
4560  function siblingCheck( a, b, ret ) {
4561          if ( a === b ) {
4562                  return ret;
4563          }
4564  
4565          var cur = a.nextSibling;
4566  
4567          while ( cur ) {
4568                  if ( cur === b ) {
4569                          return -1;
4570                  }
4571  
4572                  cur = cur.nextSibling;
4573          }
4574  
4575          return 1;
4576  }
4577  
4578  sortOrder = docElem.compareDocumentPosition ?
4579          function( a, b ) {
4580                  if ( a === b ) {
4581                          hasDuplicate = true;
4582                          return 0;
4583                  }
4584  
4585                  return ( !a.compareDocumentPosition || !b.compareDocumentPosition ?
4586                          a.compareDocumentPosition :
4587                          a.compareDocumentPosition(b) & 4
4588                  ) ? -1 : 1;
4589          } :
4590          function( a, b ) {
4591                  // The nodes are identical, we can exit early
4592                  if ( a === b ) {
4593                          hasDuplicate = true;
4594                          return 0;
4595  
4596                  // Fallback to using sourceIndex (in IE) if it's available on both nodes
4597                  } else if ( a.sourceIndex && b.sourceIndex ) {
4598                          return a.sourceIndex - b.sourceIndex;
4599                  }
4600  
4601                  var al, bl,
4602                          ap = [],
4603                          bp = [],
4604                          aup = a.parentNode,
4605                          bup = b.parentNode,
4606                          cur = aup;
4607  
4608                  // If the nodes are siblings (or identical) we can do a quick check
4609                  if ( aup === bup ) {
4610                          return siblingCheck( a, b );
4611  
4612                  // If no parents were found then the nodes are disconnected
4613                  } else if ( !aup ) {
4614                          return -1;
4615  
4616                  } else if ( !bup ) {
4617                          return 1;
4618                  }
4619  
4620                  // Otherwise they're somewhere else in the tree so we need
4621                  // to build up a full list of the parentNodes for comparison
4622                  while ( cur ) {
4623                          ap.unshift( cur );
4624                          cur = cur.parentNode;
4625                  }
4626  
4627                  cur = bup;
4628  
4629                  while ( cur ) {
4630                          bp.unshift( cur );
4631                          cur = cur.parentNode;
4632                  }
4633  
4634                  al = ap.length;
4635                  bl = bp.length;
4636  
4637                  // Start walking down the tree looking for a discrepancy
4638                  for ( var i = 0; i < al && i < bl; i++ ) {
4639                          if ( ap[i] !== bp[i] ) {
4640                                  return siblingCheck( ap[i], bp[i] );
4641                          }
4642                  }
4643  
4644                  // We ended someplace up the tree so do a sibling check
4645                  return i === al ?
4646                          siblingCheck( a, bp[i], -1 ) :
4647                          siblingCheck( ap[i], b, 1 );
4648          };
4649  
4650  // Always assume the presence of duplicates if sort doesn't
4651  // pass them to our comparison function (as in Google Chrome).
4652  [0, 0].sort( sortOrder );
4653  baseHasDuplicate = !hasDuplicate;
4654  
4655  // Document sorting and removing duplicates
4656  Sizzle.uniqueSort = function( results ) {
4657          var elem,
4658                  duplicates = [],
4659                  i = 1,
4660                  j = 0;
4661  
4662          hasDuplicate = baseHasDuplicate;
4663          results.sort( sortOrder );
4664  
4665          if ( hasDuplicate ) {
4666                  for ( ; (elem = results[i]); i++ ) {
4667                          if ( elem === results[ i - 1 ] ) {
4668                                  j = duplicates.push( i );
4669                          }
4670                  }
4671                  while ( j-- ) {
4672                          results.splice( duplicates[ j ], 1 );
4673                  }
4674          }
4675  
4676          return results;
4677  };
4678  
4679  Sizzle.error = function( msg ) {
4680          throw new Error( "Syntax error, unrecognized expression: " + msg );
4681  };
4682  
4683  function tokenize( selector, parseOnly ) {
4684          var matched, match, tokens, type,
4685                  soFar, groups, preFilters,
4686                  cached = tokenCache[ expando ][ selector + " " ];
4687  
4688          if ( cached ) {
4689                  return parseOnly ? 0 : cached.slice( 0 );
4690          }
4691  
4692          soFar = selector;
4693          groups = [];
4694          preFilters = Expr.preFilter;
4695  
4696          while ( soFar ) {
4697  
4698                  // Comma and first run
4699                  if ( !matched || (match = rcomma.exec( soFar )) ) {
4700                          if ( match ) {
4701                                  // Don't consume trailing commas as valid
4702                                  soFar = soFar.slice( match[0].length ) || soFar;
4703                          }
4704                          groups.push( tokens = [] );
4705                  }
4706  
4707                  matched = false;
4708  
4709                  // Combinators
4710                  if ( (match = rcombinators.exec( soFar )) ) {
4711                          tokens.push( matched = new Token( match.shift() ) );
4712                          soFar = soFar.slice( matched.length );
4713  
4714                          // Cast descendant combinators to space
4715                          matched.type = match[0].replace( rtrim, " " );
4716                  }
4717  
4718                  // Filters
4719                  for ( type in Expr.filter ) {
4720                          if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
4721                                  (match = preFilters[ type ]( match ))) ) {
4722  
4723                                  tokens.push( matched = new Token( match.shift() ) );
4724                                  soFar = soFar.slice( matched.length );
4725                                  matched.type = type;
4726                                  matched.matches = match;
4727                          }
4728                  }
4729  
4730                  if ( !matched ) {
4731                          break;
4732                  }
4733          }
4734  
4735          // Return the length of the invalid excess
4736          // if we're just parsing
4737          // Otherwise, throw an error or return tokens
4738          return parseOnly ?
4739                  soFar.length :
4740                  soFar ?
4741                          Sizzle.error( selector ) :
4742                          // Cache the tokens
4743                          tokenCache( selector, groups ).slice( 0 );
4744  }
4745  
4746  function addCombinator( matcher, combinator, base ) {
4747          var dir = combinator.dir,
4748                  checkNonElements = base && combinator.dir === "parentNode",
4749                  doneName = done++;
4750  
4751          return combinator.first ?
4752                  // Check against closest ancestor/preceding element
4753                  function( elem, context, xml ) {
4754                          while ( (elem = elem[ dir ]) ) {
4755                                  if ( checkNonElements || elem.nodeType === 1  ) {
4756                                          return matcher( elem, context, xml );
4757                                  }
4758                          }
4759                  } :
4760  
4761                  // Check against all ancestor/preceding elements
4762                  function( elem, context, xml ) {
4763                          // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching
4764                          if ( !xml ) {
4765                                  var cache,
4766                                          dirkey = dirruns + " " + doneName + " ",
4767                                          cachedkey = dirkey + cachedruns;
4768                                  while ( (elem = elem[ dir ]) ) {
4769                                          if ( checkNonElements || elem.nodeType === 1 ) {
4770                                                  if ( (cache = elem[ expando ]) === cachedkey ) {
4771                                                          return elem.sizset;
4772                                                  } else if ( typeof cache === "string" && cache.indexOf(dirkey) === 0 ) {
4773                                                          if ( elem.sizset ) {
4774                                                                  return elem;
4775                                                          }
4776                                                  } else {
4777                                                          elem[ expando ] = cachedkey;
4778                                                          if ( matcher( elem, context, xml ) ) {
4779                                                                  elem.sizset = true;
4780                                                                  return elem;
4781                                                          }
4782                                                          elem.sizset = false;
4783                                                  }
4784                                          }
4785                                  }
4786                          } else {
4787                                  while ( (elem = elem[ dir ]) ) {
4788                                          if ( checkNonElements || elem.nodeType === 1 ) {
4789                                                  if ( matcher( elem, context, xml ) ) {
4790                                                          return elem;
4791                                                  }
4792                                          }
4793                                  }
4794                          }
4795                  };
4796  }
4797  
4798  function elementMatcher( matchers ) {
4799          return matchers.length > 1 ?
4800                  function( elem, context, xml ) {
4801                          var i = matchers.length;
4802                          while ( i-- ) {
4803                                  if ( !matchers[i]( elem, context, xml ) ) {
4804                                          return false;
4805                                  }
4806                          }
4807                          return true;
4808                  } :
4809                  matchers[0];
4810  }
4811  
4812  function condense( unmatched, map, filter, context, xml ) {
4813          var elem,
4814                  newUnmatched = [],
4815                  i = 0,
4816                  len = unmatched.length,
4817                  mapped = map != null;
4818  
4819          for ( ; i < len; i++ ) {
4820                  if ( (elem = unmatched[i]) ) {
4821                          if ( !filter || filter( elem, context, xml ) ) {
4822                                  newUnmatched.push( elem );
4823                                  if ( mapped ) {
4824                                          map.push( i );
4825                                  }
4826                          }
4827                  }
4828          }
4829  
4830          return newUnmatched;
4831  }
4832  
4833  function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
4834          if ( postFilter && !postFilter[ expando ] ) {
4835                  postFilter = setMatcher( postFilter );
4836          }
4837          if ( postFinder && !postFinder[ expando ] ) {
4838                  postFinder = setMatcher( postFinder, postSelector );
4839          }
4840          return markFunction(function( seed, results, context, xml ) {
4841                  var temp, i, elem,
4842                          preMap = [],
4843                          postMap = [],
4844                          preexisting = results.length,
4845  
4846                          // Get initial elements from seed or context
4847                          elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
4848  
4849                          // Prefilter to get matcher input, preserving a map for seed-results synchronization
4850                          matcherIn = preFilter && ( seed || !selector ) ?
4851                                  condense( elems, preMap, preFilter, context, xml ) :
4852                                  elems,
4853  
4854                          matcherOut = matcher ?
4855                                  // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
4856                                  postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
4857  
4858                                          // ...intermediate processing is necessary
4859                                          [] :
4860  
4861                                          // ...otherwise use results directly
4862                                          results :
4863                                  matcherIn;
4864  
4865                  // Find primary matches
4866                  if ( matcher ) {
4867                          matcher( matcherIn, matcherOut, context, xml );
4868                  }
4869  
4870                  // Apply postFilter
4871                  if ( postFilter ) {
4872                          temp = condense( matcherOut, postMap );
4873                          postFilter( temp, [], context, xml );
4874  
4875                          // Un-match failing elements by moving them back to matcherIn
4876                          i = temp.length;
4877                          while ( i-- ) {
4878                                  if ( (elem = temp[i]) ) {
4879                                          matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
4880                                  }
4881                          }
4882                  }
4883  
4884                  if ( seed ) {
4885                          if ( postFinder || preFilter ) {
4886                                  if ( postFinder ) {
4887                                          // Get the final matcherOut by condensing this intermediate into postFinder contexts
4888                                          temp = [];
4889                                          i = matcherOut.length;
4890                                          while ( i-- ) {
4891                                                  if ( (elem = matcherOut[i]) ) {
4892                                                          // Restore matcherIn since elem is not yet a final match
4893                                                          temp.push( (matcherIn[i] = elem) );
4894                                                  }
4895                                          }
4896                                          postFinder( null, (matcherOut = []), temp, xml );
4897                                  }
4898  
4899                                  // Move matched elements from seed to results to keep them synchronized
4900                                  i = matcherOut.length;
4901                                  while ( i-- ) {
4902                                          if ( (elem = matcherOut[i]) &&
4903                                                  (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) {
4904  
4905                                                  seed[temp] = !(results[temp] = elem);
4906                                          }
4907                                  }
4908                          }
4909  
4910                  // Add elements to results, through postFinder if defined
4911                  } else {
4912                          matcherOut = condense(
4913                                  matcherOut === results ?
4914                                          matcherOut.splice( preexisting, matcherOut.length ) :
4915                                          matcherOut
4916                          );
4917                          if ( postFinder ) {
4918                                  postFinder( null, results, matcherOut, xml );
4919                          } else {
4920                                  push.apply( results, matcherOut );
4921                          }
4922                  }
4923          });
4924  }
4925  
4926  function matcherFromTokens( tokens ) {
4927          var checkContext, matcher, j,
4928                  len = tokens.length,
4929                  leadingRelative = Expr.relative[ tokens[0].type ],
4930                  implicitRelative = leadingRelative || Expr.relative[" "],
4931                  i = leadingRelative ? 1 : 0,
4932  
4933                  // The foundational matcher ensures that elements are reachable from top-level context(s)
4934                  matchContext = addCombinator( function( elem ) {
4935                          return elem === checkContext;
4936                  }, implicitRelative, true ),
4937                  matchAnyContext = addCombinator( function( elem ) {
4938                          return indexOf.call( checkContext, elem ) > -1;
4939                  }, implicitRelative, true ),
4940                  matchers = [ function( elem, context, xml ) {
4941                          return ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
4942                                  (checkContext = context).nodeType ?
4943                                          matchContext( elem, context, xml ) :
4944                                          matchAnyContext( elem, context, xml ) );
4945                  } ];
4946  
4947          for ( ; i < len; i++ ) {
4948                  if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
4949                          matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ];
4950                  } else {
4951                          matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
4952  
4953                          // Return special upon seeing a positional matcher
4954                          if ( matcher[ expando ] ) {
4955                                  // Find the next relative operator (if any) for proper handling
4956                                  j = ++i;
4957                                  for ( ; j < len; j++ ) {
4958                                          if ( Expr.relative[ tokens[j].type ] ) {
4959                                                  break;
4960                                          }
4961                                  }
4962                                  return setMatcher(
4963                                          i > 1 && elementMatcher( matchers ),
4964                                          i > 1 && tokens.slice( 0, i - 1 ).join("").replace( rtrim, "$1" ),
4965                                          matcher,
4966                                          i < j && matcherFromTokens( tokens.slice( i, j ) ),
4967                                          j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
4968                                          j < len && tokens.join("")
4969                                  );
4970                          }
4971                          matchers.push( matcher );
4972                  }
4973          }
4974  
4975          return elementMatcher( matchers );
4976  }
4977  
4978  function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
4979          var bySet = setMatchers.length > 0,
4980                  byElement = elementMatchers.length > 0,
4981                  superMatcher = function( seed, context, xml, results, expandContext ) {
4982                          var elem, j, matcher,
4983                                  setMatched = [],
4984                                  matchedCount = 0,
4985                                  i = "0",
4986                                  unmatched = seed && [],
4987                                  outermost = expandContext != null,
4988                                  contextBackup = outermostContext,
4989                                  // We must always have either seed elements or context
4990                                  elems = seed || byElement && Expr.find["TAG"]( "*", expandContext && context.parentNode || context ),
4991                                  // Nested matchers should use non-integer dirruns
4992                                  dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.E);
4993  
4994                          if ( outermost ) {
4995                                  outermostContext = context !== document && context;
4996                                  cachedruns = superMatcher.el;
4997                          }
4998  
4999                          // Add elements passing elementMatchers directly to results
5000                          for ( ; (elem = elems[i]) != null; i++ ) {
5001                                  if ( byElement && elem ) {
5002                                          for ( j = 0; (matcher = elementMatchers[j]); j++ ) {
5003                                                  if ( matcher( elem, context, xml ) ) {
5004                                                          results.push( elem );
5005                                                          break;
5006                                                  }
5007                                          }
5008                                          if ( outermost ) {
5009                                                  dirruns = dirrunsUnique;
5010                                                  cachedruns = ++superMatcher.el;
5011                                          }
5012                                  }
5013  
5014                                  // Track unmatched elements for set filters
5015                                  if ( bySet ) {
5016                                          // They will have gone through all possible matchers
5017                                          if ( (elem = !matcher && elem) ) {
5018                                                  matchedCount--;
5019                                          }
5020  
5021                                          // Lengthen the array for every element, matched or not
5022                                          if ( seed ) {
5023                                                  unmatched.push( elem );
5024                                          }
5025                                  }
5026                          }
5027  
5028                          // Apply set filters to unmatched elements
5029                          matchedCount += i;
5030                          if ( bySet && i !== matchedCount ) {
5031                                  for ( j = 0; (matcher = setMatchers[j]); j++ ) {
5032                                          matcher( unmatched, setMatched, context, xml );
5033                                  }
5034  
5035                                  if ( seed ) {
5036                                          // Reintegrate element matches to eliminate the need for sorting
5037                                          if ( matchedCount > 0 ) {
5038                                                  while ( i-- ) {
5039                                                          if ( !(unmatched[i] || setMatched[i]) ) {
5040                                                                  setMatched[i] = pop.call( results );
5041                                                          }
5042                                                  }
5043                                          }
5044  
5045                                          // Discard index placeholder values to get only actual matches
5046                                          setMatched = condense( setMatched );
5047                                  }
5048  
5049                                  // Add matches to results
5050                                  push.apply( results, setMatched );
5051  
5052                                  // Seedless set matches succeeding multiple successful matchers stipulate sorting
5053                                  if ( outermost && !seed && setMatched.length > 0 &&
5054                                          ( matchedCount + setMatchers.length ) > 1 ) {
5055  
5056                                          Sizzle.uniqueSort( results );
5057                                  }
5058                          }
5059  
5060                          // Override manipulation of globals by nested matchers
5061                          if ( outermost ) {
5062                                  dirruns = dirrunsUnique;
5063                                  outermostContext = contextBackup;
5064                          }
5065  
5066                          return unmatched;
5067                  };
5068  
5069          superMatcher.el = 0;
5070          return bySet ?
5071                  markFunction( superMatcher ) :
5072                  superMatcher;
5073  }
5074  
5075  compile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) {
5076          var i,
5077                  setMatchers = [],
5078                  elementMatchers = [],
5079                  cached = compilerCache[ expando ][ selector + " " ];
5080  
5081          if ( !cached ) {
5082                  // Generate a function of recursive functions that can be used to check each element
5083                  if ( !group ) {
5084                          group = tokenize( selector );
5085                  }
5086                  i = group.length;
5087                  while ( i-- ) {
5088                          cached = matcherFromTokens( group[i] );
5089                          if ( cached[ expando ] ) {
5090                                  setMatchers.push( cached );
5091                          } else {
5092                                  elementMatchers.push( cached );
5093                          }
5094                  }
5095  
5096                  // Cache the compiled function
5097                  cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
5098          }
5099          return cached;
5100  };
5101  
5102  function multipleContexts( selector, contexts, results ) {
5103          var i = 0,
5104                  len = contexts.length;
5105          for ( ; i < len; i++ ) {
5106                  Sizzle( selector, contexts[i], results );
5107          }
5108          return results;
5109  }
5110  
5111  function select( selector, context, results, seed, xml ) {
5112          var i, tokens, token, type, find,
5113                  match = tokenize( selector ),
5114                  j = match.length;
5115  
5116          if ( !seed ) {
5117                  // Try to minimize operations if there is only one group
5118                  if ( match.length === 1 ) {
5119  
5120                          // Take a shortcut and set the context if the root selector is an ID
5121                          tokens = match[0] = match[0].slice( 0 );
5122                          if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
5123                                          context.nodeType === 9 && !xml &&
5124                                          Expr.relative[ tokens[1].type ] ) {
5125  
5126                                  context = Expr.find["ID"]( token.matches[0].replace( rbackslash, "" ), context, xml )[0];
5127                                  if ( !context ) {
5128                                          return results;
5129                                  }
5130  
5131                                  selector = selector.slice( tokens.shift().length );
5132                          }
5133  
5134                          // Fetch a seed set for right-to-left matching
5135                          for ( i = matchExpr["POS"].test( selector ) ? -1 : tokens.length - 1; i >= 0; i-- ) {
5136                                  token = tokens[i];
5137  
5138                                  // Abort if we hit a combinator
5139                                  if ( Expr.relative[ (type = token.type) ] ) {
5140                                          break;
5141                                  }
5142                                  if ( (find = Expr.find[ type ]) ) {
5143                                          // Search, expanding context for leading sibling combinators
5144                                          if ( (seed = find(
5145                                                  token.matches[0].replace( rbackslash, "" ),
5146                                                  rsibling.test( tokens[0].type ) && context.parentNode || context,
5147                                                  xml
5148                                          )) ) {
5149  
5150                                                  // If seed is empty or no tokens remain, we can return early
5151                                                  tokens.splice( i, 1 );
5152                                                  selector = seed.length && tokens.join("");
5153                                                  if ( !selector ) {
5154                                                          push.apply( results, slice.call( seed, 0 ) );
5155                                                          return results;
5156                                                  }
5157  
5158                                                  break;
5159                                          }
5160                                  }
5161                          }
5162                  }
5163          }
5164  
5165          // Compile and execute a filtering function
5166          // Provide `match` to avoid retokenization if we modified the selector above
5167          compile( selector, match )(
5168                  seed,
5169                  context,
5170                  xml,
5171                  results,
5172                  rsibling.test( selector )
5173          );
5174          return results;
5175  }
5176  
5177  if ( document.querySelectorAll ) {
5178          (function() {
5179                  var disconnectedMatch,
5180                          oldSelect = select,
5181                          rescape = /'|\\/g,
5182                          rattributeQuotes = /\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,
5183  
5184                          // qSa(:focus) reports false when true (Chrome 21), no need to also add to buggyMatches since matches checks buggyQSA
5185                          // A support test would require too much code (would include document ready)
5186                          rbuggyQSA = [ ":focus" ],
5187  
5188                          // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
5189                          // A support test would require too much code (would include document ready)
5190                          // just skip matchesSelector for :active
5191                          rbuggyMatches = [ ":active" ],
5192                          matches = docElem.matchesSelector ||
5193                                  docElem.mozMatchesSelector ||
5194                                  docElem.webkitMatchesSelector ||
5195                                  docElem.oMatchesSelector ||
5196                                  docElem.msMatchesSelector;
5197  
5198                  // Build QSA regex
5199                  // Regex strategy adopted from Diego Perini
5200                  assert(function( div ) {
5201                          // Select is set to empty string on purpose
5202                          // This is to test IE's treatment of not explictly
5203                          // setting a boolean content attribute,
5204                          // since its presence should be enough
5205                          // http://bugs.jquery.com/ticket/12359
5206                          div.innerHTML = "<select><option selected=''></option></select>";
5207  
5208                          // IE8 - Some boolean attributes are not treated correctly
5209                          if ( !div.querySelectorAll("[selected]").length ) {
5210                                  rbuggyQSA.push( "\\[" + whitespace + "*(?:checked|disabled|ismap|multiple|readonly|selected|value)" );
5211                          }
5212  
5213                          // Webkit/Opera - :checked should return selected option elements
5214                          // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
5215                          // IE8 throws error here (do not put tests after this one)
5216                          if ( !div.querySelectorAll(":checked").length ) {
5217                                  rbuggyQSA.push(":checked");
5218                          }
5219                  });
5220  
5221                  assert(function( div ) {
5222  
5223                          // Opera 10-12/IE9 - ^= $= *= and empty values
5224                          // Should not select anything
5225                          div.innerHTML = "<p test=''></p>";
5226                          if ( div.querySelectorAll("[test^='']").length ) {
5227                                  rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:\"\"|'')" );
5228                          }
5229  
5230                          // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
5231                          // IE8 throws error here (do not put tests after this one)
5232                          div.innerHTML = "<input type='hidden'/>";
5233                          if ( !div.querySelectorAll(":enabled").length ) {
5234                                  rbuggyQSA.push(":enabled", ":disabled");
5235                          }
5236                  });
5237  
5238                  // rbuggyQSA always contains :focus, so no need for a length check
5239                  rbuggyQSA = /* rbuggyQSA.length && */ new RegExp( rbuggyQSA.join("|") );
5240  
5241                  select = function( selector, context, results, seed, xml ) {
5242                          // Only use querySelectorAll when not filtering,
5243                          // when this is not xml,
5244                          // and when no QSA bugs apply
5245                          if ( !seed && !xml && !rbuggyQSA.test( selector ) ) {
5246                                  var groups, i,
5247                                          old = true,
5248                                          nid = expando,
5249                                          newContext = context,
5250                                          newSelector = context.nodeType === 9 && selector;
5251  
5252                                  // qSA works strangely on Element-rooted queries
5253                                  // We can work around this by specifying an extra ID on the root
5254                                  // and working up from there (Thanks to Andrew Dupont for the technique)
5255                                  // IE 8 doesn't work on object elements
5256                                  if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
5257                                          groups = tokenize( selector );
5258  
5259                                          if ( (old = context.getAttribute("id")) ) {
5260                                                  nid = old.replace( rescape, "\\$&" );
5261                                          } else {
5262                                                  context.setAttribute( "id", nid );
5263                                          }
5264                                          nid = "[id='" + nid + "'] ";
5265  
5266                                          i = groups.length;
5267                                          while ( i-- ) {
5268                                                  groups[i] = nid + groups[i].join("");
5269                                          }
5270                                          newContext = rsibling.test( selector ) && context.parentNode || context;
5271                                          newSelector = groups.join(",");
5272                                  }
5273  
5274                                  if ( newSelector ) {
5275                                          try {
5276                                                  push.apply( results, slice.call( newContext.querySelectorAll(
5277                                                          newSelector
5278                                                  ), 0 ) );
5279                                                  return results;
5280                                          } catch(qsaError) {
5281                                          } finally {
5282                                                  if ( !old ) {
5283                                                          context.removeAttribute("id");
5284                                                  }
5285                                          }
5286                                  }
5287                          }
5288  
5289                          return oldSelect( selector, context, results, seed, xml );
5290                  };
5291  
5292                  if ( matches ) {
5293                          assert(function( div ) {
5294                                  // Check to see if it's possible to do matchesSelector
5295                                  // on a disconnected node (IE 9)
5296                                  disconnectedMatch = matches.call( div, "div" );
5297  
5298                                  // This should fail with an exception
5299                                  // Gecko does not error, returns false instead
5300                                  try {
5301                                          matches.call( div, "[test!='']:sizzle" );
5302                                          rbuggyMatches.push( "!=", pseudos );
5303                                  } catch ( e ) {}
5304                          });
5305  
5306                          // rbuggyMatches always contains :active and :focus, so no need for a length check
5307                          rbuggyMatches = /* rbuggyMatches.length && */ new RegExp( rbuggyMatches.join("|") );
5308  
5309                          Sizzle.matchesSelector = function( elem, expr ) {
5310                                  // Make sure that attribute selectors are quoted
5311                                  expr = expr.replace( rattributeQuotes, "='$1']" );
5312  
5313                                  // rbuggyMatches always contains :active, so no need for an existence check
5314                                  if ( !isXML( elem ) && !rbuggyMatches.test( expr ) && !rbuggyQSA.test( expr ) ) {
5315                                          try {
5316                                                  var ret = matches.call( elem, expr );
5317  
5318                                                  // IE 9's matchesSelector returns false on disconnected nodes
5319                                                  if ( ret || disconnectedMatch ||
5320                                                                  // As well, disconnected nodes are said to be in a document
5321                                                                  // fragment in IE 9
5322                                                                  elem.document && elem.document.nodeType !== 11 ) {
5323                                                          return ret;
5324                                                  }
5325                                          } catch(e) {}
5326                                  }
5327  
5328                                  return Sizzle( expr, null, null, [ elem ] ).length > 0;
5329                          };
5330                  }
5331          })();
5332  }
5333  
5334  // Deprecated
5335  Expr.pseudos["nth"] = Expr.pseudos["eq"];
5336  
5337  // Back-compat
5338  function setFilters() {}
5339  Expr.filters = setFilters.prototype = Expr.pseudos;
5340  Expr.setFilters = new setFilters();
5341  
5342  // Override sizzle attribute retrieval
5343  Sizzle.attr = jQuery.attr;
5344  jQuery.find = Sizzle;
5345  jQuery.expr = Sizzle.selectors;
5346  jQuery.expr[":"] = jQuery.expr.pseudos;
5347  jQuery.unique = Sizzle.uniqueSort;
5348  jQuery.text = Sizzle.getText;
5349  jQuery.isXMLDoc = Sizzle.isXML;
5350  jQuery.contains = Sizzle.contains;
5351  
5352  
5353  })( window );
5354  var runtil = /Until$/,
5355          rparentsprev = /^(?:parents|prev(?:Until|All))/,
5356          isSimple = /^.[^:#\[\.,]*$/,
5357          rneedsContext = jQuery.expr.match.needsContext,
5358          // methods guaranteed to produce a unique set when starting from a unique set
5359          guaranteedUnique = {
5360                  children: true,
5361                  contents: true,
5362                  next: true,
5363                  prev: true
5364          };
5365  
5366  jQuery.fn.extend({
5367          find: function( selector ) {
5368                  var i, l, length, n, r, ret,
5369                          self = this;
5370  
5371                  if ( typeof selector !== "string" ) {
5372                          return jQuery( selector ).filter(function() {
5373                                  for ( i = 0, l = self.length; i < l; i++ ) {
5374                                          if ( jQuery.contains( self[ i ], this ) ) {
5375                                                  return true;
5376                                          }
5377                                  }
5378                          });
5379                  }
5380  
5381                  ret = this.pushStack( "", "find", selector );
5382  
5383                  for ( i = 0, l = this.length; i < l; i++ ) {
5384                          length = ret.length;
5385                          jQuery.find( selector, this[i], ret );
5386  
5387                          if ( i > 0 ) {
5388                                  // Make sure that the results are unique
5389                                  for ( n = length; n < ret.length; n++ ) {
5390                                          for ( r = 0; r < length; r++ ) {
5391                                                  if ( ret[r] === ret[n] ) {
5392                                                          ret.splice(n--, 1);
5393                                                          break;
5394                                                  }
5395                                          }
5396                                  }
5397                          }
5398                  }
5399  
5400                  return ret;
5401          },
5402  
5403          has: function( target ) {
5404                  var i,
5405                          targets = jQuery( target, this ),
5406                          len = targets.length;
5407  
5408                  return this.filter(function() {
5409                          for ( i = 0; i < len; i++ ) {
5410                                  if ( jQuery.contains( this, targets[i] ) ) {
5411                                          return true;
5412                                  }
5413                          }
5414                  });
5415          },
5416  
5417          not: function( selector ) {
5418                  return this.pushStack( winnow(this, selector, false), "not", selector);
5419          },
5420  
5421          filter: function( selector ) {
5422                  return this.pushStack( winnow(this, selector, true), "filter", selector );
5423          },
5424  
5425          is: function( selector ) {
5426                  return !!selector && (
5427                          typeof selector === "string" ?
5428                                  // If this is a positional/relative selector, check membership in the returned set
5429                                  // so $("p:first").is("p:last") won't return true for a doc with two "p".
5430                                  rneedsContext.test( selector ) ?
5431                                          jQuery( selector, this.context ).index( this[0] ) >= 0 :
5432                                          jQuery.filter( selector, this ).length > 0 :
5433                                  this.filter( selector ).length > 0 );
5434          },
5435  
5436          closest: function( selectors, context ) {
5437                  var cur,
5438                          i = 0,
5439                          l = this.length,
5440                          ret = [],
5441                          pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
5442                                  jQuery( selectors, context || this.context ) :
5443                                  0;
5444  
5445                  for ( ; i < l; i++ ) {
5446                          cur = this[i];
5447  
5448                          while ( cur && cur.ownerDocument && cur !== context && cur.nodeType !== 11 ) {
5449                                  if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {
5450                                          ret.push( cur );
5451                                          break;
5452                                  }
5453                                  cur = cur.parentNode;
5454                          }
5455                  }
5456  
5457                  ret = ret.length > 1 ? jQuery.unique( ret ) : ret;
5458  
5459                  return this.pushStack( ret, "closest", selectors );
5460          },
5461  
5462          // Determine the position of an element within
5463          // the matched set of elements
5464          index: function( elem ) {
5465  
5466                  // No argument, return index in parent
5467                  if ( !elem ) {
5468                          return ( this[0] && this[0].parentNode ) ? this.prevAll().length : -1;
5469                  }
5470  
5471                  // index in selector
5472                  if ( typeof elem === "string" ) {
5473                          return jQuery.inArray( this[0], jQuery( elem ) );
5474                  }
5475  
5476                  // Locate the position of the desired element
5477                  return jQuery.inArray(
5478                          // If it receives a jQuery object, the first element is used
5479                          elem.jquery ? elem[0] : elem, this );
5480          },
5481  
5482          add: function( selector, context ) {
5483                  var set = typeof selector === "string" ?
5484                                  jQuery( selector, context ) :
5485                                  jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ),
5486                          all = jQuery.merge( this.get(), set );
5487  
5488                  return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?
5489                          all :
5490                          jQuery.unique( all ) );
5491          },
5492  
5493          addBack: function( selector ) {
5494                  return this.add( selector == null ?
5495                          this.prevObject : this.prevObject.filter(selector)
5496                  );
5497          }
5498  });
5499  
5500  jQuery.fn.andSelf = jQuery.fn.addBack;
5501  
5502  // A painfully simple check to see if an element is disconnected
5503  // from a document (should be improved, where feasible).
5504  function isDisconnected( node ) {
5505          return !node || !node.parentNode || node.parentNode.nodeType === 11;
5506  }
5507  
5508  function sibling( cur, dir ) {
5509          do {
5510                  cur = cur[ dir ];
5511          } while ( cur && cur.nodeType !== 1 );
5512  
5513          return cur;
5514  }
5515  
5516  jQuery.each({
5517          parent: function( elem ) {
5518                  var parent = elem.parentNode;
5519                  return parent && parent.nodeType !== 11 ? parent : null;
5520          },
5521          parents: function( elem ) {
5522                  return jQuery.dir( elem, "parentNode" );
5523          },
5524          parentsUntil: function( elem, i, until ) {
5525                  return jQuery.dir( elem, "parentNode", until );
5526          },
5527          next: function( elem ) {
5528                  return sibling( elem, "nextSibling" );
5529          },
5530          prev: function( elem ) {
5531                  return sibling( elem, "previousSibling" );
5532          },
5533          nextAll: function( elem ) {
5534                  return jQuery.dir( elem, "nextSibling" );
5535          },
5536          prevAll: function( elem ) {
5537                  return jQuery.dir( elem, "previousSibling" );
5538          },
5539          nextUntil: function( elem, i, until ) {
5540                  return jQuery.dir( elem, "nextSibling", until );
5541          },
5542          prevUntil: function( elem, i, until ) {
5543                  return jQuery.dir( elem, "previousSibling", until );
5544          },
5545          siblings: function( elem ) {
5546                  return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );
5547          },
5548          children: function( elem ) {
5549                  return jQuery.sibling( elem.firstChild );
5550          },
5551          contents: function( elem ) {
5552                  return jQuery.nodeName( elem, "iframe" ) ?
5553                          elem.contentDocument || elem.contentWindow.document :
5554                          jQuery.merge( [], elem.childNodes );
5555          }
5556  }, function( name, fn ) {
5557          jQuery.fn[ name ] = function( until, selector ) {
5558                  var ret = jQuery.map( this, fn, until );
5559  
5560                  if ( !runtil.test( name ) ) {
5561                          selector = until;
5562                  }
5563  
5564                  if ( selector && typeof selector === "string" ) {
5565                          ret = jQuery.filter( selector, ret );
5566                  }
5567  
5568                  ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret;
5569  
5570                  if ( this.length > 1 && rparentsprev.test( name ) ) {
5571                          ret = ret.reverse();
5572                  }
5573  
5574                  return this.pushStack( ret, name, core_slice.call( arguments ).join(",") );
5575          };
5576  });
5577  
5578  jQuery.extend({
5579          filter: function( expr, elems, not ) {
5580                  if ( not ) {
5581                          expr = ":not(" + expr + ")";
5582                  }
5583  
5584                  return elems.length === 1 ?
5585                          jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :
5586                          jQuery.find.matches(expr, elems);
5587          },
5588  
5589          dir: function( elem, dir, until ) {
5590                  var matched = [],
5591                          cur = elem[ dir ];
5592  
5593                  while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
5594                          if ( cur.nodeType === 1 ) {
5595                                  matched.push( cur );
5596                          }
5597                          cur = cur[dir];
5598                  }
5599                  return matched;
5600          },
5601  
5602          sibling: function( n, elem ) {
5603                  var r = [];
5604  
5605                  for ( ; n; n = n.nextSibling ) {
5606                          if ( n.nodeType === 1 && n !== elem ) {
5607                                  r.push( n );
5608                          }
5609                  }
5610  
5611                  return r;
5612          }
5613  });
5614  
5615  // Implement the identical functionality for filter and not
5616  function winnow( elements, qualifier, keep ) {
5617  
5618          // Can't pass null or undefined to indexOf in Firefox 4
5619          // Set to 0 to skip string check
5620          qualifier = qualifier || 0;
5621  
5622          if ( jQuery.isFunction( qualifier ) ) {
5623                  return jQuery.grep(elements, function( elem, i ) {
5624                          var retVal = !!qualifier.call( elem, i, elem );
5625                          return retVal === keep;
5626                  });
5627  
5628          } else if ( qualifier.nodeType ) {
5629                  return jQuery.grep(elements, function( elem, i ) {
5630                          return ( elem === qualifier ) === keep;
5631                  });
5632  
5633          } else if ( typeof qualifier === "string" ) {
5634                  var filtered = jQuery.grep(elements, function( elem ) {
5635                          return elem.nodeType === 1;
5636                  });
5637  
5638                  if ( isSimple.test( qualifier ) ) {
5639                          return jQuery.filter(qualifier, filtered, !keep);
5640                  } else {
5641                          qualifier = jQuery.filter( qualifier, filtered );
5642                  }
5643          }
5644  
5645          return jQuery.grep(elements, function( elem, i ) {
5646                  return ( jQuery.inArray( elem, qualifier ) >= 0 ) === keep;
5647          });
5648  }
5649  function createSafeFragment( document ) {
5650          var list = nodeNames.split( "|" ),
5651          safeFrag = document.createDocumentFragment();
5652  
5653          if ( safeFrag.createElement ) {
5654                  while ( list.length ) {
5655                          safeFrag.createElement(
5656                                  list.pop()
5657                          );
5658                  }
5659          }
5660          return safeFrag;
5661  }
5662  
5663  var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" +
5664                  "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",
5665          rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g,
5666          rleadingWhitespace = /^\s+/,
5667          rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,
5668          rtagName = /<([\w:]+)/,
5669          rtbody = /<tbody/i,
5670          rhtml = /<|&#?\w+;/,
5671          rnoInnerhtml = /<(?:script|style|link)/i,
5672          rnocache = /<(?:script|object|embed|option|style)/i,
5673          rnoshimcache = new RegExp("<(?:" + nodeNames + ")[\\s/>]", "i"),
5674          rcheckableType = /^(?:checkbox|radio)$/,
5675          // checked="checked" or checked
5676          rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
5677          rscriptType = /\/(java|ecma)script/i,
5678          rcleanScript = /^\s*<!(?:\[CDATA\[|\-\-)|[\]\-]{2}>\s*$/g,
5679          wrapMap = {
5680                  option: [ 1, "<select multiple='multiple'>", "</select>" ],
5681                  legend: [ 1, "<fieldset>", "</fieldset>" ],
5682                  thead: [ 1, "<table>", "</table>" ],
5683                  tr: [ 2, "<table><tbody>", "</tbody></table>" ],
5684                  td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
5685                  col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
5686                  area: [ 1, "<map>", "</map>" ],
5687                  _default: [ 0, "", "" ]
5688          },
5689          safeFragment = createSafeFragment( document ),
5690          fragmentDiv = safeFragment.appendChild( document.createElement("div") );
5691  
5692  wrapMap.optgroup = wrapMap.option;
5693  wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
5694  wrapMap.th = wrapMap.td;
5695  
5696  // IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags,
5697  // unless wrapped in a div with non-breaking characters in front of it.
5698  if ( !jQuery.support.htmlSerialize ) {
5699          wrapMap._default = [ 1, "X<div>", "</div>" ];
5700  }
5701  
5702  jQuery.fn.extend({
5703          text: function( value ) {
5704                  return jQuery.access( this, function( value ) {
5705                          return value === undefined ?
5706                                  jQuery.text( this ) :
5707                                  this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) );
5708                  }, null, value, arguments.length );
5709          },
5710  
5711          wrapAll: function( html ) {
5712                  if ( jQuery.isFunction( html ) ) {
5713                          return this.each(function(i) {
5714                                  jQuery(this).wrapAll( html.call(this, i) );
5715                          });
5716                  }
5717  
5718                  if ( this[0] ) {
5719                          // The elements to wrap the target around
5720                          var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
5721  
5722                          if ( this[0].parentNode ) {
5723                                  wrap.insertBefore( this[0] );
5724                          }
5725  
5726                          wrap.map(function() {
5727                                  var elem = this;
5728  
5729                                  while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
5730                                          elem = elem.firstChild;
5731                                  }
5732  
5733                                  return elem;
5734                          }).append( this );
5735                  }
5736  
5737                  return this;
5738          },
5739  
5740          wrapInner: function( html ) {
5741                  if ( jQuery.isFunction( html ) ) {
5742                          return this.each(function(i) {
5743                                  jQuery(this).wrapInner( html.call(this, i) );
5744                          });
5745                  }
5746  
5747                  return this.each(function() {
5748                          var self = jQuery( this ),
5749                                  contents = self.contents();
5750  
5751                          if ( contents.length ) {
5752                                  contents.wrapAll( html );
5753  
5754                          } else {
5755                                  self.append( html );
5756                          }
5757                  });
5758          },
5759  
5760          wrap: function( html ) {
5761                  var isFunction = jQuery.isFunction( html );
5762  
5763                  return this.each(function(i) {
5764                          jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html );
5765                  });
5766          },
5767  
5768          unwrap: function() {
5769                  return this.parent().each(function() {
5770                          if ( !jQuery.nodeName( this, "body" ) ) {
5771                                  jQuery( this ).replaceWith( this.childNodes );
5772                          }
5773                  }).end();
5774          },
5775  
5776          append: function() {
5777                  return this.domManip(arguments, true, function( elem ) {
5778                          if ( this.nodeType === 1 || this.nodeType === 11 ) {
5779                                  this.appendChild( elem );
5780                          }
5781                  });
5782          },
5783  
5784          prepend: function() {
5785                  return this.domManip(arguments, true, function( elem ) {
5786                          if ( this.nodeType === 1 || this.nodeType === 11 ) {
5787                                  this.insertBefore( elem, this.firstChild );
5788                          }
5789                  });
5790          },
5791  
5792          before: function() {
5793                  if ( !isDisconnected( this[0] ) ) {
5794                          return this.domManip(arguments, false, function( elem ) {
5795                                  this.parentNode.insertBefore( elem, this );
5796                          });
5797                  }
5798  
5799                  if ( arguments.length ) {
5800                          var set = jQuery.clean( arguments );
5801                          return this.pushStack( jQuery.merge( set, this ), "before", this.selector );
5802                  }
5803          },
5804  
5805          after: function() {
5806                  if ( !isDisconnected( this[0] ) ) {
5807                          return this.domManip(arguments, false, function( elem ) {
5808                                  this.parentNode.insertBefore( elem, this.nextSibling );
5809                          });
5810                  }
5811  
5812                  if ( arguments.length ) {
5813                          var set = jQuery.clean( arguments );
5814                          return this.pushStack( jQuery.merge( this, set ), "after", this.selector );
5815                  }
5816          },
5817  
5818          // keepData is for internal use only--do not document
5819          remove: function( selector, keepData ) {
5820                  var elem,
5821                          i = 0;
5822  
5823                  for ( ; (elem = this[i]) != null; i++ ) {
5824                          if ( !selector || jQuery.filter( selector, [ elem ] ).length ) {
5825                                  if ( !keepData && elem.nodeType === 1 ) {
5826                                          jQuery.cleanData( elem.getElementsByTagName("*") );
5827                                          jQuery.cleanData( [ elem ] );
5828                                  }
5829  
5830                                  if ( elem.parentNode ) {
5831                                          elem.parentNode.removeChild( elem );
5832                                  }
5833                          }
5834                  }
5835  
5836                  return this;
5837          },
5838  
5839          empty: function() {
5840                  var elem,
5841                          i = 0;
5842  
5843                  for ( ; (elem = this[i]) != null; i++ ) {
5844                          // Remove element nodes and prevent memory leaks
5845                          if ( elem.nodeType === 1 ) {
5846                                  jQuery.cleanData( elem.getElementsByTagName("*") );
5847                          }
5848  
5849                          // Remove any remaining nodes
5850                          while ( elem.firstChild ) {
5851                                  elem.removeChild( elem.firstChild );
5852                          }
5853                  }
5854  
5855                  return this;
5856          },
5857  
5858          clone: function( dataAndEvents, deepDataAndEvents ) {
5859                  dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
5860                  deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
5861  
5862                  return this.map( function () {
5863                          return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
5864                  });
5865          },
5866  
5867          html: function( value ) {
5868                  return jQuery.access( this, function( value ) {
5869                          var elem = this[0] || {},
5870                                  i = 0,
5871                                  l = this.length;
5872  
5873                          if ( value === undefined ) {
5874                                  return elem.nodeType === 1 ?
5875                                          elem.innerHTML.replace( rinlinejQuery, "" ) :
5876                                          undefined;
5877                          }
5878  
5879                          // See if we can take a shortcut and just use innerHTML
5880                          if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
5881                                  ( jQuery.support.htmlSerialize || !rnoshimcache.test( value )  ) &&
5882                                  ( jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value ) ) &&
5883                                  !wrapMap[ ( rtagName.exec( value ) || ["", ""] )[1].toLowerCase() ] ) {
5884  
5885                                  value = value.replace( rxhtmlTag, "<$1></$2>" );
5886  
5887                                  try {
5888                                          for (; i < l; i++ ) {
5889                                                  // Remove element nodes and prevent memory leaks
5890                                                  elem = this[i] || {};
5891                                                  if ( elem.nodeType === 1 ) {
5892                                                          jQuery.cleanData( elem.getElementsByTagName( "*" ) );
5893                                                          elem.innerHTML = value;
5894                                                  }
5895                                          }
5896  
5897                                          elem = 0;
5898  
5899                                  // If using innerHTML throws an exception, use the fallback method
5900                                  } catch(e) {}
5901                          }
5902  
5903                          if ( elem ) {
5904                                  this.empty().append( value );
5905                          }
5906                  }, null, value, arguments.length );
5907          },
5908  
5909          replaceWith: function( value ) {
5910                  if ( !isDisconnected( this[0] ) ) {
5911                          // Make sure that the elements are removed from the DOM before they are inserted
5912                          // this can help fix replacing a parent with child elements
5913                          if ( jQuery.isFunction( value ) ) {
5914                                  return this.each(function(i) {
5915                                          var self = jQuery(this), old = self.html();
5916                                          self.replaceWith( value.call( this, i, old ) );
5917                                  });
5918                          }
5919  
5920                          if ( typeof value !== "string" ) {
5921                                  value = jQuery( value ).detach();
5922                          }
5923  
5924                          return this.each(function() {
5925                                  var next = this.nextSibling,
5926                                          parent = this.parentNode;
5927  
5928                                  jQuery( this ).remove();
5929  
5930                                  if ( next ) {
5931                                          jQuery(next).before( value );
5932                                  } else {
5933                                          jQuery(parent).append( value );
5934                                  }
5935                          });
5936                  }
5937  
5938                  return this.length ?
5939                          this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value ) :
5940                          this;
5941          },
5942  
5943          detach: function( selector ) {
5944                  return this.remove( selector, true );
5945          },
5946  
5947          domManip: function( args, table, callback ) {
5948  
5949                  // Flatten any nested arrays
5950                  args = [].concat.apply( [], args );
5951  
5952                  var results, first, fragment, iNoClone,
5953                          i = 0,
5954                          value = args[0],
5955                          scripts = [],
5956                          l = this.length;
5957  
5958                  // We can't cloneNode fragments that contain checked, in WebKit
5959                  if ( !jQuery.support.checkClone && l > 1 && typeof value === "string" && rchecked.test( value ) ) {
5960                          return this.each(function() {
5961                                  jQuery(this).domManip( args, table, callback );
5962                          });
5963                  }
5964  
5965                  if ( jQuery.isFunction(value) ) {
5966                          return this.each(function(i) {
5967                                  var self = jQuery(this);
5968                                  args[0] = value.call( this, i, table ? self.html() : undefined );
5969                                  self.domManip( args, table, callback );
5970                          });
5971                  }
5972  
5973                  if ( this[0] ) {
5974                          results = jQuery.buildFragment( args, this, scripts );
5975                          fragment = results.fragment;
5976                          first = fragment.firstChild;
5977  
5978                          if ( fragment.childNodes.length === 1 ) {
5979                                  fragment = first;
5980                          }
5981  
5982                          if ( first ) {
5983                                  table = table && jQuery.nodeName( first, "tr" );
5984  
5985                                  // Use the original fragment for the last item instead of the first because it can end up
5986                                  // being emptied incorrectly in certain situations (#8070).
5987                                  // Fragments from the fragment cache must always be cloned and never used in place.
5988                                  for ( iNoClone = results.cacheable || l - 1; i < l; i++ ) {
5989                                          callback.call(
5990                                                  table && jQuery.nodeName( this[i], "table" ) ?
5991                                                          findOrAppend( this[i], "tbody" ) :
5992                                                          this[i],
5993                                                  i === iNoClone ?
5994                                                          fragment :
5995                                                          jQuery.clone( fragment, true, true )
5996                                          );
5997                                  }
5998                          }
5999  
6000                          // Fix #11809: Avoid leaking memory
6001                          fragment = first = null;
6002  
6003                          if ( scripts.length ) {
6004                                  jQuery.each( scripts, function( i, elem ) {
6005                                          if ( elem.src ) {
6006                                                  if ( jQuery.ajax ) {
6007                                                          jQuery.ajax({
6008                                                                  url: elem.src,
6009                                                                  type: "GET",
6010                                                                  dataType: "script",
6011                                                                  async: false,
6012                                                                  global: false,
6013                                                                  "throws": true
6014                                                          });
6015                                                  } else {
6016                                                          jQuery.error("no ajax");
6017                                                  }
6018                                          } else {
6019                                                  jQuery.globalEval( ( elem.text || elem.textContent || elem.innerHTML || "" ).replace( rcleanScript, "" ) );
6020                                          }
6021  
6022                                          if ( elem.parentNode ) {
6023                                                  elem.parentNode.removeChild( elem );
6024                                          }
6025                                  });
6026                          }
6027                  }
6028  
6029                  return this;
6030          }
6031  });
6032  
6033  function findOrAppend( elem, tag ) {
6034          return elem.getElementsByTagName( tag )[0] || elem.appendChild( elem.ownerDocument.createElement( tag ) );
6035  }
6036  
6037  function cloneCopyEvent( src, dest ) {
6038  
6039          if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {
6040                  return;
6041          }
6042  
6043          var type, i, l,
6044                  oldData = jQuery._data( src ),
6045                  curData = jQuery._data( dest, oldData ),
6046                  events = oldData.events;
6047  
6048          if ( events ) {
6049                  delete curData.handle;
6050                  curData.events = {};
6051  
6052                  for ( type in events ) {
6053                          for ( i = 0, l = events[ type ].length; i < l; i++ ) {
6054                                  jQuery.event.add( dest, type, events[ type ][ i ] );
6055                          }
6056                  }
6057          }
6058  
6059          // make the cloned public data object a copy from the original
6060          if ( curData.data ) {
6061                  curData.data = jQuery.extend( {}, curData.data );
6062          }
6063  }
6064  
6065  function cloneFixAttributes( src, dest ) {
6066          var nodeName;
6067  
6068          // We do not need to do anything for non-Elements
6069          if ( dest.nodeType !== 1 ) {
6070                  return;
6071          }
6072  
6073          // clearAttributes removes the attributes, which we don't want,
6074          // but also removes the attachEvent events, which we *do* want
6075          if ( dest.clearAttributes ) {
6076                  dest.clearAttributes();
6077          }
6078  
6079          // mergeAttributes, in contrast, only merges back on the
6080          // original attributes, not the events
6081          if ( dest.mergeAttributes ) {
6082                  dest.mergeAttributes( src );
6083          }
6084  
6085          nodeName = dest.nodeName.toLowerCase();
6086  
6087          if ( nodeName === "object" ) {
6088                  // IE6-10 improperly clones children of object elements using classid.
6089                  // IE10 throws NoModificationAllowedError if parent is null, #12132.
6090                  if ( dest.parentNode ) {
6091                          dest.outerHTML = src.outerHTML;
6092                  }
6093  
6094                  // This path appears unavoidable for IE9. When cloning an object
6095                  // element in IE9, the outerHTML strategy above is not sufficient.
6096                  // If the src has innerHTML and the destination does not,
6097                  // copy the src.innerHTML into the dest.innerHTML. #10324
6098                  if ( jQuery.support.html5Clone && (src.innerHTML && !jQuery.trim(dest.innerHTML)) ) {
6099                          dest.innerHTML = src.innerHTML;
6100                  }
6101  
6102          } else if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
6103                  // IE6-8 fails to persist the checked state of a cloned checkbox
6104                  // or radio button. Worse, IE6-7 fail to give the cloned element
6105                  // a checked appearance if the defaultChecked value isn't also set
6106  
6107                  dest.defaultChecked = dest.checked = src.checked;
6108  
6109                  // IE6-7 get confused and end up setting the value of a cloned
6110                  // checkbox/radio button to an empty string instead of "on"
6111                  if ( dest.value !== src.value ) {
6112                          dest.value = src.value;
6113                  }
6114  
6115          // IE6-8 fails to return the selected option to the default selected
6116          // state when cloning options
6117          } else if ( nodeName === "option" ) {
6118                  dest.selected = src.defaultSelected;
6119  
6120          // IE6-8 fails to set the defaultValue to the correct value when
6121          // cloning other types of input fields
6122          } else if ( nodeName === "input" || nodeName === "textarea" ) {
6123                  dest.defaultValue = src.defaultValue;
6124  
6125          // IE blanks contents when cloning scripts
6126          } else if ( nodeName === "script" && dest.text !== src.text ) {
6127                  dest.text = src.text;
6128          }
6129  
6130          // Event data gets referenced instead of copied if the expando
6131          // gets copied too
6132          dest.removeAttribute( jQuery.expando );
6133  }
6134  
6135  jQuery.buildFragment = function( args, context, scripts ) {
6136          var fragment, cacheable, cachehit,
6137                  first = args[ 0 ];
6138  
6139          // Set context from what may come in as undefined or a jQuery collection or a node
6140          // Updated to fix #12266 where accessing context[0] could throw an exception in IE9/10 &
6141          // also doubles as fix for #8950 where plain objects caused createDocumentFragment exception
6142          context = context || document;
6143          context = !context.nodeType && context[0] || context;
6144          context = context.ownerDocument || context;
6145  
6146          // Only cache "small" (1/2 KB) HTML strings that are associated with the main document
6147          // Cloning options loses the selected state, so don't cache them
6148          // IE 6 doesn't like it when you put <object> or <embed> elements in a fragment
6149          // Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache
6150          // Lastly, IE6,7,8 will not correctly reuse cached fragments that were created from unknown elems #10501
6151          if ( args.length === 1 && typeof first === "string" && first.length < 512 && context === document &&
6152                  first.charAt(0) === "<" && !rnocache.test( first ) &&
6153                  (jQuery.support.checkClone || !rchecked.test( first )) &&
6154                  (jQuery.support.html5Clone || !rnoshimcache.test( first )) ) {
6155  
6156                  // Mark cacheable and look for a hit
6157                  cacheable = true;
6158                  fragment = jQuery.fragments[ first ];
6159                  cachehit = fragment !== undefined;
6160          }
6161  
6162          if ( !fragment ) {
6163                  fragment = context.createDocumentFragment();
6164                  jQuery.clean( args, context, fragment, scripts );
6165  
6166                  // Update the cache, but only store false
6167                  // unless this is a second parsing of the same content
6168                  if ( cacheable ) {
6169                          jQuery.fragments[ first ] = cachehit && fragment;
6170                  }
6171          }
6172  
6173          return { fragment: fragment, cacheable: cacheable };
6174  };
6175  
6176  jQuery.fragments = {};
6177  
6178  jQuery.each({
6179          appendTo: "append",
6180          prependTo: "prepend",
6181          insertBefore: "before",
6182          insertAfter: "after",
6183          replaceAll: "replaceWith"
6184  }, function( name, original ) {
6185          jQuery.fn[ name ] = function( selector ) {
6186                  var elems,
6187                          i = 0,
6188                          ret = [],
6189                          insert = jQuery( selector ),
6190                          l = insert.length,
6191                          parent = this.length === 1 && this[0].parentNode;
6192  
6193                  if ( (parent == null || parent && parent.nodeType === 11 && parent.childNodes.length === 1) && l === 1 ) {
6194                          insert[ original ]( this[0] );
6195                          return this;
6196                  } else {
6197                          for ( ; i < l; i++ ) {
6198                                  elems = ( i > 0 ? this.clone(true) : this ).get();
6199                                  jQuery( insert[i] )[ original ]( elems );
6200                                  ret = ret.concat( elems );
6201                          }
6202  
6203                          return this.pushStack( ret, name, insert.selector );
6204                  }
6205          };
6206  });
6207  
6208  function getAll( elem ) {
6209          if ( typeof elem.getElementsByTagName !== "undefined" ) {
6210                  return elem.getElementsByTagName( "*" );
6211  
6212          } else if ( typeof elem.querySelectorAll !== "undefined" ) {
6213                  return elem.querySelectorAll( "*" );
6214  
6215          } else {
6216                  return [];
6217          }
6218  }
6219  
6220  // Used in clean, fixes the defaultChecked property
6221  function fixDefaultChecked( elem ) {
6222          if ( rcheckableType.test( elem.type ) ) {
6223                  elem.defaultChecked = elem.checked;
6224          }
6225  }
6226  
6227  jQuery.extend({
6228          clone: function( elem, dataAndEvents, deepDataAndEvents ) {
6229                  var srcElements,
6230                          destElements,
6231                          i,
6232                          clone;
6233  
6234                  if ( jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) {
6235                          clone = elem.cloneNode( true );
6236  
6237                  // IE<=8 does not properly clone detached, unknown element nodes
6238                  } else {
6239                          fragmentDiv.innerHTML = elem.outerHTML;
6240                          fragmentDiv.removeChild( clone = fragmentDiv.firstChild );
6241                  }
6242  
6243                  if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) &&
6244                                  (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {
6245                          // IE copies events bound via attachEvent when using cloneNode.
6246                          // Calling detachEvent on the clone will also remove the events
6247                          // from the original. In order to get around this, we use some
6248                          // proprietary methods to clear the events. Thanks to MooTools
6249                          // guys for this hotness.
6250  
6251                          cloneFixAttributes( elem, clone );
6252  
6253                          // Using Sizzle here is crazy slow, so we use getElementsByTagName instead
6254                          srcElements = getAll( elem );
6255                          destElements = getAll( clone );
6256  
6257                          // Weird iteration because IE will replace the length property
6258                          // with an element if you are cloning the body and one of the
6259                          // elements on the page has a name or id of "length"
6260                          for ( i = 0; srcElements[i]; ++i ) {
6261                                  // Ensure that the destination node is not null; Fixes #9587
6262                                  if ( destElements[i] ) {
6263                                          cloneFixAttributes( srcElements[i], destElements[i] );
6264                                  }
6265                          }
6266                  }
6267  
6268                  // Copy the events from the original to the clone
6269                  if ( dataAndEvents ) {
6270                          cloneCopyEvent( elem, clone );
6271  
6272                          if ( deepDataAndEvents ) {
6273                                  srcElements = getAll( elem );
6274                                  destElements = getAll( clone );
6275  
6276                                  for ( i = 0; srcElements[i]; ++i ) {
6277                                          cloneCopyEvent( srcElements[i], destElements[i] );
6278                                  }
6279                          }
6280                  }
6281  
6282                  srcElements = destElements = null;
6283  
6284                  // Return the cloned set
6285                  return clone;
6286          },
6287  
6288          clean: function( elems, context, fragment, scripts ) {
6289                  var i, j, elem, tag, wrap, depth, div, hasBody, tbody, len, handleScript, jsTags,
6290                          safe = context === document && safeFragment,
6291                          ret = [];
6292  
6293                  // Ensure that context is a document
6294                  if ( !context || typeof context.createDocumentFragment === "undefined" ) {
6295                          context = document;
6296                  }
6297  
6298                  // Use the already-created safe fragment if context permits
6299                  for ( i = 0; (elem = elems[i]) != null; i++ ) {
6300                          if ( typeof elem === "number" ) {
6301                                  elem += "";
6302                          }
6303  
6304                          if ( !elem ) {
6305                                  continue;
6306                          }
6307  
6308                          // Convert html string into DOM nodes
6309                          if ( typeof elem === "string" ) {
6310                                  if ( !rhtml.test( elem ) ) {
6311                                          elem = context.createTextNode( elem );
6312                                  } else {
6313                                          // Ensure a safe container in which to render the html
6314                                          safe = safe || createSafeFragment( context );
6315                                          div = context.createElement("div");
6316                                          safe.appendChild( div );
6317  
6318                                          // Fix "XHTML"-style tags in all browsers
6319                                          elem = elem.replace(rxhtmlTag, "<$1></$2>");
6320  
6321                                          // Go to html and back, then peel off extra wrappers
6322                                          tag = ( rtagName.exec( elem ) || ["", ""] )[1].toLowerCase();
6323                                          wrap = wrapMap[ tag ] || wrapMap._default;
6324                                          depth = wrap[0];
6325                                          div.innerHTML = wrap[1] + elem + wrap[2];
6326  
6327                                          // Move to the right depth
6328                                          while ( depth-- ) {
6329                                                  div = div.lastChild;
6330                                          }
6331  
6332                                          // Remove IE's autoinserted <tbody> from table fragments
6333                                          if ( !jQuery.support.tbody ) {
6334  
6335                                                  // String was a <table>, *may* have spurious <tbody>
6336                                                  hasBody = rtbody.test(elem);
6337                                                          tbody = tag === "table" && !hasBody ?
6338                                                                  div.firstChild && div.firstChild.childNodes :
6339  
6340                                                                  // String was a bare <thead> or <tfoot>
6341                                                                  wrap[1] === "<table>" && !hasBody ?
6342                                                                          div.childNodes :
6343                                                                          [];
6344  
6345                                                  for ( j = tbody.length - 1; j >= 0 ; --j ) {
6346                                                          if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) {
6347                                                                  tbody[ j ].parentNode.removeChild( tbody[ j ] );
6348                                                          }
6349                                                  }
6350                                          }
6351  
6352                                          // IE completely kills leading whitespace when innerHTML is used
6353                                          if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
6354                                                  div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );
6355                                          }
6356  
6357                                          elem = div.childNodes;
6358  
6359                                          // Take out of fragment container (we need a fresh div each time)
6360                                          div.parentNode.removeChild( div );
6361                                  }
6362                          }
6363  
6364                          if ( elem.nodeType ) {
6365                                  ret.push( elem );
6366                          } else {
6367                                  jQuery.merge( ret, elem );
6368                          }
6369                  }
6370  
6371                  // Fix #11356: Clear elements from safeFragment
6372                  if ( div ) {
6373                          elem = div = safe = null;
6374                  }
6375  
6376                  // Reset defaultChecked for any radios and checkboxes
6377                  // about to be appended to the DOM in IE 6/7 (#8060)
6378                  if ( !jQuery.support.appendChecked ) {
6379                          for ( i = 0; (elem = ret[i]) != null; i++ ) {
6380                                  if ( jQuery.nodeName( elem, "input" ) ) {
6381                                          fixDefaultChecked( elem );
6382                                  } else if ( typeof elem.getElementsByTagName !== "undefined" ) {
6383                                          jQuery.grep( elem.getElementsByTagName("input"), fixDefaultChecked );
6384                                  }
6385                          }
6386                  }
6387  
6388                  // Append elements to a provided document fragment
6389                  if ( fragment ) {
6390                          // Special handling of each script element
6391                          handleScript = function( elem ) {
6392                                  // Check if we consider it executable
6393                                  if ( !elem.type || rscriptType.test( elem.type ) ) {
6394                                          // Detach the script and store it in the scripts array (if provided) or the fragment
6395                                          // Return truthy to indicate that it has been handled
6396                                          return scripts ?
6397                                                  scripts.push( elem.parentNode ? elem.parentNode.removeChild( elem ) : elem ) :
6398                                                  fragment.appendChild( elem );
6399                                  }
6400                          };
6401  
6402                          for ( i = 0; (elem = ret[i]) != null; i++ ) {
6403                                  // Check if we're done after handling an executable script
6404                                  if ( !( jQuery.nodeName( elem, "script" ) && handleScript( elem ) ) ) {
6405                                          // Append to fragment and handle embedded scripts
6406                                          fragment.appendChild( elem );
6407                                          if ( typeof elem.getElementsByTagName !== "undefined" ) {
6408                                                  // handleScript alters the DOM, so use jQuery.merge to ensure snapshot iteration
6409                                                  jsTags = jQuery.grep( jQuery.merge( [], elem.getElementsByTagName("script") ), handleScript );
6410  
6411                                                  // Splice the scripts into ret after their former ancestor and advance our index beyond them
6412                                                  ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) );
6413                                                  i += jsTags.length;
6414                                          }
6415                                  }
6416                          }
6417                  }
6418  
6419                  return ret;
6420          },
6421  
6422          cleanData: function( elems, /* internal */ acceptData ) {
6423                  var data, id, elem, type,
6424                          i = 0,
6425                          internalKey = jQuery.expando,
6426                          cache = jQuery.cache,
6427                          deleteExpando = jQuery.support.deleteExpando,
6428                          special = jQuery.event.special;
6429  
6430                  for ( ; (elem = elems[i]) != null; i++ ) {
6431  
6432                          if ( acceptData || jQuery.acceptData( elem ) ) {
6433  
6434                                  id = elem[ internalKey ];
6435                                  data = id && cache[ id ];
6436  
6437                                  if ( data ) {
6438                                          if ( data.events ) {
6439                                                  for ( type in data.events ) {
6440                                                          if ( special[ type ] ) {
6441                                                                  jQuery.event.remove( elem, type );
6442  
6443                                                          // This is a shortcut to avoid jQuery.event.remove's overhead
6444                                                          } else {
6445                                                                  jQuery.removeEvent( elem, type, data.handle );
6446                                                          }
6447                                                  }
6448                                          }
6449  
6450                                          // Remove cache only if it was not already removed by jQuery.event.remove
6451                                          if ( cache[ id ] ) {
6452  
6453                                                  delete cache[ id ];
6454  
6455                                                  // IE does not allow us to delete expando properties from nodes,
6456                                                  // nor does it have a removeAttribute function on Document nodes;
6457                                                  // we must handle all of these cases
6458                                                  if ( deleteExpando ) {
6459                                                          delete elem[ internalKey ];
6460  
6461                                                  } else if ( elem.removeAttribute ) {
6462                                                          elem.removeAttribute( internalKey );
6463  
6464                                                  } else {
6465                                                          elem[ internalKey ] = null;
6466                                                  }
6467  
6468                                                  jQuery.deletedIds.push( id );
6469                                          }
6470                                  }
6471                          }
6472                  }
6473          }
6474  });
6475  // Limit scope pollution from any deprecated API
6476  (function() {
6477  
6478  var matched, browser;
6479  
6480  // Use of jQuery.browser is frowned upon.
6481  // More details: http://api.jquery.com/jQuery.browser
6482  // jQuery.uaMatch maintained for back-compat
6483  jQuery.uaMatch = function( ua ) {
6484          ua = ua.toLowerCase();
6485  
6486          var match = /(chrome)[ \/]([\w.]+)/.exec( ua ) ||
6487                  /(webkit)[ \/]([\w.]+)/.exec( ua ) ||
6488                  /(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) ||
6489                  /(msie) ([\w.]+)/.exec( ua ) ||
6490                  ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) ||
6491                  [];
6492  
6493          return {
6494                  browser: match[ 1 ] || "",
6495                  version: match[ 2 ] || "0"
6496          };
6497  };
6498  
6499  matched = jQuery.uaMatch( navigator.userAgent );
6500  browser = {};
6501  
6502  if ( matched.browser ) {
6503          browser[ matched.browser ] = true;
6504          browser.version = matched.version;
6505  }
6506  
6507  // Chrome is Webkit, but Webkit is also Safari.
6508  if ( browser.chrome ) {
6509          browser.webkit = true;
6510  } else if ( browser.webkit ) {
6511          browser.safari = true;
6512  }
6513  
6514  jQuery.browser = browser;
6515  
6516  jQuery.sub = function() {
6517          function jQuerySub( selector, context ) {
6518                  return new jQuerySub.fn.init( selector, context );
6519          }
6520          jQuery.extend( true, jQuerySub, this );
6521          jQuerySub.superclass = this;
6522          jQuerySub.fn = jQuerySub.prototype = this();
6523          jQuerySub.fn.constructor = jQuerySub;
6524          jQuerySub.sub = this.sub;
6525          jQuerySub.fn.init = function init( selector, context ) {
6526                  if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) {
6527                          context = jQuerySub( context );
6528                  }
6529  
6530                  return jQuery.fn.init.call( this, selector, context, rootjQuerySub );
6531          };
6532          jQuerySub.fn.init.prototype = jQuerySub.fn;
6533          var rootjQuerySub = jQuerySub(document);
6534          return jQuerySub;
6535  };
6536  
6537  })();
6538  var curCSS, iframe, iframeDoc,
6539          ralpha = /alpha\([^)]*\)/i,
6540          ropacity = /opacity=([^)]*)/,
6541          rposition = /^(top|right|bottom|left)$/,
6542          // swappable if display is none or starts with table except "table", "table-cell", or "table-caption"
6543          // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
6544          rdisplayswap = /^(none|table(?!-c[ea]).+)/,
6545          rmargin = /^margin/,
6546          rnumsplit = new RegExp( "^(" + core_pnum + ")(.*)$", "i" ),
6547          rnumnonpx = new RegExp( "^(" + core_pnum + ")(?!px)[a-z%]+$", "i" ),
6548          rrelNum = new RegExp( "^([-+])=(" + core_pnum + ")", "i" ),
6549          elemdisplay = { BODY: "block" },
6550  
6551          cssShow = { position: "absolute", visibility: "hidden", display: "block" },
6552          cssNormalTransform = {
6553                  letterSpacing: 0,
6554                  fontWeight: 400
6555          },
6556  
6557          cssExpand = [ "Top", "Right", "Bottom", "Left" ],
6558          cssPrefixes = [ "Webkit", "O", "Moz", "ms" ],
6559  
6560          eventsToggle = jQuery.fn.toggle;
6561  
6562  // return a css property mapped to a potentially vendor prefixed property
6563  function vendorPropName( style, name ) {
6564  
6565          // shortcut for names that are not vendor prefixed
6566          if ( name in style ) {
6567                  return name;
6568          }
6569  
6570          // check for vendor prefixed names
6571          var capName = name.charAt(0).toUpperCase() + name.slice(1),
6572                  origName = name,
6573                  i = cssPrefixes.length;
6574  
6575          while ( i-- ) {
6576                  name = cssPrefixes[ i ] + capName;
6577                  if ( name in style ) {
6578                          return name;
6579                  }
6580          }
6581  
6582          return origName;
6583  }
6584  
6585  function isHidden( elem, el ) {
6586          elem = el || elem;
6587          return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem );
6588  }
6589  
6590  function showHide( elements, show ) {
6591          var elem, display,
6592                  values = [],
6593                  index = 0,
6594                  length = elements.length;
6595  
6596          for ( ; index < length; index++ ) {
6597                  elem = elements[ index ];
6598                  if ( !elem.style ) {
6599                          continue;
6600                  }
6601                  values[ index ] = jQuery._data( elem, "olddisplay" );
6602                  if ( show ) {
6603                          // Reset the inline display of this element to learn if it is
6604                          // being hidden by cascaded rules or not
6605                          if ( !values[ index ] && elem.style.display === "none" ) {
6606                                  elem.style.display = "";
6607                          }
6608  
6609                          // Set elements which have been overridden with display: none
6610                          // in a stylesheet to whatever the default browser style is
6611                          // for such an element
6612                          if ( elem.style.display === "" && isHidden( elem ) ) {
6613                                  values[ index ] = jQuery._data( elem, "olddisplay", css_defaultDisplay(elem.nodeName) );
6614                          }
6615                  } else {
6616                          display = curCSS( elem, "display" );
6617  
6618                          if ( !values[ index ] && display !== "none" ) {
6619                                  jQuery._data( elem, "olddisplay", display );
6620                          }
6621                  }
6622          }
6623  
6624          // Set the display of most of the elements in a second loop
6625          // to avoid the constant reflow
6626          for ( index = 0; index < length; index++ ) {
6627                  elem = elements[ index ];
6628                  if ( !elem.style ) {
6629                          continue;
6630                  }
6631                  if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
6632                          elem.style.display = show ? values[ index ] || "" : "none";
6633                  }
6634          }
6635  
6636          return elements;
6637  }
6638  
6639  jQuery.fn.extend({
6640          css: function( name, value ) {
6641                  return jQuery.access( this, function( elem, name, value ) {
6642                          return value !== undefined ?
6643                                  jQuery.style( elem, name, value ) :
6644                                  jQuery.css( elem, name );
6645                  }, name, value, arguments.length > 1 );
6646          },
6647          show: function() {
6648                  return showHide( this, true );
6649          },
6650          hide: function() {
6651                  return showHide( this );
6652          },
6653          toggle: function( state, fn2 ) {
6654                  var bool = typeof state === "boolean";
6655  
6656                  if ( jQuery.isFunction( state ) && jQuery.isFunction( fn2 ) ) {
6657                          return eventsToggle.apply( this, arguments );
6658                  }
6659  
6660                  return this.each(function() {
6661                          if ( bool ? state : isHidden( this ) ) {
6662                                  jQuery( this ).show();
6663                          } else {
6664                                  jQuery( this ).hide();
6665                          }
6666                  });
6667          }
6668  });
6669  
6670  jQuery.extend({
6671          // Add in style property hooks for overriding the default
6672          // behavior of getting and setting a style property
6673          cssHooks: {
6674                  opacity: {
6675                          get: function( elem, computed ) {
6676                                  if ( computed ) {
6677                                          // We should always get a number back from opacity
6678                                          var ret = curCSS( elem, "opacity" );
6679                                          return ret === "" ? "1" : ret;
6680  
6681                                  }
6682                          }
6683                  }
6684          },
6685  
6686          // Exclude the following css properties to add px
6687          cssNumber: {
6688                  "fillOpacity": true,
6689                  "fontWeight": true,
6690                  "lineHeight": true,
6691                  "opacity": true,
6692                  "orphans": true,
6693                  "widows": true,
6694                  "zIndex": true,
6695                  "zoom": true
6696          },
6697  
6698          // Add in properties whose names you wish to fix before
6699          // setting or getting the value
6700          cssProps: {
6701                  // normalize float css property
6702                  "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat"
6703          },
6704  
6705          // Get and set the style property on a DOM Node
6706          style: function( elem, name, value, extra ) {
6707                  // Don't set styles on text and comment nodes
6708                  if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
6709                          return;
6710                  }
6711  
6712                  // Make sure that we're working with the right name
6713                  var ret, type, hooks,
6714                          origName = jQuery.camelCase( name ),
6715                          style = elem.style;
6716  
6717                  name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) );
6718  
6719                  // gets hook for the prefixed version
6720                  // followed by the unprefixed version
6721                  hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
6722  
6723                  // Check if we're setting a value
6724                  if ( value !== undefined ) {
6725                          type = typeof value;
6726  
6727                          // convert relative number strings (+= or -=) to relative numbers. #7345
6728                          if ( type === "string" && (ret = rrelNum.exec( value )) ) {
6729                                  value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) );
6730                                  // Fixes bug #9237
6731                                  type = "number";
6732                          }
6733  
6734                          // Make sure that NaN and null values aren't set. See: #7116
6735                          if ( value == null || type === "number" && isNaN( value ) ) {
6736                                  return;
6737                          }
6738  
6739                          // If a number was passed in, add 'px' to the (except for certain CSS properties)
6740                          if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
6741                                  value += "px";
6742                          }
6743  
6744                          // If a hook was provided, use that value, otherwise just set the specified value
6745                          if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) {
6746                                  // Wrapped to prevent IE from throwing errors when 'invalid' values are provided
6747                                  // Fixes bug #5509
6748                                  try {
6749                                          style[ name ] = value;
6750                                  } catch(e) {}
6751                          }
6752  
6753                  } else {
6754                          // If a hook was provided get the non-computed value from there
6755                          if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
6756                                  return ret;
6757                          }
6758  
6759                          // Otherwise just get the value from the style object
6760                          return style[ name ];
6761                  }
6762          },
6763  
6764          css: function( elem, name, numeric, extra ) {
6765                  var val, num, hooks,
6766                          origName = jQuery.camelCase( name );
6767  
6768                  // Make sure that we're working with the right name
6769                  name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );
6770  
6771                  // gets hook for the prefixed version
6772                  // followed by the unprefixed version
6773                  hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
6774  
6775                  // If a hook was provided get the computed value from there
6776                  if ( hooks && "get" in hooks ) {
6777                          val = hooks.get( elem, true, extra );
6778                  }
6779  
6780                  // Otherwise, if a way to get the computed value exists, use that
6781                  if ( val === undefined ) {
6782                          val = curCSS( elem, name );
6783                  }
6784  
6785                  //convert "normal" to computed value
6786                  if ( val === "normal" && name in cssNormalTransform ) {
6787                          val = cssNormalTransform[ name ];
6788                  }
6789  
6790                  // Return, converting to number if forced or a qualifier was provided and val looks numeric
6791                  if ( numeric || extra !== undefined ) {
6792                          num = parseFloat( val );
6793                          return numeric || jQuery.isNumeric( num ) ? num || 0 : val;
6794                  }
6795                  return val;
6796          },
6797  
6798          // A method for quickly swapping in/out CSS properties to get correct calculations
6799          swap: function( elem, options, callback ) {
6800                  var ret, name,
6801                          old = {};
6802  
6803                  // Remember the old values, and insert the new ones
6804                  for ( name in options ) {
6805                          old[ name ] = elem.style[ name ];
6806                          elem.style[ name ] = options[ name ];
6807                  }
6808  
6809                  ret = callback.call( elem );
6810  
6811                  // Revert the old values
6812                  for ( name in options ) {
6813                          elem.style[ name ] = old[ name ];
6814                  }
6815  
6816                  return ret;
6817          }
6818  });
6819  
6820  // NOTE: To any future maintainer, we've window.getComputedStyle
6821  // because jsdom on node.js will break without it.
6822  if ( window.getComputedStyle ) {
6823          curCSS = function( elem, name ) {
6824                  var ret, width, minWidth, maxWidth,
6825                          computed = window.getComputedStyle( elem, null ),
6826                          style = elem.style;
6827  
6828                  if ( computed ) {
6829  
6830                          // getPropertyValue is only needed for .css('filter') in IE9, see #12537
6831                          ret = computed.getPropertyValue( name ) || computed[ name ];
6832  
6833                          if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) {
6834                                  ret = jQuery.style( elem, name );
6835                          }
6836  
6837                          // A tribute to the "awesome hack by Dean Edwards"
6838                          // Chrome < 17 and Safari 5.0 uses "computed value" instead of "used value" for margin-right
6839                          // Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels
6840                          // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values
6841                          if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) {
6842                                  width = style.width;
6843                                  minWidth = style.minWidth;
6844                                  maxWidth = style.maxWidth;
6845  
6846                                  style.minWidth = style.maxWidth = style.width = ret;
6847                                  ret = computed.width;
6848  
6849                                  style.width = width;
6850                                  style.minWidth = minWidth;
6851                                  style.maxWidth = maxWidth;
6852                          }
6853                  }
6854  
6855                  return ret;
6856          };
6857  } else if ( document.documentElement.currentStyle ) {
6858          curCSS = function( elem, name ) {
6859                  var left, rsLeft,
6860                          ret = elem.currentStyle && elem.currentStyle[ name ],
6861                          style = elem.style;
6862  
6863                  // Avoid setting ret to empty string here
6864                  // so we don't default to auto
6865                  if ( ret == null && style && style[ name ] ) {
6866                          ret = style[ name ];
6867                  }
6868  
6869                  // From the awesome hack by Dean Edwards
6870                  // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
6871  
6872                  // If we're not dealing with a regular pixel number
6873                  // but a number that has a weird ending, we need to convert it to pixels
6874                  // but not position css attributes, as those are proportional to the parent element instead
6875                  // and we can't measure the parent instead because it might trigger a "stacking dolls" problem
6876                  if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) {
6877  
6878                          // Remember the original values
6879                          left = style.left;
6880                          rsLeft = elem.runtimeStyle && elem.runtimeStyle.left;
6881  
6882                          // Put in the new values to get a computed value out
6883                          if ( rsLeft ) {
6884                                  elem.runtimeStyle.left = elem.currentStyle.left;
6885                          }
6886                          style.left = name === "fontSize" ? "1em" : ret;
6887                          ret = style.pixelLeft + "px";
6888  
6889                          // Revert the changed values
6890                          style.left = left;
6891                          if ( rsLeft ) {
6892                                  elem.runtimeStyle.left = rsLeft;
6893                          }
6894                  }
6895  
6896                  return ret === "" ? "auto" : ret;
6897          };
6898  }
6899  
6900  function setPositiveNumber( elem, value, subtract ) {
6901          var matches = rnumsplit.exec( value );
6902          return matches ?
6903                          Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) :
6904                          value;
6905  }
6906  
6907  function augmentWidthOrHeight( elem, name, extra, isBorderBox ) {
6908          var i = extra === ( isBorderBox ? "border" : "content" ) ?
6909                  // If we already have the right measurement, avoid augmentation
6910                  4 :
6911                  // Otherwise initialize for horizontal or vertical properties
6912                  name === "width" ? 1 : 0,
6913  
6914                  val = 0;
6915  
6916          for ( ; i < 4; i += 2 ) {
6917                  // both box models exclude margin, so add it if we want it
6918                  if ( extra === "margin" ) {
6919                          // we use jQuery.css instead of curCSS here
6920                          // because of the reliableMarginRight CSS hook!
6921                          val += jQuery.css( elem, extra + cssExpand[ i ], true );
6922                  }
6923  
6924                  // From this point on we use curCSS for maximum performance (relevant in animations)
6925                  if ( isBorderBox ) {
6926                          // border-box includes padding, so remove it if we want content
6927                          if ( extra === "content" ) {
6928                                  val -= parseFloat( curCSS( elem, "padding" + cssExpand[ i ] ) ) || 0;
6929                          }
6930  
6931                          // at this point, extra isn't border nor margin, so remove border
6932                          if ( extra !== "margin" ) {
6933                                  val -= parseFloat( curCSS( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0;
6934                          }
6935                  } else {
6936                          // at this point, extra isn't content, so add padding
6937                          val += parseFloat( curCSS( elem, "padding" + cssExpand[ i ] ) ) || 0;
6938  
6939                          // at this point, extra isn't content nor padding, so add border
6940                          if ( extra !== "padding" ) {
6941                                  val += parseFloat( curCSS( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0;
6942                          }
6943                  }
6944          }
6945  
6946          return val;
6947  }
6948  
6949  function getWidthOrHeight( elem, name, extra ) {
6950  
6951          // Start with offset property, which is equivalent to the border-box value
6952          var val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
6953                  valueIsBorderBox = true,
6954                  isBorderBox = jQuery.support.boxSizing && jQuery.css( elem, "boxSizing" ) === "border-box";
6955  
6956          // some non-html elements return undefined for offsetWidth, so check for null/undefined
6957          // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
6958          // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
6959          if ( val <= 0 || val == null ) {
6960                  // Fall back to computed then uncomputed css if necessary
6961                  val = curCSS( elem, name );
6962                  if ( val < 0 || val == null ) {
6963                          val = elem.style[ name ];
6964                  }
6965  
6966                  // Computed unit is not pixels. Stop here and return.
6967                  if ( rnumnonpx.test(val) ) {
6968                          return val;
6969                  }
6970  
6971                  // we need the check for style in case a browser which returns unreliable values
6972                  // for getComputedStyle silently falls back to the reliable elem.style
6973                  valueIsBorderBox = isBorderBox && ( jQuery.support.boxSizingReliable || val === elem.style[ name ] );
6974  
6975                  // Normalize "", auto, and prepare for extra
6976                  val = parseFloat( val ) || 0;
6977          }
6978  
6979          // use the active box-sizing model to add/subtract irrelevant styles
6980          return ( val +
6981                  augmentWidthOrHeight(
6982                          elem,
6983                          name,
6984                          extra || ( isBorderBox ? "border" : "content" ),
6985                          valueIsBorderBox
6986                  )
6987          ) + "px";
6988  }
6989  
6990  
6991  // Try to determine the default display value of an element
6992  function css_defaultDisplay( nodeName ) {
6993          if ( elemdisplay[ nodeName ] ) {
6994                  return elemdisplay[ nodeName ];
6995          }
6996  
6997          var elem = jQuery( "<" + nodeName + ">" ).appendTo( document.body ),
6998                  display = elem.css("display");
6999          elem.remove();
7000  
7001          // If the simple way fails,
7002          // get element's real default display by attaching it to a temp iframe
7003          if ( display === "none" || display === "" ) {
7004                  // Use the already-created iframe if possible
7005                  iframe = document.body.appendChild(
7006                          iframe || jQuery.extend( document.createElement("iframe"), {
7007                                  frameBorder: 0,
7008                                  width: 0,
7009                                  height: 0
7010                          })
7011                  );
7012  
7013                  // Create a cacheable copy of the iframe document on first call.
7014                  // IE and Opera will allow us to reuse the iframeDoc without re-writing the fake HTML
7015                  // document to it; WebKit & Firefox won't allow reusing the iframe document.
7016                  if ( !iframeDoc || !iframe.createElement ) {
7017                          iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document;
7018                          iframeDoc.write("<!doctype html><html><body>");
7019                          iframeDoc.close();
7020                  }
7021  
7022                  elem = iframeDoc.body.appendChild( iframeDoc.createElement(nodeName) );
7023  
7024                  display = curCSS( elem, "display" );
7025                  document.body.removeChild( iframe );
7026          }
7027  
7028          // Store the correct default display
7029          elemdisplay[ nodeName ] = display;
7030  
7031          return display;
7032  }
7033  
7034  jQuery.each([ "height", "width" ], function( i, name ) {
7035          jQuery.cssHooks[ name ] = {
7036                  get: function( elem, computed, extra ) {
7037                          if ( computed ) {
7038                                  // certain elements can have dimension info if we invisibly show them
7039                                  // however, it must have a current display style that would benefit from this
7040                                  if ( elem.offsetWidth === 0 && rdisplayswap.test( curCSS( elem, "display" ) ) ) {
7041                                          return jQuery.swap( elem, cssShow, function() {
7042                                                  return getWidthOrHeight( elem, name, extra );
7043                                          });
7044                                  } else {
7045                                          return getWidthOrHeight( elem, name, extra );
7046                                  }
7047                          }
7048                  },
7049  
7050                  set: function( elem, value, extra ) {
7051                          return setPositiveNumber( elem, value, extra ?
7052                                  augmentWidthOrHeight(
7053                                          elem,
7054                                          name,
7055                                          extra,
7056                                          jQuery.support.boxSizing && jQuery.css( elem, "boxSizing" ) === "border-box"
7057                                  ) : 0
7058                          );
7059                  }
7060          };
7061  });
7062  
7063  if ( !jQuery.support.opacity ) {
7064          jQuery.cssHooks.opacity = {
7065                  get: function( elem, computed ) {
7066                          // IE uses filters for opacity
7067                          return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ?
7068                                  ( 0.01 * parseFloat( RegExp.$1 ) ) + "" :
7069                                  computed ? "1" : "";
7070                  },
7071  
7072                  set: function( elem, value ) {
7073                          var style = elem.style,
7074                                  currentStyle = elem.currentStyle,
7075                                  opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "",
7076                                  filter = currentStyle && currentStyle.filter || style.filter || "";
7077  
7078                          // IE has trouble with opacity if it does not have layout
7079                          // Force it by setting the zoom level
7080                          style.zoom = 1;
7081  
7082                          // if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652
7083                          if ( value >= 1 && jQuery.trim( filter.replace( ralpha, "" ) ) === "" &&
7084                                  style.removeAttribute ) {
7085  
7086                                  // Setting style.filter to null, "" & " " still leave "filter:" in the cssText
7087                                  // if "filter:" is present at all, clearType is disabled, we want to avoid this
7088                                  // style.removeAttribute is IE Only, but so apparently is this code path...
7089                                  style.removeAttribute( "filter" );
7090  
7091                                  // if there there is no filter style applied in a css rule, we are done
7092                                  if ( currentStyle && !currentStyle.filter ) {
7093                                          return;
7094                                  }
7095                          }
7096  
7097                          // otherwise, set new filter values
7098                          style.filter = ralpha.test( filter ) ?
7099                                  filter.replace( ralpha, opacity ) :
7100                                  filter + " " + opacity;
7101                  }
7102          };
7103  }
7104  
7105  // These hooks cannot be added until DOM ready because the support test
7106  // for it is not run until after DOM ready
7107  jQuery(function() {
7108          if ( !jQuery.support.reliableMarginRight ) {
7109                  jQuery.cssHooks.marginRight = {
7110                          get: function( elem, computed ) {
7111                                  // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
7112                                  // Work around by temporarily setting element display to inline-block
7113                                  return jQuery.swap( elem, { "display": "inline-block" }, function() {
7114                                          if ( computed ) {
7115                                                  return curCSS( elem, "marginRight" );
7116                                          }
7117                                  });
7118                          }
7119                  };
7120          }
7121  
7122          // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
7123          // getComputedStyle returns percent when specified for top/left/bottom/right
7124          // rather than make the css module depend on the offset module, we just check for it here
7125          if ( !jQuery.support.pixelPosition && jQuery.fn.position ) {
7126                  jQuery.each( [ "top", "left" ], function( i, prop ) {
7127                          jQuery.cssHooks[ prop ] = {
7128                                  get: function( elem, computed ) {
7129                                          if ( computed ) {
7130                                                  var ret = curCSS( elem, prop );
7131                                                  // if curCSS returns percentage, fallback to offset
7132                                                  return rnumnonpx.test( ret ) ? jQuery( elem ).position()[ prop ] + "px" : ret;
7133                                          }
7134                                  }
7135                          };
7136                  });
7137          }
7138  
7139  });
7140  
7141  if ( jQuery.expr && jQuery.expr.filters ) {
7142          jQuery.expr.filters.hidden = function( elem ) {
7143                  return ( elem.offsetWidth === 0 && elem.offsetHeight === 0 ) || (!jQuery.support.reliableHiddenOffsets && ((elem.style && elem.style.display) || curCSS( elem, "display" )) === "none");
7144          };
7145  
7146          jQuery.expr.filters.visible = function( elem ) {
7147                  return !jQuery.expr.filters.hidden( elem );
7148          };
7149  }
7150  
7151  // These hooks are used by animate to expand properties
7152  jQuery.each({
7153          margin: "",
7154          padding: "",
7155          border: "Width"
7156  }, function( prefix, suffix ) {
7157          jQuery.cssHooks[ prefix + suffix ] = {
7158                  expand: function( value ) {
7159                          var i,
7160  
7161                                  // assumes a single number if not a string
7162                                  parts = typeof value === "string" ? value.split(" ") : [ value ],
7163                                  expanded = {};
7164  
7165                          for ( i = 0; i < 4; i++ ) {
7166                                  expanded[ prefix + cssExpand[ i ] + suffix ] =
7167                                          parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
7168                          }
7169  
7170                          return expanded;
7171                  }
7172          };
7173  
7174          if ( !rmargin.test( prefix ) ) {
7175                  jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
7176          }
7177  });
7178  var r20 = /%20/g,
7179          rbracket = /\[\]$/,
7180          rCRLF = /\r?\n/g,
7181          rinput = /^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,
7182          rselectTextarea = /^(?:select|textarea)/i;
7183  
7184  jQuery.fn.extend({
7185          serialize: function() {
7186                  return jQuery.param( this.serializeArray() );
7187          },
7188          serializeArray: function() {
7189                  return this.map(function(){
7190                          return this.elements ? jQuery.makeArray( this.elements ) : this;
7191                  })
7192                  .filter(function(){
7193                          return this.name && !this.disabled &&
7194                                  ( this.checked || rselectTextarea.test( this.nodeName ) ||
7195                                          rinput.test( this.type ) );
7196                  })
7197                  .map(function( i, elem ){
7198                          var val = jQuery( this ).val();
7199  
7200                          return val == null ?
7201                                  null :
7202                                  jQuery.isArray( val ) ?
7203                                          jQuery.map( val, function( val, i ){
7204                                                  return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
7205                                          }) :
7206                                          { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
7207                  }).get();
7208          }
7209  });
7210  
7211  //Serialize an array of form elements or a set of
7212  //key/values into a query string
7213  jQuery.param = function( a, traditional ) {
7214          var prefix,
7215                  s = [],
7216                  add = function( key, value ) {
7217                          // If value is a function, invoke it and return its value
7218                          value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value );
7219                          s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
7220                  };
7221  
7222          // Set traditional to true for jQuery <= 1.3.2 behavior.
7223          if ( traditional === undefined ) {
7224                  traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
7225          }
7226  
7227          // If an array was passed in, assume that it is an array of form elements.
7228          if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
7229                  // Serialize the form elements
7230                  jQuery.each( a, function() {
7231                          add( this.name, this.value );
7232                  });
7233  
7234          } else {
7235                  // If traditional, encode the "old" way (the way 1.3.2 or older
7236                  // did it), otherwise encode params recursively.
7237                  for ( prefix in a ) {
7238                          buildParams( prefix, a[ prefix ], traditional, add );
7239                  }
7240          }
7241  
7242          // Return the resulting serialization
7243          return s.join( "&" ).replace( r20, "+" );
7244  };
7245  
7246  function buildParams( prefix, obj, traditional, add ) {
7247          var name;
7248  
7249          if ( jQuery.isArray( obj ) ) {
7250                  // Serialize array item.
7251                  jQuery.each( obj, function( i, v ) {
7252                          if ( traditional || rbracket.test( prefix ) ) {
7253                                  // Treat each array item as a scalar.
7254                                  add( prefix, v );
7255  
7256                          } else {
7257                                  // If array item is non-scalar (array or object), encode its
7258                                  // numeric index to resolve deserialization ambiguity issues.
7259                                  // Note that rack (as of 1.0.0) can't currently deserialize
7260                                  // nested arrays properly, and attempting to do so may cause
7261                                  // a server error. Possible fixes are to modify rack's
7262                                  // deserialization algorithm or to provide an option or flag
7263                                  // to force array serialization to be shallow.
7264                                  buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add );
7265                          }
7266                  });
7267  
7268          } else if ( !traditional && jQuery.type( obj ) === "object" ) {
7269                  // Serialize object item.
7270                  for ( name in obj ) {
7271                          buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
7272                  }
7273  
7274          } else {
7275                  // Serialize scalar item.
7276                  add( prefix, obj );
7277          }
7278  }
7279  var
7280          // Document location
7281          ajaxLocParts,
7282          ajaxLocation,
7283  
7284          rhash = /#.*$/,
7285          rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL
7286          // #7653, #8125, #8152: local protocol detection
7287          rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,
7288          rnoContent = /^(?:GET|HEAD)$/,
7289          rprotocol = /^\/\//,
7290          rquery = /\?/,
7291          rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
7292          rts = /([?&])_=[^&]*/,
7293          rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,
7294  
7295          // Keep a copy of the old load method
7296          _load = jQuery.fn.load,
7297  
7298          /* Prefilters
7299           * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
7300           * 2) These are called:
7301           *    - BEFORE asking for a transport
7302           *    - AFTER param serialization (s.data is a string if s.processData is true)
7303           * 3) key is the dataType
7304           * 4) the catchall symbol "*" can be used
7305           * 5) execution will start with transport dataType and THEN continue down to "*" if needed
7306           */
7307          prefilters = {},
7308  
7309          /* Transports bindings
7310           * 1) key is the dataType
7311           * 2) the catchall symbol "*" can be used
7312           * 3) selection will start with transport dataType and THEN go to "*" if needed
7313           */
7314          transports = {},
7315  
7316          // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
7317          allTypes = ["*/"] + ["*"];
7318  
7319  // #8138, IE may throw an exception when accessing
7320  // a field from window.location if document.domain has been set
7321  try {
7322          ajaxLocation = location.href;
7323  } catch( e ) {
7324          // Use the href attribute of an A element
7325          // since IE will modify it given document.location
7326          ajaxLocation = document.createElement( "a" );
7327          ajaxLocation.href = "";
7328          ajaxLocation = ajaxLocation.href;
7329  }
7330  
7331  // Segment location into parts
7332  ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
7333  
7334  // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
7335  function addToPrefiltersOrTransports( structure ) {
7336  
7337          // dataTypeExpression is optional and defaults to "*"
7338          return function( dataTypeExpression, func ) {
7339  
7340                  if ( typeof dataTypeExpression !== "string" ) {
7341                          func = dataTypeExpression;
7342                          dataTypeExpression = "*";
7343                  }
7344  
7345                  var dataType, list, placeBefore,
7346                          dataTypes = dataTypeExpression.toLowerCase().split( core_rspace ),
7347                          i = 0,
7348                          length = dataTypes.length;
7349  
7350                  if ( jQuery.isFunction( func ) ) {
7351                          // For each dataType in the dataTypeExpression
7352                          for ( ; i < length; i++ ) {
7353                                  dataType = dataTypes[ i ];
7354                                  // We control if we're asked to add before
7355                                  // any existing element
7356                                  placeBefore = /^\+/.test( dataType );
7357                                  if ( placeBefore ) {
7358                                          dataType = dataType.substr( 1 ) || "*";
7359                                  }
7360                                  list = structure[ dataType ] = structure[ dataType ] || [];
7361                                  // then we add to the structure accordingly
7362                                  list[ placeBefore ? "unshift" : "push" ]( func );
7363                          }
7364                  }
7365          };
7366  }
7367  
7368  // Base inspection function for prefilters and transports
7369  function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR,
7370                  dataType /* internal */, inspected /* internal */ ) {
7371  
7372          dataType = dataType || options.dataTypes[ 0 ];
7373          inspected = inspected || {};
7374  
7375          inspected[ dataType ] = true;
7376  
7377          var selection,
7378                  list = structure[ dataType ],
7379                  i = 0,
7380                  length = list ? list.length : 0,
7381                  executeOnly = ( structure === prefilters );
7382  
7383          for ( ; i < length && ( executeOnly || !selection ); i++ ) {
7384                  selection = list[ i ]( options, originalOptions, jqXHR );
7385                  // If we got redirected to another dataType
7386                  // we try there if executing only and not done already
7387                  if ( typeof selection === "string" ) {
7388                          if ( !executeOnly || inspected[ selection ] ) {
7389                                  selection = undefined;
7390                          } else {
7391                                  options.dataTypes.unshift( selection );
7392                                  selection = inspectPrefiltersOrTransports(
7393                                                  structure, options, originalOptions, jqXHR, selection, inspected );
7394                          }
7395                  }
7396          }
7397          // If we're only executing or nothing was selected
7398          // we try the catchall dataType if not done already
7399          if ( ( executeOnly || !selection ) && !inspected[ "*" ] ) {
7400                  selection = inspectPrefiltersOrTransports(
7401                                  structure, options, originalOptions, jqXHR, "*", inspected );
7402          }
7403          // unnecessary when only executing (prefilters)
7404          // but it'll be ignored by the caller in that case
7405          return selection;
7406  }
7407  
7408  // A special extend for ajax options
7409  // that takes "flat" options (not to be deep extended)
7410  // Fixes #9887
7411  function ajaxExtend( target, src ) {
7412          var key, deep,
7413                  flatOptions = jQuery.ajaxSettings.flatOptions || {};
7414          for ( key in src ) {
7415                  if ( src[ key ] !== undefined ) {
7416                          ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
7417                  }
7418          }
7419          if ( deep ) {
7420                  jQuery.extend( true, target, deep );
7421          }
7422  }
7423  
7424  jQuery.fn.load = function( url, params, callback ) {
7425          if ( typeof url !== "string" && _load ) {
7426                  return _load.apply( this, arguments );
7427          }
7428  
7429          // Don't do a request if no elements are being requested
7430          if ( !this.length ) {
7431                  return this;
7432          }
7433  
7434          var selector, type, response,
7435                  self = this,
7436                  off = url.indexOf(" ");
7437  
7438          if ( off >= 0 ) {
7439                  selector = url.slice( off, url.length );
7440                  url = url.slice( 0, off );
7441          }
7442  
7443          // If it's a function
7444          if ( jQuery.isFunction( params ) ) {
7445  
7446                  // We assume that it's the callback
7447                  callback = params;
7448                  params = undefined;
7449  
7450          // Otherwise, build a param string
7451          } else if ( params && typeof params === "object" ) {
7452                  type = "POST";
7453          }
7454  
7455          // Request the remote document
7456          jQuery.ajax({
7457                  url: url,
7458  
7459                  // if "type" variable is undefined, then "GET" method will be used
7460                  type: type,
7461                  dataType: "html",
7462                  data: params,
7463                  complete: function( jqXHR, status ) {
7464                          if ( callback ) {
7465                                  self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );
7466                          }
7467                  }
7468          }).done(function( responseText ) {
7469  
7470                  // Save response for use in complete callback
7471                  response = arguments;
7472  
7473                  // See if a selector was specified
7474                  self.html( selector ?
7475  
7476                          // Create a dummy div to hold the results
7477                          jQuery("<div>")
7478  
7479                                  // inject the contents of the document in, removing the scripts
7480                                  // to avoid any 'Permission Denied' errors in IE
7481                                  .append( responseText.replace( rscript, "" ) )
7482  
7483                                  // Locate the specified elements
7484                                  .find( selector ) :
7485  
7486                          // If not, just inject the full result
7487                          responseText );
7488  
7489          });
7490  
7491          return this;
7492  };
7493  
7494  // Attach a bunch of functions for handling common AJAX events
7495  jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split( " " ), function( i, o ){
7496          jQuery.fn[ o ] = function( f ){
7497                  return this.on( o, f );
7498          };
7499  });
7500  
7501  jQuery.each( [ "get", "post" ], function( i, method ) {
7502          jQuery[ method ] = function( url, data, callback, type ) {
7503                  // shift arguments if data argument was omitted
7504                  if ( jQuery.isFunction( data ) ) {
7505                          type = type || callback;
7506                          callback = data;
7507                          data = undefined;
7508                  }
7509  
7510                  return jQuery.ajax({
7511                          type: method,
7512                          url: url,
7513                          data: data,
7514                          success: callback,
7515                          dataType: type
7516                  });
7517          };
7518  });
7519  
7520  jQuery.extend({
7521  
7522          getScript: function( url, callback ) {
7523                  return jQuery.get( url, undefined, callback, "script" );
7524          },
7525  
7526          getJSON: function( url, data, callback ) {
7527                  return jQuery.get( url, data, callback, "json" );
7528          },
7529  
7530          // Creates a full fledged settings object into target
7531          // with both ajaxSettings and settings fields.
7532          // If target is omitted, writes into ajaxSettings.
7533          ajaxSetup: function( target, settings ) {
7534                  if ( settings ) {
7535                          // Building a settings object
7536                          ajaxExtend( target, jQuery.ajaxSettings );
7537                  } else {
7538                          // Extending ajaxSettings
7539                          settings = target;
7540                          target = jQuery.ajaxSettings;
7541                  }
7542                  ajaxExtend( target, settings );
7543                  return target;
7544          },
7545  
7546          ajaxSettings: {
7547                  url: ajaxLocation,
7548                  isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
7549                  global: true,
7550                  type: "GET",
7551                  contentType: "application/x-www-form-urlencoded; charset=UTF-8",
7552                  processData: true,
7553                  async: true,
7554                  /*
7555                  timeout: 0,
7556                  data: null,
7557                  dataType: null,
7558                  username: null,
7559                  password: null,
7560                  cache: null,
7561                  throws: false,
7562                  traditional: false,
7563                  headers: {},
7564                  */
7565  
7566                  accepts: {
7567                          xml: "application/xml, text/xml",
7568                          html: "text/html",
7569                          text: "text/plain",
7570                          json: "application/json, text/javascript",
7571                          "*": allTypes
7572                  },
7573  
7574                  contents: {
7575                          xml: /xml/,
7576                          html: /html/,
7577                          json: /json/
7578                  },
7579  
7580                  responseFields: {
7581                          xml: "responseXML",
7582                          text: "responseText"
7583                  },
7584  
7585                  // List of data converters
7586                  // 1) key format is "source_type destination_type" (a single space in-between)
7587                  // 2) the catchall symbol "*" can be used for source_type
7588                  converters: {
7589  
7590                          // Convert anything to text
7591                          "* text": window.String,
7592  
7593                          // Text to html (true = no transformation)
7594                          "text html": true,
7595  
7596                          // Evaluate text as a json expression
7597                          "text json": jQuery.parseJSON,
7598  
7599                          // Parse text as xml
7600                          "text xml": jQuery.parseXML
7601                  },
7602  
7603                  // For options that shouldn't be deep extended:
7604                  // you can add your own custom options here if
7605                  // and when you create one that shouldn't be
7606                  // deep extended (see ajaxExtend)
7607                  flatOptions: {
7608                          context: true,
7609                          url: true
7610                  }
7611          },
7612  
7613          ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
7614          ajaxTransport: addToPrefiltersOrTransports( transports ),
7615  
7616          // Main method
7617          ajax: function( url, options ) {
7618  
7619                  // If url is an object, simulate pre-1.5 signature
7620                  if ( typeof url === "object" ) {
7621                          options = url;
7622                          url = undefined;
7623                  }
7624  
7625                  // Force options to be an object
7626                  options = options || {};
7627  
7628                  var // ifModified key
7629                          ifModifiedKey,
7630                          // Response headers
7631                          responseHeadersString,
7632                          responseHeaders,
7633                          // transport
7634                          transport,
7635                          // timeout handle
7636                          timeoutTimer,
7637                          // Cross-domain detection vars
7638                          parts,
7639                          // To know if global events are to be dispatched
7640                          fireGlobals,
7641                          // Loop variable
7642                          i,
7643                          // Create the final options object
7644                          s = jQuery.ajaxSetup( {}, options ),
7645                          // Callbacks context
7646                          callbackContext = s.context || s,
7647                          // Context for global events
7648                          // It's the callbackContext if one was provided in the options
7649                          // and if it's a DOM node or a jQuery collection
7650                          globalEventContext = callbackContext !== s &&
7651                                  ( callbackContext.nodeType || callbackContext instanceof jQuery ) ?
7652                                                  jQuery( callbackContext ) : jQuery.event,
7653                          // Deferreds
7654                          deferred = jQuery.Deferred(),
7655                          completeDeferred = jQuery.Callbacks( "once memory" ),
7656                          // Status-dependent callbacks
7657                          statusCode = s.statusCode || {},
7658                          // Headers (they are sent all at once)
7659                          requestHeaders = {},
7660                          requestHeadersNames = {},
7661                          // The jqXHR state
7662                          state = 0,
7663                          // Default abort message
7664                          strAbort = "canceled",
7665                          // Fake xhr
7666                          jqXHR = {
7667  
7668                                  readyState: 0,
7669  
7670                                  // Caches the header
7671                                  setRequestHeader: function( name, value ) {
7672                                          if ( !state ) {
7673                                                  var lname = name.toLowerCase();
7674                                                  name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
7675                                                  requestHeaders[ name ] = value;
7676                                          }
7677                                          return this;
7678                                  },
7679  
7680                                  // Raw string
7681                                  getAllResponseHeaders: function() {
7682                                          return state === 2 ? responseHeadersString : null;
7683                                  },
7684  
7685                                  // Builds headers hashtable if needed
7686                                  getResponseHeader: function( key ) {
7687                                          var match;
7688                                          if ( state === 2 ) {
7689                                                  if ( !responseHeaders ) {
7690                                                          responseHeaders = {};
7691                                                          while( ( match = rheaders.exec( responseHeadersString ) ) ) {
7692                                                                  responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
7693                                                          }
7694                                                  }
7695                                                  match = responseHeaders[ key.toLowerCase() ];
7696                                          }
7697                                          return match === undefined ? null : match;
7698                                  },
7699  
7700                                  // Overrides response content-type header
7701                                  overrideMimeType: function( type ) {
7702                                          if ( !state ) {
7703                                                  s.mimeType = type;
7704                                          }
7705                                          return this;
7706                                  },
7707  
7708                                  // Cancel the request
7709                                  abort: function( statusText ) {
7710                                          statusText = statusText || strAbort;
7711                                          if ( transport ) {
7712                                                  transport.abort( statusText );
7713                                          }
7714                                          done( 0, statusText );
7715                                          return this;
7716                                  }
7717                          };
7718  
7719                  // Callback for when everything is done
7720                  // It is defined here because jslint complains if it is declared
7721                  // at the end of the function (which would be more logical and readable)
7722                  function done( status, nativeStatusText, responses, headers ) {
7723                          var isSuccess, success, error, response, modified,
7724                                  statusText = nativeStatusText;
7725  
7726                          // Called once
7727                          if ( state === 2 ) {
7728                                  return;
7729                          }
7730  
7731                          // State is "done" now
7732                          state = 2;
7733  
7734                          // Clear timeout if it exists
7735                          if ( timeoutTimer ) {
7736                                  clearTimeout( timeoutTimer );
7737                          }
7738  
7739                          // Dereference transport for early garbage collection
7740                          // (no matter how long the jqXHR object will be used)
7741                          transport = undefined;
7742  
7743                          // Cache response headers
7744                          responseHeadersString = headers || "";
7745  
7746                          // Set readyState
7747                          jqXHR.readyState = status > 0 ? 4 : 0;
7748  
7749                          // Get response data
7750                          if ( responses ) {
7751                                  response = ajaxHandleResponses( s, jqXHR, responses );
7752                          }
7753  
7754                          // If successful, handle type chaining
7755                          if ( status >= 200 && status < 300 || status === 304 ) {
7756  
7757                                  // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
7758                                  if ( s.ifModified ) {
7759  
7760                                          modified = jqXHR.getResponseHeader("Last-Modified");
7761                                          if ( modified ) {
7762                                                  jQuery.lastModified[ ifModifiedKey ] = modified;
7763                                          }
7764                                          modified = jqXHR.getResponseHeader("Etag");
7765                                          if ( modified ) {
7766                                                  jQuery.etag[ ifModifiedKey ] = modified;
7767                                          }
7768                                  }
7769  
7770                                  // If not modified
7771                                  if ( status === 304 ) {
7772  
7773                                          statusText = "notmodified";
7774                                          isSuccess = true;
7775  
7776                                  // If we have data
7777                                  } else {
7778  
7779                                          isSuccess = ajaxConvert( s, response );
7780                                          statusText = isSuccess.state;
7781                                          success = isSuccess.data;
7782                                          error = isSuccess.error;
7783                                          isSuccess = !error;
7784                                  }
7785                          } else {
7786                                  // We extract error from statusText
7787                                  // then normalize statusText and status for non-aborts
7788                                  error = statusText;
7789                                  if ( !statusText || status ) {
7790                                          statusText = "error";
7791                                          if ( status < 0 ) {
7792                                                  status = 0;
7793                                          }
7794                                  }
7795                          }
7796  
7797                          // Set data for the fake xhr object
7798                          jqXHR.status = status;
7799                          jqXHR.statusText = ( nativeStatusText || statusText ) + "";
7800  
7801                          // Success/Error
7802                          if ( isSuccess ) {
7803                                  deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
7804                          } else {
7805                                  deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
7806                          }
7807  
7808                          // Status-dependent callbacks
7809                          jqXHR.statusCode( statusCode );
7810                          statusCode = undefined;
7811  
7812                          if ( fireGlobals ) {
7813                                  globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ),
7814                                                  [ jqXHR, s, isSuccess ? success : error ] );
7815                          }
7816  
7817                          // Complete
7818                          completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
7819  
7820                          if ( fireGlobals ) {
7821                                  globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
7822                                  // Handle the global AJAX counter
7823                                  if ( !( --jQuery.active ) ) {
7824                                          jQuery.event.trigger( "ajaxStop" );
7825                                  }
7826                          }
7827                  }
7828  
7829                  // Attach deferreds
7830                  deferred.promise( jqXHR );
7831                  jqXHR.success = jqXHR.done;
7832                  jqXHR.error = jqXHR.fail;
7833                  jqXHR.complete = completeDeferred.add;
7834  
7835                  // Status-dependent callbacks
7836                  jqXHR.statusCode = function( map ) {
7837                          if ( map ) {
7838                                  var tmp;
7839                                  if ( state < 2 ) {
7840                                          for ( tmp in map ) {
7841                                                  statusCode[ tmp ] = [ statusCode[tmp], map[tmp] ];
7842                                          }
7843                                  } else {
7844                                          tmp = map[ jqXHR.status ];
7845                                          jqXHR.always( tmp );
7846                                  }
7847                          }
7848                          return this;
7849                  };
7850  
7851                  // Remove hash character (#7531: and string promotion)
7852                  // Add protocol if not provided (#5866: IE7 issue with protocol-less urls)
7853                  // We also use the url parameter if available
7854                  s.url = ( ( url || s.url ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
7855  
7856                  // Extract dataTypes list
7857                  s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( core_rspace );
7858  
7859                  // A cross-domain request is in order when we have a protocol:host:port mismatch
7860                  if ( s.crossDomain == null ) {
7861                          parts = rurl.exec( s.url.toLowerCase() );
7862                          s.crossDomain = !!( parts &&
7863                                  ( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||
7864                                          ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? 80 : 443 ) ) !=
7865                                                  ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? 80 : 443 ) ) )
7866                          );
7867                  }
7868  
7869                  // Convert data if not already a string
7870                  if ( s.data && s.processData && typeof s.data !== "string" ) {
7871                          s.data = jQuery.param( s.data, s.traditional );
7872                  }
7873  
7874                  // Apply prefilters
7875                  inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
7876  
7877                  // If request was aborted inside a prefilter, stop there
7878                  if ( state === 2 ) {
7879                          return jqXHR;
7880                  }
7881  
7882                  // We can fire global events as of now if asked to
7883                  fireGlobals = s.global;
7884  
7885                  // Uppercase the type
7886                  s.type = s.type.toUpperCase();
7887  
7888                  // Determine if request has content
7889                  s.hasContent = !rnoContent.test( s.type );
7890  
7891                  // Watch for a new set of requests
7892                  if ( fireGlobals && jQuery.active++ === 0 ) {
7893                          jQuery.event.trigger( "ajaxStart" );
7894                  }
7895  
7896                  // More options handling for requests with no content
7897                  if ( !s.hasContent ) {
7898  
7899                          // If data is available, append data to url
7900                          if ( s.data ) {
7901                                  s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data;
7902                                  // #9682: remove data so that it's not used in an eventual retry
7903                                  delete s.data;
7904                          }
7905  
7906                          // Get ifModifiedKey before adding the anti-cache parameter
7907                          ifModifiedKey = s.url;
7908  
7909                          // Add anti-cache in url if needed
7910                          if ( s.cache === false ) {
7911  
7912                                  var ts = jQuery.now(),
7913                                          // try replacing _= if it is there
7914                                          ret = s.url.replace( rts, "$1_=" + ts );
7915  
7916                                  // if nothing was replaced, add timestamp to the end
7917                                  s.url = ret + ( ( ret === s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : "" );
7918                          }
7919                  }
7920  
7921                  // Set the correct header, if data is being sent
7922                  if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
7923                          jqXHR.setRequestHeader( "Content-Type", s.contentType );
7924                  }
7925  
7926                  // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
7927                  if ( s.ifModified ) {
7928                          ifModifiedKey = ifModifiedKey || s.url;
7929                          if ( jQuery.lastModified[ ifModifiedKey ] ) {
7930                                  jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ ifModifiedKey ] );
7931                          }
7932                          if ( jQuery.etag[ ifModifiedKey ] ) {
7933                                  jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ ifModifiedKey ] );
7934                          }
7935                  }
7936  
7937                  // Set the Accepts header for the server, depending on the dataType
7938                  jqXHR.setRequestHeader(
7939                          "Accept",
7940                          s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?
7941                                  s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
7942                                  s.accepts[ "*" ]
7943                  );
7944  
7945                  // Check for headers option
7946                  for ( i in s.headers ) {
7947                          jqXHR.setRequestHeader( i, s.headers[ i ] );
7948                  }
7949  
7950                  // Allow custom headers/mimetypes and early abort
7951                  if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
7952                                  // Abort if not done already and return
7953                                  return jqXHR.abort();
7954  
7955                  }
7956  
7957                  // aborting is no longer a cancellation
7958                  strAbort = "abort";
7959  
7960                  // Install callbacks on deferreds
7961                  for ( i in { success: 1, error: 1, complete: 1 } ) {
7962                          jqXHR[ i ]( s[ i ] );
7963                  }
7964  
7965                  // Get transport
7966                  transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
7967  
7968                  // If no transport, we auto-abort
7969                  if ( !transport ) {
7970                          done( -1, "No Transport" );
7971                  } else {
7972                          jqXHR.readyState = 1;
7973                          // Send global event
7974                          if ( fireGlobals ) {
7975                                  globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
7976                          }
7977                          // Timeout
7978                          if ( s.async && s.timeout > 0 ) {
7979                                  timeoutTimer = setTimeout( function(){
7980                                          jqXHR.abort( "timeout" );
7981                                  }, s.timeout );
7982                          }
7983  
7984                          try {
7985                                  state = 1;
7986                                  transport.send( requestHeaders, done );
7987                          } catch (e) {
7988                                  // Propagate exception as error if not done
7989                                  if ( state < 2 ) {
7990                                          done( -1, e );
7991                                  // Simply rethrow otherwise
7992                                  } else {
7993                                          throw e;
7994                                  }
7995                          }
7996                  }
7997  
7998                  return jqXHR;
7999          },
8000  
8001          // Counter for holding the number of active queries
8002          active: 0,
8003  
8004          // Last-Modified header cache for next request
8005          lastModified: {},
8006          etag: {}
8007  
8008  });
8009  
8010  /* Handles responses to an ajax request:
8011   * - sets all responseXXX fields accordingly
8012   * - finds the right dataType (mediates between content-type and expected dataType)
8013   * - returns the corresponding response
8014   */
8015  function ajaxHandleResponses( s, jqXHR, responses ) {
8016  
8017          var ct, type, finalDataType, firstDataType,
8018                  contents = s.contents,
8019                  dataTypes = s.dataTypes,
8020                  responseFields = s.responseFields;
8021  
8022          // Fill responseXXX fields
8023          for ( type in responseFields ) {
8024                  if ( type in responses ) {
8025                          jqXHR[ responseFields[type] ] = responses[ type ];
8026                  }
8027          }
8028  
8029          // Remove auto dataType and get content-type in the process
8030          while( dataTypes[ 0 ] === "*" ) {
8031                  dataTypes.shift();
8032                  if ( ct === undefined ) {
8033                          ct = s.mimeType || jqXHR.getResponseHeader( "content-type" );
8034                  }
8035          }
8036  
8037          // Check if we're dealing with a known content-type
8038          if ( ct ) {
8039                  for ( type in contents ) {
8040                          if ( contents[ type ] && contents[ type ].test( ct ) ) {
8041                                  dataTypes.unshift( type );
8042                                  break;
8043                          }
8044                  }
8045          }
8046  
8047          // Check to see if we have a response for the expected dataType
8048          if ( dataTypes[ 0 ] in responses ) {
8049                  finalDataType = dataTypes[ 0 ];
8050          } else {
8051                  // Try convertible dataTypes
8052                  for ( type in responses ) {
8053                          if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {
8054                                  finalDataType = type;
8055                                  break;
8056                          }
8057                          if ( !firstDataType ) {
8058                                  firstDataType = type;
8059                          }
8060                  }
8061                  // Or just use first one
8062                  finalDataType = finalDataType || firstDataType;
8063          }
8064  
8065          // If we found a dataType
8066          // We add the dataType to the list if needed
8067          // and return the corresponding response
8068          if ( finalDataType ) {
8069                  if ( finalDataType !== dataTypes[ 0 ] ) {
8070                          dataTypes.unshift( finalDataType );
8071                  }
8072                  return responses[ finalDataType ];
8073          }
8074  }
8075  
8076  // Chain conversions given the request and the original response
8077  function ajaxConvert( s, response ) {
8078  
8079          var conv, conv2, current, tmp,
8080                  // Work with a copy of dataTypes in case we need to modify it for conversion
8081                  dataTypes = s.dataTypes.slice(),
8082                  prev = dataTypes[ 0 ],
8083                  converters = {},
8084                  i = 0;
8085  
8086          // Apply the dataFilter if provided
8087          if ( s.dataFilter ) {
8088                  response = s.dataFilter( response, s.dataType );
8089          }
8090  
8091          // Create converters map with lowercased keys
8092          if ( dataTypes[ 1 ] ) {
8093                  for ( conv in s.converters ) {
8094                          converters[ conv.toLowerCase() ] = s.converters[ conv ];
8095                  }
8096          }
8097  
8098          // Convert to each sequential dataType, tolerating list modification
8099          for ( ; (current = dataTypes[++i]); ) {
8100  
8101                  // There's only work to do if current dataType is non-auto
8102                  if ( current !== "*" ) {
8103  
8104                          // Convert response if prev dataType is non-auto and differs from current
8105                          if ( prev !== "*" && prev !== current ) {
8106  
8107                                  // Seek a direct converter
8108                                  conv = converters[ prev + " " + current ] || converters[ "* " + current ];
8109  
8110                                  // If none found, seek a pair
8111                                  if ( !conv ) {
8112                                          for ( conv2 in converters ) {
8113  
8114                                                  // If conv2 outputs current
8115                                                  tmp = conv2.split(" ");
8116                                                  if ( tmp[ 1 ] === current ) {
8117  
8118                                                          // If prev can be converted to accepted input
8119                                                          conv = converters[ prev + " " + tmp[ 0 ] ] ||
8120                                                                  converters[ "* " + tmp[ 0 ] ];
8121                                                          if ( conv ) {
8122                                                                  // Condense equivalence converters
8123                                                                  if ( conv === true ) {
8124                                                                          conv = converters[ conv2 ];
8125  
8126                                                                  // Otherwise, insert the intermediate dataType
8127                                                                  } else if ( converters[ conv2 ] !== true ) {
8128                                                                          current = tmp[ 0 ];
8129                                                                          dataTypes.splice( i--, 0, current );
8130                                                                  }
8131  
8132                                                                  break;
8133                                                          }
8134                                                  }
8135                                          }
8136                                  }
8137  
8138                                  // Apply converter (if not an equivalence)
8139                                  if ( conv !== true ) {
8140  
8141                                          // Unless errors are allowed to bubble, catch and return them
8142                                          if ( conv && s["throws"] ) {
8143                                                  response = conv( response );
8144                                          } else {
8145                                                  try {
8146                                                          response = conv( response );
8147                                                  } catch ( e ) {
8148                                                          return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current };
8149                                                  }
8150                                          }
8151                                  }
8152                          }
8153  
8154                          // Update prev for next iteration
8155                          prev = current;
8156                  }
8157          }
8158  
8159          return { state: "success", data: response };
8160  }
8161  var oldCallbacks = [],
8162          rquestion = /\?/,
8163          rjsonp = /(=)\?(?=&|$)|\?\?/,
8164          nonce = jQuery.now();
8165  
8166  // Default jsonp settings
8167  jQuery.ajaxSetup({
8168          jsonp: "callback",
8169          jsonpCallback: function() {
8170                  var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );
8171                  this[ callback ] = true;
8172                  return callback;
8173          }
8174  });
8175  
8176  // Detect, normalize options and install callbacks for jsonp requests
8177  jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
8178  
8179          var callbackName, overwritten, responseContainer,
8180                  data = s.data,
8181                  url = s.url,
8182                  hasCallback = s.jsonp !== false,
8183                  replaceInUrl = hasCallback && rjsonp.test( url ),
8184                  replaceInData = hasCallback && !replaceInUrl && typeof data === "string" &&
8185                          !( s.contentType || "" ).indexOf("application/x-www-form-urlencoded") &&
8186                          rjsonp.test( data );
8187  
8188          // Handle iff the expected data type is "jsonp" or we have a parameter to set
8189          if ( s.dataTypes[ 0 ] === "jsonp" || replaceInUrl || replaceInData ) {
8190  
8191                  // Get callback name, remembering preexisting value associated with it
8192                  callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
8193                          s.jsonpCallback() :
8194                          s.jsonpCallback;
8195                  overwritten = window[ callbackName ];
8196  
8197                  // Insert callback into url or form data
8198                  if ( replaceInUrl ) {
8199                          s.url = url.replace( rjsonp, "$1" + callbackName );
8200                  } else if ( replaceInData ) {
8201                          s.data = data.replace( rjsonp, "$1" + callbackName );
8202                  } else if ( hasCallback ) {
8203                          s.url += ( rquestion.test( url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
8204                  }
8205  
8206                  // Use data converter to retrieve json after script execution
8207                  s.converters["script json"] = function() {
8208                          if ( !responseContainer ) {
8209                                  jQuery.error( callbackName + " was not called" );
8210                          }
8211                          return responseContainer[ 0 ];
8212                  };
8213  
8214                  // force json dataType
8215                  s.dataTypes[ 0 ] = "json";
8216  
8217                  // Install callback
8218                  window[ callbackName ] = function() {
8219                          responseContainer = arguments;
8220                  };
8221  
8222                  // Clean-up function (fires after converters)
8223                  jqXHR.always(function() {
8224                          // Restore preexisting value
8225                          window[ callbackName ] = overwritten;
8226  
8227                          // Save back as free
8228                          if ( s[ callbackName ] ) {
8229                                  // make sure that re-using the options doesn't screw things around
8230                                  s.jsonpCallback = originalSettings.jsonpCallback;
8231  
8232                                  // save the callback name for future use
8233                                  oldCallbacks.push( callbackName );
8234                          }
8235  
8236                          // Call if it was a function and we have a response
8237                          if ( responseContainer && jQuery.isFunction( overwritten ) ) {
8238                                  overwritten( responseContainer[ 0 ] );
8239                          }
8240  
8241                          responseContainer = overwritten = undefined;
8242                  });
8243  
8244                  // Delegate to script
8245                  return "script";
8246          }
8247  });
8248  // Install script dataType
8249  jQuery.ajaxSetup({
8250          accepts: {
8251                  script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
8252          },
8253          contents: {
8254                  script: /javascript|ecmascript/
8255          },
8256          converters: {
8257                  "text script": function( text ) {
8258                          jQuery.globalEval( text );
8259                          return text;
8260                  }
8261          }
8262  });
8263  
8264  // Handle cache's special case and global
8265  jQuery.ajaxPrefilter( "script", function( s ) {
8266          if ( s.cache === undefined ) {
8267                  s.cache = false;
8268          }
8269          if ( s.crossDomain ) {
8270                  s.type = "GET";
8271                  s.global = false;
8272          }
8273  });
8274  
8275  // Bind script tag hack transport
8276  jQuery.ajaxTransport( "script", function(s) {
8277  
8278          // This transport only deals with cross domain requests
8279          if ( s.crossDomain ) {
8280  
8281                  var script,
8282                          head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement;
8283  
8284                  return {
8285  
8286                          send: function( _, callback ) {
8287  
8288                                  script = document.createElement( "script" );
8289  
8290                                  script.async = "async";
8291  
8292                                  if ( s.scriptCharset ) {
8293                                          script.charset = s.scriptCharset;
8294                                  }
8295  
8296                                  script.src = s.url;
8297  
8298                                  // Attach handlers for all browsers
8299                                  script.onload = script.onreadystatechange = function( _, isAbort ) {
8300  
8301                                          if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {
8302  
8303                                                  // Handle memory leak in IE
8304                                                  script.onload = script.onreadystatechange = null;
8305  
8306                                                  // Remove the script
8307                                                  if ( head && script.parentNode ) {
8308                                                          head.removeChild( script );
8309                                                  }
8310  
8311                                                  // Dereference the script
8312                                                  script = undefined;
8313  
8314                                                  // Callback if not abort
8315                                                  if ( !isAbort ) {
8316                                                          callback( 200, "success" );
8317                                                  }
8318                                          }
8319                                  };
8320                                  // Use insertBefore instead of appendChild  to circumvent an IE6 bug.
8321                                  // This arises when a base node is used (#2709 and #4378).
8322                                  head.insertBefore( script, head.firstChild );
8323                          },
8324  
8325                          abort: function() {
8326                                  if ( script ) {
8327                                          script.onload( 0, 1 );
8328                                  }
8329                          }
8330                  };
8331          }
8332  });
8333  var xhrCallbacks,
8334          // #5280: Internet Explorer will keep connections alive if we don't abort on unload
8335          xhrOnUnloadAbort = window.ActiveXObject ? function() {
8336                  // Abort all pending requests
8337                  for ( var key in xhrCallbacks ) {
8338                          xhrCallbacks[ key ]( 0, 1 );
8339                  }
8340          } : false,
8341          xhrId = 0;
8342  
8343  // Functions to create xhrs
8344  function createStandardXHR() {
8345          try {
8346                  return new window.XMLHttpRequest();
8347          } catch( e ) {}
8348  }
8349  
8350  function createActiveXHR() {
8351          try {
8352                  return new window.ActiveXObject( "Microsoft.XMLHTTP" );
8353          } catch( e ) {}
8354  }
8355  
8356  // Create the request object
8357  // (This is still attached to ajaxSettings for backward compatibility)
8358  jQuery.ajaxSettings.xhr = window.ActiveXObject ?
8359          /* Microsoft failed to properly
8360           * implement the XMLHttpRequest in IE7 (can't request local files),
8361           * so we use the ActiveXObject when it is available
8362           * Additionally XMLHttpRequest can be disabled in IE7/IE8 so
8363           * we need a fallback.
8364           */
8365          function() {
8366                  return !this.isLocal && createStandardXHR() || createActiveXHR();
8367          } :
8368          // For all other browsers, use the standard XMLHttpRequest object
8369          createStandardXHR;
8370  
8371  // Determine support properties
8372  (function( xhr ) {
8373          jQuery.extend( jQuery.support, {
8374                  ajax: !!xhr,
8375                  cors: !!xhr && ( "withCredentials" in xhr )
8376          });
8377  })( jQuery.ajaxSettings.xhr() );
8378  
8379  // Create transport if the browser can provide an xhr
8380  if ( jQuery.support.ajax ) {
8381  
8382          jQuery.ajaxTransport(function( s ) {
8383                  // Cross domain only allowed if supported through XMLHttpRequest
8384                  if ( !s.crossDomain || jQuery.support.cors ) {
8385  
8386                          var callback;
8387  
8388                          return {
8389                                  send: function( headers, complete ) {
8390  
8391                                          // Get a new xhr
8392                                          var handle, i,
8393                                                  xhr = s.xhr();
8394  
8395                                          // Open the socket
8396                                          // Passing null username, generates a login popup on Opera (#2865)
8397                                          if ( s.username ) {
8398                                                  xhr.open( s.type, s.url, s.async, s.username, s.password );
8399                                          } else {
8400                                                  xhr.open( s.type, s.url, s.async );
8401                                          }
8402  
8403                                          // Apply custom fields if provided
8404                                          if ( s.xhrFields ) {
8405                                                  for ( i in s.xhrFields ) {
8406                                                          xhr[ i ] = s.xhrFields[ i ];
8407                                                  }
8408                                          }
8409  
8410                                          // Override mime type if needed
8411                                          if ( s.mimeType && xhr.overrideMimeType ) {
8412                                                  xhr.overrideMimeType( s.mimeType );
8413                                          }
8414  
8415                                          // X-Requested-With header
8416                                          // For cross-domain requests, seeing as conditions for a preflight are
8417                                          // akin to a jigsaw puzzle, we simply never set it to be sure.
8418                                          // (it can always be set on a per-request basis or even using ajaxSetup)
8419                                          // For same-domain requests, won't change header if already provided.
8420                                          if ( !s.crossDomain && !headers["X-Requested-With"] ) {
8421                                                  headers[ "X-Requested-With" ] = "XMLHttpRequest";
8422                                          }
8423  
8424                                          // Need an extra try/catch for cross domain requests in Firefox 3
8425                                          try {
8426                                                  for ( i in headers ) {
8427                                                          xhr.setRequestHeader( i, headers[ i ] );
8428                                                  }
8429                                          } catch( _ ) {}
8430  
8431                                          // Do send the request
8432                                          // This may raise an exception which is actually
8433                                          // handled in jQuery.ajax (so no try/catch here)
8434                                          xhr.send( ( s.hasContent && s.data ) || null );
8435  
8436                                          // Listener
8437                                          callback = function( _, isAbort ) {
8438  
8439                                                  var status,
8440                                                          statusText,
8441                                                          responseHeaders,
8442                                                          responses,
8443                                                          xml;
8444  
8445                                                  // Firefox throws exceptions when accessing properties
8446                                                  // of an xhr when a network error occurred
8447                                                  // http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE)
8448                                                  try {
8449  
8450                                                          // Was never called and is aborted or complete
8451                                                          if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
8452  
8453                                                                  // Only called once
8454                                                                  callback = undefined;
8455  
8456                                                                  // Do not keep as active anymore
8457                                                                  if ( handle ) {
8458                                                                          xhr.onreadystatechange = jQuery.noop;
8459                                                                          if ( xhrOnUnloadAbort ) {
8460                                                                                  delete xhrCallbacks[ handle ];
8461                                                                          }
8462                                                                  }
8463  
8464                                                                  // If it's an abort
8465                                                                  if ( isAbort ) {
8466                                                                          // Abort it manually if needed
8467                                                                          if ( xhr.readyState !== 4 ) {
8468                                                                                  xhr.abort();
8469                                                                          }
8470                                                                  } else {
8471                                                                          status = xhr.status;
8472                                                                          responseHeaders = xhr.getAllResponseHeaders();
8473                                                                          responses = {};
8474                                                                          xml = xhr.responseXML;
8475  
8476                                                                          // Construct response list
8477                                                                          if ( xml && xml.documentElement /* #4958 */ ) {
8478                                                                                  responses.xml = xml;
8479                                                                          }
8480  
8481                                                                          // When requesting binary data, IE6-9 will throw an exception
8482                                                                          // on any attempt to access responseText (#11426)
8483                                                                          try {
8484                                                                                  responses.text = xhr.responseText;
8485                                                                          } catch( e ) {
8486                                                                          }
8487  
8488                                                                          // Firefox throws an exception when accessing
8489                                                                          // statusText for faulty cross-domain requests
8490                                                                          try {
8491                                                                                  statusText = xhr.statusText;
8492                                                                          } catch( e ) {
8493                                                                                  // We normalize with Webkit giving an empty statusText
8494                                                                                  statusText = "";
8495                                                                          }
8496  
8497                                                                          // Filter status for non standard behaviors
8498  
8499                                                                          // If the request is local and we have data: assume a success
8500                                                                          // (success with no data won't get notified, that's the best we
8501                                                                          // can do given current implementations)
8502                                                                          if ( !status && s.isLocal && !s.crossDomain ) {
8503                                                                                  status = responses.text ? 200 : 404;
8504                                                                          // IE - #1450: sometimes returns 1223 when it should be 204
8505                                                                          } else if ( status === 1223 ) {
8506                                                                                  status = 204;
8507                                                                          }
8508                                                                  }
8509                                                          }
8510                                                  } catch( firefoxAccessException ) {
8511                                                          if ( !isAbort ) {
8512                                                                  complete( -1, firefoxAccessException );
8513                                                          }
8514                                                  }
8515  
8516                                                  // Call complete if needed
8517                                                  if ( responses ) {
8518                                                          complete( status, statusText, responses, responseHeaders );
8519                                                  }
8520                                          };
8521  
8522                                          if ( !s.async ) {
8523                                                  // if we're in sync mode we fire the callback
8524                                                  callback();
8525                                          } else if ( xhr.readyState === 4 ) {
8526                                                  // (IE6 & IE7) if it's in cache and has been
8527                                                  // retrieved directly we need to fire the callback
8528                                                  setTimeout( callback, 0 );
8529                                          } else {
8530                                                  handle = ++xhrId;
8531                                                  if ( xhrOnUnloadAbort ) {
8532                                                          // Create the active xhrs callbacks list if needed
8533                                                          // and attach the unload handler
8534                                                          if ( !xhrCallbacks ) {
8535                                                                  xhrCallbacks = {};
8536                                                                  jQuery( window ).unload( xhrOnUnloadAbort );
8537                                                          }
8538                                                          // Add to list of active xhrs callbacks
8539                                                          xhrCallbacks[ handle ] = callback;
8540                                                  }
8541                                                  xhr.onreadystatechange = callback;
8542                                          }
8543                                  },
8544  
8545                                  abort: function() {
8546                                          if ( callback ) {
8547                                                  callback(0,1);
8548                                          }
8549                                  }
8550                          };
8551                  }
8552          });
8553  }
8554  var fxNow, timerId,
8555          rfxtypes = /^(?:toggle|show|hide)$/,
8556          rfxnum = new RegExp( "^(?:([-+])=|)(" + core_pnum + ")([a-z%]*)$", "i" ),
8557          rrun = /queueHooks$/,
8558          animationPrefilters = [ defaultPrefilter ],
8559          tweeners = {
8560                  "*": [function( prop, value ) {
8561                          var end, unit,
8562                                  tween = this.createTween( prop, value ),
8563                                  parts = rfxnum.exec( value ),
8564                                  target = tween.cur(),
8565                                  start = +target || 0,
8566                                  scale = 1,
8567                                  maxIterations = 20;
8568  
8569                          if ( parts ) {
8570                                  end = +parts[2];
8571                                  unit = parts[3] || ( jQuery.cssNumber[ prop ] ? "" : "px" );
8572  
8573                                  // We need to compute starting value
8574                                  if ( unit !== "px" && start ) {
8575                                          // Iteratively approximate from a nonzero starting point
8576                                          // Prefer the current property, because this process will be trivial if it uses the same units
8577                                          // Fallback to end or a simple constant
8578                                          start = jQuery.css( tween.elem, prop, true ) || end || 1;
8579  
8580                                          do {
8581                                                  // If previous iteration zeroed out, double until we get *something*
8582                                                  // Use a string for doubling factor so we don't accidentally see scale as unchanged below
8583                                                  scale = scale || ".5";
8584  
8585                                                  // Adjust and apply
8586                                                  start = start / scale;
8587                                                  jQuery.style( tween.elem, prop, start + unit );
8588  
8589                                          // Update scale, tolerating zero or NaN from tween.cur()
8590                                          // And breaking the loop if scale is unchanged or perfect, or if we've just had enough
8591                                          } while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations );
8592                                  }
8593  
8594                                  tween.unit = unit;
8595                                  tween.start = start;
8596                                  // If a +=/-= token was provided, we're doing a relative animation
8597                                  tween.end = parts[1] ? start + ( parts[1] + 1 ) * end : end;
8598                          }
8599                          return tween;
8600                  }]
8601          };
8602  
8603  // Animations created synchronously will run synchronously
8604  function createFxNow() {
8605          setTimeout(function() {
8606                  fxNow = undefined;
8607          }, 0 );
8608          return ( fxNow = jQuery.now() );
8609  }
8610  
8611  function createTweens( animation, props ) {
8612          jQuery.each( props, function( prop, value ) {
8613                  var collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ),
8614                          index = 0,
8615                          length = collection.length;
8616                  for ( ; index < length; index++ ) {
8617                          if ( collection[ index ].call( animation, prop, value ) ) {
8618  
8619                                  // we're done with this property
8620                                  return;
8621                          }
8622                  }
8623          });
8624  }
8625  
8626  function Animation( elem, properties, options ) {
8627          var result,
8628                  index = 0,
8629                  tweenerIndex = 0,
8630                  length = animationPrefilters.length,
8631                  deferred = jQuery.Deferred().always( function() {
8632                          // don't match elem in the :animated selector
8633                          delete tick.elem;
8634                  }),
8635                  tick = function() {
8636                          var currentTime = fxNow || createFxNow(),
8637                                  remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
8638                                  // archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497)
8639                                  temp = remaining / animation.duration || 0,
8640                                  percent = 1 - temp,
8641                                  index = 0,
8642                                  length = animation.tweens.length;
8643  
8644                          for ( ; index < length ; index++ ) {
8645                                  animation.tweens[ index ].run( percent );
8646                          }
8647  
8648                          deferred.notifyWith( elem, [ animation, percent, remaining ]);
8649  
8650                          if ( percent < 1 && length ) {
8651                                  return remaining;
8652                          } else {
8653                                  deferred.resolveWith( elem, [ animation ] );
8654                                  return false;
8655                          }
8656                  },
8657                  animation = deferred.promise({
8658                          elem: elem,
8659                          props: jQuery.extend( {}, properties ),
8660                          opts: jQuery.extend( true, { specialEasing: {} }, options ),
8661                          originalProperties: properties,
8662                          originalOptions: options,
8663                          startTime: fxNow || createFxNow(),
8664                          duration: options.duration,
8665                          tweens: [],
8666                          createTween: function( prop, end, easing ) {
8667                                  var tween = jQuery.Tween( elem, animation.opts, prop, end,
8668                                                  animation.opts.specialEasing[ prop ] || animation.opts.easing );
8669                                  animation.tweens.push( tween );
8670                                  return tween;
8671                          },
8672                          stop: function( gotoEnd ) {
8673                                  var index = 0,
8674                                          // if we are going to the end, we want to run all the tweens
8675                                          // otherwise we skip this part
8676                                          length = gotoEnd ? animation.tweens.length : 0;
8677  
8678                                  for ( ; index < length ; index++ ) {
8679                                          animation.tweens[ index ].run( 1 );
8680                                  }
8681  
8682                                  // resolve when we played the last frame
8683                                  // otherwise, reject
8684                                  if ( gotoEnd ) {
8685                                          deferred.resolveWith( elem, [ animation, gotoEnd ] );
8686                                  } else {
8687                                          deferred.rejectWith( elem, [ animation, gotoEnd ] );
8688                                  }
8689                                  return this;
8690                          }
8691                  }),
8692                  props = animation.props;
8693  
8694          propFilter( props, animation.opts.specialEasing );
8695  
8696          for ( ; index < length ; index++ ) {
8697                  result = animationPrefilters[ index ].call( animation, elem, props, animation.opts );
8698                  if ( result ) {
8699                          return result;
8700                  }
8701          }
8702  
8703          createTweens( animation, props );
8704  
8705          if ( jQuery.isFunction( animation.opts.start ) ) {
8706                  animation.opts.start.call( elem, animation );
8707          }
8708  
8709          jQuery.fx.timer(
8710                  jQuery.extend( tick, {
8711                          anim: animation,
8712                          queue: animation.opts.queue,
8713                          elem: elem
8714                  })
8715          );
8716  
8717          // attach callbacks from options
8718          return animation.progress( animation.opts.progress )
8719                  .done( animation.opts.done, animation.opts.complete )
8720                  .fail( animation.opts.fail )
8721                  .always( animation.opts.always );
8722  }
8723  
8724  function propFilter( props, specialEasing ) {
8725          var index, name, easing, value, hooks;
8726  
8727          // camelCase, specialEasing and expand cssHook pass
8728          for ( index in props ) {
8729                  name = jQuery.camelCase( index );
8730                  easing = specialEasing[ name ];
8731                  value = props[ index ];
8732                  if ( jQuery.isArray( value ) ) {
8733                          easing = value[ 1 ];
8734                          value = props[ index ] = value[ 0 ];
8735                  }
8736  
8737                  if ( index !== name ) {
8738                          props[ name ] = value;
8739                          delete props[ index ];
8740                  }
8741  
8742                  hooks = jQuery.cssHooks[ name ];
8743                  if ( hooks && "expand" in hooks ) {
8744                          value = hooks.expand( value );
8745                          delete props[ name ];
8746  
8747                          // not quite $.extend, this wont overwrite keys already present.
8748                          // also - reusing 'index' from above because we have the correct "name"
8749                          for ( index in value ) {
8750                                  if ( !( index in props ) ) {
8751                                          props[ index ] = value[ index ];
8752                                          specialEasing[ index ] = easing;
8753                                  }
8754                          }
8755                  } else {
8756                          specialEasing[ name ] = easing;
8757                  }
8758          }
8759  }
8760  
8761  jQuery.Animation = jQuery.extend( Animation, {
8762  
8763          tweener: function( props, callback ) {
8764                  if ( jQuery.isFunction( props ) ) {
8765                          callback = props;
8766                          props = [ "*" ];
8767                  } else {
8768                          props = props.split(" ");
8769                  }
8770  
8771                  var prop,
8772                          index = 0,
8773                          length = props.length;
8774  
8775                  for ( ; index < length ; index++ ) {
8776                          prop = props[ index ];
8777                          tweeners[ prop ] = tweeners[ prop ] || [];
8778                          tweeners[ prop ].unshift( callback );
8779                  }
8780          },
8781  
8782          prefilter: function( callback, prepend ) {
8783                  if ( prepend ) {
8784                          animationPrefilters.unshift( callback );
8785                  } else {
8786                          animationPrefilters.push( callback );
8787                  }
8788          }
8789  });
8790  
8791  function defaultPrefilter( elem, props, opts ) {
8792          var index, prop, value, length, dataShow, toggle, tween, hooks, oldfire,
8793                  anim = this,
8794                  style = elem.style,
8795                  orig = {},
8796                  handled = [],
8797                  hidden = elem.nodeType && isHidden( elem );
8798  
8799          // handle queue: false promises
8800          if ( !opts.queue ) {
8801                  hooks = jQuery._queueHooks( elem, "fx" );
8802                  if ( hooks.unqueued == null ) {
8803                          hooks.unqueued = 0;
8804                          oldfire = hooks.empty.fire;
8805                          hooks.empty.fire = function() {
8806                                  if ( !hooks.unqueued ) {
8807                                          oldfire();
8808                                  }
8809                          };
8810                  }
8811                  hooks.unqueued++;
8812  
8813                  anim.always(function() {
8814                          // doing this makes sure that the complete handler will be called
8815                          // before this completes
8816                          anim.always(function() {
8817                                  hooks.unqueued--;
8818                                  if ( !jQuery.queue( elem, "fx" ).length ) {
8819                                          hooks.empty.fire();
8820                                  }
8821                          });
8822                  });
8823          }
8824  
8825          // height/width overflow pass
8826          if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) {
8827                  // Make sure that nothing sneaks out
8828                  // Record all 3 overflow attributes because IE does not
8829                  // change the overflow attribute when overflowX and
8830                  // overflowY are set to the same value
8831                  opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
8832  
8833                  // Set display property to inline-block for height/width
8834                  // animations on inline elements that are having width/height animated
8835                  if ( jQuery.css( elem, "display" ) === "inline" &&
8836                                  jQuery.css( elem, "float" ) === "none" ) {
8837  
8838                          // inline-level elements accept inline-block;
8839                          // block-level elements need to be inline with layout
8840                          if ( !jQuery.support.inlineBlockNeedsLayout || css_defaultDisplay( elem.nodeName ) === "inline" ) {
8841                                  style.display = "inline-block";
8842  
8843                          } else {
8844                                  style.zoom = 1;
8845                          }
8846                  }
8847          }
8848  
8849          if ( opts.overflow ) {
8850                  style.overflow = "hidden";
8851                  if ( !jQuery.support.shrinkWrapBlocks ) {
8852                          anim.done(function() {
8853                                  style.overflow = opts.overflow[ 0 ];
8854                                  style.overflowX = opts.overflow[ 1 ];
8855                                  style.overflowY = opts.overflow[ 2 ];
8856                          });
8857                  }
8858          }
8859  
8860  
8861          // show/hide pass
8862          for ( index in props ) {
8863                  value = props[ index ];
8864                  if ( rfxtypes.exec( value ) ) {
8865                          delete props[ index ];
8866                          toggle = toggle || value === "toggle";
8867                          if ( value === ( hidden ? "hide" : "show" ) ) {
8868                                  continue;
8869                          }
8870                          handled.push( index );
8871                  }
8872          }
8873  
8874          length = handled.length;
8875          if ( length ) {
8876                  dataShow = jQuery._data( elem, "fxshow" ) || jQuery._data( elem, "fxshow", {} );
8877                  if ( "hidden" in dataShow ) {
8878                          hidden = dataShow.hidden;
8879                  }
8880  
8881                  // store state if its toggle - enables .stop().toggle() to "reverse"
8882                  if ( toggle ) {
8883                          dataShow.hidden = !hidden;
8884                  }
8885                  if ( hidden ) {
8886                          jQuery( elem ).show();
8887                  } else {
8888                          anim.done(function() {
8889                                  jQuery( elem ).hide();
8890                          });
8891                  }
8892                  anim.done(function() {
8893                          var prop;
8894                          jQuery.removeData( elem, "fxshow", true );
8895                          for ( prop in orig ) {
8896                                  jQuery.style( elem, prop, orig[ prop ] );
8897                          }
8898                  });
8899                  for ( index = 0 ; index < length ; index++ ) {
8900                          prop = handled[ index ];
8901                          tween = anim.createTween( prop, hidden ? dataShow[ prop ] : 0 );
8902                          orig[ prop ] = dataShow[ prop ] || jQuery.style( elem, prop );
8903  
8904                          if ( !( prop in dataShow ) ) {
8905                                  dataShow[ prop ] = tween.start;
8906                                  if ( hidden ) {
8907                                          tween.end = tween.start;
8908                                          tween.start = prop === "width" || prop === "height" ? 1 : 0;
8909                                  }
8910                          }
8911                  }
8912          }
8913  }
8914  
8915  function Tween( elem, options, prop, end, easing ) {
8916          return new Tween.prototype.init( elem, options, prop, end, easing );
8917  }
8918  jQuery.Tween = Tween;
8919  
8920  Tween.prototype = {
8921          constructor: Tween,
8922          init: function( elem, options, prop, end, easing, unit ) {
8923                  this.elem = elem;
8924                  this.prop = prop;
8925                  this.easing = easing || "swing";
8926                  this.options = options;
8927                  this.start = this.now = this.cur();
8928                  this.end = end;
8929                  this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
8930          },
8931          cur: function() {
8932                  var hooks = Tween.propHooks[ this.prop ];
8933  
8934                  return hooks && hooks.get ?
8935                          hooks.get( this ) :
8936                          Tween.propHooks._default.get( this );
8937          },
8938          run: function( percent ) {
8939                  var eased,
8940                          hooks = Tween.propHooks[ this.prop ];
8941  
8942                  if ( this.options.duration ) {
8943                          this.pos = eased = jQuery.easing[ this.easing ](
8944                                  percent, this.options.duration * percent, 0, 1, this.options.duration
8945                          );
8946                  } else {
8947                          this.pos = eased = percent;
8948                  }
8949                  this.now = ( this.end - this.start ) * eased + this.start;
8950  
8951                  if ( this.options.step ) {
8952                          this.options.step.call( this.elem, this.now, this );
8953                  }
8954  
8955                  if ( hooks && hooks.set ) {
8956                          hooks.set( this );
8957                  } else {
8958                          Tween.propHooks._default.set( this );
8959                  }
8960                  return this;
8961          }
8962  };
8963  
8964  Tween.prototype.init.prototype = Tween.prototype;
8965  
8966  Tween.propHooks = {
8967          _default: {
8968                  get: function( tween ) {
8969                          var result;
8970  
8971                          if ( tween.elem[ tween.prop ] != null &&
8972                                  (!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) {
8973                                  return tween.elem[ tween.prop ];
8974                          }
8975  
8976                          // passing any value as a 4th parameter to .css will automatically
8977                          // attempt a parseFloat and fallback to a string if the parse fails
8978                          // so, simple values such as "10px" are parsed to Float.
8979                          // complex values such as "rotate(1rad)" are returned as is.
8980                          result = jQuery.css( tween.elem, tween.prop, false, "" );
8981                          // Empty strings, null, undefined and "auto" are converted to 0.
8982                          return !result || result === "auto" ? 0 : result;
8983                  },
8984                  set: function( tween ) {
8985                          // use step hook for back compat - use cssHook if its there - use .style if its
8986                          // available and use plain properties where available
8987                          if ( jQuery.fx.step[ tween.prop ] ) {
8988                                  jQuery.fx.step[ tween.prop ]( tween );
8989                          } else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) {
8990                                  jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
8991                          } else {
8992                                  tween.elem[ tween.prop ] = tween.now;
8993                          }
8994                  }
8995          }
8996  };
8997  
8998  // Remove in 2.0 - this supports IE8's panic based approach
8999  // to setting things on disconnected nodes
9000  
9001  Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
9002          set: function( tween ) {
9003                  if ( tween.elem.nodeType && tween.elem.parentNode ) {
9004                          tween.elem[ tween.prop ] = tween.now;
9005                  }
9006          }
9007  };
9008  
9009  jQuery.each([ "toggle", "show", "hide" ], function( i, name ) {
9010          var cssFn = jQuery.fn[ name ];
9011          jQuery.fn[ name ] = function( speed, easing, callback ) {
9012                  return speed == null || typeof speed === "boolean" ||
9013                          // special check for .toggle( handler, handler, ... )
9014                          ( !i && jQuery.isFunction( speed ) && jQuery.isFunction( easing ) ) ?
9015                          cssFn.apply( this, arguments ) :
9016                          this.animate( genFx( name, true ), speed, easing, callback );
9017          };
9018  });
9019  
9020  jQuery.fn.extend({
9021          fadeTo: function( speed, to, easing, callback ) {
9022  
9023                  // show any hidden elements after setting opacity to 0
9024                  return this.filter( isHidden ).css( "opacity", 0 ).show()
9025  
9026                          // animate to the value specified
9027                          .end().animate({ opacity: to }, speed, easing, callback );
9028          },
9029          animate: function( prop, speed, easing, callback ) {
9030                  var empty = jQuery.isEmptyObject( prop ),
9031                          optall = jQuery.speed( speed, easing, callback ),
9032                          doAnimation = function() {
9033                                  // Operate on a copy of prop so per-property easing won't be lost
9034                                  var anim = Animation( this, jQuery.extend( {}, prop ), optall );
9035  
9036                                  // Empty animations resolve immediately
9037                                  if ( empty ) {
9038                                          anim.stop( true );
9039                                  }
9040                          };
9041  
9042                  return empty || optall.queue === false ?
9043                          this.each( doAnimation ) :
9044                          this.queue( optall.queue, doAnimation );
9045          },
9046          stop: function( type, clearQueue, gotoEnd ) {
9047                  var stopQueue = function( hooks ) {
9048                          var stop = hooks.stop;
9049                          delete hooks.stop;
9050                          stop( gotoEnd );
9051                  };
9052  
9053                  if ( typeof type !== "string" ) {
9054                          gotoEnd = clearQueue;
9055                          clearQueue = type;
9056                          type = undefined;
9057                  }
9058                  if ( clearQueue && type !== false ) {
9059                          this.queue( type || "fx", [] );
9060                  }
9061  
9062                  return this.each(function() {
9063                          var dequeue = true,
9064                                  index = type != null && type + "queueHooks",
9065                                  timers = jQuery.timers,
9066                                  data = jQuery._data( this );
9067  
9068                          if ( index ) {
9069                                  if ( data[ index ] && data[ index ].stop ) {
9070                                          stopQueue( data[ index ] );
9071                                  }
9072                          } else {
9073                                  for ( index in data ) {
9074                                          if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
9075                                                  stopQueue( data[ index ] );
9076                                          }
9077                                  }
9078                          }
9079  
9080                          for ( index = timers.length; index--; ) {
9081                                  if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {
9082                                          timers[ index ].anim.stop( gotoEnd );
9083                                          dequeue = false;
9084                                          timers.splice( index, 1 );
9085                                  }
9086                          }
9087  
9088                          // start the next in the queue if the last step wasn't forced
9089                          // timers currently will call their complete callbacks, which will dequeue
9090                          // but only if they were gotoEnd
9091                          if ( dequeue || !gotoEnd ) {
9092                                  jQuery.dequeue( this, type );
9093                          }
9094                  });
9095          }
9096  });
9097  
9098  // Generate parameters to create a standard animation
9099  function genFx( type, includeWidth ) {
9100          var which,
9101                  attrs = { height: type },
9102                  i = 0;
9103  
9104          // if we include width, step value is 1 to do all cssExpand values,
9105          // if we don't include width, step value is 2 to skip over Left and Right
9106          includeWidth = includeWidth? 1 : 0;
9107          for( ; i < 4 ; i += 2 - includeWidth ) {
9108                  which = cssExpand[ i ];
9109                  attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
9110          }
9111  
9112          if ( includeWidth ) {
9113                  attrs.opacity = attrs.width = type;
9114          }
9115  
9116          return attrs;
9117  }
9118  
9119  // Generate shortcuts for custom animations
9120  jQuery.each({
9121          slideDown: genFx("show"),
9122          slideUp: genFx("hide"),
9123          slideToggle: genFx("toggle"),
9124          fadeIn: { opacity: "show" },
9125          fadeOut: { opacity: "hide" },
9126          fadeToggle: { opacity: "toggle" }
9127  }, function( name, props ) {
9128          jQuery.fn[ name ] = function( speed, easing, callback ) {
9129                  return this.animate( props, speed, easing, callback );
9130          };
9131  });
9132  
9133  jQuery.speed = function( speed, easing, fn ) {
9134          var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
9135                  complete: fn || !fn && easing ||
9136                          jQuery.isFunction( speed ) && speed,
9137                  duration: speed,
9138                  easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
9139          };
9140  
9141          opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
9142                  opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
9143  
9144          // normalize opt.queue - true/undefined/null -> "fx"
9145          if ( opt.queue == null || opt.queue === true ) {
9146                  opt.queue = "fx";
9147          }
9148  
9149          // Queueing
9150          opt.old = opt.complete;
9151  
9152          opt.complete = function() {
9153                  if ( jQuery.isFunction( opt.old ) ) {
9154                          opt.old.call( this );
9155                  }
9156  
9157                  if ( opt.queue ) {
9158                          jQuery.dequeue( this, opt.queue );
9159                  }
9160          };
9161  
9162          return opt;
9163  };
9164  
9165  jQuery.easing = {
9166          linear: function( p ) {
9167                  return p;
9168          },
9169          swing: function( p ) {
9170                  return 0.5 - Math.cos( p*Math.PI ) / 2;
9171          }
9172  };
9173  
9174  jQuery.timers = [];
9175  jQuery.fx = Tween.prototype.init;
9176  jQuery.fx.tick = function() {
9177          var timer,
9178                  timers = jQuery.timers,
9179                  i = 0;
9180  
9181          fxNow = jQuery.now();
9182  
9183          for ( ; i < timers.length; i++ ) {
9184                  timer = timers[ i ];
9185                  // Checks the timer has not already been removed
9186                  if ( !timer() && timers[ i ] === timer ) {
9187                          timers.splice( i--, 1 );
9188                  }
9189          }
9190  
9191          if ( !timers.length ) {
9192                  jQuery.fx.stop();
9193          }
9194          fxNow = undefined;
9195  };
9196  
9197  jQuery.fx.timer = function( timer ) {
9198          if ( timer() && jQuery.timers.push( timer ) && !timerId ) {
9199                  timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );
9200          }
9201  };
9202  
9203  jQuery.fx.interval = 13;
9204  
9205  jQuery.fx.stop = function() {
9206          clearInterval( timerId );
9207          timerId = null;
9208  };
9209  
9210  jQuery.fx.speeds = {
9211          slow: 600,
9212          fast: 200,
9213          // Default speed
9214          _default: 400
9215  };
9216  
9217  // Back Compat <1.8 extension point
9218  jQuery.fx.step = {};
9219  
9220  if ( jQuery.expr && jQuery.expr.filters ) {
9221          jQuery.expr.filters.animated = function( elem ) {
9222                  return jQuery.grep(jQuery.timers, function( fn ) {
9223                          return elem === fn.elem;
9224                  }).length;
9225          };
9226  }
9227  var rroot = /^(?:body|html)$/i;
9228  
9229  jQuery.fn.offset = function( options ) {
9230          if ( arguments.length ) {
9231                  return options === undefined ?
9232                          this :
9233                          this.each(function( i ) {
9234                                  jQuery.offset.setOffset( this, options, i );
9235                          });
9236          }
9237  
9238          var docElem, body, win, clientTop, clientLeft, scrollTop, scrollLeft,
9239                  box = { top: 0, left: 0 },
9240                  elem = this[ 0 ],
9241                  doc = elem && elem.ownerDocument;
9242  
9243          if ( !doc ) {
9244                  return;
9245          }
9246  
9247          if ( (body = doc.body) === elem ) {
9248                  return jQuery.offset.bodyOffset( elem );
9249          }
9250  
9251          docElem = doc.documentElement;
9252  
9253          // Make sure it's not a disconnected DOM node
9254          if ( !jQuery.contains( docElem, elem ) ) {
9255                  return box;
9256          }
9257  
9258          // If we don't have gBCR, just use 0,0 rather than error
9259          // BlackBerry 5, iOS 3 (original iPhone)
9260          if ( typeof elem.getBoundingClientRect !== "undefined" ) {
9261                  box = elem.getBoundingClientRect();
9262          }
9263          win = getWindow( doc );
9264          clientTop  = docElem.clientTop  || body.clientTop  || 0;
9265          clientLeft = docElem.clientLeft || body.clientLeft || 0;
9266          scrollTop  = win.pageYOffset || docElem.scrollTop;
9267          scrollLeft = win.pageXOffset || docElem.scrollLeft;
9268          return {
9269                  top: box.top  + scrollTop  - clientTop,
9270                  left: box.left + scrollLeft - clientLeft
9271          };
9272  };
9273  
9274  jQuery.offset = {
9275  
9276          bodyOffset: function( body ) {
9277                  var top = body.offsetTop,
9278                          left = body.offsetLeft;
9279  
9280                  if ( jQuery.support.doesNotIncludeMarginInBodyOffset ) {
9281                          top  += parseFloat( jQuery.css(body, "marginTop") ) || 0;
9282                          left += parseFloat( jQuery.css(body, "marginLeft") ) || 0;
9283                  }
9284  
9285                  return { top: top, left: left };
9286          },
9287  
9288          setOffset: function( elem, options, i ) {
9289                  var position = jQuery.css( elem, "position" );
9290  
9291                  // set position first, in-case top/left are set even on static elem
9292                  if ( position === "static" ) {
9293                          elem.style.position = "relative";
9294                  }
9295  
9296                  var curElem = jQuery( elem ),
9297                          curOffset = curElem.offset(),
9298                          curCSSTop = jQuery.css( elem, "top" ),
9299                          curCSSLeft = jQuery.css( elem, "left" ),
9300                          calculatePosition = ( position === "absolute" || position === "fixed" ) && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1,
9301                          props = {}, curPosition = {}, curTop, curLeft;
9302  
9303                  // need to be able to calculate position if either top or left is auto and position is either absolute or fixed
9304                  if ( calculatePosition ) {
9305                          curPosition = curElem.position();
9306                          curTop = curPosition.top;
9307                          curLeft = curPosition.left;
9308                  } else {
9309                          curTop = parseFloat( curCSSTop ) || 0;
9310                          curLeft = parseFloat( curCSSLeft ) || 0;
9311                  }
9312  
9313                  if ( jQuery.isFunction( options ) ) {
9314                          options = options.call( elem, i, curOffset );
9315                  }
9316  
9317                  if ( options.top != null ) {
9318                          props.top = ( options.top - curOffset.top ) + curTop;
9319                  }
9320                  if ( options.left != null ) {
9321                          props.left = ( options.left - curOffset.left ) + curLeft;
9322                  }
9323  
9324                  if ( "using" in options ) {
9325                          options.using.call( elem, props );
9326                  } else {
9327                          curElem.css( props );
9328                  }
9329          }
9330  };
9331  
9332  
9333  jQuery.fn.extend({
9334  
9335          position: function() {
9336                  if ( !this[0] ) {
9337                          return;
9338                  }
9339  
9340                  var elem = this[0],
9341  
9342                  // Get *real* offsetParent
9343                  offsetParent = this.offsetParent(),
9344  
9345                  // Get correct offsets
9346                  offset       = this.offset(),
9347                  parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();
9348  
9349                  // Subtract element margins
9350                  // note: when an element has margin: auto the offsetLeft and marginLeft
9351                  // are the same in Safari causing offset.left to incorrectly be 0
9352                  offset.top  -= parseFloat( jQuery.css(elem, "marginTop") ) || 0;
9353                  offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0;
9354  
9355                  // Add offsetParent borders
9356                  parentOffset.top  += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0;
9357                  parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0;
9358  
9359                  // Subtract the two offsets
9360                  return {
9361                          top:  offset.top  - parentOffset.top,
9362                          left: offset.left - parentOffset.left
9363                  };
9364          },
9365  
9366          offsetParent: function() {
9367                  return this.map(function() {
9368                          var offsetParent = this.offsetParent || document.body;
9369                          while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) {
9370                                  offsetParent = offsetParent.offsetParent;
9371                          }
9372                          return offsetParent || document.body;
9373                  });
9374          }
9375  });
9376  
9377  
9378  // Create scrollLeft and scrollTop methods
9379  jQuery.each( {scrollLeft: "pageXOffset", scrollTop: "pageYOffset"}, function( method, prop ) {
9380          var top = /Y/.test( prop );
9381  
9382          jQuery.fn[ method ] = function( val ) {
9383                  return jQuery.access( this, function( elem, method, val ) {
9384                          var win = getWindow( elem );
9385  
9386                          if ( val === undefined ) {
9387                                  return win ? (prop in win) ? win[ prop ] :
9388                                          win.document.documentElement[ method ] :
9389                                          elem[ method ];
9390                          }
9391  
9392                          if ( win ) {
9393                                  win.scrollTo(
9394                                          !top ? val : jQuery( win ).scrollLeft(),
9395                                           top ? val : jQuery( win ).scrollTop()
9396                                  );
9397  
9398                          } else {
9399                                  elem[ method ] = val;
9400                          }
9401                  }, method, val, arguments.length, null );
9402          };
9403  });
9404  
9405  function getWindow( elem ) {
9406          return jQuery.isWindow( elem ) ?
9407                  elem :
9408                  elem.nodeType === 9 ?
9409                          elem.defaultView || elem.parentWindow :
9410                          false;
9411  }
9412  // Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
9413  jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
9414          jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) {
9415                  // margin is only for outerHeight, outerWidth
9416                  jQuery.fn[ funcName ] = function( margin, value ) {
9417                          var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
9418                                  extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
9419  
9420                          return jQuery.access( this, function( elem, type, value ) {
9421                                  var doc;
9422  
9423                                  if ( jQuery.isWindow( elem ) ) {
9424                                          // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there
9425                                          // isn't a whole lot we can do. See pull request at this URL for discussion:
9426                                          // https://github.com/jquery/jquery/pull/764
9427                                          return elem.document.documentElement[ "client" + name ];
9428                                  }
9429  
9430                                  // Get document width or height
9431                                  if ( elem.nodeType === 9 ) {
9432                                          doc = elem.documentElement;
9433  
9434                                          // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], whichever is greatest
9435                                          // unfortunately, this causes bug #3838 in IE6/8 only, but there is currently no good, small way to fix it.
9436                                          return Math.max(
9437                                                  elem.body[ "scroll" + name ], doc[ "scroll" + name ],
9438                                                  elem.body[ "offset" + name ], doc[ "offset" + name ],
9439                                                  doc[ "client" + name ]
9440                                          );
9441                                  }
9442  
9443                                  return value === undefined ?
9444                                          // Get width or height on the element, requesting but not forcing parseFloat
9445                                          jQuery.css( elem, type, value, extra ) :
9446  
9447                                          // Set width or height on the element
9448                                          jQuery.style( elem, type, value, extra );
9449                          }, type, chainable ? margin : undefined, chainable, null );
9450                  };
9451          });
9452  });
9453  // Expose jQuery to the global object
9454  window.jQuery = window.$ = jQuery;
9455  
9456  // Expose jQuery as an AMD module, but only for AMD loaders that
9457  // understand the issues with loading multiple versions of jQuery
9458  // in a page that all might call define(). The loader will indicate
9459  // they have special allowances for multiple jQuery versions by
9460  // specifying define.amd.jQuery = true. Register as a named module,
9461  // since jQuery can be concatenated with other files that may use define,
9462  // but not use a proper concatenation script that understands anonymous
9463  // AMD modules. A named AMD is safest and most robust way to register.
9464  // Lowercase jquery is used because AMD module names are derived from
9465  // file names, and jQuery is normally delivered in a lowercase file name.
9466  // Do this after creating the global so that if an AMD module wants to call
9467  // noConflict to hide this version of jQuery, it will work.
9468  if ( typeof define === "function" && define.amd && define.amd.jQuery ) {
9469          define( "jquery", [], function () { return jQuery; } );
9470  }
9471  
9472  })( window );
1 /*! 2 * jQuery JavaScript Library v1.8.3 3 * http://jquery.com/ 4 * 5 * Includes Sizzle.js 6 * http://sizzlejs.com/ 7 * 8 * Copyright 2012 jQuery Foundation and other contributors 9 * Released under the MIT license 10 * http://jquery.org/license 11 * 12 * Date: Tue Nov 13 2012 08:20:33 GMT-0500 (Eastern Standard Time) 13 */ 14 (function( window, undefined ) { 15 var 16 // A central reference to the root jQuery(document) 17 rootjQuery, 18 19 // The deferred used on DOM ready 20 readyList, 21 22 // Use the correct document accordingly with window argument (sandbox) 23 document = window.document, 24 location = window.location, 25 navigator = window.navigator, 26 27 // Map over jQuery in case of overwrite 28 _jQuery = window.jQuery, 29 30 // Map over the $ in case of overwrite 31 _$ = window.$, 32 33 // Save a reference to some core methods 34 core_push = Array.prototype.push, 35 core_slice = Array.prototype.slice, 36 core_indexOf = Array.prototype.indexOf, 37 core_toString = Object.prototype.toString, 38 core_hasOwn = Object.prototype.hasOwnProperty, 39 core_trim = String.prototype.trim, 40 41 // Define a local copy of jQuery 42 jQuery = function( selector, context ) { 43 // The jQuery object is actually just the init constructor 'enhanced' 44 return new jQuery.fn.init( selector, context, rootjQuery ); 45 }, 46 47 // Used for matching numbers 48 core_pnum = /[\-+]?(?:\d*\.|)\d+(?:[eE][\-+]?\d+|)/.source, 49 50 // Used for detecting and trimming whitespace 51 core_rnotwhite = /\S/, 52 core_rspace = /\s+/, 53 54 // Make sure we trim BOM and NBSP (here's looking at you, Safari 5.0 and IE) 55 rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, 56 57 // A simple way to check for HTML strings 58 // Prioritize #id over <tag> to avoid XSS via location.hash (#9521) 59 rquickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/, 60 61 // Match a standalone tag 62 rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>|)$/, 63 64 // JSON RegExp 65 rvalidchars = /^[\],:{}\s]*$/, 66 rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, 67 rvalidescape = /\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g, 68 rvalidtokens = /"[^"\\\r\n]*"|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g, 69 70 // Matches dashed string for camelizing 71 rmsPrefix = /^-ms-/, 72 rdashAlpha = /-([\da-z])/gi, 73 74 // Used by jQuery.camelCase as callback to replace() 75 fcamelCase = function( all, letter ) { 76 return ( letter + "" ).toUpperCase(); 77 }, 78 79 // The ready event handler and self cleanup method 80 DOMContentLoaded = function() { 81 if ( document.addEventListener ) { 82 document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false ); 83 jQuery.ready(); 84 } else if ( document.readyState === "complete" ) { 85 // we're here because readyState === "complete" in oldIE 86 // which is good enough for us to call the dom ready! 87 document.detachEvent( "onreadystatechange", DOMContentLoaded ); 88 jQuery.ready(); 89 } 90 }, 91 92 // [[Class]] -> type pairs 93 class2type = {}; 94 95 jQuery.fn = jQuery.prototype = { 96 constructor: jQuery, 97 init: function( selector, context, rootjQuery ) { 98 var match, elem, ret, doc; 99 100 // Handle $(""), $(null), $(undefined), $(false) 101 if ( !selector ) { 102 return this; 103 } 104 105 // Handle $(DOMElement) 106 if ( selector.nodeType ) { 107 this.context = this[0] = selector; 108 this.length = 1; 109 return this; 110 } 111 112 // Handle HTML strings 113 if ( typeof selector === "string" ) { 114 if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { 115 // Assume that strings that start and end with <> are HTML and skip the regex check 116 match = [ null, selector, null ]; 117 118 } else { 119 match = rquickExpr.exec( selector ); 120 } 121 122 // Match html or make sure no context is specified for #id 123 if ( match && (match[1] || !context) ) { 124 125 // HANDLE: $(html) -> $(array) 126 if ( match[1] ) { 127 context = context instanceof jQuery ? context[0] : context; 128 doc = ( context && context.nodeType ? context.ownerDocument || context : document ); 129 130 // scripts is true for back-compat 131 selector = jQuery.parseHTML( match[1], doc, true ); 132 if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) { 133 this.attr.call( selector, context, true ); 134 } 135 136 return jQuery.merge( this, selector ); 137 138 // HANDLE: $(#id) 139 } else { 140 elem = document.getElementById( match[2] ); 141 142 // Check parentNode to catch when Blackberry 4.6 returns 143 // nodes that are no longer in the document #6963 144 if ( elem && elem.parentNode ) { 145 // Handle the case where IE and Opera return items 146 // by name instead of ID 147 if ( elem.id !== match[2] ) { 148 return rootjQuery.find( selector ); 149 } 150 151 // Otherwise, we inject the element directly into the jQuery object 152 this.length = 1; 153 this[0] = elem; 154 } 155 156 this.context = document; 157 this.selector = selector; 158 return this; 159 } 160 161 // HANDLE: $(expr, $(...)) 162 } else if ( !context || context.jquery ) { 163 return ( context || rootjQuery ).find( selector ); 164 165 // HANDLE: $(expr, context) 166 // (which is just equivalent to: $(context).find(expr) 167 } else { 168 return this.constructor( context ).find( selector ); 169 } 170 171 // HANDLE: $(function) 172 // Shortcut for document ready 173 } else if ( jQuery.isFunction( selector ) ) { 174 return rootjQuery.ready( selector ); 175 } 176 177 if ( selector.selector !== undefined ) { 178 this.selector = selector.selector; 179 this.context = selector.context; 180 } 181 182 return jQuery.makeArray( selector, this ); 183 }, 184 185 // Start with an empty selector 186 selector: "", 187 188 // The current version of jQuery being used 189 jquery: "1.8.3", 190 191 // The default length of a jQuery object is 0 192 length: 0, 193 194 // The number of elements contained in the matched element set 195 size: function() { 196 return this.length; 197 }, 198 199 toArray: function() { 200 return core_slice.call( this ); 201 }, 202 203 // Get the Nth element in the matched element set OR 204 // Get the whole matched element set as a clean array 205 get: function( num ) { 206 return num == null ? 207 208 // Return a 'clean' array 209 this.toArray() : 210 211 // Return just the object 212 ( num < 0 ? this[ this.length + num ] : this[ num ] ); 213 }, 214 215 // Take an array of elements and push it onto the stack 216 // (returning the new matched element set) 217 pushStack: function( elems, name, selector ) { 218 219 // Build a new jQuery matched element set 220 var ret = jQuery.merge( this.constructor(), elems ); 221 222 // Add the old object onto the stack (as a reference) 223 ret.prevObject = this; 224 225 ret.context = this.context; 226 227 if ( name === "find" ) { 228 ret.selector = this.selector + ( this.selector ? " " : "" ) + selector; 229 } else if ( name ) { 230 ret.selector = this.selector + "." + name + "(" + selector + ")"; 231 } 232 233 // Return the newly-formed element set 234 return ret; 235 }, 236 237 // Execute a callback for every element in the matched set. 238 // (You can seed the arguments with an array of args, but this is 239 // only used internally.) 240 each: function( callback, args ) { 241 return jQuery.each( this, callback, args ); 242 }, 243 244 ready: function( fn ) { 245 // Add the callback 246 jQuery.ready.promise().done( fn ); 247 248 return this; 249 }, 250 251 eq: function( i ) { 252 i = +i; 253 return i === -1 ? 254 this.slice( i ) : 255 this.slice( i, i + 1 ); 256 }, 257 258 first: function() { 259 return this.eq( 0 ); 260 }, 261 262 last: function() { 263 return this.eq( -1 ); 264 }, 265 266 slice: function() { 267 return this.pushStack( core_slice.apply( this, arguments ), 268 "slice", core_slice.call(arguments).join(",") ); 269 }, 270 271 map: function( callback ) { 272 return this.pushStack( jQuery.map(this, function( elem, i ) { 273 return callback.call( elem, i, elem ); 274 })); 275 }, 276 277 end: function() { 278 return this.prevObject || this.constructor(null); 279 }, 280 281 // For internal use only. 282 // Behaves like an Array's method, not like a jQuery method. 283 push: core_push, 284 sort: [].sort, 285 splice: [].splice 286 }; 287 288 // Give the init function the jQuery prototype for later instantiation 289 jQuery.fn.init.prototype = jQuery.fn; 290 291 jQuery.extend = jQuery.fn.extend = function() { 292 var options, name, src, copy, copyIsArray, clone, 293 target = arguments[0] || {}, 294 i = 1, 295 length = arguments.length, 296 deep = false; 297 298 // Handle a deep copy situation 299 if ( typeof target === "boolean" ) { 300 deep = target; 301 target = arguments[1] || {}; 302 // skip the boolean and the target 303 i = 2; 304 } 305 306 // Handle case when target is a string or something (possible in deep copy) 307 if ( typeof target !== "object" && !jQuery.isFunction(target) ) { 308 target = {}; 309 } 310 311 // extend jQuery itself if only one argument is passed 312 if ( length === i ) { 313 target = this; 314 --i; 315 } 316 317 for ( ; i < length; i++ ) { 318 // Only deal with non-null/undefined values 319 if ( (options = arguments[ i ]) != null ) { 320 // Extend the base object 321 for ( name in options ) { 322 src = target[ name ]; 323 copy = options[ name ]; 324 325 // Prevent never-ending loop 326 if ( target === copy ) { 327 continue; 328 } 329 330 // Recurse if we're merging plain objects or arrays 331 if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { 332 if ( copyIsArray ) { 333 copyIsArray = false; 334 clone = src && jQuery.isArray(src) ? src : []; 335 336 } else { 337 clone = src && jQuery.isPlainObject(src) ? src : {}; 338 } 339 340 // Never move original objects, clone them 341 target[ name ] = jQuery.extend( deep, clone, copy ); 342 343 // Don't bring in undefined values 344 } else if ( copy !== undefined ) { 345 target[ name ] = copy; 346 } 347 } 348 } 349 } 350 351 // Return the modified object 352 return target; 353 }; 354 355 jQuery.extend({ 356 noConflict: function( deep ) { 357 if ( window.$ === jQuery ) { 358 window.$ = _$; 359 } 360 361 if ( deep && window.jQuery === jQuery ) { 362 window.jQuery = _jQuery; 363 } 364 365 return jQuery; 366 }, 367 368 // Is the DOM ready to be used? Set to true once it occurs. 369 isReady: false, 370 371 // A counter to track how many items to wait for before 372 // the ready event fires. See #6781 373 readyWait: 1, 374 375 // Hold (or release) the ready event 376 holdReady: function( hold ) { 377 if ( hold ) { 378 jQuery.readyWait++; 379 } else { 380 jQuery.ready( true ); 381 } 382 }, 383 384 // Handle when the DOM is ready 385 ready: function( wait ) { 386 387 // Abort if there are pending holds or we're already ready 388 if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { 389 return; 390 } 391 392 // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). 393 if ( !document.body ) { 394 return setTimeout( jQuery.ready, 1 ); 395 } 396 397 // Remember that the DOM is ready 398 jQuery.isReady = true; 399 400 // If a normal DOM Ready event fired, decrement, and wait if need be 401 if ( wait !== true && --jQuery.readyWait > 0 ) { 402 return; 403 } 404 405 // If there are functions bound, to execute 406 readyList.resolveWith( document, [ jQuery ] ); 407 408 // Trigger any bound ready events 409 if ( jQuery.fn.trigger ) { 410 jQuery( document ).trigger("ready").off("ready"); 411 } 412 }, 413 414 // See test/unit/core.js for details concerning isFunction. 415 // Since version 1.3, DOM methods and functions like alert 416 // aren't supported. They return false on IE (#2968). 417 isFunction: function( obj ) { 418 return jQuery.type(obj) === "function"; 419 }, 420 421 isArray: Array.isArray || function( obj ) { 422 return jQuery.type(obj) === "array"; 423 }, 424 425 isWindow: function( obj ) { 426 return obj != null && obj == obj.window; 427 }, 428 429 isNumeric: function( obj ) { 430 return !isNaN( parseFloat(obj) ) && isFinite( obj ); 431 }, 432 433 type: function( obj ) { 434 return obj == null ? 435 String( obj ) : 436 class2type[ core_toString.call(obj) ] || "object"; 437 }, 438 439 isPlainObject: function( obj ) { 440 // Must be an Object. 441 // Because of IE, we also have to check the presence of the constructor property. 442 // Make sure that DOM nodes and window objects don't pass through, as well 443 if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { 444 return false; 445 } 446 447 try { 448 // Not own constructor property must be Object 449 if ( obj.constructor && 450 !core_hasOwn.call(obj, "constructor") && 451 !core_hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { 452 return false; 453 } 454 } catch ( e ) { 455 // IE8,9 Will throw exceptions on certain host objects #9897 456 return false; 457 } 458 459 // Own properties are enumerated firstly, so to speed up, 460 // if last one is own, then all properties are own. 461 462 var key; 463 for ( key in obj ) {} 464 465 return key === undefined || core_hasOwn.call( obj, key ); 466 }, 467 468 isEmptyObject: function( obj ) { 469 var name; 470 for ( name in obj ) { 471 return false; 472 } 473 return true; 474 }, 475 476 error: function( msg ) { 477 throw new Error( msg ); 478 }, 479 480 // data: string of html 481 // context (optional): If specified, the fragment will be created in this context, defaults to document 482 // scripts (optional): If true, will include scripts passed in the html string 483 parseHTML: function( data, context, scripts ) { 484 var parsed; 485 if ( !data || typeof data !== "string" ) { 486 return null; 487 } 488 if ( typeof context === "boolean" ) { 489 scripts = context; 490 context = 0; 491 } 492 context = context || document; 493 494 // Single tag 495 if ( (parsed = rsingleTag.exec( data )) ) { 496 return [ context.createElement( parsed[1] ) ]; 497 } 498 499 parsed = jQuery.buildFragment( [ data ], context, scripts ? null : [] ); 500 return jQuery.merge( [], 501 (parsed.cacheable ? jQuery.clone( parsed.fragment ) : parsed.fragment).childNodes ); 502 }, 503 504 parseJSON: function( data ) { 505 if ( !data || typeof data !== "string") { 506 return null; 507 } 508 509 // Make sure leading/trailing whitespace is removed (IE can't handle it) 510 data = jQuery.trim( data ); 511 512 // Attempt to parse using the native JSON parser first 513 if ( window.JSON && window.JSON.parse ) { 514 return window.JSON.parse( data ); 515 } 516 517 // Make sure the incoming data is actual JSON 518 // Logic borrowed from http://json.org/json2.js 519 if ( rvalidchars.test( data.replace( rvalidescape, "@" ) 520 .replace( rvalidtokens, "]" ) 521 .replace( rvalidbraces, "")) ) { 522 523 return ( new Function( "return " + data ) )(); 524 525 } 526 jQuery.error( "Invalid JSON: " + data ); 527 }, 528 529 // Cross-browser xml parsing 530 parseXML: function( data ) { 531 var xml, tmp; 532 if ( !data || typeof data !== "string" ) { 533 return null; 534 } 535 try { 536 if ( window.DOMParser ) { // Standard 537 tmp = new DOMParser(); 538 xml = tmp.parseFromString( data , "text/xml" ); 539 } else { // IE 540 xml = new ActiveXObject( "Microsoft.XMLDOM" ); 541 xml.async = "false"; 542 xml.loadXML( data ); 543 } 544 } catch( e ) { 545 xml = undefined; 546 } 547 if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) { 548 jQuery.error( "Invalid XML: " + data ); 549 } 550 return xml; 551 }, 552 553 noop: function() {}, 554 555 // Evaluates a script in a global context 556 // Workarounds based on findings by Jim Driscoll 557 // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context 558 globalEval: function( data ) { 559 if ( data && core_rnotwhite.test( data ) ) { 560 // We use execScript on Internet Explorer 561 // We use an anonymous function so that context is window 562 // rather than jQuery in Firefox 563 ( window.execScript || function( data ) { 564 window[ "eval" ].call( window, data ); 565 } )( data ); 566 } 567 }, 568 569 // Convert dashed to camelCase; used by the css and data modules 570 // Microsoft forgot to hump their vendor prefix (#9572) 571 camelCase: function( string ) { 572 return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); 573 }, 574 575 nodeName: function( elem, name ) { 576 return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); 577 }, 578 579 // args is for internal usage only 580 each: function( obj, callback, args ) { 581 var name, 582 i = 0, 583 length = obj.length, 584 isObj = length === undefined || jQuery.isFunction( obj ); 585 586 if ( args ) { 587 if ( isObj ) { 588 for ( name in obj ) { 589 if ( callback.apply( obj[ name ], args ) === false ) { 590 break; 591 } 592 } 593 } else { 594 for ( ; i < length; ) { 595 if ( callback.apply( obj[ i++ ], args ) === false ) { 596 break; 597 } 598 } 599 } 600 601 // A special, fast, case for the most common use of each 602 } else { 603 if ( isObj ) { 604 for ( name in obj ) { 605 if ( callback.call( obj[ name ], name, obj[ name ] ) === false ) { 606 break; 607 } 608 } 609 } else { 610 for ( ; i < length; ) { 611 if ( callback.call( obj[ i ], i, obj[ i++ ] ) === false ) { 612 break; 613 } 614 } 615 } 616 } 617 618 return obj; 619 }, 620 621 // Use native String.trim function wherever possible 622 trim: core_trim && !core_trim.call("\uFEFF\xA0") ? 623 function( text ) { 624 return text == null ? 625 "" : 626 core_trim.call( text ); 627 } : 628 629 // Otherwise use our own trimming functionality 630 function( text ) { 631 return text == null ? 632 "" : 633 ( text + "" ).replace( rtrim, "" ); 634 }, 635 636 // results is for internal usage only 637 makeArray: function( arr, results ) { 638 var type, 639 ret = results || []; 640 641 if ( arr != null ) { 642 // The window, strings (and functions) also have 'length' 643 // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930 644 type = jQuery.type( arr ); 645 646 if ( arr.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( arr ) ) { 647 core_push.call( ret, arr ); 648 } else { 649 jQuery.merge( ret, arr ); 650 } 651 } 652 653 return ret; 654 }, 655 656 inArray: function( elem, arr, i ) { 657 var len; 658 659 if ( arr ) { 660 if ( core_indexOf ) { 661 return core_indexOf.call( arr, elem, i ); 662 } 663 664 len = arr.length; 665 i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; 666 667 for ( ; i < len; i++ ) { 668 // Skip accessing in sparse arrays 669 if ( i in arr && arr[ i ] === elem ) { 670 return i; 671 } 672 } 673 } 674 675 return -1; 676 }, 677 678 merge: function( first, second ) { 679 var l = second.length, 680 i = first.length, 681 j = 0; 682 683 if ( typeof l === "number" ) { 684 for ( ; j < l; j++ ) { 685 first[ i++ ] = second[ j ]; 686 } 687 688 } else { 689 while ( second[j] !== undefined ) { 690 first[ i++ ] = second[ j++ ]; 691 } 692 } 693 694 first.length = i; 695 696 return first; 697 }, 698 699 grep: function( elems, callback, inv ) { 700 var retVal, 701 ret = [], 702 i = 0, 703 length = elems.length; 704 inv = !!inv; 705 706 // Go through the array, only saving the items 707 // that pass the validator function 708 for ( ; i < length; i++ ) { 709 retVal = !!callback( elems[ i ], i ); 710 if ( inv !== retVal ) { 711 ret.push( elems[ i ] ); 712 } 713 } 714 715 return ret; 716 }, 717 718 // arg is for internal usage only 719 map: function( elems, callback, arg ) { 720 var value, key, 721 ret = [], 722 i = 0, 723 length = elems.length, 724 // jquery objects are treated as arrays 725 isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ; 726 727 // Go through the array, translating each of the items to their 728 if ( isArray ) { 729 for ( ; i < length; i++ ) { 730 value = callback( elems[ i ], i, arg ); 731 732 if ( value != null ) { 733 ret[ ret.length ] = value; 734 } 735 } 736 737 // Go through every key on the object, 738 } else { 739 for ( key in elems ) { 740 value = callback( elems[ key ], key, arg ); 741 742 if ( value != null ) { 743 ret[ ret.length ] = value; 744 } 745 } 746 } 747 748 // Flatten any nested arrays 749 return ret.concat.apply( [], ret ); 750 }, 751 752 // A global GUID counter for objects 753 guid: 1, 754 755 // Bind a function to a context, optionally partially applying any 756 // arguments. 757 proxy: function( fn, context ) { 758 var tmp, args, proxy; 759 760 if ( typeof context === "string" ) { 761 tmp = fn[ context ]; 762 context = fn; 763 fn = tmp; 764 } 765 766 // Quick check to determine if target is callable, in the spec 767 // this throws a TypeError, but we will just return undefined. 768 if ( !jQuery.isFunction( fn ) ) { 769 return undefined; 770 } 771 772 // Simulated bind 773 args = core_slice.call( arguments, 2 ); 774 proxy = function() { 775 return fn.apply( context, args.concat( core_slice.call( arguments ) ) ); 776 }; 777 778 // Set the guid of unique handler to the same of original handler, so it can be removed 779 proxy.guid = fn.guid = fn.guid || jQuery.guid++; 780 781 return proxy; 782 }, 783 784 // Multifunctional method to get and set values of a collection 785 // The value/s can optionally be executed if it's a function 786 access: function( elems, fn, key, value, chainable, emptyGet, pass ) { 787 var exec, 788 bulk = key == null, 789 i = 0, 790 length = elems.length; 791 792 // Sets many values 793 if ( key && typeof key === "object" ) { 794 for ( i in key ) { 795 jQuery.access( elems, fn, i, key[i], 1, emptyGet, value ); 796 } 797 chainable = 1; 798 799 // Sets one value 800 } else if ( value !== undefined ) { 801 // Optionally, function values get executed if exec is true 802 exec = pass === undefined && jQuery.isFunction( value ); 803 804 if ( bulk ) { 805 // Bulk operations only iterate when executing function values 806 if ( exec ) { 807 exec = fn; 808 fn = function( elem, key, value ) { 809 return exec.call( jQuery( elem ), value ); 810 }; 811 812 // Otherwise they run against the entire set 813 } else { 814 fn.call( elems, value ); 815 fn = null; 816 } 817 } 818 819 if ( fn ) { 820 for (; i < length; i++ ) { 821 fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass ); 822 } 823 } 824 825 chainable = 1; 826 } 827 828 return chainable ? 829 elems : 830 831 // Gets 832 bulk ? 833 fn.call( elems ) : 834 length ? fn( elems[0], key ) : emptyGet; 835 }, 836 837 now: function() { 838 return ( new Date() ).getTime(); 839 } 840 }); 841 842 jQuery.ready.promise = function( obj ) { 843 if ( !readyList ) { 844 845 readyList = jQuery.Deferred(); 846 847 // Catch cases where $(document).ready() is called after the browser event has already occurred. 848 // we once tried to use readyState "interactive" here, but it caused issues like the one 849 // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15 850 if ( document.readyState === "complete" ) { 851 // Handle it asynchronously to allow scripts the opportunity to delay ready 852 setTimeout( jQuery.ready, 1 ); 853 854 // Standards-based browsers support DOMContentLoaded 855 } else if ( document.addEventListener ) { 856 // Use the handy event callback 857 document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false ); 858 859 // A fallback to window.onload, that will always work 860 window.addEventListener( "load", jQuery.ready, false ); 861 862 // If IE event model is used 863 } else { 864 // Ensure firing before onload, maybe late but safe also for iframes 865 document.attachEvent( "onreadystatechange", DOMContentLoaded ); 866 867 // A fallback to window.onload, that will always work 868 window.attachEvent( "onload", jQuery.ready ); 869 870 // If IE and not a frame 871 // continually check to see if the document is ready 872 var top = false; 873 874 try { 875 top = window.frameElement == null && document.documentElement; 876 } catch(e) {} 877 878 if ( top && top.doScroll ) { 879 (function doScrollCheck() { 880 if ( !jQuery.isReady ) { 881 882 try { 883 // Use the trick by Diego Perini 884 // http://javascript.nwbox.com/IEContentLoaded/ 885 top.doScroll("left"); 886 } catch(e) { 887 return setTimeout( doScrollCheck, 50 ); 888 } 889 890 // and execute any waiting functions 891 jQuery.ready(); 892 } 893 })(); 894 } 895 } 896 } 897 return readyList.promise( obj ); 898 }; 899 900 // Populate the class2type map 901 jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) { 902 class2type[ "[object " + name + "]" ] = name.toLowerCase(); 903 }); 904 905 // All jQuery objects should point back to these 906 rootjQuery = jQuery(document); 907 // String to Object options format cache 908 var optionsCache = {}; 909 910 // Convert String-formatted options into Object-formatted ones and store in cache 911 function createOptions( options ) { 912 var object = optionsCache[ options ] = {}; 913 jQuery.each( options.split( core_rspace ), function( _, flag ) { 914 object[ flag ] = true; 915 }); 916 return object; 917 } 918 919 /* 920 * Create a callback list using the following parameters: 921 * 922 * options: an optional list of space-separated options that will change how 923 * the callback list behaves or a more traditional option object 924 * 925 * By default a callback list will act like an event callback list and can be 926 * "fired" multiple times. 927 * 928 * Possible options: 929 * 930 * once: will ensure the callback list can only be fired once (like a Deferred) 931 * 932 * memory: will keep track of previous values and will call any callback added 933 * after the list has been fired right away with the latest "memorized" 934 * values (like a Deferred) 935 * 936 * unique: will ensure a callback can only be added once (no duplicate in the list) 937 * 938 * stopOnFalse: interrupt callings when a callback returns false 939 * 940 */ 941 jQuery.Callbacks = function( options ) { 942 943 // Convert options from String-formatted to Object-formatted if needed 944 // (we check in cache first) 945 options = typeof options === "string" ? 946 ( optionsCache[ options ] || createOptions( options ) ) : 947 jQuery.extend( {}, options ); 948 949 var // Last fire value (for non-forgettable lists) 950 memory, 951 // Flag to know if list was already fired 952 fired, 953 // Flag to know if list is currently firing 954 firing, 955 // First callback to fire (used internally by add and fireWith) 956 firingStart, 957 // End of the loop when firing 958 firingLength, 959 // Index of currently firing callback (modified by remove if needed) 960 firingIndex, 961 // Actual callback list 962 list = [], 963 // Stack of fire calls for repeatable lists 964 stack = !options.once && [], 965 // Fire callbacks 966 fire = function( data ) { 967 memory = options.memory && data; 968 fired = true; 969 firingIndex = firingStart || 0; 970 firingStart = 0; 971 firingLength = list.length; 972 firing = true; 973 for ( ; list && firingIndex < firingLength; firingIndex++ ) { 974 if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) { 975 memory = false; // To prevent further calls using add 976 break; 977 } 978 } 979 firing = false; 980 if ( list ) { 981 if ( stack ) { 982 if ( stack.length ) { 983 fire( stack.shift() ); 984 } 985 } else if ( memory ) { 986 list = []; 987 } else { 988 self.disable(); 989 } 990 } 991 }, 992 // Actual Callbacks object 993 self = { 994 // Add a callback or a collection of callbacks to the list 995 add: function() { 996 if ( list ) { 997 // First, we save the current length 998 var start = list.length; 999 (function add( args ) { 1000 jQuery.each( args, function( _, arg ) { 1001 var type = jQuery.type( arg ); 1002 if ( type === "function" ) { 1003 if ( !options.unique || !self.has( arg ) ) { 1004 list.push( arg ); 1005 } 1006 } else if ( arg && arg.length && type !== "string" ) { 1007 // Inspect recursively 1008 add( arg ); 1009 } 1010 }); 1011 })( arguments ); 1012 // Do we need to add the callbacks to the 1013 // current firing batch? 1014 if ( firing ) { 1015 firingLength = list.length; 1016 // With memory, if we're not firing then 1017 // we should call right away 1018 } else if ( memory ) { 1019 firingStart = start; 1020 fire( memory ); 1021 } 1022 } 1023 return this; 1024 }, 1025 // Remove a callback from the list 1026 remove: function() { 1027 if ( list ) { 1028 jQuery.each( arguments, function( _, arg ) { 1029 var index; 1030 while( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { 1031 list.splice( index, 1 ); 1032 // Handle firing indexes 1033 if ( firing ) { 1034 if ( index <= firingLength ) { 1035 firingLength--; 1036 } 1037 if ( index <= firingIndex ) { 1038 firingIndex--; 1039 } 1040 } 1041 } 1042 }); 1043 } 1044 return this; 1045 }, 1046 // Control if a given callback is in the list 1047 has: function( fn ) { 1048 return jQuery.inArray( fn, list ) > -1; 1049 }, 1050 // Remove all callbacks from the list 1051 empty: function() { 1052 list = []; 1053 return this; 1054 }, 1055 // Have the list do nothing anymore 1056 disable: function() { 1057 list = stack = memory = undefined; 1058 return this; 1059 }, 1060 // Is it disabled? 1061 disabled: function() { 1062 return !list; 1063 }, 1064 // Lock the list in its current state 1065 lock: function() { 1066 stack = undefined; 1067 if ( !memory ) { 1068 self.disable(); 1069 } 1070 return this; 1071 }, 1072 // Is it locked? 1073 locked: function() { 1074 return !stack; 1075 }, 1076 // Call all callbacks with the given context and arguments 1077 fireWith: function( context, args ) { 1078 args = args || []; 1079 args = [ context, args.slice ? args.slice() : args ]; 1080 if ( list && ( !fired || stack ) ) { 1081 if ( firing ) { 1082 stack.push( args ); 1083 } else { 1084 fire( args ); 1085 } 1086 } 1087 return this; 1088 }, 1089 // Call all the callbacks with the given arguments 1090 fire: function() { 1091 self.fireWith( this, arguments ); 1092 return this; 1093 }, 1094 // To know if the callbacks have already been called at least once 1095 fired: function() { 1096 return !!fired; 1097 } 1098 }; 1099 1100 return self; 1101 }; 1102 jQuery.extend({ 1103 1104 Deferred: function( func ) { 1105 var tuples = [ 1106 // action, add listener, listener list, final state 1107 [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ], 1108 [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ], 1109 [ "notify", "progress", jQuery.Callbacks("memory") ] 1110 ], 1111 state = "pending", 1112 promise = { 1113 state: function() { 1114 return state; 1115 }, 1116 always: function() { 1117 deferred.done( arguments ).fail( arguments ); 1118 return this; 1119 }, 1120 then: function( /* fnDone, fnFail, fnProgress */ ) { 1121 var fns = arguments; 1122 return jQuery.Deferred(function( newDefer ) { 1123 jQuery.each( tuples, function( i, tuple ) { 1124 var action = tuple[ 0 ], 1125 fn = fns[ i ]; 1126 // deferred[ done | fail | progress ] for forwarding actions to newDefer 1127 deferred[ tuple[1] ]( jQuery.isFunction( fn ) ? 1128 function() { 1129 var returned = fn.apply( this, arguments ); 1130 if ( returned && jQuery.isFunction( returned.promise ) ) { 1131 returned.promise() 1132 .done( newDefer.resolve ) 1133 .fail( newDefer.reject ) 1134 .progress( newDefer.notify ); 1135 } else { 1136 newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] ); 1137 } 1138 } : 1139 newDefer[ action ] 1140 ); 1141 }); 1142 fns = null; 1143 }).promise(); 1144 }, 1145 // Get a promise for this deferred 1146 // If obj is provided, the promise aspect is added to the object 1147 promise: function( obj ) { 1148 return obj != null ? jQuery.extend( obj, promise ) : promise; 1149 } 1150 }, 1151 deferred = {}; 1152 1153 // Keep pipe for back-compat 1154 promise.pipe = promise.then; 1155 1156 // Add list-specific methods 1157 jQuery.each( tuples, function( i, tuple ) { 1158 var list = tuple[ 2 ], 1159 stateString = tuple[ 3 ]; 1160 1161 // promise[ done | fail | progress ] = list.add 1162 promise[ tuple[1] ] = list.add; 1163 1164 // Handle state 1165 if ( stateString ) { 1166 list.add(function() { 1167 // state = [ resolved | rejected ] 1168 state = stateString; 1169 1170 // [ reject_list | resolve_list ].disable; progress_list.lock 1171 }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock ); 1172 } 1173 1174 // deferred[ resolve | reject | notify ] = list.fire 1175 deferred[ tuple[0] ] = list.fire; 1176 deferred[ tuple[0] + "With" ] = list.fireWith; 1177 }); 1178 1179 // Make the deferred a promise 1180 promise.promise( deferred ); 1181 1182 // Call given func if any 1183 if ( func ) { 1184 func.call( deferred, deferred ); 1185 } 1186 1187 // All done! 1188 return deferred; 1189 }, 1190 1191 // Deferred helper 1192 when: function( subordinate /* , ..., subordinateN */ ) { 1193 var i = 0, 1194 resolveValues = core_slice.call( arguments ), 1195 length = resolveValues.length, 1196 1197 // the count of uncompleted subordinates 1198 remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, 1199 1200 // the master Deferred. If resolveValues consist of only a single Deferred, just use that. 1201 deferred = remaining === 1 ? subordinate : jQuery.Deferred(), 1202 1203 // Update function for both resolve and progress values 1204 updateFunc = function( i, contexts, values ) { 1205 return function( value ) { 1206 contexts[ i ] = this; 1207 values[ i ] = arguments.length > 1 ? core_slice.call( arguments ) : value; 1208 if( values === progressValues ) { 1209 deferred.notifyWith( contexts, values ); 1210 } else if ( !( --remaining ) ) { 1211 deferred.resolveWith( contexts, values ); 1212 } 1213 }; 1214 }, 1215 1216 progressValues, progressContexts, resolveContexts; 1217 1218 // add listeners to Deferred subordinates; treat others as resolved 1219 if ( length > 1 ) { 1220 progressValues = new Array( length ); 1221 progressContexts = new Array( length ); 1222 resolveContexts = new Array( length ); 1223 for ( ; i < length; i++ ) { 1224 if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { 1225 resolveValues[ i ].promise() 1226 .done( updateFunc( i, resolveContexts, resolveValues ) ) 1227 .fail( deferred.reject ) 1228 .progress( updateFunc( i, progressContexts, progressValues ) ); 1229 } else { 1230 --remaining; 1231 } 1232 } 1233 } 1234 1235 // if we're not waiting on anything, resolve the master 1236 if ( !remaining ) { 1237 deferred.resolveWith( resolveContexts, resolveValues ); 1238 } 1239 1240 return deferred.promise(); 1241 } 1242 }); 1243 jQuery.support = (function() { 1244 1245 var support, 1246 all, 1247 a, 1248 select, 1249 opt, 1250 input, 1251 fragment, 1252 eventName, 1253 i, 1254 isSupported, 1255 clickFn, 1256 div = document.createElement("div"); 1257 1258 // Setup 1259 div.setAttribute( "className", "t" ); 1260 div.innerHTML = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>"; 1261 1262 // Support tests won't run in some limited or non-browser environments 1263 all = div.getElementsByTagName("*"); 1264 a = div.getElementsByTagName("a")[ 0 ]; 1265 if ( !all || !a || !all.length ) { 1266 return {}; 1267 } 1268 1269 // First batch of tests 1270 select = document.createElement("select"); 1271 opt = select.appendChild( document.createElement("option") ); 1272 input = div.getElementsByTagName("input")[ 0 ]; 1273 1274 a.style.cssText = "top:1px;float:left;opacity:.5"; 1275 support = { 1276 // IE strips leading whitespace when .innerHTML is used 1277 leadingWhitespace: ( div.firstChild.nodeType === 3 ), 1278 1279 // Make sure that tbody elements aren't automatically inserted 1280 // IE will insert them into empty tables 1281 tbody: !div.getElementsByTagName("tbody").length, 1282 1283 // Make sure that link elements get serialized correctly by innerHTML 1284 // This requires a wrapper element in IE 1285 htmlSerialize: !!div.getElementsByTagName("link").length, 1286 1287 // Get the style information from getAttribute 1288 // (IE uses .cssText instead) 1289 style: /top/.test( a.getAttribute("style") ), 1290 1291 // Make sure that URLs aren't manipulated 1292 // (IE normalizes it by default) 1293 hrefNormalized: ( a.getAttribute("href") === "/a" ), 1294 1295 // Make sure that element opacity exists 1296 // (IE uses filter instead) 1297 // Use a regex to work around a WebKit issue. See #5145 1298 opacity: /^0.5/.test( a.style.opacity ), 1299 1300 // Verify style float existence 1301 // (IE uses styleFloat instead of cssFloat) 1302 cssFloat: !!a.style.cssFloat, 1303 1304 // Make sure that if no value is specified for a checkbox 1305 // that it defaults to "on". 1306 // (WebKit defaults to "" instead) 1307 checkOn: ( input.value === "on" ), 1308 1309 // Make sure that a selected-by-default option has a working selected property. 1310 // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) 1311 optSelected: opt.selected, 1312 1313 // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7) 1314 getSetAttribute: div.className !== "t", 1315 1316 // Tests for enctype support on a form (#6743) 1317 enctype: !!document.createElement("form").enctype, 1318 1319 // Makes sure cloning an html5 element does not cause problems 1320 // Where outerHTML is undefined, this still works 1321 html5Clone: document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav></:nav>", 1322 1323 // jQuery.support.boxModel DEPRECATED in 1.8 since we don't support Quirks Mode 1324 boxModel: ( document.compatMode === "CSS1Compat" ), 1325 1326 // Will be defined later 1327 submitBubbles: true, 1328 changeBubbles: true, 1329 focusinBubbles: false, 1330 deleteExpando: true, 1331 noCloneEvent: true, 1332 inlineBlockNeedsLayout: false, 1333 shrinkWrapBlocks: false, 1334 reliableMarginRight: true, 1335 boxSizingReliable: true, 1336 pixelPosition: false 1337 }; 1338 1339 // Make sure checked status is properly cloned 1340 input.checked = true; 1341 support.noCloneChecked = input.cloneNode( true ).checked; 1342 1343 // Make sure that the options inside disabled selects aren't marked as disabled 1344 // (WebKit marks them as disabled) 1345 select.disabled = true; 1346 support.optDisabled = !opt.disabled; 1347 1348 // Test to see if it's possible to delete an expando from an element 1349 // Fails in Internet Explorer 1350 try { 1351 delete div.test; 1352 } catch( e ) { 1353 support.deleteExpando = false; 1354 } 1355 1356 if ( !div.addEventListener && div.attachEvent && div.fireEvent ) { 1357 div.attachEvent( "onclick", clickFn = function() { 1358 // Cloning a node shouldn't copy over any 1359 // bound event handlers (IE does this) 1360 support.noCloneEvent = false; 1361 }); 1362 div.cloneNode( true ).fireEvent("onclick"); 1363 div.detachEvent( "onclick", clickFn ); 1364 } 1365 1366 // Check if a radio maintains its value 1367 // after being appended to the DOM 1368 input = document.createElement("input"); 1369 input.value = "t"; 1370 input.setAttribute( "type", "radio" ); 1371 support.radioValue = input.value === "t"; 1372 1373 input.setAttribute( "checked", "checked" ); 1374 1375 // #11217 - WebKit loses check when the name is after the checked attribute 1376 input.setAttribute( "name", "t" ); 1377 1378 div.appendChild( input ); 1379 fragment = document.createDocumentFragment(); 1380 fragment.appendChild( div.lastChild ); 1381 1382 // WebKit doesn't clone checked state correctly in fragments 1383 support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked; 1384 1385 // Check if a disconnected checkbox will retain its checked 1386 // value of true after appended to the DOM (IE6/7) 1387 support.appendChecked = input.checked; 1388 1389 fragment.removeChild( input ); 1390 fragment.appendChild( div ); 1391 1392 // Technique from Juriy Zaytsev 1393 // http://perfectionkills.com/detecting-event-support-without-browser-sniffing/ 1394 // We only care about the case where non-standard event systems 1395 // are used, namely in IE. Short-circuiting here helps us to 1396 // avoid an eval call (in setAttribute) which can cause CSP 1397 // to go haywire. See: https://developer.mozilla.org/en/Security/CSP 1398 if ( div.attachEvent ) { 1399 for ( i in { 1400 submit: true, 1401 change: true, 1402 focusin: true 1403 }) { 1404 eventName = "on" + i; 1405 isSupported = ( eventName in div ); 1406 if ( !isSupported ) { 1407 div.setAttribute( eventName, "return;" ); 1408 isSupported = ( typeof div[ eventName ] === "function" ); 1409 } 1410 support[ i + "Bubbles" ] = isSupported; 1411 } 1412 } 1413 1414 // Run tests that need a body at doc ready 1415 jQuery(function() { 1416 var container, div, tds, marginDiv, 1417 divReset = "padding:0;margin:0;border:0;display:block;overflow:hidden;", 1418 body = document.getElementsByTagName("body")[0]; 1419 1420 if ( !body ) { 1421 // Return for frameset docs that don't have a body 1422 return; 1423 } 1424 1425 container = document.createElement("div"); 1426 container.style.cssText = "visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px"; 1427 body.insertBefore( container, body.firstChild ); 1428 1429 // Construct the test element 1430 div = document.createElement("div"); 1431 container.appendChild( div ); 1432 1433 // Check if table cells still have offsetWidth/Height when they are set 1434 // to display:none and there are still other visible table cells in a 1435 // table row; if so, offsetWidth/Height are not reliable for use when 1436 // determining if an element has been hidden directly using 1437 // display:none (it is still safe to use offsets if a parent element is 1438 // hidden; don safety goggles and see bug #4512 for more information). 1439 // (only IE 8 fails this test) 1440 div.innerHTML = "<table><tr><td></td><td>t</td></tr></table>"; 1441 tds = div.getElementsByTagName("td"); 1442 tds[ 0 ].style.cssText = "padding:0;margin:0;border:0;display:none"; 1443 isSupported = ( tds[ 0 ].offsetHeight === 0 ); 1444 1445 tds[ 0 ].style.display = ""; 1446 tds[ 1 ].style.display = "none"; 1447 1448 // Check if empty table cells still have offsetWidth/Height 1449 // (IE <= 8 fail this test) 1450 support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 ); 1451 1452 // Check box-sizing and margin behavior 1453 div.innerHTML = ""; 1454 div.style.cssText = "box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;"; 1455 support.boxSizing = ( div.offsetWidth === 4 ); 1456 support.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== 1 ); 1457 1458 // NOTE: To any future maintainer, we've window.getComputedStyle 1459 // because jsdom on node.js will break without it. 1460 if ( window.getComputedStyle ) { 1461 support.pixelPosition = ( window.getComputedStyle( div, null ) || {} ).top !== "1%"; 1462 support.boxSizingReliable = ( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px"; 1463 1464 // Check if div with explicit width and no margin-right incorrectly 1465 // gets computed margin-right based on width of container. For more 1466 // info see bug #3333 1467 // Fails in WebKit before Feb 2011 nightlies 1468 // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right 1469 marginDiv = document.createElement("div"); 1470 marginDiv.style.cssText = div.style.cssText = divReset; 1471 marginDiv.style.marginRight = marginDiv.style.width = "0"; 1472 div.style.width = "1px"; 1473 div.appendChild( marginDiv ); 1474 support.reliableMarginRight = 1475 !parseFloat( ( window.getComputedStyle( marginDiv, null ) || {} ).marginRight ); 1476 } 1477 1478 if ( typeof div.style.zoom !== "undefined" ) { 1479 // Check if natively block-level elements act like inline-block 1480 // elements when setting their display to 'inline' and giving 1481 // them layout 1482 // (IE < 8 does this) 1483 div.innerHTML = ""; 1484 div.style.cssText = divReset + "width:1px;padding:1px;display:inline;zoom:1"; 1485 support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 ); 1486 1487 // Check if elements with layout shrink-wrap their children 1488 // (IE 6 does this) 1489 div.style.display = "block"; 1490 div.style.overflow = "visible"; 1491 div.innerHTML = "<div></div>"; 1492 div.firstChild.style.width = "5px"; 1493 support.shrinkWrapBlocks = ( div.offsetWidth !== 3 ); 1494 1495 container.style.zoom = 1; 1496 } 1497 1498 // Null elements to avoid leaks in IE 1499 body.removeChild( container ); 1500 container = div = tds = marginDiv = null; 1501 }); 1502 1503 // Null elements to avoid leaks in IE 1504 fragment.removeChild( div ); 1505 all = a = select = opt = input = fragment = div = null; 1506 1507 return support; 1508 })(); 1509 var rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/, 1510 rmultiDash = /([A-Z])/g; 1511 1512 jQuery.extend({ 1513 cache: {}, 1514 1515 deletedIds: [], 1516 1517 // Remove at next major release (1.9/2.0) 1518 uuid: 0, 1519 1520 // Unique for each copy of jQuery on the page 1521 // Non-digits removed to match rinlinejQuery 1522 expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ), 1523 1524 // The following elements throw uncatchable exceptions if you 1525 // attempt to add expando properties to them. 1526 noData: { 1527 "embed": true, 1528 // Ban all objects except for Flash (which handle expandos) 1529 "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000", 1530 "applet": true 1531 }, 1532 1533 hasData: function( elem ) { 1534 elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; 1535 return !!elem && !isEmptyDataObject( elem ); 1536 }, 1537 1538 data: function( elem, name, data, pvt /* Internal Use Only */ ) { 1539 if ( !jQuery.acceptData( elem ) ) { 1540 return; 1541 } 1542 1543 var thisCache, ret, 1544 internalKey = jQuery.expando, 1545 getByName = typeof name === "string", 1546 1547 // We have to handle DOM nodes and JS objects differently because IE6-7 1548 // can't GC object references properly across the DOM-JS boundary 1549 isNode = elem.nodeType, 1550 1551 // Only DOM nodes need the global jQuery cache; JS object data is 1552 // attached directly to the object so GC can occur automatically 1553 cache = isNode ? jQuery.cache : elem, 1554 1555 // Only defining an ID for JS objects if its cache already exists allows 1556 // the code to shortcut on the same path as a DOM node with no cache 1557 id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey; 1558 1559 // Avoid doing any more work than we need to when trying to get data on an 1560 // object that has no data at all 1561 if ( (!id || !cache[id] || (!pvt && !cache[id].data)) && getByName && data === undefined ) { 1562 return; 1563 } 1564 1565 if ( !id ) { 1566 // Only DOM nodes need a new unique ID for each element since their data 1567 // ends up in the global cache 1568 if ( isNode ) { 1569 elem[ internalKey ] = id = jQuery.deletedIds.pop() || jQuery.guid++; 1570 } else { 1571 id = internalKey; 1572 } 1573 } 1574 1575 if ( !cache[ id ] ) { 1576 cache[ id ] = {}; 1577 1578 // Avoids exposing jQuery metadata on plain JS objects when the object 1579 // is serialized using JSON.stringify 1580 if ( !isNode ) { 1581 cache[ id ].toJSON = jQuery.noop; 1582 } 1583 } 1584 1585 // An object can be passed to jQuery.data instead of a key/value pair; this gets 1586 // shallow copied over onto the existing cache 1587 if ( typeof name === "object" || typeof name === "function" ) { 1588 if ( pvt ) { 1589 cache[ id ] = jQuery.extend( cache[ id ], name ); 1590 } else { 1591 cache[ id ].data = jQuery.extend( cache[ id ].data, name ); 1592 } 1593 } 1594 1595 thisCache = cache[ id ]; 1596 1597 // jQuery data() is stored in a separate object inside the object's internal data 1598 // cache in order to avoid key collisions between internal data and user-defined 1599 // data. 1600 if ( !pvt ) { 1601 if ( !thisCache.data ) { 1602 thisCache.data = {}; 1603 } 1604 1605 thisCache = thisCache.data; 1606 } 1607 1608 if ( data !== undefined ) { 1609 thisCache[ jQuery.camelCase( name ) ] = data; 1610 } 1611 1612 // Check for both converted-to-camel and non-converted data property names 1613 // If a data property was specified 1614 if ( getByName ) { 1615 1616 // First Try to find as-is property data 1617 ret = thisCache[ name ]; 1618 1619 // Test for null|undefined property data 1620 if ( ret == null ) { 1621 1622 // Try to find the camelCased property 1623 ret = thisCache[ jQuery.camelCase( name ) ]; 1624 } 1625 } else { 1626 ret = thisCache; 1627 } 1628 1629 return ret; 1630 }, 1631 1632 removeData: function( elem, name, pvt /* Internal Use Only */ ) { 1633 if ( !jQuery.acceptData( elem ) ) { 1634 return; 1635 } 1636 1637 var thisCache, i, l, 1638 1639 isNode = elem.nodeType, 1640 1641 // See jQuery.data for more information 1642 cache = isNode ? jQuery.cache : elem, 1643 id = isNode ? elem[ jQuery.expando ] : jQuery.expando; 1644 1645 // If there is already no cache entry for this object, there is no 1646 // purpose in continuing 1647 if ( !cache[ id ] ) { 1648 return; 1649 } 1650 1651 if ( name ) { 1652 1653 thisCache = pvt ? cache[ id ] : cache[ id ].data; 1654 1655 if ( thisCache ) { 1656 1657 // Support array or space separated string names for data keys 1658 if ( !jQuery.isArray( name ) ) { 1659 1660 // try the string as a key before any manipulation 1661 if ( name in thisCache ) { 1662 name = [ name ]; 1663 } else { 1664 1665 // split the camel cased version by spaces unless a key with the spaces exists 1666 name = jQuery.camelCase( name ); 1667 if ( name in thisCache ) { 1668 name = [ name ]; 1669 } else { 1670 name = name.split(" "); 1671 } 1672 } 1673 } 1674 1675 for ( i = 0, l = name.length; i < l; i++ ) { 1676 delete thisCache[ name[i] ]; 1677 } 1678 1679 // If there is no data left in the cache, we want to continue 1680 // and let the cache object itself get destroyed 1681 if ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) { 1682 return; 1683 } 1684 } 1685 } 1686 1687 // See jQuery.data for more information 1688 if ( !pvt ) { 1689 delete cache[ id ].data; 1690 1691 // Don't destroy the parent cache unless the internal data object 1692 // had been the only thing left in it 1693 if ( !isEmptyDataObject( cache[ id ] ) ) { 1694 return; 1695 } 1696 } 1697 1698 // Destroy the cache 1699 if ( isNode ) { 1700 jQuery.cleanData( [ elem ], true ); 1701 1702 // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080) 1703 } else if ( jQuery.support.deleteExpando || cache != cache.window ) { 1704 delete cache[ id ]; 1705 1706 // When all else fails, null 1707 } else { 1708 cache[ id ] = null; 1709 } 1710 }, 1711 1712 // For internal use only. 1713 _data: function( elem, name, data ) { 1714 return jQuery.data( elem, name, data, true ); 1715 }, 1716 1717 // A method for determining if a DOM node can handle the data expando 1718 acceptData: function( elem ) { 1719 var noData = elem.nodeName && jQuery.noData[ elem.nodeName.toLowerCase() ]; 1720 1721 // nodes accept data unless otherwise specified; rejection can be conditional 1722 return !noData || noData !== true && elem.getAttribute("classid") === noData; 1723 } 1724 }); 1725 1726 jQuery.fn.extend({ 1727 data: function( key, value ) { 1728 var parts, part, attr, name, l, 1729 elem = this[0], 1730 i = 0, 1731 data = null; 1732 1733 // Gets all values 1734 if ( key === undefined ) { 1735 if ( this.length ) { 1736 data = jQuery.data( elem ); 1737 1738 if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) { 1739 attr = elem.attributes; 1740 for ( l = attr.length; i < l; i++ ) { 1741 name = attr[i].name; 1742 1743 if ( !name.indexOf( "data-" ) ) { 1744 name = jQuery.camelCase( name.substring(5) ); 1745 1746 dataAttr( elem, name, data[ name ] ); 1747 } 1748 } 1749 jQuery._data( elem, "parsedAttrs", true ); 1750 } 1751 } 1752 1753 return data; 1754 } 1755 1756 // Sets multiple values 1757 if ( typeof key === "object" ) { 1758 return this.each(function() { 1759 jQuery.data( this, key ); 1760 }); 1761 } 1762 1763 parts = key.split( ".", 2 ); 1764 parts[1] = parts[1] ? "." + parts[1] : ""; 1765 part = parts[1] + "!"; 1766 1767 return jQuery.access( this, function( value ) { 1768 1769 if ( value === undefined ) { 1770 data = this.triggerHandler( "getData" + part, [ parts[0] ] ); 1771 1772 // Try to fetch any internally stored data first 1773 if ( data === undefined && elem ) { 1774 data = jQuery.data( elem, key ); 1775 data = dataAttr( elem, key, data ); 1776 } 1777 1778 return data === undefined && parts[1] ? 1779 this.data( parts[0] ) : 1780 data; 1781 } 1782 1783 parts[1] = value; 1784 this.each(function() { 1785 var self = jQuery( this ); 1786 1787 self.triggerHandler( "setData" + part, parts ); 1788 jQuery.data( this, key, value ); 1789 self.triggerHandler( "changeData" + part, parts ); 1790 }); 1791 }, null, value, arguments.length > 1, null, false ); 1792 }, 1793 1794 removeData: function( key ) { 1795 return this.each(function() { 1796 jQuery.removeData( this, key ); 1797 }); 1798 } 1799 }); 1800 1801 function dataAttr( elem, key, data ) { 1802 // If nothing was found internally, try to fetch any 1803 // data from the HTML5 data-* attribute 1804 if ( data === undefined && elem.nodeType === 1 ) { 1805 1806 var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); 1807 1808 data = elem.getAttribute( name ); 1809 1810 if ( typeof data === "string" ) { 1811 try { 1812 data = data === "true" ? true : 1813 data === "false" ? false : 1814 data === "null" ? null : 1815 // Only convert to a number if it doesn't change the string 1816 +data + "" === data ? +data : 1817 rbrace.test( data ) ? jQuery.parseJSON( data ) : 1818 data; 1819 } catch( e ) {} 1820 1821 // Make sure we set the data so it isn't changed later 1822 jQuery.data( elem, key, data ); 1823 1824 } else { 1825 data = undefined; 1826 } 1827 } 1828 1829 return data; 1830 } 1831 1832 // checks a cache object for emptiness 1833 function isEmptyDataObject( obj ) { 1834 var name; 1835 for ( name in obj ) { 1836 1837 // if the public data object is empty, the private is still empty 1838 if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) { 1839 continue; 1840 } 1841 if ( name !== "toJSON" ) { 1842 return false; 1843 } 1844 } 1845 1846 return true; 1847 } 1848 jQuery.extend({ 1849 queue: function( elem, type, data ) { 1850 var queue; 1851 1852 if ( elem ) { 1853 type = ( type || "fx" ) + "queue"; 1854 queue = jQuery._data( elem, type ); 1855 1856 // Speed up dequeue by getting out quickly if this is just a lookup 1857 if ( data ) { 1858 if ( !queue || jQuery.isArray(data) ) { 1859 queue = jQuery._data( elem, type, jQuery.makeArray(data) ); 1860 } else { 1861 queue.push( data ); 1862 } 1863 } 1864 return queue || []; 1865 } 1866 }, 1867 1868 dequeue: function( elem, type ) { 1869 type = type || "fx"; 1870 1871 var queue = jQuery.queue( elem, type ), 1872 startLength = queue.length, 1873 fn = queue.shift(), 1874 hooks = jQuery._queueHooks( elem, type ), 1875 next = function() { 1876 jQuery.dequeue( elem, type ); 1877 }; 1878 1879 // If the fx queue is dequeued, always remove the progress sentinel 1880 if ( fn === "inprogress" ) { 1881 fn = queue.shift(); 1882 startLength--; 1883 } 1884 1885 if ( fn ) { 1886 1887 // Add a progress sentinel to prevent the fx queue from being 1888 // automatically dequeued 1889 if ( type === "fx" ) { 1890 queue.unshift( "inprogress" ); 1891 } 1892 1893 // clear up the last queue stop function 1894 delete hooks.stop; 1895 fn.call( elem, next, hooks ); 1896 } 1897 1898 if ( !startLength && hooks ) { 1899 hooks.empty.fire(); 1900 } 1901 }, 1902 1903 // not intended for public consumption - generates a queueHooks object, or returns the current one 1904 _queueHooks: function( elem, type ) { 1905 var key = type + "queueHooks"; 1906 return jQuery._data( elem, key ) || jQuery._data( elem, key, { 1907 empty: jQuery.Callbacks("once memory").add(function() { 1908 jQuery.removeData( elem, type + "queue", true ); 1909 jQuery.removeData( elem, key, true ); 1910 }) 1911 }); 1912 } 1913 }); 1914 1915 jQuery.fn.extend({ 1916 queue: function( type, data ) { 1917 var setter = 2; 1918 1919 if ( typeof type !== "string" ) { 1920 data = type; 1921 type = "fx"; 1922 setter--; 1923 } 1924 1925 if ( arguments.length < setter ) { 1926 return jQuery.queue( this[0], type ); 1927 } 1928 1929 return data === undefined ? 1930 this : 1931 this.each(function() { 1932 var queue = jQuery.queue( this, type, data ); 1933 1934 // ensure a hooks for this queue 1935 jQuery._queueHooks( this, type ); 1936 1937 if ( type === "fx" && queue[0] !== "inprogress" ) { 1938 jQuery.dequeue( this, type ); 1939 } 1940 }); 1941 }, 1942 dequeue: function( type ) { 1943 return this.each(function() { 1944 jQuery.dequeue( this, type ); 1945 }); 1946 }, 1947 // Based off of the plugin by Clint Helfers, with permission. 1948 // http://blindsignals.com/index.php/2009/07/jquery-delay/ 1949 delay: function( time, type ) { 1950 time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; 1951 type = type || "fx"; 1952 1953 return this.queue( type, function( next, hooks ) { 1954 var timeout = setTimeout( next, time ); 1955 hooks.stop = function() { 1956 clearTimeout( timeout ); 1957 }; 1958 }); 1959 }, 1960 clearQueue: function( type ) { 1961 return this.queue( type || "fx", [] ); 1962 }, 1963 // Get a promise resolved when queues of a certain type 1964 // are emptied (fx is the type by default) 1965 promise: function( type, obj ) { 1966 var tmp, 1967 count = 1, 1968 defer = jQuery.Deferred(), 1969 elements = this, 1970 i = this.length, 1971 resolve = function() { 1972 if ( !( --count ) ) { 1973 defer.resolveWith( elements, [ elements ] ); 1974 } 1975 }; 1976 1977 if ( typeof type !== "string" ) { 1978 obj = type; 1979 type = undefined; 1980 } 1981 type = type || "fx"; 1982 1983 while( i-- ) { 1984 tmp = jQuery._data( elements[ i ], type + "queueHooks" ); 1985 if ( tmp && tmp.empty ) { 1986 count++; 1987 tmp.empty.add( resolve ); 1988 } 1989 } 1990 resolve(); 1991 return defer.promise( obj ); 1992 } 1993 }); 1994 var nodeHook, boolHook, fixSpecified, 1995 rclass = /[\t\r\n]/g, 1996 rreturn = /\r/g, 1997 rtype = /^(?:button|input)$/i, 1998 rfocusable = /^(?:button|input|object|select|textarea)$/i, 1999 rclickable = /^a(?:rea|)$/i, 2000 rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i, 2001 getSetAttribute = jQuery.support.getSetAttribute; 2002 2003 jQuery.fn.extend({ 2004 attr: function( name, value ) { 2005 return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 ); 2006 }, 2007 2008 removeAttr: function( name ) { 2009 return this.each(function() { 2010 jQuery.removeAttr( this, name ); 2011 }); 2012 }, 2013 2014 prop: function( name, value ) { 2015 return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 ); 2016 }, 2017 2018 removeProp: function( name ) { 2019 name = jQuery.propFix[ name ] || name; 2020 return this.each(function() { 2021 // try/catch handles cases where IE balks (such as removing a property on window) 2022 try { 2023 this[ name ] = undefined; 2024 delete this[ name ]; 2025 } catch( e ) {} 2026 }); 2027 }, 2028 2029 addClass: function( value ) { 2030 var classNames, i, l, elem, 2031 setClass, c, cl; 2032 2033 if ( jQuery.isFunction( value ) ) { 2034 return this.each(function( j ) { 2035 jQuery( this ).addClass( value.call(this, j, this.className) ); 2036 }); 2037 } 2038 2039 if ( value && typeof value === "string" ) { 2040 classNames = value.split( core_rspace ); 2041 2042 for ( i = 0, l = this.length; i < l; i++ ) { 2043 elem = this[ i ]; 2044 2045 if ( elem.nodeType === 1 ) { 2046 if ( !elem.className && classNames.length === 1 ) { 2047 elem.className = value; 2048 2049 } else { 2050 setClass = " " + elem.className + " "; 2051 2052 for ( c = 0, cl = classNames.length; c < cl; c++ ) { 2053 if ( setClass.indexOf( " " + classNames[ c ] + " " ) < 0 ) { 2054 setClass += classNames[ c ] + " "; 2055 } 2056 } 2057 elem.className = jQuery.trim( setClass ); 2058 } 2059 } 2060 } 2061 } 2062 2063 return this; 2064 }, 2065 2066 removeClass: function( value ) { 2067 var removes, className, elem, c, cl, i, l; 2068 2069 if ( jQuery.isFunction( value ) ) { 2070 return this.each(function( j ) { 2071 jQuery( this ).removeClass( value.call(this, j, this.className) ); 2072 }); 2073 } 2074 if ( (value && typeof value === "string") || value === undefined ) { 2075 removes = ( value || "" ).split( core_rspace ); 2076 2077 for ( i = 0, l = this.length; i < l; i++ ) { 2078 elem = this[ i ]; 2079 if ( elem.nodeType === 1 && elem.className ) { 2080 2081 className = (" " + elem.className + " ").replace( rclass, " " ); 2082 2083 // loop over each item in the removal list 2084 for ( c = 0, cl = removes.length; c < cl; c++ ) { 2085 // Remove until there is nothing to remove, 2086 while ( className.indexOf(" " + removes[ c ] + " ") >= 0 ) { 2087 className = className.replace( " " + removes[ c ] + " " , " " ); 2088 } 2089 } 2090 elem.className = value ? jQuery.trim( className ) : ""; 2091 } 2092 } 2093 } 2094 2095 return this; 2096 }, 2097 2098 toggleClass: function( value, stateVal ) { 2099 var type = typeof value, 2100 isBool = typeof stateVal === "boolean"; 2101 2102 if ( jQuery.isFunction( value ) ) { 2103 return this.each(function( i ) { 2104 jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal ); 2105 }); 2106 } 2107 2108 return this.each(function() { 2109 if ( type === "string" ) { 2110 // toggle individual class names 2111 var className, 2112 i = 0, 2113 self = jQuery( this ), 2114 state = stateVal, 2115 classNames = value.split( core_rspace ); 2116 2117 while ( (className = classNames[ i++ ]) ) { 2118 // check each className given, space separated list 2119 state = isBool ? state : !self.hasClass( className ); 2120 self[ state ? "addClass" : "removeClass" ]( className ); 2121 } 2122 2123 } else if ( type === "undefined" || type === "boolean" ) { 2124 if ( this.className ) { 2125 // store className if set 2126 jQuery._data( this, "__className__", this.className ); 2127 } 2128 2129 // toggle whole className 2130 this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || ""; 2131 } 2132 }); 2133 }, 2134 2135 hasClass: function( selector ) { 2136 var className = " " + selector + " ", 2137 i = 0, 2138 l = this.length; 2139 for ( ; i < l; i++ ) { 2140 if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) { 2141 return true; 2142 } 2143 } 2144 2145 return false; 2146 }, 2147 2148 val: function( value ) { 2149 var hooks, ret, isFunction, 2150 elem = this[0]; 2151 2152 if ( !arguments.length ) { 2153 if ( elem ) { 2154 hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ]; 2155 2156 if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) { 2157 return ret; 2158 } 2159 2160 ret = elem.value; 2161 2162 return typeof ret === "string" ? 2163 // handle most common string cases 2164 ret.replace(rreturn, "") : 2165 // handle cases where value is null/undef or number 2166 ret == null ? "" : ret; 2167 } 2168 2169 return; 2170 } 2171 2172 isFunction = jQuery.isFunction( value ); 2173 2174 return this.each(function( i ) { 2175 var val, 2176 self = jQuery(this); 2177 2178 if ( this.nodeType !== 1 ) { 2179 return; 2180 } 2181 2182 if ( isFunction ) { 2183 val = value.call( this, i, self.val() ); 2184 } else { 2185 val = value; 2186 } 2187 2188 // Treat null/undefined as ""; convert numbers to string 2189 if ( val == null ) { 2190 val = ""; 2191 } else if ( typeof val === "number" ) { 2192 val += ""; 2193 } else if ( jQuery.isArray( val ) ) { 2194 val = jQuery.map(val, function ( value ) { 2195 return value == null ? "" : value + ""; 2196 }); 2197 } 2198 2199 hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; 2200 2201 // If set returns undefined, fall back to normal setting 2202 if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) { 2203 this.value = val; 2204 } 2205 }); 2206 } 2207 }); 2208 2209 jQuery.extend({ 2210 valHooks: { 2211 option: { 2212 get: function( elem ) { 2213 // attributes.value is undefined in Blackberry 4.7 but 2214 // uses .value. See #6932 2215 var val = elem.attributes.value; 2216 return !val || val.specified ? elem.value : elem.text; 2217 } 2218 }, 2219 select: { 2220 get: function( elem ) { 2221 var value, option, 2222 options = elem.options, 2223 index = elem.selectedIndex, 2224 one = elem.type === "select-one" || index < 0, 2225 values = one ? null : [], 2226 max = one ? index + 1 : options.length, 2227 i = index < 0 ? 2228 max : 2229 one ? index : 0; 2230 2231 // Loop through all the selected options 2232 for ( ; i < max; i++ ) { 2233 option = options[ i ]; 2234 2235 // oldIE doesn't update selected after form reset (#2551) 2236 if ( ( option.selected || i === index ) && 2237 // Don't return options that are disabled or in a disabled optgroup 2238 ( jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null ) && 2239 ( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) { 2240 2241 // Get the specific value for the option 2242 value = jQuery( option ).val(); 2243 2244 // We don't need an array for one selects 2245 if ( one ) { 2246 return value; 2247 } 2248 2249 // Multi-Selects return an array 2250 values.push( value ); 2251 } 2252 } 2253 2254 return values; 2255 }, 2256 2257 set: function( elem, value ) { 2258 var values = jQuery.makeArray( value ); 2259 2260 jQuery(elem).find("option").each(function() { 2261 this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0; 2262 }); 2263 2264 if ( !values.length ) { 2265 elem.selectedIndex = -1; 2266 } 2267 return values; 2268 } 2269 } 2270 }, 2271 2272 // Unused in 1.8, left in so attrFn-stabbers won't die; remove in 1.9 2273 attrFn: {}, 2274 2275 attr: function( elem, name, value, pass ) { 2276 var ret, hooks, notxml, 2277 nType = elem.nodeType; 2278 2279 // don't get/set attributes on text, comment and attribute nodes 2280 if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { 2281 return; 2282 } 2283 2284 if ( pass && jQuery.isFunction( jQuery.fn[ name ] ) ) { 2285 return jQuery( elem )[ name ]( value ); 2286 } 2287 2288 // Fallback to prop when attributes are not supported 2289 if ( typeof elem.getAttribute === "undefined" ) { 2290 return jQuery.prop( elem, name, value ); 2291 } 2292 2293 notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); 2294 2295 // All attributes are lowercase 2296 // Grab necessary hook if one is defined 2297 if ( notxml ) { 2298 name = name.toLowerCase(); 2299 hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook ); 2300 } 2301 2302 if ( value !== undefined ) { 2303 2304 if ( value === null ) { 2305 jQuery.removeAttr( elem, name ); 2306 return; 2307 2308 } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) { 2309 return ret; 2310 2311 } else { 2312 elem.setAttribute( name, value + "" ); 2313 return value; 2314 } 2315 2316 } else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) { 2317 return ret; 2318 2319 } else { 2320 2321 ret = elem.getAttribute( name ); 2322 2323 // Non-existent attributes return null, we normalize to undefined 2324 return ret === null ? 2325 undefined : 2326 ret; 2327 } 2328 }, 2329 2330 removeAttr: function( elem, value ) { 2331 var propName, attrNames, name, isBool, 2332 i = 0; 2333 2334 if ( value && elem.nodeType === 1 ) { 2335 2336 attrNames = value.split( core_rspace ); 2337 2338 for ( ; i < attrNames.length; i++ ) { 2339 name = attrNames[ i ]; 2340 2341 if ( name ) { 2342 propName = jQuery.propFix[ name ] || name; 2343 isBool = rboolean.test( name ); 2344 2345 // See #9699 for explanation of this approach (setting first, then removal) 2346 // Do not do this for boolean attributes (see #10870) 2347 if ( !isBool ) { 2348 jQuery.attr( elem, name, "" ); 2349 } 2350 elem.removeAttribute( getSetAttribute ? name : propName ); 2351 2352 // Set corresponding property to false for boolean attributes 2353 if ( isBool && propName in elem ) { 2354 elem[ propName ] = false; 2355 } 2356 } 2357 } 2358 } 2359 }, 2360 2361 attrHooks: { 2362 type: { 2363 set: function( elem, value ) { 2364 // We can't allow the type property to be changed (since it causes problems in IE) 2365 if ( rtype.test( elem.nodeName ) && elem.parentNode ) { 2366 jQuery.error( "type property can't be changed" ); 2367 } else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) { 2368 // Setting the type on a radio button after the value resets the value in IE6-9 2369 // Reset value to it's default in case type is set after value 2370 // This is for element creation 2371 var val = elem.value; 2372 elem.setAttribute( "type", value ); 2373 if ( val ) { 2374 elem.value = val; 2375 } 2376 return value; 2377 } 2378 } 2379 }, 2380 // Use the value property for back compat 2381 // Use the nodeHook for button elements in IE6/7 (#1954) 2382 value: { 2383 get: function( elem, name ) { 2384 if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { 2385 return nodeHook.get( elem, name ); 2386 } 2387 return name in elem ? 2388 elem.value : 2389 null; 2390 }, 2391 set: function( elem, value, name ) { 2392 if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { 2393 return nodeHook.set( elem, value, name ); 2394 } 2395 // Does not return so that setAttribute is also used 2396 elem.value = value; 2397 } 2398 } 2399 }, 2400 2401 propFix: { 2402 tabindex: "tabIndex", 2403 readonly: "readOnly", 2404 "for": "htmlFor", 2405 "class": "className", 2406 maxlength: "maxLength", 2407 cellspacing: "cellSpacing", 2408 cellpadding: "cellPadding", 2409 rowspan: "rowSpan", 2410 colspan: "colSpan", 2411 usemap: "useMap", 2412 frameborder: "frameBorder", 2413 contenteditable: "contentEditable" 2414 }, 2415 2416 prop: function( elem, name, value ) { 2417 var ret, hooks, notxml, 2418 nType = elem.nodeType; 2419 2420 // don't get/set properties on text, comment and attribute nodes 2421 if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { 2422 return; 2423 } 2424 2425 notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); 2426 2427 if ( notxml ) { 2428 // Fix name and attach hooks 2429 name = jQuery.propFix[ name ] || name; 2430 hooks = jQuery.propHooks[ name ]; 2431 } 2432 2433 if ( value !== undefined ) { 2434 if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { 2435 return ret; 2436 2437 } else { 2438 return ( elem[ name ] = value ); 2439 } 2440 2441 } else { 2442 if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { 2443 return ret; 2444 2445 } else { 2446 return elem[ name ]; 2447 } 2448 } 2449 }, 2450 2451 propHooks: { 2452 tabIndex: { 2453 get: function( elem ) { 2454 // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set 2455 // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ 2456 var attributeNode = elem.getAttributeNode("tabindex"); 2457 2458 return attributeNode && attributeNode.specified ? 2459 parseInt( attributeNode.value, 10 ) : 2460 rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? 2461 0 : 2462 undefined; 2463 } 2464 } 2465 } 2466 }); 2467 2468 // Hook for boolean attributes 2469 boolHook = { 2470 get: function( elem, name ) { 2471 // Align boolean attributes with corresponding properties 2472 // Fall back to attribute presence where some booleans are not supported 2473 var attrNode, 2474 property = jQuery.prop( elem, name ); 2475 return property === true || typeof property !== "boolean" && ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ? 2476 name.toLowerCase() : 2477 undefined; 2478 }, 2479 set: function( elem, value, name ) { 2480 var propName; 2481 if ( value === false ) { 2482 // Remove boolean attributes when set to false 2483 jQuery.removeAttr( elem, name ); 2484 } else { 2485 // value is true since we know at this point it's type boolean and not false 2486 // Set boolean attributes to the same name and set the DOM property 2487 propName = jQuery.propFix[ name ] || name; 2488 if ( propName in elem ) { 2489 // Only set the IDL specifically if it already exists on the element 2490 elem[ propName ] = true; 2491 } 2492 2493 elem.setAttribute( name, name.toLowerCase() ); 2494 } 2495 return name; 2496 } 2497 }; 2498 2499 // IE6/7 do not support getting/setting some attributes with get/setAttribute 2500 if ( !getSetAttribute ) { 2501 2502 fixSpecified = { 2503 name: true, 2504 id: true, 2505 coords: true 2506 }; 2507 2508 // Use this for any attribute in IE6/7 2509 // This fixes almost every IE6/7 issue 2510 nodeHook = jQuery.valHooks.button = { 2511 get: function( elem, name ) { 2512 var ret; 2513 ret = elem.getAttributeNode( name ); 2514 return ret && ( fixSpecified[ name ] ? ret.value !== "" : ret.specified ) ? 2515 ret.value : 2516 undefined; 2517 }, 2518 set: function( elem, value, name ) { 2519 // Set the existing or create a new attribute node 2520 var ret = elem.getAttributeNode( name ); 2521 if ( !ret ) { 2522 ret = document.createAttribute( name ); 2523 elem.setAttributeNode( ret ); 2524 } 2525 return ( ret.value = value + "" ); 2526 } 2527 }; 2528 2529 // Set width and height to auto instead of 0 on empty string( Bug #8150 ) 2530 // This is for removals 2531 jQuery.each([ "width", "height" ], function( i, name ) { 2532 jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { 2533 set: function( elem, value ) { 2534 if ( value === "" ) { 2535 elem.setAttribute( name, "auto" ); 2536 return value; 2537 } 2538 } 2539 }); 2540 }); 2541 2542 // Set contenteditable to false on removals(#10429) 2543 // Setting to empty string throws an error as an invalid value 2544 jQuery.attrHooks.contenteditable = { 2545 get: nodeHook.get, 2546 set: function( elem, value, name ) { 2547 if ( value === "" ) { 2548 value = "false"; 2549 } 2550 nodeHook.set( elem, value, name ); 2551 } 2552 }; 2553 } 2554 2555 2556 // Some attributes require a special call on IE 2557 if ( !jQuery.support.hrefNormalized ) { 2558 jQuery.each([ "href", "src", "width", "height" ], function( i, name ) { 2559 jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { 2560 get: function( elem ) { 2561 var ret = elem.getAttribute( name, 2 ); 2562 return ret === null ? undefined : ret; 2563 } 2564 }); 2565 }); 2566 } 2567 2568 if ( !jQuery.support.style ) { 2569 jQuery.attrHooks.style = { 2570 get: function( elem ) { 2571 // Return undefined in the case of empty string 2572 // Normalize to lowercase since IE uppercases css property names 2573 return elem.style.cssText.toLowerCase() || undefined; 2574 }, 2575 set: function( elem, value ) { 2576 return ( elem.style.cssText = value + "" ); 2577 } 2578 }; 2579 } 2580 2581 // Safari mis-reports the default selected property of an option 2582 // Accessing the parent's selectedIndex property fixes it 2583 if ( !jQuery.support.optSelected ) { 2584 jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, { 2585 get: function( elem ) { 2586 var parent = elem.parentNode; 2587 2588 if ( parent ) { 2589 parent.selectedIndex; 2590 2591 // Make sure that it also works with optgroups, see #5701 2592 if ( parent.parentNode ) { 2593 parent.parentNode.selectedIndex; 2594 } 2595 } 2596 return null; 2597 } 2598 }); 2599 } 2600 2601 // IE6/7 call enctype encoding 2602 if ( !jQuery.support.enctype ) { 2603 jQuery.propFix.enctype = "encoding"; 2604 } 2605 2606 // Radios and checkboxes getter/setter 2607 if ( !jQuery.support.checkOn ) { 2608 jQuery.each([ "radio", "checkbox" ], function() { 2609 jQuery.valHooks[ this ] = { 2610 get: function( elem ) { 2611 // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified 2612 return elem.getAttribute("value") === null ? "on" : elem.value; 2613 } 2614 }; 2615 }); 2616 } 2617 jQuery.each([ "radio", "checkbox" ], function() { 2618 jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], { 2619 set: function( elem, value ) { 2620 if ( jQuery.isArray( value ) ) { 2621 return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 ); 2622 } 2623 } 2624 }); 2625 }); 2626 var rformElems = /^(?:textarea|input|select)$/i, 2627 rtypenamespace = /^([^\.]*|)(?:\.(.+)|)$/, 2628 rhoverHack = /(?:^|\s)hover(\.\S+|)\b/, 2629 rkeyEvent = /^key/, 2630 rmouseEvent = /^(?:mouse|contextmenu)|click/, 2631 rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, 2632 hoverHack = function( events ) { 2633 return jQuery.event.special.hover ? events : events.replace( rhoverHack, "mouseenter$1 mouseleave$1" ); 2634 }; 2635 2636 /* 2637 * Helper functions for managing events -- not part of the public interface. 2638 * Props to Dean Edwards' addEvent library for many of the ideas. 2639 */ 2640 jQuery.event = { 2641 2642 add: function( elem, types, handler, data, selector ) { 2643 2644 var elemData, eventHandle, events, 2645 t, tns, type, namespaces, handleObj, 2646 handleObjIn, handlers, special; 2647 2648 // Don't attach events to noData or text/comment nodes (allow plain objects tho) 2649 if ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = jQuery._data( elem )) ) { 2650 return; 2651 } 2652 2653 // Caller can pass in an object of custom data in lieu of the handler 2654 if ( handler.handler ) { 2655 handleObjIn = handler; 2656 handler = handleObjIn.handler; 2657 selector = handleObjIn.selector; 2658 } 2659 2660 // Make sure that the handler has a unique ID, used to find/remove it later 2661 if ( !handler.guid ) { 2662 handler.guid = jQuery.guid++; 2663 } 2664 2665 // Init the element's event structure and main handler, if this is the first 2666 events = elemData.events; 2667 if ( !events ) { 2668 elemData.events = events = {}; 2669 } 2670 eventHandle = elemData.handle; 2671 if ( !eventHandle ) { 2672 elemData.handle = eventHandle = function( e ) { 2673 // Discard the second event of a jQuery.event.trigger() and 2674 // when an event is called after a page has unloaded 2675 return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ? 2676 jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : 2677 undefined; 2678 }; 2679 // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events 2680 eventHandle.elem = elem; 2681 } 2682 2683 // Handle multiple events separated by a space 2684 // jQuery(...).bind("mouseover mouseout", fn); 2685 types = jQuery.trim( hoverHack(types) ).split( " " ); 2686 for ( t = 0; t < types.length; t++ ) { 2687 2688 tns = rtypenamespace.exec( types[t] ) || []; 2689 type = tns[1]; 2690 namespaces = ( tns[2] || "" ).split( "." ).sort(); 2691 2692 // If event changes its type, use the special event handlers for the changed type 2693 special = jQuery.event.special[ type ] || {}; 2694 2695 // If selector defined, determine special event api type, otherwise given type 2696 type = ( selector ? special.delegateType : special.bindType ) || type; 2697 2698 // Update special based on newly reset type 2699 special = jQuery.event.special[ type ] || {}; 2700 2701 // handleObj is passed to all event handlers 2702 handleObj = jQuery.extend({ 2703 type: type, 2704 origType: tns[1], 2705 data: data, 2706 handler: handler, 2707 guid: handler.guid, 2708 selector: selector, 2709 needsContext: selector && jQuery.expr.match.needsContext.test( selector ), 2710 namespace: namespaces.join(".") 2711 }, handleObjIn ); 2712 2713 // Init the event handler queue if we're the first 2714 handlers = events[ type ]; 2715 if ( !handlers ) { 2716 handlers = events[ type ] = []; 2717 handlers.delegateCount = 0; 2718 2719 // Only use addEventListener/attachEvent if the special events handler returns false 2720 if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { 2721 // Bind the global event handler to the element 2722 if ( elem.addEventListener ) { 2723 elem.addEventListener( type, eventHandle, false ); 2724 2725 } else if ( elem.attachEvent ) { 2726 elem.attachEvent( "on" + type, eventHandle ); 2727 } 2728 } 2729 } 2730 2731 if ( special.add ) { 2732 special.add.call( elem, handleObj ); 2733 2734 if ( !handleObj.handler.guid ) { 2735 handleObj.handler.guid = handler.guid; 2736 } 2737 } 2738 2739 // Add to the element's handler list, delegates in front 2740 if ( selector ) { 2741 handlers.splice( handlers.delegateCount++, 0, handleObj ); 2742 } else { 2743 handlers.push( handleObj ); 2744 } 2745 2746 // Keep track of which events have ever been used, for event optimization 2747 jQuery.event.global[ type ] = true; 2748 } 2749 2750 // Nullify elem to prevent memory leaks in IE 2751 elem = null; 2752 }, 2753 2754 global: {}, 2755 2756 // Detach an event or set of events from an element 2757 remove: function( elem, types, handler, selector, mappedTypes ) { 2758 2759 var t, tns, type, origType, namespaces, origCount, 2760 j, events, special, eventType, handleObj, 2761 elemData = jQuery.hasData( elem ) && jQuery._data( elem ); 2762 2763 if ( !elemData || !(events = elemData.events) ) { 2764 return; 2765 } 2766 2767 // Once for each type.namespace in types; type may be omitted 2768 types = jQuery.trim( hoverHack( types || "" ) ).split(" "); 2769 for ( t = 0; t < types.length; t++ ) { 2770 tns = rtypenamespace.exec( types[t] ) || []; 2771 type = origType = tns[1]; 2772 namespaces = tns[2]; 2773 2774 // Unbind all events (on this namespace, if provided) for the element 2775 if ( !type ) { 2776 for ( type in events ) { 2777 jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); 2778 } 2779 continue; 2780 } 2781 2782 special = jQuery.event.special[ type ] || {}; 2783 type = ( selector? special.delegateType : special.bindType ) || type; 2784 eventType = events[ type ] || []; 2785 origCount = eventType.length; 2786 namespaces = namespaces ? new RegExp("(^|\\.)" + namespaces.split(".").sort().join("\\.(?:.*\\.|)") + "(\\.|$)") : null; 2787 2788 // Remove matching events 2789 for ( j = 0; j < eventType.length; j++ ) { 2790 handleObj = eventType[ j ]; 2791 2792 if ( ( mappedTypes || origType === handleObj.origType ) && 2793 ( !handler || handler.guid === handleObj.guid ) && 2794 ( !namespaces || namespaces.test( handleObj.namespace ) ) && 2795 ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { 2796 eventType.splice( j--, 1 ); 2797 2798 if ( handleObj.selector ) { 2799 eventType.delegateCount--; 2800 } 2801 if ( special.remove ) { 2802 special.remove.call( elem, handleObj ); 2803 } 2804 } 2805 } 2806 2807 // Remove generic event handler if we removed something and no more handlers exist 2808 // (avoids potential for endless recursion during removal of special event handlers) 2809 if ( eventType.length === 0 && origCount !== eventType.length ) { 2810 if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) { 2811 jQuery.removeEvent( elem, type, elemData.handle ); 2812 } 2813 2814 delete events[ type ]; 2815 } 2816 } 2817 2818 // Remove the expando if it's no longer used 2819 if ( jQuery.isEmptyObject( events ) ) { 2820 delete elemData.handle; 2821 2822 // removeData also checks for emptiness and clears the expando if empty 2823 // so use it instead of delete 2824 jQuery.removeData( elem, "events", true ); 2825 } 2826 }, 2827 2828 // Events that are safe to short-circuit if no handlers are attached. 2829 // Native DOM events should not be added, they may have inline handlers. 2830 customEvent: { 2831 "getData": true, 2832 "setData": true, 2833 "changeData": true 2834 }, 2835 2836 trigger: function( event, data, elem, onlyHandlers ) { 2837 // Don't do events on text and comment nodes 2838 if ( elem && (elem.nodeType === 3 || elem.nodeType === 8) ) { 2839 return; 2840 } 2841 2842 // Event object or event type 2843 var cache, exclusive, i, cur, old, ontype, special, handle, eventPath, bubbleType, 2844 type = event.type || event, 2845 namespaces = []; 2846 2847 // focus/blur morphs to focusin/out; ensure we're not firing them right now 2848 if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { 2849 return; 2850 } 2851 2852 if ( type.indexOf( "!" ) >= 0 ) { 2853 // Exclusive events trigger only for the exact event (no namespaces) 2854 type = type.slice(0, -1); 2855 exclusive = true; 2856 } 2857 2858 if ( type.indexOf( "." ) >= 0 ) { 2859 // Namespaced trigger; create a regexp to match event type in handle() 2860 namespaces = type.split("."); 2861 type = namespaces.shift(); 2862 namespaces.sort(); 2863 } 2864 2865 if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) { 2866 // No jQuery handlers for this event type, and it can't have inline handlers 2867 return; 2868 } 2869 2870 // Caller can pass in an Event, Object, or just an event type string 2871 event = typeof event === "object" ? 2872 // jQuery.Event object 2873 event[ jQuery.expando ] ? event : 2874 // Object literal 2875 new jQuery.Event( type, event ) : 2876 // Just the event type (string) 2877 new jQuery.Event( type ); 2878 2879 event.type = type; 2880 event.isTrigger = true; 2881 event.exclusive = exclusive; 2882 event.namespace = namespaces.join( "." ); 2883 event.namespace_re = event.namespace? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)") : null; 2884 ontype = type.indexOf( ":" ) < 0 ? "on" + type : ""; 2885 2886 // Handle a global trigger 2887 if ( !elem ) { 2888 2889 // TODO: Stop taunting the data cache; remove global events and always attach to document 2890 cache = jQuery.cache; 2891 for ( i in cache ) { 2892 if ( cache[ i ].events && cache[ i ].events[ type ] ) { 2893 jQuery.event.trigger( event, data, cache[ i ].handle.elem, true ); 2894 } 2895 } 2896 return; 2897 } 2898 2899 // Clean up the event in case it is being reused 2900 event.result = undefined; 2901 if ( !event.target ) { 2902 event.target = elem; 2903 } 2904 2905 // Clone any incoming data and prepend the event, creating the handler arg list 2906 data = data != null ? jQuery.makeArray( data ) : []; 2907 data.unshift( event ); 2908 2909 // Allow special events to draw outside the lines 2910 special = jQuery.event.special[ type ] || {}; 2911 if ( special.trigger && special.trigger.apply( elem, data ) === false ) { 2912 return; 2913 } 2914 2915 // Determine event propagation path in advance, per W3C events spec (#9951) 2916 // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) 2917 eventPath = [[ elem, special.bindType || type ]]; 2918 if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { 2919 2920 bubbleType = special.delegateType || type; 2921 cur = rfocusMorph.test( bubbleType + type ) ? elem : elem.parentNode; 2922 for ( old = elem; cur; cur = cur.parentNode ) { 2923 eventPath.push([ cur, bubbleType ]); 2924 old = cur; 2925 } 2926 2927 // Only add window if we got to document (e.g., not plain obj or detached DOM) 2928 if ( old === (elem.ownerDocument || document) ) { 2929 eventPath.push([ old.defaultView || old.parentWindow || window, bubbleType ]); 2930 } 2931 } 2932 2933 // Fire handlers on the event path 2934 for ( i = 0; i < eventPath.length && !event.isPropagationStopped(); i++ ) { 2935 2936 cur = eventPath[i][0]; 2937 event.type = eventPath[i][1]; 2938 2939 handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" ); 2940 if ( handle ) { 2941 handle.apply( cur, data ); 2942 } 2943 // Note that this is a bare JS function and not a jQuery handler 2944 handle = ontype && cur[ ontype ]; 2945 if ( handle && jQuery.acceptData( cur ) && handle.apply && handle.apply( cur, data ) === false ) { 2946 event.preventDefault(); 2947 } 2948 } 2949 event.type = type; 2950 2951 // If nobody prevented the default action, do it now 2952 if ( !onlyHandlers && !event.isDefaultPrevented() ) { 2953 2954 if ( (!special._default || special._default.apply( elem.ownerDocument, data ) === false) && 2955 !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) { 2956 2957 // Call a native DOM method on the target with the same name name as the event. 2958 // Can't use an .isFunction() check here because IE6/7 fails that test. 2959 // Don't do default actions on window, that's where global variables be (#6170) 2960 // IE<9 dies on focus/blur to hidden element (#1486) 2961 if ( ontype && elem[ type ] && ((type !== "focus" && type !== "blur") || event.target.offsetWidth !== 0) && !jQuery.isWindow( elem ) ) { 2962 2963 // Don't re-trigger an onFOO event when we call its FOO() method 2964 old = elem[ ontype ]; 2965 2966 if ( old ) { 2967 elem[ ontype ] = null; 2968 } 2969 2970 // Prevent re-triggering of the same event, since we already bubbled it above 2971 jQuery.event.triggered = type; 2972 elem[ type ](); 2973 jQuery.event.triggered = undefined; 2974 2975 if ( old ) { 2976 elem[ ontype ] = old; 2977 } 2978 } 2979 } 2980 } 2981 2982 return event.result; 2983 }, 2984 2985 dispatch: function( event ) { 2986 2987 // Make a writable jQuery.Event from the native event object 2988 event = jQuery.event.fix( event || window.event ); 2989 2990 var i, j, cur, ret, selMatch, matched, matches, handleObj, sel, related, 2991 handlers = ( (jQuery._data( this, "events" ) || {} )[ event.type ] || []), 2992 delegateCount = handlers.delegateCount, 2993 args = core_slice.call( arguments ), 2994 run_all = !event.exclusive && !event.namespace, 2995 special = jQuery.event.special[ event.type ] || {}, 2996 handlerQueue = []; 2997 2998 // Use the fix-ed jQuery.Event rather than the (read-only) native event 2999 args[0] = event; 3000 event.delegateTarget = this; 3001 3002 // Call the preDispatch hook for the mapped type, and let it bail if desired 3003 if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { 3004 return; 3005 } 3006 3007 // Determine handlers that should run if there are delegated events 3008 // Avoid non-left-click bubbling in Firefox (#3861) 3009 if ( delegateCount && !(event.button && event.type === "click") ) { 3010 3011 for ( cur = event.target; cur != this; cur = cur.parentNode || this ) { 3012 3013 // Don't process clicks (ONLY) on disabled elements (#6911, #8165, #11382, #11764) 3014 if ( cur.disabled !== true || event.type !== "click" ) { 3015 selMatch = {}; 3016 matches = []; 3017 for ( i = 0; i < delegateCount; i++ ) { 3018 handleObj = handlers[ i ]; 3019 sel = handleObj.selector; 3020 3021 if ( selMatch[ sel ] === undefined ) { 3022 selMatch[ sel ] = handleObj.needsContext ? 3023 jQuery( sel, this ).index( cur ) >= 0 : 3024 jQuery.find( sel, this, null, [ cur ] ).length; 3025 } 3026 if ( selMatch[ sel ] ) { 3027 matches.push( handleObj ); 3028 } 3029 } 3030 if ( matches.length ) { 3031 handlerQueue.push({ elem: cur, matches: matches }); 3032 } 3033 } 3034 } 3035 } 3036 3037 // Add the remaining (directly-bound) handlers 3038 if ( handlers.length > delegateCount ) { 3039 handlerQueue.push({ elem: this, matches: handlers.slice( delegateCount ) }); 3040 } 3041 3042 // Run delegates first; they may want to stop propagation beneath us 3043 for ( i = 0; i < handlerQueue.length && !event.isPropagationStopped(); i++ ) { 3044 matched = handlerQueue[ i ]; 3045 event.currentTarget = matched.elem; 3046 3047 for ( j = 0; j < matched.matches.length && !event.isImmediatePropagationStopped(); j++ ) { 3048 handleObj = matched.matches[ j ]; 3049 3050 // Triggered event must either 1) be non-exclusive and have no namespace, or 3051 // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). 3052 if ( run_all || (!event.namespace && !handleObj.namespace) || event.namespace_re && event.namespace_re.test( handleObj.namespace ) ) { 3053 3054 event.data = handleObj.data; 3055 event.handleObj = handleObj; 3056 3057 ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) 3058 .apply( matched.elem, args ); 3059 3060 if ( ret !== undefined ) { 3061 event.result = ret; 3062 if ( ret === false ) { 3063 event.preventDefault(); 3064 event.stopPropagation(); 3065 } 3066 } 3067 } 3068 } 3069 } 3070 3071 // Call the postDispatch hook for the mapped type 3072 if ( special.postDispatch ) { 3073 special.postDispatch.call( this, event ); 3074 } 3075 3076 return event.result; 3077 }, 3078 3079 // Includes some event props shared by KeyEvent and MouseEvent 3080 // *** attrChange attrName relatedNode srcElement are not normalized, non-W3C, deprecated, will be removed in 1.8 *** 3081 props: "attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), 3082 3083 fixHooks: {}, 3084 3085 keyHooks: { 3086 props: "char charCode key keyCode".split(" "), 3087 filter: function( event, original ) { 3088 3089 // Add which for key events 3090 if ( event.which == null ) { 3091 event.which = original.charCode != null ? original.charCode : original.keyCode; 3092 } 3093 3094 return event; 3095 } 3096 }, 3097 3098 mouseHooks: { 3099 props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "), 3100 filter: function( event, original ) { 3101 var eventDoc, doc, body, 3102 button = original.button, 3103 fromElement = original.fromElement; 3104 3105 // Calculate pageX/Y if missing and clientX/Y available 3106 if ( event.pageX == null && original.clientX != null ) { 3107 eventDoc = event.target.ownerDocument || document; 3108 doc = eventDoc.documentElement; 3109 body = eventDoc.body; 3110 3111 event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); 3112 event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); 3113 } 3114 3115 // Add relatedTarget, if necessary 3116 if ( !event.relatedTarget && fromElement ) { 3117 event.relatedTarget = fromElement === event.target ? original.toElement : fromElement; 3118 } 3119 3120 // Add which for click: 1 === left; 2 === middle; 3 === right 3121 // Note: button is not normalized, so don't use it 3122 if ( !event.which && button !== undefined ) { 3123 event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); 3124 } 3125 3126 return event; 3127 } 3128 }, 3129 3130 fix: function( event ) { 3131 if ( event[ jQuery.expando ] ) { 3132 return event; 3133 } 3134 3135 // Create a writable copy of the event object and normalize some properties 3136 var i, prop, 3137 originalEvent = event, 3138 fixHook = jQuery.event.fixHooks[ event.type ] || {}, 3139 copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; 3140 3141 event = jQuery.Event( originalEvent ); 3142 3143 for ( i = copy.length; i; ) { 3144 prop = copy[ --i ]; 3145 event[ prop ] = originalEvent[ prop ]; 3146 } 3147 3148 // Fix target property, if necessary (#1925, IE 6/7/8 & Safari2) 3149 if ( !event.target ) { 3150 event.target = originalEvent.srcElement || document; 3151 } 3152 3153 // Target should not be a text node (#504, Safari) 3154 if ( event.target.nodeType === 3 ) { 3155 event.target = event.target.parentNode; 3156 } 3157 3158 // For mouse/key events, metaKey==false if it's undefined (#3368, #11328; IE6/7/8) 3159 event.metaKey = !!event.metaKey; 3160 3161 return fixHook.filter? fixHook.filter( event, originalEvent ) : event; 3162 }, 3163 3164 special: { 3165 load: { 3166 // Prevent triggered image.load events from bubbling to window.load 3167 noBubble: true 3168 }, 3169 3170 focus: { 3171 delegateType: "focusin" 3172 }, 3173 blur: { 3174 delegateType: "focusout" 3175 }, 3176 3177 beforeunload: { 3178 setup: function( data, namespaces, eventHandle ) { 3179 // We only want to do this special case on windows 3180 if ( jQuery.isWindow( this ) ) { 3181 this.onbeforeunload = eventHandle; 3182 } 3183 }, 3184 3185 teardown: function( namespaces, eventHandle ) { 3186 if ( this.onbeforeunload === eventHandle ) { 3187 this.onbeforeunload = null; 3188 } 3189 } 3190 } 3191 }, 3192 3193 simulate: function( type, elem, event, bubble ) { 3194 // Piggyback on a donor event to simulate a different one. 3195 // Fake originalEvent to avoid donor's stopPropagation, but if the 3196 // simulated event prevents default then we do the same on the donor. 3197 var e = jQuery.extend( 3198 new jQuery.Event(), 3199 event, 3200 { type: type, 3201 isSimulated: true, 3202 originalEvent: {} 3203 } 3204 ); 3205 if ( bubble ) { 3206 jQuery.event.trigger( e, null, elem ); 3207 } else { 3208 jQuery.event.dispatch.call( elem, e ); 3209 } 3210 if ( e.isDefaultPrevented() ) { 3211 event.preventDefault(); 3212 } 3213 } 3214 }; 3215 3216 // Some plugins are using, but it's undocumented/deprecated and will be removed. 3217 // The 1.7 special event interface should provide all the hooks needed now. 3218 jQuery.event.handle = jQuery.event.dispatch; 3219 3220 jQuery.removeEvent = document.removeEventListener ? 3221 function( elem, type, handle ) { 3222 if ( elem.removeEventListener ) { 3223 elem.removeEventListener( type, handle, false ); 3224 } 3225 } : 3226 function( elem, type, handle ) { 3227 var name = "on" + type; 3228 3229 if ( elem.detachEvent ) { 3230 3231 // #8545, #7054, preventing memory leaks for custom events in IE6-8 3232 // detachEvent needed property on element, by name of that event, to properly expose it to GC 3233 if ( typeof elem[ name ] === "undefined" ) { 3234 elem[ name ] = null; 3235 } 3236 3237 elem.detachEvent( name, handle ); 3238 } 3239 }; 3240 3241 jQuery.Event = function( src, props ) { 3242 // Allow instantiation without the 'new' keyword 3243 if ( !(this instanceof jQuery.Event) ) { 3244 return new jQuery.Event( src, props ); 3245 } 3246 3247 // Event object 3248 if ( src && src.type ) { 3249 this.originalEvent = src; 3250 this.type = src.type; 3251 3252 // Events bubbling up the document may have been marked as prevented 3253 // by a handler lower down the tree; reflect the correct value. 3254 this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false || 3255 src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse; 3256 3257 // Event type 3258 } else { 3259 this.type = src; 3260 } 3261 3262 // Put explicitly provided properties onto the event object 3263 if ( props ) { 3264 jQuery.extend( this, props ); 3265 } 3266 3267 // Create a timestamp if incoming event doesn't have one 3268 this.timeStamp = src && src.timeStamp || jQuery.now(); 3269 3270 // Mark it as fixed 3271 this[ jQuery.expando ] = true; 3272 }; 3273 3274 function returnFalse() { 3275 return false; 3276 } 3277 function returnTrue() { 3278 return true; 3279 } 3280 3281 // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding 3282 // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html 3283 jQuery.Event.prototype = { 3284 preventDefault: function() { 3285 this.isDefaultPrevented = returnTrue; 3286 3287 var e = this.originalEvent; 3288 if ( !e ) { 3289 return; 3290 } 3291 3292 // if preventDefault exists run it on the original event 3293 if ( e.preventDefault ) { 3294 e.preventDefault(); 3295 3296 // otherwise set the returnValue property of the original event to false (IE) 3297 } else { 3298 e.returnValue = false; 3299 } 3300 }, 3301 stopPropagation: function() { 3302 this.isPropagationStopped = returnTrue; 3303 3304 var e = this.originalEvent; 3305 if ( !e ) { 3306 return; 3307 } 3308 // if stopPropagation exists run it on the original event 3309 if ( e.stopPropagation ) { 3310 e.stopPropagation(); 3311 } 3312 // otherwise set the cancelBubble property of the original event to true (IE) 3313 e.cancelBubble = true; 3314 }, 3315 stopImmediatePropagation: function() { 3316 this.isImmediatePropagationStopped = returnTrue; 3317 this.stopPropagation(); 3318 }, 3319 isDefaultPrevented: returnFalse, 3320 isPropagationStopped: returnFalse, 3321 isImmediatePropagationStopped: returnFalse 3322 }; 3323 3324 // Create mouseenter/leave events using mouseover/out and event-time checks 3325 jQuery.each({ 3326 mouseenter: "mouseover", 3327 mouseleave: "mouseout" 3328 }, function( orig, fix ) { 3329 jQuery.event.special[ orig ] = { 3330 delegateType: fix, 3331 bindType: fix, 3332 3333 handle: function( event ) { 3334 var ret, 3335 target = this, 3336 related = event.relatedTarget, 3337 handleObj = event.handleObj, 3338 selector = handleObj.selector; 3339 3340 // For mousenter/leave call the handler if related is outside the target. 3341 // NB: No relatedTarget if the mouse left/entered the browser window 3342 if ( !related || (related !== target && !jQuery.contains( target, related )) ) { 3343 event.type = handleObj.origType; 3344 ret = handleObj.handler.apply( this, arguments ); 3345 event.type = fix; 3346 } 3347 return ret; 3348 } 3349 }; 3350 }); 3351 3352 // IE submit delegation 3353 if ( !jQuery.support.submitBubbles ) { 3354 3355 jQuery.event.special.submit = { 3356 setup: function() { 3357 // Only need this for delegated form submit events 3358 if ( jQuery.nodeName( this, "form" ) ) { 3359 return false; 3360 } 3361 3362 // Lazy-add a submit handler when a descendant form may potentially be submitted 3363 jQuery.event.add( this, "click._submit keypress._submit", function( e ) { 3364 // Node name check avoids a VML-related crash in IE (#9807) 3365 var elem = e.target, 3366 form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined; 3367 if ( form && !jQuery._data( form, "_submit_attached" ) ) { 3368 jQuery.event.add( form, "submit._submit", function( event ) { 3369 event._submit_bubble = true; 3370 }); 3371 jQuery._data( form, "_submit_attached", true ); 3372 } 3373 }); 3374 // return undefined since we don't need an event listener 3375 }, 3376 3377 postDispatch: function( event ) { 3378 // If form was submitted by the user, bubble the event up the tree 3379 if ( event._submit_bubble ) { 3380 delete event._submit_bubble; 3381 if ( this.parentNode && !event.isTrigger ) { 3382 jQuery.event.simulate( "submit", this.parentNode, event, true ); 3383 } 3384 } 3385 }, 3386 3387 teardown: function() { 3388 // Only need this for delegated form submit events 3389 if ( jQuery.nodeName( this, "form" ) ) { 3390 return false; 3391 } 3392 3393 // Remove delegated handlers; cleanData eventually reaps submit handlers attached above 3394 jQuery.event.remove( this, "._submit" ); 3395 } 3396 }; 3397 } 3398 3399 // IE change delegation and checkbox/radio fix 3400 if ( !jQuery.support.changeBubbles ) { 3401 3402 jQuery.event.special.change = { 3403 3404 setup: function() { 3405 3406 if ( rformElems.test( this.nodeName ) ) { 3407 // IE doesn't fire change on a check/radio until blur; trigger it on click 3408 // after a propertychange. Eat the blur-change in special.change.handle. 3409 // This still fires onchange a second time for check/radio after blur. 3410 if ( this.type === "checkbox" || this.type === "radio" ) { 3411 jQuery.event.add( this, "propertychange._change", function( event ) { 3412 if ( event.originalEvent.propertyName === "checked" ) { 3413 this._just_changed = true; 3414 } 3415 }); 3416 jQuery.event.add( this, "click._change", function( event ) { 3417 if ( this._just_changed && !event.isTrigger ) { 3418 this._just_changed = false; 3419 } 3420 // Allow triggered, simulated change events (#11500) 3421 jQuery.event.simulate( "change", this, event, true ); 3422 }); 3423 } 3424 return false; 3425 } 3426 // Delegated event; lazy-add a change handler on descendant inputs 3427 jQuery.event.add( this, "beforeactivate._change", function( e ) { 3428 var elem = e.target; 3429 3430 if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "_change_attached" ) ) { 3431 jQuery.event.add( elem, "change._change", function( event ) { 3432 if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { 3433 jQuery.event.simulate( "change", this.parentNode, event, true ); 3434 } 3435 }); 3436 jQuery._data( elem, "_change_attached", true ); 3437 } 3438 }); 3439 }, 3440 3441 handle: function( event ) { 3442 var elem = event.target; 3443 3444 // Swallow native change events from checkbox/radio, we already triggered them above 3445 if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) { 3446 return event.handleObj.handler.apply( this, arguments ); 3447 } 3448 }, 3449 3450 teardown: function() { 3451 jQuery.event.remove( this, "._change" ); 3452 3453 return !rformElems.test( this.nodeName ); 3454 } 3455 }; 3456 } 3457 3458 // Create "bubbling" focus and blur events 3459 if ( !jQuery.support.focusinBubbles ) { 3460 jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { 3461 3462 // Attach a single capturing handler while someone wants focusin/focusout 3463 var attaches = 0, 3464 handler = function( event ) { 3465 jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); 3466 }; 3467 3468 jQuery.event.special[ fix ] = { 3469 setup: function() { 3470 if ( attaches++ === 0 ) { 3471 document.addEventListener( orig, handler, true ); 3472 } 3473 }, 3474 teardown: function() { 3475 if ( --attaches === 0 ) { 3476 document.removeEventListener( orig, handler, true ); 3477 } 3478 } 3479 }; 3480 }); 3481 } 3482 3483 jQuery.fn.extend({ 3484 3485 on: function( types, selector, data, fn, /*INTERNAL*/ one ) { 3486 var origFn, type; 3487 3488 // Types can be a map of types/handlers 3489 if ( typeof types === "object" ) { 3490 // ( types-Object, selector, data ) 3491 if ( typeof selector !== "string" ) { // && selector != null 3492 // ( types-Object, data ) 3493 data = data || selector; 3494 selector = undefined; 3495 } 3496 for ( type in types ) { 3497 this.on( type, selector, data, types[ type ], one ); 3498 } 3499 return this; 3500 } 3501 3502 if ( data == null && fn == null ) { 3503 // ( types, fn ) 3504 fn = selector; 3505 data = selector = undefined; 3506 } else if ( fn == null ) { 3507 if ( typeof selector === "string" ) { 3508 // ( types, selector, fn ) 3509 fn = data; 3510 data = undefined; 3511 } else { 3512 // ( types, data, fn ) 3513 fn = data; 3514 data = selector; 3515 selector = undefined; 3516 } 3517 } 3518 if ( fn === false ) { 3519 fn = returnFalse; 3520 } else if ( !fn ) { 3521 return this; 3522 } 3523 3524 if ( one === 1 ) { 3525 origFn = fn; 3526 fn = function( event ) { 3527 // Can use an empty set, since event contains the info 3528 jQuery().off( event ); 3529 return origFn.apply( this, arguments ); 3530 }; 3531 // Use same guid so caller can remove using origFn 3532 fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); 3533 } 3534 return this.each( function() { 3535 jQuery.event.add( this, types, fn, data, selector ); 3536 }); 3537 }, 3538 one: function( types, selector, data, fn ) { 3539 return this.on( types, selector, data, fn, 1 ); 3540 }, 3541 off: function( types, selector, fn ) { 3542 var handleObj, type; 3543 if ( types && types.preventDefault && types.handleObj ) { 3544 // ( event ) dispatched jQuery.Event 3545 handleObj = types.handleObj; 3546 jQuery( types.delegateTarget ).off( 3547 handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, 3548 handleObj.selector, 3549 handleObj.handler 3550 ); 3551 return this; 3552 } 3553 if ( typeof types === "object" ) { 3554 // ( types-object [, selector] ) 3555 for ( type in types ) { 3556 this.off( type, selector, types[ type ] ); 3557 } 3558 return this; 3559 } 3560 if ( selector === false || typeof selector === "function" ) { 3561 // ( types [, fn] ) 3562 fn = selector; 3563 selector = undefined; 3564 } 3565 if ( fn === false ) { 3566 fn = returnFalse; 3567 } 3568 return this.each(function() { 3569 jQuery.event.remove( this, types, fn, selector ); 3570 }); 3571 }, 3572 3573 bind: function( types, data, fn ) { 3574 return this.on( types, null, data, fn ); 3575 }, 3576 unbind: function( types, fn ) { 3577 return this.off( types, null, fn ); 3578 }, 3579 3580 live: function( types, data, fn ) { 3581 jQuery( this.context ).on( types, this.selector, data, fn ); 3582 return this; 3583 }, 3584 die: function( types, fn ) { 3585 jQuery( this.context ).off( types, this.selector || "**", fn ); 3586 return this; 3587 }, 3588 3589 delegate: function( selector, types, data, fn ) { 3590 return this.on( types, selector, data, fn ); 3591 }, 3592 undelegate: function( selector, types, fn ) { 3593 // ( namespace ) or ( selector, types [, fn] ) 3594 return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn ); 3595 }, 3596 3597 trigger: function( type, data ) { 3598 return this.each(function() { 3599 jQuery.event.trigger( type, data, this ); 3600 }); 3601 }, 3602 triggerHandler: function( type, data ) { 3603 if ( this[0] ) { 3604 return jQuery.event.trigger( type, data, this[0], true ); 3605 } 3606 }, 3607 3608 toggle: function( fn ) { 3609 // Save reference to arguments for access in closure 3610 var args = arguments, 3611 guid = fn.guid || jQuery.guid++, 3612 i = 0, 3613 toggler = function( event ) { 3614 // Figure out which function to execute 3615 var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i; 3616 jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 ); 3617 3618 // Make sure that clicks stop 3619 event.preventDefault(); 3620 3621 // and execute the function 3622 return args[ lastToggle ].apply( this, arguments ) || false; 3623 }; 3624 3625 // link all the functions, so any of them can unbind this click handler 3626 toggler.guid = guid; 3627 while ( i < args.length ) { 3628 args[ i++ ].guid = guid; 3629 } 3630 3631 return this.click( toggler ); 3632 }, 3633 3634 hover: function( fnOver, fnOut ) { 3635 return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); 3636 } 3637 }); 3638 3639 jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " + 3640 "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + 3641 "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) { 3642 3643 // Handle event binding 3644 jQuery.fn[ name ] = function( data, fn ) { 3645 if ( fn == null ) { 3646 fn = data; 3647 data = null; 3648 } 3649 3650 return arguments.length > 0 ? 3651 this.on( name, null, data, fn ) : 3652 this.trigger( name ); 3653 }; 3654 3655 if ( rkeyEvent.test( name ) ) { 3656 jQuery.event.fixHooks[ name ] = jQuery.event.keyHooks; 3657 } 3658 3659 if ( rmouseEvent.test( name ) ) { 3660 jQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks; 3661 } 3662 }); 3663 /*! 3664 * Sizzle CSS Selector Engine 3665 * Copyright 2012 jQuery Foundation and other contributors 3666 * Released under the MIT license 3667 * http://sizzlejs.com/ 3668 */ 3669 (function( window, undefined ) { 3670 3671 var cachedruns, 3672 assertGetIdNotName, 3673 Expr, 3674 getText, 3675 isXML, 3676 contains, 3677 compile, 3678 sortOrder, 3679 hasDuplicate, 3680 outermostContext, 3681 3682 baseHasDuplicate = true, 3683 strundefined = "undefined", 3684 3685 expando = ( "sizcache" + Math.random() ).replace( ".", "" ), 3686 3687 Token = String, 3688 document = window.document, 3689 docElem = document.documentElement, 3690 dirruns = 0, 3691 done = 0, 3692 pop = [].pop, 3693 push = [].push, 3694 slice = [].slice, 3695 // Use a stripped-down indexOf if a native one is unavailable 3696 indexOf = [].indexOf || function( elem ) { 3697 var i = 0, 3698 len = this.length; 3699 for ( ; i < len; i++ ) { 3700 if ( this[i] === elem ) { 3701 return i; 3702 } 3703 } 3704 return -1; 3705 }, 3706 3707 // Augment a function for special use by Sizzle 3708 markFunction = function( fn, value ) { 3709 fn[ expando ] = value == null || value; 3710 return fn; 3711 }, 3712 3713 createCache = function() { 3714 var cache = {}, 3715 keys = []; 3716 3717 return markFunction(function( key, value ) { 3718 // Only keep the most recent entries 3719 if ( keys.push( key ) > Expr.cacheLength ) { 3720 delete cache[ keys.shift() ]; 3721 } 3722 3723 // Retrieve with (key + " ") to avoid collision with native Object.prototype properties (see Issue #157) 3724 return (cache[ key + " " ] = value); 3725 }, cache ); 3726 }, 3727 3728 classCache = createCache(), 3729 tokenCache = createCache(), 3730 compilerCache = createCache(), 3731 3732 // Regex 3733 3734 // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace 3735 whitespace = "[\\x20\\t\\r\\n\\f]", 3736 // http://www.w3.org/TR/css3-syntax/#characters 3737 characterEncoding = "(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+", 3738 3739 // Loosely modeled on CSS identifier characters 3740 // An unquoted value should be a CSS identifier (http://www.w3.org/TR/css3-selectors/#attribute-selectors) 3741 // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier 3742 identifier = characterEncoding.replace( "w", "w#" ), 3743 3744 // Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors 3745 operators = "([*^$|!~]?=)", 3746 attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace + 3747 "*(?:" + operators + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]", 3748 3749 // Prefer arguments not in parens/brackets, 3750 // then attribute selectors and non-pseudos (denoted by :), 3751 // then anything else 3752 // These preferences are here to reduce the number of selectors 3753 // needing tokenize in the PSEUDO preFilter 3754 pseudos = ":(" + characterEncoding + ")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:" + attributes + ")|[^:]|\\\\.)*|.*))\\)|)", 3755 3756 // For matchExpr.POS and matchExpr.needsContext 3757 pos = ":(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + 3758 "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", 3759 3760 // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter 3761 rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), 3762 3763 rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), 3764 rcombinators = new RegExp( "^" + whitespace + "*([\\x20\\t\\r\\n\\f>+~])" + whitespace + "*" ), 3765 rpseudo = new RegExp( pseudos ), 3766 3767 // Easily-parseable/retrievable ID or TAG or CLASS selectors 3768 rquickExpr = /^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/, 3769 3770 rnot = /^:not/, 3771 rsibling = /[\x20\t\r\n\f]*[+~]/, 3772 rendsWithNot = /:not\($/, 3773 3774 rheader = /h\d/i, 3775 rinputs = /input|select|textarea|button/i, 3776 3777 rbackslash = /\\(?!\\)/g, 3778 3779 matchExpr = { 3780 "ID": new RegExp( "^#(" + characterEncoding + ")" ), 3781 "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ), 3782 "NAME": new RegExp( "^\\[name=['\"]?(" + characterEncoding + ")['\"]?\\]" ), 3783 "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ), 3784 "ATTR": new RegExp( "^" + attributes ), 3785 "PSEUDO": new RegExp( "^" + pseudos ), 3786 "POS": new RegExp( pos, "i" ), 3787 "CHILD": new RegExp( "^:(only|nth|first|last)-child(?:\\(" + whitespace + 3788 "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + 3789 "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), 3790 // For use in libraries implementing .is() 3791 "needsContext": new RegExp( "^" + whitespace + "*[>+~]|" + pos, "i" ) 3792 }, 3793 3794 // Support 3795 3796 // Used for testing something on an element 3797 assert = function( fn ) { 3798 var div = document.createElement("div"); 3799 3800 try { 3801 return fn( div ); 3802 } catch (e) { 3803 return false; 3804 } finally { 3805 // release memory in IE 3806 div = null; 3807 } 3808 }, 3809 3810 // Check if getElementsByTagName("*") returns only elements 3811 assertTagNameNoComments = assert(function( div ) { 3812 div.appendChild( document.createComment("") ); 3813 return !div.getElementsByTagName("*").length; 3814 }), 3815 3816 // Check if getAttribute returns normalized href attributes 3817 assertHrefNotNormalized = assert(function( div ) { 3818 div.innerHTML = "<a href='#'></a>"; 3819 return div.firstChild && typeof div.firstChild.getAttribute !== strundefined && 3820 div.firstChild.getAttribute("href") === "#"; 3821 }), 3822 3823 // Check if attributes should be retrieved by attribute nodes 3824 assertAttributes = assert(function( div ) { 3825 div.innerHTML = "<select></select>"; 3826 var type = typeof div.lastChild.getAttribute("multiple"); 3827 // IE8 returns a string for some attributes even when not present 3828 return type !== "boolean" && type !== "string"; 3829 }), 3830 3831 // Check if getElementsByClassName can be trusted 3832 assertUsableClassName = assert(function( div ) { 3833 // Opera can't find a second classname (in 9.6) 3834 div.innerHTML = "<div class='hidden e'></div><div class='hidden'></div>"; 3835 if ( !div.getElementsByClassName || !div.getElementsByClassName("e").length ) { 3836 return false; 3837 } 3838 3839 // Safari 3.2 caches class attributes and doesn't catch changes 3840 div.lastChild.className = "e"; 3841 return div.getElementsByClassName("e").length === 2; 3842 }), 3843 3844 // Check if getElementById returns elements by name 3845 // Check if getElementsByName privileges form controls or returns elements by ID 3846 assertUsableName = assert(function( div ) { 3847 // Inject content 3848 div.id = expando + 0; 3849 div.innerHTML = "<a name='" + expando + "'></a><div name='" + expando + "'></div>"; 3850 docElem.insertBefore( div, docElem.firstChild ); 3851 3852 // Test 3853 var pass = document.getElementsByName && 3854 // buggy browsers will return fewer than the correct 2 3855 document.getElementsByName( expando ).length === 2 + 3856 // buggy browsers will return more than the correct 0 3857 document.getElementsByName( expando + 0 ).length; 3858 assertGetIdNotName = !document.getElementById( expando ); 3859 3860 // Cleanup 3861 docElem.removeChild( div ); 3862 3863 return pass; 3864 }); 3865 3866 // If slice is not available, provide a backup 3867 try { 3868 slice.call( docElem.childNodes, 0 )[0].nodeType; 3869 } catch ( e ) { 3870 slice = function( i ) { 3871 var elem, 3872 results = []; 3873 for ( ; (elem = this[i]); i++ ) { 3874 results.push( elem ); 3875 } 3876 return results; 3877 }; 3878 } 3879 3880 function Sizzle( selector, context, results, seed ) { 3881 results = results || []; 3882 context = context || document; 3883 var match, elem, xml, m, 3884 nodeType = context.nodeType; 3885 3886 if ( !selector || typeof selector !== "string" ) { 3887 return results; 3888 } 3889 3890 if ( nodeType !== 1 && nodeType !== 9 ) { 3891 return []; 3892 } 3893 3894 xml = isXML( context ); 3895 3896 if ( !xml && !seed ) { 3897 if ( (match = rquickExpr.exec( selector )) ) { 3898 // Speed-up: Sizzle("#ID") 3899 if ( (m = match[1]) ) { 3900 if ( nodeType === 9 ) { 3901 elem = context.getElementById( m ); 3902 // Check parentNode to catch when Blackberry 4.6 returns 3903 // nodes that are no longer in the document #6963 3904 if ( elem && elem.parentNode ) { 3905 // Handle the case where IE, Opera, and Webkit return items 3906 // by name instead of ID 3907 if ( elem.id === m ) { 3908 results.push( elem ); 3909 return results; 3910 } 3911 } else { 3912 return results; 3913 } 3914 } else { 3915 // Context is not a document 3916 if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) && 3917 contains( context, elem ) && elem.id === m ) { 3918 results.push( elem ); 3919 return results; 3920 } 3921 } 3922 3923 // Speed-up: Sizzle("TAG") 3924 } else if ( match[2] ) { 3925 push.apply( results, slice.call(context.getElementsByTagName( selector ), 0) ); 3926 return results; 3927 3928 // Speed-up: Sizzle(".CLASS") 3929 } else if ( (m = match[3]) && assertUsableClassName && context.getElementsByClassName ) { 3930 push.apply( results, slice.call(context.getElementsByClassName( m ), 0) ); 3931 return results; 3932 } 3933 } 3934 } 3935 3936 // All others 3937 return select( selector.replace( rtrim, "$1" ), context, results, seed, xml ); 3938 } 3939 3940 Sizzle.matches = function( expr, elements ) { 3941 return Sizzle( expr, null, null, elements ); 3942 }; 3943 3944 Sizzle.matchesSelector = function( elem, expr ) { 3945 return Sizzle( expr, null, null, [ elem ] ).length > 0; 3946 }; 3947 3948 // Returns a function to use in pseudos for input types 3949 function createInputPseudo( type ) { 3950 return function( elem ) { 3951 var name = elem.nodeName.toLowerCase(); 3952 return name === "input" && elem.type === type; 3953 }; 3954 } 3955 3956 // Returns a function to use in pseudos for buttons 3957 function createButtonPseudo( type ) { 3958 return function( elem ) { 3959 var name = elem.nodeName.toLowerCase(); 3960 return (name === "input" || name === "button") && elem.type === type; 3961 }; 3962 } 3963 3964 // Returns a function to use in pseudos for positionals 3965 function createPositionalPseudo( fn ) { 3966 return markFunction(function( argument ) { 3967 argument = +argument; 3968 return markFunction(function( seed, matches ) { 3969 var j, 3970 matchIndexes = fn( [], seed.length, argument ), 3971 i = matchIndexes.length; 3972 3973 // Match elements found at the specified indexes 3974 while ( i-- ) { 3975 if ( seed[ (j = matchIndexes[i]) ] ) { 3976 seed[j] = !(matches[j] = seed[j]); 3977 } 3978 } 3979 }); 3980 }); 3981 } 3982 3983 /** 3984 * Utility function for retrieving the text value of an array of DOM nodes 3985 * @param {Array|Element} elem 3986 */ 3987 getText = Sizzle.getText = function( elem ) { 3988 var node, 3989 ret = "", 3990 i = 0, 3991 nodeType = elem.nodeType; 3992 3993 if ( nodeType ) { 3994 if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { 3995 // Use textContent for elements 3996 // innerText usage removed for consistency of new lines (see #11153) 3997 if ( typeof elem.textContent === "string" ) { 3998 return elem.textContent; 3999 } else { 4000 // Traverse its children 4001 for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { 4002 ret += getText( elem ); 4003 } 4004 } 4005 } else if ( nodeType === 3 || nodeType === 4 ) { 4006 return elem.nodeValue; 4007 } 4008 // Do not include comment or processing instruction nodes 4009 } else { 4010 4011 // If no nodeType, this is expected to be an array 4012 for ( ; (node = elem[i]); i++ ) { 4013 // Do not traverse comment nodes 4014 ret += getText( node ); 4015 } 4016 } 4017 return ret; 4018 }; 4019 4020 isXML = Sizzle.isXML = function( elem ) { 4021 // documentElement is verified for cases where it doesn't yet exist 4022 // (such as loading iframes in IE - #4833) 4023 var documentElement = elem && (elem.ownerDocument || elem).documentElement; 4024 return documentElement ? documentElement.nodeName !== "HTML" : false; 4025 }; 4026 4027 // Element contains another 4028 contains = Sizzle.contains = docElem.contains ? 4029 function( a, b ) { 4030 var adown = a.nodeType === 9 ? a.documentElement : a, 4031 bup = b && b.parentNode; 4032 return a === bup || !!( bup && bup.nodeType === 1 && adown.contains && adown.contains(bup) ); 4033 } : 4034 docElem.compareDocumentPosition ? 4035 function( a, b ) { 4036 return b && !!( a.compareDocumentPosition( b ) & 16 ); 4037 } : 4038 function( a, b ) { 4039 while ( (b = b.parentNode) ) { 4040 if ( b === a ) { 4041 return true; 4042 } 4043 } 4044 return false; 4045 }; 4046 4047 Sizzle.attr = function( elem, name ) { 4048 var val, 4049 xml = isXML( elem ); 4050 4051 if ( !xml ) { 4052 name = name.toLowerCase(); 4053 } 4054 if ( (val = Expr.attrHandle[ name ]) ) { 4055 return val( elem ); 4056 } 4057 if ( xml || assertAttributes ) { 4058 return elem.getAttribute( name ); 4059 } 4060 val = elem.getAttributeNode( name ); 4061 return val ? 4062 typeof elem[ name ] === "boolean" ? 4063 elem[ name ] ? name : null : 4064 val.specified ? val.value : null : 4065 null; 4066 }; 4067 4068 Expr = Sizzle.selectors = { 4069 4070 // Can be adjusted by the user 4071 cacheLength: 50, 4072 4073 createPseudo: markFunction, 4074 4075 match: matchExpr, 4076 4077 // IE6/7 return a modified href 4078 attrHandle: assertHrefNotNormalized ? 4079 {} : 4080 { 4081 "href": function( elem ) { 4082 return elem.getAttribute( "href", 2 ); 4083 }, 4084 "type": function( elem ) { 4085 return elem.getAttribute("type"); 4086 } 4087 }, 4088 4089 find: { 4090 "ID": assertGetIdNotName ? 4091 function( id, context, xml ) { 4092 if ( typeof context.getElementById !== strundefined && !xml ) { 4093 var m = context.getElementById( id ); 4094 // Check parentNode to catch when Blackberry 4.6 returns 4095 // nodes that are no longer in the document #6963 4096 return m && m.parentNode ? [m] : []; 4097 } 4098 } : 4099 function( id, context, xml ) { 4100 if ( typeof context.getElementById !== strundefined && !xml ) { 4101 var m = context.getElementById( id ); 4102 4103 return m ? 4104 m.id === id || typeof m.getAttributeNode !== strundefined && m.getAttributeNode("id").value === id ? 4105 [m] : 4106 undefined : 4107 []; 4108 } 4109 }, 4110 4111 "TAG": assertTagNameNoComments ? 4112 function( tag, context ) { 4113 if ( typeof context.getElementsByTagName !== strundefined ) { 4114 return context.getElementsByTagName( tag ); 4115 } 4116 } : 4117 function( tag, context ) { 4118 var results = context.getElementsByTagName( tag ); 4119 4120 // Filter out possible comments 4121 if ( tag === "*" ) { 4122 var elem, 4123 tmp = [], 4124 i = 0; 4125 4126 for ( ; (elem = results[i]); i++ ) { 4127 if ( elem.nodeType === 1 ) { 4128 tmp.push( elem ); 4129 } 4130 } 4131 4132 return tmp; 4133 } 4134 return results; 4135 }, 4136 4137 "NAME": assertUsableName && function( tag, context ) { 4138 if ( typeof context.getElementsByName !== strundefined ) { 4139 return context.getElementsByName( name ); 4140 } 4141 }, 4142 4143 "CLASS": assertUsableClassName && function( className, context, xml ) { 4144 if ( typeof context.getElementsByClassName !== strundefined && !xml ) { 4145 return context.getElementsByClassName( className ); 4146 } 4147 } 4148 }, 4149 4150 relative: { 4151 ">": { dir: "parentNode", first: true }, 4152 " ": { dir: "parentNode" }, 4153 "+": { dir: "previousSibling", first: true }, 4154 "~": { dir: "previousSibling" } 4155 }, 4156 4157 preFilter: { 4158 "ATTR": function( match ) { 4159 match[1] = match[1].replace( rbackslash, "" ); 4160 4161 // Move the given value to match[3] whether quoted or unquoted 4162 match[3] = ( match[4] || match[5] || "" ).replace( rbackslash, "" ); 4163 4164 if ( match[2] === "~=" ) { 4165 match[3] = " " + match[3] + " "; 4166 } 4167 4168 return match.slice( 0, 4 ); 4169 }, 4170 4171 "CHILD": function( match ) { 4172 /* matches from matchExpr["CHILD"] 4173 1 type (only|nth|...) 4174 2 argument (even|odd|\d*|\d*n([+-]\d+)?|...) 4175 3 xn-component of xn+y argument ([+-]?\d*n|) 4176 4 sign of xn-component 4177 5 x of xn-component 4178 6 sign of y-component 4179 7 y of y-component 4180 */ 4181 match[1] = match[1].toLowerCase(); 4182 4183 if ( match[1] === "nth" ) { 4184 // nth-child requires argument 4185 if ( !match[2] ) { 4186 Sizzle.error( match[0] ); 4187 } 4188 4189 // numeric x and y parameters for Expr.filter.CHILD 4190 // remember that false/true cast respectively to 0/1 4191 match[3] = +( match[3] ? match[4] + (match[5] || 1) : 2 * ( match[2] === "even" || match[2] === "odd" ) ); 4192 match[4] = +( ( match[6] + match[7] ) || match[2] === "odd" ); 4193 4194 // other types prohibit arguments 4195 } else if ( match[2] ) { 4196 Sizzle.error( match[0] ); 4197 } 4198 4199 return match; 4200 }, 4201 4202 "PSEUDO": function( match ) { 4203 var unquoted, excess; 4204 if ( matchExpr["CHILD"].test( match[0] ) ) { 4205 return null; 4206 } 4207 4208 if ( match[3] ) { 4209 match[2] = match[3]; 4210 } else if ( (unquoted = match[4]) ) { 4211 // Only check arguments that contain a pseudo 4212 if ( rpseudo.test(unquoted) && 4213 // Get excess from tokenize (recursively) 4214 (excess = tokenize( unquoted, true )) && 4215 // advance to the next closing parenthesis 4216 (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { 4217 4218 // excess is a negative index 4219 unquoted = unquoted.slice( 0, excess ); 4220 match[0] = match[0].slice( 0, excess ); 4221 } 4222 match[2] = unquoted; 4223 } 4224 4225 // Return only captures needed by the pseudo filter method (type and argument) 4226 return match.slice( 0, 3 ); 4227 } 4228 }, 4229 4230 filter: { 4231 "ID": assertGetIdNotName ? 4232 function( id ) { 4233 id = id.replace( rbackslash, "" ); 4234 return function( elem ) { 4235 return elem.getAttribute("id") === id; 4236 }; 4237 } : 4238 function( id ) { 4239 id = id.replace( rbackslash, "" ); 4240 return function( elem ) { 4241 var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id"); 4242 return node && node.value === id; 4243 }; 4244 }, 4245 4246 "TAG": function( nodeName ) { 4247 if ( nodeName === "*" ) { 4248 return function() { return true; }; 4249 } 4250 nodeName = nodeName.replace( rbackslash, "" ).toLowerCase(); 4251 4252 return function( elem ) { 4253 return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; 4254 }; 4255 }, 4256 4257 "CLASS": function( className ) { 4258 var pattern = classCache[ expando ][ className + " " ]; 4259 4260 return pattern || 4261 (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && 4262 classCache( className, function( elem ) { 4263 return pattern.test( elem.className || (typeof elem.getAttribute !== strundefined && elem.getAttribute("class")) || "" ); 4264 }); 4265 }, 4266 4267 "ATTR": function( name, operator, check ) { 4268 return function( elem, context ) { 4269 var result = Sizzle.attr( elem, name ); 4270 4271 if ( result == null ) { 4272 return operator === "!="; 4273 } 4274 if ( !operator ) { 4275 return true; 4276 } 4277 4278 result += ""; 4279 4280 return operator === "=" ? result === check : 4281 operator === "!=" ? result !== check : 4282 operator === "^=" ? check && result.indexOf( check ) === 0 : 4283 operator === "*=" ? check && result.indexOf( check ) > -1 : 4284 operator === "$=" ? check && result.substr( result.length - check.length ) === check : 4285 operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 : 4286 operator === "|=" ? result === check || result.substr( 0, check.length + 1 ) === check + "-" : 4287 false; 4288 }; 4289 }, 4290 4291 "CHILD": function( type, argument, first, last ) { 4292 4293 if ( type === "nth" ) { 4294 return function( elem ) { 4295 var node, diff, 4296 parent = elem.parentNode; 4297 4298 if ( first === 1 && last === 0 ) { 4299 return true; 4300 } 4301 4302 if ( parent ) { 4303 diff = 0; 4304 for ( node = parent.firstChild; node; node = node.nextSibling ) { 4305 if ( node.nodeType === 1 ) { 4306 diff++; 4307 if ( elem === node ) { 4308 break; 4309 } 4310 } 4311 } 4312 } 4313 4314 // Incorporate the offset (or cast to NaN), then check against cycle size 4315 diff -= last; 4316 return diff === first || ( diff % first === 0 && diff / first >= 0 ); 4317 }; 4318 } 4319 4320 return function( elem ) { 4321 var node = elem; 4322 4323 switch ( type ) { 4324 case "only": 4325 case "first": 4326 while ( (node = node.previousSibling) ) { 4327 if ( node.nodeType === 1 ) { 4328 return false; 4329 } 4330 } 4331 4332 if ( type === "first" ) { 4333 return true; 4334 } 4335 4336 node = elem; 4337 4338 /* falls through */ 4339 case "last": 4340 while ( (node = node.nextSibling) ) { 4341 if ( node.nodeType === 1 ) { 4342 return false; 4343 } 4344 } 4345 4346 return true; 4347 } 4348 }; 4349 }, 4350 4351 "PSEUDO": function( pseudo, argument ) { 4352 // pseudo-class names are case-insensitive 4353 // http://www.w3.org/TR/selectors/#pseudo-classes 4354 // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters 4355 // Remember that setFilters inherits from pseudos 4356 var args, 4357 fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || 4358 Sizzle.error( "unsupported pseudo: " + pseudo ); 4359 4360 // The user may use createPseudo to indicate that 4361 // arguments are needed to create the filter function 4362 // just as Sizzle does 4363 if ( fn[ expando ] ) { 4364 return fn( argument ); 4365 } 4366 4367 // But maintain support for old signatures 4368 if ( fn.length > 1 ) { 4369 args = [ pseudo, pseudo, "", argument ]; 4370 return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? 4371 markFunction(function( seed, matches ) { 4372 var idx, 4373 matched = fn( seed, argument ), 4374 i = matched.length; 4375 while ( i-- ) { 4376 idx = indexOf.call( seed, matched[i] ); 4377 seed[ idx ] = !( matches[ idx ] = matched[i] ); 4378 } 4379 }) : 4380 function( elem ) { 4381 return fn( elem, 0, args ); 4382 }; 4383 } 4384 4385 return fn; 4386 } 4387 }, 4388 4389 pseudos: { 4390 "not": markFunction(function( selector ) { 4391 // Trim the selector passed to compile 4392 // to avoid treating leading and trailing 4393 // spaces as combinators 4394 var input = [], 4395 results = [], 4396 matcher = compile( selector.replace( rtrim, "$1" ) ); 4397 4398 return matcher[ expando ] ? 4399 markFunction(function( seed, matches, context, xml ) { 4400 var elem, 4401 unmatched = matcher( seed, null, xml, [] ), 4402 i = seed.length; 4403 4404 // Match elements unmatched by `matcher` 4405 while ( i-- ) { 4406 if ( (elem = unmatched[i]) ) { 4407 seed[i] = !(matches[i] = elem); 4408 } 4409 } 4410 }) : 4411 function( elem, context, xml ) { 4412 input[0] = elem; 4413 matcher( input, null, xml, results ); 4414 return !results.pop(); 4415 }; 4416 }), 4417 4418 "has": markFunction(function( selector ) { 4419 return function( elem ) { 4420 return Sizzle( selector, elem ).length > 0; 4421 }; 4422 }), 4423 4424 "contains": markFunction(function( text ) { 4425 return function( elem ) { 4426 return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; 4427 }; 4428 }), 4429 4430 "enabled": function( elem ) { 4431 return elem.disabled === false; 4432 }, 4433 4434 "disabled": function( elem ) { 4435 return elem.disabled === true; 4436 }, 4437 4438 "checked": function( elem ) { 4439 // In CSS3, :checked should return both checked and selected elements 4440 // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked 4441 var nodeName = elem.nodeName.toLowerCase(); 4442 return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); 4443 }, 4444 4445 "selected": function( elem ) { 4446 // Accessing this property makes selected-by-default 4447 // options in Safari work properly 4448 if ( elem.parentNode ) { 4449 elem.parentNode.selectedIndex; 4450 } 4451 4452 return elem.selected === true; 4453 }, 4454 4455 "parent": function( elem ) { 4456 return !Expr.pseudos["empty"]( elem ); 4457 }, 4458 4459 "empty": function( elem ) { 4460 // http://www.w3.org/TR/selectors/#empty-pseudo 4461 // :empty is only affected by element nodes and content nodes(including text(3), cdata(4)), 4462 // not comment, processing instructions, or others 4463 // Thanks to Diego Perini for the nodeName shortcut 4464 // Greater than "@" means alpha characters (specifically not starting with "#" or "?") 4465 var nodeType; 4466 elem = elem.firstChild; 4467 while ( elem ) { 4468 if ( elem.nodeName > "@" || (nodeType = elem.nodeType) === 3 || nodeType === 4 ) { 4469 return false; 4470 } 4471 elem = elem.nextSibling; 4472 } 4473 return true; 4474 }, 4475 4476 "header": function( elem ) { 4477 return rheader.test( elem.nodeName ); 4478 }, 4479 4480 "text": function( elem ) { 4481 var type, attr; 4482 // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) 4483 // use getAttribute instead to test this case 4484 return elem.nodeName.toLowerCase() === "input" && 4485 (type = elem.type) === "text" && 4486 ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === type ); 4487 }, 4488 4489 // Input types 4490 "radio": createInputPseudo("radio"), 4491 "checkbox": createInputPseudo("checkbox"), 4492 "file": createInputPseudo("file"), 4493 "password": createInputPseudo("password"), 4494 "image": createInputPseudo("image"), 4495 4496 "submit": createButtonPseudo("submit"), 4497 "reset": createButtonPseudo("reset"), 4498 4499 "button": function( elem ) { 4500 var name = elem.nodeName.toLowerCase(); 4501 return name === "input" && elem.type === "button" || name === "button"; 4502 }, 4503 4504 "input": function( elem ) { 4505 return rinputs.test( elem.nodeName ); 4506 }, 4507 4508 "focus": function( elem ) { 4509 var doc = elem.ownerDocument; 4510 return elem === doc.activeElement && (!doc.hasFocus || doc.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); 4511 }, 4512 4513 "active": function( elem ) { 4514 return elem === elem.ownerDocument.activeElement; 4515 }, 4516 4517 // Positional types 4518 "first": createPositionalPseudo(function() { 4519 return [ 0 ]; 4520 }), 4521 4522 "last": createPositionalPseudo(function( matchIndexes, length ) { 4523 return [ length - 1 ]; 4524 }), 4525 4526 "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { 4527 return [ argument < 0 ? argument + length : argument ]; 4528 }), 4529 4530 "even": createPositionalPseudo(function( matchIndexes, length ) { 4531 for ( var i = 0; i < length; i += 2 ) { 4532 matchIndexes.push( i ); 4533 } 4534 return matchIndexes; 4535 }), 4536 4537 "odd": createPositionalPseudo(function( matchIndexes, length ) { 4538 for ( var i = 1; i < length; i += 2 ) { 4539 matchIndexes.push( i ); 4540 } 4541 return matchIndexes; 4542 }), 4543 4544 "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { 4545 for ( var i = argument < 0 ? argument + length : argument; --i >= 0; ) { 4546 matchIndexes.push( i ); 4547 } 4548 return matchIndexes; 4549 }), 4550 4551 "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { 4552 for ( var i = argument < 0 ? argument + length : argument; ++i < length; ) { 4553 matchIndexes.push( i ); 4554 } 4555 return matchIndexes; 4556 }) 4557 } 4558 }; 4559 4560 function siblingCheck( a, b, ret ) { 4561 if ( a === b ) { 4562 return ret; 4563 } 4564 4565 var cur = a.nextSibling; 4566 4567 while ( cur ) { 4568 if ( cur === b ) { 4569 return -1; 4570 } 4571 4572 cur = cur.nextSibling; 4573 } 4574 4575 return 1; 4576 } 4577 4578 sortOrder = docElem.compareDocumentPosition ? 4579 function( a, b ) { 4580 if ( a === b ) { 4581 hasDuplicate = true; 4582 return 0; 4583 } 4584 4585 return ( !a.compareDocumentPosition || !b.compareDocumentPosition ? 4586 a.compareDocumentPosition : 4587 a.compareDocumentPosition(b) & 4 4588 ) ? -1 : 1; 4589 } : 4590 function( a, b ) { 4591 // The nodes are identical, we can exit early 4592 if ( a === b ) { 4593 hasDuplicate = true; 4594 return 0; 4595 4596 // Fallback to using sourceIndex (in IE) if it's available on both nodes 4597 } else if ( a.sourceIndex && b.sourceIndex ) { 4598 return a.sourceIndex - b.sourceIndex; 4599 } 4600 4601 var al, bl, 4602 ap = [], 4603 bp = [], 4604 aup = a.parentNode, 4605 bup = b.parentNode, 4606 cur = aup; 4607 4608 // If the nodes are siblings (or identical) we can do a quick check 4609 if ( aup === bup ) { 4610 return siblingCheck( a, b ); 4611 4612 // If no parents were found then the nodes are disconnected 4613 } else if ( !aup ) { 4614 return -1; 4615 4616 } else if ( !bup ) { 4617 return 1; 4618 } 4619 4620 // Otherwise they're somewhere else in the tree so we need 4621 // to build up a full list of the parentNodes for comparison 4622 while ( cur ) { 4623 ap.unshift( cur ); 4624 cur = cur.parentNode; 4625 } 4626 4627 cur = bup; 4628 4629 while ( cur ) { 4630 bp.unshift( cur ); 4631 cur = cur.parentNode; 4632 } 4633 4634 al = ap.length; 4635 bl = bp.length; 4636 4637 // Start walking down the tree looking for a discrepancy 4638 for ( var i = 0; i < al && i < bl; i++ ) { 4639 if ( ap[i] !== bp[i] ) { 4640 return siblingCheck( ap[i], bp[i] ); 4641 } 4642 } 4643 4644 // We ended someplace up the tree so do a sibling check 4645 return i === al ? 4646 siblingCheck( a, bp[i], -1 ) : 4647 siblingCheck( ap[i], b, 1 ); 4648 }; 4649 4650 // Always assume the presence of duplicates if sort doesn't 4651 // pass them to our comparison function (as in Google Chrome). 4652 [0, 0].sort( sortOrder ); 4653 baseHasDuplicate = !hasDuplicate; 4654 4655 // Document sorting and removing duplicates 4656 Sizzle.uniqueSort = function( results ) { 4657 var elem, 4658 duplicates = [], 4659 i = 1, 4660 j = 0; 4661 4662 hasDuplicate = baseHasDuplicate; 4663 results.sort( sortOrder ); 4664 4665 if ( hasDuplicate ) { 4666 for ( ; (elem = results[i]); i++ ) { 4667 if ( elem === results[ i - 1 ] ) { 4668 j = duplicates.push( i ); 4669 } 4670 } 4671 while ( j-- ) { 4672 results.splice( duplicates[ j ], 1 ); 4673 } 4674 } 4675 4676 return results; 4677 }; 4678 4679 Sizzle.error = function( msg ) { 4680 throw new Error( "Syntax error, unrecognized expression: " + msg ); 4681 }; 4682 4683 function tokenize( selector, parseOnly ) { 4684 var matched, match, tokens, type, 4685 soFar, groups, preFilters, 4686 cached = tokenCache[ expando ][ selector + " " ]; 4687 4688 if ( cached ) { 4689 return parseOnly ? 0 : cached.slice( 0 ); 4690 } 4691 4692 soFar = selector; 4693 groups = []; 4694 preFilters = Expr.preFilter; 4695 4696 while ( soFar ) { 4697 4698 // Comma and first run 4699 if ( !matched || (match = rcomma.exec( soFar )) ) { 4700 if ( match ) { 4701 // Don't consume trailing commas as valid 4702 soFar = soFar.slice( match[0].length ) || soFar; 4703 } 4704 groups.push( tokens = [] ); 4705 } 4706 4707 matched = false; 4708 4709 // Combinators 4710 if ( (match = rcombinators.exec( soFar )) ) { 4711 tokens.push( matched = new Token( match.shift() ) ); 4712 soFar = soFar.slice( matched.length ); 4713 4714 // Cast descendant combinators to space 4715 matched.type = match[0].replace( rtrim, " " ); 4716 } 4717 4718 // Filters 4719 for ( type in Expr.filter ) { 4720 if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || 4721 (match = preFilters[ type ]( match ))) ) { 4722 4723 tokens.push( matched = new Token( match.shift() ) ); 4724 soFar = soFar.slice( matched.length ); 4725 matched.type = type; 4726 matched.matches = match; 4727 } 4728 } 4729 4730 if ( !matched ) { 4731 break; 4732 } 4733 } 4734 4735 // Return the length of the invalid excess 4736 // if we're just parsing 4737 // Otherwise, throw an error or return tokens 4738 return parseOnly ? 4739 soFar.length : 4740 soFar ? 4741 Sizzle.error( selector ) : 4742 // Cache the tokens 4743 tokenCache( selector, groups ).slice( 0 ); 4744 } 4745 4746 function addCombinator( matcher, combinator, base ) { 4747 var dir = combinator.dir, 4748 checkNonElements = base && combinator.dir === "parentNode", 4749 doneName = done++; 4750 4751 return combinator.first ? 4752 // Check against closest ancestor/preceding element 4753 function( elem, context, xml ) { 4754 while ( (elem = elem[ dir ]) ) { 4755 if ( checkNonElements || elem.nodeType === 1 ) { 4756 return matcher( elem, context, xml ); 4757 } 4758 } 4759 } : 4760 4761 // Check against all ancestor/preceding elements 4762 function( elem, context, xml ) { 4763 // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching 4764 if ( !xml ) { 4765 var cache, 4766 dirkey = dirruns + " " + doneName + " ", 4767 cachedkey = dirkey + cachedruns; 4768 while ( (elem = elem[ dir ]) ) { 4769 if ( checkNonElements || elem.nodeType === 1 ) { 4770 if ( (cache = elem[ expando ]) === cachedkey ) { 4771 return elem.sizset; 4772 } else if ( typeof cache === "string" && cache.indexOf(dirkey) === 0 ) { 4773 if ( elem.sizset ) { 4774 return elem; 4775 } 4776 } else { 4777 elem[ expando ] = cachedkey; 4778 if ( matcher( elem, context, xml ) ) { 4779 elem.sizset = true; 4780 return elem; 4781 } 4782 elem.sizset = false; 4783 } 4784 } 4785 } 4786 } else { 4787 while ( (elem = elem[ dir ]) ) { 4788 if ( checkNonElements || elem.nodeType === 1 ) { 4789 if ( matcher( elem, context, xml ) ) { 4790 return elem; 4791 } 4792 } 4793 } 4794 } 4795 }; 4796 } 4797 4798 function elementMatcher( matchers ) { 4799 return matchers.length > 1 ? 4800 function( elem, context, xml ) { 4801 var i = matchers.length; 4802 while ( i-- ) { 4803 if ( !matchers[i]( elem, context, xml ) ) { 4804 return false; 4805 } 4806 } 4807 return true; 4808 } : 4809 matchers[0]; 4810 } 4811 4812 function condense( unmatched, map, filter, context, xml ) { 4813 var elem, 4814 newUnmatched = [], 4815 i = 0, 4816 len = unmatched.length, 4817 mapped = map != null; 4818 4819 for ( ; i < len; i++ ) { 4820 if ( (elem = unmatched[i]) ) { 4821 if ( !filter || filter( elem, context, xml ) ) { 4822 newUnmatched.push( elem ); 4823 if ( mapped ) { 4824 map.push( i ); 4825 } 4826 } 4827 } 4828 } 4829 4830 return newUnmatched; 4831 } 4832 4833 function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { 4834 if ( postFilter && !postFilter[ expando ] ) { 4835 postFilter = setMatcher( postFilter ); 4836 } 4837 if ( postFinder && !postFinder[ expando ] ) { 4838 postFinder = setMatcher( postFinder, postSelector ); 4839 } 4840 return markFunction(function( seed, results, context, xml ) { 4841 var temp, i, elem, 4842 preMap = [], 4843 postMap = [], 4844 preexisting = results.length, 4845 4846 // Get initial elements from seed or context 4847 elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), 4848 4849 // Prefilter to get matcher input, preserving a map for seed-results synchronization 4850 matcherIn = preFilter && ( seed || !selector ) ? 4851 condense( elems, preMap, preFilter, context, xml ) : 4852 elems, 4853 4854 matcherOut = matcher ? 4855 // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, 4856 postFinder || ( seed ? preFilter : preexisting || postFilter ) ? 4857 4858 // ...intermediate processing is necessary 4859 [] : 4860 4861 // ...otherwise use results directly 4862 results : 4863 matcherIn; 4864 4865 // Find primary matches 4866 if ( matcher ) { 4867 matcher( matcherIn, matcherOut, context, xml ); 4868 } 4869 4870 // Apply postFilter 4871 if ( postFilter ) { 4872 temp = condense( matcherOut, postMap ); 4873 postFilter( temp, [], context, xml ); 4874 4875 // Un-match failing elements by moving them back to matcherIn 4876 i = temp.length; 4877 while ( i-- ) { 4878 if ( (elem = temp[i]) ) { 4879 matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); 4880 } 4881 } 4882 } 4883 4884 if ( seed ) { 4885 if ( postFinder || preFilter ) { 4886 if ( postFinder ) { 4887 // Get the final matcherOut by condensing this intermediate into postFinder contexts 4888 temp = []; 4889 i = matcherOut.length; 4890 while ( i-- ) { 4891 if ( (elem = matcherOut[i]) ) { 4892 // Restore matcherIn since elem is not yet a final match 4893 temp.push( (matcherIn[i] = elem) ); 4894 } 4895 } 4896 postFinder( null, (matcherOut = []), temp, xml ); 4897 } 4898 4899 // Move matched elements from seed to results to keep them synchronized 4900 i = matcherOut.length; 4901 while ( i-- ) { 4902 if ( (elem = matcherOut[i]) && 4903 (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) { 4904 4905 seed[temp] = !(results[temp] = elem); 4906 } 4907 } 4908 } 4909 4910 // Add elements to results, through postFinder if defined 4911 } else { 4912 matcherOut = condense( 4913 matcherOut === results ? 4914 matcherOut.splice( preexisting, matcherOut.length ) : 4915 matcherOut 4916 ); 4917 if ( postFinder ) { 4918 postFinder( null, results, matcherOut, xml ); 4919 } else { 4920 push.apply( results, matcherOut ); 4921 } 4922 } 4923 }); 4924 } 4925 4926 function matcherFromTokens( tokens ) { 4927 var checkContext, matcher, j, 4928 len = tokens.length, 4929 leadingRelative = Expr.relative[ tokens[0].type ], 4930 implicitRelative = leadingRelative || Expr.relative[" "], 4931 i = leadingRelative ? 1 : 0, 4932 4933 // The foundational matcher ensures that elements are reachable from top-level context(s) 4934 matchContext = addCombinator( function( elem ) { 4935 return elem === checkContext; 4936 }, implicitRelative, true ), 4937 matchAnyContext = addCombinator( function( elem ) { 4938 return indexOf.call( checkContext, elem ) > -1; 4939 }, implicitRelative, true ), 4940 matchers = [ function( elem, context, xml ) { 4941 return ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( 4942 (checkContext = context).nodeType ? 4943 matchContext( elem, context, xml ) : 4944 matchAnyContext( elem, context, xml ) ); 4945 } ]; 4946 4947 for ( ; i < len; i++ ) { 4948 if ( (matcher = Expr.relative[ tokens[i].type ]) ) { 4949 matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ]; 4950 } else { 4951 matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); 4952 4953 // Return special upon seeing a positional matcher 4954 if ( matcher[ expando ] ) { 4955 // Find the next relative operator (if any) for proper handling 4956 j = ++i; 4957 for ( ; j < len; j++ ) { 4958 if ( Expr.relative[ tokens[j].type ] ) { 4959 break; 4960 } 4961 } 4962 return setMatcher( 4963 i > 1 && elementMatcher( matchers ), 4964 i > 1 && tokens.slice( 0, i - 1 ).join("").replace( rtrim, "$1" ), 4965 matcher, 4966 i < j && matcherFromTokens( tokens.slice( i, j ) ), 4967 j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), 4968 j < len && tokens.join("") 4969 ); 4970 } 4971 matchers.push( matcher ); 4972 } 4973 } 4974 4975 return elementMatcher( matchers ); 4976 } 4977 4978 function matcherFromGroupMatchers( elementMatchers, setMatchers ) { 4979 var bySet = setMatchers.length > 0, 4980 byElement = elementMatchers.length > 0, 4981 superMatcher = function( seed, context, xml, results, expandContext ) { 4982 var elem, j, matcher, 4983 setMatched = [], 4984 matchedCount = 0, 4985 i = "0", 4986 unmatched = seed && [], 4987 outermost = expandContext != null, 4988 contextBackup = outermostContext, 4989 // We must always have either seed elements or context 4990 elems = seed || byElement && Expr.find["TAG"]( "*", expandContext && context.parentNode || context ), 4991 // Nested matchers should use non-integer dirruns 4992 dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.E); 4993 4994 if ( outermost ) { 4995 outermostContext = context !== document && context; 4996 cachedruns = superMatcher.el; 4997 } 4998 4999 // Add elements passing elementMatchers directly to results 5000 for ( ; (elem = elems[i]) != null; i++ ) { 5001 if ( byElement && elem ) { 5002 for ( j = 0; (matcher = elementMatchers[j]); j++ ) { 5003 if ( matcher( elem, context, xml ) ) { 5004 results.push( elem ); 5005 break; 5006 } 5007 } 5008 if ( outermost ) { 5009 dirruns = dirrunsUnique; 5010 cachedruns = ++superMatcher.el; 5011 } 5012 } 5013 5014 // Track unmatched elements for set filters 5015 if ( bySet ) { 5016 // They will have gone through all possible matchers 5017 if ( (elem = !matcher && elem) ) { 5018 matchedCount--; 5019 } 5020 5021 // Lengthen the array for every element, matched or not 5022 if ( seed ) { 5023 unmatched.push( elem ); 5024 } 5025 } 5026 } 5027 5028 // Apply set filters to unmatched elements 5029 matchedCount += i; 5030 if ( bySet && i !== matchedCount ) { 5031 for ( j = 0; (matcher = setMatchers[j]); j++ ) { 5032 matcher( unmatched, setMatched, context, xml ); 5033 } 5034 5035 if ( seed ) { 5036 // Reintegrate element matches to eliminate the need for sorting 5037 if ( matchedCount > 0 ) { 5038 while ( i-- ) { 5039 if ( !(unmatched[i] || setMatched[i]) ) { 5040 setMatched[i] = pop.call( results ); 5041 } 5042 } 5043 } 5044 5045 // Discard index placeholder values to get only actual matches 5046 setMatched = condense( setMatched ); 5047 } 5048 5049 // Add matches to results 5050 push.apply( results, setMatched ); 5051 5052 // Seedless set matches succeeding multiple successful matchers stipulate sorting 5053 if ( outermost && !seed && setMatched.length > 0 && 5054 ( matchedCount + setMatchers.length ) > 1 ) { 5055 5056 Sizzle.uniqueSort( results ); 5057 } 5058 } 5059 5060 // Override manipulation of globals by nested matchers 5061 if ( outermost ) { 5062 dirruns = dirrunsUnique; 5063 outermostContext = contextBackup; 5064 } 5065 5066 return unmatched; 5067 }; 5068 5069 superMatcher.el = 0; 5070 return bySet ? 5071 markFunction( superMatcher ) : 5072 superMatcher; 5073 } 5074 5075 compile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) { 5076 var i, 5077 setMatchers = [], 5078 elementMatchers = [], 5079 cached = compilerCache[ expando ][ selector + " " ]; 5080 5081 if ( !cached ) { 5082 // Generate a function of recursive functions that can be used to check each element 5083 if ( !group ) { 5084 group = tokenize( selector ); 5085 } 5086 i = group.length; 5087 while ( i-- ) { 5088 cached = matcherFromTokens( group[i] ); 5089 if ( cached[ expando ] ) { 5090 setMatchers.push( cached ); 5091 } else { 5092 elementMatchers.push( cached ); 5093 } 5094 } 5095 5096 // Cache the compiled function 5097 cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); 5098 } 5099 return cached; 5100 }; 5101 5102 function multipleContexts( selector, contexts, results ) { 5103 var i = 0, 5104 len = contexts.length; 5105 for ( ; i < len; i++ ) { 5106 Sizzle( selector, contexts[i], results ); 5107 } 5108 return results; 5109 } 5110 5111 function select( selector, context, results, seed, xml ) { 5112 var i, tokens, token, type, find, 5113 match = tokenize( selector ), 5114 j = match.length; 5115 5116 if ( !seed ) { 5117 // Try to minimize operations if there is only one group 5118 if ( match.length === 1 ) { 5119 5120 // Take a shortcut and set the context if the root selector is an ID 5121 tokens = match[0] = match[0].slice( 0 ); 5122 if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && 5123 context.nodeType === 9 && !xml && 5124 Expr.relative[ tokens[1].type ] ) { 5125 5126 context = Expr.find["ID"]( token.matches[0].replace( rbackslash, "" ), context, xml )[0]; 5127 if ( !context ) { 5128 return results; 5129 } 5130 5131 selector = selector.slice( tokens.shift().length ); 5132 } 5133 5134 // Fetch a seed set for right-to-left matching 5135 for ( i = matchExpr["POS"].test( selector ) ? -1 : tokens.length - 1; i >= 0; i-- ) { 5136 token = tokens[i]; 5137 5138 // Abort if we hit a combinator 5139 if ( Expr.relative[ (type = token.type) ] ) { 5140 break; 5141 } 5142 if ( (find = Expr.find[ type ]) ) { 5143 // Search, expanding context for leading sibling combinators 5144 if ( (seed = find( 5145 token.matches[0].replace( rbackslash, "" ), 5146 rsibling.test( tokens[0].type ) && context.parentNode || context, 5147 xml 5148 )) ) { 5149 5150 // If seed is empty or no tokens remain, we can return early 5151 tokens.splice( i, 1 ); 5152 selector = seed.length && tokens.join(""); 5153 if ( !selector ) { 5154 push.apply( results, slice.call( seed, 0 ) ); 5155 return results; 5156 } 5157 5158 break; 5159 } 5160 } 5161 } 5162 } 5163 } 5164 5165 // Compile and execute a filtering function 5166 // Provide `match` to avoid retokenization if we modified the selector above 5167 compile( selector, match )( 5168 seed, 5169 context, 5170 xml, 5171 results, 5172 rsibling.test( selector ) 5173 ); 5174 return results; 5175 } 5176 5177 if ( document.querySelectorAll ) { 5178 (function() { 5179 var disconnectedMatch, 5180 oldSelect = select, 5181 rescape = /'|\\/g, 5182 rattributeQuotes = /\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g, 5183 5184 // qSa(:focus) reports false when true (Chrome 21), no need to also add to buggyMatches since matches checks buggyQSA 5185 // A support test would require too much code (would include document ready) 5186 rbuggyQSA = [ ":focus" ], 5187 5188 // matchesSelector(:active) reports false when true (IE9/Opera 11.5) 5189 // A support test would require too much code (would include document ready) 5190 // just skip matchesSelector for :active 5191 rbuggyMatches = [ ":active" ], 5192 matches = docElem.matchesSelector || 5193 docElem.mozMatchesSelector || 5194 docElem.webkitMatchesSelector || 5195 docElem.oMatchesSelector || 5196 docElem.msMatchesSelector; 5197 5198 // Build QSA regex 5199 // Regex strategy adopted from Diego Perini 5200 assert(function( div ) { 5201 // Select is set to empty string on purpose 5202 // This is to test IE's treatment of not explictly 5203 // setting a boolean content attribute, 5204 // since its presence should be enough 5205 // http://bugs.jquery.com/ticket/12359 5206 div.innerHTML = "<select><option selected=''></option></select>"; 5207 5208 // IE8 - Some boolean attributes are not treated correctly 5209 if ( !div.querySelectorAll("[selected]").length ) { 5210 rbuggyQSA.push( "\\[" + whitespace + "*(?:checked|disabled|ismap|multiple|readonly|selected|value)" ); 5211 } 5212 5213 // Webkit/Opera - :checked should return selected option elements 5214 // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked 5215 // IE8 throws error here (do not put tests after this one) 5216 if ( !div.querySelectorAll(":checked").length ) { 5217 rbuggyQSA.push(":checked"); 5218 } 5219 }); 5220 5221 assert(function( div ) { 5222 5223 // Opera 10-12/IE9 - ^= $= *= and empty values 5224 // Should not select anything 5225 div.innerHTML = "<p test=''></p>"; 5226 if ( div.querySelectorAll("[test^='']").length ) { 5227 rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:\"\"|'')" ); 5228 } 5229 5230 // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) 5231 // IE8 throws error here (do not put tests after this one) 5232 div.innerHTML = "<input type='hidden'/>"; 5233 if ( !div.querySelectorAll(":enabled").length ) { 5234 rbuggyQSA.push(":enabled", ":disabled"); 5235 } 5236 }); 5237 5238 // rbuggyQSA always contains :focus, so no need for a length check 5239 rbuggyQSA = /* rbuggyQSA.length && */ new RegExp( rbuggyQSA.join("|") ); 5240 5241 select = function( selector, context, results, seed, xml ) { 5242 // Only use querySelectorAll when not filtering, 5243 // when this is not xml, 5244 // and when no QSA bugs apply 5245 if ( !seed && !xml && !rbuggyQSA.test( selector ) ) { 5246 var groups, i, 5247 old = true, 5248 nid = expando, 5249 newContext = context, 5250 newSelector = context.nodeType === 9 && selector; 5251 5252 // qSA works strangely on Element-rooted queries 5253 // We can work around this by specifying an extra ID on the root 5254 // and working up from there (Thanks to Andrew Dupont for the technique) 5255 // IE 8 doesn't work on object elements 5256 if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { 5257 groups = tokenize( selector ); 5258 5259 if ( (old = context.getAttribute("id")) ) { 5260 nid = old.replace( rescape, "\\$&" ); 5261 } else { 5262 context.setAttribute( "id", nid ); 5263 } 5264 nid = "[id='" + nid + "'] "; 5265 5266 i = groups.length; 5267 while ( i-- ) { 5268 groups[i] = nid + groups[i].join(""); 5269 } 5270 newContext = rsibling.test( selector ) && context.parentNode || context; 5271 newSelector = groups.join(","); 5272 } 5273 5274 if ( newSelector ) { 5275 try { 5276 push.apply( results, slice.call( newContext.querySelectorAll( 5277 newSelector 5278 ), 0 ) ); 5279 return results; 5280 } catch(qsaError) { 5281 } finally { 5282 if ( !old ) { 5283 context.removeAttribute("id"); 5284 } 5285 } 5286 } 5287 } 5288 5289 return oldSelect( selector, context, results, seed, xml ); 5290 }; 5291 5292 if ( matches ) { 5293 assert(function( div ) { 5294 // Check to see if it's possible to do matchesSelector 5295 // on a disconnected node (IE 9) 5296 disconnectedMatch = matches.call( div, "div" ); 5297 5298 // This should fail with an exception 5299 // Gecko does not error, returns false instead 5300 try { 5301 matches.call( div, "[test!='']:sizzle" ); 5302 rbuggyMatches.push( "!=", pseudos ); 5303 } catch ( e ) {} 5304 }); 5305 5306 // rbuggyMatches always contains :active and :focus, so no need for a length check 5307 rbuggyMatches = /* rbuggyMatches.length && */ new RegExp( rbuggyMatches.join("|") ); 5308 5309 Sizzle.matchesSelector = function( elem, expr ) { 5310 // Make sure that attribute selectors are quoted 5311 expr = expr.replace( rattributeQuotes, "='$1']" ); 5312 5313 // rbuggyMatches always contains :active, so no need for an existence check 5314 if ( !isXML( elem ) && !rbuggyMatches.test( expr ) && !rbuggyQSA.test( expr ) ) { 5315 try { 5316 var ret = matches.call( elem, expr ); 5317 5318 // IE 9's matchesSelector returns false on disconnected nodes 5319 if ( ret || disconnectedMatch || 5320 // As well, disconnected nodes are said to be in a document 5321 // fragment in IE 9 5322 elem.document && elem.document.nodeType !== 11 ) { 5323 return ret; 5324 } 5325 } catch(e) {} 5326 } 5327 5328 return Sizzle( expr, null, null, [ elem ] ).length > 0; 5329 }; 5330 } 5331 })(); 5332 } 5333 5334 // Deprecated 5335 Expr.pseudos["nth"] = Expr.pseudos["eq"]; 5336 5337 // Back-compat 5338 function setFilters() {} 5339 Expr.filters = setFilters.prototype = Expr.pseudos; 5340 Expr.setFilters = new setFilters(); 5341 5342 // Override sizzle attribute retrieval 5343 Sizzle.attr = jQuery.attr; 5344 jQuery.find = Sizzle; 5345 jQuery.expr = Sizzle.selectors; 5346 jQuery.expr[":"] = jQuery.expr.pseudos; 5347 jQuery.unique = Sizzle.uniqueSort; 5348 jQuery.text = Sizzle.getText; 5349 jQuery.isXMLDoc = Sizzle.isXML; 5350 jQuery.contains = Sizzle.contains; 5351 5352 5353 })( window ); 5354 var runtil = /Until$/, 5355 rparentsprev = /^(?:parents|prev(?:Until|All))/, 5356 isSimple = /^.[^:#\[\.,]*$/, 5357 rneedsContext = jQuery.expr.match.needsContext, 5358 // methods guaranteed to produce a unique set when starting from a unique set 5359 guaranteedUnique = { 5360 children: true, 5361 contents: true, 5362 next: true, 5363 prev: true 5364 }; 5365 5366 jQuery.fn.extend({ 5367 find: function( selector ) { 5368 var i, l, length, n, r, ret, 5369 self = this; 5370 5371 if ( typeof selector !== "string" ) { 5372 return jQuery( selector ).filter(function() { 5373 for ( i = 0, l = self.length; i < l; i++ ) { 5374 if ( jQuery.contains( self[ i ], this ) ) { 5375 return true; 5376 } 5377 } 5378 }); 5379 } 5380 5381 ret = this.pushStack( "", "find", selector ); 5382 5383 for ( i = 0, l = this.length; i < l; i++ ) { 5384 length = ret.length; 5385 jQuery.find( selector, this[i], ret ); 5386 5387 if ( i > 0 ) { 5388 // Make sure that the results are unique 5389 for ( n = length; n < ret.length; n++ ) { 5390 for ( r = 0; r < length; r++ ) { 5391 if ( ret[r] === ret[n] ) { 5392 ret.splice(n--, 1); 5393 break; 5394 } 5395 } 5396 } 5397 } 5398 } 5399 5400 return ret; 5401 }, 5402 5403 has: function( target ) { 5404 var i, 5405 targets = jQuery( target, this ), 5406 len = targets.length; 5407 5408 return this.filter(function() { 5409 for ( i = 0; i < len; i++ ) { 5410 if ( jQuery.contains( this, targets[i] ) ) { 5411 return true; 5412 } 5413 } 5414 }); 5415 }, 5416 5417 not: function( selector ) { 5418 return this.pushStack( winnow(this, selector, false), "not", selector); 5419 }, 5420 5421 filter: function( selector ) { 5422 return this.pushStack( winnow(this, selector, true), "filter", selector ); 5423 }, 5424 5425 is: function( selector ) { 5426 return !!selector && ( 5427 typeof selector === "string" ? 5428 // If this is a positional/relative selector, check membership in the returned set 5429 // so $("p:first").is("p:last") won't return true for a doc with two "p". 5430 rneedsContext.test( selector ) ? 5431 jQuery( selector, this.context ).index( this[0] ) >= 0 : 5432 jQuery.filter( selector, this ).length > 0 : 5433 this.filter( selector ).length > 0 ); 5434 }, 5435 5436 closest: function( selectors, context ) { 5437 var cur, 5438 i = 0, 5439 l = this.length, 5440 ret = [], 5441 pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ? 5442 jQuery( selectors, context || this.context ) : 5443 0; 5444 5445 for ( ; i < l; i++ ) { 5446 cur = this[i]; 5447 5448 while ( cur && cur.ownerDocument && cur !== context && cur.nodeType !== 11 ) { 5449 if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) { 5450 ret.push( cur ); 5451 break; 5452 } 5453 cur = cur.parentNode; 5454 } 5455 } 5456 5457 ret = ret.length > 1 ? jQuery.unique( ret ) : ret; 5458 5459 return this.pushStack( ret, "closest", selectors ); 5460 }, 5461 5462 // Determine the position of an element within 5463 // the matched set of elements 5464 index: function( elem ) { 5465 5466 // No argument, return index in parent 5467 if ( !elem ) { 5468 return ( this[0] && this[0].parentNode ) ? this.prevAll().length : -1; 5469 } 5470 5471 // index in selector 5472 if ( typeof elem === "string" ) { 5473 return jQuery.inArray( this[0], jQuery( elem ) ); 5474 } 5475 5476 // Locate the position of the desired element 5477 return jQuery.inArray( 5478 // If it receives a jQuery object, the first element is used 5479 elem.jquery ? elem[0] : elem, this ); 5480 }, 5481 5482 add: function( selector, context ) { 5483 var set = typeof selector === "string" ? 5484 jQuery( selector, context ) : 5485 jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ), 5486 all = jQuery.merge( this.get(), set ); 5487 5488 return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ? 5489 all : 5490 jQuery.unique( all ) ); 5491 }, 5492 5493 addBack: function( selector ) { 5494 return this.add( selector == null ? 5495 this.prevObject : this.prevObject.filter(selector) 5496 ); 5497 } 5498 }); 5499 5500 jQuery.fn.andSelf = jQuery.fn.addBack; 5501 5502 // A painfully simple check to see if an element is disconnected 5503 // from a document (should be improved, where feasible). 5504 function isDisconnected( node ) { 5505 return !node || !node.parentNode || node.parentNode.nodeType === 11; 5506 } 5507 5508 function sibling( cur, dir ) { 5509 do { 5510 cur = cur[ dir ]; 5511 } while ( cur && cur.nodeType !== 1 ); 5512 5513 return cur; 5514 } 5515 5516 jQuery.each({ 5517 parent: function( elem ) { 5518 var parent = elem.parentNode; 5519 return parent && parent.nodeType !== 11 ? parent : null; 5520 }, 5521 parents: function( elem ) { 5522 return jQuery.dir( elem, "parentNode" ); 5523 }, 5524 parentsUntil: function( elem, i, until ) { 5525 return jQuery.dir( elem, "parentNode", until ); 5526 }, 5527 next: function( elem ) { 5528 return sibling( elem, "nextSibling" ); 5529 }, 5530 prev: function( elem ) { 5531 return sibling( elem, "previousSibling" ); 5532 }, 5533 nextAll: function( elem ) { 5534 return jQuery.dir( elem, "nextSibling" ); 5535 }, 5536 prevAll: function( elem ) { 5537 return jQuery.dir( elem, "previousSibling" ); 5538 }, 5539 nextUntil: function( elem, i, until ) { 5540 return jQuery.dir( elem, "nextSibling", until ); 5541 }, 5542 prevUntil: function( elem, i, until ) { 5543 return jQuery.dir( elem, "previousSibling", until ); 5544 }, 5545 siblings: function( elem ) { 5546 return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem ); 5547 }, 5548 children: function( elem ) { 5549 return jQuery.sibling( elem.firstChild ); 5550 }, 5551 contents: function( elem ) { 5552 return jQuery.nodeName( elem, "iframe" ) ? 5553 elem.contentDocument || elem.contentWindow.document : 5554 jQuery.merge( [], elem.childNodes ); 5555 } 5556 }, function( name, fn ) { 5557 jQuery.fn[ name ] = function( until, selector ) { 5558 var ret = jQuery.map( this, fn, until ); 5559 5560 if ( !runtil.test( name ) ) { 5561 selector = until; 5562 } 5563 5564 if ( selector && typeof selector === "string" ) { 5565 ret = jQuery.filter( selector, ret ); 5566 } 5567 5568 ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret; 5569 5570 if ( this.length > 1 && rparentsprev.test( name ) ) { 5571 ret = ret.reverse(); 5572 } 5573 5574 return this.pushStack( ret, name, core_slice.call( arguments ).join(",") ); 5575 }; 5576 }); 5577 5578 jQuery.extend({ 5579 filter: function( expr, elems, not ) { 5580 if ( not ) { 5581 expr = ":not(" + expr + ")"; 5582 } 5583 5584 return elems.length === 1 ? 5585 jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] : 5586 jQuery.find.matches(expr, elems); 5587 }, 5588 5589 dir: function( elem, dir, until ) { 5590 var matched = [], 5591 cur = elem[ dir ]; 5592 5593 while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { 5594 if ( cur.nodeType === 1 ) { 5595 matched.push( cur ); 5596 } 5597 cur = cur[dir]; 5598 } 5599 return matched; 5600 }, 5601 5602 sibling: function( n, elem ) { 5603 var r = []; 5604 5605 for ( ; n; n = n.nextSibling ) { 5606 if ( n.nodeType === 1 && n !== elem ) { 5607 r.push( n ); 5608 } 5609 } 5610 5611 return r; 5612 } 5613 }); 5614 5615 // Implement the identical functionality for filter and not 5616 function winnow( elements, qualifier, keep ) { 5617 5618 // Can't pass null or undefined to indexOf in Firefox 4 5619 // Set to 0 to skip string check 5620 qualifier = qualifier || 0; 5621 5622 if ( jQuery.isFunction( qualifier ) ) { 5623 return jQuery.grep(elements, function( elem, i ) { 5624 var retVal = !!qualifier.call( elem, i, elem ); 5625 return retVal === keep; 5626 }); 5627 5628 } else if ( qualifier.nodeType ) { 5629 return jQuery.grep(elements, function( elem, i ) { 5630 return ( elem === qualifier ) === keep; 5631 }); 5632 5633 } else if ( typeof qualifier === "string" ) { 5634 var filtered = jQuery.grep(elements, function( elem ) { 5635 return elem.nodeType === 1; 5636 }); 5637 5638 if ( isSimple.test( qualifier ) ) { 5639 return jQuery.filter(qualifier, filtered, !keep); 5640 } else { 5641 qualifier = jQuery.filter( qualifier, filtered ); 5642 } 5643 } 5644 5645 return jQuery.grep(elements, function( elem, i ) { 5646 return ( jQuery.inArray( elem, qualifier ) >= 0 ) === keep; 5647 }); 5648 } 5649 function createSafeFragment( document ) { 5650 var list = nodeNames.split( "|" ), 5651 safeFrag = document.createDocumentFragment(); 5652 5653 if ( safeFrag.createElement ) { 5654 while ( list.length ) { 5655 safeFrag.createElement( 5656 list.pop() 5657 ); 5658 } 5659 } 5660 return safeFrag; 5661 } 5662 5663 var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" + 5664 "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video", 5665 rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g, 5666 rleadingWhitespace = /^\s+/, 5667 rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, 5668 rtagName = /<([\w:]+)/, 5669 rtbody = /<tbody/i, 5670 rhtml = /<|&#?\w+;/, 5671 rnoInnerhtml = /<(?:script|style|link)/i, 5672 rnocache = /<(?:script|object|embed|option|style)/i, 5673 rnoshimcache = new RegExp("<(?:" + nodeNames + ")[\\s/>]", "i"), 5674 rcheckableType = /^(?:checkbox|radio)$/, 5675 // checked="checked" or checked 5676 rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, 5677 rscriptType = /\/(java|ecma)script/i, 5678 rcleanScript = /^\s*<!(?:\[CDATA\[|\-\-)|[\]\-]{2}>\s*$/g, 5679 wrapMap = { 5680 option: [ 1, "<select multiple='multiple'>", "</select>" ], 5681 legend: [ 1, "<fieldset>", "</fieldset>" ], 5682 thead: [ 1, "<table>", "</table>" ], 5683 tr: [ 2, "<table><tbody>", "</tbody></table>" ], 5684 td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ], 5685 col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ], 5686 area: [ 1, "<map>", "</map>" ], 5687 _default: [ 0, "", "" ] 5688 }, 5689 safeFragment = createSafeFragment( document ), 5690 fragmentDiv = safeFragment.appendChild( document.createElement("div") ); 5691 5692 wrapMap.optgroup = wrapMap.option; 5693 wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; 5694 wrapMap.th = wrapMap.td; 5695 5696 // IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags, 5697 // unless wrapped in a div with non-breaking characters in front of it. 5698 if ( !jQuery.support.htmlSerialize ) { 5699 wrapMap._default = [ 1, "X<div>", "</div>" ]; 5700 } 5701 5702 jQuery.fn.extend({ 5703 text: function( value ) { 5704 return jQuery.access( this, function( value ) { 5705 return value === undefined ? 5706 jQuery.text( this ) : 5707 this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) ); 5708 }, null, value, arguments.length ); 5709 }, 5710 5711 wrapAll: function( html ) { 5712 if ( jQuery.isFunction( html ) ) { 5713 return this.each(function(i) { 5714 jQuery(this).wrapAll( html.call(this, i) ); 5715 }); 5716 } 5717 5718 if ( this[0] ) { 5719 // The elements to wrap the target around 5720 var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true); 5721 5722 if ( this[0].parentNode ) { 5723 wrap.insertBefore( this[0] ); 5724 } 5725 5726 wrap.map(function() { 5727 var elem = this; 5728 5729 while ( elem.firstChild && elem.firstChild.nodeType === 1 ) { 5730 elem = elem.firstChild; 5731 } 5732 5733 return elem; 5734 }).append( this ); 5735 } 5736 5737 return this; 5738 }, 5739 5740 wrapInner: function( html ) { 5741 if ( jQuery.isFunction( html ) ) { 5742 return this.each(function(i) { 5743 jQuery(this).wrapInner( html.call(this, i) ); 5744 }); 5745 } 5746 5747 return this.each(function() { 5748 var self = jQuery( this ), 5749 contents = self.contents(); 5750 5751 if ( contents.length ) { 5752 contents.wrapAll( html ); 5753 5754 } else { 5755 self.append( html ); 5756 } 5757 }); 5758 }, 5759 5760 wrap: function( html ) { 5761 var isFunction = jQuery.isFunction( html ); 5762 5763 return this.each(function(i) { 5764 jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html ); 5765 }); 5766 }, 5767 5768 unwrap: function() { 5769 return this.parent().each(function() { 5770 if ( !jQuery.nodeName( this, "body" ) ) { 5771 jQuery( this ).replaceWith( this.childNodes ); 5772 } 5773 }).end(); 5774 }, 5775 5776 append: function() { 5777 return this.domManip(arguments, true, function( elem ) { 5778 if ( this.nodeType === 1 || this.nodeType === 11 ) { 5779 this.appendChild( elem ); 5780 } 5781 }); 5782 }, 5783 5784 prepend: function() { 5785 return this.domManip(arguments, true, function( elem ) { 5786 if ( this.nodeType === 1 || this.nodeType === 11 ) { 5787 this.insertBefore( elem, this.firstChild ); 5788 } 5789 }); 5790 }, 5791 5792 before: function() { 5793 if ( !isDisconnected( this[0] ) ) { 5794 return this.domManip(arguments, false, function( elem ) { 5795 this.parentNode.insertBefore( elem, this ); 5796 }); 5797 } 5798 5799 if ( arguments.length ) { 5800 var set = jQuery.clean( arguments ); 5801 return this.pushStack( jQuery.merge( set, this ), "before", this.selector ); 5802 } 5803 }, 5804 5805 after: function() { 5806 if ( !isDisconnected( this[0] ) ) { 5807 return this.domManip(arguments, false, function( elem ) { 5808 this.parentNode.insertBefore( elem, this.nextSibling ); 5809 }); 5810 } 5811 5812 if ( arguments.length ) { 5813 var set = jQuery.clean( arguments ); 5814 return this.pushStack( jQuery.merge( this, set ), "after", this.selector ); 5815 } 5816 }, 5817 5818 // keepData is for internal use only--do not document 5819 remove: function( selector, keepData ) { 5820 var elem, 5821 i = 0; 5822 5823 for ( ; (elem = this[i]) != null; i++ ) { 5824 if ( !selector || jQuery.filter( selector, [ elem ] ).length ) { 5825 if ( !keepData && elem.nodeType === 1 ) { 5826 jQuery.cleanData( elem.getElementsByTagName("*") ); 5827 jQuery.cleanData( [ elem ] ); 5828 } 5829 5830 if ( elem.parentNode ) { 5831 elem.parentNode.removeChild( elem ); 5832 } 5833 } 5834 } 5835 5836 return this; 5837 }, 5838 5839 empty: function() { 5840 var elem, 5841 i = 0; 5842 5843 for ( ; (elem = this[i]) != null; i++ ) { 5844 // Remove element nodes and prevent memory leaks 5845 if ( elem.nodeType === 1 ) { 5846 jQuery.cleanData( elem.getElementsByTagName("*") ); 5847 } 5848 5849 // Remove any remaining nodes 5850 while ( elem.firstChild ) { 5851 elem.removeChild( elem.firstChild ); 5852 } 5853 } 5854 5855 return this; 5856 }, 5857 5858 clone: function( dataAndEvents, deepDataAndEvents ) { 5859 dataAndEvents = dataAndEvents == null ? false : dataAndEvents; 5860 deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; 5861 5862 return this.map( function () { 5863 return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); 5864 }); 5865 }, 5866 5867 html: function( value ) { 5868 return jQuery.access( this, function( value ) { 5869 var elem = this[0] || {}, 5870 i = 0, 5871 l = this.length; 5872 5873 if ( value === undefined ) { 5874 return elem.nodeType === 1 ? 5875 elem.innerHTML.replace( rinlinejQuery, "" ) : 5876 undefined; 5877 } 5878 5879 // See if we can take a shortcut and just use innerHTML 5880 if ( typeof value === "string" && !rnoInnerhtml.test( value ) && 5881 ( jQuery.support.htmlSerialize || !rnoshimcache.test( value ) ) && 5882 ( jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value ) ) && 5883 !wrapMap[ ( rtagName.exec( value ) || ["", ""] )[1].toLowerCase() ] ) { 5884 5885 value = value.replace( rxhtmlTag, "<$1></$2>" ); 5886 5887 try { 5888 for (; i < l; i++ ) { 5889 // Remove element nodes and prevent memory leaks 5890 elem = this[i] || {}; 5891 if ( elem.nodeType === 1 ) { 5892 jQuery.cleanData( elem.getElementsByTagName( "*" ) ); 5893 elem.innerHTML = value; 5894 } 5895 } 5896 5897 elem = 0; 5898 5899 // If using innerHTML throws an exception, use the fallback method 5900 } catch(e) {} 5901 } 5902 5903 if ( elem ) { 5904 this.empty().append( value ); 5905 } 5906 }, null, value, arguments.length ); 5907 }, 5908 5909 replaceWith: function( value ) { 5910 if ( !isDisconnected( this[0] ) ) { 5911 // Make sure that the elements are removed from the DOM before they are inserted 5912 // this can help fix replacing a parent with child elements 5913 if ( jQuery.isFunction( value ) ) { 5914 return this.each(function(i) { 5915 var self = jQuery(this), old = self.html(); 5916 self.replaceWith( value.call( this, i, old ) ); 5917 }); 5918 } 5919 5920 if ( typeof value !== "string" ) { 5921 value = jQuery( value ).detach(); 5922 } 5923 5924 return this.each(function() { 5925 var next = this.nextSibling, 5926 parent = this.parentNode; 5927 5928 jQuery( this ).remove(); 5929 5930 if ( next ) { 5931 jQuery(next).before( value ); 5932 } else { 5933 jQuery(parent).append( value ); 5934 } 5935 }); 5936 } 5937 5938 return this.length ? 5939 this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value ) : 5940 this; 5941 }, 5942 5943 detach: function( selector ) { 5944 return this.remove( selector, true ); 5945 }, 5946 5947 domManip: function( args, table, callback ) { 5948 5949 // Flatten any nested arrays 5950 args = [].concat.apply( [], args ); 5951 5952 var results, first, fragment, iNoClone, 5953 i = 0, 5954 value = args[0], 5955 scripts = [], 5956 l = this.length; 5957 5958 // We can't cloneNode fragments that contain checked, in WebKit 5959 if ( !jQuery.support.checkClone && l > 1 && typeof value === "string" && rchecked.test( value ) ) { 5960 return this.each(function() { 5961 jQuery(this).domManip( args, table, callback ); 5962 }); 5963 } 5964 5965 if ( jQuery.isFunction(value) ) { 5966 return this.each(function(i) { 5967 var self = jQuery(this); 5968 args[0] = value.call( this, i, table ? self.html() : undefined ); 5969 self.domManip( args, table, callback ); 5970 }); 5971 } 5972 5973 if ( this[0] ) { 5974 results = jQuery.buildFragment( args, this, scripts ); 5975 fragment = results.fragment; 5976 first = fragment.firstChild; 5977 5978 if ( fragment.childNodes.length === 1 ) { 5979 fragment = first; 5980 } 5981 5982 if ( first ) { 5983 table = table && jQuery.nodeName( first, "tr" ); 5984 5985 // Use the original fragment for the last item instead of the first because it can end up 5986 // being emptied incorrectly in certain situations (#8070). 5987 // Fragments from the fragment cache must always be cloned and never used in place. 5988 for ( iNoClone = results.cacheable || l - 1; i < l; i++ ) { 5989 callback.call( 5990 table && jQuery.nodeName( this[i], "table" ) ? 5991 findOrAppend( this[i], "tbody" ) : 5992 this[i], 5993 i === iNoClone ? 5994 fragment : 5995 jQuery.clone( fragment, true, true ) 5996 ); 5997 } 5998 } 5999 6000 // Fix #11809: Avoid leaking memory 6001 fragment = first = null; 6002 6003 if ( scripts.length ) { 6004 jQuery.each( scripts, function( i, elem ) { 6005 if ( elem.src ) { 6006 if ( jQuery.ajax ) { 6007 jQuery.ajax({ 6008 url: elem.src, 6009 type: "GET", 6010 dataType: "script", 6011 async: false, 6012 global: false, 6013 "throws": true 6014 }); 6015 } else { 6016 jQuery.error("no ajax"); 6017 } 6018 } else { 6019 jQuery.globalEval( ( elem.text || elem.textContent || elem.innerHTML || "" ).replace( rcleanScript, "" ) ); 6020 } 6021 6022 if ( elem.parentNode ) { 6023 elem.parentNode.removeChild( elem ); 6024 } 6025 }); 6026 } 6027 } 6028 6029 return this; 6030 } 6031 }); 6032 6033 function findOrAppend( elem, tag ) { 6034 return elem.getElementsByTagName( tag )[0] || elem.appendChild( elem.ownerDocument.createElement( tag ) ); 6035 } 6036 6037 function cloneCopyEvent( src, dest ) { 6038 6039 if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) { 6040 return; 6041 } 6042 6043 var type, i, l, 6044 oldData = jQuery._data( src ), 6045 curData = jQuery._data( dest, oldData ), 6046 events = oldData.events; 6047 6048 if ( events ) { 6049 delete curData.handle; 6050 curData.events = {}; 6051 6052 for ( type in events ) { 6053 for ( i = 0, l = events[ type ].length; i < l; i++ ) { 6054 jQuery.event.add( dest, type, events[ type ][ i ] ); 6055 } 6056 } 6057 } 6058 6059 // make the cloned public data object a copy from the original 6060 if ( curData.data ) { 6061 curData.data = jQuery.extend( {}, curData.data ); 6062 } 6063 } 6064 6065 function cloneFixAttributes( src, dest ) { 6066 var nodeName; 6067 6068 // We do not need to do anything for non-Elements 6069 if ( dest.nodeType !== 1 ) { 6070 return; 6071 } 6072 6073 // clearAttributes removes the attributes, which we don't want, 6074 // but also removes the attachEvent events, which we *do* want 6075 if ( dest.clearAttributes ) { 6076 dest.clearAttributes(); 6077 } 6078 6079 // mergeAttributes, in contrast, only merges back on the 6080 // original attributes, not the events 6081 if ( dest.mergeAttributes ) { 6082 dest.mergeAttributes( src ); 6083 } 6084 6085 nodeName = dest.nodeName.toLowerCase(); 6086 6087 if ( nodeName === "object" ) { 6088 // IE6-10 improperly clones children of object elements using classid. 6089 // IE10 throws NoModificationAllowedError if parent is null, #12132. 6090 if ( dest.parentNode ) { 6091 dest.outerHTML = src.outerHTML; 6092 } 6093 6094 // This path appears unavoidable for IE9. When cloning an object 6095 // element in IE9, the outerHTML strategy above is not sufficient. 6096 // If the src has innerHTML and the destination does not, 6097 // copy the src.innerHTML into the dest.innerHTML. #10324 6098 if ( jQuery.support.html5Clone && (src.innerHTML && !jQuery.trim(dest.innerHTML)) ) { 6099 dest.innerHTML = src.innerHTML; 6100 } 6101 6102 } else if ( nodeName === "input" && rcheckableType.test( src.type ) ) { 6103 // IE6-8 fails to persist the checked state of a cloned checkbox 6104 // or radio button. Worse, IE6-7 fail to give the cloned element 6105 // a checked appearance if the defaultChecked value isn't also set 6106 6107 dest.defaultChecked = dest.checked = src.checked; 6108 6109 // IE6-7 get confused and end up setting the value of a cloned 6110 // checkbox/radio button to an empty string instead of "on" 6111 if ( dest.value !== src.value ) { 6112 dest.value = src.value; 6113 } 6114 6115 // IE6-8 fails to return the selected option to the default selected 6116 // state when cloning options 6117 } else if ( nodeName === "option" ) { 6118 dest.selected = src.defaultSelected; 6119 6120 // IE6-8 fails to set the defaultValue to the correct value when 6121 // cloning other types of input fields 6122 } else if ( nodeName === "input" || nodeName === "textarea" ) { 6123 dest.defaultValue = src.defaultValue; 6124 6125 // IE blanks contents when cloning scripts 6126 } else if ( nodeName === "script" && dest.text !== src.text ) { 6127 dest.text = src.text; 6128 } 6129 6130 // Event data gets referenced instead of copied if the expando 6131 // gets copied too 6132 dest.removeAttribute( jQuery.expando ); 6133 } 6134 6135 jQuery.buildFragment = function( args, context, scripts ) { 6136 var fragment, cacheable, cachehit, 6137 first = args[ 0 ]; 6138 6139 // Set context from what may come in as undefined or a jQuery collection or a node 6140 // Updated to fix #12266 where accessing context[0] could throw an exception in IE9/10 & 6141 // also doubles as fix for #8950 where plain objects caused createDocumentFragment exception 6142 context = context || document; 6143 context = !context.nodeType && context[0] || context; 6144 context = context.ownerDocument || context; 6145 6146 // Only cache "small" (1/2 KB) HTML strings that are associated with the main document 6147 // Cloning options loses the selected state, so don't cache them 6148 // IE 6 doesn't like it when you put <object> or <embed> elements in a fragment 6149 // Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache 6150 // Lastly, IE6,7,8 will not correctly reuse cached fragments that were created from unknown elems #10501 6151 if ( args.length === 1 && typeof first === "string" && first.length < 512 && context === document && 6152 first.charAt(0) === "<" && !rnocache.test( first ) && 6153 (jQuery.support.checkClone || !rchecked.test( first )) && 6154 (jQuery.support.html5Clone || !rnoshimcache.test( first )) ) { 6155 6156 // Mark cacheable and look for a hit 6157 cacheable = true; 6158 fragment = jQuery.fragments[ first ]; 6159 cachehit = fragment !== undefined; 6160 } 6161 6162 if ( !fragment ) { 6163 fragment = context.createDocumentFragment(); 6164 jQuery.clean( args, context, fragment, scripts ); 6165 6166 // Update the cache, but only store false 6167 // unless this is a second parsing of the same content 6168 if ( cacheable ) { 6169 jQuery.fragments[ first ] = cachehit && fragment; 6170 } 6171 } 6172 6173 return { fragment: fragment, cacheable: cacheable }; 6174 }; 6175 6176 jQuery.fragments = {}; 6177 6178 jQuery.each({ 6179 appendTo: "append", 6180 prependTo: "prepend", 6181 insertBefore: "before", 6182 insertAfter: "after", 6183 replaceAll: "replaceWith" 6184 }, function( name, original ) { 6185 jQuery.fn[ name ] = function( selector ) { 6186 var elems, 6187 i = 0, 6188 ret = [], 6189 insert = jQuery( selector ), 6190 l = insert.length, 6191 parent = this.length === 1 && this[0].parentNode; 6192 6193 if ( (parent == null || parent && parent.nodeType === 11 && parent.childNodes.length === 1) && l === 1 ) { 6194 insert[ original ]( this[0] ); 6195 return this; 6196 } else { 6197 for ( ; i < l; i++ ) { 6198 elems = ( i > 0 ? this.clone(true) : this ).get(); 6199 jQuery( insert[i] )[ original ]( elems ); 6200 ret = ret.concat( elems ); 6201 } 6202 6203 return this.pushStack( ret, name, insert.selector ); 6204 } 6205 }; 6206 }); 6207 6208 function getAll( elem ) { 6209 if ( typeof elem.getElementsByTagName !== "undefined" ) { 6210 return elem.getElementsByTagName( "*" ); 6211 6212 } else if ( typeof elem.querySelectorAll !== "undefined" ) { 6213 return elem.querySelectorAll( "*" ); 6214 6215 } else { 6216 return []; 6217 } 6218 } 6219 6220 // Used in clean, fixes the defaultChecked property 6221 function fixDefaultChecked( elem ) { 6222 if ( rcheckableType.test( elem.type ) ) { 6223 elem.defaultChecked = elem.checked; 6224 } 6225 } 6226 6227 jQuery.extend({ 6228 clone: function( elem, dataAndEvents, deepDataAndEvents ) { 6229 var srcElements, 6230 destElements, 6231 i, 6232 clone; 6233 6234 if ( jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) { 6235 clone = elem.cloneNode( true ); 6236 6237 // IE<=8 does not properly clone detached, unknown element nodes 6238 } else { 6239 fragmentDiv.innerHTML = elem.outerHTML; 6240 fragmentDiv.removeChild( clone = fragmentDiv.firstChild ); 6241 } 6242 6243 if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) && 6244 (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) { 6245 // IE copies events bound via attachEvent when using cloneNode. 6246 // Calling detachEvent on the clone will also remove the events 6247 // from the original. In order to get around this, we use some 6248 // proprietary methods to clear the events. Thanks to MooTools 6249 // guys for this hotness. 6250 6251 cloneFixAttributes( elem, clone ); 6252 6253 // Using Sizzle here is crazy slow, so we use getElementsByTagName instead 6254 srcElements = getAll( elem ); 6255 destElements = getAll( clone ); 6256 6257 // Weird iteration because IE will replace the length property 6258 // with an element if you are cloning the body and one of the 6259 // elements on the page has a name or id of "length" 6260 for ( i = 0; srcElements[i]; ++i ) { 6261 // Ensure that the destination node is not null; Fixes #9587 6262 if ( destElements[i] ) { 6263 cloneFixAttributes( srcElements[i], destElements[i] ); 6264 } 6265 } 6266 } 6267 6268 // Copy the events from the original to the clone 6269 if ( dataAndEvents ) { 6270 cloneCopyEvent( elem, clone ); 6271 6272 if ( deepDataAndEvents ) { 6273 srcElements = getAll( elem ); 6274 destElements = getAll( clone ); 6275 6276 for ( i = 0; srcElements[i]; ++i ) { 6277 cloneCopyEvent( srcElements[i], destElements[i] ); 6278 } 6279 } 6280 } 6281 6282 srcElements = destElements = null; 6283 6284 // Return the cloned set 6285 return clone; 6286 }, 6287 6288 clean: function( elems, context, fragment, scripts ) { 6289 var i, j, elem, tag, wrap, depth, div, hasBody, tbody, len, handleScript, jsTags, 6290 safe = context === document && safeFragment, 6291 ret = []; 6292 6293 // Ensure that context is a document 6294 if ( !context || typeof context.createDocumentFragment === "undefined" ) { 6295 context = document; 6296 } 6297 6298 // Use the already-created safe fragment if context permits 6299 for ( i = 0; (elem = elems[i]) != null; i++ ) { 6300 if ( typeof elem === "number" ) { 6301 elem += ""; 6302 } 6303 6304 if ( !elem ) { 6305 continue; 6306 } 6307 6308 // Convert html string into DOM nodes 6309 if ( typeof elem === "string" ) { 6310 if ( !rhtml.test( elem ) ) { 6311 elem = context.createTextNode( elem ); 6312 } else { 6313 // Ensure a safe container in which to render the html 6314 safe = safe || createSafeFragment( context ); 6315 div = context.createElement("div"); 6316 safe.appendChild( div ); 6317 6318 // Fix "XHTML"-style tags in all browsers 6319 elem = elem.replace(rxhtmlTag, "<$1></$2>"); 6320 6321 // Go to html and back, then peel off extra wrappers 6322 tag = ( rtagName.exec( elem ) || ["", ""] )[1].toLowerCase(); 6323 wrap = wrapMap[ tag ] || wrapMap._default; 6324 depth = wrap[0]; 6325 div.innerHTML = wrap[1] + elem + wrap[2]; 6326 6327 // Move to the right depth 6328 while ( depth-- ) { 6329 div = div.lastChild; 6330 } 6331 6332 // Remove IE's autoinserted <tbody> from table fragments 6333 if ( !jQuery.support.tbody ) { 6334 6335 // String was a <table>, *may* have spurious <tbody> 6336 hasBody = rtbody.test(elem); 6337 tbody = tag === "table" && !hasBody ? 6338 div.firstChild && div.firstChild.childNodes : 6339 6340 // String was a bare <thead> or <tfoot> 6341 wrap[1] === "<table>" && !hasBody ? 6342 div.childNodes : 6343 []; 6344 6345 for ( j = tbody.length - 1; j >= 0 ; --j ) { 6346 if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) { 6347 tbody[ j ].parentNode.removeChild( tbody[ j ] ); 6348 } 6349 } 6350 } 6351 6352 // IE completely kills leading whitespace when innerHTML is used 6353 if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) { 6354 div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild ); 6355 } 6356 6357 elem = div.childNodes; 6358 6359 // Take out of fragment container (we need a fresh div each time) 6360 div.parentNode.removeChild( div ); 6361 } 6362 } 6363 6364 if ( elem.nodeType ) { 6365 ret.push( elem ); 6366 } else { 6367 jQuery.merge( ret, elem ); 6368 } 6369 } 6370 6371 // Fix #11356: Clear elements from safeFragment 6372 if ( div ) { 6373 elem = div = safe = null; 6374 } 6375 6376 // Reset defaultChecked for any radios and checkboxes 6377 // about to be appended to the DOM in IE 6/7 (#8060) 6378 if ( !jQuery.support.appendChecked ) { 6379 for ( i = 0; (elem = ret[i]) != null; i++ ) { 6380 if ( jQuery.nodeName( elem, "input" ) ) { 6381 fixDefaultChecked( elem ); 6382 } else if ( typeof elem.getElementsByTagName !== "undefined" ) { 6383 jQuery.grep( elem.getElementsByTagName("input"), fixDefaultChecked ); 6384 } 6385 } 6386 } 6387 6388 // Append elements to a provided document fragment 6389 if ( fragment ) { 6390 // Special handling of each script element 6391 handleScript = function( elem ) { 6392 // Check if we consider it executable 6393 if ( !elem.type || rscriptType.test( elem.type ) ) { 6394 // Detach the script and store it in the scripts array (if provided) or the fragment 6395 // Return truthy to indicate that it has been handled 6396 return scripts ? 6397 scripts.push( elem.parentNode ? elem.parentNode.removeChild( elem ) : elem ) : 6398 fragment.appendChild( elem ); 6399 } 6400 }; 6401 6402 for ( i = 0; (elem = ret[i]) != null; i++ ) { 6403 // Check if we're done after handling an executable script 6404 if ( !( jQuery.nodeName( elem, "script" ) && handleScript( elem ) ) ) { 6405 // Append to fragment and handle embedded scripts 6406 fragment.appendChild( elem ); 6407 if ( typeof elem.getElementsByTagName !== "undefined" ) { 6408 // handleScript alters the DOM, so use jQuery.merge to ensure snapshot iteration 6409 jsTags = jQuery.grep( jQuery.merge( [], elem.getElementsByTagName("script") ), handleScript ); 6410 6411 // Splice the scripts into ret after their former ancestor and advance our index beyond them 6412 ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) ); 6413 i += jsTags.length; 6414 } 6415 } 6416 } 6417 } 6418 6419 return ret; 6420 }, 6421 6422 cleanData: function( elems, /* internal */ acceptData ) { 6423 var data, id, elem, type, 6424 i = 0, 6425 internalKey = jQuery.expando, 6426 cache = jQuery.cache, 6427 deleteExpando = jQuery.support.deleteExpando, 6428 special = jQuery.event.special; 6429 6430 for ( ; (elem = elems[i]) != null; i++ ) { 6431 6432 if ( acceptData || jQuery.acceptData( elem ) ) { 6433 6434 id = elem[ internalKey ]; 6435 data = id && cache[ id ]; 6436 6437 if ( data ) { 6438 if ( data.events ) { 6439 for ( type in data.events ) { 6440 if ( special[ type ] ) { 6441 jQuery.event.remove( elem, type ); 6442 6443 // This is a shortcut to avoid jQuery.event.remove's overhead 6444 } else { 6445 jQuery.removeEvent( elem, type, data.handle ); 6446 } 6447 } 6448 } 6449 6450 // Remove cache only if it was not already removed by jQuery.event.remove 6451 if ( cache[ id ] ) { 6452 6453 delete cache[ id ]; 6454 6455 // IE does not allow us to delete expando properties from nodes, 6456 // nor does it have a removeAttribute function on Document nodes; 6457 // we must handle all of these cases 6458 if ( deleteExpando ) { 6459 delete elem[ internalKey ]; 6460 6461 } else if ( elem.removeAttribute ) { 6462 elem.removeAttribute( internalKey ); 6463 6464 } else { 6465 elem[ internalKey ] = null; 6466 } 6467 6468 jQuery.deletedIds.push( id ); 6469 } 6470 } 6471 } 6472 } 6473 } 6474 }); 6475 // Limit scope pollution from any deprecated API 6476 (function() { 6477 6478 var matched, browser; 6479 6480 // Use of jQuery.browser is frowned upon. 6481 // More details: http://api.jquery.com/jQuery.browser 6482 // jQuery.uaMatch maintained for back-compat 6483 jQuery.uaMatch = function( ua ) { 6484 ua = ua.toLowerCase(); 6485 6486 var match = /(chrome)[ \/]([\w.]+)/.exec( ua ) || 6487 /(webkit)[ \/]([\w.]+)/.exec( ua ) || 6488 /(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) || 6489 /(msie) ([\w.]+)/.exec( ua ) || 6490 ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) || 6491 []; 6492 6493 return { 6494 browser: match[ 1 ] || "", 6495 version: match[ 2 ] || "0" 6496 }; 6497 }; 6498 6499 matched = jQuery.uaMatch( navigator.userAgent ); 6500 browser = {}; 6501 6502 if ( matched.browser ) { 6503 browser[ matched.browser ] = true; 6504 browser.version = matched.version; 6505 } 6506 6507 // Chrome is Webkit, but Webkit is also Safari. 6508 if ( browser.chrome ) { 6509 browser.webkit = true; 6510 } else if ( browser.webkit ) { 6511 browser.safari = true; 6512 } 6513 6514 jQuery.browser = browser; 6515 6516 jQuery.sub = function() { 6517 function jQuerySub( selector, context ) { 6518 return new jQuerySub.fn.init( selector, context ); 6519 } 6520 jQuery.extend( true, jQuerySub, this ); 6521 jQuerySub.superclass = this; 6522 jQuerySub.fn = jQuerySub.prototype = this(); 6523 jQuerySub.fn.constructor = jQuerySub; 6524 jQuerySub.sub = this.sub; 6525 jQuerySub.fn.init = function init( selector, context ) { 6526 if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) { 6527 context = jQuerySub( context ); 6528 } 6529 6530 return jQuery.fn.init.call( this, selector, context, rootjQuerySub ); 6531 }; 6532 jQuerySub.fn.init.prototype = jQuerySub.fn; 6533 var rootjQuerySub = jQuerySub(document); 6534 return jQuerySub; 6535 }; 6536 6537 })(); 6538 var curCSS, iframe, iframeDoc, 6539 ralpha = /alpha\([^)]*\)/i, 6540 ropacity = /opacity=([^)]*)/, 6541 rposition = /^(top|right|bottom|left)$/, 6542 // swappable if display is none or starts with table except "table", "table-cell", or "table-caption" 6543 // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display 6544 rdisplayswap = /^(none|table(?!-c[ea]).+)/, 6545 rmargin = /^margin/, 6546 rnumsplit = new RegExp( "^(" + core_pnum + ")(.*)$", "i" ), 6547 rnumnonpx = new RegExp( "^(" + core_pnum + ")(?!px)[a-z%]+$", "i" ), 6548 rrelNum = new RegExp( "^([-+])=(" + core_pnum + ")", "i" ), 6549 elemdisplay = { BODY: "block" }, 6550 6551 cssShow = { position: "absolute", visibility: "hidden", display: "block" }, 6552 cssNormalTransform = { 6553 letterSpacing: 0, 6554 fontWeight: 400 6555 }, 6556 6557 cssExpand = [ "Top", "Right", "Bottom", "Left" ], 6558 cssPrefixes = [ "Webkit", "O", "Moz", "ms" ], 6559 6560 eventsToggle = jQuery.fn.toggle; 6561 6562 // return a css property mapped to a potentially vendor prefixed property 6563 function vendorPropName( style, name ) { 6564 6565 // shortcut for names that are not vendor prefixed 6566 if ( name in style ) { 6567 return name; 6568 } 6569 6570 // check for vendor prefixed names 6571 var capName = name.charAt(0).toUpperCase() + name.slice(1), 6572 origName = name, 6573 i = cssPrefixes.length; 6574 6575 while ( i-- ) { 6576 name = cssPrefixes[ i ] + capName; 6577 if ( name in style ) { 6578 return name; 6579 } 6580 } 6581 6582 return origName; 6583 } 6584 6585 function isHidden( elem, el ) { 6586 elem = el || elem; 6587 return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem ); 6588 } 6589 6590 function showHide( elements, show ) { 6591 var elem, display, 6592 values = [], 6593 index = 0, 6594 length = elements.length; 6595 6596 for ( ; index < length; index++ ) { 6597 elem = elements[ index ]; 6598 if ( !elem.style ) { 6599 continue; 6600 } 6601 values[ index ] = jQuery._data( elem, "olddisplay" ); 6602 if ( show ) { 6603 // Reset the inline display of this element to learn if it is 6604 // being hidden by cascaded rules or not 6605 if ( !values[ index ] && elem.style.display === "none" ) { 6606 elem.style.display = ""; 6607 } 6608 6609 // Set elements which have been overridden with display: none 6610 // in a stylesheet to whatever the default browser style is 6611 // for such an element 6612 if ( elem.style.display === "" && isHidden( elem ) ) { 6613 values[ index ] = jQuery._data( elem, "olddisplay", css_defaultDisplay(elem.nodeName) ); 6614 } 6615 } else { 6616 display = curCSS( elem, "display" ); 6617 6618 if ( !values[ index ] && display !== "none" ) { 6619 jQuery._data( elem, "olddisplay", display ); 6620 } 6621 } 6622 } 6623 6624 // Set the display of most of the elements in a second loop 6625 // to avoid the constant reflow 6626 for ( index = 0; index < length; index++ ) { 6627 elem = elements[ index ]; 6628 if ( !elem.style ) { 6629 continue; 6630 } 6631 if ( !show || elem.style.display === "none" || elem.style.display === "" ) { 6632 elem.style.display = show ? values[ index ] || "" : "none"; 6633 } 6634 } 6635 6636 return elements; 6637 } 6638 6639 jQuery.fn.extend({ 6640 css: function( name, value ) { 6641 return jQuery.access( this, function( elem, name, value ) { 6642 return value !== undefined ? 6643 jQuery.style( elem, name, value ) : 6644 jQuery.css( elem, name ); 6645 }, name, value, arguments.length > 1 ); 6646 }, 6647 show: function() { 6648 return showHide( this, true ); 6649 }, 6650 hide: function() { 6651 return showHide( this ); 6652 }, 6653 toggle: function( state, fn2 ) { 6654 var bool = typeof state === "boolean"; 6655 6656 if ( jQuery.isFunction( state ) && jQuery.isFunction( fn2 ) ) { 6657 return eventsToggle.apply( this, arguments ); 6658 } 6659 6660 return this.each(function() { 6661 if ( bool ? state : isHidden( this ) ) { 6662 jQuery( this ).show(); 6663 } else { 6664 jQuery( this ).hide(); 6665 } 6666 }); 6667 } 6668 }); 6669 6670 jQuery.extend({ 6671 // Add in style property hooks for overriding the default 6672 // behavior of getting and setting a style property 6673 cssHooks: { 6674 opacity: { 6675 get: function( elem, computed ) { 6676 if ( computed ) { 6677 // We should always get a number back from opacity 6678 var ret = curCSS( elem, "opacity" ); 6679 return ret === "" ? "1" : ret; 6680 6681 } 6682 } 6683 } 6684 }, 6685 6686 // Exclude the following css properties to add px 6687 cssNumber: { 6688 "fillOpacity": true, 6689 "fontWeight": true, 6690 "lineHeight": true, 6691 "opacity": true, 6692 "orphans": true, 6693 "widows": true, 6694 "zIndex": true, 6695 "zoom": true 6696 }, 6697 6698 // Add in properties whose names you wish to fix before 6699 // setting or getting the value 6700 cssProps: { 6701 // normalize float css property 6702 "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat" 6703 }, 6704 6705 // Get and set the style property on a DOM Node 6706 style: function( elem, name, value, extra ) { 6707 // Don't set styles on text and comment nodes 6708 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { 6709 return; 6710 } 6711 6712 // Make sure that we're working with the right name 6713 var ret, type, hooks, 6714 origName = jQuery.camelCase( name ), 6715 style = elem.style; 6716 6717 name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) ); 6718 6719 // gets hook for the prefixed version 6720 // followed by the unprefixed version 6721 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; 6722 6723 // Check if we're setting a value 6724 if ( value !== undefined ) { 6725 type = typeof value; 6726 6727 // convert relative number strings (+= or -=) to relative numbers. #7345 6728 if ( type === "string" && (ret = rrelNum.exec( value )) ) { 6729 value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) ); 6730 // Fixes bug #9237 6731 type = "number"; 6732 } 6733 6734 // Make sure that NaN and null values aren't set. See: #7116 6735 if ( value == null || type === "number" && isNaN( value ) ) { 6736 return; 6737 } 6738 6739 // If a number was passed in, add 'px' to the (except for certain CSS properties) 6740 if ( type === "number" && !jQuery.cssNumber[ origName ] ) { 6741 value += "px"; 6742 } 6743 6744 // If a hook was provided, use that value, otherwise just set the specified value 6745 if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) { 6746 // Wrapped to prevent IE from throwing errors when 'invalid' values are provided 6747 // Fixes bug #5509 6748 try { 6749 style[ name ] = value; 6750 } catch(e) {} 6751 } 6752 6753 } else { 6754 // If a hook was provided get the non-computed value from there 6755 if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) { 6756 return ret; 6757 } 6758 6759 // Otherwise just get the value from the style object 6760 return style[ name ]; 6761 } 6762 }, 6763 6764 css: function( elem, name, numeric, extra ) { 6765 var val, num, hooks, 6766 origName = jQuery.camelCase( name ); 6767 6768 // Make sure that we're working with the right name 6769 name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) ); 6770 6771 // gets hook for the prefixed version 6772 // followed by the unprefixed version 6773 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; 6774 6775 // If a hook was provided get the computed value from there 6776 if ( hooks && "get" in hooks ) { 6777 val = hooks.get( elem, true, extra ); 6778 } 6779 6780 // Otherwise, if a way to get the computed value exists, use that 6781 if ( val === undefined ) { 6782 val = curCSS( elem, name ); 6783 } 6784 6785 //convert "normal" to computed value 6786 if ( val === "normal" && name in cssNormalTransform ) { 6787 val = cssNormalTransform[ name ]; 6788 } 6789 6790 // Return, converting to number if forced or a qualifier was provided and val looks numeric 6791 if ( numeric || extra !== undefined ) { 6792 num = parseFloat( val ); 6793 return numeric || jQuery.isNumeric( num ) ? num || 0 : val; 6794 } 6795 return val; 6796 }, 6797 6798 // A method for quickly swapping in/out CSS properties to get correct calculations 6799 swap: function( elem, options, callback ) { 6800 var ret, name, 6801 old = {}; 6802 6803 // Remember the old values, and insert the new ones 6804 for ( name in options ) { 6805 old[ name ] = elem.style[ name ]; 6806 elem.style[ name ] = options[ name ]; 6807 } 6808 6809 ret = callback.call( elem ); 6810 6811 // Revert the old values 6812 for ( name in options ) { 6813 elem.style[ name ] = old[ name ]; 6814 } 6815 6816 return ret; 6817 } 6818 }); 6819 6820 // NOTE: To any future maintainer, we've window.getComputedStyle 6821 // because jsdom on node.js will break without it. 6822 if ( window.getComputedStyle ) { 6823 curCSS = function( elem, name ) { 6824 var ret, width, minWidth, maxWidth, 6825 computed = window.getComputedStyle( elem, null ), 6826 style = elem.style; 6827 6828 if ( computed ) { 6829 6830 // getPropertyValue is only needed for .css('filter') in IE9, see #12537 6831 ret = computed.getPropertyValue( name ) || computed[ name ]; 6832 6833 if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) { 6834 ret = jQuery.style( elem, name ); 6835 } 6836 6837 // A tribute to the "awesome hack by Dean Edwards" 6838 // Chrome < 17 and Safari 5.0 uses "computed value" instead of "used value" for margin-right 6839 // Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels 6840 // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values 6841 if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) { 6842 width = style.width; 6843 minWidth = style.minWidth; 6844 maxWidth = style.maxWidth; 6845 6846 style.minWidth = style.maxWidth = style.width = ret; 6847 ret = computed.width; 6848 6849 style.width = width; 6850 style.minWidth = minWidth; 6851 style.maxWidth = maxWidth; 6852 } 6853 } 6854 6855 return ret; 6856 }; 6857 } else if ( document.documentElement.currentStyle ) { 6858 curCSS = function( elem, name ) { 6859 var left, rsLeft, 6860 ret = elem.currentStyle && elem.currentStyle[ name ], 6861 style = elem.style; 6862 6863 // Avoid setting ret to empty string here 6864 // so we don't default to auto 6865 if ( ret == null && style && style[ name ] ) { 6866 ret = style[ name ]; 6867 } 6868 6869 // From the awesome hack by Dean Edwards 6870 // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 6871 6872 // If we're not dealing with a regular pixel number 6873 // but a number that has a weird ending, we need to convert it to pixels 6874 // but not position css attributes, as those are proportional to the parent element instead 6875 // and we can't measure the parent instead because it might trigger a "stacking dolls" problem 6876 if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) { 6877 6878 // Remember the original values 6879 left = style.left; 6880 rsLeft = elem.runtimeStyle && elem.runtimeStyle.left; 6881 6882 // Put in the new values to get a computed value out 6883 if ( rsLeft ) { 6884 elem.runtimeStyle.left = elem.currentStyle.left; 6885 } 6886 style.left = name === "fontSize" ? "1em" : ret; 6887 ret = style.pixelLeft + "px"; 6888 6889 // Revert the changed values 6890 style.left = left; 6891 if ( rsLeft ) { 6892 elem.runtimeStyle.left = rsLeft; 6893 } 6894 } 6895 6896 return ret === "" ? "auto" : ret; 6897 }; 6898 } 6899 6900 function setPositiveNumber( elem, value, subtract ) { 6901 var matches = rnumsplit.exec( value ); 6902 return matches ? 6903 Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) : 6904 value; 6905 } 6906 6907 function augmentWidthOrHeight( elem, name, extra, isBorderBox ) { 6908 var i = extra === ( isBorderBox ? "border" : "content" ) ? 6909 // If we already have the right measurement, avoid augmentation 6910 4 : 6911 // Otherwise initialize for horizontal or vertical properties 6912 name === "width" ? 1 : 0, 6913 6914 val = 0; 6915 6916 for ( ; i < 4; i += 2 ) { 6917 // both box models exclude margin, so add it if we want it 6918 if ( extra === "margin" ) { 6919 // we use jQuery.css instead of curCSS here 6920 // because of the reliableMarginRight CSS hook! 6921 val += jQuery.css( elem, extra + cssExpand[ i ], true ); 6922 } 6923 6924 // From this point on we use curCSS for maximum performance (relevant in animations) 6925 if ( isBorderBox ) { 6926 // border-box includes padding, so remove it if we want content 6927 if ( extra === "content" ) { 6928 val -= parseFloat( curCSS( elem, "padding" + cssExpand[ i ] ) ) || 0; 6929 } 6930 6931 // at this point, extra isn't border nor margin, so remove border 6932 if ( extra !== "margin" ) { 6933 val -= parseFloat( curCSS( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0; 6934 } 6935 } else { 6936 // at this point, extra isn't content, so add padding 6937 val += parseFloat( curCSS( elem, "padding" + cssExpand[ i ] ) ) || 0; 6938 6939 // at this point, extra isn't content nor padding, so add border 6940 if ( extra !== "padding" ) { 6941 val += parseFloat( curCSS( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0; 6942 } 6943 } 6944 } 6945 6946 return val; 6947 } 6948 6949 function getWidthOrHeight( elem, name, extra ) { 6950 6951 // Start with offset property, which is equivalent to the border-box value 6952 var val = name === "width" ? elem.offsetWidth : elem.offsetHeight, 6953 valueIsBorderBox = true, 6954 isBorderBox = jQuery.support.boxSizing && jQuery.css( elem, "boxSizing" ) === "border-box"; 6955 6956 // some non-html elements return undefined for offsetWidth, so check for null/undefined 6957 // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285 6958 // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668 6959 if ( val <= 0 || val == null ) { 6960 // Fall back to computed then uncomputed css if necessary 6961 val = curCSS( elem, name ); 6962 if ( val < 0 || val == null ) { 6963 val = elem.style[ name ]; 6964 } 6965 6966 // Computed unit is not pixels. Stop here and return. 6967 if ( rnumnonpx.test(val) ) { 6968 return val; 6969 } 6970 6971 // we need the check for style in case a browser which returns unreliable values 6972 // for getComputedStyle silently falls back to the reliable elem.style 6973 valueIsBorderBox = isBorderBox && ( jQuery.support.boxSizingReliable || val === elem.style[ name ] ); 6974 6975 // Normalize "", auto, and prepare for extra 6976 val = parseFloat( val ) || 0; 6977 } 6978 6979 // use the active box-sizing model to add/subtract irrelevant styles 6980 return ( val + 6981 augmentWidthOrHeight( 6982 elem, 6983 name, 6984 extra || ( isBorderBox ? "border" : "content" ), 6985 valueIsBorderBox 6986 ) 6987 ) + "px"; 6988 } 6989 6990 6991 // Try to determine the default display value of an element 6992 function css_defaultDisplay( nodeName ) { 6993 if ( elemdisplay[ nodeName ] ) { 6994 return elemdisplay[ nodeName ]; 6995 } 6996 6997 var elem = jQuery( "<" + nodeName + ">" ).appendTo( document.body ), 6998 display = elem.css("display"); 6999 elem.remove(); 7000 7001 // If the simple way fails, 7002 // get element's real default display by attaching it to a temp iframe 7003 if ( display === "none" || display === "" ) { 7004 // Use the already-created iframe if possible 7005 iframe = document.body.appendChild( 7006 iframe || jQuery.extend( document.createElement("iframe"), { 7007 frameBorder: 0, 7008 width: 0, 7009 height: 0 7010 }) 7011 ); 7012 7013 // Create a cacheable copy of the iframe document on first call. 7014 // IE and Opera will allow us to reuse the iframeDoc without re-writing the fake HTML 7015 // document to it; WebKit & Firefox won't allow reusing the iframe document. 7016 if ( !iframeDoc || !iframe.createElement ) { 7017 iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document; 7018 iframeDoc.write("<!doctype html><html><body>"); 7019 iframeDoc.close(); 7020 } 7021 7022 elem = iframeDoc.body.appendChild( iframeDoc.createElement(nodeName) ); 7023 7024 display = curCSS( elem, "display" ); 7025 document.body.removeChild( iframe ); 7026 } 7027 7028 // Store the correct default display 7029 elemdisplay[ nodeName ] = display; 7030 7031 return display; 7032 } 7033 7034 jQuery.each([ "height", "width" ], function( i, name ) { 7035 jQuery.cssHooks[ name ] = { 7036 get: function( elem, computed, extra ) { 7037 if ( computed ) { 7038 // certain elements can have dimension info if we invisibly show them 7039 // however, it must have a current display style that would benefit from this 7040 if ( elem.offsetWidth === 0 && rdisplayswap.test( curCSS( elem, "display" ) ) ) { 7041 return jQuery.swap( elem, cssShow, function() { 7042 return getWidthOrHeight( elem, name, extra ); 7043 }); 7044 } else { 7045 return getWidthOrHeight( elem, name, extra ); 7046 } 7047 } 7048 }, 7049 7050 set: function( elem, value, extra ) { 7051 return setPositiveNumber( elem, value, extra ? 7052 augmentWidthOrHeight( 7053 elem, 7054 name, 7055 extra, 7056 jQuery.support.boxSizing && jQuery.css( elem, "boxSizing" ) === "border-box" 7057 ) : 0 7058 ); 7059 } 7060 }; 7061 }); 7062 7063 if ( !jQuery.support.opacity ) { 7064 jQuery.cssHooks.opacity = { 7065 get: function( elem, computed ) { 7066 // IE uses filters for opacity 7067 return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ? 7068 ( 0.01 * parseFloat( RegExp.$1 ) ) + "" : 7069 computed ? "1" : ""; 7070 }, 7071 7072 set: function( elem, value ) { 7073 var style = elem.style, 7074 currentStyle = elem.currentStyle, 7075 opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "", 7076 filter = currentStyle && currentStyle.filter || style.filter || ""; 7077 7078 // IE has trouble with opacity if it does not have layout 7079 // Force it by setting the zoom level 7080 style.zoom = 1; 7081 7082 // if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652 7083 if ( value >= 1 && jQuery.trim( filter.replace( ralpha, "" ) ) === "" && 7084 style.removeAttribute ) { 7085 7086 // Setting style.filter to null, "" & " " still leave "filter:" in the cssText 7087 // if "filter:" is present at all, clearType is disabled, we want to avoid this 7088 // style.removeAttribute is IE Only, but so apparently is this code path... 7089 style.removeAttribute( "filter" ); 7090 7091 // if there there is no filter style applied in a css rule, we are done 7092 if ( currentStyle && !currentStyle.filter ) { 7093 return; 7094 } 7095 } 7096 7097 // otherwise, set new filter values 7098 style.filter = ralpha.test( filter ) ? 7099 filter.replace( ralpha, opacity ) : 7100 filter + " " + opacity; 7101 } 7102 }; 7103 } 7104 7105 // These hooks cannot be added until DOM ready because the support test 7106 // for it is not run until after DOM ready 7107 jQuery(function() { 7108 if ( !jQuery.support.reliableMarginRight ) { 7109 jQuery.cssHooks.marginRight = { 7110 get: function( elem, computed ) { 7111 // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right 7112 // Work around by temporarily setting element display to inline-block 7113 return jQuery.swap( elem, { "display": "inline-block" }, function() { 7114 if ( computed ) { 7115 return curCSS( elem, "marginRight" ); 7116 } 7117 }); 7118 } 7119 }; 7120 } 7121 7122 // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084 7123 // getComputedStyle returns percent when specified for top/left/bottom/right 7124 // rather than make the css module depend on the offset module, we just check for it here 7125 if ( !jQuery.support.pixelPosition && jQuery.fn.position ) { 7126 jQuery.each( [ "top", "left" ], function( i, prop ) { 7127 jQuery.cssHooks[ prop ] = { 7128 get: function( elem, computed ) { 7129 if ( computed ) { 7130 var ret = curCSS( elem, prop ); 7131 // if curCSS returns percentage, fallback to offset 7132 return rnumnonpx.test( ret ) ? jQuery( elem ).position()[ prop ] + "px" : ret; 7133 } 7134 } 7135 }; 7136 }); 7137 } 7138 7139 }); 7140 7141 if ( jQuery.expr && jQuery.expr.filters ) { 7142 jQuery.expr.filters.hidden = function( elem ) { 7143 return ( elem.offsetWidth === 0 && elem.offsetHeight === 0 ) || (!jQuery.support.reliableHiddenOffsets && ((elem.style && elem.style.display) || curCSS( elem, "display" )) === "none"); 7144 }; 7145 7146 jQuery.expr.filters.visible = function( elem ) { 7147 return !jQuery.expr.filters.hidden( elem ); 7148 }; 7149 } 7150 7151 // These hooks are used by animate to expand properties 7152 jQuery.each({ 7153 margin: "", 7154 padding: "", 7155 border: "Width" 7156 }, function( prefix, suffix ) { 7157 jQuery.cssHooks[ prefix + suffix ] = { 7158 expand: function( value ) { 7159 var i, 7160 7161 // assumes a single number if not a string 7162 parts = typeof value === "string" ? value.split(" ") : [ value ], 7163 expanded = {}; 7164 7165 for ( i = 0; i < 4; i++ ) { 7166 expanded[ prefix + cssExpand[ i ] + suffix ] = 7167 parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; 7168 } 7169 7170 return expanded; 7171 } 7172 }; 7173 7174 if ( !rmargin.test( prefix ) ) { 7175 jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; 7176 } 7177 }); 7178 var r20 = /%20/g, 7179 rbracket = /\[\]$/, 7180 rCRLF = /\r?\n/g, 7181 rinput = /^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i, 7182 rselectTextarea = /^(?:select|textarea)/i; 7183 7184 jQuery.fn.extend({ 7185 serialize: function() { 7186 return jQuery.param( this.serializeArray() ); 7187 }, 7188 serializeArray: function() { 7189 return this.map(function(){ 7190 return this.elements ? jQuery.makeArray( this.elements ) : this; 7191 }) 7192 .filter(function(){ 7193 return this.name && !this.disabled && 7194 ( this.checked || rselectTextarea.test( this.nodeName ) || 7195 rinput.test( this.type ) ); 7196 }) 7197 .map(function( i, elem ){ 7198 var val = jQuery( this ).val(); 7199 7200 return val == null ? 7201 null : 7202 jQuery.isArray( val ) ? 7203 jQuery.map( val, function( val, i ){ 7204 return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; 7205 }) : 7206 { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; 7207 }).get(); 7208 } 7209 }); 7210 7211 //Serialize an array of form elements or a set of 7212 //key/values into a query string 7213 jQuery.param = function( a, traditional ) { 7214 var prefix, 7215 s = [], 7216 add = function( key, value ) { 7217 // If value is a function, invoke it and return its value 7218 value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value ); 7219 s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value ); 7220 }; 7221 7222 // Set traditional to true for jQuery <= 1.3.2 behavior. 7223 if ( traditional === undefined ) { 7224 traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional; 7225 } 7226 7227 // If an array was passed in, assume that it is an array of form elements. 7228 if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { 7229 // Serialize the form elements 7230 jQuery.each( a, function() { 7231 add( this.name, this.value ); 7232 }); 7233 7234 } else { 7235 // If traditional, encode the "old" way (the way 1.3.2 or older 7236 // did it), otherwise encode params recursively. 7237 for ( prefix in a ) { 7238 buildParams( prefix, a[ prefix ], traditional, add ); 7239 } 7240 } 7241 7242 // Return the resulting serialization 7243 return s.join( "&" ).replace( r20, "+" ); 7244 }; 7245 7246 function buildParams( prefix, obj, traditional, add ) { 7247 var name; 7248 7249 if ( jQuery.isArray( obj ) ) { 7250 // Serialize array item. 7251 jQuery.each( obj, function( i, v ) { 7252 if ( traditional || rbracket.test( prefix ) ) { 7253 // Treat each array item as a scalar. 7254 add( prefix, v ); 7255 7256 } else { 7257 // If array item is non-scalar (array or object), encode its 7258 // numeric index to resolve deserialization ambiguity issues. 7259 // Note that rack (as of 1.0.0) can't currently deserialize 7260 // nested arrays properly, and attempting to do so may cause 7261 // a server error. Possible fixes are to modify rack's 7262 // deserialization algorithm or to provide an option or flag 7263 // to force array serialization to be shallow. 7264 buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add ); 7265 } 7266 }); 7267 7268 } else if ( !traditional && jQuery.type( obj ) === "object" ) { 7269 // Serialize object item. 7270 for ( name in obj ) { 7271 buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); 7272 } 7273 7274 } else { 7275 // Serialize scalar item. 7276 add( prefix, obj ); 7277 } 7278 } 7279 var 7280 // Document location 7281 ajaxLocParts, 7282 ajaxLocation, 7283 7284 rhash = /#.*$/, 7285 rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL 7286 // #7653, #8125, #8152: local protocol detection 7287 rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/, 7288 rnoContent = /^(?:GET|HEAD)$/, 7289 rprotocol = /^\/\//, 7290 rquery = /\?/, 7291 rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, 7292 rts = /([?&])_=[^&]*/, 7293 rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/, 7294 7295 // Keep a copy of the old load method 7296 _load = jQuery.fn.load, 7297 7298 /* Prefilters 7299 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) 7300 * 2) These are called: 7301 * - BEFORE asking for a transport 7302 * - AFTER param serialization (s.data is a string if s.processData is true) 7303 * 3) key is the dataType 7304 * 4) the catchall symbol "*" can be used 7305 * 5) execution will start with transport dataType and THEN continue down to "*" if needed 7306 */ 7307 prefilters = {}, 7308 7309 /* Transports bindings 7310 * 1) key is the dataType 7311 * 2) the catchall symbol "*" can be used 7312 * 3) selection will start with transport dataType and THEN go to "*" if needed 7313 */ 7314 transports = {}, 7315 7316 // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression 7317 allTypes = ["*/"] + ["*"]; 7318 7319 // #8138, IE may throw an exception when accessing 7320 // a field from window.location if document.domain has been set 7321 try { 7322 ajaxLocation = location.href; 7323 } catch( e ) { 7324 // Use the href attribute of an A element 7325 // since IE will modify it given document.location 7326 ajaxLocation = document.createElement( "a" ); 7327 ajaxLocation.href = ""; 7328 ajaxLocation = ajaxLocation.href; 7329 } 7330 7331 // Segment location into parts 7332 ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || []; 7333 7334 // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport 7335 function addToPrefiltersOrTransports( structure ) { 7336 7337 // dataTypeExpression is optional and defaults to "*" 7338 return function( dataTypeExpression, func ) { 7339 7340 if ( typeof dataTypeExpression !== "string" ) { 7341 func = dataTypeExpression; 7342 dataTypeExpression = "*"; 7343 } 7344 7345 var dataType, list, placeBefore, 7346 dataTypes = dataTypeExpression.toLowerCase().split( core_rspace ), 7347 i = 0, 7348 length = dataTypes.length; 7349 7350 if ( jQuery.isFunction( func ) ) { 7351 // For each dataType in the dataTypeExpression 7352 for ( ; i < length; i++ ) { 7353 dataType = dataTypes[ i ]; 7354 // We control if we're asked to add before 7355 // any existing element 7356 placeBefore = /^\+/.test( dataType ); 7357 if ( placeBefore ) { 7358 dataType = dataType.substr( 1 ) || "*"; 7359 } 7360 list = structure[ dataType ] = structure[ dataType ] || []; 7361 // then we add to the structure accordingly 7362 list[ placeBefore ? "unshift" : "push" ]( func ); 7363 } 7364 } 7365 }; 7366 } 7367 7368 // Base inspection function for prefilters and transports 7369 function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR, 7370 dataType /* internal */, inspected /* internal */ ) { 7371 7372 dataType = dataType || options.dataTypes[ 0 ]; 7373 inspected = inspected || {}; 7374 7375 inspected[ dataType ] = true; 7376 7377 var selection, 7378 list = structure[ dataType ], 7379 i = 0, 7380 length = list ? list.length : 0, 7381 executeOnly = ( structure === prefilters ); 7382 7383 for ( ; i < length && ( executeOnly || !selection ); i++ ) { 7384 selection = list[ i ]( options, originalOptions, jqXHR ); 7385 // If we got redirected to another dataType 7386 // we try there if executing only and not done already 7387 if ( typeof selection === "string" ) { 7388 if ( !executeOnly || inspected[ selection ] ) { 7389 selection = undefined; 7390 } else { 7391 options.dataTypes.unshift( selection ); 7392 selection = inspectPrefiltersOrTransports( 7393 structure, options, originalOptions, jqXHR, selection, inspected ); 7394 } 7395 } 7396 } 7397 // If we're only executing or nothing was selected 7398 // we try the catchall dataType if not done already 7399 if ( ( executeOnly || !selection ) && !inspected[ "*" ] ) { 7400 selection = inspectPrefiltersOrTransports( 7401 structure, options, originalOptions, jqXHR, "*", inspected ); 7402 } 7403 // unnecessary when only executing (prefilters) 7404 // but it'll be ignored by the caller in that case 7405 return selection; 7406 } 7407 7408 // A special extend for ajax options 7409 // that takes "flat" options (not to be deep extended) 7410 // Fixes #9887 7411 function ajaxExtend( target, src ) { 7412 var key, deep, 7413 flatOptions = jQuery.ajaxSettings.flatOptions || {}; 7414 for ( key in src ) { 7415 if ( src[ key ] !== undefined ) { 7416 ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; 7417 } 7418 } 7419 if ( deep ) { 7420 jQuery.extend( true, target, deep ); 7421 } 7422 } 7423 7424 jQuery.fn.load = function( url, params, callback ) { 7425 if ( typeof url !== "string" && _load ) { 7426 return _load.apply( this, arguments ); 7427 } 7428 7429 // Don't do a request if no elements are being requested 7430 if ( !this.length ) { 7431 return this; 7432 } 7433 7434 var selector, type, response, 7435 self = this, 7436 off = url.indexOf(" "); 7437 7438 if ( off >= 0 ) { 7439 selector = url.slice( off, url.length ); 7440 url = url.slice( 0, off ); 7441 } 7442 7443 // If it's a function 7444 if ( jQuery.isFunction( params ) ) { 7445 7446 // We assume that it's the callback 7447 callback = params; 7448 params = undefined; 7449 7450 // Otherwise, build a param string 7451 } else if ( params && typeof params === "object" ) { 7452 type = "POST"; 7453 } 7454 7455 // Request the remote document 7456 jQuery.ajax({ 7457 url: url, 7458 7459 // if "type" variable is undefined, then "GET" method will be used 7460 type: type, 7461 dataType: "html", 7462 data: params, 7463 complete: function( jqXHR, status ) { 7464 if ( callback ) { 7465 self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] ); 7466 } 7467 } 7468 }).done(function( responseText ) { 7469 7470 // Save response for use in complete callback 7471 response = arguments; 7472 7473 // See if a selector was specified 7474 self.html( selector ? 7475 7476 // Create a dummy div to hold the results 7477 jQuery("<div>") 7478 7479 // inject the contents of the document in, removing the scripts 7480 // to avoid any 'Permission Denied' errors in IE 7481 .append( responseText.replace( rscript, "" ) ) 7482 7483 // Locate the specified elements 7484 .find( selector ) : 7485 7486 // If not, just inject the full result 7487 responseText ); 7488 7489 }); 7490 7491 return this; 7492 }; 7493 7494 // Attach a bunch of functions for handling common AJAX events 7495 jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split( " " ), function( i, o ){ 7496 jQuery.fn[ o ] = function( f ){ 7497 return this.on( o, f ); 7498 }; 7499 }); 7500 7501 jQuery.each( [ "get", "post" ], function( i, method ) { 7502 jQuery[ method ] = function( url, data, callback, type ) { 7503 // shift arguments if data argument was omitted 7504 if ( jQuery.isFunction( data ) ) { 7505 type = type || callback; 7506 callback = data; 7507 data = undefined; 7508 } 7509 7510 return jQuery.ajax({ 7511 type: method, 7512 url: url, 7513 data: data, 7514 success: callback, 7515 dataType: type 7516 }); 7517 }; 7518 }); 7519 7520 jQuery.extend({ 7521 7522 getScript: function( url, callback ) { 7523 return jQuery.get( url, undefined, callback, "script" ); 7524 }, 7525 7526 getJSON: function( url, data, callback ) { 7527 return jQuery.get( url, data, callback, "json" ); 7528 }, 7529 7530 // Creates a full fledged settings object into target 7531 // with both ajaxSettings and settings fields. 7532 // If target is omitted, writes into ajaxSettings. 7533 ajaxSetup: function( target, settings ) { 7534 if ( settings ) { 7535 // Building a settings object 7536 ajaxExtend( target, jQuery.ajaxSettings ); 7537 } else { 7538 // Extending ajaxSettings 7539 settings = target; 7540 target = jQuery.ajaxSettings; 7541 } 7542 ajaxExtend( target, settings ); 7543 return target; 7544 }, 7545 7546 ajaxSettings: { 7547 url: ajaxLocation, 7548 isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ), 7549 global: true, 7550 type: "GET", 7551 contentType: "application/x-www-form-urlencoded; charset=UTF-8", 7552 processData: true, 7553 async: true, 7554 /* 7555 timeout: 0, 7556 data: null, 7557 dataType: null, 7558 username: null, 7559 password: null, 7560 cache: null, 7561 throws: false, 7562 traditional: false, 7563 headers: {}, 7564 */ 7565 7566 accepts: { 7567 xml: "application/xml, text/xml", 7568 html: "text/html", 7569 text: "text/plain", 7570 json: "application/json, text/javascript", 7571 "*": allTypes 7572 }, 7573 7574 contents: { 7575 xml: /xml/, 7576 html: /html/, 7577 json: /json/ 7578 }, 7579 7580 responseFields: { 7581 xml: "responseXML", 7582 text: "responseText" 7583 }, 7584 7585 // List of data converters 7586 // 1) key format is "source_type destination_type" (a single space in-between) 7587 // 2) the catchall symbol "*" can be used for source_type 7588 converters: { 7589 7590 // Convert anything to text 7591 "* text": window.String, 7592 7593 // Text to html (true = no transformation) 7594 "text html": true, 7595 7596 // Evaluate text as a json expression 7597 "text json": jQuery.parseJSON, 7598 7599 // Parse text as xml 7600 "text xml": jQuery.parseXML 7601 }, 7602 7603 // For options that shouldn't be deep extended: 7604 // you can add your own custom options here if 7605 // and when you create one that shouldn't be 7606 // deep extended (see ajaxExtend) 7607 flatOptions: { 7608 context: true, 7609 url: true 7610 } 7611 }, 7612 7613 ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), 7614 ajaxTransport: addToPrefiltersOrTransports( transports ), 7615 7616 // Main method 7617 ajax: function( url, options ) { 7618 7619 // If url is an object, simulate pre-1.5 signature 7620 if ( typeof url === "object" ) { 7621 options = url; 7622 url = undefined; 7623 } 7624 7625 // Force options to be an object 7626 options = options || {}; 7627 7628 var // ifModified key 7629 ifModifiedKey, 7630 // Response headers 7631 responseHeadersString, 7632 responseHeaders, 7633 // transport 7634 transport, 7635 // timeout handle 7636 timeoutTimer, 7637 // Cross-domain detection vars 7638 parts, 7639 // To know if global events are to be dispatched 7640 fireGlobals, 7641 // Loop variable 7642 i, 7643 // Create the final options object 7644 s = jQuery.ajaxSetup( {}, options ), 7645 // Callbacks context 7646 callbackContext = s.context || s, 7647 // Context for global events 7648 // It's the callbackContext if one was provided in the options 7649 // and if it's a DOM node or a jQuery collection 7650 globalEventContext = callbackContext !== s && 7651 ( callbackContext.nodeType || callbackContext instanceof jQuery ) ? 7652 jQuery( callbackContext ) : jQuery.event, 7653 // Deferreds 7654 deferred = jQuery.Deferred(), 7655 completeDeferred = jQuery.Callbacks( "once memory" ), 7656 // Status-dependent callbacks 7657 statusCode = s.statusCode || {}, 7658 // Headers (they are sent all at once) 7659 requestHeaders = {}, 7660 requestHeadersNames = {}, 7661 // The jqXHR state 7662 state = 0, 7663 // Default abort message 7664 strAbort = "canceled", 7665 // Fake xhr 7666 jqXHR = { 7667 7668 readyState: 0, 7669 7670 // Caches the header 7671 setRequestHeader: function( name, value ) { 7672 if ( !state ) { 7673 var lname = name.toLowerCase(); 7674 name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name; 7675 requestHeaders[ name ] = value; 7676 } 7677 return this; 7678 }, 7679 7680 // Raw string 7681 getAllResponseHeaders: function() { 7682 return state === 2 ? responseHeadersString : null; 7683 }, 7684 7685 // Builds headers hashtable if needed 7686 getResponseHeader: function( key ) { 7687 var match; 7688 if ( state === 2 ) { 7689 if ( !responseHeaders ) { 7690 responseHeaders = {}; 7691 while( ( match = rheaders.exec( responseHeadersString ) ) ) { 7692 responseHeaders[ match[1].toLowerCase() ] = match[ 2 ]; 7693 } 7694 } 7695 match = responseHeaders[ key.toLowerCase() ]; 7696 } 7697 return match === undefined ? null : match; 7698 }, 7699 7700 // Overrides response content-type header 7701 overrideMimeType: function( type ) { 7702 if ( !state ) { 7703 s.mimeType = type; 7704 } 7705 return this; 7706 }, 7707 7708 // Cancel the request 7709 abort: function( statusText ) { 7710 statusText = statusText || strAbort; 7711 if ( transport ) { 7712 transport.abort( statusText ); 7713 } 7714 done( 0, statusText ); 7715 return this; 7716 } 7717 }; 7718 7719 // Callback for when everything is done 7720 // It is defined here because jslint complains if it is declared 7721 // at the end of the function (which would be more logical and readable) 7722 function done( status, nativeStatusText, responses, headers ) { 7723 var isSuccess, success, error, response, modified, 7724 statusText = nativeStatusText; 7725 7726 // Called once 7727 if ( state === 2 ) { 7728 return; 7729 } 7730 7731 // State is "done" now 7732 state = 2; 7733 7734 // Clear timeout if it exists 7735 if ( timeoutTimer ) { 7736 clearTimeout( timeoutTimer ); 7737 } 7738 7739 // Dereference transport for early garbage collection 7740 // (no matter how long the jqXHR object will be used) 7741 transport = undefined; 7742 7743 // Cache response headers 7744 responseHeadersString = headers || ""; 7745 7746 // Set readyState 7747 jqXHR.readyState = status > 0 ? 4 : 0; 7748 7749 // Get response data 7750 if ( responses ) { 7751 response = ajaxHandleResponses( s, jqXHR, responses ); 7752 } 7753 7754 // If successful, handle type chaining 7755 if ( status >= 200 && status < 300 || status === 304 ) { 7756 7757 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. 7758 if ( s.ifModified ) { 7759 7760 modified = jqXHR.getResponseHeader("Last-Modified"); 7761 if ( modified ) { 7762 jQuery.lastModified[ ifModifiedKey ] = modified; 7763 } 7764 modified = jqXHR.getResponseHeader("Etag"); 7765 if ( modified ) { 7766 jQuery.etag[ ifModifiedKey ] = modified; 7767 } 7768 } 7769 7770 // If not modified 7771 if ( status === 304 ) { 7772 7773 statusText = "notmodified"; 7774 isSuccess = true; 7775 7776 // If we have data 7777 } else { 7778 7779 isSuccess = ajaxConvert( s, response ); 7780 statusText = isSuccess.state; 7781 success = isSuccess.data; 7782 error = isSuccess.error; 7783 isSuccess = !error; 7784 } 7785 } else { 7786 // We extract error from statusText 7787 // then normalize statusText and status for non-aborts 7788 error = statusText; 7789 if ( !statusText || status ) { 7790 statusText = "error"; 7791 if ( status < 0 ) { 7792 status = 0; 7793 } 7794 } 7795 } 7796 7797 // Set data for the fake xhr object 7798 jqXHR.status = status; 7799 jqXHR.statusText = ( nativeStatusText || statusText ) + ""; 7800 7801 // Success/Error 7802 if ( isSuccess ) { 7803 deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); 7804 } else { 7805 deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); 7806 } 7807 7808 // Status-dependent callbacks 7809 jqXHR.statusCode( statusCode ); 7810 statusCode = undefined; 7811 7812 if ( fireGlobals ) { 7813 globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ), 7814 [ jqXHR, s, isSuccess ? success : error ] ); 7815 } 7816 7817 // Complete 7818 completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); 7819 7820 if ( fireGlobals ) { 7821 globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); 7822 // Handle the global AJAX counter 7823 if ( !( --jQuery.active ) ) { 7824 jQuery.event.trigger( "ajaxStop" ); 7825 } 7826 } 7827 } 7828 7829 // Attach deferreds 7830 deferred.promise( jqXHR ); 7831 jqXHR.success = jqXHR.done; 7832 jqXHR.error = jqXHR.fail; 7833 jqXHR.complete = completeDeferred.add; 7834 7835 // Status-dependent callbacks 7836 jqXHR.statusCode = function( map ) { 7837 if ( map ) { 7838 var tmp; 7839 if ( state < 2 ) { 7840 for ( tmp in map ) { 7841 statusCode[ tmp ] = [ statusCode[tmp], map[tmp] ]; 7842 } 7843 } else { 7844 tmp = map[ jqXHR.status ]; 7845 jqXHR.always( tmp ); 7846 } 7847 } 7848 return this; 7849 }; 7850 7851 // Remove hash character (#7531: and string promotion) 7852 // Add protocol if not provided (#5866: IE7 issue with protocol-less urls) 7853 // We also use the url parameter if available 7854 s.url = ( ( url || s.url ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" ); 7855 7856 // Extract dataTypes list 7857 s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( core_rspace ); 7858 7859 // A cross-domain request is in order when we have a protocol:host:port mismatch 7860 if ( s.crossDomain == null ) { 7861 parts = rurl.exec( s.url.toLowerCase() ); 7862 s.crossDomain = !!( parts && 7863 ( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] || 7864 ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? 80 : 443 ) ) != 7865 ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? 80 : 443 ) ) ) 7866 ); 7867 } 7868 7869 // Convert data if not already a string 7870 if ( s.data && s.processData && typeof s.data !== "string" ) { 7871 s.data = jQuery.param( s.data, s.traditional ); 7872 } 7873 7874 // Apply prefilters 7875 inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); 7876 7877 // If request was aborted inside a prefilter, stop there 7878 if ( state === 2 ) { 7879 return jqXHR; 7880 } 7881 7882 // We can fire global events as of now if asked to 7883 fireGlobals = s.global; 7884 7885 // Uppercase the type 7886 s.type = s.type.toUpperCase(); 7887 7888 // Determine if request has content 7889 s.hasContent = !rnoContent.test( s.type ); 7890 7891 // Watch for a new set of requests 7892 if ( fireGlobals && jQuery.active++ === 0 ) { 7893 jQuery.event.trigger( "ajaxStart" ); 7894 } 7895 7896 // More options handling for requests with no content 7897 if ( !s.hasContent ) { 7898 7899 // If data is available, append data to url 7900 if ( s.data ) { 7901 s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data; 7902 // #9682: remove data so that it's not used in an eventual retry 7903 delete s.data; 7904 } 7905 7906 // Get ifModifiedKey before adding the anti-cache parameter 7907 ifModifiedKey = s.url; 7908 7909 // Add anti-cache in url if needed 7910 if ( s.cache === false ) { 7911 7912 var ts = jQuery.now(), 7913 // try replacing _= if it is there 7914 ret = s.url.replace( rts, "$1_=" + ts ); 7915 7916 // if nothing was replaced, add timestamp to the end 7917 s.url = ret + ( ( ret === s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : "" ); 7918 } 7919 } 7920 7921 // Set the correct header, if data is being sent 7922 if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { 7923 jqXHR.setRequestHeader( "Content-Type", s.contentType ); 7924 } 7925 7926 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. 7927 if ( s.ifModified ) { 7928 ifModifiedKey = ifModifiedKey || s.url; 7929 if ( jQuery.lastModified[ ifModifiedKey ] ) { 7930 jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ ifModifiedKey ] ); 7931 } 7932 if ( jQuery.etag[ ifModifiedKey ] ) { 7933 jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ ifModifiedKey ] ); 7934 } 7935 } 7936 7937 // Set the Accepts header for the server, depending on the dataType 7938 jqXHR.setRequestHeader( 7939 "Accept", 7940 s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ? 7941 s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : 7942 s.accepts[ "*" ] 7943 ); 7944 7945 // Check for headers option 7946 for ( i in s.headers ) { 7947 jqXHR.setRequestHeader( i, s.headers[ i ] ); 7948 } 7949 7950 // Allow custom headers/mimetypes and early abort 7951 if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) { 7952 // Abort if not done already and return 7953 return jqXHR.abort(); 7954 7955 } 7956 7957 // aborting is no longer a cancellation 7958 strAbort = "abort"; 7959 7960 // Install callbacks on deferreds 7961 for ( i in { success: 1, error: 1, complete: 1 } ) { 7962 jqXHR[ i ]( s[ i ] ); 7963 } 7964 7965 // Get transport 7966 transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); 7967 7968 // If no transport, we auto-abort 7969 if ( !transport ) { 7970 done( -1, "No Transport" ); 7971 } else { 7972 jqXHR.readyState = 1; 7973 // Send global event 7974 if ( fireGlobals ) { 7975 globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); 7976 } 7977 // Timeout 7978 if ( s.async && s.timeout > 0 ) { 7979 timeoutTimer = setTimeout( function(){ 7980 jqXHR.abort( "timeout" ); 7981 }, s.timeout ); 7982 } 7983 7984 try { 7985 state = 1; 7986 transport.send( requestHeaders, done ); 7987 } catch (e) { 7988 // Propagate exception as error if not done 7989 if ( state < 2 ) { 7990 done( -1, e ); 7991 // Simply rethrow otherwise 7992 } else { 7993 throw e; 7994 } 7995 } 7996 } 7997 7998 return jqXHR; 7999 }, 8000 8001 // Counter for holding the number of active queries 8002 active: 0, 8003 8004 // Last-Modified header cache for next request 8005 lastModified: {}, 8006 etag: {} 8007 8008 }); 8009 8010 /* Handles responses to an ajax request: 8011 * - sets all responseXXX fields accordingly 8012 * - finds the right dataType (mediates between content-type and expected dataType) 8013 * - returns the corresponding response 8014 */ 8015 function ajaxHandleResponses( s, jqXHR, responses ) { 8016 8017 var ct, type, finalDataType, firstDataType, 8018 contents = s.contents, 8019 dataTypes = s.dataTypes, 8020 responseFields = s.responseFields; 8021 8022 // Fill responseXXX fields 8023 for ( type in responseFields ) { 8024 if ( type in responses ) { 8025 jqXHR[ responseFields[type] ] = responses[ type ]; 8026 } 8027 } 8028 8029 // Remove auto dataType and get content-type in the process 8030 while( dataTypes[ 0 ] === "*" ) { 8031 dataTypes.shift(); 8032 if ( ct === undefined ) { 8033 ct = s.mimeType || jqXHR.getResponseHeader( "content-type" ); 8034 } 8035 } 8036 8037 // Check if we're dealing with a known content-type 8038 if ( ct ) { 8039 for ( type in contents ) { 8040 if ( contents[ type ] && contents[ type ].test( ct ) ) { 8041 dataTypes.unshift( type ); 8042 break; 8043 } 8044 } 8045 } 8046 8047 // Check to see if we have a response for the expected dataType 8048 if ( dataTypes[ 0 ] in responses ) { 8049 finalDataType = dataTypes[ 0 ]; 8050 } else { 8051 // Try convertible dataTypes 8052 for ( type in responses ) { 8053 if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) { 8054 finalDataType = type; 8055 break; 8056 } 8057 if ( !firstDataType ) { 8058 firstDataType = type; 8059 } 8060 } 8061 // Or just use first one 8062 finalDataType = finalDataType || firstDataType; 8063 } 8064 8065 // If we found a dataType 8066 // We add the dataType to the list if needed 8067 // and return the corresponding response 8068 if ( finalDataType ) { 8069 if ( finalDataType !== dataTypes[ 0 ] ) { 8070 dataTypes.unshift( finalDataType ); 8071 } 8072 return responses[ finalDataType ]; 8073 } 8074 } 8075 8076 // Chain conversions given the request and the original response 8077 function ajaxConvert( s, response ) { 8078 8079 var conv, conv2, current, tmp, 8080 // Work with a copy of dataTypes in case we need to modify it for conversion 8081 dataTypes = s.dataTypes.slice(), 8082 prev = dataTypes[ 0 ], 8083 converters = {}, 8084 i = 0; 8085 8086 // Apply the dataFilter if provided 8087 if ( s.dataFilter ) { 8088 response = s.dataFilter( response, s.dataType ); 8089 } 8090 8091 // Create converters map with lowercased keys 8092 if ( dataTypes[ 1 ] ) { 8093 for ( conv in s.converters ) { 8094 converters[ conv.toLowerCase() ] = s.converters[ conv ]; 8095 } 8096 } 8097 8098 // Convert to each sequential dataType, tolerating list modification 8099 for ( ; (current = dataTypes[++i]); ) { 8100 8101 // There's only work to do if current dataType is non-auto 8102 if ( current !== "*" ) { 8103 8104 // Convert response if prev dataType is non-auto and differs from current 8105 if ( prev !== "*" && prev !== current ) { 8106 8107 // Seek a direct converter 8108 conv = converters[ prev + " " + current ] || converters[ "* " + current ]; 8109 8110 // If none found, seek a pair 8111 if ( !conv ) { 8112 for ( conv2 in converters ) { 8113 8114 // If conv2 outputs current 8115 tmp = conv2.split(" "); 8116 if ( tmp[ 1 ] === current ) { 8117 8118 // If prev can be converted to accepted input 8119 conv = converters[ prev + " " + tmp[ 0 ] ] || 8120 converters[ "* " + tmp[ 0 ] ]; 8121 if ( conv ) { 8122 // Condense equivalence converters 8123 if ( conv === true ) { 8124 conv = converters[ conv2 ]; 8125 8126 // Otherwise, insert the intermediate dataType 8127 } else if ( converters[ conv2 ] !== true ) { 8128 current = tmp[ 0 ]; 8129 dataTypes.splice( i--, 0, current ); 8130 } 8131 8132 break; 8133 } 8134 } 8135 } 8136 } 8137 8138 // Apply converter (if not an equivalence) 8139 if ( conv !== true ) { 8140 8141 // Unless errors are allowed to bubble, catch and return them 8142 if ( conv && s["throws"] ) { 8143 response = conv( response ); 8144 } else { 8145 try { 8146 response = conv( response ); 8147 } catch ( e ) { 8148 return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current }; 8149 } 8150 } 8151 } 8152 } 8153 8154 // Update prev for next iteration 8155 prev = current; 8156 } 8157 } 8158 8159 return { state: "success", data: response }; 8160 } 8161 var oldCallbacks = [], 8162 rquestion = /\?/, 8163 rjsonp = /(=)\?(?=&|$)|\?\?/, 8164 nonce = jQuery.now(); 8165 8166 // Default jsonp settings 8167 jQuery.ajaxSetup({ 8168 jsonp: "callback", 8169 jsonpCallback: function() { 8170 var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) ); 8171 this[ callback ] = true; 8172 return callback; 8173 } 8174 }); 8175 8176 // Detect, normalize options and install callbacks for jsonp requests 8177 jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { 8178 8179 var callbackName, overwritten, responseContainer, 8180 data = s.data, 8181 url = s.url, 8182 hasCallback = s.jsonp !== false, 8183 replaceInUrl = hasCallback && rjsonp.test( url ), 8184 replaceInData = hasCallback && !replaceInUrl && typeof data === "string" && 8185 !( s.contentType || "" ).indexOf("application/x-www-form-urlencoded") && 8186 rjsonp.test( data ); 8187 8188 // Handle iff the expected data type is "jsonp" or we have a parameter to set 8189 if ( s.dataTypes[ 0 ] === "jsonp" || replaceInUrl || replaceInData ) { 8190 8191 // Get callback name, remembering preexisting value associated with it 8192 callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ? 8193 s.jsonpCallback() : 8194 s.jsonpCallback; 8195 overwritten = window[ callbackName ]; 8196 8197 // Insert callback into url or form data 8198 if ( replaceInUrl ) { 8199 s.url = url.replace( rjsonp, "$1" + callbackName ); 8200 } else if ( replaceInData ) { 8201 s.data = data.replace( rjsonp, "$1" + callbackName ); 8202 } else if ( hasCallback ) { 8203 s.url += ( rquestion.test( url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName; 8204 } 8205 8206 // Use data converter to retrieve json after script execution 8207 s.converters["script json"] = function() { 8208 if ( !responseContainer ) { 8209 jQuery.error( callbackName + " was not called" ); 8210 } 8211 return responseContainer[ 0 ]; 8212 }; 8213 8214 // force json dataType 8215 s.dataTypes[ 0 ] = "json"; 8216 8217 // Install callback 8218 window[ callbackName ] = function() { 8219 responseContainer = arguments; 8220 }; 8221 8222 // Clean-up function (fires after converters) 8223 jqXHR.always(function() { 8224 // Restore preexisting value 8225 window[ callbackName ] = overwritten; 8226 8227 // Save back as free 8228 if ( s[ callbackName ] ) { 8229 // make sure that re-using the options doesn't screw things around 8230 s.jsonpCallback = originalSettings.jsonpCallback; 8231 8232 // save the callback name for future use 8233 oldCallbacks.push( callbackName ); 8234 } 8235 8236 // Call if it was a function and we have a response 8237 if ( responseContainer && jQuery.isFunction( overwritten ) ) { 8238 overwritten( responseContainer[ 0 ] ); 8239 } 8240 8241 responseContainer = overwritten = undefined; 8242 }); 8243 8244 // Delegate to script 8245 return "script"; 8246 } 8247 }); 8248 // Install script dataType 8249 jQuery.ajaxSetup({ 8250 accepts: { 8251 script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript" 8252 }, 8253 contents: { 8254 script: /javascript|ecmascript/ 8255 }, 8256 converters: { 8257 "text script": function( text ) { 8258 jQuery.globalEval( text ); 8259 return text; 8260 } 8261 } 8262 }); 8263 8264 // Handle cache's special case and global 8265 jQuery.ajaxPrefilter( "script", function( s ) { 8266 if ( s.cache === undefined ) { 8267 s.cache = false; 8268 } 8269 if ( s.crossDomain ) { 8270 s.type = "GET"; 8271 s.global = false; 8272 } 8273 }); 8274 8275 // Bind script tag hack transport 8276 jQuery.ajaxTransport( "script", function(s) { 8277 8278 // This transport only deals with cross domain requests 8279 if ( s.crossDomain ) { 8280 8281 var script, 8282 head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement; 8283 8284 return { 8285 8286 send: function( _, callback ) { 8287 8288 script = document.createElement( "script" ); 8289 8290 script.async = "async"; 8291 8292 if ( s.scriptCharset ) { 8293 script.charset = s.scriptCharset; 8294 } 8295 8296 script.src = s.url; 8297 8298 // Attach handlers for all browsers 8299 script.onload = script.onreadystatechange = function( _, isAbort ) { 8300 8301 if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) { 8302 8303 // Handle memory leak in IE 8304 script.onload = script.onreadystatechange = null; 8305 8306 // Remove the script 8307 if ( head && script.parentNode ) { 8308 head.removeChild( script ); 8309 } 8310 8311 // Dereference the script 8312 script = undefined; 8313 8314 // Callback if not abort 8315 if ( !isAbort ) { 8316 callback( 200, "success" ); 8317 } 8318 } 8319 }; 8320 // Use insertBefore instead of appendChild to circumvent an IE6 bug. 8321 // This arises when a base node is used (#2709 and #4378). 8322 head.insertBefore( script, head.firstChild ); 8323 }, 8324 8325 abort: function() { 8326 if ( script ) { 8327 script.onload( 0, 1 ); 8328 } 8329 } 8330 }; 8331 } 8332 }); 8333 var xhrCallbacks, 8334 // #5280: Internet Explorer will keep connections alive if we don't abort on unload 8335 xhrOnUnloadAbort = window.ActiveXObject ? function() { 8336 // Abort all pending requests 8337 for ( var key in xhrCallbacks ) { 8338 xhrCallbacks[ key ]( 0, 1 ); 8339 } 8340 } : false, 8341 xhrId = 0; 8342 8343 // Functions to create xhrs 8344 function createStandardXHR() { 8345 try { 8346 return new window.XMLHttpRequest(); 8347 } catch( e ) {} 8348 } 8349 8350 function createActiveXHR() { 8351 try { 8352 return new window.ActiveXObject( "Microsoft.XMLHTTP" ); 8353 } catch( e ) {} 8354 } 8355 8356 // Create the request object 8357 // (This is still attached to ajaxSettings for backward compatibility) 8358 jQuery.ajaxSettings.xhr = window.ActiveXObject ? 8359 /* Microsoft failed to properly 8360 * implement the XMLHttpRequest in IE7 (can't request local files), 8361 * so we use the ActiveXObject when it is available 8362 * Additionally XMLHttpRequest can be disabled in IE7/IE8 so 8363 * we need a fallback. 8364 */ 8365 function() { 8366 return !this.isLocal && createStandardXHR() || createActiveXHR(); 8367 } : 8368 // For all other browsers, use the standard XMLHttpRequest object 8369 createStandardXHR; 8370 8371 // Determine support properties 8372 (function( xhr ) { 8373 jQuery.extend( jQuery.support, { 8374 ajax: !!xhr, 8375 cors: !!xhr && ( "withCredentials" in xhr ) 8376 }); 8377 })( jQuery.ajaxSettings.xhr() ); 8378 8379 // Create transport if the browser can provide an xhr 8380 if ( jQuery.support.ajax ) { 8381 8382 jQuery.ajaxTransport(function( s ) { 8383 // Cross domain only allowed if supported through XMLHttpRequest 8384 if ( !s.crossDomain || jQuery.support.cors ) { 8385 8386 var callback; 8387 8388 return { 8389 send: function( headers, complete ) { 8390 8391 // Get a new xhr 8392 var handle, i, 8393 xhr = s.xhr(); 8394 8395 // Open the socket 8396 // Passing null username, generates a login popup on Opera (#2865) 8397 if ( s.username ) { 8398 xhr.open( s.type, s.url, s.async, s.username, s.password ); 8399 } else { 8400 xhr.open( s.type, s.url, s.async ); 8401 } 8402 8403 // Apply custom fields if provided 8404 if ( s.xhrFields ) { 8405 for ( i in s.xhrFields ) { 8406 xhr[ i ] = s.xhrFields[ i ]; 8407 } 8408 } 8409 8410 // Override mime type if needed 8411 if ( s.mimeType && xhr.overrideMimeType ) { 8412 xhr.overrideMimeType( s.mimeType ); 8413 } 8414 8415 // X-Requested-With header 8416 // For cross-domain requests, seeing as conditions for a preflight are 8417 // akin to a jigsaw puzzle, we simply never set it to be sure. 8418 // (it can always be set on a per-request basis or even using ajaxSetup) 8419 // For same-domain requests, won't change header if already provided. 8420 if ( !s.crossDomain && !headers["X-Requested-With"] ) { 8421 headers[ "X-Requested-With" ] = "XMLHttpRequest"; 8422 } 8423 8424 // Need an extra try/catch for cross domain requests in Firefox 3 8425 try { 8426 for ( i in headers ) { 8427 xhr.setRequestHeader( i, headers[ i ] ); 8428 } 8429 } catch( _ ) {} 8430 8431 // Do send the request 8432 // This may raise an exception which is actually 8433 // handled in jQuery.ajax (so no try/catch here) 8434 xhr.send( ( s.hasContent && s.data ) || null ); 8435 8436 // Listener 8437 callback = function( _, isAbort ) { 8438 8439 var status, 8440 statusText, 8441 responseHeaders, 8442 responses, 8443 xml; 8444 8445 // Firefox throws exceptions when accessing properties 8446 // of an xhr when a network error occurred 8447 // http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE) 8448 try { 8449 8450 // Was never called and is aborted or complete 8451 if ( callback && ( isAbort || xhr.readyState === 4 ) ) { 8452 8453 // Only called once 8454 callback = undefined; 8455 8456 // Do not keep as active anymore 8457 if ( handle ) { 8458 xhr.onreadystatechange = jQuery.noop; 8459 if ( xhrOnUnloadAbort ) { 8460 delete xhrCallbacks[ handle ]; 8461 } 8462 } 8463 8464 // If it's an abort 8465 if ( isAbort ) { 8466 // Abort it manually if needed 8467 if ( xhr.readyState !== 4 ) { 8468 xhr.abort(); 8469 } 8470 } else { 8471 status = xhr.status; 8472 responseHeaders = xhr.getAllResponseHeaders(); 8473 responses = {}; 8474 xml = xhr.responseXML; 8475 8476 // Construct response list 8477 if ( xml && xml.documentElement /* #4958 */ ) { 8478 responses.xml = xml; 8479 } 8480 8481 // When requesting binary data, IE6-9 will throw an exception 8482 // on any attempt to access responseText (#11426) 8483 try { 8484 responses.text = xhr.responseText; 8485 } catch( e ) { 8486 } 8487 8488 // Firefox throws an exception when accessing 8489 // statusText for faulty cross-domain requests 8490 try { 8491 statusText = xhr.statusText; 8492 } catch( e ) { 8493 // We normalize with Webkit giving an empty statusText 8494 statusText = ""; 8495 } 8496 8497 // Filter status for non standard behaviors 8498 8499 // If the request is local and we have data: assume a success 8500 // (success with no data won't get notified, that's the best we 8501 // can do given current implementations) 8502 if ( !status && s.isLocal && !s.crossDomain ) { 8503 status = responses.text ? 200 : 404; 8504 // IE - #1450: sometimes returns 1223 when it should be 204 8505 } else if ( status === 1223 ) { 8506 status = 204; 8507 } 8508 } 8509 } 8510 } catch( firefoxAccessException ) { 8511 if ( !isAbort ) { 8512 complete( -1, firefoxAccessException ); 8513 } 8514 } 8515 8516 // Call complete if needed 8517 if ( responses ) { 8518 complete( status, statusText, responses, responseHeaders ); 8519 } 8520 }; 8521 8522 if ( !s.async ) { 8523 // if we're in sync mode we fire the callback 8524 callback(); 8525 } else if ( xhr.readyState === 4 ) { 8526 // (IE6 & IE7) if it's in cache and has been 8527 // retrieved directly we need to fire the callback 8528 setTimeout( callback, 0 ); 8529 } else { 8530 handle = ++xhrId; 8531 if ( xhrOnUnloadAbort ) { 8532 // Create the active xhrs callbacks list if needed 8533 // and attach the unload handler 8534 if ( !xhrCallbacks ) { 8535 xhrCallbacks = {}; 8536 jQuery( window ).unload( xhrOnUnloadAbort ); 8537 } 8538 // Add to list of active xhrs callbacks 8539 xhrCallbacks[ handle ] = callback; 8540 } 8541 xhr.onreadystatechange = callback; 8542 } 8543 }, 8544 8545 abort: function() { 8546 if ( callback ) { 8547 callback(0,1); 8548 } 8549 } 8550 }; 8551 } 8552 }); 8553 } 8554 var fxNow, timerId, 8555 rfxtypes = /^(?:toggle|show|hide)$/, 8556 rfxnum = new RegExp( "^(?:([-+])=|)(" + core_pnum + ")([a-z%]*)$", "i" ), 8557 rrun = /queueHooks$/, 8558 animationPrefilters = [ defaultPrefilter ], 8559 tweeners = { 8560 "*": [function( prop, value ) { 8561 var end, unit, 8562 tween = this.createTween( prop, value ), 8563 parts = rfxnum.exec( value ), 8564 target = tween.cur(), 8565 start = +target || 0, 8566 scale = 1, 8567 maxIterations = 20; 8568 8569 if ( parts ) { 8570 end = +parts[2]; 8571 unit = parts[3] || ( jQuery.cssNumber[ prop ] ? "" : "px" ); 8572 8573 // We need to compute starting value 8574 if ( unit !== "px" && start ) { 8575 // Iteratively approximate from a nonzero starting point 8576 // Prefer the current property, because this process will be trivial if it uses the same units 8577 // Fallback to end or a simple constant 8578 start = jQuery.css( tween.elem, prop, true ) || end || 1; 8579 8580 do { 8581 // If previous iteration zeroed out, double until we get *something* 8582 // Use a string for doubling factor so we don't accidentally see scale as unchanged below 8583 scale = scale || ".5"; 8584 8585 // Adjust and apply 8586 start = start / scale; 8587 jQuery.style( tween.elem, prop, start + unit ); 8588 8589 // Update scale, tolerating zero or NaN from tween.cur() 8590 // And breaking the loop if scale is unchanged or perfect, or if we've just had enough 8591 } while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations ); 8592 } 8593 8594 tween.unit = unit; 8595 tween.start = start; 8596 // If a +=/-= token was provided, we're doing a relative animation 8597 tween.end = parts[1] ? start + ( parts[1] + 1 ) * end : end; 8598 } 8599 return tween; 8600 }] 8601 }; 8602 8603 // Animations created synchronously will run synchronously 8604 function createFxNow() { 8605 setTimeout(function() { 8606 fxNow = undefined; 8607 }, 0 ); 8608 return ( fxNow = jQuery.now() ); 8609 } 8610 8611 function createTweens( animation, props ) { 8612 jQuery.each( props, function( prop, value ) { 8613 var collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ), 8614 index = 0, 8615 length = collection.length; 8616 for ( ; index < length; index++ ) { 8617 if ( collection[ index ].call( animation, prop, value ) ) { 8618 8619 // we're done with this property 8620 return; 8621 } 8622 } 8623 }); 8624 } 8625 8626 function Animation( elem, properties, options ) { 8627 var result, 8628 index = 0, 8629 tweenerIndex = 0, 8630 length = animationPrefilters.length, 8631 deferred = jQuery.Deferred().always( function() { 8632 // don't match elem in the :animated selector 8633 delete tick.elem; 8634 }), 8635 tick = function() { 8636 var currentTime = fxNow || createFxNow(), 8637 remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), 8638 // archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497) 8639 temp = remaining / animation.duration || 0, 8640 percent = 1 - temp, 8641 index = 0, 8642 length = animation.tweens.length; 8643 8644 for ( ; index < length ; index++ ) { 8645 animation.tweens[ index ].run( percent ); 8646 } 8647 8648 deferred.notifyWith( elem, [ animation, percent, remaining ]); 8649 8650 if ( percent < 1 && length ) { 8651 return remaining; 8652 } else { 8653 deferred.resolveWith( elem, [ animation ] ); 8654 return false; 8655 } 8656 }, 8657 animation = deferred.promise({ 8658 elem: elem, 8659 props: jQuery.extend( {}, properties ), 8660 opts: jQuery.extend( true, { specialEasing: {} }, options ), 8661 originalProperties: properties, 8662 originalOptions: options, 8663 startTime: fxNow || createFxNow(), 8664 duration: options.duration, 8665 tweens: [], 8666 createTween: function( prop, end, easing ) { 8667 var tween = jQuery.Tween( elem, animation.opts, prop, end, 8668 animation.opts.specialEasing[ prop ] || animation.opts.easing ); 8669 animation.tweens.push( tween ); 8670 return tween; 8671 }, 8672 stop: function( gotoEnd ) { 8673 var index = 0, 8674 // if we are going to the end, we want to run all the tweens 8675 // otherwise we skip this part 8676 length = gotoEnd ? animation.tweens.length : 0; 8677 8678 for ( ; index < length ; index++ ) { 8679 animation.tweens[ index ].run( 1 ); 8680 } 8681 8682 // resolve when we played the last frame 8683 // otherwise, reject 8684 if ( gotoEnd ) { 8685 deferred.resolveWith( elem, [ animation, gotoEnd ] ); 8686 } else { 8687 deferred.rejectWith( elem, [ animation, gotoEnd ] ); 8688 } 8689 return this; 8690 } 8691 }), 8692 props = animation.props; 8693 8694 propFilter( props, animation.opts.specialEasing ); 8695 8696 for ( ; index < length ; index++ ) { 8697 result = animationPrefilters[ index ].call( animation, elem, props, animation.opts ); 8698 if ( result ) { 8699 return result; 8700 } 8701 } 8702 8703 createTweens( animation, props ); 8704 8705 if ( jQuery.isFunction( animation.opts.start ) ) { 8706 animation.opts.start.call( elem, animation ); 8707 } 8708 8709 jQuery.fx.timer( 8710 jQuery.extend( tick, { 8711 anim: animation, 8712 queue: animation.opts.queue, 8713 elem: elem 8714 }) 8715 ); 8716 8717 // attach callbacks from options 8718 return animation.progress( animation.opts.progress ) 8719 .done( animation.opts.done, animation.opts.complete ) 8720 .fail( animation.opts.fail ) 8721 .always( animation.opts.always ); 8722 } 8723 8724 function propFilter( props, specialEasing ) { 8725 var index, name, easing, value, hooks; 8726 8727 // camelCase, specialEasing and expand cssHook pass 8728 for ( index in props ) { 8729 name = jQuery.camelCase( index ); 8730 easing = specialEasing[ name ]; 8731 value = props[ index ]; 8732 if ( jQuery.isArray( value ) ) { 8733 easing = value[ 1 ]; 8734 value = props[ index ] = value[ 0 ]; 8735 } 8736 8737 if ( index !== name ) { 8738 props[ name ] = value; 8739 delete props[ index ]; 8740 } 8741 8742 hooks = jQuery.cssHooks[ name ]; 8743 if ( hooks && "expand" in hooks ) { 8744 value = hooks.expand( value ); 8745 delete props[ name ]; 8746 8747 // not quite $.extend, this wont overwrite keys already present. 8748 // also - reusing 'index' from above because we have the correct "name" 8749 for ( index in value ) { 8750 if ( !( index in props ) ) { 8751 props[ index ] = value[ index ]; 8752 specialEasing[ index ] = easing; 8753 } 8754 } 8755 } else { 8756 specialEasing[ name ] = easing; 8757 } 8758 } 8759 } 8760 8761 jQuery.Animation = jQuery.extend( Animation, { 8762 8763 tweener: function( props, callback ) { 8764 if ( jQuery.isFunction( props ) ) { 8765 callback = props; 8766 props = [ "*" ]; 8767 } else { 8768 props = props.split(" "); 8769 } 8770 8771 var prop, 8772 index = 0, 8773 length = props.length; 8774 8775 for ( ; index < length ; index++ ) { 8776 prop = props[ index ]; 8777 tweeners[ prop ] = tweeners[ prop ] || []; 8778 tweeners[ prop ].unshift( callback ); 8779 } 8780 }, 8781 8782 prefilter: function( callback, prepend ) { 8783 if ( prepend ) { 8784 animationPrefilters.unshift( callback ); 8785 } else { 8786 animationPrefilters.push( callback ); 8787 } 8788 } 8789 }); 8790 8791 function defaultPrefilter( elem, props, opts ) { 8792 var index, prop, value, length, dataShow, toggle, tween, hooks, oldfire, 8793 anim = this, 8794 style = elem.style, 8795 orig = {}, 8796 handled = [], 8797 hidden = elem.nodeType && isHidden( elem ); 8798 8799 // handle queue: false promises 8800 if ( !opts.queue ) { 8801 hooks = jQuery._queueHooks( elem, "fx" ); 8802 if ( hooks.unqueued == null ) { 8803 hooks.unqueued = 0; 8804 oldfire = hooks.empty.fire; 8805 hooks.empty.fire = function() { 8806 if ( !hooks.unqueued ) { 8807 oldfire(); 8808 } 8809 }; 8810 } 8811 hooks.unqueued++; 8812 8813 anim.always(function() { 8814 // doing this makes sure that the complete handler will be called 8815 // before this completes 8816 anim.always(function() { 8817 hooks.unqueued--; 8818 if ( !jQuery.queue( elem, "fx" ).length ) { 8819 hooks.empty.fire(); 8820 } 8821 }); 8822 }); 8823 } 8824 8825 // height/width overflow pass 8826 if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) { 8827 // Make sure that nothing sneaks out 8828 // Record all 3 overflow attributes because IE does not 8829 // change the overflow attribute when overflowX and 8830 // overflowY are set to the same value 8831 opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; 8832 8833 // Set display property to inline-block for height/width 8834 // animations on inline elements that are having width/height animated 8835 if ( jQuery.css( elem, "display" ) === "inline" && 8836 jQuery.css( elem, "float" ) === "none" ) { 8837 8838 // inline-level elements accept inline-block; 8839 // block-level elements need to be inline with layout 8840 if ( !jQuery.support.inlineBlockNeedsLayout || css_defaultDisplay( elem.nodeName ) === "inline" ) { 8841 style.display = "inline-block"; 8842 8843 } else { 8844 style.zoom = 1; 8845 } 8846 } 8847 } 8848 8849 if ( opts.overflow ) { 8850 style.overflow = "hidden"; 8851 if ( !jQuery.support.shrinkWrapBlocks ) { 8852 anim.done(function() { 8853 style.overflow = opts.overflow[ 0 ]; 8854 style.overflowX = opts.overflow[ 1 ]; 8855 style.overflowY = opts.overflow[ 2 ]; 8856 }); 8857 } 8858 } 8859 8860 8861 // show/hide pass 8862 for ( index in props ) { 8863 value = props[ index ]; 8864 if ( rfxtypes.exec( value ) ) { 8865 delete props[ index ]; 8866 toggle = toggle || value === "toggle"; 8867 if ( value === ( hidden ? "hide" : "show" ) ) { 8868 continue; 8869 } 8870 handled.push( index ); 8871 } 8872 } 8873 8874 length = handled.length; 8875 if ( length ) { 8876 dataShow = jQuery._data( elem, "fxshow" ) || jQuery._data( elem, "fxshow", {} ); 8877 if ( "hidden" in dataShow ) { 8878 hidden = dataShow.hidden; 8879 } 8880 8881 // store state if its toggle - enables .stop().toggle() to "reverse" 8882 if ( toggle ) { 8883 dataShow.hidden = !hidden; 8884 } 8885 if ( hidden ) { 8886 jQuery( elem ).show(); 8887 } else { 8888 anim.done(function() { 8889 jQuery( elem ).hide(); 8890 }); 8891 } 8892 anim.done(function() { 8893 var prop; 8894 jQuery.removeData( elem, "fxshow", true ); 8895 for ( prop in orig ) { 8896 jQuery.style( elem, prop, orig[ prop ] ); 8897 } 8898 }); 8899 for ( index = 0 ; index < length ; index++ ) { 8900 prop = handled[ index ]; 8901 tween = anim.createTween( prop, hidden ? dataShow[ prop ] : 0 ); 8902 orig[ prop ] = dataShow[ prop ] || jQuery.style( elem, prop ); 8903 8904 if ( !( prop in dataShow ) ) { 8905 dataShow[ prop ] = tween.start; 8906 if ( hidden ) { 8907 tween.end = tween.start; 8908 tween.start = prop === "width" || prop === "height" ? 1 : 0; 8909 } 8910 } 8911 } 8912 } 8913 } 8914 8915 function Tween( elem, options, prop, end, easing ) { 8916 return new Tween.prototype.init( elem, options, prop, end, easing ); 8917 } 8918 jQuery.Tween = Tween; 8919 8920 Tween.prototype = { 8921 constructor: Tween, 8922 init: function( elem, options, prop, end, easing, unit ) { 8923 this.elem = elem; 8924 this.prop = prop; 8925 this.easing = easing || "swing"; 8926 this.options = options; 8927 this.start = this.now = this.cur(); 8928 this.end = end; 8929 this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); 8930 }, 8931 cur: function() { 8932 var hooks = Tween.propHooks[ this.prop ]; 8933 8934 return hooks && hooks.get ? 8935 hooks.get( this ) : 8936 Tween.propHooks._default.get( this ); 8937 }, 8938 run: function( percent ) { 8939 var eased, 8940 hooks = Tween.propHooks[ this.prop ]; 8941 8942 if ( this.options.duration ) { 8943 this.pos = eased = jQuery.easing[ this.easing ]( 8944 percent, this.options.duration * percent, 0, 1, this.options.duration 8945 ); 8946 } else { 8947 this.pos = eased = percent; 8948 } 8949 this.now = ( this.end - this.start ) * eased + this.start; 8950 8951 if ( this.options.step ) { 8952 this.options.step.call( this.elem, this.now, this ); 8953 } 8954 8955 if ( hooks && hooks.set ) { 8956 hooks.set( this ); 8957 } else { 8958 Tween.propHooks._default.set( this ); 8959 } 8960 return this; 8961 } 8962 }; 8963 8964 Tween.prototype.init.prototype = Tween.prototype; 8965 8966 Tween.propHooks = { 8967 _default: { 8968 get: function( tween ) { 8969 var result; 8970 8971 if ( tween.elem[ tween.prop ] != null && 8972 (!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) { 8973 return tween.elem[ tween.prop ]; 8974 } 8975 8976 // passing any value as a 4th parameter to .css will automatically 8977 // attempt a parseFloat and fallback to a string if the parse fails 8978 // so, simple values such as "10px" are parsed to Float. 8979 // complex values such as "rotate(1rad)" are returned as is. 8980 result = jQuery.css( tween.elem, tween.prop, false, "" ); 8981 // Empty strings, null, undefined and "auto" are converted to 0. 8982 return !result || result === "auto" ? 0 : result; 8983 }, 8984 set: function( tween ) { 8985 // use step hook for back compat - use cssHook if its there - use .style if its 8986 // available and use plain properties where available 8987 if ( jQuery.fx.step[ tween.prop ] ) { 8988 jQuery.fx.step[ tween.prop ]( tween ); 8989 } else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) { 8990 jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); 8991 } else { 8992 tween.elem[ tween.prop ] = tween.now; 8993 } 8994 } 8995 } 8996 }; 8997 8998 // Remove in 2.0 - this supports IE8's panic based approach 8999 // to setting things on disconnected nodes 9000 9001 Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { 9002 set: function( tween ) { 9003 if ( tween.elem.nodeType && tween.elem.parentNode ) { 9004 tween.elem[ tween.prop ] = tween.now; 9005 } 9006 } 9007 }; 9008 9009 jQuery.each([ "toggle", "show", "hide" ], function( i, name ) { 9010 var cssFn = jQuery.fn[ name ]; 9011 jQuery.fn[ name ] = function( speed, easing, callback ) { 9012 return speed == null || typeof speed === "boolean" || 9013 // special check for .toggle( handler, handler, ... ) 9014 ( !i && jQuery.isFunction( speed ) && jQuery.isFunction( easing ) ) ? 9015 cssFn.apply( this, arguments ) : 9016 this.animate( genFx( name, true ), speed, easing, callback ); 9017 }; 9018 }); 9019 9020 jQuery.fn.extend({ 9021 fadeTo: function( speed, to, easing, callback ) { 9022 9023 // show any hidden elements after setting opacity to 0 9024 return this.filter( isHidden ).css( "opacity", 0 ).show() 9025 9026 // animate to the value specified 9027 .end().animate({ opacity: to }, speed, easing, callback ); 9028 }, 9029 animate: function( prop, speed, easing, callback ) { 9030 var empty = jQuery.isEmptyObject( prop ), 9031 optall = jQuery.speed( speed, easing, callback ), 9032 doAnimation = function() { 9033 // Operate on a copy of prop so per-property easing won't be lost 9034 var anim = Animation( this, jQuery.extend( {}, prop ), optall ); 9035 9036 // Empty animations resolve immediately 9037 if ( empty ) { 9038 anim.stop( true ); 9039 } 9040 }; 9041 9042 return empty || optall.queue === false ? 9043 this.each( doAnimation ) : 9044 this.queue( optall.queue, doAnimation ); 9045 }, 9046 stop: function( type, clearQueue, gotoEnd ) { 9047 var stopQueue = function( hooks ) { 9048 var stop = hooks.stop; 9049 delete hooks.stop; 9050 stop( gotoEnd ); 9051 }; 9052 9053 if ( typeof type !== "string" ) { 9054 gotoEnd = clearQueue; 9055 clearQueue = type; 9056 type = undefined; 9057 } 9058 if ( clearQueue && type !== false ) { 9059 this.queue( type || "fx", [] ); 9060 } 9061 9062 return this.each(function() { 9063 var dequeue = true, 9064 index = type != null && type + "queueHooks", 9065 timers = jQuery.timers, 9066 data = jQuery._data( this ); 9067 9068 if ( index ) { 9069 if ( data[ index ] && data[ index ].stop ) { 9070 stopQueue( data[ index ] ); 9071 } 9072 } else { 9073 for ( index in data ) { 9074 if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { 9075 stopQueue( data[ index ] ); 9076 } 9077 } 9078 } 9079 9080 for ( index = timers.length; index--; ) { 9081 if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) { 9082 timers[ index ].anim.stop( gotoEnd ); 9083 dequeue = false; 9084 timers.splice( index, 1 ); 9085 } 9086 } 9087 9088 // start the next in the queue if the last step wasn't forced 9089 // timers currently will call their complete callbacks, which will dequeue 9090 // but only if they were gotoEnd 9091 if ( dequeue || !gotoEnd ) { 9092 jQuery.dequeue( this, type ); 9093 } 9094 }); 9095 } 9096 }); 9097 9098 // Generate parameters to create a standard animation 9099 function genFx( type, includeWidth ) { 9100 var which, 9101 attrs = { height: type }, 9102 i = 0; 9103 9104 // if we include width, step value is 1 to do all cssExpand values, 9105 // if we don't include width, step value is 2 to skip over Left and Right 9106 includeWidth = includeWidth? 1 : 0; 9107 for( ; i < 4 ; i += 2 - includeWidth ) { 9108 which = cssExpand[ i ]; 9109 attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; 9110 } 9111 9112 if ( includeWidth ) { 9113 attrs.opacity = attrs.width = type; 9114 } 9115 9116 return attrs; 9117 } 9118 9119 // Generate shortcuts for custom animations 9120 jQuery.each({ 9121 slideDown: genFx("show"), 9122 slideUp: genFx("hide"), 9123 slideToggle: genFx("toggle"), 9124 fadeIn: { opacity: "show" }, 9125 fadeOut: { opacity: "hide" }, 9126 fadeToggle: { opacity: "toggle" } 9127 }, function( name, props ) { 9128 jQuery.fn[ name ] = function( speed, easing, callback ) { 9129 return this.animate( props, speed, easing, callback ); 9130 }; 9131 }); 9132 9133 jQuery.speed = function( speed, easing, fn ) { 9134 var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { 9135 complete: fn || !fn && easing || 9136 jQuery.isFunction( speed ) && speed, 9137 duration: speed, 9138 easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing 9139 }; 9140 9141 opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration : 9142 opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default; 9143 9144 // normalize opt.queue - true/undefined/null -> "fx" 9145 if ( opt.queue == null || opt.queue === true ) { 9146 opt.queue = "fx"; 9147 } 9148 9149 // Queueing 9150 opt.old = opt.complete; 9151 9152 opt.complete = function() { 9153 if ( jQuery.isFunction( opt.old ) ) { 9154 opt.old.call( this ); 9155 } 9156 9157 if ( opt.queue ) { 9158 jQuery.dequeue( this, opt.queue ); 9159 } 9160 }; 9161 9162 return opt; 9163 }; 9164 9165 jQuery.easing = { 9166 linear: function( p ) { 9167 return p; 9168 }, 9169 swing: function( p ) { 9170 return 0.5 - Math.cos( p*Math.PI ) / 2; 9171 } 9172 }; 9173 9174 jQuery.timers = []; 9175 jQuery.fx = Tween.prototype.init; 9176 jQuery.fx.tick = function() { 9177 var timer, 9178 timers = jQuery.timers, 9179 i = 0; 9180 9181 fxNow = jQuery.now(); 9182 9183 for ( ; i < timers.length; i++ ) { 9184 timer = timers[ i ]; 9185 // Checks the timer has not already been removed 9186 if ( !timer() && timers[ i ] === timer ) { 9187 timers.splice( i--, 1 ); 9188 } 9189 } 9190 9191 if ( !timers.length ) { 9192 jQuery.fx.stop(); 9193 } 9194 fxNow = undefined; 9195 }; 9196 9197 jQuery.fx.timer = function( timer ) { 9198 if ( timer() && jQuery.timers.push( timer ) && !timerId ) { 9199 timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval ); 9200 } 9201 }; 9202 9203 jQuery.fx.interval = 13; 9204 9205 jQuery.fx.stop = function() { 9206 clearInterval( timerId ); 9207 timerId = null; 9208 }; 9209 9210 jQuery.fx.speeds = { 9211 slow: 600, 9212 fast: 200, 9213 // Default speed 9214 _default: 400 9215 }; 9216 9217 // Back Compat <1.8 extension point 9218 jQuery.fx.step = {}; 9219 9220 if ( jQuery.expr && jQuery.expr.filters ) { 9221 jQuery.expr.filters.animated = function( elem ) { 9222 return jQuery.grep(jQuery.timers, function( fn ) { 9223 return elem === fn.elem; 9224 }).length; 9225 }; 9226 } 9227 var rroot = /^(?:body|html)$/i; 9228 9229 jQuery.fn.offset = function( options ) { 9230 if ( arguments.length ) { 9231 return options === undefined ? 9232 this : 9233 this.each(function( i ) { 9234 jQuery.offset.setOffset( this, options, i ); 9235 }); 9236 } 9237 9238 var docElem, body, win, clientTop, clientLeft, scrollTop, scrollLeft, 9239 box = { top: 0, left: 0 }, 9240 elem = this[ 0 ], 9241 doc = elem && elem.ownerDocument; 9242 9243 if ( !doc ) { 9244 return; 9245 } 9246 9247 if ( (body = doc.body) === elem ) { 9248 return jQuery.offset.bodyOffset( elem ); 9249 } 9250 9251 docElem = doc.documentElement; 9252 9253 // Make sure it's not a disconnected DOM node 9254 if ( !jQuery.contains( docElem, elem ) ) { 9255 return box; 9256 } 9257 9258 // If we don't have gBCR, just use 0,0 rather than error 9259 // BlackBerry 5, iOS 3 (original iPhone) 9260 if ( typeof elem.getBoundingClientRect !== "undefined" ) { 9261 box = elem.getBoundingClientRect(); 9262 } 9263 win = getWindow( doc ); 9264 clientTop = docElem.clientTop || body.clientTop || 0; 9265 clientLeft = docElem.clientLeft || body.clientLeft || 0; 9266 scrollTop = win.pageYOffset || docElem.scrollTop; 9267 scrollLeft = win.pageXOffset || docElem.scrollLeft; 9268 return { 9269 top: box.top + scrollTop - clientTop, 9270 left: box.left + scrollLeft - clientLeft 9271 }; 9272 }; 9273 9274 jQuery.offset = { 9275 9276 bodyOffset: function( body ) { 9277 var top = body.offsetTop, 9278 left = body.offsetLeft; 9279 9280 if ( jQuery.support.doesNotIncludeMarginInBodyOffset ) { 9281 top += parseFloat( jQuery.css(body, "marginTop") ) || 0; 9282 left += parseFloat( jQuery.css(body, "marginLeft") ) || 0; 9283 } 9284 9285 return { top: top, left: left }; 9286 }, 9287 9288 setOffset: function( elem, options, i ) { 9289 var position = jQuery.css( elem, "position" ); 9290 9291 // set position first, in-case top/left are set even on static elem 9292 if ( position === "static" ) { 9293 elem.style.position = "relative"; 9294 } 9295 9296 var curElem = jQuery( elem ), 9297 curOffset = curElem.offset(), 9298 curCSSTop = jQuery.css( elem, "top" ), 9299 curCSSLeft = jQuery.css( elem, "left" ), 9300 calculatePosition = ( position === "absolute" || position === "fixed" ) && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1, 9301 props = {}, curPosition = {}, curTop, curLeft; 9302 9303 // need to be able to calculate position if either top or left is auto and position is either absolute or fixed 9304 if ( calculatePosition ) { 9305 curPosition = curElem.position(); 9306 curTop = curPosition.top; 9307 curLeft = curPosition.left; 9308 } else { 9309 curTop = parseFloat( curCSSTop ) || 0; 9310 curLeft = parseFloat( curCSSLeft ) || 0; 9311 } 9312 9313 if ( jQuery.isFunction( options ) ) { 9314 options = options.call( elem, i, curOffset ); 9315 } 9316 9317 if ( options.top != null ) { 9318 props.top = ( options.top - curOffset.top ) + curTop; 9319 } 9320 if ( options.left != null ) { 9321 props.left = ( options.left - curOffset.left ) + curLeft; 9322 } 9323 9324 if ( "using" in options ) { 9325 options.using.call( elem, props ); 9326 } else { 9327 curElem.css( props ); 9328 } 9329 } 9330 }; 9331 9332 9333 jQuery.fn.extend({ 9334 9335 position: function() { 9336 if ( !this[0] ) { 9337 return; 9338 } 9339 9340 var elem = this[0], 9341 9342 // Get *real* offsetParent 9343 offsetParent = this.offsetParent(), 9344 9345 // Get correct offsets 9346 offset = this.offset(), 9347 parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset(); 9348 9349 // Subtract element margins 9350 // note: when an element has margin: auto the offsetLeft and marginLeft 9351 // are the same in Safari causing offset.left to incorrectly be 0 9352 offset.top -= parseFloat( jQuery.css(elem, "marginTop") ) || 0; 9353 offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0; 9354 9355 // Add offsetParent borders 9356 parentOffset.top += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0; 9357 parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0; 9358 9359 // Subtract the two offsets 9360 return { 9361 top: offset.top - parentOffset.top, 9362 left: offset.left - parentOffset.left 9363 }; 9364 }, 9365 9366 offsetParent: function() { 9367 return this.map(function() { 9368 var offsetParent = this.offsetParent || document.body; 9369 while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) { 9370 offsetParent = offsetParent.offsetParent; 9371 } 9372 return offsetParent || document.body; 9373 }); 9374 } 9375 }); 9376 9377 9378 // Create scrollLeft and scrollTop methods 9379 jQuery.each( {scrollLeft: "pageXOffset", scrollTop: "pageYOffset"}, function( method, prop ) { 9380 var top = /Y/.test( prop ); 9381 9382 jQuery.fn[ method ] = function( val ) { 9383 return jQuery.access( this, function( elem, method, val ) { 9384 var win = getWindow( elem ); 9385 9386 if ( val === undefined ) { 9387 return win ? (prop in win) ? win[ prop ] : 9388 win.document.documentElement[ method ] : 9389 elem[ method ]; 9390 } 9391 9392 if ( win ) { 9393 win.scrollTo( 9394 !top ? val : jQuery( win ).scrollLeft(), 9395 top ? val : jQuery( win ).scrollTop() 9396 ); 9397 9398 } else { 9399 elem[ method ] = val; 9400 } 9401 }, method, val, arguments.length, null ); 9402 }; 9403 }); 9404 9405 function getWindow( elem ) { 9406 return jQuery.isWindow( elem ) ? 9407 elem : 9408 elem.nodeType === 9 ? 9409 elem.defaultView || elem.parentWindow : 9410 false; 9411 } 9412 // Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods 9413 jQuery.each( { Height: "height", Width: "width" }, function( name, type ) { 9414 jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) { 9415 // margin is only for outerHeight, outerWidth 9416 jQuery.fn[ funcName ] = function( margin, value ) { 9417 var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ), 9418 extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" ); 9419 9420 return jQuery.access( this, function( elem, type, value ) { 9421 var doc; 9422 9423 if ( jQuery.isWindow( elem ) ) { 9424 // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there 9425 // isn't a whole lot we can do. See pull request at this URL for discussion: 9426 // https://github.com/jquery/jquery/pull/764 9427 return elem.document.documentElement[ "client" + name ]; 9428 } 9429 9430 // Get document width or height 9431 if ( elem.nodeType === 9 ) { 9432 doc = elem.documentElement; 9433 9434 // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], whichever is greatest 9435 // unfortunately, this causes bug #3838 in IE6/8 only, but there is currently no good, small way to fix it. 9436 return Math.max( 9437 elem.body[ "scroll" + name ], doc[ "scroll" + name ], 9438 elem.body[ "offset" + name ], doc[ "offset" + name ], 9439 doc[ "client" + name ] 9440 ); 9441 } 9442 9443 return value === undefined ? 9444 // Get width or height on the element, requesting but not forcing parseFloat 9445 jQuery.css( elem, type, value, extra ) : 9446 9447 // Set width or height on the element 9448 jQuery.style( elem, type, value, extra ); 9449 }, type, chainable ? margin : undefined, chainable, null ); 9450 }; 9451 }); 9452 }); 9453 // Expose jQuery to the global object 9454 window.jQuery = window.$ = jQuery; 9455 9456 // Expose jQuery as an AMD module, but only for AMD loaders that 9457 // understand the issues with loading multiple versions of jQuery 9458 // in a page that all might call define(). The loader will indicate 9459 // they have special allowances for multiple jQuery versions by 9460 // specifying define.amd.jQuery = true. Register as a named module, 9461 // since jQuery can be concatenated with other files that may use define, 9462 // but not use a proper concatenation script that understands anonymous 9463 // AMD modules. A named AMD is safest and most robust way to register. 9464 // Lowercase jquery is used because AMD module names are derived from 9465 // file names, and jQuery is normally delivered in a lowercase file name. 9466 // Do this after creating the global so that if an AMD module wants to call 9467 // noConflict to hide this version of jQuery, it will work. 9468 if ( typeof define === "function" && define.amd && define.amd.jQuery ) { 9469 define( "jquery", [], function () { return jQuery; } ); 9470 } 9471 9472 })( window );

Contacte con nosotros
¿No puede leer el artículo? ¡Póngase en contacto con nosotros para obtener una respuesta gratuita! Ayuda gratuita para sitios personales y de pequeñas empresas
Tel: 020-2206-9892
QQ咨询:1025174874
(iii) Correo electrónico: info@361sale.com
Horario de trabajo: de lunes a viernes, de 9:30 a 18:30, días festivos libres
© Declaración de reproducción
Este artículo fue escrito por Harry
EL FIN
Si le gusta, apóyela.
felicitaciones0 compartir (alegrías, beneficios, privilegios, etc.) con los demás
comentarios compra de sofás

Por favor, inicie sesión para enviar un comentario

    Sin comentarios