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

WordPress源代码——jquery(jquery-1.10.2.js)
-

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 ); -

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

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

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

WordPress源代码——jquery(jquery-1.4.4.js)
1 /*! 2 * jQuery JavaScript Library v1.4.4 3 * http://jquery.com/ 4 * 5 * Copyright 2010, John Resig 6 * Dual licensed under the MIT or GPL Version 2 licenses. 7 * http://jquery.org/license 8 * 9 * Includes Sizzle.js 10 * http://sizzlejs.com/ 11 * Copyright 2010, The Dojo Foundation 12 * Released under the MIT, BSD, and GPL Licenses. 13 * 14 * Date: Thu Nov 11 19:04:53 2010 -0500 15 */ 16 (function( window, undefined ) { 17 18 // Use the correct document accordingly with window argument (sandbox) 19 var document = window.document; 20 var jQuery = (function() { 21 22 // Define a local copy of jQuery 23 var jQuery = function( selector, context ) { 24 // The jQuery object is actually just the init constructor 'enhanced' 25 return new jQuery.fn.init( selector, context ); 26 }, 27 28 // Map over jQuery in case of overwrite 29 _jQuery = window.jQuery, 30 31 // Map over the $ in case of overwrite 32 _$ = window.$, 33 34 // A central reference to the root jQuery(document) 35 rootjQuery, 36 37 // A simple way to check for HTML strings or ID strings 38 // (both of which we optimize for) 39 quickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]+)$)/, 40 41 // Is it a simple selector 42 isSimple = /^.[^:#\[\.,]*$/, 43 44 // Check if a string has a non-whitespace character in it 45 rnotwhite = /\S/, 46 rwhite = /\s/, 47 48 // Used for trimming whitespace 49 trimLeft = /^\s+/, 50 trimRight = /\s+$/, 51 52 // Check for non-word characters 53 rnonword = /\W/, 54 55 // Check for digits 56 rdigit = /\d/, 57 58 // Match a standalone tag 59 rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/, 60 61 // JSON RegExp 62 rvalidchars = /^[\],:{}\s]*$/, 63 rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, 64 rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, 65 rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, 66 67 // Useragent RegExp 68 rwebkit = /(webkit)[ \/]([\w.]+)/, 69 ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/, 70 rmsie = /(msie) ([\w.]+)/, 71 rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/, 72 73 // Keep a UserAgent string for use with jQuery.browser 74 userAgent = navigator.userAgent, 75 76 // For matching the engine and version of the browser 77 browserMatch, 78 79 // Has the ready events already been bound? 80 readyBound = false, 81 82 // The functions to execute on DOM ready 83 readyList = [], 84 85 // The ready event handler 86 DOMContentLoaded, 87 88 // Save a reference to some core methods 89 toString = Object.prototype.toString, 90 hasOwn = Object.prototype.hasOwnProperty, 91 push = Array.prototype.push, 92 slice = Array.prototype.slice, 93 trim = String.prototype.trim, 94 indexOf = Array.prototype.indexOf, 95 96 // [[Class]] -> type pairs 97 class2type = {}; 98 99 jQuery.fn = jQuery.prototype = { 100 init: function( selector, context ) { 101 var match, elem, ret, doc; 102 103 // Handle $(""), $(null), or $(undefined) 104 if ( !selector ) { 105 return this; 106 } 107 108 // Handle $(DOMElement) 109 if ( selector.nodeType ) { 110 this.context = this[0] = selector; 111 this.length = 1; 112 return this; 113 } 114 115 // The body element only exists once, optimize finding it 116 if ( selector === "body" && !context && document.body ) { 117 this.context = document; 118 this[0] = document.body; 119 this.selector = "body"; 120 this.length = 1; 121 return this; 122 } 123 124 // Handle HTML strings 125 if ( typeof selector === "string" ) { 126 // Are we dealing with HTML string or an ID? 127 match = quickExpr.exec( selector ); 128 129 // Verify a match, and that no context was specified for #id 130 if ( match && (match[1] || !context) ) { 131 132 // HANDLE: $(html) -> $(array) 133 if ( match[1] ) { 134 doc = (context ? context.ownerDocument || context : document); 135 136 // If a single string is passed in and it's a single tag 137 // just do a createElement and skip the rest 138 ret = rsingleTag.exec( selector ); 139 140 if ( ret ) { 141 if ( jQuery.isPlainObject( context ) ) { 142 selector = [ document.createElement( ret[1] ) ]; 143 jQuery.fn.attr.call( selector, context, true ); 144 145 } else { 146 selector = [ doc.createElement( ret[1] ) ]; 147 } 148 149 } else { 150 ret = jQuery.buildFragment( [ match[1] ], [ doc ] ); 151 selector = (ret.cacheable ? ret.fragment.cloneNode(true) : ret.fragment).childNodes; 152 } 153 154 return jQuery.merge( this, selector ); 155 156 // HANDLE: $("#id") 157 } else { 158 elem = document.getElementById( match[2] ); 159 160 // Check parentNode to catch when Blackberry 4.6 returns 161 // nodes that are no longer in the document #6963 162 if ( elem && elem.parentNode ) { 163 // Handle the case where IE and Opera return items 164 // by name instead of ID 165 if ( elem.id !== match[2] ) { 166 return rootjQuery.find( selector ); 167 } 168 169 // Otherwise, we inject the element directly into the jQuery object 170 this.length = 1; 171 this[0] = elem; 172 } 173 174 this.context = document; 175 this.selector = selector; 176 return this; 177 } 178 179 // HANDLE: $("TAG") 180 } else if ( !context && !rnonword.test( selector ) ) { 181 this.selector = selector; 182 this.context = document; 183 selector = document.getElementsByTagName( selector ); 184 return jQuery.merge( this, selector ); 185 186 // HANDLE: $(expr, $(...)) 187 } else if ( !context || context.jquery ) { 188 return (context || rootjQuery).find( selector ); 189 190 // HANDLE: $(expr, context) 191 // (which is just equivalent to: $(context).find(expr) 192 } else { 193 return jQuery( context ).find( selector ); 194 } 195 196 // HANDLE: $(function) 197 // Shortcut for document ready 198 } else if ( jQuery.isFunction( selector ) ) { 199 return rootjQuery.ready( selector ); 200 } 201 202 if (selector.selector !== undefined) { 203 this.selector = selector.selector; 204 this.context = selector.context; 205 } 206 207 return jQuery.makeArray( selector, this ); 208 }, 209 210 // Start with an empty selector 211 selector: "", 212 213 // The current version of jQuery being used 214 jquery: "1.4.4", 215 216 // The default length of a jQuery object is 0 217 length: 0, 218 219 // The number of elements contained in the matched element set 220 size: function() { 221 return this.length; 222 }, 223 224 toArray: function() { 225 return slice.call( this, 0 ); 226 }, 227 228 // Get the Nth element in the matched element set OR 229 // Get the whole matched element set as a clean array 230 get: function( num ) { 231 return num == null ? 232 233 // Return a 'clean' array 234 this.toArray() : 235 236 // Return just the object 237 ( num < 0 ? this.slice(num)[ 0 ] : this[ num ] ); 238 }, 239 240 // Take an array of elements and push it onto the stack 241 // (returning the new matched element set) 242 pushStack: function( elems, name, selector ) { 243 // Build a new jQuery matched element set 244 var ret = jQuery(); 245 246 if ( jQuery.isArray( elems ) ) { 247 push.apply( ret, elems ); 248 249 } else { 250 jQuery.merge( ret, elems ); 251 } 252 253 // Add the old object onto the stack (as a reference) 254 ret.prevObject = this; 255 256 ret.context = this.context; 257 258 if ( name === "find" ) { 259 ret.selector = this.selector + (this.selector ? " " : "") + selector; 260 } else if ( name ) { 261 ret.selector = this.selector + "." + name + "(" + selector + ")"; 262 } 263 264 // Return the newly-formed element set 265 return ret; 266 }, 267 268 // Execute a callback for every element in the matched set. 269 // (You can seed the arguments with an array of args, but this is 270 // only used internally.) 271 each: function( callback, args ) { 272 return jQuery.each( this, callback, args ); 273 }, 274 275 ready: function( fn ) { 276 // Attach the listeners 277 jQuery.bindReady(); 278 279 // If the DOM is already ready 280 if ( jQuery.isReady ) { 281 // Execute the function immediately 282 fn.call( document, jQuery ); 283 284 // Otherwise, remember the function for later 285 } else if ( readyList ) { 286 // Add the function to the wait list 287 readyList.push( fn ); 288 } 289 290 return this; 291 }, 292 293 eq: function( i ) { 294 return i === -1 ? 295 this.slice( i ) : 296 this.slice( i, +i + 1 ); 297 }, 298 299 first: function() { 300 return this.eq( 0 ); 301 }, 302 303 last: function() { 304 return this.eq( -1 ); 305 }, 306 307 slice: function() { 308 return this.pushStack( slice.apply( this, arguments ), 309 "slice", slice.call(arguments).join(",") ); 310 }, 311 312 map: function( callback ) { 313 return this.pushStack( jQuery.map(this, function( elem, i ) { 314 return callback.call( elem, i, elem ); 315 })); 316 }, 317 318 end: function() { 319 return this.prevObject || jQuery(null); 320 }, 321 322 // For internal use only. 323 // Behaves like an Array's method, not like a jQuery method. 324 push: push, 325 sort: [].sort, 326 splice: [].splice 327 }; 328 329 // Give the init function the jQuery prototype for later instantiation 330 jQuery.fn.init.prototype = jQuery.fn; 331 332 jQuery.extend = jQuery.fn.extend = function() { 333 var options, name, src, copy, copyIsArray, clone, 334 target = arguments[0] || {}, 335 i = 1, 336 length = arguments.length, 337 deep = false; 338 339 // Handle a deep copy situation 340 if ( typeof target === "boolean" ) { 341 deep = target; 342 target = arguments[1] || {}; 343 // skip the boolean and the target 344 i = 2; 345 } 346 347 // Handle case when target is a string or something (possible in deep copy) 348 if ( typeof target !== "object" && !jQuery.isFunction(target) ) { 349 target = {}; 350 } 351 352 // extend jQuery itself if only one argument is passed 353 if ( length === i ) { 354 target = this; 355 --i; 356 } 357 358 for ( ; i < length; i++ ) { 359 // Only deal with non-null/undefined values 360 if ( (options = arguments[ i ]) != null ) { 361 // Extend the base object 362 for ( name in options ) { 363 src = target[ name ]; 364 copy = options[ name ]; 365 366 // Prevent never-ending loop 367 if ( target === copy ) { 368 continue; 369 } 370 371 // Recurse if we're merging plain objects or arrays 372 if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { 373 if ( copyIsArray ) { 374 copyIsArray = false; 375 clone = src && jQuery.isArray(src) ? src : []; 376 377 } else { 378 clone = src && jQuery.isPlainObject(src) ? src : {}; 379 } 380 381 // Never move original objects, clone them 382 target[ name ] = jQuery.extend( deep, clone, copy ); 383 384 // Don't bring in undefined values 385 } else if ( copy !== undefined ) { 386 target[ name ] = copy; 387 } 388 } 389 } 390 } 391 392 // Return the modified object 393 return target; 394 }; 395 396 jQuery.extend({ 397 noConflict: function( deep ) { 398 window.$ = _$; 399 400 if ( deep ) { 401 window.jQuery = _jQuery; 402 } 403 404 return jQuery; 405 }, 406 407 // Is the DOM ready to be used? Set to true once it occurs. 408 isReady: false, 409 410 // A counter to track how many items to wait for before 411 // the ready event fires. See #6781 412 readyWait: 1, 413 414 // Handle when the DOM is ready 415 ready: function( wait ) { 416 // A third-party is pushing the ready event forwards 417 if ( wait === true ) { 418 jQuery.readyWait--; 419 } 420 421 // Make sure that the DOM is not already loaded 422 if ( !jQuery.readyWait || (wait !== true && !jQuery.isReady) ) { 423 // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). 424 if ( !document.body ) { 425 return setTimeout( jQuery.ready, 1 ); 426 } 427 428 // Remember that the DOM is ready 429 jQuery.isReady = true; 430 431 // If a normal DOM Ready event fired, decrement, and wait if need be 432 if ( wait !== true && --jQuery.readyWait > 0 ) { 433 return; 434 } 435 436 // If there are functions bound, to execute 437 if ( readyList ) { 438 // Execute all of them 439 var fn, 440 i = 0, 441 ready = readyList; 442 443 // Reset the list of functions 444 readyList = null; 445 446 while ( (fn = ready[ i++ ]) ) { 447 fn.call( document, jQuery ); 448 } 449 450 // Trigger any bound ready events 451 if ( jQuery.fn.trigger ) { 452 jQuery( document ).trigger( "ready" ).unbind( "ready" ); 453 } 454 } 455 } 456 }, 457 458 bindReady: function() { 459 if ( readyBound ) { 460 return; 461 } 462 463 readyBound = true; 464 465 // Catch cases where $(document).ready() is called after the 466 // browser event has already occurred. 467 if ( document.readyState === "complete" ) { 468 // Handle it asynchronously to allow scripts the opportunity to delay ready 469 return setTimeout( jQuery.ready, 1 ); 470 } 471 472 // Mozilla, Opera and webkit nightlies currently support this event 473 if ( document.addEventListener ) { 474 // Use the handy event callback 475 document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false ); 476 477 // A fallback to window.onload, that will always work 478 window.addEventListener( "load", jQuery.ready, false ); 479 480 // If IE event model is used 481 } else if ( document.attachEvent ) { 482 // ensure firing before onload, 483 // maybe late but safe also for iframes 484 document.attachEvent("onreadystatechange", DOMContentLoaded); 485 486 // A fallback to window.onload, that will always work 487 window.attachEvent( "onload", jQuery.ready ); 488 489 // If IE and not a frame 490 // continually check to see if the document is ready 491 var toplevel = false; 492 493 try { 494 toplevel = window.frameElement == null; 495 } catch(e) {} 496 497 if ( document.documentElement.doScroll && toplevel ) { 498 doScrollCheck(); 499 } 500 } 501 }, 502 503 // See test/unit/core.js for details concerning isFunction. 504 // Since version 1.3, DOM methods and functions like alert 505 // aren't supported. They return false on IE (#2968). 506 isFunction: function( obj ) { 507 return jQuery.type(obj) === "function"; 508 }, 509 510 isArray: Array.isArray || function( obj ) { 511 return jQuery.type(obj) === "array"; 512 }, 513 514 // A crude way of determining if an object is a window 515 isWindow: function( obj ) { 516 return obj && typeof obj === "object" && "setInterval" in obj; 517 }, 518 519 isNaN: function( obj ) { 520 return obj == null || !rdigit.test( obj ) || isNaN( obj ); 521 }, 522 523 type: function( obj ) { 524 return obj == null ? 525 String( obj ) : 526 class2type[ toString.call(obj) ] || "object"; 527 }, 528 529 isPlainObject: function( obj ) { 530 // Must be an Object. 531 // Because of IE, we also have to check the presence of the constructor property. 532 // Make sure that DOM nodes and window objects don't pass through, as well 533 if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { 534 return false; 535 } 536 537 // Not own constructor property must be Object 538 if ( obj.constructor && 539 !hasOwn.call(obj, "constructor") && 540 !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { 541 return false; 542 } 543 544 // Own properties are enumerated firstly, so to speed up, 545 // if last one is own, then all properties are own. 546 547 var key; 548 for ( key in obj ) {} 549 550 return key === undefined || hasOwn.call( obj, key ); 551 }, 552 553 isEmptyObject: function( obj ) { 554 for ( var name in obj ) { 555 return false; 556 } 557 return true; 558 }, 559 560 error: function( msg ) { 561 throw msg; 562 }, 563 564 parseJSON: function( data ) { 565 if ( typeof data !== "string" || !data ) { 566 return null; 567 } 568 569 // Make sure leading/trailing whitespace is removed (IE can't handle it) 570 data = jQuery.trim( data ); 571 572 // Make sure the incoming data is actual JSON 573 // Logic borrowed from http://json.org/json2.js 574 if ( rvalidchars.test(data.replace(rvalidescape, "@") 575 .replace(rvalidtokens, "]") 576 .replace(rvalidbraces, "")) ) { 577 578 // Try to use the native JSON parser first 579 return window.JSON && window.JSON.parse ? 580 window.JSON.parse( data ) : 581 (new Function("return " + data))(); 582 583 } else { 584 jQuery.error( "Invalid JSON: " + data ); 585 } 586 }, 587 588 noop: function() {}, 589 590 // Evalulates a script in a global context 591 globalEval: function( data ) { 592 if ( data && rnotwhite.test(data) ) { 593 // Inspired by code by Andrea Giammarchi 594 // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html 595 var head = document.getElementsByTagName("head")[0] || document.documentElement, 596 script = document.createElement("script"); 597 598 script.type = "text/javascript"; 599 600 if ( jQuery.support.scriptEval ) { 601 script.appendChild( document.createTextNode( data ) ); 602 } else { 603 script.text = data; 604 } 605 606 // Use insertBefore instead of appendChild to circumvent an IE6 bug. 607 // This arises when a base node is used (#2709). 608 head.insertBefore( script, head.firstChild ); 609 head.removeChild( script ); 610 } 611 }, 612 613 nodeName: function( elem, name ) { 614 return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase(); 615 }, 616 617 // args is for internal usage only 618 each: function( object, callback, args ) { 619 var name, i = 0, 620 length = object.length, 621 isObj = length === undefined || jQuery.isFunction(object); 622 623 if ( args ) { 624 if ( isObj ) { 625 for ( name in object ) { 626 if ( callback.apply( object[ name ], args ) === false ) { 627 break; 628 } 629 } 630 } else { 631 for ( ; i < length; ) { 632 if ( callback.apply( object[ i++ ], args ) === false ) { 633 break; 634 } 635 } 636 } 637 638 // A special, fast, case for the most common use of each 639 } else { 640 if ( isObj ) { 641 for ( name in object ) { 642 if ( callback.call( object[ name ], name, object[ name ] ) === false ) { 643 break; 644 } 645 } 646 } else { 647 for ( var value = object[0]; 648 i < length && callback.call( value, i, value ) !== false; value = object[++i] ) {} 649 } 650 } 651 652 return object; 653 }, 654 655 // Use native String.trim function wherever possible 656 trim: trim ? 657 function( text ) { 658 return text == null ? 659 "" : 660 trim.call( text ); 661 } : 662 663 // Otherwise use our own trimming functionality 664 function( text ) { 665 return text == null ? 666 "" : 667 text.toString().replace( trimLeft, "" ).replace( trimRight, "" ); 668 }, 669 670 // results is for internal usage only 671 makeArray: function( array, results ) { 672 var ret = results || []; 673 674 if ( array != null ) { 675 // The window, strings (and functions) also have 'length' 676 // The extra typeof function check is to prevent crashes 677 // in Safari 2 (See: #3039) 678 // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930 679 var type = jQuery.type(array); 680 681 if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) { 682 push.call( ret, array ); 683 } else { 684 jQuery.merge( ret, array ); 685 } 686 } 687 688 return ret; 689 }, 690 691 inArray: function( elem, array ) { 692 if ( array.indexOf ) { 693 return array.indexOf( elem ); 694 } 695 696 for ( var i = 0, length = array.length; i < length; i++ ) { 697 if ( array[ i ] === elem ) { 698 return i; 699 } 700 } 701 702 return -1; 703 }, 704 705 merge: function( first, second ) { 706 var i = first.length, 707 j = 0; 708 709 if ( typeof second.length === "number" ) { 710 for ( var l = second.length; j < l; j++ ) { 711 first[ i++ ] = second[ j ]; 712 } 713 714 } else { 715 while ( second[j] !== undefined ) { 716 first[ i++ ] = second[ j++ ]; 717 } 718 } 719 720 first.length = i; 721 722 return first; 723 }, 724 725 grep: function( elems, callback, inv ) { 726 var ret = [], retVal; 727 inv = !!inv; 728 729 // Go through the array, only saving the items 730 // that pass the validator function 731 for ( var i = 0, length = elems.length; i < length; i++ ) { 732 retVal = !!callback( elems[ i ], i ); 733 if ( inv !== retVal ) { 734 ret.push( elems[ i ] ); 735 } 736 } 737 738 return ret; 739 }, 740 741 // arg is for internal usage only 742 map: function( elems, callback, arg ) { 743 var ret = [], value; 744 745 // Go through the array, translating each of the items to their 746 // new value (or values). 747 for ( var i = 0, length = elems.length; i < length; i++ ) { 748 value = callback( elems[ i ], i, arg ); 749 750 if ( value != null ) { 751 ret[ ret.length ] = value; 752 } 753 } 754 755 return ret.concat.apply( [], ret ); 756 }, 757 758 // A global GUID counter for objects 759 guid: 1, 760 761 proxy: function( fn, proxy, thisObject ) { 762 if ( arguments.length === 2 ) { 763 if ( typeof proxy === "string" ) { 764 thisObject = fn; 765 fn = thisObject[ proxy ]; 766 proxy = undefined; 767 768 } else if ( proxy && !jQuery.isFunction( proxy ) ) { 769 thisObject = proxy; 770 proxy = undefined; 771 } 772 } 773 774 if ( !proxy && fn ) { 775 proxy = function() { 776 return fn.apply( thisObject || this, arguments ); 777 }; 778 } 779 780 // Set the guid of unique handler to the same of original handler, so it can be removed 781 if ( fn ) { 782 proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++; 783 } 784 785 // So proxy can be declared as an argument 786 return proxy; 787 }, 788 789 // Mutifunctional method to get and set values to a collection 790 // The value/s can be optionally by executed if its a function 791 access: function( elems, key, value, exec, fn, pass ) { 792 var length = elems.length; 793 794 // Setting many attributes 795 if ( typeof key === "object" ) { 796 for ( var k in key ) { 797 jQuery.access( elems, k, key[k], exec, fn, value ); 798 } 799 return elems; 800 } 801 802 // Setting one attribute 803 if ( value !== undefined ) { 804 // Optionally, function values get executed if exec is true 805 exec = !pass && exec && jQuery.isFunction(value); 806 807 for ( var i = 0; i < length; i++ ) { 808 fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass ); 809 } 810 811 return elems; 812 } 813 814 // Getting an attribute 815 return length ? fn( elems[0], key ) : undefined; 816 }, 817 818 now: function() { 819 return (new Date()).getTime(); 820 }, 821 822 // Use of jQuery.browser is frowned upon. 823 // More details: http://docs.jquery.com/Utilities/jQuery.browser 824 uaMatch: function( ua ) { 825 ua = ua.toLowerCase(); 826 827 var match = rwebkit.exec( ua ) || 828 ropera.exec( ua ) || 829 rmsie.exec( ua ) || 830 ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) || 831 []; 832 833 return { browser: match[1] || "", version: match[2] || "0" }; 834 }, 835 836 browser: {} 837 }); 838 839 // Populate the class2type map 840 jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) { 841 class2type[ "[object " + name + "]" ] = name.toLowerCase(); 842 }); 843 844 browserMatch = jQuery.uaMatch( userAgent ); 845 if ( browserMatch.browser ) { 846 jQuery.browser[ browserMatch.browser ] = true; 847 jQuery.browser.version = browserMatch.version; 848 } 849 850 // Deprecated, use jQuery.browser.webkit instead 851 if ( jQuery.browser.webkit ) { 852 jQuery.browser.safari = true; 853 } 854 855 if ( indexOf ) { 856 jQuery.inArray = function( elem, array ) { 857 return indexOf.call( array, elem ); 858 }; 859 } 860 861 // Verify that \s matches non-breaking spaces 862 // (IE fails on this test) 863 if ( !rwhite.test( "\xA0" ) ) { 864 trimLeft = /^[\s\xA0]+/; 865 trimRight = /[\s\xA0]+$/; 866 } 867 868 // All jQuery objects should point back to these 869 rootjQuery = jQuery(document); 870 871 // Cleanup functions for the document ready method 872 if ( document.addEventListener ) { 873 DOMContentLoaded = function() { 874 document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false ); 875 jQuery.ready(); 876 }; 877 878 } else if ( document.attachEvent ) { 879 DOMContentLoaded = function() { 880 // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). 881 if ( document.readyState === "complete" ) { 882 document.detachEvent( "onreadystatechange", DOMContentLoaded ); 883 jQuery.ready(); 884 } 885 }; 886 } 887 888 // The DOM ready check for Internet Explorer 889 function doScrollCheck() { 890 if ( jQuery.isReady ) { 891 return; 892 } 893 894 try { 895 // If IE is used, use the trick by Diego Perini 896 // http://javascript.nwbox.com/IEContentLoaded/ 897 document.documentElement.doScroll("left"); 898 } catch(e) { 899 setTimeout( doScrollCheck, 1 ); 900 return; 901 } 902 903 // and execute any waiting functions 904 jQuery.ready(); 905 } 906 907 // Expose jQuery to the global object 908 return (window.jQuery = window.$ = jQuery); 909 910 })(); 911 912 913 (function() { 914 915 jQuery.support = {}; 916 917 var root = document.documentElement, 918 script = document.createElement("script"), 919 div = document.createElement("div"), 920 id = "script" + jQuery.now(); 921 922 div.style.display = "none"; 923 div.innerHTML = " <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>"; 924 925 var all = div.getElementsByTagName("*"), 926 a = div.getElementsByTagName("a")[0], 927 select = document.createElement("select"), 928 opt = select.appendChild( document.createElement("option") ); 929 930 // Can't get basic test support 931 if ( !all || !all.length || !a ) { 932 return; 933 } 934 935 jQuery.support = { 936 // IE strips leading whitespace when .innerHTML is used 937 leadingWhitespace: div.firstChild.nodeType === 3, 938 939 // Make sure that tbody elements aren't automatically inserted 940 // IE will insert them into empty tables 941 tbody: !div.getElementsByTagName("tbody").length, 942 943 // Make sure that link elements get serialized correctly by innerHTML 944 // This requires a wrapper element in IE 945 htmlSerialize: !!div.getElementsByTagName("link").length, 946 947 // Get the style information from getAttribute 948 // (IE uses .cssText insted) 949 style: /red/.test( a.getAttribute("style") ), 950 951 // Make sure that URLs aren't manipulated 952 // (IE normalizes it by default) 953 hrefNormalized: a.getAttribute("href") === "/a", 954 955 // Make sure that element opacity exists 956 // (IE uses filter instead) 957 // Use a regex to work around a WebKit issue. See #5145 958 opacity: /^0.55$/.test( a.style.opacity ), 959 960 // Verify style float existence 961 // (IE uses styleFloat instead of cssFloat) 962 cssFloat: !!a.style.cssFloat, 963 964 // Make sure that if no value is specified for a checkbox 965 // that it defaults to "on". 966 // (WebKit defaults to "" instead) 967 checkOn: div.getElementsByTagName("input")[0].value === "on", 968 969 // Make sure that a selected-by-default option has a working selected property. 970 // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) 971 optSelected: opt.selected, 972 973 // Will be defined later 974 deleteExpando: true, 975 optDisabled: false, 976 checkClone: false, 977 scriptEval: false, 978 noCloneEvent: true, 979 boxModel: null, 980 inlineBlockNeedsLayout: false, 981 shrinkWrapBlocks: false, 982 reliableHiddenOffsets: true 983 }; 984 985 // Make sure that the options inside disabled selects aren't marked as disabled 986 // (WebKit marks them as diabled) 987 select.disabled = true; 988 jQuery.support.optDisabled = !opt.disabled; 989 990 script.type = "text/javascript"; 991 try { 992 script.appendChild( document.createTextNode( "window." + id + "=1;" ) ); 993 } catch(e) {} 994 995 root.insertBefore( script, root.firstChild ); 996 997 // Make sure that the execution of code works by injecting a script 998 // tag with appendChild/createTextNode 999 // (IE doesn't support this, fails, and uses .text instead) 1000 if ( window[ id ] ) { 1001 jQuery.support.scriptEval = true; 1002 delete window[ id ]; 1003 } 1004 1005 // Test to see if it's possible to delete an expando from an element 1006 // Fails in Internet Explorer 1007 try { 1008 delete script.test; 1009 1010 } catch(e) { 1011 jQuery.support.deleteExpando = false; 1012 } 1013 1014 root.removeChild( script ); 1015 1016 if ( div.attachEvent && div.fireEvent ) { 1017 div.attachEvent("onclick", function click() { 1018 // Cloning a node shouldn't copy over any 1019 // bound event handlers (IE does this) 1020 jQuery.support.noCloneEvent = false; 1021 div.detachEvent("onclick", click); 1022 }); 1023 div.cloneNode(true).fireEvent("onclick"); 1024 } 1025 1026 div = document.createElement("div"); 1027 div.innerHTML = "<input type='radio' name='radiotest' checked='checked'/>"; 1028 1029 var fragment = document.createDocumentFragment(); 1030 fragment.appendChild( div.firstChild ); 1031 1032 // WebKit doesn't clone checked state correctly in fragments 1033 jQuery.support.checkClone = fragment.cloneNode(true).cloneNode(true).lastChild.checked; 1034 1035 // Figure out if the W3C box model works as expected 1036 // document.body must exist before we can do this 1037 jQuery(function() { 1038 var div = document.createElement("div"); 1039 div.style.width = div.style.paddingLeft = "1px"; 1040 1041 document.body.appendChild( div ); 1042 jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2; 1043 1044 if ( "zoom" in div.style ) { 1045 // Check if natively block-level elements act like inline-block 1046 // elements when setting their display to 'inline' and giving 1047 // them layout 1048 // (IE < 8 does this) 1049 div.style.display = "inline"; 1050 div.style.zoom = 1; 1051 jQuery.support.inlineBlockNeedsLayout = div.offsetWidth === 2; 1052 1053 // Check if elements with layout shrink-wrap their children 1054 // (IE 6 does this) 1055 div.style.display = ""; 1056 div.innerHTML = "<div style='width:4px;'></div>"; 1057 jQuery.support.shrinkWrapBlocks = div.offsetWidth !== 2; 1058 } 1059 1060 div.innerHTML = "<table><tr><td style='padding:0;display:none'></td><td>t</td></tr></table>"; 1061 var tds = div.getElementsByTagName("td"); 1062 1063 // Check if table cells still have offsetWidth/Height when they are set 1064 // to display:none and there are still other visible table cells in a 1065 // table row; if so, offsetWidth/Height are not reliable for use when 1066 // determining if an element has been hidden directly using 1067 // display:none (it is still safe to use offsets if a parent element is 1068 // hidden; don safety goggles and see bug #4512 for more information). 1069 // (only IE 8 fails this test) 1070 jQuery.support.reliableHiddenOffsets = tds[0].offsetHeight === 0; 1071 1072 tds[0].style.display = ""; 1073 tds[1].style.display = "none"; 1074 1075 // Check if empty table cells still have offsetWidth/Height 1076 // (IE < 8 fail this test) 1077 jQuery.support.reliableHiddenOffsets = jQuery.support.reliableHiddenOffsets && tds[0].offsetHeight === 0; 1078 div.innerHTML = ""; 1079 1080 document.body.removeChild( div ).style.display = "none"; 1081 div = tds = null; 1082 }); 1083 1084 // Technique from Juriy Zaytsev 1085 // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/ 1086 var eventSupported = function( eventName ) { 1087 var el = document.createElement("div"); 1088 eventName = "on" + eventName; 1089 1090 var isSupported = (eventName in el); 1091 if ( !isSupported ) { 1092 el.setAttribute(eventName, "return;"); 1093 isSupported = typeof el[eventName] === "function"; 1094 } 1095 el = null; 1096 1097 return isSupported; 1098 }; 1099 1100 jQuery.support.submitBubbles = eventSupported("submit"); 1101 jQuery.support.changeBubbles = eventSupported("change"); 1102 1103 // release memory in IE 1104 root = script = div = all = a = null; 1105 })(); 1106 1107 1108 1109 var windowData = {}, 1110 rbrace = /^(?:\{.*\}|\[.*\])$/; 1111 1112 jQuery.extend({ 1113 cache: {}, 1114 1115 // Please use with caution 1116 uuid: 0, 1117 1118 // Unique for each copy of jQuery on the page 1119 expando: "jQuery" + jQuery.now(), 1120 1121 // The following elements throw uncatchable exceptions if you 1122 // attempt to add expando properties to them. 1123 noData: { 1124 "embed": true, 1125 // Ban all objects except for Flash (which handle expandos) 1126 "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000", 1127 "applet": true 1128 }, 1129 1130 data: function( elem, name, data ) { 1131 if ( !jQuery.acceptData( elem ) ) { 1132 return; 1133 } 1134 1135 elem = elem == window ? 1136 windowData : 1137 elem; 1138 1139 var isNode = elem.nodeType, 1140 id = isNode ? elem[ jQuery.expando ] : null, 1141 cache = jQuery.cache, thisCache; 1142 1143 if ( isNode && !id && typeof name === "string" && data === undefined ) { 1144 return; 1145 } 1146 1147 // Get the data from the object directly 1148 if ( !isNode ) { 1149 cache = elem; 1150 1151 // Compute a unique ID for the element 1152 } else if ( !id ) { 1153 elem[ jQuery.expando ] = id = ++jQuery.uuid; 1154 } 1155 1156 // Avoid generating a new cache unless none exists and we 1157 // want to manipulate it. 1158 if ( typeof name === "object" ) { 1159 if ( isNode ) { 1160 cache[ id ] = jQuery.extend(cache[ id ], name); 1161 1162 } else { 1163 jQuery.extend( cache, name ); 1164 } 1165 1166 } else if ( isNode && !cache[ id ] ) { 1167 cache[ id ] = {}; 1168 } 1169 1170 thisCache = isNode ? cache[ id ] : cache; 1171 1172 // Prevent overriding the named cache with undefined values 1173 if ( data !== undefined ) { 1174 thisCache[ name ] = data; 1175 } 1176 1177 return typeof name === "string" ? thisCache[ name ] : thisCache; 1178 }, 1179 1180 removeData: function( elem, name ) { 1181 if ( !jQuery.acceptData( elem ) ) { 1182 return; 1183 } 1184 1185 elem = elem == window ? 1186 windowData : 1187 elem; 1188 1189 var isNode = elem.nodeType, 1190 id = isNode ? elem[ jQuery.expando ] : elem, 1191 cache = jQuery.cache, 1192 thisCache = isNode ? cache[ id ] : id; 1193 1194 // If we want to remove a specific section of the element's data 1195 if ( name ) { 1196 if ( thisCache ) { 1197 // Remove the section of cache data 1198 delete thisCache[ name ]; 1199 1200 // If we've removed all the data, remove the element's cache 1201 if ( isNode && jQuery.isEmptyObject(thisCache) ) { 1202 jQuery.removeData( elem ); 1203 } 1204 } 1205 1206 // Otherwise, we want to remove all of the element's data 1207 } else { 1208 if ( isNode && jQuery.support.deleteExpando ) { 1209 delete elem[ jQuery.expando ]; 1210 1211 } else if ( elem.removeAttribute ) { 1212 elem.removeAttribute( jQuery.expando ); 1213 1214 // Completely remove the data cache 1215 } else if ( isNode ) { 1216 delete cache[ id ]; 1217 1218 // Remove all fields from the object 1219 } else { 1220 for ( var n in elem ) { 1221 delete elem[ n ]; 1222 } 1223 } 1224 } 1225 }, 1226 1227 // A method for determining if a DOM node can handle the data expando 1228 acceptData: function( elem ) { 1229 if ( elem.nodeName ) { 1230 var match = jQuery.noData[ elem.nodeName.toLowerCase() ]; 1231 1232 if ( match ) { 1233 return !(match === true || elem.getAttribute("classid") !== match); 1234 } 1235 } 1236 1237 return true; 1238 } 1239 }); 1240 1241 jQuery.fn.extend({ 1242 data: function( key, value ) { 1243 var data = null; 1244 1245 if ( typeof key === "undefined" ) { 1246 if ( this.length ) { 1247 var attr = this[0].attributes, name; 1248 data = jQuery.data( this[0] ); 1249 1250 for ( var i = 0, l = attr.length; i < l; i++ ) { 1251 name = attr[i].name; 1252 1253 if ( name.indexOf( "data-" ) === 0 ) { 1254 name = name.substr( 5 ); 1255 dataAttr( this[0], name, data[ name ] ); 1256 } 1257 } 1258 } 1259 1260 return data; 1261 1262 } else if ( typeof key === "object" ) { 1263 return this.each(function() { 1264 jQuery.data( this, key ); 1265 }); 1266 } 1267 1268 var parts = key.split("."); 1269 parts[1] = parts[1] ? "." + parts[1] : ""; 1270 1271 if ( value === undefined ) { 1272 data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]); 1273 1274 // Try to fetch any internally stored data first 1275 if ( data === undefined && this.length ) { 1276 data = jQuery.data( this[0], key ); 1277 data = dataAttr( this[0], key, data ); 1278 } 1279 1280 return data === undefined && parts[1] ? 1281 this.data( parts[0] ) : 1282 data; 1283 1284 } else { 1285 return this.each(function() { 1286 var $this = jQuery( this ), 1287 args = [ parts[0], value ]; 1288 1289 $this.triggerHandler( "setData" + parts[1] + "!", args ); 1290 jQuery.data( this, key, value ); 1291 $this.triggerHandler( "changeData" + parts[1] + "!", args ); 1292 }); 1293 } 1294 }, 1295 1296 removeData: function( key ) { 1297 return this.each(function() { 1298 jQuery.removeData( this, key ); 1299 }); 1300 } 1301 }); 1302 1303 function dataAttr( elem, key, data ) { 1304 // If nothing was found internally, try to fetch any 1305 // data from the HTML5 data-* attribute 1306 if ( data === undefined && elem.nodeType === 1 ) { 1307 data = elem.getAttribute( "data-" + key ); 1308 1309 if ( typeof data === "string" ) { 1310 try { 1311 data = data === "true" ? true : 1312 data === "false" ? false : 1313 data === "null" ? null : 1314 !jQuery.isNaN( data ) ? parseFloat( data ) : 1315 rbrace.test( data ) ? jQuery.parseJSON( data ) : 1316 data; 1317 } catch( e ) {} 1318 1319 // Make sure we set the data so it isn't changed later 1320 jQuery.data( elem, key, data ); 1321 1322 } else { 1323 data = undefined; 1324 } 1325 } 1326 1327 return data; 1328 } 1329 1330 1331 1332 1333 jQuery.extend({ 1334 queue: function( elem, type, data ) { 1335 if ( !elem ) { 1336 return; 1337 } 1338 1339 type = (type || "fx") + "queue"; 1340 var q = jQuery.data( elem, type ); 1341 1342 // Speed up dequeue by getting out quickly if this is just a lookup 1343 if ( !data ) { 1344 return q || []; 1345 } 1346 1347 if ( !q || jQuery.isArray(data) ) { 1348 q = jQuery.data( elem, type, jQuery.makeArray(data) ); 1349 1350 } else { 1351 q.push( data ); 1352 } 1353 1354 return q; 1355 }, 1356 1357 dequeue: function( elem, type ) { 1358 type = type || "fx"; 1359 1360 var queue = jQuery.queue( elem, type ), 1361 fn = queue.shift(); 1362 1363 // If the fx queue is dequeued, always remove the progress sentinel 1364 if ( fn === "inprogress" ) { 1365 fn = queue.shift(); 1366 } 1367 1368 if ( fn ) { 1369 // Add a progress sentinel to prevent the fx queue from being 1370 // automatically dequeued 1371 if ( type === "fx" ) { 1372 queue.unshift("inprogress"); 1373 } 1374 1375 fn.call(elem, function() { 1376 jQuery.dequeue(elem, type); 1377 }); 1378 } 1379 } 1380 }); 1381 1382 jQuery.fn.extend({ 1383 queue: function( type, data ) { 1384 if ( typeof type !== "string" ) { 1385 data = type; 1386 type = "fx"; 1387 } 1388 1389 if ( data === undefined ) { 1390 return jQuery.queue( this[0], type ); 1391 } 1392 return this.each(function( i ) { 1393 var queue = jQuery.queue( this, type, data ); 1394 1395 if ( type === "fx" && queue[0] !== "inprogress" ) { 1396 jQuery.dequeue( this, type ); 1397 } 1398 }); 1399 }, 1400 dequeue: function( type ) { 1401 return this.each(function() { 1402 jQuery.dequeue( this, type ); 1403 }); 1404 }, 1405 1406 // Based off of the plugin by Clint Helfers, with permission. 1407 // http://blindsignals.com/index.php/2009/07/jquery-delay/ 1408 delay: function( time, type ) { 1409 time = jQuery.fx ? jQuery.fx.speeds[time] || time : time; 1410 type = type || "fx"; 1411 1412 return this.queue( type, function() { 1413 var elem = this; 1414 setTimeout(function() { 1415 jQuery.dequeue( elem, type ); 1416 }, time ); 1417 }); 1418 }, 1419 1420 clearQueue: function( type ) { 1421 return this.queue( type || "fx", [] ); 1422 } 1423 }); 1424 1425 1426 1427 1428 var rclass = /[\n\t]/g, 1429 rspaces = /\s+/, 1430 rreturn = /\r/g, 1431 rspecialurl = /^(?:href|src|style)$/, 1432 rtype = /^(?:button|input)$/i, 1433 rfocusable = /^(?:button|input|object|select|textarea)$/i, 1434 rclickable = /^a(?:rea)?$/i, 1435 rradiocheck = /^(?:radio|checkbox)$/i; 1436 1437 jQuery.props = { 1438 "for": "htmlFor", 1439 "class": "className", 1440 readonly: "readOnly", 1441 maxlength: "maxLength", 1442 cellspacing: "cellSpacing", 1443 rowspan: "rowSpan", 1444 colspan: "colSpan", 1445 tabindex: "tabIndex", 1446 usemap: "useMap", 1447 frameborder: "frameBorder" 1448 }; 1449 1450 jQuery.fn.extend({ 1451 attr: function( name, value ) { 1452 return jQuery.access( this, name, value, true, jQuery.attr ); 1453 }, 1454 1455 removeAttr: function( name, fn ) { 1456 return this.each(function(){ 1457 jQuery.attr( this, name, "" ); 1458 if ( this.nodeType === 1 ) { 1459 this.removeAttribute( name ); 1460 } 1461 }); 1462 }, 1463 1464 addClass: function( value ) { 1465 if ( jQuery.isFunction(value) ) { 1466 return this.each(function(i) { 1467 var self = jQuery(this); 1468 self.addClass( value.call(this, i, self.attr("class")) ); 1469 }); 1470 } 1471 1472 if ( value && typeof value === "string" ) { 1473 var classNames = (value || "").split( rspaces ); 1474 1475 for ( var i = 0, l = this.length; i < l; i++ ) { 1476 var elem = this[i]; 1477 1478 if ( elem.nodeType === 1 ) { 1479 if ( !elem.className ) { 1480 elem.className = value; 1481 1482 } else { 1483 var className = " " + elem.className + " ", 1484 setClass = elem.className; 1485 1486 for ( var c = 0, cl = classNames.length; c < cl; c++ ) { 1487 if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) { 1488 setClass += " " + classNames[c]; 1489 } 1490 } 1491 elem.className = jQuery.trim( setClass ); 1492 } 1493 } 1494 } 1495 } 1496 1497 return this; 1498 }, 1499 1500 removeClass: function( value ) { 1501 if ( jQuery.isFunction(value) ) { 1502 return this.each(function(i) { 1503 var self = jQuery(this); 1504 self.removeClass( value.call(this, i, self.attr("class")) ); 1505 }); 1506 } 1507 1508 if ( (value && typeof value === "string") || value === undefined ) { 1509 var classNames = (value || "").split( rspaces ); 1510 1511 for ( var i = 0, l = this.length; i < l; i++ ) { 1512 var elem = this[i]; 1513 1514 if ( elem.nodeType === 1 && elem.className ) { 1515 if ( value ) { 1516 var className = (" " + elem.className + " ").replace(rclass, " "); 1517 for ( var c = 0, cl = classNames.length; c < cl; c++ ) { 1518 className = className.replace(" " + classNames[c] + " ", " "); 1519 } 1520 elem.className = jQuery.trim( className ); 1521 1522 } else { 1523 elem.className = ""; 1524 } 1525 } 1526 } 1527 } 1528 1529 return this; 1530 }, 1531 1532 toggleClass: function( value, stateVal ) { 1533 var type = typeof value, 1534 isBool = typeof stateVal === "boolean"; 1535 1536 if ( jQuery.isFunction( value ) ) { 1537 return this.each(function(i) { 1538 var self = jQuery(this); 1539 self.toggleClass( value.call(this, i, self.attr("class"), stateVal), stateVal ); 1540 }); 1541 } 1542 1543 return this.each(function() { 1544 if ( type === "string" ) { 1545 // toggle individual class names 1546 var className, 1547 i = 0, 1548 self = jQuery( this ), 1549 state = stateVal, 1550 classNames = value.split( rspaces ); 1551 1552 while ( (className = classNames[ i++ ]) ) { 1553 // check each className given, space seperated list 1554 state = isBool ? state : !self.hasClass( className ); 1555 self[ state ? "addClass" : "removeClass" ]( className ); 1556 } 1557 1558 } else if ( type === "undefined" || type === "boolean" ) { 1559 if ( this.className ) { 1560 // store className if set 1561 jQuery.data( this, "__className__", this.className ); 1562 } 1563 1564 // toggle whole className 1565 this.className = this.className || value === false ? "" : jQuery.data( this, "__className__" ) || ""; 1566 } 1567 }); 1568 }, 1569 1570 hasClass: function( selector ) { 1571 var className = " " + selector + " "; 1572 for ( var i = 0, l = this.length; i < l; i++ ) { 1573 if ( (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) { 1574 return true; 1575 } 1576 } 1577 1578 return false; 1579 }, 1580 1581 val: function( value ) { 1582 if ( !arguments.length ) { 1583 var elem = this[0]; 1584 1585 if ( elem ) { 1586 if ( jQuery.nodeName( elem, "option" ) ) { 1587 // attributes.value is undefined in Blackberry 4.7 but 1588 // uses .value. See #6932 1589 var val = elem.attributes.value; 1590 return !val || val.specified ? elem.value : elem.text; 1591 } 1592 1593 // We need to handle select boxes special 1594 if ( jQuery.nodeName( elem, "select" ) ) { 1595 var index = elem.selectedIndex, 1596 values = [], 1597 options = elem.options, 1598 one = elem.type === "select-one"; 1599 1600 // Nothing was selected 1601 if ( index < 0 ) { 1602 return null; 1603 } 1604 1605 // Loop through all the selected options 1606 for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) { 1607 var option = options[ i ]; 1608 1609 // Don't return options that are disabled or in a disabled optgroup 1610 if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) && 1611 (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) { 1612 1613 // Get the specific value for the option 1614 value = jQuery(option).val(); 1615 1616 // We don't need an array for one selects 1617 if ( one ) { 1618 return value; 1619 } 1620 1621 // Multi-Selects return an array 1622 values.push( value ); 1623 } 1624 } 1625 1626 return values; 1627 } 1628 1629 // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified 1630 if ( rradiocheck.test( elem.type ) && !jQuery.support.checkOn ) { 1631 return elem.getAttribute("value") === null ? "on" : elem.value; 1632 } 1633 1634 1635 // Everything else, we just grab the value 1636 return (elem.value || "").replace(rreturn, ""); 1637 1638 } 1639 1640 return undefined; 1641 } 1642 1643 var isFunction = jQuery.isFunction(value); 1644 1645 return this.each(function(i) { 1646 var self = jQuery(this), val = value; 1647 1648 if ( this.nodeType !== 1 ) { 1649 return; 1650 } 1651 1652 if ( isFunction ) { 1653 val = value.call(this, i, self.val()); 1654 } 1655 1656 // Treat null/undefined as ""; convert numbers to string 1657 if ( val == null ) { 1658 val = ""; 1659 } else if ( typeof val === "number" ) { 1660 val += ""; 1661 } else if ( jQuery.isArray(val) ) { 1662 val = jQuery.map(val, function (value) { 1663 return value == null ? "" : value + ""; 1664 }); 1665 } 1666 1667 if ( jQuery.isArray(val) && rradiocheck.test( this.type ) ) { 1668 this.checked = jQuery.inArray( self.val(), val ) >= 0; 1669 1670 } else if ( jQuery.nodeName( this, "select" ) ) { 1671 var values = jQuery.makeArray(val); 1672 1673 jQuery( "option", this ).each(function() { 1674 this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0; 1675 }); 1676 1677 if ( !values.length ) { 1678 this.selectedIndex = -1; 1679 } 1680 1681 } else { 1682 this.value = val; 1683 } 1684 }); 1685 } 1686 }); 1687 1688 jQuery.extend({ 1689 attrFn: { 1690 val: true, 1691 css: true, 1692 html: true, 1693 text: true, 1694 data: true, 1695 width: true, 1696 height: true, 1697 offset: true 1698 }, 1699 1700 attr: function( elem, name, value, pass ) { 1701 // don't set attributes on text and comment nodes 1702 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) { 1703 return undefined; 1704 } 1705 1706 if ( pass && name in jQuery.attrFn ) { 1707 return jQuery(elem)[name](value); 1708 } 1709 1710 var notxml = elem.nodeType !== 1 || !jQuery.isXMLDoc( elem ), 1711 // Whether we are setting (or getting) 1712 set = value !== undefined; 1713 1714 // Try to normalize/fix the name 1715 name = notxml && jQuery.props[ name ] || name; 1716 1717 // These attributes require special treatment 1718 var special = rspecialurl.test( name ); 1719 1720 // Safari mis-reports the default selected property of an option 1721 // Accessing the parent's selectedIndex property fixes it 1722 if ( name === "selected" && !jQuery.support.optSelected ) { 1723 var parent = elem.parentNode; 1724 if ( parent ) { 1725 parent.selectedIndex; 1726 1727 // Make sure that it also works with optgroups, see #5701 1728 if ( parent.parentNode ) { 1729 parent.parentNode.selectedIndex; 1730 } 1731 } 1732 } 1733 1734 // If applicable, access the attribute via the DOM 0 way 1735 // 'in' checks fail in Blackberry 4.7 #6931 1736 if ( (name in elem || elem[ name ] !== undefined) && notxml && !special ) { 1737 if ( set ) { 1738 // We can't allow the type property to be changed (since it causes problems in IE) 1739 if ( name === "type" && rtype.test( elem.nodeName ) && elem.parentNode ) { 1740 jQuery.error( "type property can't be changed" ); 1741 } 1742 1743 if ( value === null ) { 1744 if ( elem.nodeType === 1 ) { 1745 elem.removeAttribute( name ); 1746 } 1747 1748 } else { 1749 elem[ name ] = value; 1750 } 1751 } 1752 1753 // browsers index elements by id/name on forms, give priority to attributes. 1754 if ( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) ) { 1755 return elem.getAttributeNode( name ).nodeValue; 1756 } 1757 1758 // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set 1759 // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ 1760 if ( name === "tabIndex" ) { 1761 var attributeNode = elem.getAttributeNode( "tabIndex" ); 1762 1763 return attributeNode && attributeNode.specified ? 1764 attributeNode.value : 1765 rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? 1766 0 : 1767 undefined; 1768 } 1769 1770 return elem[ name ]; 1771 } 1772 1773 if ( !jQuery.support.style && notxml && name === "style" ) { 1774 if ( set ) { 1775 elem.style.cssText = "" + value; 1776 } 1777 1778 return elem.style.cssText; 1779 } 1780 1781 if ( set ) { 1782 // convert the value to a string (all browsers do this but IE) see #1070 1783 elem.setAttribute( name, "" + value ); 1784 } 1785 1786 // Ensure that missing attributes return undefined 1787 // Blackberry 4.7 returns "" from getAttribute #6938 1788 if ( !elem.attributes[ name ] && (elem.hasAttribute && !elem.hasAttribute( name )) ) { 1789 return undefined; 1790 } 1791 1792 var attr = !jQuery.support.hrefNormalized && notxml && special ? 1793 // Some attributes require a special call on IE 1794 elem.getAttribute( name, 2 ) : 1795 elem.getAttribute( name ); 1796 1797 // Non-existent attributes return null, we normalize to undefined 1798 return attr === null ? undefined : attr; 1799 } 1800 }); 1801 1802 1803 1804 1805 var rnamespaces = /\.(.*)$/, 1806 rformElems = /^(?:textarea|input|select)$/i, 1807 rperiod = /\./g, 1808 rspace = / /g, 1809 rescape = /[^\w\s.|`]/g, 1810 fcleanup = function( nm ) { 1811 return nm.replace(rescape, "\\$&"); 1812 }, 1813 focusCounts = { focusin: 0, focusout: 0 }; 1814 1815 /* 1816 * A number of helper functions used for managing events. 1817 * Many of the ideas behind this code originated from 1818 * Dean Edwards' addEvent library. 1819 */ 1820 jQuery.event = { 1821 1822 // Bind an event to an element 1823 // Original by Dean Edwards 1824 add: function( elem, types, handler, data ) { 1825 if ( elem.nodeType === 3 || elem.nodeType === 8 ) { 1826 return; 1827 } 1828 1829 // For whatever reason, IE has trouble passing the window object 1830 // around, causing it to be cloned in the process 1831 if ( jQuery.isWindow( elem ) && ( elem !== window && !elem.frameElement ) ) { 1832 elem = window; 1833 } 1834 1835 if ( handler === false ) { 1836 handler = returnFalse; 1837 } else if ( !handler ) { 1838 // Fixes bug #7229. Fix recommended by jdalton 1839 return; 1840 } 1841 1842 var handleObjIn, handleObj; 1843 1844 if ( handler.handler ) { 1845 handleObjIn = handler; 1846 handler = handleObjIn.handler; 1847 } 1848 1849 // Make sure that the function being executed has a unique ID 1850 if ( !handler.guid ) { 1851 handler.guid = jQuery.guid++; 1852 } 1853 1854 // Init the element's event structure 1855 var elemData = jQuery.data( elem ); 1856 1857 // If no elemData is found then we must be trying to bind to one of the 1858 // banned noData elements 1859 if ( !elemData ) { 1860 return; 1861 } 1862 1863 // Use a key less likely to result in collisions for plain JS objects. 1864 // Fixes bug #7150. 1865 var eventKey = elem.nodeType ? "events" : "__events__", 1866 events = elemData[ eventKey ], 1867 eventHandle = elemData.handle; 1868 1869 if ( typeof events === "function" ) { 1870 // On plain objects events is a fn that holds the the data 1871 // which prevents this data from being JSON serialized 1872 // the function does not need to be called, it just contains the data 1873 eventHandle = events.handle; 1874 events = events.events; 1875 1876 } else if ( !events ) { 1877 if ( !elem.nodeType ) { 1878 // On plain objects, create a fn that acts as the holder 1879 // of the values to avoid JSON serialization of event data 1880 elemData[ eventKey ] = elemData = function(){}; 1881 } 1882 1883 elemData.events = events = {}; 1884 } 1885 1886 if ( !eventHandle ) { 1887 elemData.handle = eventHandle = function() { 1888 // Handle the second event of a trigger and when 1889 // an event is called after a page has unloaded 1890 return typeof jQuery !== "undefined" && !jQuery.event.triggered ? 1891 jQuery.event.handle.apply( eventHandle.elem, arguments ) : 1892 undefined; 1893 }; 1894 } 1895 1896 // Add elem as a property of the handle function 1897 // This is to prevent a memory leak with non-native events in IE. 1898 eventHandle.elem = elem; 1899 1900 // Handle multiple events separated by a space 1901 // jQuery(...).bind("mouseover mouseout", fn); 1902 types = types.split(" "); 1903 1904 var type, i = 0, namespaces; 1905 1906 while ( (type = types[ i++ ]) ) { 1907 handleObj = handleObjIn ? 1908 jQuery.extend({}, handleObjIn) : 1909 { handler: handler, data: data }; 1910 1911 // Namespaced event handlers 1912 if ( type.indexOf(".") > -1 ) { 1913 namespaces = type.split("."); 1914 type = namespaces.shift(); 1915 handleObj.namespace = namespaces.slice(0).sort().join("."); 1916 1917 } else { 1918 namespaces = []; 1919 handleObj.namespace = ""; 1920 } 1921 1922 handleObj.type = type; 1923 if ( !handleObj.guid ) { 1924 handleObj.guid = handler.guid; 1925 } 1926 1927 // Get the current list of functions bound to this event 1928 var handlers = events[ type ], 1929 special = jQuery.event.special[ type ] || {}; 1930 1931 // Init the event handler queue 1932 if ( !handlers ) { 1933 handlers = events[ type ] = []; 1934 1935 // Check for a special event handler 1936 // Only use addEventListener/attachEvent if the special 1937 // events handler returns false 1938 if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { 1939 // Bind the global event handler to the element 1940 if ( elem.addEventListener ) { 1941 elem.addEventListener( type, eventHandle, false ); 1942 1943 } else if ( elem.attachEvent ) { 1944 elem.attachEvent( "on" + type, eventHandle ); 1945 } 1946 } 1947 } 1948 1949 if ( special.add ) { 1950 special.add.call( elem, handleObj ); 1951 1952 if ( !handleObj.handler.guid ) { 1953 handleObj.handler.guid = handler.guid; 1954 } 1955 } 1956 1957 // Add the function to the element's handler list 1958 handlers.push( handleObj ); 1959 1960 // Keep track of which events have been used, for global triggering 1961 jQuery.event.global[ type ] = true; 1962 } 1963 1964 // Nullify elem to prevent memory leaks in IE 1965 elem = null; 1966 }, 1967 1968 global: {}, 1969 1970 // Detach an event or set of events from an element 1971 remove: function( elem, types, handler, pos ) { 1972 // don't do events on text and comment nodes 1973 if ( elem.nodeType === 3 || elem.nodeType === 8 ) { 1974 return; 1975 } 1976 1977 if ( handler === false ) { 1978 handler = returnFalse; 1979 } 1980 1981 var ret, type, fn, j, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType, 1982 eventKey = elem.nodeType ? "events" : "__events__", 1983 elemData = jQuery.data( elem ), 1984 events = elemData && elemData[ eventKey ]; 1985 1986 if ( !elemData || !events ) { 1987 return; 1988 } 1989 1990 if ( typeof events === "function" ) { 1991 elemData = events; 1992 events = events.events; 1993 } 1994 1995 // types is actually an event object here 1996 if ( types && types.type ) { 1997 handler = types.handler; 1998 types = types.type; 1999 } 2000 2001 // Unbind all events for the element 2002 if ( !types || typeof types === "string" && types.charAt(0) === "." ) { 2003 types = types || ""; 2004 2005 for ( type in events ) { 2006 jQuery.event.remove( elem, type + types ); 2007 } 2008 2009 return; 2010 } 2011 2012 // Handle multiple events separated by a space 2013 // jQuery(...).unbind("mouseover mouseout", fn); 2014 types = types.split(" "); 2015 2016 while ( (type = types[ i++ ]) ) { 2017 origType = type; 2018 handleObj = null; 2019 all = type.indexOf(".") < 0; 2020 namespaces = []; 2021 2022 if ( !all ) { 2023 // Namespaced event handlers 2024 namespaces = type.split("."); 2025 type = namespaces.shift(); 2026 2027 namespace = new RegExp("(^|\\.)" + 2028 jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)"); 2029 } 2030 2031 eventType = events[ type ]; 2032 2033 if ( !eventType ) { 2034 continue; 2035 } 2036 2037 if ( !handler ) { 2038 for ( j = 0; j < eventType.length; j++ ) { 2039 handleObj = eventType[ j ]; 2040 2041 if ( all || namespace.test( handleObj.namespace ) ) { 2042 jQuery.event.remove( elem, origType, handleObj.handler, j ); 2043 eventType.splice( j--, 1 ); 2044 } 2045 } 2046 2047 continue; 2048 } 2049 2050 special = jQuery.event.special[ type ] || {}; 2051 2052 for ( j = pos || 0; j < eventType.length; j++ ) { 2053 handleObj = eventType[ j ]; 2054 2055 if ( handler.guid === handleObj.guid ) { 2056 // remove the given handler for the given type 2057 if ( all || namespace.test( handleObj.namespace ) ) { 2058 if ( pos == null ) { 2059 eventType.splice( j--, 1 ); 2060 } 2061 2062 if ( special.remove ) { 2063 special.remove.call( elem, handleObj ); 2064 } 2065 } 2066 2067 if ( pos != null ) { 2068 break; 2069 } 2070 } 2071 } 2072 2073 // remove generic event handler if no more handlers exist 2074 if ( eventType.length === 0 || pos != null && eventType.length === 1 ) { 2075 if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) { 2076 jQuery.removeEvent( elem, type, elemData.handle ); 2077 } 2078 2079 ret = null; 2080 delete events[ type ]; 2081 } 2082 } 2083 2084 // Remove the expando if it's no longer used 2085 if ( jQuery.isEmptyObject( events ) ) { 2086 var handle = elemData.handle; 2087 if ( handle ) { 2088 handle.elem = null; 2089 } 2090 2091 delete elemData.events; 2092 delete elemData.handle; 2093 2094 if ( typeof elemData === "function" ) { 2095 jQuery.removeData( elem, eventKey ); 2096 2097 } else if ( jQuery.isEmptyObject( elemData ) ) { 2098 jQuery.removeData( elem ); 2099 } 2100 } 2101 }, 2102 2103 // bubbling is internal 2104 trigger: function( event, data, elem /*, bubbling */ ) { 2105 // Event object or event type 2106 var type = event.type || event, 2107 bubbling = arguments[3]; 2108 2109 if ( !bubbling ) { 2110 event = typeof event === "object" ? 2111 // jQuery.Event object 2112 event[ jQuery.expando ] ? event : 2113 // Object literal 2114 jQuery.extend( jQuery.Event(type), event ) : 2115 // Just the event type (string) 2116 jQuery.Event(type); 2117 2118 if ( type.indexOf("!") >= 0 ) { 2119 event.type = type = type.slice(0, -1); 2120 event.exclusive = true; 2121 } 2122 2123 // Handle a global trigger 2124 if ( !elem ) { 2125 // Don't bubble custom events when global (to avoid too much overhead) 2126 event.stopPropagation(); 2127 2128 // Only trigger if we've ever bound an event for it 2129 if ( jQuery.event.global[ type ] ) { 2130 jQuery.each( jQuery.cache, function() { 2131 if ( this.events && this.events[type] ) { 2132 jQuery.event.trigger( event, data, this.handle.elem ); 2133 } 2134 }); 2135 } 2136 } 2137 2138 // Handle triggering a single element 2139 2140 // don't do events on text and comment nodes 2141 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) { 2142 return undefined; 2143 } 2144 2145 // Clean up in case it is reused 2146 event.result = undefined; 2147 event.target = elem; 2148 2149 // Clone the incoming data, if any 2150 data = jQuery.makeArray( data ); 2151 data.unshift( event ); 2152 } 2153 2154 event.currentTarget = elem; 2155 2156 // Trigger the event, it is assumed that "handle" is a function 2157 var handle = elem.nodeType ? 2158 jQuery.data( elem, "handle" ) : 2159 (jQuery.data( elem, "__events__" ) || {}).handle; 2160 2161 if ( handle ) { 2162 handle.apply( elem, data ); 2163 } 2164 2165 var parent = elem.parentNode || elem.ownerDocument; 2166 2167 // Trigger an inline bound script 2168 try { 2169 if ( !(elem && elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()]) ) { 2170 if ( elem[ "on" + type ] && elem[ "on" + type ].apply( elem, data ) === false ) { 2171 event.result = false; 2172 event.preventDefault(); 2173 } 2174 } 2175 2176 // prevent IE from throwing an error for some elements with some event types, see #3533 2177 } catch (inlineError) {} 2178 2179 if ( !event.isPropagationStopped() && parent ) { 2180 jQuery.event.trigger( event, data, parent, true ); 2181 2182 } else if ( !event.isDefaultPrevented() ) { 2183 var old, 2184 target = event.target, 2185 targetType = type.replace( rnamespaces, "" ), 2186 isClick = jQuery.nodeName( target, "a" ) && targetType === "click", 2187 special = jQuery.event.special[ targetType ] || {}; 2188 2189 if ( (!special._default || special._default.call( elem, event ) === false) && 2190 !isClick && !(target && target.nodeName && jQuery.noData[target.nodeName.toLowerCase()]) ) { 2191 2192 try { 2193 if ( target[ targetType ] ) { 2194 // Make sure that we don't accidentally re-trigger the onFOO events 2195 old = target[ "on" + targetType ]; 2196 2197 if ( old ) { 2198 target[ "on" + targetType ] = null; 2199 } 2200 2201 jQuery.event.triggered = true; 2202 target[ targetType ](); 2203 } 2204 2205 // prevent IE from throwing an error for some elements with some event types, see #3533 2206 } catch (triggerError) {} 2207 2208 if ( old ) { 2209 target[ "on" + targetType ] = old; 2210 } 2211 2212 jQuery.event.triggered = false; 2213 } 2214 } 2215 }, 2216 2217 handle: function( event ) { 2218 var all, handlers, namespaces, namespace_re, events, 2219 namespace_sort = [], 2220 args = jQuery.makeArray( arguments ); 2221 2222 event = args[0] = jQuery.event.fix( event || window.event ); 2223 event.currentTarget = this; 2224 2225 // Namespaced event handlers 2226 all = event.type.indexOf(".") < 0 && !event.exclusive; 2227 2228 if ( !all ) { 2229 namespaces = event.type.split("."); 2230 event.type = namespaces.shift(); 2231 namespace_sort = namespaces.slice(0).sort(); 2232 namespace_re = new RegExp("(^|\\.)" + namespace_sort.join("\\.(?:.*\\.)?") + "(\\.|$)"); 2233 } 2234 2235 event.namespace = event.namespace || namespace_sort.join("."); 2236 2237 events = jQuery.data(this, this.nodeType ? "events" : "__events__"); 2238 2239 if ( typeof events === "function" ) { 2240 events = events.events; 2241 } 2242 2243 handlers = (events || {})[ event.type ]; 2244 2245 if ( events && handlers ) { 2246 // Clone the handlers to prevent manipulation 2247 handlers = handlers.slice(0); 2248 2249 for ( var j = 0, l = handlers.length; j < l; j++ ) { 2250 var handleObj = handlers[ j ]; 2251 2252 // Filter the functions by class 2253 if ( all || namespace_re.test( handleObj.namespace ) ) { 2254 // Pass in a reference to the handler function itself 2255 // So that we can later remove it 2256 event.handler = handleObj.handler; 2257 event.data = handleObj.data; 2258 event.handleObj = handleObj; 2259 2260 var ret = handleObj.handler.apply( this, args ); 2261 2262 if ( ret !== undefined ) { 2263 event.result = ret; 2264 if ( ret === false ) { 2265 event.preventDefault(); 2266 event.stopPropagation(); 2267 } 2268 } 2269 2270 if ( event.isImmediatePropagationStopped() ) { 2271 break; 2272 } 2273 } 2274 } 2275 } 2276 2277 return event.result; 2278 }, 2279 2280 props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "), 2281 2282 fix: function( event ) { 2283 if ( event[ jQuery.expando ] ) { 2284 return event; 2285 } 2286 2287 // store a copy of the original event object 2288 // and "clone" to set read-only properties 2289 var originalEvent = event; 2290 event = jQuery.Event( originalEvent ); 2291 2292 for ( var i = this.props.length, prop; i; ) { 2293 prop = this.props[ --i ]; 2294 event[ prop ] = originalEvent[ prop ]; 2295 } 2296 2297 // Fix target property, if necessary 2298 if ( !event.target ) { 2299 // Fixes #1925 where srcElement might not be defined either 2300 event.target = event.srcElement || document; 2301 } 2302 2303 // check if target is a textnode (safari) 2304 if ( event.target.nodeType === 3 ) { 2305 event.target = event.target.parentNode; 2306 } 2307 2308 // Add relatedTarget, if necessary 2309 if ( !event.relatedTarget && event.fromElement ) { 2310 event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement; 2311 } 2312 2313 // Calculate pageX/Y if missing and clientX/Y available 2314 if ( event.pageX == null && event.clientX != null ) { 2315 var doc = document.documentElement, 2316 body = document.body; 2317 2318 event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0); 2319 event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0); 2320 } 2321 2322 // Add which for key events 2323 if ( event.which == null && (event.charCode != null || event.keyCode != null) ) { 2324 event.which = event.charCode != null ? event.charCode : event.keyCode; 2325 } 2326 2327 // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs) 2328 if ( !event.metaKey && event.ctrlKey ) { 2329 event.metaKey = event.ctrlKey; 2330 } 2331 2332 // Add which for click: 1 === left; 2 === middle; 3 === right 2333 // Note: button is not normalized, so don't use it 2334 if ( !event.which && event.button !== undefined ) { 2335 event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) )); 2336 } 2337 2338 return event; 2339 }, 2340 2341 // Deprecated, use jQuery.guid instead 2342 guid: 1E8, 2343 2344 // Deprecated, use jQuery.proxy instead 2345 proxy: jQuery.proxy, 2346 2347 special: { 2348 ready: { 2349 // Make sure the ready event is setup 2350 setup: jQuery.bindReady, 2351 teardown: jQuery.noop 2352 }, 2353 2354 live: { 2355 add: function( handleObj ) { 2356 jQuery.event.add( this, 2357 liveConvert( handleObj.origType, handleObj.selector ), 2358 jQuery.extend({}, handleObj, {handler: liveHandler, guid: handleObj.handler.guid}) ); 2359 }, 2360 2361 remove: function( handleObj ) { 2362 jQuery.event.remove( this, liveConvert( handleObj.origType, handleObj.selector ), handleObj ); 2363 } 2364 }, 2365 2366 beforeunload: { 2367 setup: function( data, namespaces, eventHandle ) { 2368 // We only want to do this special case on windows 2369 if ( jQuery.isWindow( this ) ) { 2370 this.onbeforeunload = eventHandle; 2371 } 2372 }, 2373 2374 teardown: function( namespaces, eventHandle ) { 2375 if ( this.onbeforeunload === eventHandle ) { 2376 this.onbeforeunload = null; 2377 } 2378 } 2379 } 2380 } 2381 }; 2382 2383 jQuery.removeEvent = document.removeEventListener ? 2384 function( elem, type, handle ) { 2385 if ( elem.removeEventListener ) { 2386 elem.removeEventListener( type, handle, false ); 2387 } 2388 } : 2389 function( elem, type, handle ) { 2390 if ( elem.detachEvent ) { 2391 elem.detachEvent( "on" + type, handle ); 2392 } 2393 }; 2394 2395 jQuery.Event = function( src ) { 2396 // Allow instantiation without the 'new' keyword 2397 if ( !this.preventDefault ) { 2398 return new jQuery.Event( src ); 2399 } 2400 2401 // Event object 2402 if ( src && src.type ) { 2403 this.originalEvent = src; 2404 this.type = src.type; 2405 // Event type 2406 } else { 2407 this.type = src; 2408 } 2409 2410 // timeStamp is buggy for some events on Firefox(#3843) 2411 // So we won't rely on the native value 2412 this.timeStamp = jQuery.now(); 2413 2414 // Mark it as fixed 2415 this[ jQuery.expando ] = true; 2416 }; 2417 2418 function returnFalse() { 2419 return false; 2420 } 2421 function returnTrue() { 2422 return true; 2423 } 2424 2425 // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding 2426 // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html 2427 jQuery.Event.prototype = { 2428 preventDefault: function() { 2429 this.isDefaultPrevented = returnTrue; 2430 2431 var e = this.originalEvent; 2432 if ( !e ) { 2433 return; 2434 } 2435 2436 // if preventDefault exists run it on the original event 2437 if ( e.preventDefault ) { 2438 e.preventDefault(); 2439 2440 // otherwise set the returnValue property of the original event to false (IE) 2441 } else { 2442 e.returnValue = false; 2443 } 2444 }, 2445 stopPropagation: function() { 2446 this.isPropagationStopped = returnTrue; 2447 2448 var e = this.originalEvent; 2449 if ( !e ) { 2450 return; 2451 } 2452 // if stopPropagation exists run it on the original event 2453 if ( e.stopPropagation ) { 2454 e.stopPropagation(); 2455 } 2456 // otherwise set the cancelBubble property of the original event to true (IE) 2457 e.cancelBubble = true; 2458 }, 2459 stopImmediatePropagation: function() { 2460 this.isImmediatePropagationStopped = returnTrue; 2461 this.stopPropagation(); 2462 }, 2463 isDefaultPrevented: returnFalse, 2464 isPropagationStopped: returnFalse, 2465 isImmediatePropagationStopped: returnFalse 2466 }; 2467 2468 // Checks if an event happened on an element within another element 2469 // Used in jQuery.event.special.mouseenter and mouseleave handlers 2470 var withinElement = function( event ) { 2471 // Check if mouse(over|out) are still within the same parent element 2472 var parent = event.relatedTarget; 2473 2474 // Firefox sometimes assigns relatedTarget a XUL element 2475 // which we cannot access the parentNode property of 2476 try { 2477 // Traverse up the tree 2478 while ( parent && parent !== this ) { 2479 parent = parent.parentNode; 2480 } 2481 2482 if ( parent !== this ) { 2483 // set the correct event type 2484 event.type = event.data; 2485 2486 // handle event if we actually just moused on to a non sub-element 2487 jQuery.event.handle.apply( this, arguments ); 2488 } 2489 2490 // assuming we've left the element since we most likely mousedover a xul element 2491 } catch(e) { } 2492 }, 2493 2494 // In case of event delegation, we only need to rename the event.type, 2495 // liveHandler will take care of the rest. 2496 delegate = function( event ) { 2497 event.type = event.data; 2498 jQuery.event.handle.apply( this, arguments ); 2499 }; 2500 2501 // Create mouseenter and mouseleave events 2502 jQuery.each({ 2503 mouseenter: "mouseover", 2504 mouseleave: "mouseout" 2505 }, function( orig, fix ) { 2506 jQuery.event.special[ orig ] = { 2507 setup: function( data ) { 2508 jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig ); 2509 }, 2510 teardown: function( data ) { 2511 jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement ); 2512 } 2513 }; 2514 }); 2515 2516 // submit delegation 2517 if ( !jQuery.support.submitBubbles ) { 2518 2519 jQuery.event.special.submit = { 2520 setup: function( data, namespaces ) { 2521 if ( this.nodeName.toLowerCase() !== "form" ) { 2522 jQuery.event.add(this, "click.specialSubmit", function( e ) { 2523 var elem = e.target, 2524 type = elem.type; 2525 2526 if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) { 2527 e.liveFired = undefined; 2528 return trigger( "submit", this, arguments ); 2529 } 2530 }); 2531 2532 jQuery.event.add(this, "keypress.specialSubmit", function( e ) { 2533 var elem = e.target, 2534 type = elem.type; 2535 2536 if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) { 2537 e.liveFired = undefined; 2538 return trigger( "submit", this, arguments ); 2539 } 2540 }); 2541 2542 } else { 2543 return false; 2544 } 2545 }, 2546 2547 teardown: function( namespaces ) { 2548 jQuery.event.remove( this, ".specialSubmit" ); 2549 } 2550 }; 2551 2552 } 2553 2554 // change delegation, happens here so we have bind. 2555 if ( !jQuery.support.changeBubbles ) { 2556 2557 var changeFilters, 2558 2559 getVal = function( elem ) { 2560 var type = elem.type, val = elem.value; 2561 2562 if ( type === "radio" || type === "checkbox" ) { 2563 val = elem.checked; 2564 2565 } else if ( type === "select-multiple" ) { 2566 val = elem.selectedIndex > -1 ? 2567 jQuery.map( elem.options, function( elem ) { 2568 return elem.selected; 2569 }).join("-") : 2570 ""; 2571 2572 } else if ( elem.nodeName.toLowerCase() === "select" ) { 2573 val = elem.selectedIndex; 2574 } 2575 2576 return val; 2577 }, 2578 2579 testChange = function testChange( e ) { 2580 var elem = e.target, data, val; 2581 2582 if ( !rformElems.test( elem.nodeName ) || elem.readOnly ) { 2583 return; 2584 } 2585 2586 data = jQuery.data( elem, "_change_data" ); 2587 val = getVal(elem); 2588 2589 // the current data will be also retrieved by beforeactivate 2590 if ( e.type !== "focusout" || elem.type !== "radio" ) { 2591 jQuery.data( elem, "_change_data", val ); 2592 } 2593 2594 if ( data === undefined || val === data ) { 2595 return; 2596 } 2597 2598 if ( data != null || val ) { 2599 e.type = "change"; 2600 e.liveFired = undefined; 2601 return jQuery.event.trigger( e, arguments[1], elem ); 2602 } 2603 }; 2604 2605 jQuery.event.special.change = { 2606 filters: { 2607 focusout: testChange, 2608 2609 beforedeactivate: testChange, 2610 2611 click: function( e ) { 2612 var elem = e.target, type = elem.type; 2613 2614 if ( type === "radio" || type === "checkbox" || elem.nodeName.toLowerCase() === "select" ) { 2615 return testChange.call( this, e ); 2616 } 2617 }, 2618 2619 // Change has to be called before submit 2620 // Keydown will be called before keypress, which is used in submit-event delegation 2621 keydown: function( e ) { 2622 var elem = e.target, type = elem.type; 2623 2624 if ( (e.keyCode === 13 && elem.nodeName.toLowerCase() !== "textarea") || 2625 (e.keyCode === 32 && (type === "checkbox" || type === "radio")) || 2626 type === "select-multiple" ) { 2627 return testChange.call( this, e ); 2628 } 2629 }, 2630 2631 // Beforeactivate happens also before the previous element is blurred 2632 // with this event you can't trigger a change event, but you can store 2633 // information 2634 beforeactivate: function( e ) { 2635 var elem = e.target; 2636 jQuery.data( elem, "_change_data", getVal(elem) ); 2637 } 2638 }, 2639 2640 setup: function( data, namespaces ) { 2641 if ( this.type === "file" ) { 2642 return false; 2643 } 2644 2645 for ( var type in changeFilters ) { 2646 jQuery.event.add( this, type + ".specialChange", changeFilters[type] ); 2647 } 2648 2649 return rformElems.test( this.nodeName ); 2650 }, 2651 2652 teardown: function( namespaces ) { 2653 jQuery.event.remove( this, ".specialChange" ); 2654 2655 return rformElems.test( this.nodeName ); 2656 } 2657 }; 2658 2659 changeFilters = jQuery.event.special.change.filters; 2660 2661 // Handle when the input is .focus()'d 2662 changeFilters.focus = changeFilters.beforeactivate; 2663 } 2664 2665 function trigger( type, elem, args ) { 2666 args[0].type = type; 2667 return jQuery.event.handle.apply( elem, args ); 2668 } 2669 2670 // Create "bubbling" focus and blur events 2671 if ( document.addEventListener ) { 2672 jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { 2673 jQuery.event.special[ fix ] = { 2674 setup: function() { 2675 if ( focusCounts[fix]++ === 0 ) { 2676 document.addEventListener( orig, handler, true ); 2677 } 2678 }, 2679 teardown: function() { 2680 if ( --focusCounts[fix] === 0 ) { 2681 document.removeEventListener( orig, handler, true ); 2682 } 2683 } 2684 }; 2685 2686 function handler( e ) { 2687 e = jQuery.event.fix( e ); 2688 e.type = fix; 2689 return jQuery.event.trigger( e, null, e.target ); 2690 } 2691 }); 2692 } 2693 2694 jQuery.each(["bind", "one"], function( i, name ) { 2695 jQuery.fn[ name ] = function( type, data, fn ) { 2696 // Handle object literals 2697 if ( typeof type === "object" ) { 2698 for ( var key in type ) { 2699 this[ name ](key, data, type[key], fn); 2700 } 2701 return this; 2702 } 2703 2704 if ( jQuery.isFunction( data ) || data === false ) { 2705 fn = data; 2706 data = undefined; 2707 } 2708 2709 var handler = name === "one" ? jQuery.proxy( fn, function( event ) { 2710 jQuery( this ).unbind( event, handler ); 2711 return fn.apply( this, arguments ); 2712 }) : fn; 2713 2714 if ( type === "unload" && name !== "one" ) { 2715 this.one( type, data, fn ); 2716 2717 } else { 2718 for ( var i = 0, l = this.length; i < l; i++ ) { 2719 jQuery.event.add( this[i], type, handler, data ); 2720 } 2721 } 2722 2723 return this; 2724 }; 2725 }); 2726 2727 jQuery.fn.extend({ 2728 unbind: function( type, fn ) { 2729 // Handle object literals 2730 if ( typeof type === "object" && !type.preventDefault ) { 2731 for ( var key in type ) { 2732 this.unbind(key, type[key]); 2733 } 2734 2735 } else { 2736 for ( var i = 0, l = this.length; i < l; i++ ) { 2737 jQuery.event.remove( this[i], type, fn ); 2738 } 2739 } 2740 2741 return this; 2742 }, 2743 2744 delegate: function( selector, types, data, fn ) { 2745 return this.live( types, data, fn, selector ); 2746 }, 2747 2748 undelegate: function( selector, types, fn ) { 2749 if ( arguments.length === 0 ) { 2750 return this.unbind( "live" ); 2751 2752 } else { 2753 return this.die( types, null, fn, selector ); 2754 } 2755 }, 2756 2757 trigger: function( type, data ) { 2758 return this.each(function() { 2759 jQuery.event.trigger( type, data, this ); 2760 }); 2761 }, 2762 2763 triggerHandler: function( type, data ) { 2764 if ( this[0] ) { 2765 var event = jQuery.Event( type ); 2766 event.preventDefault(); 2767 event.stopPropagation(); 2768 jQuery.event.trigger( event, data, this[0] ); 2769 return event.result; 2770 } 2771 }, 2772 2773 toggle: function( fn ) { 2774 // Save reference to arguments for access in closure 2775 var args = arguments, 2776 i = 1; 2777 2778 // link all the functions, so any of them can unbind this click handler 2779 while ( i < args.length ) { 2780 jQuery.proxy( fn, args[ i++ ] ); 2781 } 2782 2783 return this.click( jQuery.proxy( fn, function( event ) { 2784 // Figure out which function to execute 2785 var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i; 2786 jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 ); 2787 2788 // Make sure that clicks stop 2789 event.preventDefault(); 2790 2791 // and execute the function 2792 return args[ lastToggle ].apply( this, arguments ) || false; 2793 })); 2794 }, 2795 2796 hover: function( fnOver, fnOut ) { 2797 return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); 2798 } 2799 }); 2800 2801 var liveMap = { 2802 focus: "focusin", 2803 blur: "focusout", 2804 mouseenter: "mouseover", 2805 mouseleave: "mouseout" 2806 }; 2807 2808 jQuery.each(["live", "die"], function( i, name ) { 2809 jQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) { 2810 var type, i = 0, match, namespaces, preType, 2811 selector = origSelector || this.selector, 2812 context = origSelector ? this : jQuery( this.context ); 2813 2814 if ( typeof types === "object" && !types.preventDefault ) { 2815 for ( var key in types ) { 2816 context[ name ]( key, data, types[key], selector ); 2817 } 2818 2819 return this; 2820 } 2821 2822 if ( jQuery.isFunction( data ) ) { 2823 fn = data; 2824 data = undefined; 2825 } 2826 2827 types = (types || "").split(" "); 2828 2829 while ( (type = types[ i++ ]) != null ) { 2830 match = rnamespaces.exec( type ); 2831 namespaces = ""; 2832 2833 if ( match ) { 2834 namespaces = match[0]; 2835 type = type.replace( rnamespaces, "" ); 2836 } 2837 2838 if ( type === "hover" ) { 2839 types.push( "mouseenter" + namespaces, "mouseleave" + namespaces ); 2840 continue; 2841 } 2842 2843 preType = type; 2844 2845 if ( type === "focus" || type === "blur" ) { 2846 types.push( liveMap[ type ] + namespaces ); 2847 type = type + namespaces; 2848 2849 } else { 2850 type = (liveMap[ type ] || type) + namespaces; 2851 } 2852 2853 if ( name === "live" ) { 2854 // bind live handler 2855 for ( var j = 0, l = context.length; j < l; j++ ) { 2856 jQuery.event.add( context[j], "live." + liveConvert( type, selector ), 2857 { data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } ); 2858 } 2859 2860 } else { 2861 // unbind live handler 2862 context.unbind( "live." + liveConvert( type, selector ), fn ); 2863 } 2864 } 2865 2866 return this; 2867 }; 2868 }); 2869 2870 function liveHandler( event ) { 2871 var stop, maxLevel, related, match, handleObj, elem, j, i, l, data, close, namespace, ret, 2872 elems = [], 2873 selectors = [], 2874 events = jQuery.data( this, this.nodeType ? "events" : "__events__" ); 2875 2876 if ( typeof events === "function" ) { 2877 events = events.events; 2878 } 2879 2880 // Make sure we avoid non-left-click bubbling in Firefox (#3861) 2881 if ( event.liveFired === this || !events || !events.live || event.button && event.type === "click" ) { 2882 return; 2883 } 2884 2885 if ( event.namespace ) { 2886 namespace = new RegExp("(^|\\.)" + event.namespace.split(".").join("\\.(?:.*\\.)?") + "(\\.|$)"); 2887 } 2888 2889 event.liveFired = this; 2890 2891 var live = events.live.slice(0); 2892 2893 for ( j = 0; j < live.length; j++ ) { 2894 handleObj = live[j]; 2895 2896 if ( handleObj.origType.replace( rnamespaces, "" ) === event.type ) { 2897 selectors.push( handleObj.selector ); 2898 2899 } else { 2900 live.splice( j--, 1 ); 2901 } 2902 } 2903 2904 match = jQuery( event.target ).closest( selectors, event.currentTarget ); 2905 2906 for ( i = 0, l = match.length; i < l; i++ ) { 2907 close = match[i]; 2908 2909 for ( j = 0; j < live.length; j++ ) { 2910 handleObj = live[j]; 2911 2912 if ( close.selector === handleObj.selector && (!namespace || namespace.test( handleObj.namespace )) ) { 2913 elem = close.elem; 2914 related = null; 2915 2916 // Those two events require additional checking 2917 if ( handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave" ) { 2918 event.type = handleObj.preType; 2919 related = jQuery( event.relatedTarget ).closest( handleObj.selector )[0]; 2920 } 2921 2922 if ( !related || related !== elem ) { 2923 elems.push({ elem: elem, handleObj: handleObj, level: close.level }); 2924 } 2925 } 2926 } 2927 } 2928 2929 for ( i = 0, l = elems.length; i < l; i++ ) { 2930 match = elems[i]; 2931 2932 if ( maxLevel && match.level > maxLevel ) { 2933 break; 2934 } 2935 2936 event.currentTarget = match.elem; 2937 event.data = match.handleObj.data; 2938 event.handleObj = match.handleObj; 2939 2940 ret = match.handleObj.origHandler.apply( match.elem, arguments ); 2941 2942 if ( ret === false || event.isPropagationStopped() ) { 2943 maxLevel = match.level; 2944 2945 if ( ret === false ) { 2946 stop = false; 2947 } 2948 if ( event.isImmediatePropagationStopped() ) { 2949 break; 2950 } 2951 } 2952 } 2953 2954 return stop; 2955 } 2956 2957 function liveConvert( type, selector ) { 2958 return (type && type !== "*" ? type + "." : "") + selector.replace(rperiod, "`").replace(rspace, "&"); 2959 } 2960 2961 jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " + 2962 "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + 2963 "change select submit keydown keypress keyup error").split(" "), function( i, name ) { 2964 2965 // Handle event binding 2966 jQuery.fn[ name ] = function( data, fn ) { 2967 if ( fn == null ) { 2968 fn = data; 2969 data = null; 2970 } 2971 2972 return arguments.length > 0 ? 2973 this.bind( name, data, fn ) : 2974 this.trigger( name ); 2975 }; 2976 2977 if ( jQuery.attrFn ) { 2978 jQuery.attrFn[ name ] = true; 2979 } 2980 }); 2981 2982 // Prevent memory leaks in IE 2983 // Window isn't included so as not to unbind existing unload events 2984 // More info: 2985 // - http://isaacschlueter.com/2006/10/msie-memory-leaks/ 2986 if ( window.attachEvent && !window.addEventListener ) { 2987 jQuery(window).bind("unload", function() { 2988 for ( var id in jQuery.cache ) { 2989 if ( jQuery.cache[ id ].handle ) { 2990 // Try/Catch is to handle iframes being unloaded, see #4280 2991 try { 2992 jQuery.event.remove( jQuery.cache[ id ].handle.elem ); 2993 } catch(e) {} 2994 } 2995 } 2996 }); 2997 } 2998 2999 3000 /*! 3001 * Sizzle CSS Selector Engine - v1.0 3002 * Copyright 2009, The Dojo Foundation 3003 * Released under the MIT, BSD, and GPL Licenses. 3004 * More information: http://sizzlejs.com/ 3005 */ 3006 (function(){ 3007 3008 var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, 3009 done = 0, 3010 toString = Object.prototype.toString, 3011 hasDuplicate = false, 3012 baseHasDuplicate = true; 3013 3014 // Here we check if the JavaScript engine is using some sort of 3015 // optimization where it does not always call our comparision 3016 // function. If that is the case, discard the hasDuplicate value. 3017 // Thus far that includes Google Chrome. 3018 [0, 0].sort(function() { 3019 baseHasDuplicate = false; 3020 return 0; 3021 }); 3022 3023 var Sizzle = function( selector, context, results, seed ) { 3024 results = results || []; 3025 context = context || document; 3026 3027 var origContext = context; 3028 3029 if ( context.nodeType !== 1 && context.nodeType !== 9 ) { 3030 return []; 3031 } 3032 3033 if ( !selector || typeof selector !== "string" ) { 3034 return results; 3035 } 3036 3037 var m, set, checkSet, extra, ret, cur, pop, i, 3038 prune = true, 3039 contextXML = Sizzle.isXML( context ), 3040 parts = [], 3041 soFar = selector; 3042 3043 // Reset the position of the chunker regexp (start from head) 3044 do { 3045 chunker.exec( "" ); 3046 m = chunker.exec( soFar ); 3047 3048 if ( m ) { 3049 soFar = m[3]; 3050 3051 parts.push( m[1] ); 3052 3053 if ( m[2] ) { 3054 extra = m[3]; 3055 break; 3056 } 3057 } 3058 } while ( m ); 3059 3060 if ( parts.length > 1 && origPOS.exec( selector ) ) { 3061 3062 if ( parts.length === 2 && Expr.relative[ parts[0] ] ) { 3063 set = posProcess( parts[0] + parts[1], context ); 3064 3065 } else { 3066 set = Expr.relative[ parts[0] ] ? 3067 [ context ] : 3068 Sizzle( parts.shift(), context ); 3069 3070 while ( parts.length ) { 3071 selector = parts.shift(); 3072 3073 if ( Expr.relative[ selector ] ) { 3074 selector += parts.shift(); 3075 } 3076 3077 set = posProcess( selector, set ); 3078 } 3079 } 3080 3081 } else { 3082 // Take a shortcut and set the context if the root selector is an ID 3083 // (but not if it'll be faster if the inner selector is an ID) 3084 if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML && 3085 Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) { 3086 3087 ret = Sizzle.find( parts.shift(), context, contextXML ); 3088 context = ret.expr ? 3089 Sizzle.filter( ret.expr, ret.set )[0] : 3090 ret.set[0]; 3091 } 3092 3093 if ( context ) { 3094 ret = seed ? 3095 { expr: parts.pop(), set: makeArray(seed) } : 3096 Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML ); 3097 3098 set = ret.expr ? 3099 Sizzle.filter( ret.expr, ret.set ) : 3100 ret.set; 3101 3102 if ( parts.length > 0 ) { 3103 checkSet = makeArray( set ); 3104 3105 } else { 3106 prune = false; 3107 } 3108 3109 while ( parts.length ) { 3110 cur = parts.pop(); 3111 pop = cur; 3112 3113 if ( !Expr.relative[ cur ] ) { 3114 cur = ""; 3115 } else { 3116 pop = parts.pop(); 3117 } 3118 3119 if ( pop == null ) { 3120 pop = context; 3121 } 3122 3123 Expr.relative[ cur ]( checkSet, pop, contextXML ); 3124 } 3125 3126 } else { 3127 checkSet = parts = []; 3128 } 3129 } 3130 3131 if ( !checkSet ) { 3132 checkSet = set; 3133 } 3134 3135 if ( !checkSet ) { 3136 Sizzle.error( cur || selector ); 3137 } 3138 3139 if ( toString.call(checkSet) === "[object Array]" ) { 3140 if ( !prune ) { 3141 results.push.apply( results, checkSet ); 3142 3143 } else if ( context && context.nodeType === 1 ) { 3144 for ( i = 0; checkSet[i] != null; i++ ) { 3145 if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) { 3146 results.push( set[i] ); 3147 } 3148 } 3149 3150 } else { 3151 for ( i = 0; checkSet[i] != null; i++ ) { 3152 if ( checkSet[i] && checkSet[i].nodeType === 1 ) { 3153 results.push( set[i] ); 3154 } 3155 } 3156 } 3157 3158 } else { 3159 makeArray( checkSet, results ); 3160 } 3161 3162 if ( extra ) { 3163 Sizzle( extra, origContext, results, seed ); 3164 Sizzle.uniqueSort( results ); 3165 } 3166 3167 return results; 3168 }; 3169 3170 Sizzle.uniqueSort = function( results ) { 3171 if ( sortOrder ) { 3172 hasDuplicate = baseHasDuplicate; 3173 results.sort( sortOrder ); 3174 3175 if ( hasDuplicate ) { 3176 for ( var i = 1; i < results.length; i++ ) { 3177 if ( results[i] === results[ i - 1 ] ) { 3178 results.splice( i--, 1 ); 3179 } 3180 } 3181 } 3182 } 3183 3184 return results; 3185 }; 3186 3187 Sizzle.matches = function( expr, set ) { 3188 return Sizzle( expr, null, null, set ); 3189 }; 3190 3191 Sizzle.matchesSelector = function( node, expr ) { 3192 return Sizzle( expr, null, null, [node] ).length > 0; 3193 }; 3194 3195 Sizzle.find = function( expr, context, isXML ) { 3196 var set; 3197 3198 if ( !expr ) { 3199 return []; 3200 } 3201 3202 for ( var i = 0, l = Expr.order.length; i < l; i++ ) { 3203 var match, 3204 type = Expr.order[i]; 3205 3206 if ( (match = Expr.leftMatch[ type ].exec( expr )) ) { 3207 var left = match[1]; 3208 match.splice( 1, 1 ); 3209 3210 if ( left.substr( left.length - 1 ) !== "\\" ) { 3211 match[1] = (match[1] || "").replace(/\\/g, ""); 3212 set = Expr.find[ type ]( match, context, isXML ); 3213 3214 if ( set != null ) { 3215 expr = expr.replace( Expr.match[ type ], "" ); 3216 break; 3217 } 3218 } 3219 } 3220 } 3221 3222 if ( !set ) { 3223 set = context.getElementsByTagName( "*" ); 3224 } 3225 3226 return { set: set, expr: expr }; 3227 }; 3228 3229 Sizzle.filter = function( expr, set, inplace, not ) { 3230 var match, anyFound, 3231 old = expr, 3232 result = [], 3233 curLoop = set, 3234 isXMLFilter = set && set[0] && Sizzle.isXML( set[0] ); 3235 3236 while ( expr && set.length ) { 3237 for ( var type in Expr.filter ) { 3238 if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) { 3239 var found, item, 3240 filter = Expr.filter[ type ], 3241 left = match[1]; 3242 3243 anyFound = false; 3244 3245 match.splice(1,1); 3246 3247 if ( left.substr( left.length - 1 ) === "\\" ) { 3248 continue; 3249 } 3250 3251 if ( curLoop === result ) { 3252 result = []; 3253 } 3254 3255 if ( Expr.preFilter[ type ] ) { 3256 match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter ); 3257 3258 if ( !match ) { 3259 anyFound = found = true; 3260 3261 } else if ( match === true ) { 3262 continue; 3263 } 3264 } 3265 3266 if ( match ) { 3267 for ( var i = 0; (item = curLoop[i]) != null; i++ ) { 3268 if ( item ) { 3269 found = filter( item, match, i, curLoop ); 3270 var pass = not ^ !!found; 3271 3272 if ( inplace && found != null ) { 3273 if ( pass ) { 3274 anyFound = true; 3275 3276 } else { 3277 curLoop[i] = false; 3278 } 3279 3280 } else if ( pass ) { 3281 result.push( item ); 3282 anyFound = true; 3283 } 3284 } 3285 } 3286 } 3287 3288 if ( found !== undefined ) { 3289 if ( !inplace ) { 3290 curLoop = result; 3291 } 3292 3293 expr = expr.replace( Expr.match[ type ], "" ); 3294 3295 if ( !anyFound ) { 3296 return []; 3297 } 3298 3299 break; 3300 } 3301 } 3302 } 3303 3304 // Improper expression 3305 if ( expr === old ) { 3306 if ( anyFound == null ) { 3307 Sizzle.error( expr ); 3308 3309 } else { 3310 break; 3311 } 3312 } 3313 3314 old = expr; 3315 } 3316 3317 return curLoop; 3318 }; 3319 3320 Sizzle.error = function( msg ) { 3321 throw "Syntax error, unrecognized expression: " + msg; 3322 }; 3323 3324 var Expr = Sizzle.selectors = { 3325 order: [ "ID", "NAME", "TAG" ], 3326 3327 match: { 3328 ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, 3329 CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, 3330 NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/, 3331 ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/, 3332 TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/, 3333 CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+\-]*)\))?/, 3334 POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/, 3335 PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/ 3336 }, 3337 3338 leftMatch: {}, 3339 3340 attrMap: { 3341 "class": "className", 3342 "for": "htmlFor" 3343 }, 3344 3345 attrHandle: { 3346 href: function( elem ) { 3347 return elem.getAttribute( "href" ); 3348 } 3349 }, 3350 3351 relative: { 3352 "+": function(checkSet, part){ 3353 var isPartStr = typeof part === "string", 3354 isTag = isPartStr && !/\W/.test( part ), 3355 isPartStrNotTag = isPartStr && !isTag; 3356 3357 if ( isTag ) { 3358 part = part.toLowerCase(); 3359 } 3360 3361 for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) { 3362 if ( (elem = checkSet[i]) ) { 3363 while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {} 3364 3365 checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ? 3366 elem || false : 3367 elem === part; 3368 } 3369 } 3370 3371 if ( isPartStrNotTag ) { 3372 Sizzle.filter( part, checkSet, true ); 3373 } 3374 }, 3375 3376 ">": function( checkSet, part ) { 3377 var elem, 3378 isPartStr = typeof part === "string", 3379 i = 0, 3380 l = checkSet.length; 3381 3382 if ( isPartStr && !/\W/.test( part ) ) { 3383 part = part.toLowerCase(); 3384 3385 for ( ; i < l; i++ ) { 3386 elem = checkSet[i]; 3387 3388 if ( elem ) { 3389 var parent = elem.parentNode; 3390 checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false; 3391 } 3392 } 3393 3394 } else { 3395 for ( ; i < l; i++ ) { 3396 elem = checkSet[i]; 3397 3398 if ( elem ) { 3399 checkSet[i] = isPartStr ? 3400 elem.parentNode : 3401 elem.parentNode === part; 3402 } 3403 } 3404 3405 if ( isPartStr ) { 3406 Sizzle.filter( part, checkSet, true ); 3407 } 3408 } 3409 }, 3410 3411 "": function(checkSet, part, isXML){ 3412 var nodeCheck, 3413 doneName = done++, 3414 checkFn = dirCheck; 3415 3416 if ( typeof part === "string" && !/\W/.test(part) ) { 3417 part = part.toLowerCase(); 3418 nodeCheck = part; 3419 checkFn = dirNodeCheck; 3420 } 3421 3422 checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML ); 3423 }, 3424 3425 "~": function( checkSet, part, isXML ) { 3426 var nodeCheck, 3427 doneName = done++, 3428 checkFn = dirCheck; 3429 3430 if ( typeof part === "string" && !/\W/.test( part ) ) { 3431 part = part.toLowerCase(); 3432 nodeCheck = part; 3433 checkFn = dirNodeCheck; 3434 } 3435 3436 checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML ); 3437 } 3438 }, 3439 3440 find: { 3441 ID: function( match, context, isXML ) { 3442 if ( typeof context.getElementById !== "undefined" && !isXML ) { 3443 var m = context.getElementById(match[1]); 3444 // Check parentNode to catch when Blackberry 4.6 returns 3445 // nodes that are no longer in the document #6963 3446 return m && m.parentNode ? [m] : []; 3447 } 3448 }, 3449 3450 NAME: function( match, context ) { 3451 if ( typeof context.getElementsByName !== "undefined" ) { 3452 var ret = [], 3453 results = context.getElementsByName( match[1] ); 3454 3455 for ( var i = 0, l = results.length; i < l; i++ ) { 3456 if ( results[i].getAttribute("name") === match[1] ) { 3457 ret.push( results[i] ); 3458 } 3459 } 3460 3461 return ret.length === 0 ? null : ret; 3462 } 3463 }, 3464 3465 TAG: function( match, context ) { 3466 return context.getElementsByTagName( match[1] ); 3467 } 3468 }, 3469 preFilter: { 3470 CLASS: function( match, curLoop, inplace, result, not, isXML ) { 3471 match = " " + match[1].replace(/\\/g, "") + " "; 3472 3473 if ( isXML ) { 3474 return match; 3475 } 3476 3477 for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) { 3478 if ( elem ) { 3479 if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n]/g, " ").indexOf(match) >= 0) ) { 3480 if ( !inplace ) { 3481 result.push( elem ); 3482 } 3483 3484 } else if ( inplace ) { 3485 curLoop[i] = false; 3486 } 3487 } 3488 } 3489 3490 return false; 3491 }, 3492 3493 ID: function( match ) { 3494 return match[1].replace(/\\/g, ""); 3495 }, 3496 3497 TAG: function( match, curLoop ) { 3498 return match[1].toLowerCase(); 3499 }, 3500 3501 CHILD: function( match ) { 3502 if ( match[1] === "nth" ) { 3503 // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6' 3504 var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec( 3505 match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" || 3506 !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]); 3507 3508 // calculate the numbers (first)n+(last) including if they are negative 3509 match[2] = (test[1] + (test[2] || 1)) - 0; 3510 match[3] = test[3] - 0; 3511 } 3512 3513 // TODO: Move to normal caching system 3514 match[0] = done++; 3515 3516 return match; 3517 }, 3518 3519 ATTR: function( match, curLoop, inplace, result, not, isXML ) { 3520 var name = match[1].replace(/\\/g, ""); 3521 3522 if ( !isXML && Expr.attrMap[name] ) { 3523 match[1] = Expr.attrMap[name]; 3524 } 3525 3526 if ( match[2] === "~=" ) { 3527 match[4] = " " + match[4] + " "; 3528 } 3529 3530 return match; 3531 }, 3532 3533 PSEUDO: function( match, curLoop, inplace, result, not ) { 3534 if ( match[1] === "not" ) { 3535 // If we're dealing with a complex expression, or a simple one 3536 if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) { 3537 match[3] = Sizzle(match[3], null, null, curLoop); 3538 3539 } else { 3540 var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not); 3541 3542 if ( !inplace ) { 3543 result.push.apply( result, ret ); 3544 } 3545 3546 return false; 3547 } 3548 3549 } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) { 3550 return true; 3551 } 3552 3553 return match; 3554 }, 3555 3556 POS: function( match ) { 3557 match.unshift( true ); 3558 3559 return match; 3560 } 3561 }, 3562 3563 filters: { 3564 enabled: function( elem ) { 3565 return elem.disabled === false && elem.type !== "hidden"; 3566 }, 3567 3568 disabled: function( elem ) { 3569 return elem.disabled === true; 3570 }, 3571 3572 checked: function( elem ) { 3573 return elem.checked === true; 3574 }, 3575 3576 selected: function( elem ) { 3577 // Accessing this property makes selected-by-default 3578 // options in Safari work properly 3579 elem.parentNode.selectedIndex; 3580 3581 return elem.selected === true; 3582 }, 3583 3584 parent: function( elem ) { 3585 return !!elem.firstChild; 3586 }, 3587 3588 empty: function( elem ) { 3589 return !elem.firstChild; 3590 }, 3591 3592 has: function( elem, i, match ) { 3593 return !!Sizzle( match[3], elem ).length; 3594 }, 3595 3596 header: function( elem ) { 3597 return (/h\d/i).test( elem.nodeName ); 3598 }, 3599 3600 text: function( elem ) { 3601 return "text" === elem.type; 3602 }, 3603 radio: function( elem ) { 3604 return "radio" === elem.type; 3605 }, 3606 3607 checkbox: function( elem ) { 3608 return "checkbox" === elem.type; 3609 }, 3610 3611 file: function( elem ) { 3612 return "file" === elem.type; 3613 }, 3614 password: function( elem ) { 3615 return "password" === elem.type; 3616 }, 3617 3618 submit: function( elem ) { 3619 return "submit" === elem.type; 3620 }, 3621 3622 image: function( elem ) { 3623 return "image" === elem.type; 3624 }, 3625 3626 reset: function( elem ) { 3627 return "reset" === elem.type; 3628 }, 3629 3630 button: function( elem ) { 3631 return "button" === elem.type || elem.nodeName.toLowerCase() === "button"; 3632 }, 3633 3634 input: function( elem ) { 3635 return (/input|select|textarea|button/i).test( elem.nodeName ); 3636 } 3637 }, 3638 setFilters: { 3639 first: function( elem, i ) { 3640 return i === 0; 3641 }, 3642 3643 last: function( elem, i, match, array ) { 3644 return i === array.length - 1; 3645 }, 3646 3647 even: function( elem, i ) { 3648 return i % 2 === 0; 3649 }, 3650 3651 odd: function( elem, i ) { 3652 return i % 2 === 1; 3653 }, 3654 3655 lt: function( elem, i, match ) { 3656 return i < match[3] - 0; 3657 }, 3658 3659 gt: function( elem, i, match ) { 3660 return i > match[3] - 0; 3661 }, 3662 3663 nth: function( elem, i, match ) { 3664 return match[3] - 0 === i; 3665 }, 3666 3667 eq: function( elem, i, match ) { 3668 return match[3] - 0 === i; 3669 } 3670 }, 3671 filter: { 3672 PSEUDO: function( elem, match, i, array ) { 3673 var name = match[1], 3674 filter = Expr.filters[ name ]; 3675 3676 if ( filter ) { 3677 return filter( elem, i, match, array ); 3678 3679 } else if ( name === "contains" ) { 3680 return (elem.textContent || elem.innerText || Sizzle.getText([ elem ]) || "").indexOf(match[3]) >= 0; 3681 3682 } else if ( name === "not" ) { 3683 var not = match[3]; 3684 3685 for ( var j = 0, l = not.length; j < l; j++ ) { 3686 if ( not[j] === elem ) { 3687 return false; 3688 } 3689 } 3690 3691 return true; 3692 3693 } else { 3694 Sizzle.error( "Syntax error, unrecognized expression: " + name ); 3695 } 3696 }, 3697 3698 CHILD: function( elem, match ) { 3699 var type = match[1], 3700 node = elem; 3701 3702 switch ( type ) { 3703 case "only": 3704 case "first": 3705 while ( (node = node.previousSibling) ) { 3706 if ( node.nodeType === 1 ) { 3707 return false; 3708 } 3709 } 3710 3711 if ( type === "first" ) { 3712 return true; 3713 } 3714 3715 node = elem; 3716 3717 case "last": 3718 while ( (node = node.nextSibling) ) { 3719 if ( node.nodeType === 1 ) { 3720 return false; 3721 } 3722 } 3723 3724 return true; 3725 3726 case "nth": 3727 var first = match[2], 3728 last = match[3]; 3729 3730 if ( first === 1 && last === 0 ) { 3731 return true; 3732 } 3733 3734 var doneName = match[0], 3735 parent = elem.parentNode; 3736 3737 if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) { 3738 var count = 0; 3739 3740 for ( node = parent.firstChild; node; node = node.nextSibling ) { 3741 if ( node.nodeType === 1 ) { 3742 node.nodeIndex = ++count; 3743 } 3744 } 3745 3746 parent.sizcache = doneName; 3747 } 3748 3749 var diff = elem.nodeIndex - last; 3750 3751 if ( first === 0 ) { 3752 return diff === 0; 3753 3754 } else { 3755 return ( diff % first === 0 && diff / first >= 0 ); 3756 } 3757 } 3758 }, 3759 3760 ID: function( elem, match ) { 3761 return elem.nodeType === 1 && elem.getAttribute("id") === match; 3762 }, 3763 3764 TAG: function( elem, match ) { 3765 return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match; 3766 }, 3767 3768 CLASS: function( elem, match ) { 3769 return (" " + (elem.className || elem.getAttribute("class")) + " ") 3770 .indexOf( match ) > -1; 3771 }, 3772 3773 ATTR: function( elem, match ) { 3774 var name = match[1], 3775 result = Expr.attrHandle[ name ] ? 3776 Expr.attrHandle[ name ]( elem ) : 3777 elem[ name ] != null ? 3778 elem[ name ] : 3779 elem.getAttribute( name ), 3780 value = result + "", 3781 type = match[2], 3782 check = match[4]; 3783 3784 return result == null ? 3785 type === "!=" : 3786 type === "=" ? 3787 value === check : 3788 type === "*=" ? 3789 value.indexOf(check) >= 0 : 3790 type === "~=" ? 3791 (" " + value + " ").indexOf(check) >= 0 : 3792 !check ? 3793 value && result !== false : 3794 type === "!=" ? 3795 value !== check : 3796 type === "^=" ? 3797 value.indexOf(check) === 0 : 3798 type === "$=" ? 3799 value.substr(value.length - check.length) === check : 3800 type === "|=" ? 3801 value === check || value.substr(0, check.length + 1) === check + "-" : 3802 false; 3803 }, 3804 3805 POS: function( elem, match, i, array ) { 3806 var name = match[2], 3807 filter = Expr.setFilters[ name ]; 3808 3809 if ( filter ) { 3810 return filter( elem, i, match, array ); 3811 } 3812 } 3813 } 3814 }; 3815 3816 var origPOS = Expr.match.POS, 3817 fescape = function(all, num){ 3818 return "\\" + (num - 0 + 1); 3819 }; 3820 3821 for ( var type in Expr.match ) { 3822 Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) ); 3823 Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) ); 3824 } 3825 3826 var makeArray = function( array, results ) { 3827 array = Array.prototype.slice.call( array, 0 ); 3828 3829 if ( results ) { 3830 results.push.apply( results, array ); 3831 return results; 3832 } 3833 3834 return array; 3835 }; 3836 3837 // Perform a simple check to determine if the browser is capable of 3838 // converting a NodeList to an array using builtin methods. 3839 // Also verifies that the returned array holds DOM nodes 3840 // (which is not the case in the Blackberry browser) 3841 try { 3842 Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType; 3843 3844 // Provide a fallback method if it does not work 3845 } catch( e ) { 3846 makeArray = function( array, results ) { 3847 var i = 0, 3848 ret = results || []; 3849 3850 if ( toString.call(array) === "[object Array]" ) { 3851 Array.prototype.push.apply( ret, array ); 3852 3853 } else { 3854 if ( typeof array.length === "number" ) { 3855 for ( var l = array.length; i < l; i++ ) { 3856 ret.push( array[i] ); 3857 } 3858 3859 } else { 3860 for ( ; array[i]; i++ ) { 3861 ret.push( array[i] ); 3862 } 3863 } 3864 } 3865 3866 return ret; 3867 }; 3868 } 3869 3870 var sortOrder, siblingCheck; 3871 3872 if ( document.documentElement.compareDocumentPosition ) { 3873 sortOrder = function( a, b ) { 3874 if ( a === b ) { 3875 hasDuplicate = true; 3876 return 0; 3877 } 3878 3879 if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) { 3880 return a.compareDocumentPosition ? -1 : 1; 3881 } 3882 3883 return a.compareDocumentPosition(b) & 4 ? -1 : 1; 3884 }; 3885 3886 } else { 3887 sortOrder = function( a, b ) { 3888 var al, bl, 3889 ap = [], 3890 bp = [], 3891 aup = a.parentNode, 3892 bup = b.parentNode, 3893 cur = aup; 3894 3895 // The nodes are identical, we can exit early 3896 if ( a === b ) { 3897 hasDuplicate = true; 3898 return 0; 3899 3900 // If the nodes are siblings (or identical) we can do a quick check 3901 } else if ( aup === bup ) { 3902 return siblingCheck( a, b ); 3903 3904 // If no parents were found then the nodes are disconnected 3905 } else if ( !aup ) { 3906 return -1; 3907 3908 } else if ( !bup ) { 3909 return 1; 3910 } 3911 3912 // Otherwise they're somewhere else in the tree so we need 3913 // to build up a full list of the parentNodes for comparison 3914 while ( cur ) { 3915 ap.unshift( cur ); 3916 cur = cur.parentNode; 3917 } 3918 3919 cur = bup; 3920 3921 while ( cur ) { 3922 bp.unshift( cur ); 3923 cur = cur.parentNode; 3924 } 3925 3926 al = ap.length; 3927 bl = bp.length; 3928 3929 // Start walking down the tree looking for a discrepancy 3930 for ( var i = 0; i < al && i < bl; i++ ) { 3931 if ( ap[i] !== bp[i] ) { 3932 return siblingCheck( ap[i], bp[i] ); 3933 } 3934 } 3935 3936 // We ended someplace up the tree so do a sibling check 3937 return i === al ? 3938 siblingCheck( a, bp[i], -1 ) : 3939 siblingCheck( ap[i], b, 1 ); 3940 }; 3941 3942 siblingCheck = function( a, b, ret ) { 3943 if ( a === b ) { 3944 return ret; 3945 } 3946 3947 var cur = a.nextSibling; 3948 3949 while ( cur ) { 3950 if ( cur === b ) { 3951 return -1; 3952 } 3953 3954 cur = cur.nextSibling; 3955 } 3956 3957 return 1; 3958 }; 3959 } 3960 3961 // Utility function for retreiving the text value of an array of DOM nodes 3962 Sizzle.getText = function( elems ) { 3963 var ret = "", elem; 3964 3965 for ( var i = 0; elems[i]; i++ ) { 3966 elem = elems[i]; 3967 3968 // Get the text from text nodes and CDATA nodes 3969 if ( elem.nodeType === 3 || elem.nodeType === 4 ) { 3970 ret += elem.nodeValue; 3971 3972 // Traverse everything else, except comment nodes 3973 } else if ( elem.nodeType !== 8 ) { 3974 ret += Sizzle.getText( elem.childNodes ); 3975 } 3976 } 3977 3978 return ret; 3979 }; 3980 3981 // Check to see if the browser returns elements by name when 3982 // querying by getElementById (and provide a workaround) 3983 (function(){ 3984 // We're going to inject a fake input element with a specified name 3985 var form = document.createElement("div"), 3986 id = "script" + (new Date()).getTime(), 3987 root = document.documentElement; 3988 3989 form.innerHTML = "<a name='" + id + "'/>"; 3990 3991 // Inject it into the root element, check its status, and remove it quickly 3992 root.insertBefore( form, root.firstChild ); 3993 3994 // The workaround has to do additional checks after a getElementById 3995 // Which slows things down for other browsers (hence the branching) 3996 if ( document.getElementById( id ) ) { 3997 Expr.find.ID = function( match, context, isXML ) { 3998 if ( typeof context.getElementById !== "undefined" && !isXML ) { 3999 var m = context.getElementById(match[1]); 4000 4001 return m ? 4002 m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? 4003 [m] : 4004 undefined : 4005 []; 4006 } 4007 }; 4008 4009 Expr.filter.ID = function( elem, match ) { 4010 var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); 4011 4012 return elem.nodeType === 1 && node && node.nodeValue === match; 4013 }; 4014 } 4015 4016 root.removeChild( form ); 4017 4018 // release memory in IE 4019 root = form = null; 4020 })(); 4021 4022 (function(){ 4023 // Check to see if the browser returns only elements 4024 // when doing getElementsByTagName("*") 4025 4026 // Create a fake element 4027 var div = document.createElement("div"); 4028 div.appendChild( document.createComment("") ); 4029 4030 // Make sure no comments are found 4031 if ( div.getElementsByTagName("*").length > 0 ) { 4032 Expr.find.TAG = function( match, context ) { 4033 var results = context.getElementsByTagName( match[1] ); 4034 4035 // Filter out possible comments 4036 if ( match[1] === "*" ) { 4037 var tmp = []; 4038 4039 for ( var i = 0; results[i]; i++ ) { 4040 if ( results[i].nodeType === 1 ) { 4041 tmp.push( results[i] ); 4042 } 4043 } 4044 4045 results = tmp; 4046 } 4047 4048 return results; 4049 }; 4050 } 4051 4052 // Check to see if an attribute returns normalized href attributes 4053 div.innerHTML = "<a href='#'></a>"; 4054 4055 if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" && 4056 div.firstChild.getAttribute("href") !== "#" ) { 4057 4058 Expr.attrHandle.href = function( elem ) { 4059 return elem.getAttribute( "href", 2 ); 4060 }; 4061 } 4062 4063 // release memory in IE 4064 div = null; 4065 })(); 4066 4067 if ( document.querySelectorAll ) { 4068 (function(){ 4069 var oldSizzle = Sizzle, 4070 div = document.createElement("div"), 4071 id = "__sizzle__"; 4072 4073 div.innerHTML = "<p class='TEST'></p>"; 4074 4075 // Safari can't handle uppercase or unicode characters when 4076 // in quirks mode. 4077 if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) { 4078 return; 4079 } 4080 4081 Sizzle = function( query, context, extra, seed ) { 4082 context = context || document; 4083 4084 // Make sure that attribute selectors are quoted 4085 query = query.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']"); 4086 4087 // Only use querySelectorAll on non-XML documents 4088 // (ID selectors don't work in non-HTML documents) 4089 if ( !seed && !Sizzle.isXML(context) ) { 4090 if ( context.nodeType === 9 ) { 4091 try { 4092 return makeArray( context.querySelectorAll(query), extra ); 4093 } catch(qsaError) {} 4094 4095 // qSA works strangely on Element-rooted queries 4096 // We can work around this by specifying an extra ID on the root 4097 // and working up from there (Thanks to Andrew Dupont for the technique) 4098 // IE 8 doesn't work on object elements 4099 } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { 4100 var old = context.getAttribute( "id" ), 4101 nid = old || id; 4102 4103 if ( !old ) { 4104 context.setAttribute( "id", nid ); 4105 } 4106 4107 try { 4108 return makeArray( context.querySelectorAll( "#" + nid + " " + query ), extra ); 4109 4110 } catch(pseudoError) { 4111 } finally { 4112 if ( !old ) { 4113 context.removeAttribute( "id" ); 4114 } 4115 } 4116 } 4117 } 4118 4119 return oldSizzle(query, context, extra, seed); 4120 }; 4121 4122 for ( var prop in oldSizzle ) { 4123 Sizzle[ prop ] = oldSizzle[ prop ]; 4124 } 4125 4126 // release memory in IE 4127 div = null; 4128 })(); 4129 } 4130 4131 (function(){ 4132 var html = document.documentElement, 4133 matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector, 4134 pseudoWorks = false; 4135 4136 try { 4137 // This should fail with an exception 4138 // Gecko does not error, returns false instead 4139 matches.call( document.documentElement, "[test!='']:sizzle" ); 4140 4141 } catch( pseudoError ) { 4142 pseudoWorks = true; 4143 } 4144 4145 if ( matches ) { 4146 Sizzle.matchesSelector = function( node, expr ) { 4147 // Make sure that attribute selectors are quoted 4148 expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']"); 4149 4150 if ( !Sizzle.isXML( node ) ) { 4151 try { 4152 if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) { 4153 return matches.call( node, expr ); 4154 } 4155 } catch(e) {} 4156 } 4157 4158 return Sizzle(expr, null, null, [node]).length > 0; 4159 }; 4160 } 4161 })(); 4162 4163 (function(){ 4164 var div = document.createElement("div"); 4165 4166 div.innerHTML = "<div class='test e'></div><div class='test'></div>"; 4167 4168 // Opera can't find a second classname (in 9.6) 4169 // Also, make sure that getElementsByClassName actually exists 4170 if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) { 4171 return; 4172 } 4173 4174 // Safari caches class attributes, doesn't catch changes (in 3.2) 4175 div.lastChild.className = "e"; 4176 4177 if ( div.getElementsByClassName("e").length === 1 ) { 4178 return; 4179 } 4180 4181 Expr.order.splice(1, 0, "CLASS"); 4182 Expr.find.CLASS = function( match, context, isXML ) { 4183 if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) { 4184 return context.getElementsByClassName(match[1]); 4185 } 4186 }; 4187 4188 // release memory in IE 4189 div = null; 4190 })(); 4191 4192 function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { 4193 for ( var i = 0, l = checkSet.length; i < l; i++ ) { 4194 var elem = checkSet[i]; 4195 4196 if ( elem ) { 4197 var match = false; 4198 4199 elem = elem[dir]; 4200 4201 while ( elem ) { 4202 if ( elem.sizcache === doneName ) { 4203 match = checkSet[elem.sizset]; 4204 break; 4205 } 4206 4207 if ( elem.nodeType === 1 && !isXML ){ 4208 elem.sizcache = doneName; 4209 elem.sizset = i; 4210 } 4211 4212 if ( elem.nodeName.toLowerCase() === cur ) { 4213 match = elem; 4214 break; 4215 } 4216 4217 elem = elem[dir]; 4218 } 4219 4220 checkSet[i] = match; 4221 } 4222 } 4223 } 4224 4225 function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { 4226 for ( var i = 0, l = checkSet.length; i < l; i++ ) { 4227 var elem = checkSet[i]; 4228 4229 if ( elem ) { 4230 var match = false; 4231 4232 elem = elem[dir]; 4233 4234 while ( elem ) { 4235 if ( elem.sizcache === doneName ) { 4236 match = checkSet[elem.sizset]; 4237 break; 4238 } 4239 4240 if ( elem.nodeType === 1 ) { 4241 if ( !isXML ) { 4242 elem.sizcache = doneName; 4243 elem.sizset = i; 4244 } 4245 4246 if ( typeof cur !== "string" ) { 4247 if ( elem === cur ) { 4248 match = true; 4249 break; 4250 } 4251 4252 } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) { 4253 match = elem; 4254 break; 4255 } 4256 } 4257 4258 elem = elem[dir]; 4259 } 4260 4261 checkSet[i] = match; 4262 } 4263 } 4264 } 4265 4266 if ( document.documentElement.contains ) { 4267 Sizzle.contains = function( a, b ) { 4268 return a !== b && (a.contains ? a.contains(b) : true); 4269 }; 4270 4271 } else if ( document.documentElement.compareDocumentPosition ) { 4272 Sizzle.contains = function( a, b ) { 4273 return !!(a.compareDocumentPosition(b) & 16); 4274 }; 4275 4276 } else { 4277 Sizzle.contains = function() { 4278 return false; 4279 }; 4280 } 4281 4282 Sizzle.isXML = function( elem ) { 4283 // documentElement is verified for cases where it doesn't yet exist 4284 // (such as loading iframes in IE - #4833) 4285 var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement; 4286 4287 return documentElement ? documentElement.nodeName !== "HTML" : false; 4288 }; 4289 4290 var posProcess = function( selector, context ) { 4291 var match, 4292 tmpSet = [], 4293 later = "", 4294 root = context.nodeType ? [context] : context; 4295 4296 // Position selectors must be done after the filter 4297 // And so must :not(positional) so we move all PSEUDOs to the end 4298 while ( (match = Expr.match.PSEUDO.exec( selector )) ) { 4299 later += match[0]; 4300 selector = selector.replace( Expr.match.PSEUDO, "" ); 4301 } 4302 4303 selector = Expr.relative[selector] ? selector + "*" : selector; 4304 4305 for ( var i = 0, l = root.length; i < l; i++ ) { 4306 Sizzle( selector, root[i], tmpSet ); 4307 } 4308 4309 return Sizzle.filter( later, tmpSet ); 4310 }; 4311 4312 // EXPOSE 4313 jQuery.find = Sizzle; 4314 jQuery.expr = Sizzle.selectors; 4315 jQuery.expr[":"] = jQuery.expr.filters; 4316 jQuery.unique = Sizzle.uniqueSort; 4317 jQuery.text = Sizzle.getText; 4318 jQuery.isXMLDoc = Sizzle.isXML; 4319 jQuery.contains = Sizzle.contains; 4320 4321 4322 })(); 4323 4324 4325 var runtil = /Until$/, 4326 rparentsprev = /^(?:parents|prevUntil|prevAll)/, 4327 // Note: This RegExp should be improved, or likely pulled from Sizzle 4328 rmultiselector = /,/, 4329 isSimple = /^.[^:#\[\.,]*$/, 4330 slice = Array.prototype.slice, 4331 POS = jQuery.expr.match.POS; 4332 4333 jQuery.fn.extend({ 4334 find: function( selector ) { 4335 var ret = this.pushStack( "", "find", selector ), 4336 length = 0; 4337 4338 for ( var i = 0, l = this.length; i < l; i++ ) { 4339 length = ret.length; 4340 jQuery.find( selector, this[i], ret ); 4341 4342 if ( i > 0 ) { 4343 // Make sure that the results are unique 4344 for ( var n = length; n < ret.length; n++ ) { 4345 for ( var r = 0; r < length; r++ ) { 4346 if ( ret[r] === ret[n] ) { 4347 ret.splice(n--, 1); 4348 break; 4349 } 4350 } 4351 } 4352 } 4353 } 4354 4355 return ret; 4356 }, 4357 4358 has: function( target ) { 4359 var targets = jQuery( target ); 4360 return this.filter(function() { 4361 for ( var i = 0, l = targets.length; i < l; i++ ) { 4362 if ( jQuery.contains( this, targets[i] ) ) { 4363 return true; 4364 } 4365 } 4366 }); 4367 }, 4368 4369 not: function( selector ) { 4370 return this.pushStack( winnow(this, selector, false), "not", selector); 4371 }, 4372 4373 filter: function( selector ) { 4374 return this.pushStack( winnow(this, selector, true), "filter", selector ); 4375 }, 4376 4377 is: function( selector ) { 4378 return !!selector && jQuery.filter( selector, this ).length > 0; 4379 }, 4380 4381 closest: function( selectors, context ) { 4382 var ret = [], i, l, cur = this[0]; 4383 4384 if ( jQuery.isArray( selectors ) ) { 4385 var match, selector, 4386 matches = {}, 4387 level = 1; 4388 4389 if ( cur && selectors.length ) { 4390 for ( i = 0, l = selectors.length; i < l; i++ ) { 4391 selector = selectors[i]; 4392 4393 if ( !matches[selector] ) { 4394 matches[selector] = jQuery.expr.match.POS.test( selector ) ? 4395 jQuery( selector, context || this.context ) : 4396 selector; 4397 } 4398 } 4399 4400 while ( cur && cur.ownerDocument && cur !== context ) { 4401 for ( selector in matches ) { 4402 match = matches[selector]; 4403 4404 if ( match.jquery ? match.index(cur) > -1 : jQuery(cur).is(match) ) { 4405 ret.push({ selector: selector, elem: cur, level: level }); 4406 } 4407 } 4408 4409 cur = cur.parentNode; 4410 level++; 4411 } 4412 } 4413 4414 return ret; 4415 } 4416 4417 var pos = POS.test( selectors ) ? 4418 jQuery( selectors, context || this.context ) : null; 4419 4420 for ( i = 0, l = this.length; i < l; i++ ) { 4421 cur = this[i]; 4422 4423 while ( cur ) { 4424 if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) { 4425 ret.push( cur ); 4426 break; 4427 4428 } else { 4429 cur = cur.parentNode; 4430 if ( !cur || !cur.ownerDocument || cur === context ) { 4431 break; 4432 } 4433 } 4434 } 4435 } 4436 4437 ret = ret.length > 1 ? jQuery.unique(ret) : ret; 4438 4439 return this.pushStack( ret, "closest", selectors ); 4440 }, 4441 4442 // Determine the position of an element within 4443 // the matched set of elements 4444 index: function( elem ) { 4445 if ( !elem || typeof elem === "string" ) { 4446 return jQuery.inArray( this[0], 4447 // If it receives a string, the selector is used 4448 // If it receives nothing, the siblings are used 4449 elem ? jQuery( elem ) : this.parent().children() ); 4450 } 4451 // Locate the position of the desired element 4452 return jQuery.inArray( 4453 // If it receives a jQuery object, the first element is used 4454 elem.jquery ? elem[0] : elem, this ); 4455 }, 4456 4457 add: function( selector, context ) { 4458 var set = typeof selector === "string" ? 4459 jQuery( selector, context || this.context ) : 4460 jQuery.makeArray( selector ), 4461 all = jQuery.merge( this.get(), set ); 4462 4463 return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ? 4464 all : 4465 jQuery.unique( all ) ); 4466 }, 4467 4468 andSelf: function() { 4469 return this.add( this.prevObject ); 4470 } 4471 }); 4472 4473 // A painfully simple check to see if an element is disconnected 4474 // from a document (should be improved, where feasible). 4475 function isDisconnected( node ) { 4476 return !node || !node.parentNode || node.parentNode.nodeType === 11; 4477 } 4478 4479 jQuery.each({ 4480 parent: function( elem ) { 4481 var parent = elem.parentNode; 4482 return parent && parent.nodeType !== 11 ? parent : null; 4483 }, 4484 parents: function( elem ) { 4485 return jQuery.dir( elem, "parentNode" ); 4486 }, 4487 parentsUntil: function( elem, i, until ) { 4488 return jQuery.dir( elem, "parentNode", until ); 4489 }, 4490 next: function( elem ) { 4491 return jQuery.nth( elem, 2, "nextSibling" ); 4492 }, 4493 prev: function( elem ) { 4494 return jQuery.nth( elem, 2, "previousSibling" ); 4495 }, 4496 nextAll: function( elem ) { 4497 return jQuery.dir( elem, "nextSibling" ); 4498 }, 4499 prevAll: function( elem ) { 4500 return jQuery.dir( elem, "previousSibling" ); 4501 }, 4502 nextUntil: function( elem, i, until ) { 4503 return jQuery.dir( elem, "nextSibling", until ); 4504 }, 4505 prevUntil: function( elem, i, until ) { 4506 return jQuery.dir( elem, "previousSibling", until ); 4507 }, 4508 siblings: function( elem ) { 4509 return jQuery.sibling( elem.parentNode.firstChild, elem ); 4510 }, 4511 children: function( elem ) { 4512 return jQuery.sibling( elem.firstChild ); 4513 }, 4514 contents: function( elem ) { 4515 return jQuery.nodeName( elem, "iframe" ) ? 4516 elem.contentDocument || elem.contentWindow.document : 4517 jQuery.makeArray( elem.childNodes ); 4518 } 4519 }, function( name, fn ) { 4520 jQuery.fn[ name ] = function( until, selector ) { 4521 var ret = jQuery.map( this, fn, until ); 4522 4523 if ( !runtil.test( name ) ) { 4524 selector = until; 4525 } 4526 4527 if ( selector && typeof selector === "string" ) { 4528 ret = jQuery.filter( selector, ret ); 4529 } 4530 4531 ret = this.length > 1 ? jQuery.unique( ret ) : ret; 4532 4533 if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) { 4534 ret = ret.reverse(); 4535 } 4536 4537 return this.pushStack( ret, name, slice.call(arguments).join(",") ); 4538 }; 4539 }); 4540 4541 jQuery.extend({ 4542 filter: function( expr, elems, not ) { 4543 if ( not ) { 4544 expr = ":not(" + expr + ")"; 4545 } 4546 4547 return elems.length === 1 ? 4548 jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] : 4549 jQuery.find.matches(expr, elems); 4550 }, 4551 4552 dir: function( elem, dir, until ) { 4553 var matched = [], 4554 cur = elem[ dir ]; 4555 4556 while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { 4557 if ( cur.nodeType === 1 ) { 4558 matched.push( cur ); 4559 } 4560 cur = cur[dir]; 4561 } 4562 return matched; 4563 }, 4564 4565 nth: function( cur, result, dir, elem ) { 4566 result = result || 1; 4567 var num = 0; 4568 4569 for ( ; cur; cur = cur[dir] ) { 4570 if ( cur.nodeType === 1 && ++num === result ) { 4571 break; 4572 } 4573 } 4574 4575 return cur; 4576 }, 4577 4578 sibling: function( n, elem ) { 4579 var r = []; 4580 4581 for ( ; n; n = n.nextSibling ) { 4582 if ( n.nodeType === 1 && n !== elem ) { 4583 r.push( n ); 4584 } 4585 } 4586 4587 return r; 4588 } 4589 }); 4590 4591 // Implement the identical functionality for filter and not 4592 function winnow( elements, qualifier, keep ) { 4593 if ( jQuery.isFunction( qualifier ) ) { 4594 return jQuery.grep(elements, function( elem, i ) { 4595 var retVal = !!qualifier.call( elem, i, elem ); 4596 return retVal === keep; 4597 }); 4598 4599 } else if ( qualifier.nodeType ) { 4600 return jQuery.grep(elements, function( elem, i ) { 4601 return (elem === qualifier) === keep; 4602 }); 4603 4604 } else if ( typeof qualifier === "string" ) { 4605 var filtered = jQuery.grep(elements, function( elem ) { 4606 return elem.nodeType === 1; 4607 }); 4608 4609 if ( isSimple.test( qualifier ) ) { 4610 return jQuery.filter(qualifier, filtered, !keep); 4611 } else { 4612 qualifier = jQuery.filter( qualifier, filtered ); 4613 } 4614 } 4615 4616 return jQuery.grep(elements, function( elem, i ) { 4617 return (jQuery.inArray( elem, qualifier ) >= 0) === keep; 4618 }); 4619 } 4620 4621 4622 4623 4624 var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g, 4625 rleadingWhitespace = /^\s+/, 4626 rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig, 4627 rtagName = /<([\w:]+)/, 4628 rtbody = /<tbody/i, 4629 rhtml = /<|&#?\w+;/, 4630 rnocache = /<(?:script|object|embed|option|style)/i, 4631 // checked="checked" or checked (html5) 4632 rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, 4633 raction = /\=([^="'>\s]+\/)>/g, 4634 wrapMap = { 4635 option: [ 1, "<select multiple='multiple'>", "</select>" ], 4636 legend: [ 1, "<fieldset>", "</fieldset>" ], 4637 thead: [ 1, "<table>", "</table>" ], 4638 tr: [ 2, "<table><tbody>", "</tbody></table>" ], 4639 td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ], 4640 col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ], 4641 area: [ 1, "<map>", "</map>" ], 4642 _default: [ 0, "", "" ] 4643 }; 4644 4645 wrapMap.optgroup = wrapMap.option; 4646 wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; 4647 wrapMap.th = wrapMap.td; 4648 4649 // IE can't serialize <link> and <script> tags normally 4650 if ( !jQuery.support.htmlSerialize ) { 4651 wrapMap._default = [ 1, "div<div>", "</div>" ]; 4652 } 4653 4654 jQuery.fn.extend({ 4655 text: function( text ) { 4656 if ( jQuery.isFunction(text) ) { 4657 return this.each(function(i) { 4658 var self = jQuery( this ); 4659 4660 self.text( text.call(this, i, self.text()) ); 4661 }); 4662 } 4663 4664 if ( typeof text !== "object" && text !== undefined ) { 4665 return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) ); 4666 } 4667 4668 return jQuery.text( this ); 4669 }, 4670 4671 wrapAll: function( html ) { 4672 if ( jQuery.isFunction( html ) ) { 4673 return this.each(function(i) { 4674 jQuery(this).wrapAll( html.call(this, i) ); 4675 }); 4676 } 4677 4678 if ( this[0] ) { 4679 // The elements to wrap the target around 4680 var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true); 4681 4682 if ( this[0].parentNode ) { 4683 wrap.insertBefore( this[0] ); 4684 } 4685 4686 wrap.map(function() { 4687 var elem = this; 4688 4689 while ( elem.firstChild && elem.firstChild.nodeType === 1 ) { 4690 elem = elem.firstChild; 4691 } 4692 4693 return elem; 4694 }).append(this); 4695 } 4696 4697 return this; 4698 }, 4699 4700 wrapInner: function( html ) { 4701 if ( jQuery.isFunction( html ) ) { 4702 return this.each(function(i) { 4703 jQuery(this).wrapInner( html.call(this, i) ); 4704 }); 4705 } 4706 4707 return this.each(function() { 4708 var self = jQuery( this ), 4709 contents = self.contents(); 4710 4711 if ( contents.length ) { 4712 contents.wrapAll( html ); 4713 4714 } else { 4715 self.append( html ); 4716 } 4717 }); 4718 }, 4719 4720 wrap: function( html ) { 4721 return this.each(function() { 4722 jQuery( this ).wrapAll( html ); 4723 }); 4724 }, 4725 4726 unwrap: function() { 4727 return this.parent().each(function() { 4728 if ( !jQuery.nodeName( this, "body" ) ) { 4729 jQuery( this ).replaceWith( this.childNodes ); 4730 } 4731 }).end(); 4732 }, 4733 4734 append: function() { 4735 return this.domManip(arguments, true, function( elem ) { 4736 if ( this.nodeType === 1 ) { 4737 this.appendChild( elem ); 4738 } 4739 }); 4740 }, 4741 4742 prepend: function() { 4743 return this.domManip(arguments, true, function( elem ) { 4744 if ( this.nodeType === 1 ) { 4745 this.insertBefore( elem, this.firstChild ); 4746 } 4747 }); 4748 }, 4749 4750 before: function() { 4751 if ( this[0] && this[0].parentNode ) { 4752 return this.domManip(arguments, false, function( elem ) { 4753 this.parentNode.insertBefore( elem, this ); 4754 }); 4755 } else if ( arguments.length ) { 4756 var set = jQuery(arguments[0]); 4757 set.push.apply( set, this.toArray() ); 4758 return this.pushStack( set, "before", arguments ); 4759 } 4760 }, 4761 4762 after: function() { 4763 if ( this[0] && this[0].parentNode ) { 4764 return this.domManip(arguments, false, function( elem ) { 4765 this.parentNode.insertBefore( elem, this.nextSibling ); 4766 }); 4767 } else if ( arguments.length ) { 4768 var set = this.pushStack( this, "after", arguments ); 4769 set.push.apply( set, jQuery(arguments[0]).toArray() ); 4770 return set; 4771 } 4772 }, 4773 4774 // keepData is for internal use only--do not document 4775 remove: function( selector, keepData ) { 4776 for ( var i = 0, elem; (elem = this[i]) != null; i++ ) { 4777 if ( !selector || jQuery.filter( selector, [ elem ] ).length ) { 4778 if ( !keepData && elem.nodeType === 1 ) { 4779 jQuery.cleanData( elem.getElementsByTagName("*") ); 4780 jQuery.cleanData( [ elem ] ); 4781 } 4782 4783 if ( elem.parentNode ) { 4784 elem.parentNode.removeChild( elem ); 4785 } 4786 } 4787 } 4788 4789 return this; 4790 }, 4791 4792 empty: function() { 4793 for ( var i = 0, elem; (elem = this[i]) != null; i++ ) { 4794 // Remove element nodes and prevent memory leaks 4795 if ( elem.nodeType === 1 ) { 4796 jQuery.cleanData( elem.getElementsByTagName("*") ); 4797 } 4798 4799 // Remove any remaining nodes 4800 while ( elem.firstChild ) { 4801 elem.removeChild( elem.firstChild ); 4802 } 4803 } 4804 4805 return this; 4806 }, 4807 4808 clone: function( events ) { 4809 // Do the clone 4810 var ret = this.map(function() { 4811 if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) { 4812 // IE copies events bound via attachEvent when 4813 // using cloneNode. Calling detachEvent on the 4814 // clone will also remove the events from the orignal 4815 // In order to get around this, we use innerHTML. 4816 // Unfortunately, this means some modifications to 4817 // attributes in IE that are actually only stored 4818 // as properties will not be copied (such as the 4819 // the name attribute on an input). 4820 var html = this.outerHTML, 4821 ownerDocument = this.ownerDocument; 4822 4823 if ( !html ) { 4824 var div = ownerDocument.createElement("div"); 4825 div.appendChild( this.cloneNode(true) ); 4826 html = div.innerHTML; 4827 } 4828 4829 return jQuery.clean([html.replace(rinlinejQuery, "") 4830 // Handle the case in IE 8 where action=/test/> self-closes a tag 4831 .replace(raction, '="$1">') 4832 .replace(rleadingWhitespace, "")], ownerDocument)[0]; 4833 } else { 4834 return this.cloneNode(true); 4835 } 4836 }); 4837 4838 // Copy the events from the original to the clone 4839 if ( events === true ) { 4840 cloneCopyEvent( this, ret ); 4841 cloneCopyEvent( this.find("*"), ret.find("*") ); 4842 } 4843 4844 // Return the cloned set 4845 return ret; 4846 }, 4847 4848 html: function( value ) { 4849 if ( value === undefined ) { 4850 return this[0] && this[0].nodeType === 1 ? 4851 this[0].innerHTML.replace(rinlinejQuery, "") : 4852 null; 4853 4854 // See if we can take a shortcut and just use innerHTML 4855 } else if ( typeof value === "string" && !rnocache.test( value ) && 4856 (jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) && 4857 !wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) { 4858 4859 value = value.replace(rxhtmlTag, "<$1></$2>"); 4860 4861 try { 4862 for ( var i = 0, l = this.length; i < l; i++ ) { 4863 // Remove element nodes and prevent memory leaks 4864 if ( this[i].nodeType === 1 ) { 4865 jQuery.cleanData( this[i].getElementsByTagName("*") ); 4866 this[i].innerHTML = value; 4867 } 4868 } 4869 4870 // If using innerHTML throws an exception, use the fallback method 4871 } catch(e) { 4872 this.empty().append( value ); 4873 } 4874 4875 } else if ( jQuery.isFunction( value ) ) { 4876 this.each(function(i){ 4877 var self = jQuery( this ); 4878 4879 self.html( value.call(this, i, self.html()) ); 4880 }); 4881 4882 } else { 4883 this.empty().append( value ); 4884 } 4885 4886 return this; 4887 }, 4888 4889 replaceWith: function( value ) { 4890 if ( this[0] && this[0].parentNode ) { 4891 // Make sure that the elements are removed from the DOM before they are inserted 4892 // this can help fix replacing a parent with child elements 4893 if ( jQuery.isFunction( value ) ) { 4894 return this.each(function(i) { 4895 var self = jQuery(this), old = self.html(); 4896 self.replaceWith( value.call( this, i, old ) ); 4897 }); 4898 } 4899 4900 if ( typeof value !== "string" ) { 4901 value = jQuery( value ).detach(); 4902 } 4903 4904 return this.each(function() { 4905 var next = this.nextSibling, 4906 parent = this.parentNode; 4907 4908 jQuery( this ).remove(); 4909 4910 if ( next ) { 4911 jQuery(next).before( value ); 4912 } else { 4913 jQuery(parent).append( value ); 4914 } 4915 }); 4916 } else { 4917 return this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value ); 4918 } 4919 }, 4920 4921 detach: function( selector ) { 4922 return this.remove( selector, true ); 4923 }, 4924 4925 domManip: function( args, table, callback ) { 4926 var results, first, fragment, parent, 4927 value = args[0], 4928 scripts = []; 4929 4930 // We can't cloneNode fragments that contain checked, in WebKit 4931 if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) { 4932 return this.each(function() { 4933 jQuery(this).domManip( args, table, callback, true ); 4934 }); 4935 } 4936 4937 if ( jQuery.isFunction(value) ) { 4938 return this.each(function(i) { 4939 var self = jQuery(this); 4940 args[0] = value.call(this, i, table ? self.html() : undefined); 4941 self.domManip( args, table, callback ); 4942 }); 4943 } 4944 4945 if ( this[0] ) { 4946 parent = value && value.parentNode; 4947 4948 // If we're in a fragment, just use that instead of building a new one 4949 if ( jQuery.support.parentNode && parent && parent.nodeType === 11 && parent.childNodes.length === this.length ) { 4950 results = { fragment: parent }; 4951 4952 } else { 4953 results = jQuery.buildFragment( args, this, scripts ); 4954 } 4955 4956 fragment = results.fragment; 4957 4958 if ( fragment.childNodes.length === 1 ) { 4959 first = fragment = fragment.firstChild; 4960 } else { 4961 first = fragment.firstChild; 4962 } 4963 4964 if ( first ) { 4965 table = table && jQuery.nodeName( first, "tr" ); 4966 4967 for ( var i = 0, l = this.length; i < l; i++ ) { 4968 callback.call( 4969 table ? 4970 root(this[i], first) : 4971 this[i], 4972 i > 0 || results.cacheable || this.length > 1 ? 4973 fragment.cloneNode(true) : 4974 fragment 4975 ); 4976 } 4977 } 4978 4979 if ( scripts.length ) { 4980 jQuery.each( scripts, evalScript ); 4981 } 4982 } 4983 4984 return this; 4985 } 4986 }); 4987 4988 function root( elem, cur ) { 4989 return jQuery.nodeName(elem, "table") ? 4990 (elem.getElementsByTagName("tbody")[0] || 4991 elem.appendChild(elem.ownerDocument.createElement("tbody"))) : 4992 elem; 4993 } 4994 4995 function cloneCopyEvent(orig, ret) { 4996 var i = 0; 4997 4998 ret.each(function() { 4999 if ( this.nodeName !== (orig[i] && orig[i].nodeName) ) { 5000 return; 5001 } 5002 5003 var oldData = jQuery.data( orig[i++] ), 5004 curData = jQuery.data( this, oldData ), 5005 events = oldData && oldData.events; 5006 5007 if ( events ) { 5008 delete curData.handle; 5009 curData.events = {}; 5010 5011 for ( var type in events ) { 5012 for ( var handler in events[ type ] ) { 5013 jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data ); 5014 } 5015 } 5016 } 5017 }); 5018 } 5019 5020 jQuery.buildFragment = function( args, nodes, scripts ) { 5021 var fragment, cacheable, cacheresults, 5022 doc = (nodes && nodes[0] ? nodes[0].ownerDocument || nodes[0] : document); 5023 5024 // Only cache "small" (1/2 KB) strings that are associated with the main document 5025 // Cloning options loses the selected state, so don't cache them 5026 // IE 6 doesn't like it when you put <object> or <embed> elements in a fragment 5027 // Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache 5028 if ( args.length === 1 && typeof args[0] === "string" && args[0].length < 512 && doc === document && 5029 !rnocache.test( args[0] ) && (jQuery.support.checkClone || !rchecked.test( args[0] )) ) { 5030 5031 cacheable = true; 5032 cacheresults = jQuery.fragments[ args[0] ]; 5033 if ( cacheresults ) { 5034 if ( cacheresults !== 1 ) { 5035 fragment = cacheresults; 5036 } 5037 } 5038 } 5039 5040 if ( !fragment ) { 5041 fragment = doc.createDocumentFragment(); 5042 jQuery.clean( args, doc, fragment, scripts ); 5043 } 5044 5045 if ( cacheable ) { 5046 jQuery.fragments[ args[0] ] = cacheresults ? fragment : 1; 5047 } 5048 5049 return { fragment: fragment, cacheable: cacheable }; 5050 }; 5051 5052 jQuery.fragments = {}; 5053 5054 jQuery.each({ 5055 appendTo: "append", 5056 prependTo: "prepend", 5057 insertBefore: "before", 5058 insertAfter: "after", 5059 replaceAll: "replaceWith" 5060 }, function( name, original ) { 5061 jQuery.fn[ name ] = function( selector ) { 5062 var ret = [], 5063 insert = jQuery( selector ), 5064 parent = this.length === 1 && this[0].parentNode; 5065 5066 if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) { 5067 insert[ original ]( this[0] ); 5068 return this; 5069 5070 } else { 5071 for ( var i = 0, l = insert.length; i < l; i++ ) { 5072 var elems = (i > 0 ? this.clone(true) : this).get(); 5073 jQuery( insert[i] )[ original ]( elems ); 5074 ret = ret.concat( elems ); 5075 } 5076 5077 return this.pushStack( ret, name, insert.selector ); 5078 } 5079 }; 5080 }); 5081 5082 jQuery.extend({ 5083 clean: function( elems, context, fragment, scripts ) { 5084 context = context || document; 5085 5086 // !context.createElement fails in IE with an error but returns typeof 'object' 5087 if ( typeof context.createElement === "undefined" ) { 5088 context = context.ownerDocument || context[0] && context[0].ownerDocument || document; 5089 } 5090 5091 var ret = []; 5092 5093 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { 5094 if ( typeof elem === "number" ) { 5095 elem += ""; 5096 } 5097 5098 if ( !elem ) { 5099 continue; 5100 } 5101 5102 // Convert html string into DOM nodes 5103 if ( typeof elem === "string" && !rhtml.test( elem ) ) { 5104 elem = context.createTextNode( elem ); 5105 5106 } else if ( typeof elem === "string" ) { 5107 // Fix "XHTML"-style tags in all browsers 5108 elem = elem.replace(rxhtmlTag, "<$1></$2>"); 5109 5110 // Trim whitespace, otherwise indexOf won't work as expected 5111 var tag = (rtagName.exec( elem ) || ["", ""])[1].toLowerCase(), 5112 wrap = wrapMap[ tag ] || wrapMap._default, 5113 depth = wrap[0], 5114 div = context.createElement("div"); 5115 5116 // Go to html and back, then peel off extra wrappers 5117 div.innerHTML = wrap[1] + elem + wrap[2]; 5118 5119 // Move to the right depth 5120 while ( depth-- ) { 5121 div = div.lastChild; 5122 } 5123 5124 // Remove IE's autoinserted <tbody> from table fragments 5125 if ( !jQuery.support.tbody ) { 5126 5127 // String was a <table>, *may* have spurious <tbody> 5128 var hasBody = rtbody.test(elem), 5129 tbody = tag === "table" && !hasBody ? 5130 div.firstChild && div.firstChild.childNodes : 5131 5132 // String was a bare <thead> or <tfoot> 5133 wrap[1] === "<table>" && !hasBody ? 5134 div.childNodes : 5135 []; 5136 5137 for ( var j = tbody.length - 1; j >= 0 ; --j ) { 5138 if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) { 5139 tbody[ j ].parentNode.removeChild( tbody[ j ] ); 5140 } 5141 } 5142 5143 } 5144 5145 // IE completely kills leading whitespace when innerHTML is used 5146 if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) { 5147 div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild ); 5148 } 5149 5150 elem = div.childNodes; 5151 } 5152 5153 if ( elem.nodeType ) { 5154 ret.push( elem ); 5155 } else { 5156 ret = jQuery.merge( ret, elem ); 5157 } 5158 } 5159 5160 if ( fragment ) { 5161 for ( i = 0; ret[i]; i++ ) { 5162 if ( scripts && jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) { 5163 scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] ); 5164 5165 } else { 5166 if ( ret[i].nodeType === 1 ) { 5167 ret.splice.apply( ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))) ); 5168 } 5169 fragment.appendChild( ret[i] ); 5170 } 5171 } 5172 } 5173 5174 return ret; 5175 }, 5176 5177 cleanData: function( elems ) { 5178 var data, id, cache = jQuery.cache, 5179 special = jQuery.event.special, 5180 deleteExpando = jQuery.support.deleteExpando; 5181 5182 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { 5183 if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) { 5184 continue; 5185 } 5186 5187 id = elem[ jQuery.expando ]; 5188 5189 if ( id ) { 5190 data = cache[ id ]; 5191 5192 if ( data && data.events ) { 5193 for ( var type in data.events ) { 5194 if ( special[ type ] ) { 5195 jQuery.event.remove( elem, type ); 5196 5197 } else { 5198 jQuery.removeEvent( elem, type, data.handle ); 5199 } 5200 } 5201 } 5202 5203 if ( deleteExpando ) { 5204 delete elem[ jQuery.expando ]; 5205 5206 } else if ( elem.removeAttribute ) { 5207 elem.removeAttribute( jQuery.expando ); 5208 } 5209 5210 delete cache[ id ]; 5211 } 5212 } 5213 } 5214 }); 5215 5216 function evalScript( i, elem ) { 5217 if ( elem.src ) { 5218 jQuery.ajax({ 5219 url: elem.src, 5220 async: false, 5221 dataType: "script" 5222 }); 5223 } else { 5224 jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" ); 5225 } 5226 5227 if ( elem.parentNode ) { 5228 elem.parentNode.removeChild( elem ); 5229 } 5230 } 5231 5232 5233 5234 5235 var ralpha = /alpha\([^)]*\)/i, 5236 ropacity = /opacity=([^)]*)/, 5237 rdashAlpha = /-([a-z])/ig, 5238 rupper = /([A-Z])/g, 5239 rnumpx = /^-?\d+(?:px)?$/i, 5240 rnum = /^-?\d/, 5241 5242 cssShow = { position: "absolute", visibility: "hidden", display: "block" }, 5243 cssWidth = [ "Left", "Right" ], 5244 cssHeight = [ "Top", "Bottom" ], 5245 curCSS, 5246 5247 getComputedStyle, 5248 currentStyle, 5249 5250 fcamelCase = function( all, letter ) { 5251 return letter.toUpperCase(); 5252 }; 5253 5254 jQuery.fn.css = function( name, value ) { 5255 // Setting 'undefined' is a no-op 5256 if ( arguments.length === 2 && value === undefined ) { 5257 return this; 5258 } 5259 5260 return jQuery.access( this, name, value, true, function( elem, name, value ) { 5261 return value !== undefined ? 5262 jQuery.style( elem, name, value ) : 5263 jQuery.css( elem, name ); 5264 }); 5265 }; 5266 5267 jQuery.extend({ 5268 // Add in style property hooks for overriding the default 5269 // behavior of getting and setting a style property 5270 cssHooks: { 5271 opacity: { 5272 get: function( elem, computed ) { 5273 if ( computed ) { 5274 // We should always get a number back from opacity 5275 var ret = curCSS( elem, "opacity", "opacity" ); 5276 return ret === "" ? "1" : ret; 5277 5278 } else { 5279 return elem.style.opacity; 5280 } 5281 } 5282 } 5283 }, 5284 5285 // Exclude the following css properties to add px 5286 cssNumber: { 5287 "zIndex": true, 5288 "fontWeight": true, 5289 "opacity": true, 5290 "zoom": true, 5291 "lineHeight": true 5292 }, 5293 5294 // Add in properties whose names you wish to fix before 5295 // setting or getting the value 5296 cssProps: { 5297 // normalize float css property 5298 "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat" 5299 }, 5300 5301 // Get and set the style property on a DOM Node 5302 style: function( elem, name, value, extra ) { 5303 // Don't set styles on text and comment nodes 5304 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { 5305 return; 5306 } 5307 5308 // Make sure that we're working with the right name 5309 var ret, origName = jQuery.camelCase( name ), 5310 style = elem.style, hooks = jQuery.cssHooks[ origName ]; 5311 5312 name = jQuery.cssProps[ origName ] || origName; 5313 5314 // Check if we're setting a value 5315 if ( value !== undefined ) { 5316 // Make sure that NaN and null values aren't set. See: #7116 5317 if ( typeof value === "number" && isNaN( value ) || value == null ) { 5318 return; 5319 } 5320 5321 // If a number was passed in, add 'px' to the (except for certain CSS properties) 5322 if ( typeof value === "number" && !jQuery.cssNumber[ origName ] ) { 5323 value += "px"; 5324 } 5325 5326 // If a hook was provided, use that value, otherwise just set the specified value 5327 if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value )) !== undefined ) { 5328 // Wrapped to prevent IE from throwing errors when 'invalid' values are provided 5329 // Fixes bug #5509 5330 try { 5331 style[ name ] = value; 5332 } catch(e) {} 5333 } 5334 5335 } else { 5336 // If a hook was provided get the non-computed value from there 5337 if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) { 5338 return ret; 5339 } 5340 5341 // Otherwise just get the value from the style object 5342 return style[ name ]; 5343 } 5344 }, 5345 5346 css: function( elem, name, extra ) { 5347 // Make sure that we're working with the right name 5348 var ret, origName = jQuery.camelCase( name ), 5349 hooks = jQuery.cssHooks[ origName ]; 5350 5351 name = jQuery.cssProps[ origName ] || origName; 5352 5353 // If a hook was provided get the computed value from there 5354 if ( hooks && "get" in hooks && (ret = hooks.get( elem, true, extra )) !== undefined ) { 5355 return ret; 5356 5357 // Otherwise, if a way to get the computed value exists, use that 5358 } else if ( curCSS ) { 5359 return curCSS( elem, name, origName ); 5360 } 5361 }, 5362 5363 // A method for quickly swapping in/out CSS properties to get correct calculations 5364 swap: function( elem, options, callback ) { 5365 var old = {}; 5366 5367 // Remember the old values, and insert the new ones 5368 for ( var name in options ) { 5369 old[ name ] = elem.style[ name ]; 5370 elem.style[ name ] = options[ name ]; 5371 } 5372 5373 callback.call( elem ); 5374 5375 // Revert the old values 5376 for ( name in options ) { 5377 elem.style[ name ] = old[ name ]; 5378 } 5379 }, 5380 5381 camelCase: function( string ) { 5382 return string.replace( rdashAlpha, fcamelCase ); 5383 } 5384 }); 5385 5386 // DEPRECATED, Use jQuery.css() instead 5387 jQuery.curCSS = jQuery.css; 5388 5389 jQuery.each(["height", "width"], function( i, name ) { 5390 jQuery.cssHooks[ name ] = { 5391 get: function( elem, computed, extra ) { 5392 var val; 5393 5394 if ( computed ) { 5395 if ( elem.offsetWidth !== 0 ) { 5396 val = getWH( elem, name, extra ); 5397 5398 } else { 5399 jQuery.swap( elem, cssShow, function() { 5400 val = getWH( elem, name, extra ); 5401 }); 5402 } 5403 5404 if ( val <= 0 ) { 5405 val = curCSS( elem, name, name ); 5406 5407 if ( val === "0px" && currentStyle ) { 5408 val = currentStyle( elem, name, name ); 5409 } 5410 5411 if ( val != null ) { 5412 // Should return "auto" instead of 0, use 0 for 5413 // temporary backwards-compat 5414 return val === "" || val === "auto" ? "0px" : val; 5415 } 5416 } 5417 5418 if ( val < 0 || val == null ) { 5419 val = elem.style[ name ]; 5420 5421 // Should return "auto" instead of 0, use 0 for 5422 // temporary backwards-compat 5423 return val === "" || val === "auto" ? "0px" : val; 5424 } 5425 5426 return typeof val === "string" ? val : val + "px"; 5427 } 5428 }, 5429 5430 set: function( elem, value ) { 5431 if ( rnumpx.test( value ) ) { 5432 // ignore negative width and height values #1599 5433 value = parseFloat(value); 5434 5435 if ( value >= 0 ) { 5436 return value + "px"; 5437 } 5438 5439 } else { 5440 return value; 5441 } 5442 } 5443 }; 5444 }); 5445 5446 if ( !jQuery.support.opacity ) { 5447 jQuery.cssHooks.opacity = { 5448 get: function( elem, computed ) { 5449 // IE uses filters for opacity 5450 return ropacity.test((computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "") ? 5451 (parseFloat(RegExp.$1) / 100) + "" : 5452 computed ? "1" : ""; 5453 }, 5454 5455 set: function( elem, value ) { 5456 var style = elem.style; 5457 5458 // IE has trouble with opacity if it does not have layout 5459 // Force it by setting the zoom level 5460 style.zoom = 1; 5461 5462 // Set the alpha filter to set the opacity 5463 var opacity = jQuery.isNaN(value) ? 5464 "" : 5465 "alpha(opacity=" + value * 100 + ")", 5466 filter = style.filter || ""; 5467 5468 style.filter = ralpha.test(filter) ? 5469 filter.replace(ralpha, opacity) : 5470 style.filter + ' ' + opacity; 5471 } 5472 }; 5473 } 5474 5475 if ( document.defaultView && document.defaultView.getComputedStyle ) { 5476 getComputedStyle = function( elem, newName, name ) { 5477 var ret, defaultView, computedStyle; 5478 5479 name = name.replace( rupper, "-$1" ).toLowerCase(); 5480 5481 if ( !(defaultView = elem.ownerDocument.defaultView) ) { 5482 return undefined; 5483 } 5484 5485 if ( (computedStyle = defaultView.getComputedStyle( elem, null )) ) { 5486 ret = computedStyle.getPropertyValue( name ); 5487 if ( ret === "" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) { 5488 ret = jQuery.style( elem, name ); 5489 } 5490 } 5491 5492 return ret; 5493 }; 5494 } 5495 5496 if ( document.documentElement.currentStyle ) { 5497 currentStyle = function( elem, name ) { 5498 var left, rsLeft, 5499 ret = elem.currentStyle && elem.currentStyle[ name ], 5500 style = elem.style; 5501 5502 // From the awesome hack by Dean Edwards 5503 // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 5504 5505 // If we're not dealing with a regular pixel number 5506 // but a number that has a weird ending, we need to convert it to pixels 5507 if ( !rnumpx.test( ret ) && rnum.test( ret ) ) { 5508 // Remember the original values 5509 left = style.left; 5510 rsLeft = elem.runtimeStyle.left; 5511 5512 // Put in the new values to get a computed value out 5513 elem.runtimeStyle.left = elem.currentStyle.left; 5514 style.left = name === "fontSize" ? "1em" : (ret || 0); 5515 ret = style.pixelLeft + "px"; 5516 5517 // Revert the changed values 5518 style.left = left; 5519 elem.runtimeStyle.left = rsLeft; 5520 } 5521 5522 return ret === "" ? "auto" : ret; 5523 }; 5524 } 5525 5526 curCSS = getComputedStyle || currentStyle; 5527 5528 function getWH( elem, name, extra ) { 5529 var which = name === "width" ? cssWidth : cssHeight, 5530 val = name === "width" ? elem.offsetWidth : elem.offsetHeight; 5531 5532 if ( extra === "border" ) { 5533 return val; 5534 } 5535 5536 jQuery.each( which, function() { 5537 if ( !extra ) { 5538 val -= parseFloat(jQuery.css( elem, "padding" + this )) || 0; 5539 } 5540 5541 if ( extra === "margin" ) { 5542 val += parseFloat(jQuery.css( elem, "margin" + this )) || 0; 5543 5544 } else { 5545 val -= parseFloat(jQuery.css( elem, "border" + this + "Width" )) || 0; 5546 } 5547 }); 5548 5549 return val; 5550 } 5551 5552 if ( jQuery.expr && jQuery.expr.filters ) { 5553 jQuery.expr.filters.hidden = function( elem ) { 5554 var width = elem.offsetWidth, 5555 height = elem.offsetHeight; 5556 5557 return (width === 0 && height === 0) || (!jQuery.support.reliableHiddenOffsets && (elem.style.display || jQuery.css( elem, "display" )) === "none"); 5558 }; 5559 5560 jQuery.expr.filters.visible = function( elem ) { 5561 return !jQuery.expr.filters.hidden( elem ); 5562 }; 5563 } 5564 5565 5566 5567 5568 var jsc = jQuery.now(), 5569 rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, 5570 rselectTextarea = /^(?:select|textarea)/i, 5571 rinput = /^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i, 5572 rnoContent = /^(?:GET|HEAD)$/, 5573 rbracket = /\[\]$/, 5574 jsre = /\=\?(&|$)/, 5575 rquery = /\?/, 5576 rts = /([?&])_=[^&]*/, 5577 rurl = /^(\w+:)?\/\/([^\/?#]+)/, 5578 r20 = /%20/g, 5579 rhash = /#.*$/, 5580 5581 // Keep a copy of the old load method 5582 _load = jQuery.fn.load; 5583 5584 jQuery.fn.extend({ 5585 load: function( url, params, callback ) { 5586 if ( typeof url !== "string" && _load ) { 5587 return _load.apply( this, arguments ); 5588 5589 // Don't do a request if no elements are being requested 5590 } else if ( !this.length ) { 5591 return this; 5592 } 5593 5594 var off = url.indexOf(" "); 5595 if ( off >= 0 ) { 5596 var selector = url.slice(off, url.length); 5597 url = url.slice(0, off); 5598 } 5599 5600 // Default to a GET request 5601 var type = "GET"; 5602 5603 // If the second parameter was provided 5604 if ( params ) { 5605 // If it's a function 5606 if ( jQuery.isFunction( params ) ) { 5607 // We assume that it's the callback 5608 callback = params; 5609 params = null; 5610 5611 // Otherwise, build a param string 5612 } else if ( typeof params === "object" ) { 5613 params = jQuery.param( params, jQuery.ajaxSettings.traditional ); 5614 type = "POST"; 5615 } 5616 } 5617 5618 var self = this; 5619 5620 // Request the remote document 5621 jQuery.ajax({ 5622 url: url, 5623 type: type, 5624 dataType: "html", 5625 data: params, 5626 complete: function( res, status ) { 5627 // If successful, inject the HTML into all the matched elements 5628 if ( status === "success" || status === "notmodified" ) { 5629 // See if a selector was specified 5630 self.html( selector ? 5631 // Create a dummy div to hold the results 5632 jQuery("<div>") 5633 // inject the contents of the document in, removing the scripts 5634 // to avoid any 'Permission Denied' errors in IE 5635 .append(res.responseText.replace(rscript, "")) 5636 5637 // Locate the specified elements 5638 .find(selector) : 5639 5640 // If not, just inject the full result 5641 res.responseText ); 5642 } 5643 5644 if ( callback ) { 5645 self.each( callback, [res.responseText, status, res] ); 5646 } 5647 } 5648 }); 5649 5650 return this; 5651 }, 5652 5653 serialize: function() { 5654 return jQuery.param(this.serializeArray()); 5655 }, 5656 5657 serializeArray: function() { 5658 return this.map(function() { 5659 return this.elements ? jQuery.makeArray(this.elements) : this; 5660 }) 5661 .filter(function() { 5662 return this.name && !this.disabled && 5663 (this.checked || rselectTextarea.test(this.nodeName) || 5664 rinput.test(this.type)); 5665 }) 5666 .map(function( i, elem ) { 5667 var val = jQuery(this).val(); 5668 5669 return val == null ? 5670 null : 5671 jQuery.isArray(val) ? 5672 jQuery.map( val, function( val, i ) { 5673 return { name: elem.name, value: val }; 5674 }) : 5675 { name: elem.name, value: val }; 5676 }).get(); 5677 } 5678 }); 5679 5680 // Attach a bunch of functions for handling common AJAX events 5681 jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "), function( i, o ) { 5682 jQuery.fn[o] = function( f ) { 5683 return this.bind(o, f); 5684 }; 5685 }); 5686 5687 jQuery.extend({ 5688 get: function( url, data, callback, type ) { 5689 // shift arguments if data argument was omited 5690 if ( jQuery.isFunction( data ) ) { 5691 type = type || callback; 5692 callback = data; 5693 data = null; 5694 } 5695 5696 return jQuery.ajax({ 5697 type: "GET", 5698 url: url, 5699 data: data, 5700 success: callback, 5701 dataType: type 5702 }); 5703 }, 5704 5705 getScript: function( url, callback ) { 5706 return jQuery.get(url, null, callback, "script"); 5707 }, 5708 5709 getJSON: function( url, data, callback ) { 5710 return jQuery.get(url, data, callback, "json"); 5711 }, 5712 5713 post: function( url, data, callback, type ) { 5714 // shift arguments if data argument was omited 5715 if ( jQuery.isFunction( data ) ) { 5716 type = type || callback; 5717 callback = data; 5718 data = {}; 5719 } 5720 5721 return jQuery.ajax({ 5722 type: "POST", 5723 url: url, 5724 data: data, 5725 success: callback, 5726 dataType: type 5727 }); 5728 }, 5729 5730 ajaxSetup: function( settings ) { 5731 jQuery.extend( jQuery.ajaxSettings, settings ); 5732 }, 5733 5734 ajaxSettings: { 5735 url: location.href, 5736 global: true, 5737 type: "GET", 5738 contentType: "application/x-www-form-urlencoded", 5739 processData: true, 5740 async: true, 5741 /* 5742 timeout: 0, 5743 data: null, 5744 username: null, 5745 password: null, 5746 traditional: false, 5747 */ 5748 // This function can be overriden by calling jQuery.ajaxSetup 5749 xhr: function() { 5750 return new window.XMLHttpRequest(); 5751 }, 5752 accepts: { 5753 xml: "application/xml, text/xml", 5754 html: "text/html", 5755 script: "text/javascript, application/javascript", 5756 json: "application/json, text/javascript", 5757 text: "text/plain", 5758 _default: "*/*" 5759 } 5760 }, 5761 5762 ajax: function( origSettings ) { 5763 var s = jQuery.extend(true, {}, jQuery.ajaxSettings, origSettings), 5764 jsonp, status, data, type = s.type.toUpperCase(), noContent = rnoContent.test(type); 5765 5766 s.url = s.url.replace( rhash, "" ); 5767 5768 // Use original (not extended) context object if it was provided 5769 s.context = origSettings && origSettings.context != null ? origSettings.context : s; 5770 5771 // convert data if not already a string 5772 if ( s.data && s.processData && typeof s.data !== "string" ) { 5773 s.data = jQuery.param( s.data, s.traditional ); 5774 } 5775 5776 // Handle JSONP Parameter Callbacks 5777 if ( s.dataType === "jsonp" ) { 5778 if ( type === "GET" ) { 5779 if ( !jsre.test( s.url ) ) { 5780 s.url += (rquery.test( s.url ) ? "&" : "?") + (s.jsonp || "callback") + "=?"; 5781 } 5782 } else if ( !s.data || !jsre.test(s.data) ) { 5783 s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?"; 5784 } 5785 s.dataType = "json"; 5786 } 5787 5788 // Build temporary JSONP function 5789 if ( s.dataType === "json" && (s.data && jsre.test(s.data) || jsre.test(s.url)) ) { 5790 jsonp = s.jsonpCallback || ("jsonp" + jsc++); 5791 5792 // Replace the =? sequence both in the query string and the data 5793 if ( s.data ) { 5794 s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1"); 5795 } 5796 5797 s.url = s.url.replace(jsre, "=" + jsonp + "$1"); 5798 5799 // We need to make sure 5800 // that a JSONP style response is executed properly 5801 s.dataType = "script"; 5802 5803 // Handle JSONP-style loading 5804 var customJsonp = window[ jsonp ]; 5805 5806 window[ jsonp ] = function( tmp ) { 5807 if ( jQuery.isFunction( customJsonp ) ) { 5808 customJsonp( tmp ); 5809 5810 } else { 5811 // Garbage collect 5812 window[ jsonp ] = undefined; 5813 5814 try { 5815 delete window[ jsonp ]; 5816 } catch( jsonpError ) {} 5817 } 5818 5819 data = tmp; 5820 jQuery.handleSuccess( s, xhr, status, data ); 5821 jQuery.handleComplete( s, xhr, status, data ); 5822 5823 if ( head ) { 5824 head.removeChild( script ); 5825 } 5826 }; 5827 } 5828 5829 if ( s.dataType === "script" && s.cache === null ) { 5830 s.cache = false; 5831 } 5832 5833 if ( s.cache === false && noContent ) { 5834 var ts = jQuery.now(); 5835 5836 // try replacing _= if it is there 5837 var ret = s.url.replace(rts, "$1_=" + ts); 5838 5839 // if nothing was replaced, add timestamp to the end 5840 s.url = ret + ((ret === s.url) ? (rquery.test(s.url) ? "&" : "?") + "_=" + ts : ""); 5841 } 5842 5843 // If data is available, append data to url for GET/HEAD requests 5844 if ( s.data && noContent ) { 5845 s.url += (rquery.test(s.url) ? "&" : "?") + s.data; 5846 } 5847 5848 // Watch for a new set of requests 5849 if ( s.global && jQuery.active++ === 0 ) { 5850 jQuery.event.trigger( "ajaxStart" ); 5851 } 5852 5853 // Matches an absolute URL, and saves the domain 5854 var parts = rurl.exec( s.url ), 5855 remote = parts && (parts[1] && parts[1].toLowerCase() !== location.protocol || parts[2].toLowerCase() !== location.host); 5856 5857 // If we're requesting a remote document 5858 // and trying to load JSON or Script with a GET 5859 if ( s.dataType === "script" && type === "GET" && remote ) { 5860 var head = document.getElementsByTagName("head")[0] || document.documentElement; 5861 var script = document.createElement("script"); 5862 if ( s.scriptCharset ) { 5863 script.charset = s.scriptCharset; 5864 } 5865 script.src = s.url; 5866 5867 // Handle Script loading 5868 if ( !jsonp ) { 5869 var done = false; 5870 5871 // Attach handlers for all browsers 5872 script.onload = script.onreadystatechange = function() { 5873 if ( !done && (!this.readyState || 5874 this.readyState === "loaded" || this.readyState === "complete") ) { 5875 done = true; 5876 jQuery.handleSuccess( s, xhr, status, data ); 5877 jQuery.handleComplete( s, xhr, status, data ); 5878 5879 // Handle memory leak in IE 5880 script.onload = script.onreadystatechange = null; 5881 if ( head && script.parentNode ) { 5882 head.removeChild( script ); 5883 } 5884 } 5885 }; 5886 } 5887 5888 // Use insertBefore instead of appendChild to circumvent an IE6 bug. 5889 // This arises when a base node is used (#2709 and #4378). 5890 head.insertBefore( script, head.firstChild ); 5891 5892 // We handle everything using the script element injection 5893 return undefined; 5894 } 5895 5896 var requestDone = false; 5897 5898 // Create the request object 5899 var xhr = s.xhr(); 5900 5901 if ( !xhr ) { 5902 return; 5903 } 5904 5905 // Open the socket 5906 // Passing null username, generates a login popup on Opera (#2865) 5907 if ( s.username ) { 5908 xhr.open(type, s.url, s.async, s.username, s.password); 5909 } else { 5910 xhr.open(type, s.url, s.async); 5911 } 5912 5913 // Need an extra try/catch for cross domain requests in Firefox 3 5914 try { 5915 // Set content-type if data specified and content-body is valid for this type 5916 if ( (s.data != null && !noContent) || (origSettings && origSettings.contentType) ) { 5917 xhr.setRequestHeader("Content-Type", s.contentType); 5918 } 5919 5920 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. 5921 if ( s.ifModified ) { 5922 if ( jQuery.lastModified[s.url] ) { 5923 xhr.setRequestHeader("If-Modified-Since", jQuery.lastModified[s.url]); 5924 } 5925 5926 if ( jQuery.etag[s.url] ) { 5927 xhr.setRequestHeader("If-None-Match", jQuery.etag[s.url]); 5928 } 5929 } 5930 5931 // Set header so the called script knows that it's an XMLHttpRequest 5932 // Only send the header if it's not a remote XHR 5933 if ( !remote ) { 5934 xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); 5935 } 5936 5937 // Set the Accepts header for the server, depending on the dataType 5938 xhr.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ? 5939 s.accepts[ s.dataType ] + ", */*; q=0.01" : 5940 s.accepts._default ); 5941 } catch( headerError ) {} 5942 5943 // Allow custom headers/mimetypes and early abort 5944 if ( s.beforeSend && s.beforeSend.call(s.context, xhr, s) === false ) { 5945 // Handle the global AJAX counter 5946 if ( s.global && jQuery.active-- === 1 ) { 5947 jQuery.event.trigger( "ajaxStop" ); 5948 } 5949 5950 // close opended socket 5951 xhr.abort(); 5952 return false; 5953 } 5954 5955 if ( s.global ) { 5956 jQuery.triggerGlobal( s, "ajaxSend", [xhr, s] ); 5957 } 5958 5959 // Wait for a response to come back 5960 var onreadystatechange = xhr.onreadystatechange = function( isTimeout ) { 5961 // The request was aborted 5962 if ( !xhr || xhr.readyState === 0 || isTimeout === "abort" ) { 5963 // Opera doesn't call onreadystatechange before this point 5964 // so we simulate the call 5965 if ( !requestDone ) { 5966 jQuery.handleComplete( s, xhr, status, data ); 5967 } 5968 5969 requestDone = true; 5970 if ( xhr ) { 5971 xhr.onreadystatechange = jQuery.noop; 5972 } 5973 5974 // The transfer is complete and the data is available, or the request timed out 5975 } else if ( !requestDone && xhr && (xhr.readyState === 4 || isTimeout === "timeout") ) { 5976 requestDone = true; 5977 xhr.onreadystatechange = jQuery.noop; 5978 5979 status = isTimeout === "timeout" ? 5980 "timeout" : 5981 !jQuery.httpSuccess( xhr ) ? 5982 "error" : 5983 s.ifModified && jQuery.httpNotModified( xhr, s.url ) ? 5984 "notmodified" : 5985 "success"; 5986 5987 var errMsg; 5988 5989 if ( status === "success" ) { 5990 // Watch for, and catch, XML document parse errors 5991 try { 5992 // process the data (runs the xml through httpData regardless of callback) 5993 data = jQuery.httpData( xhr, s.dataType, s ); 5994 } catch( parserError ) { 5995 status = "parsererror"; 5996 errMsg = parserError; 5997 } 5998 } 5999 6000 // Make sure that the request was successful or notmodified 6001 if ( status === "success" || status === "notmodified" ) { 6002 // JSONP handles its own success callback 6003 if ( !jsonp ) { 6004 jQuery.handleSuccess( s, xhr, status, data ); 6005 } 6006 } else { 6007 jQuery.handleError( s, xhr, status, errMsg ); 6008 } 6009 6010 // Fire the complete handlers 6011 if ( !jsonp ) { 6012 jQuery.handleComplete( s, xhr, status, data ); 6013 } 6014 6015 if ( isTimeout === "timeout" ) { 6016 xhr.abort(); 6017 } 6018 6019 // Stop memory leaks 6020 if ( s.async ) { 6021 xhr = null; 6022 } 6023 } 6024 }; 6025 6026 // Override the abort handler, if we can (IE 6 doesn't allow it, but that's OK) 6027 // Opera doesn't fire onreadystatechange at all on abort 6028 try { 6029 var oldAbort = xhr.abort; 6030 xhr.abort = function() { 6031 if ( xhr ) { 6032 // oldAbort has no call property in IE7 so 6033 // just do it this way, which works in all 6034 // browsers 6035 Function.prototype.call.call( oldAbort, xhr ); 6036 } 6037 6038 onreadystatechange( "abort" ); 6039 }; 6040 } catch( abortError ) {} 6041 6042 // Timeout checker 6043 if ( s.async && s.timeout > 0 ) { 6044 setTimeout(function() { 6045 // Check to see if the request is still happening 6046 if ( xhr && !requestDone ) { 6047 onreadystatechange( "timeout" ); 6048 } 6049 }, s.timeout); 6050 } 6051 6052 // Send the data 6053 try { 6054 xhr.send( noContent || s.data == null ? null : s.data ); 6055 6056 } catch( sendError ) { 6057 jQuery.handleError( s, xhr, null, sendError ); 6058 6059 // Fire the complete handlers 6060 jQuery.handleComplete( s, xhr, status, data ); 6061 } 6062 6063 // firefox 1.5 doesn't fire statechange for sync requests 6064 if ( !s.async ) { 6065 onreadystatechange(); 6066 } 6067 6068 // return XMLHttpRequest to allow aborting the request etc. 6069 return xhr; 6070 }, 6071 6072 // Serialize an array of form elements or a set of 6073 // key/values into a query string 6074 param: function( a, traditional ) { 6075 var s = [], 6076 add = function( key, value ) { 6077 // If value is a function, invoke it and return its value 6078 value = jQuery.isFunction(value) ? value() : value; 6079 s[ s.length ] = encodeURIComponent(key) + "=" + encodeURIComponent(value); 6080 }; 6081 6082 // Set traditional to true for jQuery <= 1.3.2 behavior. 6083 if ( traditional === undefined ) { 6084 traditional = jQuery.ajaxSettings.traditional; 6085 } 6086 6087 // If an array was passed in, assume that it is an array of form elements. 6088 if ( jQuery.isArray(a) || a.jquery ) { 6089 // Serialize the form elements 6090 jQuery.each( a, function() { 6091 add( this.name, this.value ); 6092 }); 6093 6094 } else { 6095 // If traditional, encode the "old" way (the way 1.3.2 or older 6096 // did it), otherwise encode params recursively. 6097 for ( var prefix in a ) { 6098 buildParams( prefix, a[prefix], traditional, add ); 6099 } 6100 } 6101 6102 // Return the resulting serialization 6103 return s.join("&").replace(r20, "+"); 6104 } 6105 }); 6106 6107 function buildParams( prefix, obj, traditional, add ) { 6108 if ( jQuery.isArray(obj) && obj.length ) { 6109 // Serialize array item. 6110 jQuery.each( obj, function( i, v ) { 6111 if ( traditional || rbracket.test( prefix ) ) { 6112 // Treat each array item as a scalar. 6113 add( prefix, v ); 6114 6115 } else { 6116 // If array item is non-scalar (array or object), encode its 6117 // numeric index to resolve deserialization ambiguity issues. 6118 // Note that rack (as of 1.0.0) can't currently deserialize 6119 // nested arrays properly, and attempting to do so may cause 6120 // a server error. Possible fixes are to modify rack's 6121 // deserialization algorithm or to provide an option or flag 6122 // to force array serialization to be shallow. 6123 buildParams( prefix + "[" + ( typeof v === "object" || jQuery.isArray(v) ? i : "" ) + "]", v, traditional, add ); 6124 } 6125 }); 6126 6127 } else if ( !traditional && obj != null && typeof obj === "object" ) { 6128 if ( jQuery.isEmptyObject( obj ) ) { 6129 add( prefix, "" ); 6130 6131 // Serialize object item. 6132 } else { 6133 jQuery.each( obj, function( k, v ) { 6134 buildParams( prefix + "[" + k + "]", v, traditional, add ); 6135 }); 6136 } 6137 6138 } else { 6139 // Serialize scalar item. 6140 add( prefix, obj ); 6141 } 6142 } 6143 6144 // This is still on the jQuery object... for now 6145 // Want to move this to jQuery.ajax some day 6146 jQuery.extend({ 6147 6148 // Counter for holding the number of active queries 6149 active: 0, 6150 6151 // Last-Modified header cache for next request 6152 lastModified: {}, 6153 etag: {}, 6154 6155 handleError: function( s, xhr, status, e ) { 6156 // If a local callback was specified, fire it 6157 if ( s.error ) { 6158 s.error.call( s.context, xhr, status, e ); 6159 } 6160 6161 // Fire the global callback 6162 if ( s.global ) { 6163 jQuery.triggerGlobal( s, "ajaxError", [xhr, s, e] ); 6164 } 6165 }, 6166 6167 handleSuccess: function( s, xhr, status, data ) { 6168 // If a local callback was specified, fire it and pass it the data 6169 if ( s.success ) { 6170 s.success.call( s.context, data, status, xhr ); 6171 } 6172 6173 // Fire the global callback 6174 if ( s.global ) { 6175 jQuery.triggerGlobal( s, "ajaxSuccess", [xhr, s] ); 6176 } 6177 }, 6178 6179 handleComplete: function( s, xhr, status ) { 6180 // Process result 6181 if ( s.complete ) { 6182 s.complete.call( s.context, xhr, status ); 6183 } 6184 6185 // The request was completed 6186 if ( s.global ) { 6187 jQuery.triggerGlobal( s, "ajaxComplete", [xhr, s] ); 6188 } 6189 6190 // Handle the global AJAX counter 6191 if ( s.global && jQuery.active-- === 1 ) { 6192 jQuery.event.trigger( "ajaxStop" ); 6193 } 6194 }, 6195 6196 triggerGlobal: function( s, type, args ) { 6197 (s.context && s.context.url == null ? jQuery(s.context) : jQuery.event).trigger(type, args); 6198 }, 6199 6200 // Determines if an XMLHttpRequest was successful or not 6201 httpSuccess: function( xhr ) { 6202 try { 6203 // IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450 6204 return !xhr.status && location.protocol === "file:" || 6205 xhr.status >= 200 && xhr.status < 300 || 6206 xhr.status === 304 || xhr.status === 1223; 6207 } catch(e) {} 6208 6209 return false; 6210 }, 6211 6212 // Determines if an XMLHttpRequest returns NotModified 6213 httpNotModified: function( xhr, url ) { 6214 var lastModified = xhr.getResponseHeader("Last-Modified"), 6215 etag = xhr.getResponseHeader("Etag"); 6216 6217 if ( lastModified ) { 6218 jQuery.lastModified[url] = lastModified; 6219 } 6220 6221 if ( etag ) { 6222 jQuery.etag[url] = etag; 6223 } 6224 6225 return xhr.status === 304; 6226 }, 6227 6228 httpData: function( xhr, type, s ) { 6229 var ct = xhr.getResponseHeader("content-type") || "", 6230 xml = type === "xml" || !type && ct.indexOf("xml") >= 0, 6231 data = xml ? xhr.responseXML : xhr.responseText; 6232 6233 if ( xml && data.documentElement.nodeName === "parsererror" ) { 6234 jQuery.error( "parsererror" ); 6235 } 6236 6237 // Allow a pre-filtering function to sanitize the response 6238 // s is checked to keep backwards compatibility 6239 if ( s && s.dataFilter ) { 6240 data = s.dataFilter( data, type ); 6241 } 6242 6243 // The filter can actually parse the response 6244 if ( typeof data === "string" ) { 6245 // Get the JavaScript object, if JSON is used. 6246 if ( type === "json" || !type && ct.indexOf("json") >= 0 ) { 6247 data = jQuery.parseJSON( data ); 6248 6249 // If the type is "script", eval it in global context 6250 } else if ( type === "script" || !type && ct.indexOf("javascript") >= 0 ) { 6251 jQuery.globalEval( data ); 6252 } 6253 } 6254 6255 return data; 6256 } 6257 6258 }); 6259 6260 /* 6261 * Create the request object; Microsoft failed to properly 6262 * implement the XMLHttpRequest in IE7 (can't request local files), 6263 * so we use the ActiveXObject when it is available 6264 * Additionally XMLHttpRequest can be disabled in IE7/IE8 so 6265 * we need a fallback. 6266 */ 6267 if ( window.ActiveXObject ) { 6268 jQuery.ajaxSettings.xhr = function() { 6269 if ( window.location.protocol !== "file:" ) { 6270 try { 6271 return new window.XMLHttpRequest(); 6272 } catch(xhrError) {} 6273 } 6274 6275 try { 6276 return new window.ActiveXObject("Microsoft.XMLHTTP"); 6277 } catch(activeError) {} 6278 }; 6279 } 6280 6281 // Does this browser support XHR requests? 6282 jQuery.support.ajax = !!jQuery.ajaxSettings.xhr(); 6283 6284 6285 6286 6287 var elemdisplay = {}, 6288 rfxtypes = /^(?:toggle|show|hide)$/, 6289 rfxnum = /^([+\-]=)?([\d+.\-]+)(.*)$/, 6290 timerId, 6291 fxAttrs = [ 6292 // height animations 6293 [ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ], 6294 // width animations 6295 [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ], 6296 // opacity animations 6297 [ "opacity" ] 6298 ]; 6299 6300 jQuery.fn.extend({ 6301 show: function( speed, easing, callback ) { 6302 var elem, display; 6303 6304 if ( speed || speed === 0 ) { 6305 return this.animate( genFx("show", 3), speed, easing, callback); 6306 6307 } else { 6308 for ( var i = 0, j = this.length; i < j; i++ ) { 6309 elem = this[i]; 6310 display = elem.style.display; 6311 6312 // Reset the inline display of this element to learn if it is 6313 // being hidden by cascaded rules or not 6314 if ( !jQuery.data(elem, "olddisplay") && display === "none" ) { 6315 display = elem.style.display = ""; 6316 } 6317 6318 // Set elements which have been overridden with display: none 6319 // in a stylesheet to whatever the default browser style is 6320 // for such an element 6321 if ( display === "" && jQuery.css( elem, "display" ) === "none" ) { 6322 jQuery.data(elem, "olddisplay", defaultDisplay(elem.nodeName)); 6323 } 6324 } 6325 6326 // Set the display of most of the elements in a second loop 6327 // to avoid the constant reflow 6328 for ( i = 0; i < j; i++ ) { 6329 elem = this[i]; 6330 display = elem.style.display; 6331 6332 if ( display === "" || display === "none" ) { 6333 elem.style.display = jQuery.data(elem, "olddisplay") || ""; 6334 } 6335 } 6336 6337 return this; 6338 } 6339 }, 6340 6341 hide: function( speed, easing, callback ) { 6342 if ( speed || speed === 0 ) { 6343 return this.animate( genFx("hide", 3), speed, easing, callback); 6344 6345 } else { 6346 for ( var i = 0, j = this.length; i < j; i++ ) { 6347 var display = jQuery.css( this[i], "display" ); 6348 6349 if ( display !== "none" ) { 6350 jQuery.data( this[i], "olddisplay", display ); 6351 } 6352 } 6353 6354 // Set the display of the elements in a second loop 6355 // to avoid the constant reflow 6356 for ( i = 0; i < j; i++ ) { 6357 this[i].style.display = "none"; 6358 } 6359 6360 return this; 6361 } 6362 }, 6363 6364 // Save the old toggle function 6365 _toggle: jQuery.fn.toggle, 6366 6367 toggle: function( fn, fn2, callback ) { 6368 var bool = typeof fn === "boolean"; 6369 6370 if ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) { 6371 this._toggle.apply( this, arguments ); 6372 6373 } else if ( fn == null || bool ) { 6374 this.each(function() { 6375 var state = bool ? fn : jQuery(this).is(":hidden"); 6376 jQuery(this)[ state ? "show" : "hide" ](); 6377 }); 6378 6379 } else { 6380 this.animate(genFx("toggle", 3), fn, fn2, callback); 6381 } 6382 6383 return this; 6384 }, 6385 6386 fadeTo: function( speed, to, easing, callback ) { 6387 return this.filter(":hidden").css("opacity", 0).show().end() 6388 .animate({opacity: to}, speed, easing, callback); 6389 }, 6390 6391 animate: function( prop, speed, easing, callback ) { 6392 var optall = jQuery.speed(speed, easing, callback); 6393 6394 if ( jQuery.isEmptyObject( prop ) ) { 6395 return this.each( optall.complete ); 6396 } 6397 6398 return this[ optall.queue === false ? "each" : "queue" ](function() { 6399 // XXX 'this' does not always have a nodeName when running the 6400 // test suite 6401 6402 var opt = jQuery.extend({}, optall), p, 6403 isElement = this.nodeType === 1, 6404 hidden = isElement && jQuery(this).is(":hidden"), 6405 self = this; 6406 6407 for ( p in prop ) { 6408 var name = jQuery.camelCase( p ); 6409 6410 if ( p !== name ) { 6411 prop[ name ] = prop[ p ]; 6412 delete prop[ p ]; 6413 p = name; 6414 } 6415 6416 if ( prop[p] === "hide" && hidden || prop[p] === "show" && !hidden ) { 6417 return opt.complete.call(this); 6418 } 6419 6420 if ( isElement && ( p === "height" || p === "width" ) ) { 6421 // Make sure that nothing sneaks out 6422 // Record all 3 overflow attributes because IE does not 6423 // change the overflow attribute when overflowX and 6424 // overflowY are set to the same value 6425 opt.overflow = [ this.style.overflow, this.style.overflowX, this.style.overflowY ]; 6426 6427 // Set display property to inline-block for height/width 6428 // animations on inline elements that are having width/height 6429 // animated 6430 if ( jQuery.css( this, "display" ) === "inline" && 6431 jQuery.css( this, "float" ) === "none" ) { 6432 if ( !jQuery.support.inlineBlockNeedsLayout ) { 6433 this.style.display = "inline-block"; 6434 6435 } else { 6436 var display = defaultDisplay(this.nodeName); 6437 6438 // inline-level elements accept inline-block; 6439 // block-level elements need to be inline with layout 6440 if ( display === "inline" ) { 6441 this.style.display = "inline-block"; 6442 6443 } else { 6444 this.style.display = "inline"; 6445 this.style.zoom = 1; 6446 } 6447 } 6448 } 6449 } 6450 6451 if ( jQuery.isArray( prop[p] ) ) { 6452 // Create (if needed) and add to specialEasing 6453 (opt.specialEasing = opt.specialEasing || {})[p] = prop[p][1]; 6454 prop[p] = prop[p][0]; 6455 } 6456 } 6457 6458 if ( opt.overflow != null ) { 6459 this.style.overflow = "hidden"; 6460 } 6461 6462 opt.curAnim = jQuery.extend({}, prop); 6463 6464 jQuery.each( prop, function( name, val ) { 6465 var e = new jQuery.fx( self, opt, name ); 6466 6467 if ( rfxtypes.test(val) ) { 6468 e[ val === "toggle" ? hidden ? "show" : "hide" : val ]( prop ); 6469 6470 } else { 6471 var parts = rfxnum.exec(val), 6472 start = e.cur() || 0; 6473 6474 if ( parts ) { 6475 var end = parseFloat( parts[2] ), 6476 unit = parts[3] || "px"; 6477 6478 // We need to compute starting value 6479 if ( unit !== "px" ) { 6480 jQuery.style( self, name, (end || 1) + unit); 6481 start = ((end || 1) / e.cur()) * start; 6482 jQuery.style( self, name, start + unit); 6483 } 6484 6485 // If a +=/-= token was provided, we're doing a relative animation 6486 if ( parts[1] ) { 6487 end = ((parts[1] === "-=" ? -1 : 1) * end) + start; 6488 } 6489 6490 e.custom( start, end, unit ); 6491 6492 } else { 6493 e.custom( start, val, "" ); 6494 } 6495 } 6496 }); 6497 6498 // For JS strict compliance 6499 return true; 6500 }); 6501 }, 6502 6503 stop: function( clearQueue, gotoEnd ) { 6504 var timers = jQuery.timers; 6505 6506 if ( clearQueue ) { 6507 this.queue([]); 6508 } 6509 6510 this.each(function() { 6511 // go in reverse order so anything added to the queue during the loop is ignored 6512 for ( var i = timers.length - 1; i >= 0; i-- ) { 6513 if ( timers[i].elem === this ) { 6514 if (gotoEnd) { 6515 // force the next step to be the last 6516 timers[i](true); 6517 } 6518 6519 timers.splice(i, 1); 6520 } 6521 } 6522 }); 6523 6524 // start the next in the queue if the last step wasn't forced 6525 if ( !gotoEnd ) { 6526 this.dequeue(); 6527 } 6528 6529 return this; 6530 } 6531 6532 }); 6533 6534 function genFx( type, num ) { 6535 var obj = {}; 6536 6537 jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function() { 6538 obj[ this ] = type; 6539 }); 6540 6541 return obj; 6542 } 6543 6544 // Generate shortcuts for custom animations 6545 jQuery.each({ 6546 slideDown: genFx("show", 1), 6547 slideUp: genFx("hide", 1), 6548 slideToggle: genFx("toggle", 1), 6549 fadeIn: { opacity: "show" }, 6550 fadeOut: { opacity: "hide" }, 6551 fadeToggle: { opacity: "toggle" } 6552 }, function( name, props ) { 6553 jQuery.fn[ name ] = function( speed, easing, callback ) { 6554 return this.animate( props, speed, easing, callback ); 6555 }; 6556 }); 6557 6558 jQuery.extend({ 6559 speed: function( speed, easing, fn ) { 6560 var opt = speed && typeof speed === "object" ? jQuery.extend({}, speed) : { 6561 complete: fn || !fn && easing || 6562 jQuery.isFunction( speed ) && speed, 6563 duration: speed, 6564 easing: fn && easing || easing && !jQuery.isFunction(easing) && easing 6565 }; 6566 6567 opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration : 6568 opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[opt.duration] : jQuery.fx.speeds._default; 6569 6570 // Queueing 6571 opt.old = opt.complete; 6572 opt.complete = function() { 6573 if ( opt.queue !== false ) { 6574 jQuery(this).dequeue(); 6575 } 6576 if ( jQuery.isFunction( opt.old ) ) { 6577 opt.old.call( this ); 6578 } 6579 }; 6580 6581 return opt; 6582 }, 6583 6584 easing: { 6585 linear: function( p, n, firstNum, diff ) { 6586 return firstNum + diff * p; 6587 }, 6588 swing: function( p, n, firstNum, diff ) { 6589 return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum; 6590 } 6591 }, 6592 6593 timers: [], 6594 6595 fx: function( elem, options, prop ) { 6596 this.options = options; 6597 this.elem = elem; 6598 this.prop = prop; 6599 6600 if ( !options.orig ) { 6601 options.orig = {}; 6602 } 6603 } 6604 6605 }); 6606 6607 jQuery.fx.prototype = { 6608 // Simple function for setting a style value 6609 update: function() { 6610 if ( this.options.step ) { 6611 this.options.step.call( this.elem, this.now, this ); 6612 } 6613 6614 (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this ); 6615 }, 6616 6617 // Get the current size 6618 cur: function() { 6619 if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) ) { 6620 return this.elem[ this.prop ]; 6621 } 6622 6623 var r = parseFloat( jQuery.css( this.elem, this.prop ) ); 6624 return r && r > -10000 ? r : 0; 6625 }, 6626 6627 // Start an animation from one number to another 6628 custom: function( from, to, unit ) { 6629 var self = this, 6630 fx = jQuery.fx; 6631 6632 this.startTime = jQuery.now(); 6633 this.start = from; 6634 this.end = to; 6635 this.unit = unit || this.unit || "px"; 6636 this.now = this.start; 6637 this.pos = this.state = 0; 6638 6639 function t( gotoEnd ) { 6640 return self.step(gotoEnd); 6641 } 6642 6643 t.elem = this.elem; 6644 6645 if ( t() && jQuery.timers.push(t) && !timerId ) { 6646 timerId = setInterval(fx.tick, fx.interval); 6647 } 6648 }, 6649 6650 // Simple 'show' function 6651 show: function() { 6652 // Remember where we started, so that we can go back to it later 6653 this.options.orig[this.prop] = jQuery.style( this.elem, this.prop ); 6654 this.options.show = true; 6655 6656 // Begin the animation 6657 // Make sure that we start at a small width/height to avoid any 6658 // flash of content 6659 this.custom(this.prop === "width" || this.prop === "height" ? 1 : 0, this.cur()); 6660 6661 // Start by showing the element 6662 jQuery( this.elem ).show(); 6663 }, 6664 6665 // Simple 'hide' function 6666 hide: function() { 6667 // Remember where we started, so that we can go back to it later 6668 this.options.orig[this.prop] = jQuery.style( this.elem, this.prop ); 6669 this.options.hide = true; 6670 6671 // Begin the animation 6672 this.custom(this.cur(), 0); 6673 }, 6674 6675 // Each step of an animation 6676 step: function( gotoEnd ) { 6677 var t = jQuery.now(), done = true; 6678 6679 if ( gotoEnd || t >= this.options.duration + this.startTime ) { 6680 this.now = this.end; 6681 this.pos = this.state = 1; 6682 this.update(); 6683 6684 this.options.curAnim[ this.prop ] = true; 6685 6686 for ( var i in this.options.curAnim ) { 6687 if ( this.options.curAnim[i] !== true ) { 6688 done = false; 6689 } 6690 } 6691 6692 if ( done ) { 6693 // Reset the overflow 6694 if ( this.options.overflow != null && !jQuery.support.shrinkWrapBlocks ) { 6695 var elem = this.elem, 6696 options = this.options; 6697 6698 jQuery.each( [ "", "X", "Y" ], function (index, value) { 6699 elem.style[ "overflow" + value ] = options.overflow[index]; 6700 } ); 6701 } 6702 6703 // Hide the element if the "hide" operation was done 6704 if ( this.options.hide ) { 6705 jQuery(this.elem).hide(); 6706 } 6707 6708 // Reset the properties, if the item has been hidden or shown 6709 if ( this.options.hide || this.options.show ) { 6710 for ( var p in this.options.curAnim ) { 6711 jQuery.style( this.elem, p, this.options.orig[p] ); 6712 } 6713 } 6714 6715 // Execute the complete function 6716 this.options.complete.call( this.elem ); 6717 } 6718 6719 return false; 6720 6721 } else { 6722 var n = t - this.startTime; 6723 this.state = n / this.options.duration; 6724 6725 // Perform the easing function, defaults to swing 6726 var specialEasing = this.options.specialEasing && this.options.specialEasing[this.prop]; 6727 var defaultEasing = this.options.easing || (jQuery.easing.swing ? "swing" : "linear"); 6728 this.pos = jQuery.easing[specialEasing || defaultEasing](this.state, n, 0, 1, this.options.duration); 6729 this.now = this.start + ((this.end - this.start) * this.pos); 6730 6731 // Perform the next step of the animation 6732 this.update(); 6733 } 6734 6735 return true; 6736 } 6737 }; 6738 6739 jQuery.extend( jQuery.fx, { 6740 tick: function() { 6741 var timers = jQuery.timers; 6742 6743 for ( var i = 0; i < timers.length; i++ ) { 6744 if ( !timers[i]() ) { 6745 timers.splice(i--, 1); 6746 } 6747 } 6748 6749 if ( !timers.length ) { 6750 jQuery.fx.stop(); 6751 } 6752 }, 6753 6754 interval: 13, 6755 6756 stop: function() { 6757 clearInterval( timerId ); 6758 timerId = null; 6759 }, 6760 6761 speeds: { 6762 slow: 600, 6763 fast: 200, 6764 // Default speed 6765 _default: 400 6766 }, 6767 6768 step: { 6769 opacity: function( fx ) { 6770 jQuery.style( fx.elem, "opacity", fx.now ); 6771 }, 6772 6773 _default: function( fx ) { 6774 if ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) { 6775 fx.elem.style[ fx.prop ] = (fx.prop === "width" || fx.prop === "height" ? Math.max(0, fx.now) : fx.now) + fx.unit; 6776 } else { 6777 fx.elem[ fx.prop ] = fx.now; 6778 } 6779 } 6780 } 6781 }); 6782 6783 if ( jQuery.expr && jQuery.expr.filters ) { 6784 jQuery.expr.filters.animated = function( elem ) { 6785 return jQuery.grep(jQuery.timers, function( fn ) { 6786 return elem === fn.elem; 6787 }).length; 6788 }; 6789 } 6790 6791 function defaultDisplay( nodeName ) { 6792 if ( !elemdisplay[ nodeName ] ) { 6793 var elem = jQuery("<" + nodeName + ">").appendTo("body"), 6794 display = elem.css("display"); 6795 6796 elem.remove(); 6797 6798 if ( display === "none" || display === "" ) { 6799 display = "block"; 6800 } 6801 6802 elemdisplay[ nodeName ] = display; 6803 } 6804 6805 return elemdisplay[ nodeName ]; 6806 } 6807 6808 6809 6810 6811 var rtable = /^t(?:able|d|h)$/i, 6812 rroot = /^(?:body|html)$/i; 6813 6814 if ( "getBoundingClientRect" in document.documentElement ) { 6815 jQuery.fn.offset = function( options ) { 6816 var elem = this[0], box; 6817 6818 if ( options ) { 6819 return this.each(function( i ) { 6820 jQuery.offset.setOffset( this, options, i ); 6821 }); 6822 } 6823 6824 if ( !elem || !elem.ownerDocument ) { 6825 return null; 6826 } 6827 6828 if ( elem === elem.ownerDocument.body ) { 6829 return jQuery.offset.bodyOffset( elem ); 6830 } 6831 6832 try { 6833 box = elem.getBoundingClientRect(); 6834 } catch(e) {} 6835 6836 var doc = elem.ownerDocument, 6837 docElem = doc.documentElement; 6838 6839 // Make sure we're not dealing with a disconnected DOM node 6840 if ( !box || !jQuery.contains( docElem, elem ) ) { 6841 return box || { top: 0, left: 0 }; 6842 } 6843 6844 var body = doc.body, 6845 win = getWindow(doc), 6846 clientTop = docElem.clientTop || body.clientTop || 0, 6847 clientLeft = docElem.clientLeft || body.clientLeft || 0, 6848 scrollTop = (win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop || body.scrollTop ), 6849 scrollLeft = (win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft), 6850 top = box.top + scrollTop - clientTop, 6851 left = box.left + scrollLeft - clientLeft; 6852 6853 return { top: top, left: left }; 6854 }; 6855 6856 } else { 6857 jQuery.fn.offset = function( options ) { 6858 var elem = this[0]; 6859 6860 if ( options ) { 6861 return this.each(function( i ) { 6862 jQuery.offset.setOffset( this, options, i ); 6863 }); 6864 } 6865 6866 if ( !elem || !elem.ownerDocument ) { 6867 return null; 6868 } 6869 6870 if ( elem === elem.ownerDocument.body ) { 6871 return jQuery.offset.bodyOffset( elem ); 6872 } 6873 6874 jQuery.offset.initialize(); 6875 6876 var computedStyle, 6877 offsetParent = elem.offsetParent, 6878 prevOffsetParent = elem, 6879 doc = elem.ownerDocument, 6880 docElem = doc.documentElement, 6881 body = doc.body, 6882 defaultView = doc.defaultView, 6883 prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle, 6884 top = elem.offsetTop, 6885 left = elem.offsetLeft; 6886 6887 while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) { 6888 if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) { 6889 break; 6890 } 6891 6892 computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle; 6893 top -= elem.scrollTop; 6894 left -= elem.scrollLeft; 6895 6896 if ( elem === offsetParent ) { 6897 top += elem.offsetTop; 6898 left += elem.offsetLeft; 6899 6900 if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && rtable.test(elem.nodeName)) ) { 6901 top += parseFloat( computedStyle.borderTopWidth ) || 0; 6902 left += parseFloat( computedStyle.borderLeftWidth ) || 0; 6903 } 6904 6905 prevOffsetParent = offsetParent; 6906 offsetParent = elem.offsetParent; 6907 } 6908 6909 if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) { 6910 top += parseFloat( computedStyle.borderTopWidth ) || 0; 6911 left += parseFloat( computedStyle.borderLeftWidth ) || 0; 6912 } 6913 6914 prevComputedStyle = computedStyle; 6915 } 6916 6917 if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) { 6918 top += body.offsetTop; 6919 left += body.offsetLeft; 6920 } 6921 6922 if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) { 6923 top += Math.max( docElem.scrollTop, body.scrollTop ); 6924 left += Math.max( docElem.scrollLeft, body.scrollLeft ); 6925 } 6926 6927 return { top: top, left: left }; 6928 }; 6929 } 6930 6931 jQuery.offset = { 6932 initialize: function() { 6933 var body = document.body, container = document.createElement("div"), innerDiv, checkDiv, table, td, bodyMarginTop = parseFloat( jQuery.css(body, "marginTop") ) || 0, 6934 html = "<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>"; 6935 6936 jQuery.extend( container.style, { position: "absolute", top: 0, left: 0, margin: 0, border: 0, width: "1px", height: "1px", visibility: "hidden" } ); 6937 6938 container.innerHTML = html; 6939 body.insertBefore( container, body.firstChild ); 6940 innerDiv = container.firstChild; 6941 checkDiv = innerDiv.firstChild; 6942 td = innerDiv.nextSibling.firstChild.firstChild; 6943 6944 this.doesNotAddBorder = (checkDiv.offsetTop !== 5); 6945 this.doesAddBorderForTableAndCells = (td.offsetTop === 5); 6946 6947 checkDiv.style.position = "fixed"; 6948 checkDiv.style.top = "20px"; 6949 6950 // safari subtracts parent border width here which is 5px 6951 this.supportsFixedPosition = (checkDiv.offsetTop === 20 || checkDiv.offsetTop === 15); 6952 checkDiv.style.position = checkDiv.style.top = ""; 6953 6954 innerDiv.style.overflow = "hidden"; 6955 innerDiv.style.position = "relative"; 6956 6957 this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5); 6958 6959 this.doesNotIncludeMarginInBodyOffset = (body.offsetTop !== bodyMarginTop); 6960 6961 body.removeChild( container ); 6962 body = container = innerDiv = checkDiv = table = td = null; 6963 jQuery.offset.initialize = jQuery.noop; 6964 }, 6965 6966 bodyOffset: function( body ) { 6967 var top = body.offsetTop, 6968 left = body.offsetLeft; 6969 6970 jQuery.offset.initialize(); 6971 6972 if ( jQuery.offset.doesNotIncludeMarginInBodyOffset ) { 6973 top += parseFloat( jQuery.css(body, "marginTop") ) || 0; 6974 left += parseFloat( jQuery.css(body, "marginLeft") ) || 0; 6975 } 6976 6977 return { top: top, left: left }; 6978 }, 6979 6980 setOffset: function( elem, options, i ) { 6981 var position = jQuery.css( elem, "position" ); 6982 6983 // set position first, in-case top/left are set even on static elem 6984 if ( position === "static" ) { 6985 elem.style.position = "relative"; 6986 } 6987 6988 var curElem = jQuery( elem ), 6989 curOffset = curElem.offset(), 6990 curCSSTop = jQuery.css( elem, "top" ), 6991 curCSSLeft = jQuery.css( elem, "left" ), 6992 calculatePosition = (position === "absolute" && jQuery.inArray('auto', [curCSSTop, curCSSLeft]) > -1), 6993 props = {}, curPosition = {}, curTop, curLeft; 6994 6995 // need to be able to calculate position if either top or left is auto and position is absolute 6996 if ( calculatePosition ) { 6997 curPosition = curElem.position(); 6998 } 6999 7000 curTop = calculatePosition ? curPosition.top : parseInt( curCSSTop, 10 ) || 0; 7001 curLeft = calculatePosition ? curPosition.left : parseInt( curCSSLeft, 10 ) || 0; 7002 7003 if ( jQuery.isFunction( options ) ) { 7004 options = options.call( elem, i, curOffset ); 7005 } 7006 7007 if (options.top != null) { 7008 props.top = (options.top - curOffset.top) + curTop; 7009 } 7010 if (options.left != null) { 7011 props.left = (options.left - curOffset.left) + curLeft; 7012 } 7013 7014 if ( "using" in options ) { 7015 options.using.call( elem, props ); 7016 } else { 7017 curElem.css( props ); 7018 } 7019 } 7020 }; 7021 7022 7023 jQuery.fn.extend({ 7024 position: function() { 7025 if ( !this[0] ) { 7026 return null; 7027 } 7028 7029 var elem = this[0], 7030 7031 // Get *real* offsetParent 7032 offsetParent = this.offsetParent(), 7033 7034 // Get correct offsets 7035 offset = this.offset(), 7036 parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset(); 7037 7038 // Subtract element margins 7039 // note: when an element has margin: auto the offsetLeft and marginLeft 7040 // are the same in Safari causing offset.left to incorrectly be 0 7041 offset.top -= parseFloat( jQuery.css(elem, "marginTop") ) || 0; 7042 offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0; 7043 7044 // Add offsetParent borders 7045 parentOffset.top += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0; 7046 parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0; 7047 7048 // Subtract the two offsets 7049 return { 7050 top: offset.top - parentOffset.top, 7051 left: offset.left - parentOffset.left 7052 }; 7053 }, 7054 7055 offsetParent: function() { 7056 return this.map(function() { 7057 var offsetParent = this.offsetParent || document.body; 7058 while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) { 7059 offsetParent = offsetParent.offsetParent; 7060 } 7061 return offsetParent; 7062 }); 7063 } 7064 }); 7065 7066 7067 // Create scrollLeft and scrollTop methods 7068 jQuery.each( ["Left", "Top"], function( i, name ) { 7069 var method = "scroll" + name; 7070 7071 jQuery.fn[ method ] = function(val) { 7072 var elem = this[0], win; 7073 7074 if ( !elem ) { 7075 return null; 7076 } 7077 7078 if ( val !== undefined ) { 7079 // Set the scroll offset 7080 return this.each(function() { 7081 win = getWindow( this ); 7082 7083 if ( win ) { 7084 win.scrollTo( 7085 !i ? val : jQuery(win).scrollLeft(), 7086 i ? val : jQuery(win).scrollTop() 7087 ); 7088 7089 } else { 7090 this[ method ] = val; 7091 } 7092 }); 7093 } else { 7094 win = getWindow( elem ); 7095 7096 // Return the scroll offset 7097 return win ? ("pageXOffset" in win) ? win[ i ? "pageYOffset" : "pageXOffset" ] : 7098 jQuery.support.boxModel && win.document.documentElement[ method ] || 7099 win.document.body[ method ] : 7100 elem[ method ]; 7101 } 7102 }; 7103 }); 7104 7105 function getWindow( elem ) { 7106 return jQuery.isWindow( elem ) ? 7107 elem : 7108 elem.nodeType === 9 ? 7109 elem.defaultView || elem.parentWindow : 7110 false; 7111 } 7112 7113 7114 7115 7116 // Create innerHeight, innerWidth, outerHeight and outerWidth methods 7117 jQuery.each([ "Height", "Width" ], function( i, name ) { 7118 7119 var type = name.toLowerCase(); 7120 7121 // innerHeight and innerWidth 7122 jQuery.fn["inner" + name] = function() { 7123 return this[0] ? 7124 parseFloat( jQuery.css( this[0], type, "padding" ) ) : 7125 null; 7126 }; 7127 7128 // outerHeight and outerWidth 7129 jQuery.fn["outer" + name] = function( margin ) { 7130 return this[0] ? 7131 parseFloat( jQuery.css( this[0], type, margin ? "margin" : "border" ) ) : 7132 null; 7133 }; 7134 7135 jQuery.fn[ type ] = function( size ) { 7136 // Get window width or height 7137 var elem = this[0]; 7138 if ( !elem ) { 7139 return size == null ? null : this; 7140 } 7141 7142 if ( jQuery.isFunction( size ) ) { 7143 return this.each(function( i ) { 7144 var self = jQuery( this ); 7145 self[ type ]( size.call( this, i, self[ type ]() ) ); 7146 }); 7147 } 7148 7149 if ( jQuery.isWindow( elem ) ) { 7150 // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode 7151 return elem.document.compatMode === "CSS1Compat" && elem.document.documentElement[ "client" + name ] || 7152 elem.document.body[ "client" + name ]; 7153 7154 // Get document width or height 7155 } else if ( elem.nodeType === 9 ) { 7156 // Either scroll[Width/Height] or offset[Width/Height], whichever is greater 7157 return Math.max( 7158 elem.documentElement["client" + name], 7159 elem.body["scroll" + name], elem.documentElement["scroll" + name], 7160 elem.body["offset" + name], elem.documentElement["offset" + name] 7161 ); 7162 7163 // Get or set width or height on the element 7164 } else if ( size === undefined ) { 7165 var orig = jQuery.css( elem, type ), 7166 ret = parseFloat( orig ); 7167 7168 return jQuery.isNaN( ret ) ? orig : ret; 7169 7170 // Set the width or height on the element (default to pixels if value is unitless) 7171 } else { 7172 return this.css( type, typeof size === "string" ? size : size + "px" ); 7173 } 7174 }; 7175 7176 }); 7177 7178 7179 })(window); -

WordPress源代码——jquery(jquery-1.4.2.js)
1 /*! 2 * jQuery JavaScript Library v1.4.2 3 * http://jquery.com/ 4 * 5 * Copyright 2010, John Resig 6 * Dual licensed under the MIT or GPL Version 2 licenses. 7 * http://jquery.org/license 8 * 9 * Includes Sizzle.js 10 * http://sizzlejs.com/ 11 * Copyright 2010, The Dojo Foundation 12 * Released under the MIT, BSD, and GPL Licenses. 13 * 14 * Date: Sat Feb 13 22:33:48 2010 -0500 15 */ 16 (function( window, undefined ) { 17 18 // Define a local copy of jQuery 19 var jQuery = function( selector, context ) { 20 // The jQuery object is actually just the init constructor 'enhanced' 21 return new jQuery.fn.init( selector, context ); 22 }, 23 24 // Map over jQuery in case of overwrite 25 _jQuery = window.jQuery, 26 27 // Map over the $ in case of overwrite 28 _$ = window.$, 29 30 // Use the correct document accordingly with window argument (sandbox) 31 document = window.document, 32 33 // A central reference to the root jQuery(document) 34 rootjQuery, 35 36 // A simple way to check for HTML strings or ID strings 37 // (both of which we optimize for) 38 quickExpr = /^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/, 39 40 // Is it a simple selector 41 isSimple = /^.[^:#\[\.,]*$/, 42 43 // Check if a string has a non-whitespace character in it 44 rnotwhite = /\S/, 45 46 // Used for trimming whitespace 47 rtrim = /^(\s|\u00A0)+|(\s|\u00A0)+$/g, 48 49 // Match a standalone tag 50 rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/, 51 52 // Keep a UserAgent string for use with jQuery.browser 53 userAgent = navigator.userAgent, 54 55 // For matching the engine and version of the browser 56 browserMatch, 57 58 // Has the ready events already been bound? 59 readyBound = false, 60 61 // The functions to execute on DOM ready 62 readyList = [], 63 64 // The ready event handler 65 DOMContentLoaded, 66 67 // Save a reference to some core methods 68 toString = Object.prototype.toString, 69 hasOwnProperty = Object.prototype.hasOwnProperty, 70 push = Array.prototype.push, 71 slice = Array.prototype.slice, 72 indexOf = Array.prototype.indexOf; 73 74 jQuery.fn = jQuery.prototype = { 75 init: function( selector, context ) { 76 var match, elem, ret, doc; 77 78 // Handle $(""), $(null), or $(undefined) 79 if ( !selector ) { 80 return this; 81 } 82 83 // Handle $(DOMElement) 84 if ( selector.nodeType ) { 85 this.context = this[0] = selector; 86 this.length = 1; 87 return this; 88 } 89 90 // The body element only exists once, optimize finding it 91 if ( selector === "body" && !context ) { 92 this.context = document; 93 this[0] = document.body; 94 this.selector = "body"; 95 this.length = 1; 96 return this; 97 } 98 99 // Handle HTML strings 100 if ( typeof selector === "string" ) { 101 // Are we dealing with HTML string or an ID? 102 match = quickExpr.exec( selector ); 103 104 // Verify a match, and that no context was specified for #id 105 if ( match && (match[1] || !context) ) { 106 107 // HANDLE: $(html) -> $(array) 108 if ( match[1] ) { 109 doc = (context ? context.ownerDocument || context : document); 110 111 // If a single string is passed in and it's a single tag 112 // just do a createElement and skip the rest 113 ret = rsingleTag.exec( selector ); 114 115 if ( ret ) { 116 if ( jQuery.isPlainObject( context ) ) { 117 selector = [ document.createElement( ret[1] ) ]; 118 jQuery.fn.attr.call( selector, context, true ); 119 120 } else { 121 selector = [ doc.createElement( ret[1] ) ]; 122 } 123 124 } else { 125 ret = buildFragment( [ match[1] ], [ doc ] ); 126 selector = (ret.cacheable ? ret.fragment.cloneNode(true) : ret.fragment).childNodes; 127 } 128 129 return jQuery.merge( this, selector ); 130 131 // HANDLE: $("#id") 132 } else { 133 elem = document.getElementById( match[2] ); 134 135 if ( elem ) { 136 // Handle the case where IE and Opera return items 137 // by name instead of ID 138 if ( elem.id !== match[2] ) { 139 return rootjQuery.find( selector ); 140 } 141 142 // Otherwise, we inject the element directly into the jQuery object 143 this.length = 1; 144 this[0] = elem; 145 } 146 147 this.context = document; 148 this.selector = selector; 149 return this; 150 } 151 152 // HANDLE: $("TAG") 153 } else if ( !context && /^\w+$/.test( selector ) ) { 154 this.selector = selector; 155 this.context = document; 156 selector = document.getElementsByTagName( selector ); 157 return jQuery.merge( this, selector ); 158 159 // HANDLE: $(expr, $(...)) 160 } else if ( !context || context.jquery ) { 161 return (context || rootjQuery).find( selector ); 162 163 // HANDLE: $(expr, context) 164 // (which is just equivalent to: $(context).find(expr) 165 } else { 166 return jQuery( context ).find( selector ); 167 } 168 169 // HANDLE: $(function) 170 // Shortcut for document ready 171 } else if ( jQuery.isFunction( selector ) ) { 172 return rootjQuery.ready( selector ); 173 } 174 175 if (selector.selector !== undefined) { 176 this.selector = selector.selector; 177 this.context = selector.context; 178 } 179 180 return jQuery.makeArray( selector, this ); 181 }, 182 183 // Start with an empty selector 184 selector: "", 185 186 // The current version of jQuery being used 187 jquery: "1.4.2", 188 189 // The default length of a jQuery object is 0 190 length: 0, 191 192 // The number of elements contained in the matched element set 193 size: function() { 194 return this.length; 195 }, 196 197 toArray: function() { 198 return slice.call( this, 0 ); 199 }, 200 201 // Get the Nth element in the matched element set OR 202 // Get the whole matched element set as a clean array 203 get: function( num ) { 204 return num == null ? 205 206 // Return a 'clean' array 207 this.toArray() : 208 209 // Return just the object 210 ( num < 0 ? this.slice(num)[ 0 ] : this[ num ] ); 211 }, 212 213 // Take an array of elements and push it onto the stack 214 // (returning the new matched element set) 215 pushStack: function( elems, name, selector ) { 216 // Build a new jQuery matched element set 217 var ret = jQuery(); 218 219 if ( jQuery.isArray( elems ) ) { 220 push.apply( ret, elems ); 221 222 } else { 223 jQuery.merge( ret, elems ); 224 } 225 226 // Add the old object onto the stack (as a reference) 227 ret.prevObject = this; 228 229 ret.context = this.context; 230 231 if ( name === "find" ) { 232 ret.selector = this.selector + (this.selector ? " " : "") + selector; 233 } else if ( name ) { 234 ret.selector = this.selector + "." + name + "(" + selector + ")"; 235 } 236 237 // Return the newly-formed element set 238 return ret; 239 }, 240 241 // Execute a callback for every element in the matched set. 242 // (You can seed the arguments with an array of args, but this is 243 // only used internally.) 244 each: function( callback, args ) { 245 return jQuery.each( this, callback, args ); 246 }, 247 248 ready: function( fn ) { 249 // Attach the listeners 250 jQuery.bindReady(); 251 252 // If the DOM is already ready 253 if ( jQuery.isReady ) { 254 // Execute the function immediately 255 fn.call( document, jQuery ); 256 257 // Otherwise, remember the function for later 258 } else if ( readyList ) { 259 // Add the function to the wait list 260 readyList.push( fn ); 261 } 262 263 return this; 264 }, 265 266 eq: function( i ) { 267 return i === -1 ? 268 this.slice( i ) : 269 this.slice( i, +i + 1 ); 270 }, 271 272 first: function() { 273 return this.eq( 0 ); 274 }, 275 276 last: function() { 277 return this.eq( -1 ); 278 }, 279 280 slice: function() { 281 return this.pushStack( slice.apply( this, arguments ), 282 "slice", slice.call(arguments).join(",") ); 283 }, 284 285 map: function( callback ) { 286 return this.pushStack( jQuery.map(this, function( elem, i ) { 287 return callback.call( elem, i, elem ); 288 })); 289 }, 290 291 end: function() { 292 return this.prevObject || jQuery(null); 293 }, 294 295 // For internal use only. 296 // Behaves like an Array's method, not like a jQuery method. 297 push: push, 298 sort: [].sort, 299 splice: [].splice 300 }; 301 302 // Give the init function the jQuery prototype for later instantiation 303 jQuery.fn.init.prototype = jQuery.fn; 304 305 jQuery.extend = jQuery.fn.extend = function() { 306 // copy reference to target object 307 var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options, name, src, copy; 308 309 // Handle a deep copy situation 310 if ( typeof target === "boolean" ) { 311 deep = target; 312 target = arguments[1] || {}; 313 // skip the boolean and the target 314 i = 2; 315 } 316 317 // Handle case when target is a string or something (possible in deep copy) 318 if ( typeof target !== "object" && !jQuery.isFunction(target) ) { 319 target = {}; 320 } 321 322 // extend jQuery itself if only one argument is passed 323 if ( length === i ) { 324 target = this; 325 --i; 326 } 327 328 for ( ; i < length; i++ ) { 329 // Only deal with non-null/undefined values 330 if ( (options = arguments[ i ]) != null ) { 331 // Extend the base object 332 for ( name in options ) { 333 src = target[ name ]; 334 copy = options[ name ]; 335 336 // Prevent never-ending loop 337 if ( target === copy ) { 338 continue; 339 } 340 341 // Recurse if we're merging object literal values or arrays 342 if ( deep && copy && ( jQuery.isPlainObject(copy) || jQuery.isArray(copy) ) ) { 343 var clone = src && ( jQuery.isPlainObject(src) || jQuery.isArray(src) ) ? src 344 : jQuery.isArray(copy) ? [] : {}; 345 346 // Never move original objects, clone them 347 target[ name ] = jQuery.extend( deep, clone, copy ); 348 349 // Don't bring in undefined values 350 } else if ( copy !== undefined ) { 351 target[ name ] = copy; 352 } 353 } 354 } 355 } 356 357 // Return the modified object 358 return target; 359 }; 360 361 jQuery.extend({ 362 noConflict: function( deep ) { 363 window.$ = _$; 364 365 if ( deep ) { 366 window.jQuery = _jQuery; 367 } 368 369 return jQuery; 370 }, 371 372 // Is the DOM ready to be used? Set to true once it occurs. 373 isReady: false, 374 375 // Handle when the DOM is ready 376 ready: function() { 377 // Make sure that the DOM is not already loaded 378 if ( !jQuery.isReady ) { 379 // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). 380 if ( !document.body ) { 381 return setTimeout( jQuery.ready, 13 ); 382 } 383 384 // Remember that the DOM is ready 385 jQuery.isReady = true; 386 387 // If there are functions bound, to execute 388 if ( readyList ) { 389 // Execute all of them 390 var fn, i = 0; 391 while ( (fn = readyList[ i++ ]) ) { 392 fn.call( document, jQuery ); 393 } 394 395 // Reset the list of functions 396 readyList = null; 397 } 398 399 // Trigger any bound ready events 400 if ( jQuery.fn.triggerHandler ) { 401 jQuery( document ).triggerHandler( "ready" ); 402 } 403 } 404 }, 405 406 bindReady: function() { 407 if ( readyBound ) { 408 return; 409 } 410 411 readyBound = true; 412 413 // Catch cases where $(document).ready() is called after the 414 // browser event has already occurred. 415 if ( document.readyState === "complete" ) { 416 return jQuery.ready(); 417 } 418 419 // Mozilla, Opera and webkit nightlies currently support this event 420 if ( document.addEventListener ) { 421 // Use the handy event callback 422 document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false ); 423 424 // A fallback to window.onload, that will always work 425 window.addEventListener( "load", jQuery.ready, false ); 426 427 // If IE event model is used 428 } else if ( document.attachEvent ) { 429 // ensure firing before onload, 430 // maybe late but safe also for iframes 431 document.attachEvent("onreadystatechange", DOMContentLoaded); 432 433 // A fallback to window.onload, that will always work 434 window.attachEvent( "onload", jQuery.ready ); 435 436 // If IE and not a frame 437 // continually check to see if the document is ready 438 var toplevel = false; 439 440 try { 441 toplevel = window.frameElement == null; 442 } catch(e) {} 443 444 if ( document.documentElement.doScroll && toplevel ) { 445 doScrollCheck(); 446 } 447 } 448 }, 449 450 // See test/unit/core.js for details concerning isFunction. 451 // Since version 1.3, DOM methods and functions like alert 452 // aren't supported. They return false on IE (#2968). 453 isFunction: function( obj ) { 454 return toString.call(obj) === "[object Function]"; 455 }, 456 457 isArray: function( obj ) { 458 return toString.call(obj) === "[object Array]"; 459 }, 460 461 isPlainObject: function( obj ) { 462 // Must be an Object. 463 // Because of IE, we also have to check the presence of the constructor property. 464 // Make sure that DOM nodes and window objects don't pass through, as well 465 if ( !obj || toString.call(obj) !== "[object Object]" || obj.nodeType || obj.setInterval ) { 466 return false; 467 } 468 469 // Not own constructor property must be Object 470 if ( obj.constructor 471 && !hasOwnProperty.call(obj, "constructor") 472 && !hasOwnProperty.call(obj.constructor.prototype, "isPrototypeOf") ) { 473 return false; 474 } 475 476 // Own properties are enumerated firstly, so to speed up, 477 // if last one is own, then all properties are own. 478 479 var key; 480 for ( key in obj ) {} 481 482 return key === undefined || hasOwnProperty.call( obj, key ); 483 }, 484 485 isEmptyObject: function( obj ) { 486 for ( var name in obj ) { 487 return false; 488 } 489 return true; 490 }, 491 492 error: function( msg ) { 493 throw msg; 494 }, 495 496 parseJSON: function( data ) { 497 if ( typeof data !== "string" || !data ) { 498 return null; 499 } 500 501 // Make sure leading/trailing whitespace is removed (IE can't handle it) 502 data = jQuery.trim( data ); 503 504 // Make sure the incoming data is actual JSON 505 // Logic borrowed from http://json.org/json2.js 506 if ( /^[\],:{}\s]*$/.test(data.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, "@") 507 .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]") 508 .replace(/(?:^|:|,)(?:\s*\[)+/g, "")) ) { 509 510 // Try to use the native JSON parser first 511 return window.JSON && window.JSON.parse ? 512 window.JSON.parse( data ) : 513 (new Function("return " + data))(); 514 515 } else { 516 jQuery.error( "Invalid JSON: " + data ); 517 } 518 }, 519 520 noop: function() {}, 521 522 // Evalulates a script in a global context 523 globalEval: function( data ) { 524 if ( data && rnotwhite.test(data) ) { 525 // Inspired by code by Andrea Giammarchi 526 // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html 527 var head = document.getElementsByTagName("head")[0] || document.documentElement, 528 script = document.createElement("script"); 529 530 script.type = "text/javascript"; 531 532 if ( jQuery.support.scriptEval ) { 533 script.appendChild( document.createTextNode( data ) ); 534 } else { 535 script.text = data; 536 } 537 538 // Use insertBefore instead of appendChild to circumvent an IE6 bug. 539 // This arises when a base node is used (#2709). 540 head.insertBefore( script, head.firstChild ); 541 head.removeChild( script ); 542 } 543 }, 544 545 nodeName: function( elem, name ) { 546 return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase(); 547 }, 548 549 // args is for internal usage only 550 each: function( object, callback, args ) { 551 var name, i = 0, 552 length = object.length, 553 isObj = length === undefined || jQuery.isFunction(object); 554 555 if ( args ) { 556 if ( isObj ) { 557 for ( name in object ) { 558 if ( callback.apply( object[ name ], args ) === false ) { 559 break; 560 } 561 } 562 } else { 563 for ( ; i < length; ) { 564 if ( callback.apply( object[ i++ ], args ) === false ) { 565 break; 566 } 567 } 568 } 569 570 // A special, fast, case for the most common use of each 571 } else { 572 if ( isObj ) { 573 for ( name in object ) { 574 if ( callback.call( object[ name ], name, object[ name ] ) === false ) { 575 break; 576 } 577 } 578 } else { 579 for ( var value = object[0]; 580 i < length && callback.call( value, i, value ) !== false; value = object[++i] ) {} 581 } 582 } 583 584 return object; 585 }, 586 587 trim: function( text ) { 588 return (text || "").replace( rtrim, "" ); 589 }, 590 591 // results is for internal usage only 592 makeArray: function( array, results ) { 593 var ret = results || []; 594 595 if ( array != null ) { 596 // The window, strings (and functions) also have 'length' 597 // The extra typeof function check is to prevent crashes 598 // in Safari 2 (See: #3039) 599 if ( array.length == null || typeof array === "string" || jQuery.isFunction(array) || (typeof array !== "function" && array.setInterval) ) { 600 push.call( ret, array ); 601 } else { 602 jQuery.merge( ret, array ); 603 } 604 } 605 606 return ret; 607 }, 608 609 inArray: function( elem, array ) { 610 if ( array.indexOf ) { 611 return array.indexOf( elem ); 612 } 613 614 for ( var i = 0, length = array.length; i < length; i++ ) { 615 if ( array[ i ] === elem ) { 616 return i; 617 } 618 } 619 620 return -1; 621 }, 622 623 merge: function( first, second ) { 624 var i = first.length, j = 0; 625 626 if ( typeof second.length === "number" ) { 627 for ( var l = second.length; j < l; j++ ) { 628 first[ i++ ] = second[ j ]; 629 } 630 631 } else { 632 while ( second[j] !== undefined ) { 633 first[ i++ ] = second[ j++ ]; 634 } 635 } 636 637 first.length = i; 638 639 return first; 640 }, 641 642 grep: function( elems, callback, inv ) { 643 var ret = []; 644 645 // Go through the array, only saving the items 646 // that pass the validator function 647 for ( var i = 0, length = elems.length; i < length; i++ ) { 648 if ( !inv !== !callback( elems[ i ], i ) ) { 649 ret.push( elems[ i ] ); 650 } 651 } 652 653 return ret; 654 }, 655 656 // arg is for internal usage only 657 map: function( elems, callback, arg ) { 658 var ret = [], value; 659 660 // Go through the array, translating each of the items to their 661 // new value (or values). 662 for ( var i = 0, length = elems.length; i < length; i++ ) { 663 value = callback( elems[ i ], i, arg ); 664 665 if ( value != null ) { 666 ret[ ret.length ] = value; 667 } 668 } 669 670 return ret.concat.apply( [], ret ); 671 }, 672 673 // A global GUID counter for objects 674 guid: 1, 675 676 proxy: function( fn, proxy, thisObject ) { 677 if ( arguments.length === 2 ) { 678 if ( typeof proxy === "string" ) { 679 thisObject = fn; 680 fn = thisObject[ proxy ]; 681 proxy = undefined; 682 683 } else if ( proxy && !jQuery.isFunction( proxy ) ) { 684 thisObject = proxy; 685 proxy = undefined; 686 } 687 } 688 689 if ( !proxy && fn ) { 690 proxy = function() { 691 return fn.apply( thisObject || this, arguments ); 692 }; 693 } 694 695 // Set the guid of unique handler to the same of original handler, so it can be removed 696 if ( fn ) { 697 proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++; 698 } 699 700 // So proxy can be declared as an argument 701 return proxy; 702 }, 703 704 // Use of jQuery.browser is frowned upon. 705 // More details: http://docs.jquery.com/Utilities/jQuery.browser 706 uaMatch: function( ua ) { 707 ua = ua.toLowerCase(); 708 709 var match = /(webkit)[ \/]([\w.]+)/.exec( ua ) || 710 /(opera)(?:.*version)?[ \/]([\w.]+)/.exec( ua ) || 711 /(msie) ([\w.]+)/.exec( ua ) || 712 !/compatible/.test( ua ) && /(mozilla)(?:.*? rv:([\w.]+))?/.exec( ua ) || 713 []; 714 715 return { browser: match[1] || "", version: match[2] || "0" }; 716 }, 717 718 browser: {} 719 }); 720 721 browserMatch = jQuery.uaMatch( userAgent ); 722 if ( browserMatch.browser ) { 723 jQuery.browser[ browserMatch.browser ] = true; 724 jQuery.browser.version = browserMatch.version; 725 } 726 727 // Deprecated, use jQuery.browser.webkit instead 728 if ( jQuery.browser.webkit ) { 729 jQuery.browser.safari = true; 730 } 731 732 if ( indexOf ) { 733 jQuery.inArray = function( elem, array ) { 734 return indexOf.call( array, elem ); 735 }; 736 } 737 738 // All jQuery objects should point back to these 739 rootjQuery = jQuery(document); 740 741 // Cleanup functions for the document ready method 742 if ( document.addEventListener ) { 743 DOMContentLoaded = function() { 744 document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false ); 745 jQuery.ready(); 746 }; 747 748 } else if ( document.attachEvent ) { 749 DOMContentLoaded = function() { 750 // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). 751 if ( document.readyState === "complete" ) { 752 document.detachEvent( "onreadystatechange", DOMContentLoaded ); 753 jQuery.ready(); 754 } 755 }; 756 } 757 758 // The DOM ready check for Internet Explorer 759 function doScrollCheck() { 760 if ( jQuery.isReady ) { 761 return; 762 } 763 764 try { 765 // If IE is used, use the trick by Diego Perini 766 // http://javascript.nwbox.com/IEContentLoaded/ 767 document.documentElement.doScroll("left"); 768 } catch( error ) { 769 setTimeout( doScrollCheck, 1 ); 770 return; 771 } 772 773 // and execute any waiting functions 774 jQuery.ready(); 775 } 776 777 function evalScript( i, elem ) { 778 if ( elem.src ) { 779 jQuery.ajax({ 780 url: elem.src, 781 async: false, 782 dataType: "script" 783 }); 784 } else { 785 jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" ); 786 } 787 788 if ( elem.parentNode ) { 789 elem.parentNode.removeChild( elem ); 790 } 791 } 792 793 // Mutifunctional method to get and set values to a collection 794 // The value/s can be optionally by executed if its a function 795 function access( elems, key, value, exec, fn, pass ) { 796 var length = elems.length; 797 798 // Setting many attributes 799 if ( typeof key === "object" ) { 800 for ( var k in key ) { 801 access( elems, k, key[k], exec, fn, value ); 802 } 803 return elems; 804 } 805 806 // Setting one attribute 807 if ( value !== undefined ) { 808 // Optionally, function values get executed if exec is true 809 exec = !pass && exec && jQuery.isFunction(value); 810 811 for ( var i = 0; i < length; i++ ) { 812 fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass ); 813 } 814 815 return elems; 816 } 817 818 // Getting an attribute 819 return length ? fn( elems[0], key ) : undefined; 820 } 821 822 function now() { 823 return (new Date).getTime(); 824 } 825 (function() { 826 827 jQuery.support = {}; 828 829 var root = document.documentElement, 830 script = document.createElement("script"), 831 div = document.createElement("div"), 832 id = "script" + now(); 833 834 div.style.display = "none"; 835 div.innerHTML = " <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>"; 836 837 var all = div.getElementsByTagName("*"), 838 a = div.getElementsByTagName("a")[0]; 839 840 // Can't get basic test support 841 if ( !all || !all.length || !a ) { 842 return; 843 } 844 845 jQuery.support = { 846 // IE strips leading whitespace when .innerHTML is used 847 leadingWhitespace: div.firstChild.nodeType === 3, 848 849 // Make sure that tbody elements aren't automatically inserted 850 // IE will insert them into empty tables 851 tbody: !div.getElementsByTagName("tbody").length, 852 853 // Make sure that link elements get serialized correctly by innerHTML 854 // This requires a wrapper element in IE 855 htmlSerialize: !!div.getElementsByTagName("link").length, 856 857 // Get the style information from getAttribute 858 // (IE uses .cssText insted) 859 style: /red/.test( a.getAttribute("style") ), 860 861 // Make sure that URLs aren't manipulated 862 // (IE normalizes it by default) 863 hrefNormalized: a.getAttribute("href") === "/a", 864 865 // Make sure that element opacity exists 866 // (IE uses filter instead) 867 // Use a regex to work around a WebKit issue. See #5145 868 opacity: /^0.55$/.test( a.style.opacity ), 869 870 // Verify style float existence 871 // (IE uses styleFloat instead of cssFloat) 872 cssFloat: !!a.style.cssFloat, 873 874 // Make sure that if no value is specified for a checkbox 875 // that it defaults to "on". 876 // (WebKit defaults to "" instead) 877 checkOn: div.getElementsByTagName("input")[0].value === "on", 878 879 // Make sure that a selected-by-default option has a working selected property. 880 // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) 881 optSelected: document.createElement("select").appendChild( document.createElement("option") ).selected, 882 883 parentNode: div.removeChild( div.appendChild( document.createElement("div") ) ).parentNode === null, 884 885 // Will be defined later 886 deleteExpando: true, 887 checkClone: false, 888 scriptEval: false, 889 noCloneEvent: true, 890 boxModel: null 891 }; 892 893 script.type = "text/javascript"; 894 try { 895 script.appendChild( document.createTextNode( "window." + id + "=1;" ) ); 896 } catch(e) {} 897 898 root.insertBefore( script, root.firstChild ); 899 900 // Make sure that the execution of code works by injecting a script 901 // tag with appendChild/createTextNode 902 // (IE doesn't support this, fails, and uses .text instead) 903 if ( window[ id ] ) { 904 jQuery.support.scriptEval = true; 905 delete window[ id ]; 906 } 907 908 // Test to see if it's possible to delete an expando from an element 909 // Fails in Internet Explorer 910 try { 911 delete script.test; 912 913 } catch(e) { 914 jQuery.support.deleteExpando = false; 915 } 916 917 root.removeChild( script ); 918 919 if ( div.attachEvent && div.fireEvent ) { 920 div.attachEvent("onclick", function click() { 921 // Cloning a node shouldn't copy over any 922 // bound event handlers (IE does this) 923 jQuery.support.noCloneEvent = false; 924 div.detachEvent("onclick", click); 925 }); 926 div.cloneNode(true).fireEvent("onclick"); 927 } 928 929 div = document.createElement("div"); 930 div.innerHTML = "<input type='radio' name='radiotest' checked='checked'/>"; 931 932 var fragment = document.createDocumentFragment(); 933 fragment.appendChild( div.firstChild ); 934 935 // WebKit doesn't clone checked state correctly in fragments 936 jQuery.support.checkClone = fragment.cloneNode(true).cloneNode(true).lastChild.checked; 937 938 // Figure out if the W3C box model works as expected 939 // document.body must exist before we can do this 940 jQuery(function() { 941 var div = document.createElement("div"); 942 div.style.width = div.style.paddingLeft = "1px"; 943 944 document.body.appendChild( div ); 945 jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2; 946 document.body.removeChild( div ).style.display = 'none'; 947 948 div = null; 949 }); 950 951 // Technique from Juriy Zaytsev 952 // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/ 953 var eventSupported = function( eventName ) { 954 var el = document.createElement("div"); 955 eventName = "on" + eventName; 956 957 var isSupported = (eventName in el); 958 if ( !isSupported ) { 959 el.setAttribute(eventName, "return;"); 960 isSupported = typeof el[eventName] === "function"; 961 } 962 el = null; 963 964 return isSupported; 965 }; 966 967 jQuery.support.submitBubbles = eventSupported("submit"); 968 jQuery.support.changeBubbles = eventSupported("change"); 969 970 // release memory in IE 971 root = script = div = all = a = null; 972 })(); 973 974 jQuery.props = { 975 "for": "htmlFor", 976 "class": "className", 977 readonly: "readOnly", 978 maxlength: "maxLength", 979 cellspacing: "cellSpacing", 980 rowspan: "rowSpan", 981 colspan: "colSpan", 982 tabindex: "tabIndex", 983 usemap: "useMap", 984 frameborder: "frameBorder" 985 }; 986 var expando = "jQuery" + now(), uuid = 0, windowData = {}; 987 988 jQuery.extend({ 989 cache: {}, 990 991 expando:expando, 992 993 // The following elements throw uncatchable exceptions if you 994 // attempt to add expando properties to them. 995 noData: { 996 "embed": true, 997 "object": true, 998 "applet": true 999 }, 1000 1001 data: function( elem, name, data ) { 1002 if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) { 1003 return; 1004 } 1005 1006 elem = elem == window ? 1007 windowData : 1008 elem; 1009 1010 var id = elem[ expando ], cache = jQuery.cache, thisCache; 1011 1012 if ( !id && typeof name === "string" && data === undefined ) { 1013 return null; 1014 } 1015 1016 // Compute a unique ID for the element 1017 if ( !id ) { 1018 id = ++uuid; 1019 } 1020 1021 // Avoid generating a new cache unless none exists and we 1022 // want to manipulate it. 1023 if ( typeof name === "object" ) { 1024 elem[ expando ] = id; 1025 thisCache = cache[ id ] = jQuery.extend(true, {}, name); 1026 1027 } else if ( !cache[ id ] ) { 1028 elem[ expando ] = id; 1029 cache[ id ] = {}; 1030 } 1031 1032 thisCache = cache[ id ]; 1033 1034 // Prevent overriding the named cache with undefined values 1035 if ( data !== undefined ) { 1036 thisCache[ name ] = data; 1037 } 1038 1039 return typeof name === "string" ? thisCache[ name ] : thisCache; 1040 }, 1041 1042 removeData: function( elem, name ) { 1043 if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) { 1044 return; 1045 } 1046 1047 elem = elem == window ? 1048 windowData : 1049 elem; 1050 1051 var id = elem[ expando ], cache = jQuery.cache, thisCache = cache[ id ]; 1052 1053 // If we want to remove a specific section of the element's data 1054 if ( name ) { 1055 if ( thisCache ) { 1056 // Remove the section of cache data 1057 delete thisCache[ name ]; 1058 1059 // If we've removed all the data, remove the element's cache 1060 if ( jQuery.isEmptyObject(thisCache) ) { 1061 jQuery.removeData( elem ); 1062 } 1063 } 1064 1065 // Otherwise, we want to remove all of the element's data 1066 } else { 1067 if ( jQuery.support.deleteExpando ) { 1068 delete elem[ jQuery.expando ]; 1069 1070 } else if ( elem.removeAttribute ) { 1071 elem.removeAttribute( jQuery.expando ); 1072 } 1073 1074 // Completely remove the data cache 1075 delete cache[ id ]; 1076 } 1077 } 1078 }); 1079 1080 jQuery.fn.extend({ 1081 data: function( key, value ) { 1082 if ( typeof key === "undefined" && this.length ) { 1083 return jQuery.data( this[0] ); 1084 1085 } else if ( typeof key === "object" ) { 1086 return this.each(function() { 1087 jQuery.data( this, key ); 1088 }); 1089 } 1090 1091 var parts = key.split("."); 1092 parts[1] = parts[1] ? "." + parts[1] : ""; 1093 1094 if ( value === undefined ) { 1095 var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]); 1096 1097 if ( data === undefined && this.length ) { 1098 data = jQuery.data( this[0], key ); 1099 } 1100 return data === undefined && parts[1] ? 1101 this.data( parts[0] ) : 1102 data; 1103 } else { 1104 return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function() { 1105 jQuery.data( this, key, value ); 1106 }); 1107 } 1108 }, 1109 1110 removeData: function( key ) { 1111 return this.each(function() { 1112 jQuery.removeData( this, key ); 1113 }); 1114 } 1115 }); 1116 jQuery.extend({ 1117 queue: function( elem, type, data ) { 1118 if ( !elem ) { 1119 return; 1120 } 1121 1122 type = (type || "fx") + "queue"; 1123 var q = jQuery.data( elem, type ); 1124 1125 // Speed up dequeue by getting out quickly if this is just a lookup 1126 if ( !data ) { 1127 return q || []; 1128 } 1129 1130 if ( !q || jQuery.isArray(data) ) { 1131 q = jQuery.data( elem, type, jQuery.makeArray(data) ); 1132 1133 } else { 1134 q.push( data ); 1135 } 1136 1137 return q; 1138 }, 1139 1140 dequeue: function( elem, type ) { 1141 type = type || "fx"; 1142 1143 var queue = jQuery.queue( elem, type ), fn = queue.shift(); 1144 1145 // If the fx queue is dequeued, always remove the progress sentinel 1146 if ( fn === "inprogress" ) { 1147 fn = queue.shift(); 1148 } 1149 1150 if ( fn ) { 1151 // Add a progress sentinel to prevent the fx queue from being 1152 // automatically dequeued 1153 if ( type === "fx" ) { 1154 queue.unshift("inprogress"); 1155 } 1156 1157 fn.call(elem, function() { 1158 jQuery.dequeue(elem, type); 1159 }); 1160 } 1161 } 1162 }); 1163 1164 jQuery.fn.extend({ 1165 queue: function( type, data ) { 1166 if ( typeof type !== "string" ) { 1167 data = type; 1168 type = "fx"; 1169 } 1170 1171 if ( data === undefined ) { 1172 return jQuery.queue( this[0], type ); 1173 } 1174 return this.each(function( i, elem ) { 1175 var queue = jQuery.queue( this, type, data ); 1176 1177 if ( type === "fx" && queue[0] !== "inprogress" ) { 1178 jQuery.dequeue( this, type ); 1179 } 1180 }); 1181 }, 1182 dequeue: function( type ) { 1183 return this.each(function() { 1184 jQuery.dequeue( this, type ); 1185 }); 1186 }, 1187 1188 // Based off of the plugin by Clint Helfers, with permission. 1189 // http://blindsignals.com/index.php/2009/07/jquery-delay/ 1190 delay: function( time, type ) { 1191 time = jQuery.fx ? jQuery.fx.speeds[time] || time : time; 1192 type = type || "fx"; 1193 1194 return this.queue( type, function() { 1195 var elem = this; 1196 setTimeout(function() { 1197 jQuery.dequeue( elem, type ); 1198 }, time ); 1199 }); 1200 }, 1201 1202 clearQueue: function( type ) { 1203 return this.queue( type || "fx", [] ); 1204 } 1205 }); 1206 var rclass = /[\n\t]/g, 1207 rspace = /\s+/, 1208 rreturn = /\r/g, 1209 rspecialurl = /href|src|style/, 1210 rtype = /(button|input)/i, 1211 rfocusable = /(button|input|object|select|textarea)/i, 1212 rclickable = /^(a|area)$/i, 1213 rradiocheck = /radio|checkbox/; 1214 1215 jQuery.fn.extend({ 1216 attr: function( name, value ) { 1217 return access( this, name, value, true, jQuery.attr ); 1218 }, 1219 1220 removeAttr: function( name, fn ) { 1221 return this.each(function(){ 1222 jQuery.attr( this, name, "" ); 1223 if ( this.nodeType === 1 ) { 1224 this.removeAttribute( name ); 1225 } 1226 }); 1227 }, 1228 1229 addClass: function( value ) { 1230 if ( jQuery.isFunction(value) ) { 1231 return this.each(function(i) { 1232 var self = jQuery(this); 1233 self.addClass( value.call(this, i, self.attr("class")) ); 1234 }); 1235 } 1236 1237 if ( value && typeof value === "string" ) { 1238 var classNames = (value || "").split( rspace ); 1239 1240 for ( var i = 0, l = this.length; i < l; i++ ) { 1241 var elem = this[i]; 1242 1243 if ( elem.nodeType === 1 ) { 1244 if ( !elem.className ) { 1245 elem.className = value; 1246 1247 } else { 1248 var className = " " + elem.className + " ", setClass = elem.className; 1249 for ( var c = 0, cl = classNames.length; c < cl; c++ ) { 1250 if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) { 1251 setClass += " " + classNames[c]; 1252 } 1253 } 1254 elem.className = jQuery.trim( setClass ); 1255 } 1256 } 1257 } 1258 } 1259 1260 return this; 1261 }, 1262 1263 removeClass: function( value ) { 1264 if ( jQuery.isFunction(value) ) { 1265 return this.each(function(i) { 1266 var self = jQuery(this); 1267 self.removeClass( value.call(this, i, self.attr("class")) ); 1268 }); 1269 } 1270 1271 if ( (value && typeof value === "string") || value === undefined ) { 1272 var classNames = (value || "").split(rspace); 1273 1274 for ( var i = 0, l = this.length; i < l; i++ ) { 1275 var elem = this[i]; 1276 1277 if ( elem.nodeType === 1 && elem.className ) { 1278 if ( value ) { 1279 var className = (" " + elem.className + " ").replace(rclass, " "); 1280 for ( var c = 0, cl = classNames.length; c < cl; c++ ) { 1281 className = className.replace(" " + classNames[c] + " ", " "); 1282 } 1283 elem.className = jQuery.trim( className ); 1284 1285 } else { 1286 elem.className = ""; 1287 } 1288 } 1289 } 1290 } 1291 1292 return this; 1293 }, 1294 1295 toggleClass: function( value, stateVal ) { 1296 var type = typeof value, isBool = typeof stateVal === "boolean"; 1297 1298 if ( jQuery.isFunction( value ) ) { 1299 return this.each(function(i) { 1300 var self = jQuery(this); 1301 self.toggleClass( value.call(this, i, self.attr("class"), stateVal), stateVal ); 1302 }); 1303 } 1304 1305 return this.each(function() { 1306 if ( type === "string" ) { 1307 // toggle individual class names 1308 var className, i = 0, self = jQuery(this), 1309 state = stateVal, 1310 classNames = value.split( rspace ); 1311 1312 while ( (className = classNames[ i++ ]) ) { 1313 // check each className given, space seperated list 1314 state = isBool ? state : !self.hasClass( className ); 1315 self[ state ? "addClass" : "removeClass" ]( className ); 1316 } 1317 1318 } else if ( type === "undefined" || type === "boolean" ) { 1319 if ( this.className ) { 1320 // store className if set 1321 jQuery.data( this, "__className__", this.className ); 1322 } 1323 1324 // toggle whole className 1325 this.className = this.className || value === false ? "" : jQuery.data( this, "__className__" ) || ""; 1326 } 1327 }); 1328 }, 1329 1330 hasClass: function( selector ) { 1331 var className = " " + selector + " "; 1332 for ( var i = 0, l = this.length; i < l; i++ ) { 1333 if ( (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) { 1334 return true; 1335 } 1336 } 1337 1338 return false; 1339 }, 1340 1341 val: function( value ) { 1342 if ( value === undefined ) { 1343 var elem = this[0]; 1344 1345 if ( elem ) { 1346 if ( jQuery.nodeName( elem, "option" ) ) { 1347 return (elem.attributes.value || {}).specified ? elem.value : elem.text; 1348 } 1349 1350 // We need to handle select boxes special 1351 if ( jQuery.nodeName( elem, "select" ) ) { 1352 var index = elem.selectedIndex, 1353 values = [], 1354 options = elem.options, 1355 one = elem.type === "select-one"; 1356 1357 // Nothing was selected 1358 if ( index < 0 ) { 1359 return null; 1360 } 1361 1362 // Loop through all the selected options 1363 for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) { 1364 var option = options[ i ]; 1365 1366 if ( option.selected ) { 1367 // Get the specifc value for the option 1368 value = jQuery(option).val(); 1369 1370 // We don't need an array for one selects 1371 if ( one ) { 1372 return value; 1373 } 1374 1375 // Multi-Selects return an array 1376 values.push( value ); 1377 } 1378 } 1379 1380 return values; 1381 } 1382 1383 // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified 1384 if ( rradiocheck.test( elem.type ) && !jQuery.support.checkOn ) { 1385 return elem.getAttribute("value") === null ? "on" : elem.value; 1386 } 1387 1388 1389 // Everything else, we just grab the value 1390 return (elem.value || "").replace(rreturn, ""); 1391 1392 } 1393 1394 return undefined; 1395 } 1396 1397 var isFunction = jQuery.isFunction(value); 1398 1399 return this.each(function(i) { 1400 var self = jQuery(this), val = value; 1401 1402 if ( this.nodeType !== 1 ) { 1403 return; 1404 } 1405 1406 if ( isFunction ) { 1407 val = value.call(this, i, self.val()); 1408 } 1409 1410 // Typecast each time if the value is a Function and the appended 1411 // value is therefore different each time. 1412 if ( typeof val === "number" ) { 1413 val += ""; 1414 } 1415 1416 if ( jQuery.isArray(val) && rradiocheck.test( this.type ) ) { 1417 this.checked = jQuery.inArray( self.val(), val ) >= 0; 1418 1419 } else if ( jQuery.nodeName( this, "select" ) ) { 1420 var values = jQuery.makeArray(val); 1421 1422 jQuery( "option", this ).each(function() { 1423 this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0; 1424 }); 1425 1426 if ( !values.length ) { 1427 this.selectedIndex = -1; 1428 } 1429 1430 } else { 1431 this.value = val; 1432 } 1433 }); 1434 } 1435 }); 1436 1437 jQuery.extend({ 1438 attrFn: { 1439 val: true, 1440 css: true, 1441 html: true, 1442 text: true, 1443 data: true, 1444 width: true, 1445 height: true, 1446 offset: true 1447 }, 1448 1449 attr: function( elem, name, value, pass ) { 1450 // don't set attributes on text and comment nodes 1451 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) { 1452 return undefined; 1453 } 1454 1455 if ( pass && name in jQuery.attrFn ) { 1456 return jQuery(elem)[name](value); 1457 } 1458 1459 var notxml = elem.nodeType !== 1 || !jQuery.isXMLDoc( elem ), 1460 // Whether we are setting (or getting) 1461 set = value !== undefined; 1462 1463 // Try to normalize/fix the name 1464 name = notxml && jQuery.props[ name ] || name; 1465 1466 // Only do all the following if this is a node (faster for style) 1467 if ( elem.nodeType === 1 ) { 1468 // These attributes require special treatment 1469 var special = rspecialurl.test( name ); 1470 1471 // Safari mis-reports the default selected property of an option 1472 // Accessing the parent's selectedIndex property fixes it 1473 if ( name === "selected" && !jQuery.support.optSelected ) { 1474 var parent = elem.parentNode; 1475 if ( parent ) { 1476 parent.selectedIndex; 1477 1478 // Make sure that it also works with optgroups, see #5701 1479 if ( parent.parentNode ) { 1480 parent.parentNode.selectedIndex; 1481 } 1482 } 1483 } 1484 1485 // If applicable, access the attribute via the DOM 0 way 1486 if ( name in elem && notxml && !special ) { 1487 if ( set ) { 1488 // We can't allow the type property to be changed (since it causes problems in IE) 1489 if ( name === "type" && rtype.test( elem.nodeName ) && elem.parentNode ) { 1490 jQuery.error( "type property can't be changed" ); 1491 } 1492 1493 elem[ name ] = value; 1494 } 1495 1496 // browsers index elements by id/name on forms, give priority to attributes. 1497 if ( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) ) { 1498 return elem.getAttributeNode( name ).nodeValue; 1499 } 1500 1501 // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set 1502 // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ 1503 if ( name === "tabIndex" ) { 1504 var attributeNode = elem.getAttributeNode( "tabIndex" ); 1505 1506 return attributeNode && attributeNode.specified ? 1507 attributeNode.value : 1508 rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? 1509 0 : 1510 undefined; 1511 } 1512 1513 return elem[ name ]; 1514 } 1515 1516 if ( !jQuery.support.style && notxml && name === "style" ) { 1517 if ( set ) { 1518 elem.style.cssText = "" + value; 1519 } 1520 1521 return elem.style.cssText; 1522 } 1523 1524 if ( set ) { 1525 // convert the value to a string (all browsers do this but IE) see #1070 1526 elem.setAttribute( name, "" + value ); 1527 } 1528 1529 var attr = !jQuery.support.hrefNormalized && notxml && special ? 1530 // Some attributes require a special call on IE 1531 elem.getAttribute( name, 2 ) : 1532 elem.getAttribute( name ); 1533 1534 // Non-existent attributes return null, we normalize to undefined 1535 return attr === null ? undefined : attr; 1536 } 1537 1538 // elem is actually elem.style ... set the style 1539 // Using attr for specific style information is now deprecated. Use style instead. 1540 return jQuery.style( elem, name, value ); 1541 } 1542 }); 1543 var rnamespaces = /\.(.*)$/, 1544 fcleanup = function( nm ) { 1545 return nm.replace(/[^\w\s\.\|`]/g, function( ch ) { 1546 return "\\" + ch; 1547 }); 1548 }; 1549 1550 /* 1551 * A number of helper functions used for managing events. 1552 * Many of the ideas behind this code originated from 1553 * Dean Edwards' addEvent library. 1554 */ 1555 jQuery.event = { 1556 1557 // Bind an event to an element 1558 // Original by Dean Edwards 1559 add: function( elem, types, handler, data ) { 1560 if ( elem.nodeType === 3 || elem.nodeType === 8 ) { 1561 return; 1562 } 1563 1564 // For whatever reason, IE has trouble passing the window object 1565 // around, causing it to be cloned in the process 1566 if ( elem.setInterval && ( elem !== window && !elem.frameElement ) ) { 1567 elem = window; 1568 } 1569 1570 var handleObjIn, handleObj; 1571 1572 if ( handler.handler ) { 1573 handleObjIn = handler; 1574 handler = handleObjIn.handler; 1575 } 1576 1577 // Make sure that the function being executed has a unique ID 1578 if ( !handler.guid ) { 1579 handler.guid = jQuery.guid++; 1580 } 1581 1582 // Init the element's event structure 1583 var elemData = jQuery.data( elem ); 1584 1585 // If no elemData is found then we must be trying to bind to one of the 1586 // banned noData elements 1587 if ( !elemData ) { 1588 return; 1589 } 1590 1591 var events = elemData.events = elemData.events || {}, 1592 eventHandle = elemData.handle, eventHandle; 1593 1594 if ( !eventHandle ) { 1595 elemData.handle = eventHandle = function() { 1596 // Handle the second event of a trigger and when 1597 // an event is called after a page has unloaded 1598 return typeof jQuery !== "undefined" && !jQuery.event.triggered ? 1599 jQuery.event.handle.apply( eventHandle.elem, arguments ) : 1600 undefined; 1601 }; 1602 } 1603 1604 // Add elem as a property of the handle function 1605 // This is to prevent a memory leak with non-native events in IE. 1606 eventHandle.elem = elem; 1607 1608 // Handle multiple events separated by a space 1609 // jQuery(...).bind("mouseover mouseout", fn); 1610 types = types.split(" "); 1611 1612 var type, i = 0, namespaces; 1613 1614 while ( (type = types[ i++ ]) ) { 1615 handleObj = handleObjIn ? 1616 jQuery.extend({}, handleObjIn) : 1617 { handler: handler, data: data }; 1618 1619 // Namespaced event handlers 1620 if ( type.indexOf(".") > -1 ) { 1621 namespaces = type.split("."); 1622 type = namespaces.shift(); 1623 handleObj.namespace = namespaces.slice(0).sort().join("."); 1624 1625 } else { 1626 namespaces = []; 1627 handleObj.namespace = ""; 1628 } 1629 1630 handleObj.type = type; 1631 handleObj.guid = handler.guid; 1632 1633 // Get the current list of functions bound to this event 1634 var handlers = events[ type ], 1635 special = jQuery.event.special[ type ] || {}; 1636 1637 // Init the event handler queue 1638 if ( !handlers ) { 1639 handlers = events[ type ] = []; 1640 1641 // Check for a special event handler 1642 // Only use addEventListener/attachEvent if the special 1643 // events handler returns false 1644 if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { 1645 // Bind the global event handler to the element 1646 if ( elem.addEventListener ) { 1647 elem.addEventListener( type, eventHandle, false ); 1648 1649 } else if ( elem.attachEvent ) { 1650 elem.attachEvent( "on" + type, eventHandle ); 1651 } 1652 } 1653 } 1654 1655 if ( special.add ) { 1656 special.add.call( elem, handleObj ); 1657 1658 if ( !handleObj.handler.guid ) { 1659 handleObj.handler.guid = handler.guid; 1660 } 1661 } 1662 1663 // Add the function to the element's handler list 1664 handlers.push( handleObj ); 1665 1666 // Keep track of which events have been used, for global triggering 1667 jQuery.event.global[ type ] = true; 1668 } 1669 1670 // Nullify elem to prevent memory leaks in IE 1671 elem = null; 1672 }, 1673 1674 global: {}, 1675 1676 // Detach an event or set of events from an element 1677 remove: function( elem, types, handler, pos ) { 1678 // don't do events on text and comment nodes 1679 if ( elem.nodeType === 3 || elem.nodeType === 8 ) { 1680 return; 1681 } 1682 1683 var ret, type, fn, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType, 1684 elemData = jQuery.data( elem ), 1685 events = elemData && elemData.events; 1686 1687 if ( !elemData || !events ) { 1688 return; 1689 } 1690 1691 // types is actually an event object here 1692 if ( types && types.type ) { 1693 handler = types.handler; 1694 types = types.type; 1695 } 1696 1697 // Unbind all events for the element 1698 if ( !types || typeof types === "string" && types.charAt(0) === "." ) { 1699 types = types || ""; 1700 1701 for ( type in events ) { 1702 jQuery.event.remove( elem, type + types ); 1703 } 1704 1705 return; 1706 } 1707 1708 // Handle multiple events separated by a space 1709 // jQuery(...).unbind("mouseover mouseout", fn); 1710 types = types.split(" "); 1711 1712 while ( (type = types[ i++ ]) ) { 1713 origType = type; 1714 handleObj = null; 1715 all = type.indexOf(".") < 0; 1716 namespaces = []; 1717 1718 if ( !all ) { 1719 // Namespaced event handlers 1720 namespaces = type.split("."); 1721 type = namespaces.shift(); 1722 1723 namespace = new RegExp("(^|\\.)" + 1724 jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)") 1725 } 1726 1727 eventType = events[ type ]; 1728 1729 if ( !eventType ) { 1730 continue; 1731 } 1732 1733 if ( !handler ) { 1734 for ( var j = 0; j < eventType.length; j++ ) { 1735 handleObj = eventType[ j ]; 1736 1737 if ( all || namespace.test( handleObj.namespace ) ) { 1738 jQuery.event.remove( elem, origType, handleObj.handler, j ); 1739 eventType.splice( j--, 1 ); 1740 } 1741 } 1742 1743 continue; 1744 } 1745 1746 special = jQuery.event.special[ type ] || {}; 1747 1748 for ( var j = pos || 0; j < eventType.length; j++ ) { 1749 handleObj = eventType[ j ]; 1750 1751 if ( handler.guid === handleObj.guid ) { 1752 // remove the given handler for the given type 1753 if ( all || namespace.test( handleObj.namespace ) ) { 1754 if ( pos == null ) { 1755 eventType.splice( j--, 1 ); 1756 } 1757 1758 if ( special.remove ) { 1759 special.remove.call( elem, handleObj ); 1760 } 1761 } 1762 1763 if ( pos != null ) { 1764 break; 1765 } 1766 } 1767 } 1768 1769 // remove generic event handler if no more handlers exist 1770 if ( eventType.length === 0 || pos != null && eventType.length === 1 ) { 1771 if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) { 1772 removeEvent( elem, type, elemData.handle ); 1773 } 1774 1775 ret = null; 1776 delete events[ type ]; 1777 } 1778 } 1779 1780 // Remove the expando if it's no longer used 1781 if ( jQuery.isEmptyObject( events ) ) { 1782 var handle = elemData.handle; 1783 if ( handle ) { 1784 handle.elem = null; 1785 } 1786 1787 delete elemData.events; 1788 delete elemData.handle; 1789 1790 if ( jQuery.isEmptyObject( elemData ) ) { 1791 jQuery.removeData( elem ); 1792 } 1793 } 1794 }, 1795 1796 // bubbling is internal 1797 trigger: function( event, data, elem /*, bubbling */ ) { 1798 // Event object or event type 1799 var type = event.type || event, 1800 bubbling = arguments[3]; 1801 1802 if ( !bubbling ) { 1803 event = typeof event === "object" ? 1804 // jQuery.Event object 1805 event[expando] ? event : 1806 // Object literal 1807 jQuery.extend( jQuery.Event(type), event ) : 1808 // Just the event type (string) 1809 jQuery.Event(type); 1810 1811 if ( type.indexOf("!") >= 0 ) { 1812 event.type = type = type.slice(0, -1); 1813 event.exclusive = true; 1814 } 1815 1816 // Handle a global trigger 1817 if ( !elem ) { 1818 // Don't bubble custom events when global (to avoid too much overhead) 1819 event.stopPropagation(); 1820 1821 // Only trigger if we've ever bound an event for it 1822 if ( jQuery.event.global[ type ] ) { 1823 jQuery.each( jQuery.cache, function() { 1824 if ( this.events && this.events[type] ) { 1825 jQuery.event.trigger( event, data, this.handle.elem ); 1826 } 1827 }); 1828 } 1829 } 1830 1831 // Handle triggering a single element 1832 1833 // don't do events on text and comment nodes 1834 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) { 1835 return undefined; 1836 } 1837 1838 // Clean up in case it is reused 1839 event.result = undefined; 1840 event.target = elem; 1841 1842 // Clone the incoming data, if any 1843 data = jQuery.makeArray( data ); 1844 data.unshift( event ); 1845 } 1846 1847 event.currentTarget = elem; 1848 1849 // Trigger the event, it is assumed that "handle" is a function 1850 var handle = jQuery.data( elem, "handle" ); 1851 if ( handle ) { 1852 handle.apply( elem, data ); 1853 } 1854 1855 var parent = elem.parentNode || elem.ownerDocument; 1856 1857 // Trigger an inline bound script 1858 try { 1859 if ( !(elem && elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()]) ) { 1860 if ( elem[ "on" + type ] && elem[ "on" + type ].apply( elem, data ) === false ) { 1861 event.result = false; 1862 } 1863 } 1864 1865 // prevent IE from throwing an error for some elements with some event types, see #3533 1866 } catch (e) {} 1867 1868 if ( !event.isPropagationStopped() && parent ) { 1869 jQuery.event.trigger( event, data, parent, true ); 1870 1871 } else if ( !event.isDefaultPrevented() ) { 1872 var target = event.target, old, 1873 isClick = jQuery.nodeName(target, "a") && type === "click", 1874 special = jQuery.event.special[ type ] || {}; 1875 1876 if ( (!special._default || special._default.call( elem, event ) === false) && 1877 !isClick && !(target && target.nodeName && jQuery.noData[target.nodeName.toLowerCase()]) ) { 1878 1879 try { 1880 if ( target[ type ] ) { 1881 // Make sure that we don't accidentally re-trigger the onFOO events 1882 old = target[ "on" + type ]; 1883 1884 if ( old ) { 1885 target[ "on" + type ] = null; 1886 } 1887 1888 jQuery.event.triggered = true; 1889 target[ type ](); 1890 } 1891 1892 // prevent IE from throwing an error for some elements with some event types, see #3533 1893 } catch (e) {} 1894 1895 if ( old ) { 1896 target[ "on" + type ] = old; 1897 } 1898 1899 jQuery.event.triggered = false; 1900 } 1901 } 1902 }, 1903 1904 handle: function( event ) { 1905 var all, handlers, namespaces, namespace, events; 1906 1907 event = arguments[0] = jQuery.event.fix( event || window.event ); 1908 event.currentTarget = this; 1909 1910 // Namespaced event handlers 1911 all = event.type.indexOf(".") < 0 && !event.exclusive; 1912 1913 if ( !all ) { 1914 namespaces = event.type.split("."); 1915 event.type = namespaces.shift(); 1916 namespace = new RegExp("(^|\\.)" + namespaces.slice(0).sort().join("\\.(?:.*\\.)?") + "(\\.|$)"); 1917 } 1918 1919 var events = jQuery.data(this, "events"), handlers = events[ event.type ]; 1920 1921 if ( events && handlers ) { 1922 // Clone the handlers to prevent manipulation 1923 handlers = handlers.slice(0); 1924 1925 for ( var j = 0, l = handlers.length; j < l; j++ ) { 1926 var handleObj = handlers[ j ]; 1927 1928 // Filter the functions by class 1929 if ( all || namespace.test( handleObj.namespace ) ) { 1930 // Pass in a reference to the handler function itself 1931 // So that we can later remove it 1932 event.handler = handleObj.handler; 1933 event.data = handleObj.data; 1934 event.handleObj = handleObj; 1935 1936 var ret = handleObj.handler.apply( this, arguments ); 1937 1938 if ( ret !== undefined ) { 1939 event.result = ret; 1940 if ( ret === false ) { 1941 event.preventDefault(); 1942 event.stopPropagation(); 1943 } 1944 } 1945 1946 if ( event.isImmediatePropagationStopped() ) { 1947 break; 1948 } 1949 } 1950 } 1951 } 1952 1953 return event.result; 1954 }, 1955 1956 props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "), 1957 1958 fix: function( event ) { 1959 if ( event[ expando ] ) { 1960 return event; 1961 } 1962 1963 // store a copy of the original event object 1964 // and "clone" to set read-only properties 1965 var originalEvent = event; 1966 event = jQuery.Event( originalEvent ); 1967 1968 for ( var i = this.props.length, prop; i; ) { 1969 prop = this.props[ --i ]; 1970 event[ prop ] = originalEvent[ prop ]; 1971 } 1972 1973 // Fix target property, if necessary 1974 if ( !event.target ) { 1975 event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either 1976 } 1977 1978 // check if target is a textnode (safari) 1979 if ( event.target.nodeType === 3 ) { 1980 event.target = event.target.parentNode; 1981 } 1982 1983 // Add relatedTarget, if necessary 1984 if ( !event.relatedTarget && event.fromElement ) { 1985 event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement; 1986 } 1987 1988 // Calculate pageX/Y if missing and clientX/Y available 1989 if ( event.pageX == null && event.clientX != null ) { 1990 var doc = document.documentElement, body = document.body; 1991 event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0); 1992 event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0); 1993 } 1994 1995 // Add which for key events 1996 if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) ) { 1997 event.which = event.charCode || event.keyCode; 1998 } 1999 2000 // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs) 2001 if ( !event.metaKey && event.ctrlKey ) { 2002 event.metaKey = event.ctrlKey; 2003 } 2004 2005 // Add which for click: 1 === left; 2 === middle; 3 === right 2006 // Note: button is not normalized, so don't use it 2007 if ( !event.which && event.button !== undefined ) { 2008 event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) )); 2009 } 2010 2011 return event; 2012 }, 2013 2014 // Deprecated, use jQuery.guid instead 2015 guid: 1E8, 2016 2017 // Deprecated, use jQuery.proxy instead 2018 proxy: jQuery.proxy, 2019 2020 special: { 2021 ready: { 2022 // Make sure the ready event is setup 2023 setup: jQuery.bindReady, 2024 teardown: jQuery.noop 2025 }, 2026 2027 live: { 2028 add: function( handleObj ) { 2029 jQuery.event.add( this, handleObj.origType, jQuery.extend({}, handleObj, {handler: liveHandler}) ); 2030 }, 2031 2032 remove: function( handleObj ) { 2033 var remove = true, 2034 type = handleObj.origType.replace(rnamespaces, ""); 2035 2036 jQuery.each( jQuery.data(this, "events").live || [], function() { 2037 if ( type === this.origType.replace(rnamespaces, "") ) { 2038 remove = false; 2039 return false; 2040 } 2041 }); 2042 2043 if ( remove ) { 2044 jQuery.event.remove( this, handleObj.origType, liveHandler ); 2045 } 2046 } 2047 2048 }, 2049 2050 beforeunload: { 2051 setup: function( data, namespaces, eventHandle ) { 2052 // We only want to do this special case on windows 2053 if ( this.setInterval ) { 2054 this.onbeforeunload = eventHandle; 2055 } 2056 2057 return false; 2058 }, 2059 teardown: function( namespaces, eventHandle ) { 2060 if ( this.onbeforeunload === eventHandle ) { 2061 this.onbeforeunload = null; 2062 } 2063 } 2064 } 2065 } 2066 }; 2067 2068 var removeEvent = document.removeEventListener ? 2069 function( elem, type, handle ) { 2070 elem.removeEventListener( type, handle, false ); 2071 } : 2072 function( elem, type, handle ) { 2073 elem.detachEvent( "on" + type, handle ); 2074 }; 2075 2076 jQuery.Event = function( src ) { 2077 // Allow instantiation without the 'new' keyword 2078 if ( !this.preventDefault ) { 2079 return new jQuery.Event( src ); 2080 } 2081 2082 // Event object 2083 if ( src && src.type ) { 2084 this.originalEvent = src; 2085 this.type = src.type; 2086 // Event type 2087 } else { 2088 this.type = src; 2089 } 2090 2091 // timeStamp is buggy for some events on Firefox(#3843) 2092 // So we won't rely on the native value 2093 this.timeStamp = now(); 2094 2095 // Mark it as fixed 2096 this[ expando ] = true; 2097 }; 2098 2099 function returnFalse() { 2100 return false; 2101 } 2102 function returnTrue() { 2103 return true; 2104 } 2105 2106 // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding 2107 // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html 2108 jQuery.Event.prototype = { 2109 preventDefault: function() { 2110 this.isDefaultPrevented = returnTrue; 2111 2112 var e = this.originalEvent; 2113 if ( !e ) { 2114 return; 2115 } 2116 2117 // if preventDefault exists run it on the original event 2118 if ( e.preventDefault ) { 2119 e.preventDefault(); 2120 } 2121 // otherwise set the returnValue property of the original event to false (IE) 2122 e.returnValue = false; 2123 }, 2124 stopPropagation: function() { 2125 this.isPropagationStopped = returnTrue; 2126 2127 var e = this.originalEvent; 2128 if ( !e ) { 2129 return; 2130 } 2131 // if stopPropagation exists run it on the original event 2132 if ( e.stopPropagation ) { 2133 e.stopPropagation(); 2134 } 2135 // otherwise set the cancelBubble property of the original event to true (IE) 2136 e.cancelBubble = true; 2137 }, 2138 stopImmediatePropagation: function() { 2139 this.isImmediatePropagationStopped = returnTrue; 2140 this.stopPropagation(); 2141 }, 2142 isDefaultPrevented: returnFalse, 2143 isPropagationStopped: returnFalse, 2144 isImmediatePropagationStopped: returnFalse 2145 }; 2146 2147 // Checks if an event happened on an element within another element 2148 // Used in jQuery.event.special.mouseenter and mouseleave handlers 2149 var withinElement = function( event ) { 2150 // Check if mouse(over|out) are still within the same parent element 2151 var parent = event.relatedTarget; 2152 2153 // Firefox sometimes assigns relatedTarget a XUL element 2154 // which we cannot access the parentNode property of 2155 try { 2156 // Traverse up the tree 2157 while ( parent && parent !== this ) { 2158 parent = parent.parentNode; 2159 } 2160 2161 if ( parent !== this ) { 2162 // set the correct event type 2163 event.type = event.data; 2164 2165 // handle event if we actually just moused on to a non sub-element 2166 jQuery.event.handle.apply( this, arguments ); 2167 } 2168 2169 // assuming we've left the element since we most likely mousedover a xul element 2170 } catch(e) { } 2171 }, 2172 2173 // In case of event delegation, we only need to rename the event.type, 2174 // liveHandler will take care of the rest. 2175 delegate = function( event ) { 2176 event.type = event.data; 2177 jQuery.event.handle.apply( this, arguments ); 2178 }; 2179 2180 // Create mouseenter and mouseleave events 2181 jQuery.each({ 2182 mouseenter: "mouseover", 2183 mouseleave: "mouseout" 2184 }, function( orig, fix ) { 2185 jQuery.event.special[ orig ] = { 2186 setup: function( data ) { 2187 jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig ); 2188 }, 2189 teardown: function( data ) { 2190 jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement ); 2191 } 2192 }; 2193 }); 2194 2195 // submit delegation 2196 if ( !jQuery.support.submitBubbles ) { 2197 2198 jQuery.event.special.submit = { 2199 setup: function( data, namespaces ) { 2200 if ( this.nodeName.toLowerCase() !== "form" ) { 2201 jQuery.event.add(this, "click.specialSubmit", function( e ) { 2202 var elem = e.target, type = elem.type; 2203 2204 if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) { 2205 return trigger( "submit", this, arguments ); 2206 } 2207 }); 2208 2209 jQuery.event.add(this, "keypress.specialSubmit", function( e ) { 2210 var elem = e.target, type = elem.type; 2211 2212 if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) { 2213 return trigger( "submit", this, arguments ); 2214 } 2215 }); 2216 2217 } else { 2218 return false; 2219 } 2220 }, 2221 2222 teardown: function( namespaces ) { 2223 jQuery.event.remove( this, ".specialSubmit" ); 2224 } 2225 }; 2226 2227 } 2228 2229 // change delegation, happens here so we have bind. 2230 if ( !jQuery.support.changeBubbles ) { 2231 2232 var formElems = /textarea|input|select/i, 2233 2234 changeFilters, 2235 2236 getVal = function( elem ) { 2237 var type = elem.type, val = elem.value; 2238 2239 if ( type === "radio" || type === "checkbox" ) { 2240 val = elem.checked; 2241 2242 } else if ( type === "select-multiple" ) { 2243 val = elem.selectedIndex > -1 ? 2244 jQuery.map( elem.options, function( elem ) { 2245 return elem.selected; 2246 }).join("-") : 2247 ""; 2248 2249 } else if ( elem.nodeName.toLowerCase() === "select" ) { 2250 val = elem.selectedIndex; 2251 } 2252 2253 return val; 2254 }, 2255 2256 testChange = function testChange( e ) { 2257 var elem = e.target, data, val; 2258 2259 if ( !formElems.test( elem.nodeName ) || elem.readOnly ) { 2260 return; 2261 } 2262 2263 data = jQuery.data( elem, "_change_data" ); 2264 val = getVal(elem); 2265 2266 // the current data will be also retrieved by beforeactivate 2267 if ( e.type !== "focusout" || elem.type !== "radio" ) { 2268 jQuery.data( elem, "_change_data", val ); 2269 } 2270 2271 if ( data === undefined || val === data ) { 2272 return; 2273 } 2274 2275 if ( data != null || val ) { 2276 e.type = "change"; 2277 return jQuery.event.trigger( e, arguments[1], elem ); 2278 } 2279 }; 2280 2281 jQuery.event.special.change = { 2282 filters: { 2283 focusout: testChange, 2284 2285 click: function( e ) { 2286 var elem = e.target, type = elem.type; 2287 2288 if ( type === "radio" || type === "checkbox" || elem.nodeName.toLowerCase() === "select" ) { 2289 return testChange.call( this, e ); 2290 } 2291 }, 2292 2293 // Change has to be called before submit 2294 // Keydown will be called before keypress, which is used in submit-event delegation 2295 keydown: function( e ) { 2296 var elem = e.target, type = elem.type; 2297 2298 if ( (e.keyCode === 13 && elem.nodeName.toLowerCase() !== "textarea") || 2299 (e.keyCode === 32 && (type === "checkbox" || type === "radio")) || 2300 type === "select-multiple" ) { 2301 return testChange.call( this, e ); 2302 } 2303 }, 2304 2305 // Beforeactivate happens also before the previous element is blurred 2306 // with this event you can't trigger a change event, but you can store 2307 // information/focus[in] is not needed anymore 2308 beforeactivate: function( e ) { 2309 var elem = e.target; 2310 jQuery.data( elem, "_change_data", getVal(elem) ); 2311 } 2312 }, 2313 2314 setup: function( data, namespaces ) { 2315 if ( this.type === "file" ) { 2316 return false; 2317 } 2318 2319 for ( var type in changeFilters ) { 2320 jQuery.event.add( this, type + ".specialChange", changeFilters[type] ); 2321 } 2322 2323 return formElems.test( this.nodeName ); 2324 }, 2325 2326 teardown: function( namespaces ) { 2327 jQuery.event.remove( this, ".specialChange" ); 2328 2329 return formElems.test( this.nodeName ); 2330 } 2331 }; 2332 2333 changeFilters = jQuery.event.special.change.filters; 2334 } 2335 2336 function trigger( type, elem, args ) { 2337 args[0].type = type; 2338 return jQuery.event.handle.apply( elem, args ); 2339 } 2340 2341 // Create "bubbling" focus and blur events 2342 if ( document.addEventListener ) { 2343 jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { 2344 jQuery.event.special[ fix ] = { 2345 setup: function() { 2346 this.addEventListener( orig, handler, true ); 2347 }, 2348 teardown: function() { 2349 this.removeEventListener( orig, handler, true ); 2350 } 2351 }; 2352 2353 function handler( e ) { 2354 e = jQuery.event.fix( e ); 2355 e.type = fix; 2356 return jQuery.event.handle.call( this, e ); 2357 } 2358 }); 2359 } 2360 2361 jQuery.each(["bind", "one"], function( i, name ) { 2362 jQuery.fn[ name ] = function( type, data, fn ) { 2363 // Handle object literals 2364 if ( typeof type === "object" ) { 2365 for ( var key in type ) { 2366 this[ name ](key, data, type[key], fn); 2367 } 2368 return this; 2369 } 2370 2371 if ( jQuery.isFunction( data ) ) { 2372 fn = data; 2373 data = undefined; 2374 } 2375 2376 var handler = name === "one" ? jQuery.proxy( fn, function( event ) { 2377 jQuery( this ).unbind( event, handler ); 2378 return fn.apply( this, arguments ); 2379 }) : fn; 2380 2381 if ( type === "unload" && name !== "one" ) { 2382 this.one( type, data, fn ); 2383 2384 } else { 2385 for ( var i = 0, l = this.length; i < l; i++ ) { 2386 jQuery.event.add( this[i], type, handler, data ); 2387 } 2388 } 2389 2390 return this; 2391 }; 2392 }); 2393 2394 jQuery.fn.extend({ 2395 unbind: function( type, fn ) { 2396 // Handle object literals 2397 if ( typeof type === "object" && !type.preventDefault ) { 2398 for ( var key in type ) { 2399 this.unbind(key, type[key]); 2400 } 2401 2402 } else { 2403 for ( var i = 0, l = this.length; i < l; i++ ) { 2404 jQuery.event.remove( this[i], type, fn ); 2405 } 2406 } 2407 2408 return this; 2409 }, 2410 2411 delegate: function( selector, types, data, fn ) { 2412 return this.live( types, data, fn, selector ); 2413 }, 2414 2415 undelegate: function( selector, types, fn ) { 2416 if ( arguments.length === 0 ) { 2417 return this.unbind( "live" ); 2418 2419 } else { 2420 return this.die( types, null, fn, selector ); 2421 } 2422 }, 2423 2424 trigger: function( type, data ) { 2425 return this.each(function() { 2426 jQuery.event.trigger( type, data, this ); 2427 }); 2428 }, 2429 2430 triggerHandler: function( type, data ) { 2431 if ( this[0] ) { 2432 var event = jQuery.Event( type ); 2433 event.preventDefault(); 2434 event.stopPropagation(); 2435 jQuery.event.trigger( event, data, this[0] ); 2436 return event.result; 2437 } 2438 }, 2439 2440 toggle: function( fn ) { 2441 // Save reference to arguments for access in closure 2442 var args = arguments, i = 1; 2443 2444 // link all the functions, so any of them can unbind this click handler 2445 while ( i < args.length ) { 2446 jQuery.proxy( fn, args[ i++ ] ); 2447 } 2448 2449 return this.click( jQuery.proxy( fn, function( event ) { 2450 // Figure out which function to execute 2451 var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i; 2452 jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 ); 2453 2454 // Make sure that clicks stop 2455 event.preventDefault(); 2456 2457 // and execute the function 2458 return args[ lastToggle ].apply( this, arguments ) || false; 2459 })); 2460 }, 2461 2462 hover: function( fnOver, fnOut ) { 2463 return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); 2464 } 2465 }); 2466 2467 var liveMap = { 2468 focus: "focusin", 2469 blur: "focusout", 2470 mouseenter: "mouseover", 2471 mouseleave: "mouseout" 2472 }; 2473 2474 jQuery.each(["live", "die"], function( i, name ) { 2475 jQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) { 2476 var type, i = 0, match, namespaces, preType, 2477 selector = origSelector || this.selector, 2478 context = origSelector ? this : jQuery( this.context ); 2479 2480 if ( jQuery.isFunction( data ) ) { 2481 fn = data; 2482 data = undefined; 2483 } 2484 2485 types = (types || "").split(" "); 2486 2487 while ( (type = types[ i++ ]) != null ) { 2488 match = rnamespaces.exec( type ); 2489 namespaces = ""; 2490 2491 if ( match ) { 2492 namespaces = match[0]; 2493 type = type.replace( rnamespaces, "" ); 2494 } 2495 2496 if ( type === "hover" ) { 2497 types.push( "mouseenter" + namespaces, "mouseleave" + namespaces ); 2498 continue; 2499 } 2500 2501 preType = type; 2502 2503 if ( type === "focus" || type === "blur" ) { 2504 types.push( liveMap[ type ] + namespaces ); 2505 type = type + namespaces; 2506 2507 } else { 2508 type = (liveMap[ type ] || type) + namespaces; 2509 } 2510 2511 if ( name === "live" ) { 2512 // bind live handler 2513 context.each(function(){ 2514 jQuery.event.add( this, liveConvert( type, selector ), 2515 { data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } ); 2516 }); 2517 2518 } else { 2519 // unbind live handler 2520 context.unbind( liveConvert( type, selector ), fn ); 2521 } 2522 } 2523 2524 return this; 2525 } 2526 }); 2527 2528 function liveHandler( event ) { 2529 var stop, elems = [], selectors = [], args = arguments, 2530 related, match, handleObj, elem, j, i, l, data, 2531 events = jQuery.data( this, "events" ); 2532 2533 // Make sure we avoid non-left-click bubbling in Firefox (#3861) 2534 if ( event.liveFired === this || !events || !events.live || event.button && event.type === "click" ) { 2535 return; 2536 } 2537 2538 event.liveFired = this; 2539 2540 var live = events.live.slice(0); 2541 2542 for ( j = 0; j < live.length; j++ ) { 2543 handleObj = live[j]; 2544 2545 if ( handleObj.origType.replace( rnamespaces, "" ) === event.type ) { 2546 selectors.push( handleObj.selector ); 2547 2548 } else { 2549 live.splice( j--, 1 ); 2550 } 2551 } 2552 2553 match = jQuery( event.target ).closest( selectors, event.currentTarget ); 2554 2555 for ( i = 0, l = match.length; i < l; i++ ) { 2556 for ( j = 0; j < live.length; j++ ) { 2557 handleObj = live[j]; 2558 2559 if ( match[i].selector === handleObj.selector ) { 2560 elem = match[i].elem; 2561 related = null; 2562 2563 // Those two events require additional checking 2564 if ( handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave" ) { 2565 related = jQuery( event.relatedTarget ).closest( handleObj.selector )[0]; 2566 } 2567 2568 if ( !related || related !== elem ) { 2569 elems.push({ elem: elem, handleObj: handleObj }); 2570 } 2571 } 2572 } 2573 } 2574 2575 for ( i = 0, l = elems.length; i < l; i++ ) { 2576 match = elems[i]; 2577 event.currentTarget = match.elem; 2578 event.data = match.handleObj.data; 2579 event.handleObj = match.handleObj; 2580 2581 if ( match.handleObj.origHandler.apply( match.elem, args ) === false ) { 2582 stop = false; 2583 break; 2584 } 2585 } 2586 2587 return stop; 2588 } 2589 2590 function liveConvert( type, selector ) { 2591 return "live." + (type && type !== "*" ? type + "." : "") + selector.replace(/\./g, "`").replace(/ /g, "&"); 2592 } 2593 2594 jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " + 2595 "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + 2596 "change select submit keydown keypress keyup error").split(" "), function( i, name ) { 2597 2598 // Handle event binding 2599 jQuery.fn[ name ] = function( fn ) { 2600 return fn ? this.bind( name, fn ) : this.trigger( name ); 2601 }; 2602 2603 if ( jQuery.attrFn ) { 2604 jQuery.attrFn[ name ] = true; 2605 } 2606 }); 2607 2608 // Prevent memory leaks in IE 2609 // Window isn't included so as not to unbind existing unload events 2610 // More info: 2611 // - http://isaacschlueter.com/2006/10/msie-memory-leaks/ 2612 if ( window.attachEvent && !window.addEventListener ) { 2613 window.attachEvent("onunload", function() { 2614 for ( var id in jQuery.cache ) { 2615 if ( jQuery.cache[ id ].handle ) { 2616 // Try/Catch is to handle iframes being unloaded, see #4280 2617 try { 2618 jQuery.event.remove( jQuery.cache[ id ].handle.elem ); 2619 } catch(e) {} 2620 } 2621 } 2622 }); 2623 } 2624 /*! 2625 * Sizzle CSS Selector Engine - v1.0 2626 * Copyright 2009, The Dojo Foundation 2627 * Released under the MIT, BSD, and GPL Licenses. 2628 * More information: http://sizzlejs.com/ 2629 */ 2630 (function(){ 2631 2632 var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, 2633 done = 0, 2634 toString = Object.prototype.toString, 2635 hasDuplicate = false, 2636 baseHasDuplicate = true; 2637 2638 // Here we check if the JavaScript engine is using some sort of 2639 // optimization where it does not always call our comparision 2640 // function. If that is the case, discard the hasDuplicate value. 2641 // Thus far that includes Google Chrome. 2642 [0, 0].sort(function(){ 2643 baseHasDuplicate = false; 2644 return 0; 2645 }); 2646 2647 var Sizzle = function(selector, context, results, seed) { 2648 results = results || []; 2649 var origContext = context = context || document; 2650 2651 if ( context.nodeType !== 1 && context.nodeType !== 9 ) { 2652 return []; 2653 } 2654 2655 if ( !selector || typeof selector !== "string" ) { 2656 return results; 2657 } 2658 2659 var parts = [], m, set, checkSet, extra, prune = true, contextXML = isXML(context), 2660 soFar = selector; 2661 2662 // Reset the position of the chunker regexp (start from head) 2663 while ( (chunker.exec(""), m = chunker.exec(soFar)) !== null ) { 2664 soFar = m[3]; 2665 2666 parts.push( m[1] ); 2667 2668 if ( m[2] ) { 2669 extra = m[3]; 2670 break; 2671 } 2672 } 2673 2674 if ( parts.length > 1 && origPOS.exec( selector ) ) { 2675 if ( parts.length === 2 && Expr.relative[ parts[0] ] ) { 2676 set = posProcess( parts[0] + parts[1], context ); 2677 } else { 2678 set = Expr.relative[ parts[0] ] ? 2679 [ context ] : 2680 Sizzle( parts.shift(), context ); 2681 2682 while ( parts.length ) { 2683 selector = parts.shift(); 2684 2685 if ( Expr.relative[ selector ] ) { 2686 selector += parts.shift(); 2687 } 2688 2689 set = posProcess( selector, set ); 2690 } 2691 } 2692 } else { 2693 // Take a shortcut and set the context if the root selector is an ID 2694 // (but not if it'll be faster if the inner selector is an ID) 2695 if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML && 2696 Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) { 2697 var ret = Sizzle.find( parts.shift(), context, contextXML ); 2698 context = ret.expr ? Sizzle.filter( ret.expr, ret.set )[0] : ret.set[0]; 2699 } 2700 2701 if ( context ) { 2702 var ret = seed ? 2703 { expr: parts.pop(), set: makeArray(seed) } : 2704 Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML ); 2705 set = ret.expr ? Sizzle.filter( ret.expr, ret.set ) : ret.set; 2706 2707 if ( parts.length > 0 ) { 2708 checkSet = makeArray(set); 2709 } else { 2710 prune = false; 2711 } 2712 2713 while ( parts.length ) { 2714 var cur = parts.pop(), pop = cur; 2715 2716 if ( !Expr.relative[ cur ] ) { 2717 cur = ""; 2718 } else { 2719 pop = parts.pop(); 2720 } 2721 2722 if ( pop == null ) { 2723 pop = context; 2724 } 2725 2726 Expr.relative[ cur ]( checkSet, pop, contextXML ); 2727 } 2728 } else { 2729 checkSet = parts = []; 2730 } 2731 } 2732 2733 if ( !checkSet ) { 2734 checkSet = set; 2735 } 2736 2737 if ( !checkSet ) { 2738 Sizzle.error( cur || selector ); 2739 } 2740 2741 if ( toString.call(checkSet) === "[object Array]" ) { 2742 if ( !prune ) { 2743 results.push.apply( results, checkSet ); 2744 } else if ( context && context.nodeType === 1 ) { 2745 for ( var i = 0; checkSet[i] != null; i++ ) { 2746 if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) { 2747 results.push( set[i] ); 2748 } 2749 } 2750 } else { 2751 for ( var i = 0; checkSet[i] != null; i++ ) { 2752 if ( checkSet[i] && checkSet[i].nodeType === 1 ) { 2753 results.push( set[i] ); 2754 } 2755 } 2756 } 2757 } else { 2758 makeArray( checkSet, results ); 2759 } 2760 2761 if ( extra ) { 2762 Sizzle( extra, origContext, results, seed ); 2763 Sizzle.uniqueSort( results ); 2764 } 2765 2766 return results; 2767 }; 2768 2769 Sizzle.uniqueSort = function(results){ 2770 if ( sortOrder ) { 2771 hasDuplicate = baseHasDuplicate; 2772 results.sort(sortOrder); 2773 2774 if ( hasDuplicate ) { 2775 for ( var i = 1; i < results.length; i++ ) { 2776 if ( results[i] === results[i-1] ) { 2777 results.splice(i--, 1); 2778 } 2779 } 2780 } 2781 } 2782 2783 return results; 2784 }; 2785 2786 Sizzle.matches = function(expr, set){ 2787 return Sizzle(expr, null, null, set); 2788 }; 2789 2790 Sizzle.find = function(expr, context, isXML){ 2791 var set, match; 2792 2793 if ( !expr ) { 2794 return []; 2795 } 2796 2797 for ( var i = 0, l = Expr.order.length; i < l; i++ ) { 2798 var type = Expr.order[i], match; 2799 2800 if ( (match = Expr.leftMatch[ type ].exec( expr )) ) { 2801 var left = match[1]; 2802 match.splice(1,1); 2803 2804 if ( left.substr( left.length - 1 ) !== "\\" ) { 2805 match[1] = (match[1] || "").replace(/\\/g, ""); 2806 set = Expr.find[ type ]( match, context, isXML ); 2807 if ( set != null ) { 2808 expr = expr.replace( Expr.match[ type ], "" ); 2809 break; 2810 } 2811 } 2812 } 2813 } 2814 2815 if ( !set ) { 2816 set = context.getElementsByTagName("*"); 2817 } 2818 2819 return {set: set, expr: expr}; 2820 }; 2821 2822 Sizzle.filter = function(expr, set, inplace, not){ 2823 var old = expr, result = [], curLoop = set, match, anyFound, 2824 isXMLFilter = set && set[0] && isXML(set[0]); 2825 2826 while ( expr && set.length ) { 2827 for ( var type in Expr.filter ) { 2828 if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) { 2829 var filter = Expr.filter[ type ], found, item, left = match[1]; 2830 anyFound = false; 2831 2832 match.splice(1,1); 2833 2834 if ( left.substr( left.length - 1 ) === "\\" ) { 2835 continue; 2836 } 2837 2838 if ( curLoop === result ) { 2839 result = []; 2840 } 2841 2842 if ( Expr.preFilter[ type ] ) { 2843 match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter ); 2844 2845 if ( !match ) { 2846 anyFound = found = true; 2847 } else if ( match === true ) { 2848 continue; 2849 } 2850 } 2851 2852 if ( match ) { 2853 for ( var i = 0; (item = curLoop[i]) != null; i++ ) { 2854 if ( item ) { 2855 found = filter( item, match, i, curLoop ); 2856 var pass = not ^ !!found; 2857 2858 if ( inplace && found != null ) { 2859 if ( pass ) { 2860 anyFound = true; 2861 } else { 2862 curLoop[i] = false; 2863 } 2864 } else if ( pass ) { 2865 result.push( item ); 2866 anyFound = true; 2867 } 2868 } 2869 } 2870 } 2871 2872 if ( found !== undefined ) { 2873 if ( !inplace ) { 2874 curLoop = result; 2875 } 2876 2877 expr = expr.replace( Expr.match[ type ], "" ); 2878 2879 if ( !anyFound ) { 2880 return []; 2881 } 2882 2883 break; 2884 } 2885 } 2886 } 2887 2888 // Improper expression 2889 if ( expr === old ) { 2890 if ( anyFound == null ) { 2891 Sizzle.error( expr ); 2892 } else { 2893 break; 2894 } 2895 } 2896 2897 old = expr; 2898 } 2899 2900 return curLoop; 2901 }; 2902 2903 Sizzle.error = function( msg ) { 2904 throw "Syntax error, unrecognized expression: " + msg; 2905 }; 2906 2907 var Expr = Sizzle.selectors = { 2908 order: [ "ID", "NAME", "TAG" ], 2909 match: { 2910 ID: /#((?:[\w\u00c0-\uFFFF-]|\\.)+)/, 2911 CLASS: /\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/, 2912 NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/, 2913 ATTR: /\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/, 2914 TAG: /^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/, 2915 CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/, 2916 POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/, 2917 PSEUDO: /:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/ 2918 }, 2919 leftMatch: {}, 2920 attrMap: { 2921 "class": "className", 2922 "for": "htmlFor" 2923 }, 2924 attrHandle: { 2925 href: function(elem){ 2926 return elem.getAttribute("href"); 2927 } 2928 }, 2929 relative: { 2930 "+": function(checkSet, part){ 2931 var isPartStr = typeof part === "string", 2932 isTag = isPartStr && !/\W/.test(part), 2933 isPartStrNotTag = isPartStr && !isTag; 2934 2935 if ( isTag ) { 2936 part = part.toLowerCase(); 2937 } 2938 2939 for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) { 2940 if ( (elem = checkSet[i]) ) { 2941 while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {} 2942 2943 checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ? 2944 elem || false : 2945 elem === part; 2946 } 2947 } 2948 2949 if ( isPartStrNotTag ) { 2950 Sizzle.filter( part, checkSet, true ); 2951 } 2952 }, 2953 ">": function(checkSet, part){ 2954 var isPartStr = typeof part === "string"; 2955 2956 if ( isPartStr && !/\W/.test(part) ) { 2957 part = part.toLowerCase(); 2958 2959 for ( var i = 0, l = checkSet.length; i < l; i++ ) { 2960 var elem = checkSet[i]; 2961 if ( elem ) { 2962 var parent = elem.parentNode; 2963 checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false; 2964 } 2965 } 2966 } else { 2967 for ( var i = 0, l = checkSet.length; i < l; i++ ) { 2968 var elem = checkSet[i]; 2969 if ( elem ) { 2970 checkSet[i] = isPartStr ? 2971 elem.parentNode : 2972 elem.parentNode === part; 2973 } 2974 } 2975 2976 if ( isPartStr ) { 2977 Sizzle.filter( part, checkSet, true ); 2978 } 2979 } 2980 }, 2981 "": function(checkSet, part, isXML){ 2982 var doneName = done++, checkFn = dirCheck; 2983 2984 if ( typeof part === "string" && !/\W/.test(part) ) { 2985 var nodeCheck = part = part.toLowerCase(); 2986 checkFn = dirNodeCheck; 2987 } 2988 2989 checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML); 2990 }, 2991 "~": function(checkSet, part, isXML){ 2992 var doneName = done++, checkFn = dirCheck; 2993 2994 if ( typeof part === "string" && !/\W/.test(part) ) { 2995 var nodeCheck = part = part.toLowerCase(); 2996 checkFn = dirNodeCheck; 2997 } 2998 2999 checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML); 3000 } 3001 }, 3002 find: { 3003 ID: function(match, context, isXML){ 3004 if ( typeof context.getElementById !== "undefined" && !isXML ) { 3005 var m = context.getElementById(match[1]); 3006 return m ? [m] : []; 3007 } 3008 }, 3009 NAME: function(match, context){ 3010 if ( typeof context.getElementsByName !== "undefined" ) { 3011 var ret = [], results = context.getElementsByName(match[1]); 3012 3013 for ( var i = 0, l = results.length; i < l; i++ ) { 3014 if ( results[i].getAttribute("name") === match[1] ) { 3015 ret.push( results[i] ); 3016 } 3017 } 3018 3019 return ret.length === 0 ? null : ret; 3020 } 3021 }, 3022 TAG: function(match, context){ 3023 return context.getElementsByTagName(match[1]); 3024 } 3025 }, 3026 preFilter: { 3027 CLASS: function(match, curLoop, inplace, result, not, isXML){ 3028 match = " " + match[1].replace(/\\/g, "") + " "; 3029 3030 if ( isXML ) { 3031 return match; 3032 } 3033 3034 for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) { 3035 if ( elem ) { 3036 if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n]/g, " ").indexOf(match) >= 0) ) { 3037 if ( !inplace ) { 3038 result.push( elem ); 3039 } 3040 } else if ( inplace ) { 3041 curLoop[i] = false; 3042 } 3043 } 3044 } 3045 3046 return false; 3047 }, 3048 ID: function(match){ 3049 return match[1].replace(/\\/g, ""); 3050 }, 3051 TAG: function(match, curLoop){ 3052 return match[1].toLowerCase(); 3053 }, 3054 CHILD: function(match){ 3055 if ( match[1] === "nth" ) { 3056 // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6' 3057 var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec( 3058 match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" || 3059 !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]); 3060 3061 // calculate the numbers (first)n+(last) including if they are negative 3062 match[2] = (test[1] + (test[2] || 1)) - 0; 3063 match[3] = test[3] - 0; 3064 } 3065 3066 // TODO: Move to normal caching system 3067 match[0] = done++; 3068 3069 return match; 3070 }, 3071 ATTR: function(match, curLoop, inplace, result, not, isXML){ 3072 var name = match[1].replace(/\\/g, ""); 3073 3074 if ( !isXML && Expr.attrMap[name] ) { 3075 match[1] = Expr.attrMap[name]; 3076 } 3077 3078 if ( match[2] === "~=" ) { 3079 match[4] = " " + match[4] + " "; 3080 } 3081 3082 return match; 3083 }, 3084 PSEUDO: function(match, curLoop, inplace, result, not){ 3085 if ( match[1] === "not" ) { 3086 // If we're dealing with a complex expression, or a simple one 3087 if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) { 3088 match[3] = Sizzle(match[3], null, null, curLoop); 3089 } else { 3090 var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not); 3091 if ( !inplace ) { 3092 result.push.apply( result, ret ); 3093 } 3094 return false; 3095 } 3096 } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) { 3097 return true; 3098 } 3099 3100 return match; 3101 }, 3102 POS: function(match){ 3103 match.unshift( true ); 3104 return match; 3105 } 3106 }, 3107 filters: { 3108 enabled: function(elem){ 3109 return elem.disabled === false && elem.type !== "hidden"; 3110 }, 3111 disabled: function(elem){ 3112 return elem.disabled === true; 3113 }, 3114 checked: function(elem){ 3115 return elem.checked === true; 3116 }, 3117 selected: function(elem){ 3118 // Accessing this property makes selected-by-default 3119 // options in Safari work properly 3120 elem.parentNode.selectedIndex; 3121 return elem.selected === true; 3122 }, 3123 parent: function(elem){ 3124 return !!elem.firstChild; 3125 }, 3126 empty: function(elem){ 3127 return !elem.firstChild; 3128 }, 3129 has: function(elem, i, match){ 3130 return !!Sizzle( match[3], elem ).length; 3131 }, 3132 header: function(elem){ 3133 return /h\d/i.test( elem.nodeName ); 3134 }, 3135 text: function(elem){ 3136 return "text" === elem.type; 3137 }, 3138 radio: function(elem){ 3139 return "radio" === elem.type; 3140 }, 3141 checkbox: function(elem){ 3142 return "checkbox" === elem.type; 3143 }, 3144 file: function(elem){ 3145 return "file" === elem.type; 3146 }, 3147 password: function(elem){ 3148 return "password" === elem.type; 3149 }, 3150 submit: function(elem){ 3151 return "submit" === elem.type; 3152 }, 3153 image: function(elem){ 3154 return "image" === elem.type; 3155 }, 3156 reset: function(elem){ 3157 return "reset" === elem.type; 3158 }, 3159 button: function(elem){ 3160 return "button" === elem.type || elem.nodeName.toLowerCase() === "button"; 3161 }, 3162 input: function(elem){ 3163 return /input|select|textarea|button/i.test(elem.nodeName); 3164 } 3165 }, 3166 setFilters: { 3167 first: function(elem, i){ 3168 return i === 0; 3169 }, 3170 last: function(elem, i, match, array){ 3171 return i === array.length - 1; 3172 }, 3173 even: function(elem, i){ 3174 return i % 2 === 0; 3175 }, 3176 odd: function(elem, i){ 3177 return i % 2 === 1; 3178 }, 3179 lt: function(elem, i, match){ 3180 return i < match[3] - 0; 3181 }, 3182 gt: function(elem, i, match){ 3183 return i > match[3] - 0; 3184 }, 3185 nth: function(elem, i, match){ 3186 return match[3] - 0 === i; 3187 }, 3188 eq: function(elem, i, match){ 3189 return match[3] - 0 === i; 3190 } 3191 }, 3192 filter: { 3193 PSEUDO: function(elem, match, i, array){ 3194 var name = match[1], filter = Expr.filters[ name ]; 3195 3196 if ( filter ) { 3197 return filter( elem, i, match, array ); 3198 } else if ( name === "contains" ) { 3199 return (elem.textContent || elem.innerText || getText([ elem ]) || "").indexOf(match[3]) >= 0; 3200 } else if ( name === "not" ) { 3201 var not = match[3]; 3202 3203 for ( var i = 0, l = not.length; i < l; i++ ) { 3204 if ( not[i] === elem ) { 3205 return false; 3206 } 3207 } 3208 3209 return true; 3210 } else { 3211 Sizzle.error( "Syntax error, unrecognized expression: " + name ); 3212 } 3213 }, 3214 CHILD: function(elem, match){ 3215 var type = match[1], node = elem; 3216 switch (type) { 3217 case 'only': 3218 case 'first': 3219 while ( (node = node.previousSibling) ) { 3220 if ( node.nodeType === 1 ) { 3221 return false; 3222 } 3223 } 3224 if ( type === "first" ) { 3225 return true; 3226 } 3227 node = elem; 3228 case 'last': 3229 while ( (node = node.nextSibling) ) { 3230 if ( node.nodeType === 1 ) { 3231 return false; 3232 } 3233 } 3234 return true; 3235 case 'nth': 3236 var first = match[2], last = match[3]; 3237 3238 if ( first === 1 && last === 0 ) { 3239 return true; 3240 } 3241 3242 var doneName = match[0], 3243 parent = elem.parentNode; 3244 3245 if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) { 3246 var count = 0; 3247 for ( node = parent.firstChild; node; node = node.nextSibling ) { 3248 if ( node.nodeType === 1 ) { 3249 node.nodeIndex = ++count; 3250 } 3251 } 3252 parent.sizcache = doneName; 3253 } 3254 3255 var diff = elem.nodeIndex - last; 3256 if ( first === 0 ) { 3257 return diff === 0; 3258 } else { 3259 return ( diff % first === 0 && diff / first >= 0 ); 3260 } 3261 } 3262 }, 3263 ID: function(elem, match){ 3264 return elem.nodeType === 1 && elem.getAttribute("id") === match; 3265 }, 3266 TAG: function(elem, match){ 3267 return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match; 3268 }, 3269 CLASS: function(elem, match){ 3270 return (" " + (elem.className || elem.getAttribute("class")) + " ") 3271 .indexOf( match ) > -1; 3272 }, 3273 ATTR: function(elem, match){ 3274 var name = match[1], 3275 result = Expr.attrHandle[ name ] ? 3276 Expr.attrHandle[ name ]( elem ) : 3277 elem[ name ] != null ? 3278 elem[ name ] : 3279 elem.getAttribute( name ), 3280 value = result + "", 3281 type = match[2], 3282 check = match[4]; 3283 3284 return result == null ? 3285 type === "!=" : 3286 type === "=" ? 3287 value === check : 3288 type === "*=" ? 3289 value.indexOf(check) >= 0 : 3290 type === "~=" ? 3291 (" " + value + " ").indexOf(check) >= 0 : 3292 !check ? 3293 value && result !== false : 3294 type === "!=" ? 3295 value !== check : 3296 type === "^=" ? 3297 value.indexOf(check) === 0 : 3298 type === "$=" ? 3299 value.substr(value.length - check.length) === check : 3300 type === "|=" ? 3301 value === check || value.substr(0, check.length + 1) === check + "-" : 3302 false; 3303 }, 3304 POS: function(elem, match, i, array){ 3305 var name = match[2], filter = Expr.setFilters[ name ]; 3306 3307 if ( filter ) { 3308 return filter( elem, i, match, array ); 3309 } 3310 } 3311 } 3312 }; 3313 3314 var origPOS = Expr.match.POS; 3315 3316 for ( var type in Expr.match ) { 3317 Expr.match[ type ] = new RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source ); 3318 Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, function(all, num){ 3319 return "\\" + (num - 0 + 1); 3320 })); 3321 } 3322 3323 var makeArray = function(array, results) { 3324 array = Array.prototype.slice.call( array, 0 ); 3325 3326 if ( results ) { 3327 results.push.apply( results, array ); 3328 return results; 3329 } 3330 3331 return array; 3332 }; 3333 3334 // Perform a simple check to determine if the browser is capable of 3335 // converting a NodeList to an array using builtin methods. 3336 // Also verifies that the returned array holds DOM nodes 3337 // (which is not the case in the Blackberry browser) 3338 try { 3339 Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType; 3340 3341 // Provide a fallback method if it does not work 3342 } catch(e){ 3343 makeArray = function(array, results) { 3344 var ret = results || []; 3345 3346 if ( toString.call(array) === "[object Array]" ) { 3347 Array.prototype.push.apply( ret, array ); 3348 } else { 3349 if ( typeof array.length === "number" ) { 3350 for ( var i = 0, l = array.length; i < l; i++ ) { 3351 ret.push( array[i] ); 3352 } 3353 } else { 3354 for ( var i = 0; array[i]; i++ ) { 3355 ret.push( array[i] ); 3356 } 3357 } 3358 } 3359 3360 return ret; 3361 }; 3362 } 3363 3364 var sortOrder; 3365 3366 if ( document.documentElement.compareDocumentPosition ) { 3367 sortOrder = function( a, b ) { 3368 if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) { 3369 if ( a == b ) { 3370 hasDuplicate = true; 3371 } 3372 return a.compareDocumentPosition ? -1 : 1; 3373 } 3374 3375 var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1; 3376 if ( ret === 0 ) { 3377 hasDuplicate = true; 3378 } 3379 return ret; 3380 }; 3381 } else if ( "sourceIndex" in document.documentElement ) { 3382 sortOrder = function( a, b ) { 3383 if ( !a.sourceIndex || !b.sourceIndex ) { 3384 if ( a == b ) { 3385 hasDuplicate = true; 3386 } 3387 return a.sourceIndex ? -1 : 1; 3388 } 3389 3390 var ret = a.sourceIndex - b.sourceIndex; 3391 if ( ret === 0 ) { 3392 hasDuplicate = true; 3393 } 3394 return ret; 3395 }; 3396 } else if ( document.createRange ) { 3397 sortOrder = function( a, b ) { 3398 if ( !a.ownerDocument || !b.ownerDocument ) { 3399 if ( a == b ) { 3400 hasDuplicate = true; 3401 } 3402 return a.ownerDocument ? -1 : 1; 3403 } 3404 3405 var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange(); 3406 aRange.setStart(a, 0); 3407 aRange.setEnd(a, 0); 3408 bRange.setStart(b, 0); 3409 bRange.setEnd(b, 0); 3410 var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange); 3411 if ( ret === 0 ) { 3412 hasDuplicate = true; 3413 } 3414 return ret; 3415 }; 3416 } 3417 3418 // Utility function for retreiving the text value of an array of DOM nodes 3419 function getText( elems ) { 3420 var ret = "", elem; 3421 3422 for ( var i = 0; elems[i]; i++ ) { 3423 elem = elems[i]; 3424 3425 // Get the text from text nodes and CDATA nodes 3426 if ( elem.nodeType === 3 || elem.nodeType === 4 ) { 3427 ret += elem.nodeValue; 3428 3429 // Traverse everything else, except comment nodes 3430 } else if ( elem.nodeType !== 8 ) { 3431 ret += getText( elem.childNodes ); 3432 } 3433 } 3434 3435 return ret; 3436 } 3437 3438 // Check to see if the browser returns elements by name when 3439 // querying by getElementById (and provide a workaround) 3440 (function(){ 3441 // We're going to inject a fake input element with a specified name 3442 var form = document.createElement("div"), 3443 id = "script" + (new Date).getTime(); 3444 form.innerHTML = "<a name='" + id + "'/>"; 3445 3446 // Inject it into the root element, check its status, and remove it quickly 3447 var root = document.documentElement; 3448 root.insertBefore( form, root.firstChild ); 3449 3450 // The workaround has to do additional checks after a getElementById 3451 // Which slows things down for other browsers (hence the branching) 3452 if ( document.getElementById( id ) ) { 3453 Expr.find.ID = function(match, context, isXML){ 3454 if ( typeof context.getElementById !== "undefined" && !isXML ) { 3455 var m = context.getElementById(match[1]); 3456 return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : []; 3457 } 3458 }; 3459 3460 Expr.filter.ID = function(elem, match){ 3461 var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); 3462 return elem.nodeType === 1 && node && node.nodeValue === match; 3463 }; 3464 } 3465 3466 root.removeChild( form ); 3467 root = form = null; // release memory in IE 3468 })(); 3469 3470 (function(){ 3471 // Check to see if the browser returns only elements 3472 // when doing getElementsByTagName("*") 3473 3474 // Create a fake element 3475 var div = document.createElement("div"); 3476 div.appendChild( document.createComment("") ); 3477 3478 // Make sure no comments are found 3479 if ( div.getElementsByTagName("*").length > 0 ) { 3480 Expr.find.TAG = function(match, context){ 3481 var results = context.getElementsByTagName(match[1]); 3482 3483 // Filter out possible comments 3484 if ( match[1] === "*" ) { 3485 var tmp = []; 3486 3487 for ( var i = 0; results[i]; i++ ) { 3488 if ( results[i].nodeType === 1 ) { 3489 tmp.push( results[i] ); 3490 } 3491 } 3492 3493 results = tmp; 3494 } 3495 3496 return results; 3497 }; 3498 } 3499 3500 // Check to see if an attribute returns normalized href attributes 3501 div.innerHTML = "<a href='#'></a>"; 3502 if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" && 3503 div.firstChild.getAttribute("href") !== "#" ) { 3504 Expr.attrHandle.href = function(elem){ 3505 return elem.getAttribute("href", 2); 3506 }; 3507 } 3508 3509 div = null; // release memory in IE 3510 })(); 3511 3512 if ( document.querySelectorAll ) { 3513 (function(){ 3514 var oldSizzle = Sizzle, div = document.createElement("div"); 3515 div.innerHTML = "<p class='TEST'></p>"; 3516 3517 // Safari can't handle uppercase or unicode characters when 3518 // in quirks mode. 3519 if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) { 3520 return; 3521 } 3522 3523 Sizzle = function(query, context, extra, seed){ 3524 context = context || document; 3525 3526 // Only use querySelectorAll on non-XML documents 3527 // (ID selectors don't work in non-HTML documents) 3528 if ( !seed && context.nodeType === 9 && !isXML(context) ) { 3529 try { 3530 return makeArray( context.querySelectorAll(query), extra ); 3531 } catch(e){} 3532 } 3533 3534 return oldSizzle(query, context, extra, seed); 3535 }; 3536 3537 for ( var prop in oldSizzle ) { 3538 Sizzle[ prop ] = oldSizzle[ prop ]; 3539 } 3540 3541 div = null; // release memory in IE 3542 })(); 3543 } 3544 3545 (function(){ 3546 var div = document.createElement("div"); 3547 3548 div.innerHTML = "<div class='test e'></div><div class='test'></div>"; 3549 3550 // Opera can't find a second classname (in 9.6) 3551 // Also, make sure that getElementsByClassName actually exists 3552 if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) { 3553 return; 3554 } 3555 3556 // Safari caches class attributes, doesn't catch changes (in 3.2) 3557 div.lastChild.className = "e"; 3558 3559 if ( div.getElementsByClassName("e").length === 1 ) { 3560 return; 3561 } 3562 3563 Expr.order.splice(1, 0, "CLASS"); 3564 Expr.find.CLASS = function(match, context, isXML) { 3565 if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) { 3566 return context.getElementsByClassName(match[1]); 3567 } 3568 }; 3569 3570 div = null; // release memory in IE 3571 })(); 3572 3573 function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { 3574 for ( var i = 0, l = checkSet.length; i < l; i++ ) { 3575 var elem = checkSet[i]; 3576 if ( elem ) { 3577 elem = elem[dir]; 3578 var match = false; 3579 3580 while ( elem ) { 3581 if ( elem.sizcache === doneName ) { 3582 match = checkSet[elem.sizset]; 3583 break; 3584 } 3585 3586 if ( elem.nodeType === 1 && !isXML ){ 3587 elem.sizcache = doneName; 3588 elem.sizset = i; 3589 } 3590 3591 if ( elem.nodeName.toLowerCase() === cur ) { 3592 match = elem; 3593 break; 3594 } 3595 3596 elem = elem[dir]; 3597 } 3598 3599 checkSet[i] = match; 3600 } 3601 } 3602 } 3603 3604 function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { 3605 for ( var i = 0, l = checkSet.length; i < l; i++ ) { 3606 var elem = checkSet[i]; 3607 if ( elem ) { 3608 elem = elem[dir]; 3609 var match = false; 3610 3611 while ( elem ) { 3612 if ( elem.sizcache === doneName ) { 3613 match = checkSet[elem.sizset]; 3614 break; 3615 } 3616 3617 if ( elem.nodeType === 1 ) { 3618 if ( !isXML ) { 3619 elem.sizcache = doneName; 3620 elem.sizset = i; 3621 } 3622 if ( typeof cur !== "string" ) { 3623 if ( elem === cur ) { 3624 match = true; 3625 break; 3626 } 3627 3628 } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) { 3629 match = elem; 3630 break; 3631 } 3632 } 3633 3634 elem = elem[dir]; 3635 } 3636 3637 checkSet[i] = match; 3638 } 3639 } 3640 } 3641 3642 var contains = document.compareDocumentPosition ? function(a, b){ 3643 return !!(a.compareDocumentPosition(b) & 16); 3644 } : function(a, b){ 3645 return a !== b && (a.contains ? a.contains(b) : true); 3646 }; 3647 3648 var isXML = function(elem){ 3649 // documentElement is verified for cases where it doesn't yet exist 3650 // (such as loading iframes in IE - #4833) 3651 var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement; 3652 return documentElement ? documentElement.nodeName !== "HTML" : false; 3653 }; 3654 3655 var posProcess = function(selector, context){ 3656 var tmpSet = [], later = "", match, 3657 root = context.nodeType ? [context] : context; 3658 3659 // Position selectors must be done after the filter 3660 // And so must :not(positional) so we move all PSEUDOs to the end 3661 while ( (match = Expr.match.PSEUDO.exec( selector )) ) { 3662 later += match[0]; 3663 selector = selector.replace( Expr.match.PSEUDO, "" ); 3664 } 3665 3666 selector = Expr.relative[selector] ? selector + "*" : selector; 3667 3668 for ( var i = 0, l = root.length; i < l; i++ ) { 3669 Sizzle( selector, root[i], tmpSet ); 3670 } 3671 3672 return Sizzle.filter( later, tmpSet ); 3673 }; 3674 3675 // EXPOSE 3676 jQuery.find = Sizzle; 3677 jQuery.expr = Sizzle.selectors; 3678 jQuery.expr[":"] = jQuery.expr.filters; 3679 jQuery.unique = Sizzle.uniqueSort; 3680 jQuery.text = getText; 3681 jQuery.isXMLDoc = isXML; 3682 jQuery.contains = contains; 3683 3684 return; 3685 3686 window.Sizzle = Sizzle; 3687 3688 })(); 3689 var runtil = /Until$/, 3690 rparentsprev = /^(?:parents|prevUntil|prevAll)/, 3691 // Note: This RegExp should be improved, or likely pulled from Sizzle 3692 rmultiselector = /,/, 3693 slice = Array.prototype.slice; 3694 3695 // Implement the identical functionality for filter and not 3696 var winnow = function( elements, qualifier, keep ) { 3697 if ( jQuery.isFunction( qualifier ) ) { 3698 return jQuery.grep(elements, function( elem, i ) { 3699 return !!qualifier.call( elem, i, elem ) === keep; 3700 }); 3701 3702 } else if ( qualifier.nodeType ) { 3703 return jQuery.grep(elements, function( elem, i ) { 3704 return (elem === qualifier) === keep; 3705 }); 3706 3707 } else if ( typeof qualifier === "string" ) { 3708 var filtered = jQuery.grep(elements, function( elem ) { 3709 return elem.nodeType === 1; 3710 }); 3711 3712 if ( isSimple.test( qualifier ) ) { 3713 return jQuery.filter(qualifier, filtered, !keep); 3714 } else { 3715 qualifier = jQuery.filter( qualifier, filtered ); 3716 } 3717 } 3718 3719 return jQuery.grep(elements, function( elem, i ) { 3720 return (jQuery.inArray( elem, qualifier ) >= 0) === keep; 3721 }); 3722 }; 3723 3724 jQuery.fn.extend({ 3725 find: function( selector ) { 3726 var ret = this.pushStack( "", "find", selector ), length = 0; 3727 3728 for ( var i = 0, l = this.length; i < l; i++ ) { 3729 length = ret.length; 3730 jQuery.find( selector, this[i], ret ); 3731 3732 if ( i > 0 ) { 3733 // Make sure that the results are unique 3734 for ( var n = length; n < ret.length; n++ ) { 3735 for ( var r = 0; r < length; r++ ) { 3736 if ( ret[r] === ret[n] ) { 3737 ret.splice(n--, 1); 3738 break; 3739 } 3740 } 3741 } 3742 } 3743 } 3744 3745 return ret; 3746 }, 3747 3748 has: function( target ) { 3749 var targets = jQuery( target ); 3750 return this.filter(function() { 3751 for ( var i = 0, l = targets.length; i < l; i++ ) { 3752 if ( jQuery.contains( this, targets[i] ) ) { 3753 return true; 3754 } 3755 } 3756 }); 3757 }, 3758 3759 not: function( selector ) { 3760 return this.pushStack( winnow(this, selector, false), "not", selector); 3761 }, 3762 3763 filter: function( selector ) { 3764 return this.pushStack( winnow(this, selector, true), "filter", selector ); 3765 }, 3766 3767 is: function( selector ) { 3768 return !!selector && jQuery.filter( selector, this ).length > 0; 3769 }, 3770 3771 closest: function( selectors, context ) { 3772 if ( jQuery.isArray( selectors ) ) { 3773 var ret = [], cur = this[0], match, matches = {}, selector; 3774 3775 if ( cur && selectors.length ) { 3776 for ( var i = 0, l = selectors.length; i < l; i++ ) { 3777 selector = selectors[i]; 3778 3779 if ( !matches[selector] ) { 3780 matches[selector] = jQuery.expr.match.POS.test( selector ) ? 3781 jQuery( selector, context || this.context ) : 3782 selector; 3783 } 3784 } 3785 3786 while ( cur && cur.ownerDocument && cur !== context ) { 3787 for ( selector in matches ) { 3788 match = matches[selector]; 3789 3790 if ( match.jquery ? match.index(cur) > -1 : jQuery(cur).is(match) ) { 3791 ret.push({ selector: selector, elem: cur }); 3792 delete matches[selector]; 3793 } 3794 } 3795 cur = cur.parentNode; 3796 } 3797 } 3798 3799 return ret; 3800 } 3801 3802 var pos = jQuery.expr.match.POS.test( selectors ) ? 3803 jQuery( selectors, context || this.context ) : null; 3804 3805 return this.map(function( i, cur ) { 3806 while ( cur && cur.ownerDocument && cur !== context ) { 3807 if ( pos ? pos.index(cur) > -1 : jQuery(cur).is(selectors) ) { 3808 return cur; 3809 } 3810 cur = cur.parentNode; 3811 } 3812 return null; 3813 }); 3814 }, 3815 3816 // Determine the position of an element within 3817 // the matched set of elements 3818 index: function( elem ) { 3819 if ( !elem || typeof elem === "string" ) { 3820 return jQuery.inArray( this[0], 3821 // If it receives a string, the selector is used 3822 // If it receives nothing, the siblings are used 3823 elem ? jQuery( elem ) : this.parent().children() ); 3824 } 3825 // Locate the position of the desired element 3826 return jQuery.inArray( 3827 // If it receives a jQuery object, the first element is used 3828 elem.jquery ? elem[0] : elem, this ); 3829 }, 3830 3831 add: function( selector, context ) { 3832 var set = typeof selector === "string" ? 3833 jQuery( selector, context || this.context ) : 3834 jQuery.makeArray( selector ), 3835 all = jQuery.merge( this.get(), set ); 3836 3837 return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ? 3838 all : 3839 jQuery.unique( all ) ); 3840 }, 3841 3842 andSelf: function() { 3843 return this.add( this.prevObject ); 3844 } 3845 }); 3846 3847 // A painfully simple check to see if an element is disconnected 3848 // from a document (should be improved, where feasible). 3849 function isDisconnected( node ) { 3850 return !node || !node.parentNode || node.parentNode.nodeType === 11; 3851 } 3852 3853 jQuery.each({ 3854 parent: function( elem ) { 3855 var parent = elem.parentNode; 3856 return parent && parent.nodeType !== 11 ? parent : null; 3857 }, 3858 parents: function( elem ) { 3859 return jQuery.dir( elem, "parentNode" ); 3860 }, 3861 parentsUntil: function( elem, i, until ) { 3862 return jQuery.dir( elem, "parentNode", until ); 3863 }, 3864 next: function( elem ) { 3865 return jQuery.nth( elem, 2, "nextSibling" ); 3866 }, 3867 prev: function( elem ) { 3868 return jQuery.nth( elem, 2, "previousSibling" ); 3869 }, 3870 nextAll: function( elem ) { 3871 return jQuery.dir( elem, "nextSibling" ); 3872 }, 3873 prevAll: function( elem ) { 3874 return jQuery.dir( elem, "previousSibling" ); 3875 }, 3876 nextUntil: function( elem, i, until ) { 3877 return jQuery.dir( elem, "nextSibling", until ); 3878 }, 3879 prevUntil: function( elem, i, until ) { 3880 return jQuery.dir( elem, "previousSibling", until ); 3881 }, 3882 siblings: function( elem ) { 3883 return jQuery.sibling( elem.parentNode.firstChild, elem ); 3884 }, 3885 children: function( elem ) { 3886 return jQuery.sibling( elem.firstChild ); 3887 }, 3888 contents: function( elem ) { 3889 return jQuery.nodeName( elem, "iframe" ) ? 3890 elem.contentDocument || elem.contentWindow.document : 3891 jQuery.makeArray( elem.childNodes ); 3892 } 3893 }, function( name, fn ) { 3894 jQuery.fn[ name ] = function( until, selector ) { 3895 var ret = jQuery.map( this, fn, until ); 3896 3897 if ( !runtil.test( name ) ) { 3898 selector = until; 3899 } 3900 3901 if ( selector && typeof selector === "string" ) { 3902 ret = jQuery.filter( selector, ret ); 3903 } 3904 3905 ret = this.length > 1 ? jQuery.unique( ret ) : ret; 3906 3907 if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) { 3908 ret = ret.reverse(); 3909 } 3910 3911 return this.pushStack( ret, name, slice.call(arguments).join(",") ); 3912 }; 3913 }); 3914 3915 jQuery.extend({ 3916 filter: function( expr, elems, not ) { 3917 if ( not ) { 3918 expr = ":not(" + expr + ")"; 3919 } 3920 3921 return jQuery.find.matches(expr, elems); 3922 }, 3923 3924 dir: function( elem, dir, until ) { 3925 var matched = [], cur = elem[dir]; 3926 while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { 3927 if ( cur.nodeType === 1 ) { 3928 matched.push( cur ); 3929 } 3930 cur = cur[dir]; 3931 } 3932 return matched; 3933 }, 3934 3935 nth: function( cur, result, dir, elem ) { 3936 result = result || 1; 3937 var num = 0; 3938 3939 for ( ; cur; cur = cur[dir] ) { 3940 if ( cur.nodeType === 1 && ++num === result ) { 3941 break; 3942 } 3943 } 3944 3945 return cur; 3946 }, 3947 3948 sibling: function( n, elem ) { 3949 var r = []; 3950 3951 for ( ; n; n = n.nextSibling ) { 3952 if ( n.nodeType === 1 && n !== elem ) { 3953 r.push( n ); 3954 } 3955 } 3956 3957 return r; 3958 } 3959 }); 3960 var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g, 3961 rleadingWhitespace = /^\s+/, 3962 rxhtmlTag = /(<([\w:]+)[^>]*?)\/>/g, 3963 rselfClosing = /^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i, 3964 rtagName = /<([\w:]+)/, 3965 rtbody = /<tbody/i, 3966 rhtml = /<|&#?\w+;/, 3967 rnocache = /<script|<object|<embed|<option|<style/i, 3968 rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, // checked="checked" or checked (html5) 3969 fcloseTag = function( all, front, tag ) { 3970 return rselfClosing.test( tag ) ? 3971 all : 3972 front + "></" + tag + ">"; 3973 }, 3974 wrapMap = { 3975 option: [ 1, "<select multiple='multiple'>", "</select>" ], 3976 legend: [ 1, "<fieldset>", "</fieldset>" ], 3977 thead: [ 1, "<table>", "</table>" ], 3978 tr: [ 2, "<table><tbody>", "</tbody></table>" ], 3979 td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ], 3980 col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ], 3981 area: [ 1, "<map>", "</map>" ], 3982 _default: [ 0, "", "" ] 3983 }; 3984 3985 wrapMap.optgroup = wrapMap.option; 3986 wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; 3987 wrapMap.th = wrapMap.td; 3988 3989 // IE can't serialize <link> and <script> tags normally 3990 if ( !jQuery.support.htmlSerialize ) { 3991 wrapMap._default = [ 1, "div<div>", "</div>" ]; 3992 } 3993 3994 jQuery.fn.extend({ 3995 text: function( text ) { 3996 if ( jQuery.isFunction(text) ) { 3997 return this.each(function(i) { 3998 var self = jQuery(this); 3999 self.text( text.call(this, i, self.text()) ); 4000 }); 4001 } 4002 4003 if ( typeof text !== "object" && text !== undefined ) { 4004 return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) ); 4005 } 4006 4007 return jQuery.text( this ); 4008 }, 4009 4010 wrapAll: function( html ) { 4011 if ( jQuery.isFunction( html ) ) { 4012 return this.each(function(i) { 4013 jQuery(this).wrapAll( html.call(this, i) ); 4014 }); 4015 } 4016 4017 if ( this[0] ) { 4018 // The elements to wrap the target around 4019 var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true); 4020 4021 if ( this[0].parentNode ) { 4022 wrap.insertBefore( this[0] ); 4023 } 4024 4025 wrap.map(function() { 4026 var elem = this; 4027 4028 while ( elem.firstChild && elem.firstChild.nodeType === 1 ) { 4029 elem = elem.firstChild; 4030 } 4031 4032 return elem; 4033 }).append(this); 4034 } 4035 4036 return this; 4037 }, 4038 4039 wrapInner: function( html ) { 4040 if ( jQuery.isFunction( html ) ) { 4041 return this.each(function(i) { 4042 jQuery(this).wrapInner( html.call(this, i) ); 4043 }); 4044 } 4045 4046 return this.each(function() { 4047 var self = jQuery( this ), contents = self.contents(); 4048 4049 if ( contents.length ) { 4050 contents.wrapAll( html ); 4051 4052 } else { 4053 self.append( html ); 4054 } 4055 }); 4056 }, 4057 4058 wrap: function( html ) { 4059 return this.each(function() { 4060 jQuery( this ).wrapAll( html ); 4061 }); 4062 }, 4063 4064 unwrap: function() { 4065 return this.parent().each(function() { 4066 if ( !jQuery.nodeName( this, "body" ) ) { 4067 jQuery( this ).replaceWith( this.childNodes ); 4068 } 4069 }).end(); 4070 }, 4071 4072 append: function() { 4073 return this.domManip(arguments, true, function( elem ) { 4074 if ( this.nodeType === 1 ) { 4075 this.appendChild( elem ); 4076 } 4077 }); 4078 }, 4079 4080 prepend: function() { 4081 return this.domManip(arguments, true, function( elem ) { 4082 if ( this.nodeType === 1 ) { 4083 this.insertBefore( elem, this.firstChild ); 4084 } 4085 }); 4086 }, 4087 4088 before: function() { 4089 if ( this[0] && this[0].parentNode ) { 4090 return this.domManip(arguments, false, function( elem ) { 4091 this.parentNode.insertBefore( elem, this ); 4092 }); 4093 } else if ( arguments.length ) { 4094 var set = jQuery(arguments[0]); 4095 set.push.apply( set, this.toArray() ); 4096 return this.pushStack( set, "before", arguments ); 4097 } 4098 }, 4099 4100 after: function() { 4101 if ( this[0] && this[0].parentNode ) { 4102 return this.domManip(arguments, false, function( elem ) { 4103 this.parentNode.insertBefore( elem, this.nextSibling ); 4104 }); 4105 } else if ( arguments.length ) { 4106 var set = this.pushStack( this, "after", arguments ); 4107 set.push.apply( set, jQuery(arguments[0]).toArray() ); 4108 return set; 4109 } 4110 }, 4111 4112 // keepData is for internal use only--do not document 4113 remove: function( selector, keepData ) { 4114 for ( var i = 0, elem; (elem = this[i]) != null; i++ ) { 4115 if ( !selector || jQuery.filter( selector, [ elem ] ).length ) { 4116 if ( !keepData && elem.nodeType === 1 ) { 4117 jQuery.cleanData( elem.getElementsByTagName("*") ); 4118 jQuery.cleanData( [ elem ] ); 4119 } 4120 4121 if ( elem.parentNode ) { 4122 elem.parentNode.removeChild( elem ); 4123 } 4124 } 4125 } 4126 4127 return this; 4128 }, 4129 4130 empty: function() { 4131 for ( var i = 0, elem; (elem = this[i]) != null; i++ ) { 4132 // Remove element nodes and prevent memory leaks 4133 if ( elem.nodeType === 1 ) { 4134 jQuery.cleanData( elem.getElementsByTagName("*") ); 4135 } 4136 4137 // Remove any remaining nodes 4138 while ( elem.firstChild ) { 4139 elem.removeChild( elem.firstChild ); 4140 } 4141 } 4142 4143 return this; 4144 }, 4145 4146 clone: function( events ) { 4147 // Do the clone 4148 var ret = this.map(function() { 4149 if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) { 4150 // IE copies events bound via attachEvent when 4151 // using cloneNode. Calling detachEvent on the 4152 // clone will also remove the events from the orignal 4153 // In order to get around this, we use innerHTML. 4154 // Unfortunately, this means some modifications to 4155 // attributes in IE that are actually only stored 4156 // as properties will not be copied (such as the 4157 // the name attribute on an input). 4158 var html = this.outerHTML, ownerDocument = this.ownerDocument; 4159 if ( !html ) { 4160 var div = ownerDocument.createElement("div"); 4161 div.appendChild( this.cloneNode(true) ); 4162 html = div.innerHTML; 4163 } 4164 4165 return jQuery.clean([html.replace(rinlinejQuery, "") 4166 // Handle the case in IE 8 where action=/test/> self-closes a tag 4167 .replace(/=([^="'>\s]+\/)>/g, '="$1">') 4168 .replace(rleadingWhitespace, "")], ownerDocument)[0]; 4169 } else { 4170 return this.cloneNode(true); 4171 } 4172 }); 4173 4174 // Copy the events from the original to the clone 4175 if ( events === true ) { 4176 cloneCopyEvent( this, ret ); 4177 cloneCopyEvent( this.find("*"), ret.find("*") ); 4178 } 4179 4180 // Return the cloned set 4181 return ret; 4182 }, 4183 4184 html: function( value ) { 4185 if ( value === undefined ) { 4186 return this[0] && this[0].nodeType === 1 ? 4187 this[0].innerHTML.replace(rinlinejQuery, "") : 4188 null; 4189 4190 // See if we can take a shortcut and just use innerHTML 4191 } else if ( typeof value === "string" && !rnocache.test( value ) && 4192 (jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) && 4193 !wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) { 4194 4195 value = value.replace(rxhtmlTag, fcloseTag); 4196 4197 try { 4198 for ( var i = 0, l = this.length; i < l; i++ ) { 4199 // Remove element nodes and prevent memory leaks 4200 if ( this[i].nodeType === 1 ) { 4201 jQuery.cleanData( this[i].getElementsByTagName("*") ); 4202 this[i].innerHTML = value; 4203 } 4204 } 4205 4206 // If using innerHTML throws an exception, use the fallback method 4207 } catch(e) { 4208 this.empty().append( value ); 4209 } 4210 4211 } else if ( jQuery.isFunction( value ) ) { 4212 this.each(function(i){ 4213 var self = jQuery(this), old = self.html(); 4214 self.empty().append(function(){ 4215 return value.call( this, i, old ); 4216 }); 4217 }); 4218 4219 } else { 4220 this.empty().append( value ); 4221 } 4222 4223 return this; 4224 }, 4225 4226 replaceWith: function( value ) { 4227 if ( this[0] && this[0].parentNode ) { 4228 // Make sure that the elements are removed from the DOM before they are inserted 4229 // this can help fix replacing a parent with child elements 4230 if ( jQuery.isFunction( value ) ) { 4231 return this.each(function(i) { 4232 var self = jQuery(this), old = self.html(); 4233 self.replaceWith( value.call( this, i, old ) ); 4234 }); 4235 } 4236 4237 if ( typeof value !== "string" ) { 4238 value = jQuery(value).detach(); 4239 } 4240 4241 return this.each(function() { 4242 var next = this.nextSibling, parent = this.parentNode; 4243 4244 jQuery(this).remove(); 4245 4246 if ( next ) { 4247 jQuery(next).before( value ); 4248 } else { 4249 jQuery(parent).append( value ); 4250 } 4251 }); 4252 } else { 4253 return this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value ); 4254 } 4255 }, 4256 4257 detach: function( selector ) { 4258 return this.remove( selector, true ); 4259 }, 4260 4261 domManip: function( args, table, callback ) { 4262 var results, first, value = args[0], scripts = [], fragment, parent; 4263 4264 // We can't cloneNode fragments that contain checked, in WebKit 4265 if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) { 4266 return this.each(function() { 4267 jQuery(this).domManip( args, table, callback, true ); 4268 }); 4269 } 4270 4271 if ( jQuery.isFunction(value) ) { 4272 return this.each(function(i) { 4273 var self = jQuery(this); 4274 args[0] = value.call(this, i, table ? self.html() : undefined); 4275 self.domManip( args, table, callback ); 4276 }); 4277 } 4278 4279 if ( this[0] ) { 4280 parent = value && value.parentNode; 4281 4282 // If we're in a fragment, just use that instead of building a new one 4283 if ( jQuery.support.parentNode && parent && parent.nodeType === 11 && parent.childNodes.length === this.length ) { 4284 results = { fragment: parent }; 4285 4286 } else { 4287 results = buildFragment( args, this, scripts ); 4288 } 4289 4290 fragment = results.fragment; 4291 4292 if ( fragment.childNodes.length === 1 ) { 4293 first = fragment = fragment.firstChild; 4294 } else { 4295 first = fragment.firstChild; 4296 } 4297 4298 if ( first ) { 4299 table = table && jQuery.nodeName( first, "tr" ); 4300 4301 for ( var i = 0, l = this.length; i < l; i++ ) { 4302 callback.call( 4303 table ? 4304 root(this[i], first) : 4305 this[i], 4306 i > 0 || results.cacheable || this.length > 1 ? 4307 fragment.cloneNode(true) : 4308 fragment 4309 ); 4310 } 4311 } 4312 4313 if ( scripts.length ) { 4314 jQuery.each( scripts, evalScript ); 4315 } 4316 } 4317 4318 return this; 4319 4320 function root( elem, cur ) { 4321 return jQuery.nodeName(elem, "table") ? 4322 (elem.getElementsByTagName("tbody")[0] || 4323 elem.appendChild(elem.ownerDocument.createElement("tbody"))) : 4324 elem; 4325 } 4326 } 4327 }); 4328 4329 function cloneCopyEvent(orig, ret) { 4330 var i = 0; 4331 4332 ret.each(function() { 4333 if ( this.nodeName !== (orig[i] && orig[i].nodeName) ) { 4334 return; 4335 } 4336 4337 var oldData = jQuery.data( orig[i++] ), curData = jQuery.data( this, oldData ), events = oldData && oldData.events; 4338 4339 if ( events ) { 4340 delete curData.handle; 4341 curData.events = {}; 4342 4343 for ( var type in events ) { 4344 for ( var handler in events[ type ] ) { 4345 jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data ); 4346 } 4347 } 4348 } 4349 }); 4350 } 4351 4352 function buildFragment( args, nodes, scripts ) { 4353 var fragment, cacheable, cacheresults, 4354 doc = (nodes && nodes[0] ? nodes[0].ownerDocument || nodes[0] : document); 4355 4356 // Only cache "small" (1/2 KB) strings that are associated with the main document 4357 // Cloning options loses the selected state, so don't cache them 4358 // IE 6 doesn't like it when you put <object> or <embed> elements in a fragment 4359 // Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache 4360 if ( args.length === 1 && typeof args[0] === "string" && args[0].length < 512 && doc === document && 4361 !rnocache.test( args[0] ) && (jQuery.support.checkClone || !rchecked.test( args[0] )) ) { 4362 4363 cacheable = true; 4364 cacheresults = jQuery.fragments[ args[0] ]; 4365 if ( cacheresults ) { 4366 if ( cacheresults !== 1 ) { 4367 fragment = cacheresults; 4368 } 4369 } 4370 } 4371 4372 if ( !fragment ) { 4373 fragment = doc.createDocumentFragment(); 4374 jQuery.clean( args, doc, fragment, scripts ); 4375 } 4376 4377 if ( cacheable ) { 4378 jQuery.fragments[ args[0] ] = cacheresults ? fragment : 1; 4379 } 4380 4381 return { fragment: fragment, cacheable: cacheable }; 4382 } 4383 4384 jQuery.fragments = {}; 4385 4386 jQuery.each({ 4387 appendTo: "append", 4388 prependTo: "prepend", 4389 insertBefore: "before", 4390 insertAfter: "after", 4391 replaceAll: "replaceWith" 4392 }, function( name, original ) { 4393 jQuery.fn[ name ] = function( selector ) { 4394 var ret = [], insert = jQuery( selector ), 4395 parent = this.length === 1 && this[0].parentNode; 4396 4397 if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) { 4398 insert[ original ]( this[0] ); 4399 return this; 4400 4401 } else { 4402 for ( var i = 0, l = insert.length; i < l; i++ ) { 4403 var elems = (i > 0 ? this.clone(true) : this).get(); 4404 jQuery.fn[ original ].apply( jQuery(insert[i]), elems ); 4405 ret = ret.concat( elems ); 4406 } 4407 4408 return this.pushStack( ret, name, insert.selector ); 4409 } 4410 }; 4411 }); 4412 4413 jQuery.extend({ 4414 clean: function( elems, context, fragment, scripts ) { 4415 context = context || document; 4416 4417 // !context.createElement fails in IE with an error but returns typeof 'object' 4418 if ( typeof context.createElement === "undefined" ) { 4419 context = context.ownerDocument || context[0] && context[0].ownerDocument || document; 4420 } 4421 4422 var ret = []; 4423 4424 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { 4425 if ( typeof elem === "number" ) { 4426 elem += ""; 4427 } 4428 4429 if ( !elem ) { 4430 continue; 4431 } 4432 4433 // Convert html string into DOM nodes 4434 if ( typeof elem === "string" && !rhtml.test( elem ) ) { 4435 elem = context.createTextNode( elem ); 4436 4437 } else if ( typeof elem === "string" ) { 4438 // Fix "XHTML"-style tags in all browsers 4439 elem = elem.replace(rxhtmlTag, fcloseTag); 4440 4441 // Trim whitespace, otherwise indexOf won't work as expected 4442 var tag = (rtagName.exec( elem ) || ["", ""])[1].toLowerCase(), 4443 wrap = wrapMap[ tag ] || wrapMap._default, 4444 depth = wrap[0], 4445 div = context.createElement("div"); 4446 4447 // Go to html and back, then peel off extra wrappers 4448 div.innerHTML = wrap[1] + elem + wrap[2]; 4449 4450 // Move to the right depth 4451 while ( depth-- ) { 4452 div = div.lastChild; 4453 } 4454 4455 // Remove IE's autoinserted <tbody> from table fragments 4456 if ( !jQuery.support.tbody ) { 4457 4458 // String was a <table>, *may* have spurious <tbody> 4459 var hasBody = rtbody.test(elem), 4460 tbody = tag === "table" && !hasBody ? 4461 div.firstChild && div.firstChild.childNodes : 4462 4463 // String was a bare <thead> or <tfoot> 4464 wrap[1] === "<table>" && !hasBody ? 4465 div.childNodes : 4466 []; 4467 4468 for ( var j = tbody.length - 1; j >= 0 ; --j ) { 4469 if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) { 4470 tbody[ j ].parentNode.removeChild( tbody[ j ] ); 4471 } 4472 } 4473 4474 } 4475 4476 // IE completely kills leading whitespace when innerHTML is used 4477 if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) { 4478 div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild ); 4479 } 4480 4481 elem = div.childNodes; 4482 } 4483 4484 if ( elem.nodeType ) { 4485 ret.push( elem ); 4486 } else { 4487 ret = jQuery.merge( ret, elem ); 4488 } 4489 } 4490 4491 if ( fragment ) { 4492 for ( var i = 0; ret[i]; i++ ) { 4493 if ( scripts && jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) { 4494 scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] ); 4495 4496 } else { 4497 if ( ret[i].nodeType === 1 ) { 4498 ret.splice.apply( ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))) ); 4499 } 4500 fragment.appendChild( ret[i] ); 4501 } 4502 } 4503 } 4504 4505 return ret; 4506 }, 4507 4508 cleanData: function( elems ) { 4509 var data, id, cache = jQuery.cache, 4510 special = jQuery.event.special, 4511 deleteExpando = jQuery.support.deleteExpando; 4512 4513 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { 4514 id = elem[ jQuery.expando ]; 4515 4516 if ( id ) { 4517 data = cache[ id ]; 4518 4519 if ( data.events ) { 4520 for ( var type in data.events ) { 4521 if ( special[ type ] ) { 4522 jQuery.event.remove( elem, type ); 4523 4524 } else { 4525 removeEvent( elem, type, data.handle ); 4526 } 4527 } 4528 } 4529 4530 if ( deleteExpando ) { 4531 delete elem[ jQuery.expando ]; 4532 4533 } else if ( elem.removeAttribute ) { 4534 elem.removeAttribute( jQuery.expando ); 4535 } 4536 4537 delete cache[ id ]; 4538 } 4539 } 4540 } 4541 }); 4542 // exclude the following css properties to add px 4543 var rexclude = /z-?index|font-?weight|opacity|zoom|line-?height/i, 4544 ralpha = /alpha\([^)]*\)/, 4545 ropacity = /opacity=([^)]*)/, 4546 rfloat = /float/i, 4547 rdashAlpha = /-([a-z])/ig, 4548 rupper = /([A-Z])/g, 4549 rnumpx = /^-?\d+(?:px)?$/i, 4550 rnum = /^-?\d/, 4551 4552 cssShow = { position: "absolute", visibility: "hidden", display:"block" }, 4553 cssWidth = [ "Left", "Right" ], 4554 cssHeight = [ "Top", "Bottom" ], 4555 4556 // cache check for defaultView.getComputedStyle 4557 getComputedStyle = document.defaultView && document.defaultView.getComputedStyle, 4558 // normalize float css property 4559 styleFloat = jQuery.support.cssFloat ? "cssFloat" : "styleFloat", 4560 fcamelCase = function( all, letter ) { 4561 return letter.toUpperCase(); 4562 }; 4563 4564 jQuery.fn.css = function( name, value ) { 4565 return access( this, name, value, true, function( elem, name, value ) { 4566 if ( value === undefined ) { 4567 return jQuery.curCSS( elem, name ); 4568 } 4569 4570 if ( typeof value === "number" && !rexclude.test(name) ) { 4571 value += "px"; 4572 } 4573 4574 jQuery.style( elem, name, value ); 4575 }); 4576 }; 4577 4578 jQuery.extend({ 4579 style: function( elem, name, value ) { 4580 // don't set styles on text and comment nodes 4581 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) { 4582 return undefined; 4583 } 4584 4585 // ignore negative width and height values #1599 4586 if ( (name === "width" || name === "height") && parseFloat(value) < 0 ) { 4587 value = undefined; 4588 } 4589 4590 var style = elem.style || elem, set = value !== undefined; 4591 4592 // IE uses filters for opacity 4593 if ( !jQuery.support.opacity && name === "opacity" ) { 4594 if ( set ) { 4595 // IE has trouble with opacity if it does not have layout 4596 // Force it by setting the zoom level 4597 style.zoom = 1; 4598 4599 // Set the alpha filter to set the opacity 4600 var opacity = parseInt( value, 10 ) + "" === "NaN" ? "" : "alpha(opacity=" + value * 100 + ")"; 4601 var filter = style.filter || jQuery.curCSS( elem, "filter" ) || ""; 4602 style.filter = ralpha.test(filter) ? filter.replace(ralpha, opacity) : opacity; 4603 } 4604 4605 return style.filter && style.filter.indexOf("opacity=") >= 0 ? 4606 (parseFloat( ropacity.exec(style.filter)[1] ) / 100) + "": 4607 ""; 4608 } 4609 4610 // Make sure we're using the right name for getting the float value 4611 if ( rfloat.test( name ) ) { 4612 name = styleFloat; 4613 } 4614 4615 name = name.replace(rdashAlpha, fcamelCase); 4616 4617 if ( set ) { 4618 style[ name ] = value; 4619 } 4620 4621 return style[ name ]; 4622 }, 4623 4624 css: function( elem, name, force, extra ) { 4625 if ( name === "width" || name === "height" ) { 4626 var val, props = cssShow, which = name === "width" ? cssWidth : cssHeight; 4627 4628 function getWH() { 4629 val = name === "width" ? elem.offsetWidth : elem.offsetHeight; 4630 4631 if ( extra === "border" ) { 4632 return; 4633 } 4634 4635 jQuery.each( which, function() { 4636 if ( !extra ) { 4637 val -= parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0; 4638 } 4639 4640 if ( extra === "margin" ) { 4641 val += parseFloat(jQuery.curCSS( elem, "margin" + this, true)) || 0; 4642 } else { 4643 val -= parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0; 4644 } 4645 }); 4646 } 4647 4648 if ( elem.offsetWidth !== 0 ) { 4649 getWH(); 4650 } else { 4651 jQuery.swap( elem, props, getWH ); 4652 } 4653 4654 return Math.max(0, Math.round(val)); 4655 } 4656 4657 return jQuery.curCSS( elem, name, force ); 4658 }, 4659 4660 curCSS: function( elem, name, force ) { 4661 var ret, style = elem.style, filter; 4662 4663 // IE uses filters for opacity 4664 if ( !jQuery.support.opacity && name === "opacity" && elem.currentStyle ) { 4665 ret = ropacity.test(elem.currentStyle.filter || "") ? 4666 (parseFloat(RegExp.$1) / 100) + "" : 4667 ""; 4668 4669 return ret === "" ? 4670 "1" : 4671 ret; 4672 } 4673 4674 // Make sure we're using the right name for getting the float value 4675 if ( rfloat.test( name ) ) { 4676 name = styleFloat; 4677 } 4678 4679 if ( !force && style && style[ name ] ) { 4680 ret = style[ name ]; 4681 4682 } else if ( getComputedStyle ) { 4683 4684 // Only "float" is needed here 4685 if ( rfloat.test( name ) ) { 4686 name = "float"; 4687 } 4688 4689 name = name.replace( rupper, "-$1" ).toLowerCase(); 4690 4691 var defaultView = elem.ownerDocument.defaultView; 4692 4693 if ( !defaultView ) { 4694 return null; 4695 } 4696 4697 var computedStyle = defaultView.getComputedStyle( elem, null ); 4698 4699 if ( computedStyle ) { 4700 ret = computedStyle.getPropertyValue( name ); 4701 } 4702 4703 // We should always get a number back from opacity 4704 if ( name === "opacity" && ret === "" ) { 4705 ret = "1"; 4706 } 4707 4708 } else if ( elem.currentStyle ) { 4709 var camelCase = name.replace(rdashAlpha, fcamelCase); 4710 4711 ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ]; 4712 4713 // From the awesome hack by Dean Edwards 4714 // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 4715 4716 // If we're not dealing with a regular pixel number 4717 // but a number that has a weird ending, we need to convert it to pixels 4718 if ( !rnumpx.test( ret ) && rnum.test( ret ) ) { 4719 // Remember the original values 4720 var left = style.left, rsLeft = elem.runtimeStyle.left; 4721 4722 // Put in the new values to get a computed value out 4723 elem.runtimeStyle.left = elem.currentStyle.left; 4724 style.left = camelCase === "fontSize" ? "1em" : (ret || 0); 4725 ret = style.pixelLeft + "px"; 4726 4727 // Revert the changed values 4728 style.left = left; 4729 elem.runtimeStyle.left = rsLeft; 4730 } 4731 } 4732 4733 return ret; 4734 }, 4735 4736 // A method for quickly swapping in/out CSS properties to get correct calculations 4737 swap: function( elem, options, callback ) { 4738 var old = {}; 4739 4740 // Remember the old values, and insert the new ones 4741 for ( var name in options ) { 4742 old[ name ] = elem.style[ name ]; 4743 elem.style[ name ] = options[ name ]; 4744 } 4745 4746 callback.call( elem ); 4747 4748 // Revert the old values 4749 for ( var name in options ) { 4750 elem.style[ name ] = old[ name ]; 4751 } 4752 } 4753 }); 4754 4755 if ( jQuery.expr && jQuery.expr.filters ) { 4756 jQuery.expr.filters.hidden = function( elem ) { 4757 var width = elem.offsetWidth, height = elem.offsetHeight, 4758 skip = elem.nodeName.toLowerCase() === "tr"; 4759 4760 return width === 0 && height === 0 && !skip ? 4761 true : 4762 width > 0 && height > 0 && !skip ? 4763 false : 4764 jQuery.curCSS(elem, "display") === "none"; 4765 }; 4766 4767 jQuery.expr.filters.visible = function( elem ) { 4768 return !jQuery.expr.filters.hidden( elem ); 4769 }; 4770 } 4771 var jsc = now(), 4772 rscript = /<script(.|\s)*?\/script>/gi, 4773 rselectTextarea = /select|textarea/i, 4774 rinput = /color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i, 4775 jsre = /=\?(&|$)/, 4776 rquery = /\?/, 4777 rts = /(\?|&)_=.*?(&|$)/, 4778 rurl = /^(\w+:)?\/\/([^\/?#]+)/, 4779 r20 = /%20/g, 4780 4781 // Keep a copy of the old load method 4782 _load = jQuery.fn.load; 4783 4784 jQuery.fn.extend({ 4785 load: function( url, params, callback ) { 4786 if ( typeof url !== "string" ) { 4787 return _load.call( this, url ); 4788 4789 // Don't do a request if no elements are being requested 4790 } else if ( !this.length ) { 4791 return this; 4792 } 4793 4794 var off = url.indexOf(" "); 4795 if ( off >= 0 ) { 4796 var selector = url.slice(off, url.length); 4797 url = url.slice(0, off); 4798 } 4799 4800 // Default to a GET request 4801 var type = "GET"; 4802 4803 // If the second parameter was provided 4804 if ( params ) { 4805 // If it's a function 4806 if ( jQuery.isFunction( params ) ) { 4807 // We assume that it's the callback 4808 callback = params; 4809 params = null; 4810 4811 // Otherwise, build a param string 4812 } else if ( typeof params === "object" ) { 4813 params = jQuery.param( params, jQuery.ajaxSettings.traditional ); 4814 type = "POST"; 4815 } 4816 } 4817 4818 var self = this; 4819 4820 // Request the remote document 4821 jQuery.ajax({ 4822 url: url, 4823 type: type, 4824 dataType: "html", 4825 data: params, 4826 complete: function( res, status ) { 4827 // If successful, inject the HTML into all the matched elements 4828 if ( status === "success" || status === "notmodified" ) { 4829 // See if a selector was specified 4830 self.html( selector ? 4831 // Create a dummy div to hold the results 4832 jQuery("<div />") 4833 // inject the contents of the document in, removing the scripts 4834 // to avoid any 'Permission Denied' errors in IE 4835 .append(res.responseText.replace(rscript, "")) 4836 4837 // Locate the specified elements 4838 .find(selector) : 4839 4840 // If not, just inject the full result 4841 res.responseText ); 4842 } 4843 4844 if ( callback ) { 4845 self.each( callback, [res.responseText, status, res] ); 4846 } 4847 } 4848 }); 4849 4850 return this; 4851 }, 4852 4853 serialize: function() { 4854 return jQuery.param(this.serializeArray()); 4855 }, 4856 serializeArray: function() { 4857 return this.map(function() { 4858 return this.elements ? jQuery.makeArray(this.elements) : this; 4859 }) 4860 .filter(function() { 4861 return this.name && !this.disabled && 4862 (this.checked || rselectTextarea.test(this.nodeName) || 4863 rinput.test(this.type)); 4864 }) 4865 .map(function( i, elem ) { 4866 var val = jQuery(this).val(); 4867 4868 return val == null ? 4869 null : 4870 jQuery.isArray(val) ? 4871 jQuery.map( val, function( val, i ) { 4872 return { name: elem.name, value: val }; 4873 }) : 4874 { name: elem.name, value: val }; 4875 }).get(); 4876 } 4877 }); 4878 4879 // Attach a bunch of functions for handling common AJAX events 4880 jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "), function( i, o ) { 4881 jQuery.fn[o] = function( f ) { 4882 return this.bind(o, f); 4883 }; 4884 }); 4885 4886 jQuery.extend({ 4887 4888 get: function( url, data, callback, type ) { 4889 // shift arguments if data argument was omited 4890 if ( jQuery.isFunction( data ) ) { 4891 type = type || callback; 4892 callback = data; 4893 data = null; 4894 } 4895 4896 return jQuery.ajax({ 4897 type: "GET", 4898 url: url, 4899 data: data, 4900 success: callback, 4901 dataType: type 4902 }); 4903 }, 4904 4905 getScript: function( url, callback ) { 4906 return jQuery.get(url, null, callback, "script"); 4907 }, 4908 4909 getJSON: function( url, data, callback ) { 4910 return jQuery.get(url, data, callback, "json"); 4911 }, 4912 4913 post: function( url, data, callback, type ) { 4914 // shift arguments if data argument was omited 4915 if ( jQuery.isFunction( data ) ) { 4916 type = type || callback; 4917 callback = data; 4918 data = {}; 4919 } 4920 4921 return jQuery.ajax({ 4922 type: "POST", 4923 url: url, 4924 data: data, 4925 success: callback, 4926 dataType: type 4927 }); 4928 }, 4929 4930 ajaxSetup: function( settings ) { 4931 jQuery.extend( jQuery.ajaxSettings, settings ); 4932 }, 4933 4934 ajaxSettings: { 4935 url: location.href, 4936 global: true, 4937 type: "GET", 4938 contentType: "application/x-www-form-urlencoded", 4939 processData: true, 4940 async: true, 4941 /* 4942 timeout: 0, 4943 data: null, 4944 username: null, 4945 password: null, 4946 traditional: false, 4947 */ 4948 // Create the request object; Microsoft failed to properly 4949 // implement the XMLHttpRequest in IE7 (can't request local files), 4950 // so we use the ActiveXObject when it is available 4951 // This function can be overriden by calling jQuery.ajaxSetup 4952 xhr: window.XMLHttpRequest && (window.location.protocol !== "file:" || !window.ActiveXObject) ? 4953 function() { 4954 return new window.XMLHttpRequest(); 4955 } : 4956 function() { 4957 try { 4958 return new window.ActiveXObject("Microsoft.XMLHTTP"); 4959 } catch(e) {} 4960 }, 4961 accepts: { 4962 xml: "application/xml, text/xml", 4963 html: "text/html", 4964 script: "text/javascript, application/javascript", 4965 json: "application/json, text/javascript", 4966 text: "text/plain", 4967 _default: "*/*" 4968 } 4969 }, 4970 4971 // Last-Modified header cache for next request 4972 lastModified: {}, 4973 etag: {}, 4974 4975 ajax: function( origSettings ) { 4976 var s = jQuery.extend(true, {}, jQuery.ajaxSettings, origSettings); 4977 4978 var jsonp, status, data, 4979 callbackContext = origSettings && origSettings.context || s, 4980 type = s.type.toUpperCase(); 4981 4982 // convert data if not already a string 4983 if ( s.data && s.processData && typeof s.data !== "string" ) { 4984 s.data = jQuery.param( s.data, s.traditional ); 4985 } 4986 4987 // Handle JSONP Parameter Callbacks 4988 if ( s.dataType === "jsonp" ) { 4989 if ( type === "GET" ) { 4990 if ( !jsre.test( s.url ) ) { 4991 s.url += (rquery.test( s.url ) ? "&" : "?") + (s.jsonp || "callback") + "=?"; 4992 } 4993 } else if ( !s.data || !jsre.test(s.data) ) { 4994 s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?"; 4995 } 4996 s.dataType = "json"; 4997 } 4998 4999 // Build temporary JSONP function 5000 if ( s.dataType === "json" && (s.data && jsre.test(s.data) || jsre.test(s.url)) ) { 5001 jsonp = s.jsonpCallback || ("jsonp" + jsc++); 5002 5003 // Replace the =? sequence both in the query string and the data 5004 if ( s.data ) { 5005 s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1"); 5006 } 5007 5008 s.url = s.url.replace(jsre, "=" + jsonp + "$1"); 5009 5010 // We need to make sure 5011 // that a JSONP style response is executed properly 5012 s.dataType = "script"; 5013 5014 // Handle JSONP-style loading 5015 window[ jsonp ] = window[ jsonp ] || function( tmp ) { 5016 data = tmp; 5017 success(); 5018 complete(); 5019 // Garbage collect 5020 window[ jsonp ] = undefined; 5021 5022 try { 5023 delete window[ jsonp ]; 5024 } catch(e) {} 5025 5026 if ( head ) { 5027 head.removeChild( script ); 5028 } 5029 }; 5030 } 5031 5032 if ( s.dataType === "script" && s.cache === null ) { 5033 s.cache = false; 5034 } 5035 5036 if ( s.cache === false && type === "GET" ) { 5037 var ts = now(); 5038 5039 // try replacing _= if it is there 5040 var ret = s.url.replace(rts, "$1_=" + ts + "$2"); 5041 5042 // if nothing was replaced, add timestamp to the end 5043 s.url = ret + ((ret === s.url) ? (rquery.test(s.url) ? "&" : "?") + "_=" + ts : ""); 5044 } 5045 5046 // If data is available, append data to url for get requests 5047 if ( s.data && type === "GET" ) { 5048 s.url += (rquery.test(s.url) ? "&" : "?") + s.data; 5049 } 5050 5051 // Watch for a new set of requests 5052 if ( s.global && ! jQuery.active++ ) { 5053 jQuery.event.trigger( "ajaxStart" ); 5054 } 5055 5056 // Matches an absolute URL, and saves the domain 5057 var parts = rurl.exec( s.url ), 5058 remote = parts && (parts[1] && parts[1] !== location.protocol || parts[2] !== location.host); 5059 5060 // If we're requesting a remote document 5061 // and trying to load JSON or Script with a GET 5062 if ( s.dataType === "script" && type === "GET" && remote ) { 5063 var head = document.getElementsByTagName("head")[0] || document.documentElement; 5064 var script = document.createElement("script"); 5065 script.src = s.url; 5066 if ( s.scriptCharset ) { 5067 script.charset = s.scriptCharset; 5068 } 5069 5070 // Handle Script loading 5071 if ( !jsonp ) { 5072 var done = false; 5073 5074 // Attach handlers for all browsers 5075 script.onload = script.onreadystatechange = function() { 5076 if ( !done && (!this.readyState || 5077 this.readyState === "loaded" || this.readyState === "complete") ) { 5078 done = true; 5079 success(); 5080 complete(); 5081 5082 // Handle memory leak in IE 5083 script.onload = script.onreadystatechange = null; 5084 if ( head && script.parentNode ) { 5085 head.removeChild( script ); 5086 } 5087 } 5088 }; 5089 } 5090 5091 // Use insertBefore instead of appendChild to circumvent an IE6 bug. 5092 // This arises when a base node is used (#2709 and #4378). 5093 head.insertBefore( script, head.firstChild ); 5094 5095 // We handle everything using the script element injection 5096 return undefined; 5097 } 5098 5099 var requestDone = false; 5100 5101 // Create the request object 5102 var xhr = s.xhr(); 5103 5104 if ( !xhr ) { 5105 return; 5106 } 5107 5108 // Open the socket 5109 // Passing null username, generates a login popup on Opera (#2865) 5110 if ( s.username ) { 5111 xhr.open(type, s.url, s.async, s.username, s.password); 5112 } else { 5113 xhr.open(type, s.url, s.async); 5114 } 5115 5116 // Need an extra try/catch for cross domain requests in Firefox 3 5117 try { 5118 // Set the correct header, if data is being sent 5119 if ( s.data || origSettings && origSettings.contentType ) { 5120 xhr.setRequestHeader("Content-Type", s.contentType); 5121 } 5122 5123 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. 5124 if ( s.ifModified ) { 5125 if ( jQuery.lastModified[s.url] ) { 5126 xhr.setRequestHeader("If-Modified-Since", jQuery.lastModified[s.url]); 5127 } 5128 5129 if ( jQuery.etag[s.url] ) { 5130 xhr.setRequestHeader("If-None-Match", jQuery.etag[s.url]); 5131 } 5132 } 5133 5134 // Set header so the called script knows that it's an XMLHttpRequest 5135 // Only send the header if it's not a remote XHR 5136 if ( !remote ) { 5137 xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); 5138 } 5139 5140 // Set the Accepts header for the server, depending on the dataType 5141 xhr.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ? 5142 s.accepts[ s.dataType ] + ", */*" : 5143 s.accepts._default ); 5144 } catch(e) {} 5145 5146 // Allow custom headers/mimetypes and early abort 5147 if ( s.beforeSend && s.beforeSend.call(callbackContext, xhr, s) === false ) { 5148 // Handle the global AJAX counter 5149 if ( s.global && ! --jQuery.active ) { 5150 jQuery.event.trigger( "ajaxStop" ); 5151 } 5152 5153 // close opended socket 5154 xhr.abort(); 5155 return false; 5156 } 5157 5158 if ( s.global ) { 5159 trigger("ajaxSend", [xhr, s]); 5160 } 5161 5162 // Wait for a response to come back 5163 var onreadystatechange = xhr.onreadystatechange = function( isTimeout ) { 5164 // The request was aborted 5165 if ( !xhr || xhr.readyState === 0 || isTimeout === "abort" ) { 5166 // Opera doesn't call onreadystatechange before this point 5167 // so we simulate the call 5168 if ( !requestDone ) { 5169 complete(); 5170 } 5171 5172 requestDone = true; 5173 if ( xhr ) { 5174 xhr.onreadystatechange = jQuery.noop; 5175 } 5176 5177 // The transfer is complete and the data is available, or the request timed out 5178 } else if ( !requestDone && xhr && (xhr.readyState === 4 || isTimeout === "timeout") ) { 5179 requestDone = true; 5180 xhr.onreadystatechange = jQuery.noop; 5181 5182 status = isTimeout === "timeout" ? 5183 "timeout" : 5184 !jQuery.httpSuccess( xhr ) ? 5185 "error" : 5186 s.ifModified && jQuery.httpNotModified( xhr, s.url ) ? 5187 "notmodified" : 5188 "success"; 5189 5190 var errMsg; 5191 5192 if ( status === "success" ) { 5193 // Watch for, and catch, XML document parse errors 5194 try { 5195 // process the data (runs the xml through httpData regardless of callback) 5196 data = jQuery.httpData( xhr, s.dataType, s ); 5197 } catch(err) { 5198 status = "parsererror"; 5199 errMsg = err; 5200 } 5201 } 5202 5203 // Make sure that the request was successful or notmodified 5204 if ( status === "success" || status === "notmodified" ) { 5205 // JSONP handles its own success callback 5206 if ( !jsonp ) { 5207 success(); 5208 } 5209 } else { 5210 jQuery.handleError(s, xhr, status, errMsg); 5211 } 5212 5213 // Fire the complete handlers 5214 complete(); 5215 5216 if ( isTimeout === "timeout" ) { 5217 xhr.abort(); 5218 } 5219 5220 // Stop memory leaks 5221 if ( s.async ) { 5222 xhr = null; 5223 } 5224 } 5225 }; 5226 5227 // Override the abort handler, if we can (IE doesn't allow it, but that's OK) 5228 // Opera doesn't fire onreadystatechange at all on abort 5229 try { 5230 var oldAbort = xhr.abort; 5231 xhr.abort = function() { 5232 if ( xhr ) { 5233 oldAbort.call( xhr ); 5234 } 5235 5236 onreadystatechange( "abort" ); 5237 }; 5238 } catch(e) { } 5239 5240 // Timeout checker 5241 if ( s.async && s.timeout > 0 ) { 5242 setTimeout(function() { 5243 // Check to see if the request is still happening 5244 if ( xhr && !requestDone ) { 5245 onreadystatechange( "timeout" ); 5246 } 5247 }, s.timeout); 5248 } 5249 5250 // Send the data 5251 try { 5252 xhr.send( type === "POST" || type === "PUT" || type === "DELETE" ? s.data : null ); 5253 } catch(e) { 5254 jQuery.handleError(s, xhr, null, e); 5255 // Fire the complete handlers 5256 complete(); 5257 } 5258 5259 // firefox 1.5 doesn't fire statechange for sync requests 5260 if ( !s.async ) { 5261 onreadystatechange(); 5262 } 5263 5264 function success() { 5265 // If a local callback was specified, fire it and pass it the data 5266 if ( s.success ) { 5267 s.success.call( callbackContext, data, status, xhr ); 5268 } 5269 5270 // Fire the global callback 5271 if ( s.global ) { 5272 trigger( "ajaxSuccess", [xhr, s] ); 5273 } 5274 } 5275 5276 function complete() { 5277 // Process result 5278 if ( s.complete ) { 5279 s.complete.call( callbackContext, xhr, status); 5280 } 5281 5282 // The request was completed 5283 if ( s.global ) { 5284 trigger( "ajaxComplete", [xhr, s] ); 5285 } 5286 5287 // Handle the global AJAX counter 5288 if ( s.global && ! --jQuery.active ) { 5289 jQuery.event.trigger( "ajaxStop" ); 5290 } 5291 } 5292 5293 function trigger(type, args) { 5294 (s.context ? jQuery(s.context) : jQuery.event).trigger(type, args); 5295 } 5296 5297 // return XMLHttpRequest to allow aborting the request etc. 5298 return xhr; 5299 }, 5300 5301 handleError: function( s, xhr, status, e ) { 5302 // If a local callback was specified, fire it 5303 if ( s.error ) { 5304 s.error.call( s.context || s, xhr, status, e ); 5305 } 5306 5307 // Fire the global callback 5308 if ( s.global ) { 5309 (s.context ? jQuery(s.context) : jQuery.event).trigger( "ajaxError", [xhr, s, e] ); 5310 } 5311 }, 5312 5313 // Counter for holding the number of active queries 5314 active: 0, 5315 5316 // Determines if an XMLHttpRequest was successful or not 5317 httpSuccess: function( xhr ) { 5318 try { 5319 // IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450 5320 return !xhr.status && location.protocol === "file:" || 5321 // Opera returns 0 when status is 304 5322 ( xhr.status >= 200 && xhr.status < 300 ) || 5323 xhr.status === 304 || xhr.status === 1223 || xhr.status === 0; 5324 } catch(e) {} 5325 5326 return false; 5327 }, 5328 5329 // Determines if an XMLHttpRequest returns NotModified 5330 httpNotModified: function( xhr, url ) { 5331 var lastModified = xhr.getResponseHeader("Last-Modified"), 5332 etag = xhr.getResponseHeader("Etag"); 5333 5334 if ( lastModified ) { 5335 jQuery.lastModified[url] = lastModified; 5336 } 5337 5338 if ( etag ) { 5339 jQuery.etag[url] = etag; 5340 } 5341 5342 // Opera returns 0 when status is 304 5343 return xhr.status === 304 || xhr.status === 0; 5344 }, 5345 5346 httpData: function( xhr, type, s ) { 5347 var ct = xhr.getResponseHeader("content-type") || "", 5348 xml = type === "xml" || !type && ct.indexOf("xml") >= 0, 5349 data = xml ? xhr.responseXML : xhr.responseText; 5350 5351 if ( xml && data.documentElement.nodeName === "parsererror" ) { 5352 jQuery.error( "parsererror" ); 5353 } 5354 5355 // Allow a pre-filtering function to sanitize the response 5356 // s is checked to keep backwards compatibility 5357 if ( s && s.dataFilter ) { 5358 data = s.dataFilter( data, type ); 5359 } 5360 5361 // The filter can actually parse the response 5362 if ( typeof data === "string" ) { 5363 // Get the JavaScript object, if JSON is used. 5364 if ( type === "json" || !type && ct.indexOf("json") >= 0 ) { 5365 data = jQuery.parseJSON( data ); 5366 5367 // If the type is "script", eval it in global context 5368 } else if ( type === "script" || !type && ct.indexOf("javascript") >= 0 ) { 5369 jQuery.globalEval( data ); 5370 } 5371 } 5372 5373 return data; 5374 }, 5375 5376 // Serialize an array of form elements or a set of 5377 // key/values into a query string 5378 param: function( a, traditional ) { 5379 var s = []; 5380 5381 // Set traditional to true for jQuery <= 1.3.2 behavior. 5382 if ( traditional === undefined ) { 5383 traditional = jQuery.ajaxSettings.traditional; 5384 } 5385 5386 // If an array was passed in, assume that it is an array of form elements. 5387 if ( jQuery.isArray(a) || a.jquery ) { 5388 // Serialize the form elements 5389 jQuery.each( a, function() { 5390 add( this.name, this.value ); 5391 }); 5392 5393 } else { 5394 // If traditional, encode the "old" way (the way 1.3.2 or older 5395 // did it), otherwise encode params recursively. 5396 for ( var prefix in a ) { 5397 buildParams( prefix, a[prefix] ); 5398 } 5399 } 5400 5401 // Return the resulting serialization 5402 return s.join("&").replace(r20, "+"); 5403 5404 function buildParams( prefix, obj ) { 5405 if ( jQuery.isArray(obj) ) { 5406 // Serialize array item. 5407 jQuery.each( obj, function( i, v ) { 5408 if ( traditional || /\[\]$/.test( prefix ) ) { 5409 // Treat each array item as a scalar. 5410 add( prefix, v ); 5411 } else { 5412 // If array item is non-scalar (array or object), encode its 5413 // numeric index to resolve deserialization ambiguity issues. 5414 // Note that rack (as of 1.0.0) can't currently deserialize 5415 // nested arrays properly, and attempting to do so may cause 5416 // a server error. Possible fixes are to modify rack's 5417 // deserialization algorithm or to provide an option or flag 5418 // to force array serialization to be shallow. 5419 buildParams( prefix + "[" + ( typeof v === "object" || jQuery.isArray(v) ? i : "" ) + "]", v ); 5420 } 5421 }); 5422 5423 } else if ( !traditional && obj != null && typeof obj === "object" ) { 5424 // Serialize object item. 5425 jQuery.each( obj, function( k, v ) { 5426 buildParams( prefix + "[" + k + "]", v ); 5427 }); 5428 5429 } else { 5430 // Serialize scalar item. 5431 add( prefix, obj ); 5432 } 5433 } 5434 5435 function add( key, value ) { 5436 // If value is a function, invoke it and return its value 5437 value = jQuery.isFunction(value) ? value() : value; 5438 s[ s.length ] = encodeURIComponent(key) + "=" + encodeURIComponent(value); 5439 } 5440 } 5441 }); 5442 var elemdisplay = {}, 5443 rfxtypes = /toggle|show|hide/, 5444 rfxnum = /^([+-]=)?([\d+-.]+)(.*)$/, 5445 timerId, 5446 fxAttrs = [ 5447 // height animations 5448 [ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ], 5449 // width animations 5450 [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ], 5451 // opacity animations 5452 [ "opacity" ] 5453 ]; 5454 5455 jQuery.fn.extend({ 5456 show: function( speed, callback ) { 5457 if ( speed || speed === 0) { 5458 return this.animate( genFx("show", 3), speed, callback); 5459 5460 } else { 5461 for ( var i = 0, l = this.length; i < l; i++ ) { 5462 var old = jQuery.data(this[i], "olddisplay"); 5463 5464 this[i].style.display = old || ""; 5465 5466 if ( jQuery.css(this[i], "display") === "none" ) { 5467 var nodeName = this[i].nodeName, display; 5468 5469 if ( elemdisplay[ nodeName ] ) { 5470 display = elemdisplay[ nodeName ]; 5471 5472 } else { 5473 var elem = jQuery("<" + nodeName + " />").appendTo("body"); 5474 5475 display = elem.css("display"); 5476 5477 if ( display === "none" ) { 5478 display = "block"; 5479 } 5480 5481 elem.remove(); 5482 5483 elemdisplay[ nodeName ] = display; 5484 } 5485 5486 jQuery.data(this[i], "olddisplay", display); 5487 } 5488 } 5489 5490 // Set the display of the elements in a second loop 5491 // to avoid the constant reflow 5492 for ( var j = 0, k = this.length; j < k; j++ ) { 5493 this[j].style.display = jQuery.data(this[j], "olddisplay") || ""; 5494 } 5495 5496 return this; 5497 } 5498 }, 5499 5500 hide: function( speed, callback ) { 5501 if ( speed || speed === 0 ) { 5502 return this.animate( genFx("hide", 3), speed, callback); 5503 5504 } else { 5505 for ( var i = 0, l = this.length; i < l; i++ ) { 5506 var old = jQuery.data(this[i], "olddisplay"); 5507 if ( !old && old !== "none" ) { 5508 jQuery.data(this[i], "olddisplay", jQuery.css(this[i], "display")); 5509 } 5510 } 5511 5512 // Set the display of the elements in a second loop 5513 // to avoid the constant reflow 5514 for ( var j = 0, k = this.length; j < k; j++ ) { 5515 this[j].style.display = "none"; 5516 } 5517 5518 return this; 5519 } 5520 }, 5521 5522 // Save the old toggle function 5523 _toggle: jQuery.fn.toggle, 5524 5525 toggle: function( fn, fn2 ) { 5526 var bool = typeof fn === "boolean"; 5527 5528 if ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) { 5529 this._toggle.apply( this, arguments ); 5530 5531 } else if ( fn == null || bool ) { 5532 this.each(function() { 5533 var state = bool ? fn : jQuery(this).is(":hidden"); 5534 jQuery(this)[ state ? "show" : "hide" ](); 5535 }); 5536 5537 } else { 5538 this.animate(genFx("toggle", 3), fn, fn2); 5539 } 5540 5541 return this; 5542 }, 5543 5544 fadeTo: function( speed, to, callback ) { 5545 return this.filter(":hidden").css("opacity", 0).show().end() 5546 .animate({opacity: to}, speed, callback); 5547 }, 5548 5549 animate: function( prop, speed, easing, callback ) { 5550 var optall = jQuery.speed(speed, easing, callback); 5551 5552 if ( jQuery.isEmptyObject( prop ) ) { 5553 return this.each( optall.complete ); 5554 } 5555 5556 return this[ optall.queue === false ? "each" : "queue" ](function() { 5557 var opt = jQuery.extend({}, optall), p, 5558 hidden = this.nodeType === 1 && jQuery(this).is(":hidden"), 5559 self = this; 5560 5561 for ( p in prop ) { 5562 var name = p.replace(rdashAlpha, fcamelCase); 5563 5564 if ( p !== name ) { 5565 prop[ name ] = prop[ p ]; 5566 delete prop[ p ]; 5567 p = name; 5568 } 5569 5570 if ( prop[p] === "hide" && hidden || prop[p] === "show" && !hidden ) { 5571 return opt.complete.call(this); 5572 } 5573 5574 if ( ( p === "height" || p === "width" ) && this.style ) { 5575 // Store display property 5576 opt.display = jQuery.css(this, "display"); 5577 5578 // Make sure that nothing sneaks out 5579 opt.overflow = this.style.overflow; 5580 } 5581 5582 if ( jQuery.isArray( prop[p] ) ) { 5583 // Create (if needed) and add to specialEasing 5584 (opt.specialEasing = opt.specialEasing || {})[p] = prop[p][1]; 5585 prop[p] = prop[p][0]; 5586 } 5587 } 5588 5589 if ( opt.overflow != null ) { 5590 this.style.overflow = "hidden"; 5591 } 5592 5593 opt.curAnim = jQuery.extend({}, prop); 5594 5595 jQuery.each( prop, function( name, val ) { 5596 var e = new jQuery.fx( self, opt, name ); 5597 5598 if ( rfxtypes.test(val) ) { 5599 e[ val === "toggle" ? hidden ? "show" : "hide" : val ]( prop ); 5600 5601 } else { 5602 var parts = rfxnum.exec(val), 5603 start = e.cur(true) || 0; 5604 5605 if ( parts ) { 5606 var end = parseFloat( parts[2] ), 5607 unit = parts[3] || "px"; 5608 5609 // We need to compute starting value 5610 if ( unit !== "px" ) { 5611 self.style[ name ] = (end || 1) + unit; 5612 start = ((end || 1) / e.cur(true)) * start; 5613 self.style[ name ] = start + unit; 5614 } 5615 5616 // If a +=/-= token was provided, we're doing a relative animation 5617 if ( parts[1] ) { 5618 end = ((parts[1] === "-=" ? -1 : 1) * end) + start; 5619 } 5620 5621 e.custom( start, end, unit ); 5622 5623 } else { 5624 e.custom( start, val, "" ); 5625 } 5626 } 5627 }); 5628 5629 // For JS strict compliance 5630 return true; 5631 }); 5632 }, 5633 5634 stop: function( clearQueue, gotoEnd ) { 5635 var timers = jQuery.timers; 5636 5637 if ( clearQueue ) { 5638 this.queue([]); 5639 } 5640 5641 this.each(function() { 5642 // go in reverse order so anything added to the queue during the loop is ignored 5643 for ( var i = timers.length - 1; i >= 0; i-- ) { 5644 if ( timers[i].elem === this ) { 5645 if (gotoEnd) { 5646 // force the next step to be the last 5647 timers[i](true); 5648 } 5649 5650 timers.splice(i, 1); 5651 } 5652 } 5653 }); 5654 5655 // start the next in the queue if the last step wasn't forced 5656 if ( !gotoEnd ) { 5657 this.dequeue(); 5658 } 5659 5660 return this; 5661 } 5662 5663 }); 5664 5665 // Generate shortcuts for custom animations 5666 jQuery.each({ 5667 slideDown: genFx("show", 1), 5668 slideUp: genFx("hide", 1), 5669 slideToggle: genFx("toggle", 1), 5670 fadeIn: { opacity: "show" }, 5671 fadeOut: { opacity: "hide" } 5672 }, function( name, props ) { 5673 jQuery.fn[ name ] = function( speed, callback ) { 5674 return this.animate( props, speed, callback ); 5675 }; 5676 }); 5677 5678 jQuery.extend({ 5679 speed: function( speed, easing, fn ) { 5680 var opt = speed && typeof speed === "object" ? speed : { 5681 complete: fn || !fn && easing || 5682 jQuery.isFunction( speed ) && speed, 5683 duration: speed, 5684 easing: fn && easing || easing && !jQuery.isFunction(easing) && easing 5685 }; 5686 5687 opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration : 5688 jQuery.fx.speeds[opt.duration] || jQuery.fx.speeds._default; 5689 5690 // Queueing 5691 opt.old = opt.complete; 5692 opt.complete = function() { 5693 if ( opt.queue !== false ) { 5694 jQuery(this).dequeue(); 5695 } 5696 if ( jQuery.isFunction( opt.old ) ) { 5697 opt.old.call( this ); 5698 } 5699 }; 5700 5701 return opt; 5702 }, 5703 5704 easing: { 5705 linear: function( p, n, firstNum, diff ) { 5706 return firstNum + diff * p; 5707 }, 5708 swing: function( p, n, firstNum, diff ) { 5709 return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum; 5710 } 5711 }, 5712 5713 timers: [], 5714 5715 fx: function( elem, options, prop ) { 5716 this.options = options; 5717 this.elem = elem; 5718 this.prop = prop; 5719 5720 if ( !options.orig ) { 5721 options.orig = {}; 5722 } 5723 } 5724 5725 }); 5726 5727 jQuery.fx.prototype = { 5728 // Simple function for setting a style value 5729 update: function() { 5730 if ( this.options.step ) { 5731 this.options.step.call( this.elem, this.now, this ); 5732 } 5733 5734 (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this ); 5735 5736 // Set display property to block for height/width animations 5737 if ( ( this.prop === "height" || this.prop === "width" ) && this.elem.style ) { 5738 this.elem.style.display = "block"; 5739 } 5740 }, 5741 5742 // Get the current size 5743 cur: function( force ) { 5744 if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) ) { 5745 return this.elem[ this.prop ]; 5746 } 5747 5748 var r = parseFloat(jQuery.css(this.elem, this.prop, force)); 5749 return r && r > -10000 ? r : parseFloat(jQuery.curCSS(this.elem, this.prop)) || 0; 5750 }, 5751 5752 // Start an animation from one number to another 5753 custom: function( from, to, unit ) { 5754 this.startTime = now(); 5755 this.start = from; 5756 this.end = to; 5757 this.unit = unit || this.unit || "px"; 5758 this.now = this.start; 5759 this.pos = this.state = 0; 5760 5761 var self = this; 5762 function t( gotoEnd ) { 5763 return self.step(gotoEnd); 5764 } 5765 5766 t.elem = this.elem; 5767 5768 if ( t() && jQuery.timers.push(t) && !timerId ) { 5769 timerId = setInterval(jQuery.fx.tick, 13); 5770 } 5771 }, 5772 5773 // Simple 'show' function 5774 show: function() { 5775 // Remember where we started, so that we can go back to it later 5776 this.options.orig[this.prop] = jQuery.style( this.elem, this.prop ); 5777 this.options.show = true; 5778 5779 // Begin the animation 5780 // Make sure that we start at a small width/height to avoid any 5781 // flash of content 5782 this.custom(this.prop === "width" || this.prop === "height" ? 1 : 0, this.cur()); 5783 5784 // Start by showing the element 5785 jQuery( this.elem ).show(); 5786 }, 5787 5788 // Simple 'hide' function 5789 hide: function() { 5790 // Remember where we started, so that we can go back to it later 5791 this.options.orig[this.prop] = jQuery.style( this.elem, this.prop ); 5792 this.options.hide = true; 5793 5794 // Begin the animation 5795 this.custom(this.cur(), 0); 5796 }, 5797 5798 // Each step of an animation 5799 step: function( gotoEnd ) { 5800 var t = now(), done = true; 5801 5802 if ( gotoEnd || t >= this.options.duration + this.startTime ) { 5803 this.now = this.end; 5804 this.pos = this.state = 1; 5805 this.update(); 5806 5807 this.options.curAnim[ this.prop ] = true; 5808 5809 for ( var i in this.options.curAnim ) { 5810 if ( this.options.curAnim[i] !== true ) { 5811 done = false; 5812 } 5813 } 5814 5815 if ( done ) { 5816 if ( this.options.display != null ) { 5817 // Reset the overflow 5818 this.elem.style.overflow = this.options.overflow; 5819 5820 // Reset the display 5821 var old = jQuery.data(this.elem, "olddisplay"); 5822 this.elem.style.display = old ? old : this.options.display; 5823 5824 if ( jQuery.css(this.elem, "display") === "none" ) { 5825 this.elem.style.display = "block"; 5826 } 5827 } 5828 5829 // Hide the element if the "hide" operation was done 5830 if ( this.options.hide ) { 5831 jQuery(this.elem).hide(); 5832 } 5833 5834 // Reset the properties, if the item has been hidden or shown 5835 if ( this.options.hide || this.options.show ) { 5836 for ( var p in this.options.curAnim ) { 5837 jQuery.style(this.elem, p, this.options.orig[p]); 5838 } 5839 } 5840 5841 // Execute the complete function 5842 this.options.complete.call( this.elem ); 5843 } 5844 5845 return false; 5846 5847 } else { 5848 var n = t - this.startTime; 5849 this.state = n / this.options.duration; 5850 5851 // Perform the easing function, defaults to swing 5852 var specialEasing = this.options.specialEasing && this.options.specialEasing[this.prop]; 5853 var defaultEasing = this.options.easing || (jQuery.easing.swing ? "swing" : "linear"); 5854 this.pos = jQuery.easing[specialEasing || defaultEasing](this.state, n, 0, 1, this.options.duration); 5855 this.now = this.start + ((this.end - this.start) * this.pos); 5856 5857 // Perform the next step of the animation 5858 this.update(); 5859 } 5860 5861 return true; 5862 } 5863 }; 5864 5865 jQuery.extend( jQuery.fx, { 5866 tick: function() { 5867 var timers = jQuery.timers; 5868 5869 for ( var i = 0; i < timers.length; i++ ) { 5870 if ( !timers[i]() ) { 5871 timers.splice(i--, 1); 5872 } 5873 } 5874 5875 if ( !timers.length ) { 5876 jQuery.fx.stop(); 5877 } 5878 }, 5879 5880 stop: function() { 5881 clearInterval( timerId ); 5882 timerId = null; 5883 }, 5884 5885 speeds: { 5886 slow: 600, 5887 fast: 200, 5888 // Default speed 5889 _default: 400 5890 }, 5891 5892 step: { 5893 opacity: function( fx ) { 5894 jQuery.style(fx.elem, "opacity", fx.now); 5895 }, 5896 5897 _default: function( fx ) { 5898 if ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) { 5899 fx.elem.style[ fx.prop ] = (fx.prop === "width" || fx.prop === "height" ? Math.max(0, fx.now) : fx.now) + fx.unit; 5900 } else { 5901 fx.elem[ fx.prop ] = fx.now; 5902 } 5903 } 5904 } 5905 }); 5906 5907 if ( jQuery.expr && jQuery.expr.filters ) { 5908 jQuery.expr.filters.animated = function( elem ) { 5909 return jQuery.grep(jQuery.timers, function( fn ) { 5910 return elem === fn.elem; 5911 }).length; 5912 }; 5913 } 5914 5915 function genFx( type, num ) { 5916 var obj = {}; 5917 5918 jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function() { 5919 obj[ this ] = type; 5920 }); 5921 5922 return obj; 5923 } 5924 if ( "getBoundingClientRect" in document.documentElement ) { 5925 jQuery.fn.offset = function( options ) { 5926 var elem = this[0]; 5927 5928 if ( options ) { 5929 return this.each(function( i ) { 5930 jQuery.offset.setOffset( this, options, i ); 5931 }); 5932 } 5933 5934 if ( !elem || !elem.ownerDocument ) { 5935 return null; 5936 } 5937 5938 if ( elem === elem.ownerDocument.body ) { 5939 return jQuery.offset.bodyOffset( elem ); 5940 } 5941 5942 var box = elem.getBoundingClientRect(), doc = elem.ownerDocument, body = doc.body, docElem = doc.documentElement, 5943 clientTop = docElem.clientTop || body.clientTop || 0, clientLeft = docElem.clientLeft || body.clientLeft || 0, 5944 top = box.top + (self.pageYOffset || jQuery.support.boxModel && docElem.scrollTop || body.scrollTop ) - clientTop, 5945 left = box.left + (self.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft) - clientLeft; 5946 5947 return { top: top, left: left }; 5948 }; 5949 5950 } else { 5951 jQuery.fn.offset = function( options ) { 5952 var elem = this[0]; 5953 5954 if ( options ) { 5955 return this.each(function( i ) { 5956 jQuery.offset.setOffset( this, options, i ); 5957 }); 5958 } 5959 5960 if ( !elem || !elem.ownerDocument ) { 5961 return null; 5962 } 5963 5964 if ( elem === elem.ownerDocument.body ) { 5965 return jQuery.offset.bodyOffset( elem ); 5966 } 5967 5968 jQuery.offset.initialize(); 5969 5970 var offsetParent = elem.offsetParent, prevOffsetParent = elem, 5971 doc = elem.ownerDocument, computedStyle, docElem = doc.documentElement, 5972 body = doc.body, defaultView = doc.defaultView, 5973 prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle, 5974 top = elem.offsetTop, left = elem.offsetLeft; 5975 5976 while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) { 5977 if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) { 5978 break; 5979 } 5980 5981 computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle; 5982 top -= elem.scrollTop; 5983 left -= elem.scrollLeft; 5984 5985 if ( elem === offsetParent ) { 5986 top += elem.offsetTop; 5987 left += elem.offsetLeft; 5988 5989 if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && /^t(able|d|h)$/i.test(elem.nodeName)) ) { 5990 top += parseFloat( computedStyle.borderTopWidth ) || 0; 5991 left += parseFloat( computedStyle.borderLeftWidth ) || 0; 5992 } 5993 5994 prevOffsetParent = offsetParent, offsetParent = elem.offsetParent; 5995 } 5996 5997 if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) { 5998 top += parseFloat( computedStyle.borderTopWidth ) || 0; 5999 left += parseFloat( computedStyle.borderLeftWidth ) || 0; 6000 } 6001 6002 prevComputedStyle = computedStyle; 6003 } 6004 6005 if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) { 6006 top += body.offsetTop; 6007 left += body.offsetLeft; 6008 } 6009 6010 if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) { 6011 top += Math.max( docElem.scrollTop, body.scrollTop ); 6012 left += Math.max( docElem.scrollLeft, body.scrollLeft ); 6013 } 6014 6015 return { top: top, left: left }; 6016 }; 6017 } 6018 6019 jQuery.offset = { 6020 initialize: function() { 6021 var body = document.body, container = document.createElement("div"), innerDiv, checkDiv, table, td, bodyMarginTop = parseFloat( jQuery.curCSS(body, "marginTop", true) ) || 0, 6022 html = "<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>"; 6023 6024 jQuery.extend( container.style, { position: "absolute", top: 0, left: 0, margin: 0, border: 0, width: "1px", height: "1px", visibility: "hidden" } ); 6025 6026 container.innerHTML = html; 6027 body.insertBefore( container, body.firstChild ); 6028 innerDiv = container.firstChild; 6029 checkDiv = innerDiv.firstChild; 6030 td = innerDiv.nextSibling.firstChild.firstChild; 6031 6032 this.doesNotAddBorder = (checkDiv.offsetTop !== 5); 6033 this.doesAddBorderForTableAndCells = (td.offsetTop === 5); 6034 6035 checkDiv.style.position = "fixed", checkDiv.style.top = "20px"; 6036 // safari subtracts parent border width here which is 5px 6037 this.supportsFixedPosition = (checkDiv.offsetTop === 20 || checkDiv.offsetTop === 15); 6038 checkDiv.style.position = checkDiv.style.top = ""; 6039 6040 innerDiv.style.overflow = "hidden", innerDiv.style.position = "relative"; 6041 this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5); 6042 6043 this.doesNotIncludeMarginInBodyOffset = (body.offsetTop !== bodyMarginTop); 6044 6045 body.removeChild( container ); 6046 body = container = innerDiv = checkDiv = table = td = null; 6047 jQuery.offset.initialize = jQuery.noop; 6048 }, 6049 6050 bodyOffset: function( body ) { 6051 var top = body.offsetTop, left = body.offsetLeft; 6052 6053 jQuery.offset.initialize(); 6054 6055 if ( jQuery.offset.doesNotIncludeMarginInBodyOffset ) { 6056 top += parseFloat( jQuery.curCSS(body, "marginTop", true) ) || 0; 6057 left += parseFloat( jQuery.curCSS(body, "marginLeft", true) ) || 0; 6058 } 6059 6060 return { top: top, left: left }; 6061 }, 6062 6063 setOffset: function( elem, options, i ) { 6064 // set position first, in-case top/left are set even on static elem 6065 if ( /static/.test( jQuery.curCSS( elem, "position" ) ) ) { 6066 elem.style.position = "relative"; 6067 } 6068 var curElem = jQuery( elem ), 6069 curOffset = curElem.offset(), 6070 curTop = parseInt( jQuery.curCSS( elem, "top", true ), 10 ) || 0, 6071 curLeft = parseInt( jQuery.curCSS( elem, "left", true ), 10 ) || 0; 6072 6073 if ( jQuery.isFunction( options ) ) { 6074 options = options.call( elem, i, curOffset ); 6075 } 6076 6077 var props = { 6078 top: (options.top - curOffset.top) + curTop, 6079 left: (options.left - curOffset.left) + curLeft 6080 }; 6081 6082 if ( "using" in options ) { 6083 options.using.call( elem, props ); 6084 } else { 6085 curElem.css( props ); 6086 } 6087 } 6088 }; 6089 6090 6091 jQuery.fn.extend({ 6092 position: function() { 6093 if ( !this[0] ) { 6094 return null; 6095 } 6096 6097 var elem = this[0], 6098 6099 // Get *real* offsetParent 6100 offsetParent = this.offsetParent(), 6101 6102 // Get correct offsets 6103 offset = this.offset(), 6104 parentOffset = /^body|html$/i.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset(); 6105 6106 // Subtract element margins 6107 // note: when an element has margin: auto the offsetLeft and marginLeft 6108 // are the same in Safari causing offset.left to incorrectly be 0 6109 offset.top -= parseFloat( jQuery.curCSS(elem, "marginTop", true) ) || 0; 6110 offset.left -= parseFloat( jQuery.curCSS(elem, "marginLeft", true) ) || 0; 6111 6112 // Add offsetParent borders 6113 parentOffset.top += parseFloat( jQuery.curCSS(offsetParent[0], "borderTopWidth", true) ) || 0; 6114 parentOffset.left += parseFloat( jQuery.curCSS(offsetParent[0], "borderLeftWidth", true) ) || 0; 6115 6116 // Subtract the two offsets 6117 return { 6118 top: offset.top - parentOffset.top, 6119 left: offset.left - parentOffset.left 6120 }; 6121 }, 6122 6123 offsetParent: function() { 6124 return this.map(function() { 6125 var offsetParent = this.offsetParent || document.body; 6126 while ( offsetParent && (!/^body|html$/i.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) { 6127 offsetParent = offsetParent.offsetParent; 6128 } 6129 return offsetParent; 6130 }); 6131 } 6132 }); 6133 6134 6135 // Create scrollLeft and scrollTop methods 6136 jQuery.each( ["Left", "Top"], function( i, name ) { 6137 var method = "scroll" + name; 6138 6139 jQuery.fn[ method ] = function(val) { 6140 var elem = this[0], win; 6141 6142 if ( !elem ) { 6143 return null; 6144 } 6145 6146 if ( val !== undefined ) { 6147 // Set the scroll offset 6148 return this.each(function() { 6149 win = getWindow( this ); 6150 6151 if ( win ) { 6152 win.scrollTo( 6153 !i ? val : jQuery(win).scrollLeft(), 6154 i ? val : jQuery(win).scrollTop() 6155 ); 6156 6157 } else { 6158 this[ method ] = val; 6159 } 6160 }); 6161 } else { 6162 win = getWindow( elem ); 6163 6164 // Return the scroll offset 6165 return win ? ("pageXOffset" in win) ? win[ i ? "pageYOffset" : "pageXOffset" ] : 6166 jQuery.support.boxModel && win.document.documentElement[ method ] || 6167 win.document.body[ method ] : 6168 elem[ method ]; 6169 } 6170 }; 6171 }); 6172 6173 function getWindow( elem ) { 6174 return ("scrollTo" in elem && elem.document) ? 6175 elem : 6176 elem.nodeType === 9 ? 6177 elem.defaultView || elem.parentWindow : 6178 false; 6179 } 6180 // Create innerHeight, innerWidth, outerHeight and outerWidth methods 6181 jQuery.each([ "Height", "Width" ], function( i, name ) { 6182 6183 var type = name.toLowerCase(); 6184 6185 // innerHeight and innerWidth 6186 jQuery.fn["inner" + name] = function() { 6187 return this[0] ? 6188 jQuery.css( this[0], type, false, "padding" ) : 6189 null; 6190 }; 6191 6192 // outerHeight and outerWidth 6193 jQuery.fn["outer" + name] = function( margin ) { 6194 return this[0] ? 6195 jQuery.css( this[0], type, false, margin ? "margin" : "border" ) : 6196 null; 6197 }; 6198 6199 jQuery.fn[ type ] = function( size ) { 6200 // Get window width or height 6201 var elem = this[0]; 6202 if ( !elem ) { 6203 return size == null ? null : this; 6204 } 6205 6206 if ( jQuery.isFunction( size ) ) { 6207 return this.each(function( i ) { 6208 var self = jQuery( this ); 6209 self[ type ]( size.call( this, i, self[ type ]() ) ); 6210 }); 6211 } 6212 6213 return ("scrollTo" in elem && elem.document) ? // does it walk and quack like a window? 6214 // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode 6215 elem.document.compatMode === "CSS1Compat" && elem.document.documentElement[ "client" + name ] || 6216 elem.document.body[ "client" + name ] : 6217 6218 // Get document width or height 6219 (elem.nodeType === 9) ? // is it a document 6220 // Either scroll[Width/Height] or offset[Width/Height], whichever is greater 6221 Math.max( 6222 elem.documentElement["client" + name], 6223 elem.body["scroll" + name], elem.documentElement["scroll" + name], 6224 elem.body["offset" + name], elem.documentElement["offset" + name] 6225 ) : 6226 6227 // Get or set width or height on the element 6228 size === undefined ? 6229 // Get width or height on the element 6230 jQuery.css( elem, type ) : 6231 6232 // Set the width or height on the element (default to pixels if value is unitless) 6233 this.css( type, typeof size === "string" ? size : size + "px" ); 6234 }; 6235 6236 }); 6237 // Expose jQuery to the global object 6238 window.jQuery = window.$ = jQuery; 6239 6240 })(window); -

WordPress源代码——jquery(jquery-1.3.2.js)
1 /*! 2 * jQuery JavaScript Library v1.3.2 3 * http://jquery.com/ 4 * 5 * Copyright (c) 2009 John Resig 6 * Dual licensed under the MIT and GPL licenses. 7 * http://docs.jquery.com/License 8 * 9 * Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009) 10 * Revision: 6246 11 */ 12 (function(){ 13 14 var 15 // Will speed up references to window, and allows munging its name. 16 window = this, 17 // Will speed up references to undefined, and allows munging its name. 18 undefined, 19 // Map over jQuery in case of overwrite 20 _jQuery = window.jQuery, 21 // Map over the $ in case of overwrite 22 _$ = window.$, 23 24 jQuery = window.jQuery = window.$ = function( selector, context ) { 25 // The jQuery object is actually just the init constructor 'enhanced' 26 return new jQuery.fn.init( selector, context ); 27 }, 28 29 // A simple way to check for HTML strings or ID strings 30 // (both of which we optimize for) 31 quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/, 32 // Is it a simple selector 33 isSimple = /^.[^:#\[\.,]*$/; 34 35 jQuery.fn = jQuery.prototype = { 36 init: function( selector, context ) { 37 // Make sure that a selection was provided 38 selector = selector || document; 39 40 // Handle $(DOMElement) 41 if ( selector.nodeType ) { 42 this[0] = selector; 43 this.length = 1; 44 this.context = selector; 45 return this; 46 } 47 // Handle HTML strings 48 if ( typeof selector === "string" ) { 49 // Are we dealing with HTML string or an ID? 50 var match = quickExpr.exec( selector ); 51 52 // Verify a match, and that no context was specified for #id 53 if ( match && (match[1] || !context) ) { 54 55 // HANDLE: $(html) -> $(array) 56 if ( match[1] ) 57 selector = jQuery.clean( [ match[1] ], context ); 58 59 // HANDLE: $("#id") 60 else { 61 var elem = document.getElementById( match[3] ); 62 63 // Handle the case where IE and Opera return items 64 // by name instead of ID 65 if ( elem && elem.id != match[3] ) 66 return jQuery().find( selector ); 67 68 // Otherwise, we inject the element directly into the jQuery object 69 var ret = jQuery( elem || [] ); 70 ret.context = document; 71 ret.selector = selector; 72 return ret; 73 } 74 75 // HANDLE: $(expr, [context]) 76 // (which is just equivalent to: $(content).find(expr) 77 } else 78 return jQuery( context ).find( selector ); 79 80 // HANDLE: $(function) 81 // Shortcut for document ready 82 } else if ( jQuery.isFunction( selector ) ) 83 return jQuery( document ).ready( selector ); 84 85 // Make sure that old selector state is passed along 86 if ( selector.selector && selector.context ) { 87 this.selector = selector.selector; 88 this.context = selector.context; 89 } 90 91 return this.setArray(jQuery.isArray( selector ) ? 92 selector : 93 jQuery.makeArray(selector)); 94 }, 95 96 // Start with an empty selector 97 selector: "", 98 99 // The current version of jQuery being used 100 jquery: "1.3.2", 101 102 // The number of elements contained in the matched element set 103 size: function() { 104 return this.length; 105 }, 106 107 // Get the Nth element in the matched element set OR 108 // Get the whole matched element set as a clean array 109 get: function( num ) { 110 return num === undefined ? 111 112 // Return a 'clean' array 113 Array.prototype.slice.call( this ) : 114 115 // Return just the object 116 this[ num ]; 117 }, 118 119 // Take an array of elements and push it onto the stack 120 // (returning the new matched element set) 121 pushStack: function( elems, name, selector ) { 122 // Build a new jQuery matched element set 123 var ret = jQuery( elems ); 124 125 // Add the old object onto the stack (as a reference) 126 ret.prevObject = this; 127 128 ret.context = this.context; 129 130 if ( name === "find" ) 131 ret.selector = this.selector + (this.selector ? " " : "") + selector; 132 else if ( name ) 133 ret.selector = this.selector + "." + name + "(" + selector + ")"; 134 135 // Return the newly-formed element set 136 return ret; 137 }, 138 139 // Force the current matched set of elements to become 140 // the specified array of elements (destroying the stack in the process) 141 // You should use pushStack() in order to do this, but maintain the stack 142 setArray: function( elems ) { 143 // Resetting the length to 0, then using the native Array push 144 // is a super-fast way to populate an object with array-like properties 145 this.length = 0; 146 Array.prototype.push.apply( this, elems ); 147 148 return this; 149 }, 150 151 // Execute a callback for every element in the matched set. 152 // (You can seed the arguments with an array of args, but this is 153 // only used internally.) 154 each: function( callback, args ) { 155 return jQuery.each( this, callback, args ); 156 }, 157 158 // Determine the position of an element within 159 // the matched set of elements 160 index: function( elem ) { 161 // Locate the position of the desired element 162 return jQuery.inArray( 163 // If it receives a jQuery object, the first element is used 164 elem && elem.jquery ? elem[0] : elem 165 , this ); 166 }, 167 168 attr: function( name, value, type ) { 169 var options = name; 170 171 // Look for the case where we're accessing a style value 172 if ( typeof name === "string" ) 173 if ( value === undefined ) 174 return this[0] && jQuery[ type || "attr" ]( this[0], name ); 175 176 else { 177 options = {}; 178 options[ name ] = value; 179 } 180 181 // Check to see if we're setting style values 182 return this.each(function(i){ 183 // Set all the styles 184 for ( name in options ) 185 jQuery.attr( 186 type ? 187 this.style : 188 this, 189 name, jQuery.prop( this, options[ name ], type, i, name ) 190 ); 191 }); 192 }, 193 194 css: function( key, value ) { 195 // ignore negative width and height values 196 if ( (key == 'width' || key == 'height') && parseFloat(value) < 0 ) 197 value = undefined; 198 return this.attr( key, value, "curCSS" ); 199 }, 200 201 text: function( text ) { 202 if ( typeof text !== "object" && text != null ) 203 return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) ); 204 205 var ret = ""; 206 207 jQuery.each( text || this, function(){ 208 jQuery.each( this.childNodes, function(){ 209 if ( this.nodeType != 8 ) 210 ret += this.nodeType != 1 ? 211 this.nodeValue : 212 jQuery.fn.text( [ this ] ); 213 }); 214 }); 215 216 return ret; 217 }, 218 219 wrapAll: function( html ) { 220 if ( this[0] ) { 221 // The elements to wrap the target around 222 var wrap = jQuery( html, this[0].ownerDocument ).clone(); 223 224 if ( this[0].parentNode ) 225 wrap.insertBefore( this[0] ); 226 227 wrap.map(function(){ 228 var elem = this; 229 230 while ( elem.firstChild ) 231 elem = elem.firstChild; 232 233 return elem; 234 }).append(this); 235 } 236 237 return this; 238 }, 239 240 wrapInner: function( html ) { 241 return this.each(function(){ 242 jQuery( this ).contents().wrapAll( html ); 243 }); 244 }, 245 246 wrap: function( html ) { 247 return this.each(function(){ 248 jQuery( this ).wrapAll( html ); 249 }); 250 }, 251 252 append: function() { 253 return this.domManip(arguments, true, function(elem){ 254 if (this.nodeType == 1) 255 this.appendChild( elem ); 256 }); 257 }, 258 259 prepend: function() { 260 return this.domManip(arguments, true, function(elem){ 261 if (this.nodeType == 1) 262 this.insertBefore( elem, this.firstChild ); 263 }); 264 }, 265 266 before: function() { 267 return this.domManip(arguments, false, function(elem){ 268 this.parentNode.insertBefore( elem, this ); 269 }); 270 }, 271 272 after: function() { 273 return this.domManip(arguments, false, function(elem){ 274 this.parentNode.insertBefore( elem, this.nextSibling ); 275 }); 276 }, 277 278 end: function() { 279 return this.prevObject || jQuery( [] ); 280 }, 281 282 // For internal use only. 283 // Behaves like an Array's method, not like a jQuery method. 284 push: [].push, 285 sort: [].sort, 286 splice: [].splice, 287 288 find: function( selector ) { 289 if ( this.length === 1 ) { 290 var ret = this.pushStack( [], "find", selector ); 291 ret.length = 0; 292 jQuery.find( selector, this[0], ret ); 293 return ret; 294 } else { 295 return this.pushStack( jQuery.unique(jQuery.map(this, function(elem){ 296 return jQuery.find( selector, elem ); 297 })), "find", selector ); 298 } 299 }, 300 301 clone: function( events ) { 302 // Do the clone 303 var ret = this.map(function(){ 304 if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) { 305 // IE copies events bound via attachEvent when 306 // using cloneNode. Calling detachEvent on the 307 // clone will also remove the events from the orignal 308 // In order to get around this, we use innerHTML. 309 // Unfortunately, this means some modifications to 310 // attributes in IE that are actually only stored 311 // as properties will not be copied (such as the 312 // the name attribute on an input). 313 var html = this.outerHTML; 314 if ( !html ) { 315 var div = this.ownerDocument.createElement("div"); 316 div.appendChild( this.cloneNode(true) ); 317 html = div.innerHTML; 318 } 319 320 return jQuery.clean([html.replace(/ jQuery\d+="(?:\d+|null)"/g, "").replace(/^\s*/, "")])[0]; 321 } else 322 return this.cloneNode(true); 323 }); 324 325 // Copy the events from the original to the clone 326 if ( events === true ) { 327 var orig = this.find("*").andSelf(), i = 0; 328 329 ret.find("*").andSelf().each(function(){ 330 if ( this.nodeName !== orig[i].nodeName ) 331 return; 332 333 var events = jQuery.data( orig[i], "events" ); 334 335 for ( var type in events ) { 336 for ( var handler in events[ type ] ) { 337 jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data ); 338 } 339 } 340 341 i++; 342 }); 343 } 344 345 // Return the cloned set 346 return ret; 347 }, 348 349 filter: function( selector ) { 350 return this.pushStack( 351 jQuery.isFunction( selector ) && 352 jQuery.grep(this, function(elem, i){ 353 return selector.call( elem, i ); 354 }) || 355 356 jQuery.multiFilter( selector, jQuery.grep(this, function(elem){ 357 return elem.nodeType === 1; 358 }) ), "filter", selector ); 359 }, 360 361 closest: function( selector ) { 362 var pos = jQuery.expr.match.POS.test( selector ) ? jQuery(selector) : null, 363 closer = 0; 364 365 return this.map(function(){ 366 var cur = this; 367 while ( cur && cur.ownerDocument ) { 368 if ( pos ? pos.index(cur) > -1 : jQuery(cur).is(selector) ) { 369 jQuery.data(cur, "closest", closer); 370 return cur; 371 } 372 cur = cur.parentNode; 373 closer++; 374 } 375 }); 376 }, 377 378 not: function( selector ) { 379 if ( typeof selector === "string" ) 380 // test special case where just one selector is passed in 381 if ( isSimple.test( selector ) ) 382 return this.pushStack( jQuery.multiFilter( selector, this, true ), "not", selector ); 383 else 384 selector = jQuery.multiFilter( selector, this ); 385 386 var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType; 387 return this.filter(function() { 388 return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector; 389 }); 390 }, 391 392 add: function( selector ) { 393 return this.pushStack( jQuery.unique( jQuery.merge( 394 this.get(), 395 typeof selector === "string" ? 396 jQuery( selector ) : 397 jQuery.makeArray( selector ) 398 ))); 399 }, 400 401 is: function( selector ) { 402 return !!selector && jQuery.multiFilter( selector, this ).length > 0; 403 }, 404 405 hasClass: function( selector ) { 406 return !!selector && this.is( "." + selector ); 407 }, 408 409 val: function( value ) { 410 if ( value === undefined ) { 411 var elem = this[0]; 412 413 if ( elem ) { 414 if( jQuery.nodeName( elem, 'option' ) ) 415 return (elem.attributes.value || {}).specified ? elem.value : elem.text; 416 417 // We need to handle select boxes special 418 if ( jQuery.nodeName( elem, "select" ) ) { 419 var index = elem.selectedIndex, 420 values = [], 421 options = elem.options, 422 one = elem.type == "select-one"; 423 424 // Nothing was selected 425 if ( index < 0 ) 426 return null; 427 428 // Loop through all the selected options 429 for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) { 430 var option = options[ i ]; 431 432 if ( option.selected ) { 433 // Get the specifc value for the option 434 value = jQuery(option).val(); 435 436 // We don't need an array for one selects 437 if ( one ) 438 return value; 439 440 // Multi-Selects return an array 441 values.push( value ); 442 } 443 } 444 445 return values; 446 } 447 448 // Everything else, we just grab the value 449 return (elem.value || "").replace(/\r/g, ""); 450 451 } 452 453 return undefined; 454 } 455 456 if ( typeof value === "number" ) 457 value += ''; 458 459 return this.each(function(){ 460 if ( this.nodeType != 1 ) 461 return; 462 463 if ( jQuery.isArray(value) && /radio|checkbox/.test( this.type ) ) 464 this.checked = (jQuery.inArray(this.value, value) >= 0 || 465 jQuery.inArray(this.name, value) >= 0); 466 467 else if ( jQuery.nodeName( this, "select" ) ) { 468 var values = jQuery.makeArray(value); 469 470 jQuery( "option", this ).each(function(){ 471 this.selected = (jQuery.inArray( this.value, values ) >= 0 || 472 jQuery.inArray( this.text, values ) >= 0); 473 }); 474 475 if ( !values.length ) 476 this.selectedIndex = -1; 477 478 } else 479 this.value = value; 480 }); 481 }, 482 483 html: function( value ) { 484 return value === undefined ? 485 (this[0] ? 486 this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g, "") : 487 null) : 488 this.empty().append( value ); 489 }, 490 491 replaceWith: function( value ) { 492 return this.after( value ).remove(); 493 }, 494 495 eq: function( i ) { 496 return this.slice( i, +i + 1 ); 497 }, 498 499 slice: function() { 500 return this.pushStack( Array.prototype.slice.apply( this, arguments ), 501 "slice", Array.prototype.slice.call(arguments).join(",") ); 502 }, 503 504 map: function( callback ) { 505 return this.pushStack( jQuery.map(this, function(elem, i){ 506 return callback.call( elem, i, elem ); 507 })); 508 }, 509 510 andSelf: function() { 511 return this.add( this.prevObject ); 512 }, 513 514 domManip: function( args, table, callback ) { 515 if ( this[0] ) { 516 var fragment = (this[0].ownerDocument || this[0]).createDocumentFragment(), 517 scripts = jQuery.clean( args, (this[0].ownerDocument || this[0]), fragment ), 518 first = fragment.firstChild; 519 520 if ( first ) 521 for ( var i = 0, l = this.length; i < l; i++ ) 522 callback.call( root(this[i], first), this.length > 1 || i > 0 ? 523 fragment.cloneNode(true) : fragment ); 524 525 if ( scripts ) 526 jQuery.each( scripts, evalScript ); 527 } 528 529 return this; 530 531 function root( elem, cur ) { 532 return table && jQuery.nodeName(elem, "table") && jQuery.nodeName(cur, "tr") ? 533 (elem.getElementsByTagName("tbody")[0] || 534 elem.appendChild(elem.ownerDocument.createElement("tbody"))) : 535 elem; 536 } 537 } 538 }; 539 540 // Give the init function the jQuery prototype for later instantiation 541 jQuery.fn.init.prototype = jQuery.fn; 542 543 function evalScript( i, elem ) { 544 if ( elem.src ) 545 jQuery.ajax({ 546 url: elem.src, 547 async: false, 548 dataType: "script" 549 }); 550 551 else 552 jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" ); 553 554 if ( elem.parentNode ) 555 elem.parentNode.removeChild( elem ); 556 } 557 558 function now(){ 559 return +new Date; 560 } 561 562 jQuery.extend = jQuery.fn.extend = function() { 563 // copy reference to target object 564 var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options; 565 566 // Handle a deep copy situation 567 if ( typeof target === "boolean" ) { 568 deep = target; 569 target = arguments[1] || {}; 570 // skip the boolean and the target 571 i = 2; 572 } 573 574 // Handle case when target is a string or something (possible in deep copy) 575 if ( typeof target !== "object" && !jQuery.isFunction(target) ) 576 target = {}; 577 578 // extend jQuery itself if only one argument is passed 579 if ( length == i ) { 580 target = this; 581 --i; 582 } 583 584 for ( ; i < length; i++ ) 585 // Only deal with non-null/undefined values 586 if ( (options = arguments[ i ]) != null ) 587 // Extend the base object 588 for ( var name in options ) { 589 var src = target[ name ], copy = options[ name ]; 590 591 // Prevent never-ending loop 592 if ( target === copy ) 593 continue; 594 595 // Recurse if we're merging object values 596 if ( deep && copy && typeof copy === "object" && !copy.nodeType ) 597 target[ name ] = jQuery.extend( deep, 598 // Never move original objects, clone them 599 src || ( copy.length != null ? [ ] : { } ) 600 , copy ); 601 602 // Don't bring in undefined values 603 else if ( copy !== undefined ) 604 target[ name ] = copy; 605 606 } 607 608 // Return the modified object 609 return target; 610 }; 611 612 // exclude the following css properties to add px 613 var exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i, 614 // cache defaultView 615 defaultView = document.defaultView || {}, 616 toString = Object.prototype.toString; 617 618 jQuery.extend({ 619 noConflict: function( deep ) { 620 window.$ = _$; 621 622 if ( deep ) 623 window.jQuery = _jQuery; 624 625 return jQuery; 626 }, 627 628 // See test/unit/core.js for details concerning isFunction. 629 // Since version 1.3, DOM methods and functions like alert 630 // aren't supported. They return false on IE (#2968). 631 isFunction: function( obj ) { 632 return toString.call(obj) === "[object Function]"; 633 }, 634 635 isArray: function( obj ) { 636 return toString.call(obj) === "[object Array]"; 637 }, 638 639 // check if an element is in a (or is an) XML document 640 isXMLDoc: function( elem ) { 641 return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" || 642 !!elem.ownerDocument && jQuery.isXMLDoc( elem.ownerDocument ); 643 }, 644 645 // Evalulates a script in a global context 646 globalEval: function( data ) { 647 if ( data && /\S/.test(data) ) { 648 // Inspired by code by Andrea Giammarchi 649 // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html 650 var head = document.getElementsByTagName("head")[0] || document.documentElement, 651 script = document.createElement("script"); 652 653 script.type = "text/javascript"; 654 if ( jQuery.support.scriptEval ) 655 script.appendChild( document.createTextNode( data ) ); 656 else 657 script.text = data; 658 659 // Use insertBefore instead of appendChild to circumvent an IE6 bug. 660 // This arises when a base node is used (#2709). 661 head.insertBefore( script, head.firstChild ); 662 head.removeChild( script ); 663 } 664 }, 665 666 nodeName: function( elem, name ) { 667 return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase(); 668 }, 669 670 // args is for internal usage only 671 each: function( object, callback, args ) { 672 var name, i = 0, length = object.length; 673 674 if ( args ) { 675 if ( length === undefined ) { 676 for ( name in object ) 677 if ( callback.apply( object[ name ], args ) === false ) 678 break; 679 } else 680 for ( ; i < length; ) 681 if ( callback.apply( object[ i++ ], args ) === false ) 682 break; 683 684 // A special, fast, case for the most common use of each 685 } else { 686 if ( length === undefined ) { 687 for ( name in object ) 688 if ( callback.call( object[ name ], name, object[ name ] ) === false ) 689 break; 690 } else 691 for ( var value = object[0]; 692 i < length && callback.call( value, i, value ) !== false; value = object[++i] ){} 693 } 694 695 return object; 696 }, 697 698 prop: function( elem, value, type, i, name ) { 699 // Handle executable functions 700 if ( jQuery.isFunction( value ) ) 701 value = value.call( elem, i ); 702 703 // Handle passing in a number to a CSS property 704 return typeof value === "number" && type == "curCSS" && !exclude.test( name ) ? 705 value + "px" : 706 value; 707 }, 708 709 className: { 710 // internal only, use addClass("class") 711 add: function( elem, classNames ) { 712 jQuery.each((classNames || "").split(/\s+/), function(i, className){ 713 if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) ) 714 elem.className += (elem.className ? " " : "") + className; 715 }); 716 }, 717 718 // internal only, use removeClass("class") 719 remove: function( elem, classNames ) { 720 if (elem.nodeType == 1) 721 elem.className = classNames !== undefined ? 722 jQuery.grep(elem.className.split(/\s+/), function(className){ 723 return !jQuery.className.has( classNames, className ); 724 }).join(" ") : 725 ""; 726 }, 727 728 // internal only, use hasClass("class") 729 has: function( elem, className ) { 730 return elem && jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1; 731 } 732 }, 733 734 // A method for quickly swapping in/out CSS properties to get correct calculations 735 swap: function( elem, options, callback ) { 736 var old = {}; 737 // Remember the old values, and insert the new ones 738 for ( var name in options ) { 739 old[ name ] = elem.style[ name ]; 740 elem.style[ name ] = options[ name ]; 741 } 742 743 callback.call( elem ); 744 745 // Revert the old values 746 for ( var name in options ) 747 elem.style[ name ] = old[ name ]; 748 }, 749 750 css: function( elem, name, force, extra ) { 751 if ( name == "width" || name == "height" ) { 752 var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ]; 753 754 function getWH() { 755 val = name == "width" ? elem.offsetWidth : elem.offsetHeight; 756 757 if ( extra === "border" ) 758 return; 759 760 jQuery.each( which, function() { 761 if ( !extra ) 762 val -= parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0; 763 if ( extra === "margin" ) 764 val += parseFloat(jQuery.curCSS( elem, "margin" + this, true)) || 0; 765 else 766 val -= parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0; 767 }); 768 } 769 770 if ( elem.offsetWidth !== 0 ) 771 getWH(); 772 else 773 jQuery.swap( elem, props, getWH ); 774 775 return Math.max(0, Math.round(val)); 776 } 777 778 return jQuery.curCSS( elem, name, force ); 779 }, 780 781 curCSS: function( elem, name, force ) { 782 var ret, style = elem.style; 783 784 // We need to handle opacity special in IE 785 if ( name == "opacity" && !jQuery.support.opacity ) { 786 ret = jQuery.attr( style, "opacity" ); 787 788 return ret == "" ? 789 "1" : 790 ret; 791 } 792 793 // Make sure we're using the right name for getting the float value 794 if ( name.match( /float/i ) ) 795 name = styleFloat; 796 797 if ( !force && style && style[ name ] ) 798 ret = style[ name ]; 799 800 else if ( defaultView.getComputedStyle ) { 801 802 // Only "float" is needed here 803 if ( name.match( /float/i ) ) 804 name = "float"; 805 806 name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase(); 807 808 var computedStyle = defaultView.getComputedStyle( elem, null ); 809 810 if ( computedStyle ) 811 ret = computedStyle.getPropertyValue( name ); 812 813 // We should always get a number back from opacity 814 if ( name == "opacity" && ret == "" ) 815 ret = "1"; 816 817 } else if ( elem.currentStyle ) { 818 var camelCase = name.replace(/\-(\w)/g, function(all, letter){ 819 return letter.toUpperCase(); 820 }); 821 822 ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ]; 823 824 // From the awesome hack by Dean Edwards 825 // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 826 827 // If we're not dealing with a regular pixel number 828 // but a number that has a weird ending, we need to convert it to pixels 829 if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) { 830 // Remember the original values 831 var left = style.left, rsLeft = elem.runtimeStyle.left; 832 833 // Put in the new values to get a computed value out 834 elem.runtimeStyle.left = elem.currentStyle.left; 835 style.left = ret || 0; 836 ret = style.pixelLeft + "px"; 837 838 // Revert the changed values 839 style.left = left; 840 elem.runtimeStyle.left = rsLeft; 841 } 842 } 843 844 return ret; 845 }, 846 847 clean: function( elems, context, fragment ) { 848 context = context || document; 849 850 // !context.createElement fails in IE with an error but returns typeof 'object' 851 if ( typeof context.createElement === "undefined" ) 852 context = context.ownerDocument || context[0] && context[0].ownerDocument || document; 853 854 // If a single string is passed in and it's a single tag 855 // just do a createElement and skip the rest 856 if ( !fragment && elems.length === 1 && typeof elems[0] === "string" ) { 857 var match = /^<(\w+)\s*\/?>$/.exec(elems[0]); 858 if ( match ) 859 return [ context.createElement( match[1] ) ]; 860 } 861 862 var ret = [], scripts = [], div = context.createElement("div"); 863 864 jQuery.each(elems, function(i, elem){ 865 if ( typeof elem === "number" ) 866 elem += ''; 867 868 if ( !elem ) 869 return; 870 871 // Convert html string into DOM nodes 872 if ( typeof elem === "string" ) { 873 // Fix "XHTML"-style tags in all browsers 874 elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){ 875 return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ? 876 all : 877 front + "></" + tag + ">"; 878 }); 879 880 // Trim whitespace, otherwise indexOf won't work as expected 881 var tags = elem.replace(/^\s+/, "").substring(0, 10).toLowerCase(); 882 883 var wrap = 884 // option or optgroup 885 !tags.indexOf("<opt") && 886 [ 1, "<select multiple='multiple'>", "</select>" ] || 887 888 !tags.indexOf("<leg") && 889 [ 1, "<fieldset>", "</fieldset>" ] || 890 891 tags.match(/^<(thead|tbody|tfoot|colg|cap)/) && 892 [ 1, "<table>", "</table>" ] || 893 894 !tags.indexOf("<tr") && 895 [ 2, "<table><tbody>", "</tbody></table>" ] || 896 897 // <thead> matched above 898 (!tags.indexOf("<td") || !tags.indexOf("<th")) && 899 [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ] || 900 901 !tags.indexOf("<col") && 902 [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ] || 903 904 // IE can't serialize <link> and <script> tags normally 905 !jQuery.support.htmlSerialize && 906 [ 1, "div<div>", "</div>" ] || 907 908 [ 0, "", "" ]; 909 910 // Go to html and back, then peel off extra wrappers 911 div.innerHTML = wrap[1] + elem + wrap[2]; 912 913 // Move to the right depth 914 while ( wrap[0]-- ) 915 div = div.lastChild; 916 917 // Remove IE's autoinserted <tbody> from table fragments 918 if ( !jQuery.support.tbody ) { 919 920 // String was a <table>, *may* have spurious <tbody> 921 var hasBody = /<tbody/i.test(elem), 922 tbody = !tags.indexOf("<table") && !hasBody ? 923 div.firstChild && div.firstChild.childNodes : 924 925 // String was a bare <thead> or <tfoot> 926 wrap[1] == "<table>" && !hasBody ? 927 div.childNodes : 928 []; 929 930 for ( var j = tbody.length - 1; j >= 0 ; --j ) 931 if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) 932 tbody[ j ].parentNode.removeChild( tbody[ j ] ); 933 934 } 935 936 // IE completely kills leading whitespace when innerHTML is used 937 if ( !jQuery.support.leadingWhitespace && /^\s/.test( elem ) ) 938 div.insertBefore( context.createTextNode( elem.match(/^\s*/)[0] ), div.firstChild ); 939 940 elem = jQuery.makeArray( div.childNodes ); 941 } 942 943 if ( elem.nodeType ) 944 ret.push( elem ); 945 else 946 ret = jQuery.merge( ret, elem ); 947 948 }); 949 950 if ( fragment ) { 951 for ( var i = 0; ret[i]; i++ ) { 952 if ( jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) { 953 scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] ); 954 } else { 955 if ( ret[i].nodeType === 1 ) 956 ret.splice.apply( ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))) ); 957 fragment.appendChild( ret[i] ); 958 } 959 } 960 961 return scripts; 962 } 963 964 return ret; 965 }, 966 967 attr: function( elem, name, value ) { 968 // don't set attributes on text and comment nodes 969 if (!elem || elem.nodeType == 3 || elem.nodeType == 8) 970 return undefined; 971 972 var notxml = !jQuery.isXMLDoc( elem ), 973 // Whether we are setting (or getting) 974 set = value !== undefined; 975 976 // Try to normalize/fix the name 977 name = notxml && jQuery.props[ name ] || name; 978 979 // Only do all the following if this is a node (faster for style) 980 // IE elem.getAttribute passes even for style 981 if ( elem.tagName ) { 982 983 // These attributes require special treatment 984 var special = /href|src|style/.test( name ); 985 986 // Safari mis-reports the default selected property of a hidden option 987 // Accessing the parent's selectedIndex property fixes it 988 if ( name == "selected" && elem.parentNode ) 989 elem.parentNode.selectedIndex; 990 991 // If applicable, access the attribute via the DOM 0 way 992 if ( name in elem && notxml && !special ) { 993 if ( set ){ 994 // We can't allow the type property to be changed (since it causes problems in IE) 995 if ( name == "type" && jQuery.nodeName( elem, "input" ) && elem.parentNode ) 996 throw "type property can't be changed"; 997 998 elem[ name ] = value; 999 } 1000 1001 // browsers index elements by id/name on forms, give priority to attributes. 1002 if( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) ) 1003 return elem.getAttributeNode( name ).nodeValue; 1004 1005 // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set 1006 // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ 1007 if ( name == "tabIndex" ) { 1008 var attributeNode = elem.getAttributeNode( "tabIndex" ); 1009 return attributeNode && attributeNode.specified 1010 ? attributeNode.value 1011 : elem.nodeName.match(/(button|input|object|select|textarea)/i) 1012 ? 0 1013 : elem.nodeName.match(/^(a|area)$/i) && elem.href 1014 ? 0 1015 : undefined; 1016 } 1017 1018 return elem[ name ]; 1019 } 1020 1021 if ( !jQuery.support.style && notxml && name == "style" ) 1022 return jQuery.attr( elem.style, "cssText", value ); 1023 1024 if ( set ) 1025 // convert the value to a string (all browsers do this but IE) see #1070 1026 elem.setAttribute( name, "" + value ); 1027 1028 var attr = !jQuery.support.hrefNormalized && notxml && special 1029 // Some attributes require a special call on IE 1030 ? elem.getAttribute( name, 2 ) 1031 : elem.getAttribute( name ); 1032 1033 // Non-existent attributes return null, we normalize to undefined 1034 return attr === null ? undefined : attr; 1035 } 1036 1037 // elem is actually elem.style ... set the style 1038 1039 // IE uses filters for opacity 1040 if ( !jQuery.support.opacity && name == "opacity" ) { 1041 if ( set ) { 1042 // IE has trouble with opacity if it does not have layout 1043 // Force it by setting the zoom level 1044 elem.zoom = 1; 1045 1046 // Set the alpha filter to set the opacity 1047 elem.filter = (elem.filter || "").replace( /alpha\([^)]*\)/, "" ) + 1048 (parseInt( value ) + '' == "NaN" ? "" : "alpha(opacity=" + value * 100 + ")"); 1049 } 1050 1051 return elem.filter && elem.filter.indexOf("opacity=") >= 0 ? 1052 (parseFloat( elem.filter.match(/opacity=([^)]*)/)[1] ) / 100) + '': 1053 ""; 1054 } 1055 1056 name = name.replace(/-([a-z])/ig, function(all, letter){ 1057 return letter.toUpperCase(); 1058 }); 1059 1060 if ( set ) 1061 elem[ name ] = value; 1062 1063 return elem[ name ]; 1064 }, 1065 1066 trim: function( text ) { 1067 return (text || "").replace( /^\s+|\s+$/g, "" ); 1068 }, 1069 1070 makeArray: function( array ) { 1071 var ret = []; 1072 1073 if( array != null ){ 1074 var i = array.length; 1075 // The window, strings (and functions) also have 'length' 1076 if( i == null || typeof array === "string" || jQuery.isFunction(array) || array.setInterval ) 1077 ret[0] = array; 1078 else 1079 while( i ) 1080 ret[--i] = array[i]; 1081 } 1082 1083 return ret; 1084 }, 1085 1086 inArray: function( elem, array ) { 1087 for ( var i = 0, length = array.length; i < length; i++ ) 1088 // Use === because on IE, window == document 1089 if ( array[ i ] === elem ) 1090 return i; 1091 1092 return -1; 1093 }, 1094 1095 merge: function( first, second ) { 1096 // We have to loop this way because IE & Opera overwrite the length 1097 // expando of getElementsByTagName 1098 var i = 0, elem, pos = first.length; 1099 // Also, we need to make sure that the correct elements are being returned 1100 // (IE returns comment nodes in a '*' query) 1101 if ( !jQuery.support.getAll ) { 1102 while ( (elem = second[ i++ ]) != null ) 1103 if ( elem.nodeType != 8 ) 1104 first[ pos++ ] = elem; 1105 1106 } else 1107 while ( (elem = second[ i++ ]) != null ) 1108 first[ pos++ ] = elem; 1109 1110 return first; 1111 }, 1112 1113 unique: function( array ) { 1114 var ret = [], done = {}; 1115 1116 try { 1117 1118 for ( var i = 0, length = array.length; i < length; i++ ) { 1119 var id = jQuery.data( array[ i ] ); 1120 1121 if ( !done[ id ] ) { 1122 done[ id ] = true; 1123 ret.push( array[ i ] ); 1124 } 1125 } 1126 1127 } catch( e ) { 1128 ret = array; 1129 } 1130 1131 return ret; 1132 }, 1133 1134 grep: function( elems, callback, inv ) { 1135 var ret = []; 1136 1137 // Go through the array, only saving the items 1138 // that pass the validator function 1139 for ( var i = 0, length = elems.length; i < length; i++ ) 1140 if ( !inv != !callback( elems[ i ], i ) ) 1141 ret.push( elems[ i ] ); 1142 1143 return ret; 1144 }, 1145 1146 map: function( elems, callback ) { 1147 var ret = []; 1148 1149 // Go through the array, translating each of the items to their 1150 // new value (or values). 1151 for ( var i = 0, length = elems.length; i < length; i++ ) { 1152 var value = callback( elems[ i ], i ); 1153 1154 if ( value != null ) 1155 ret[ ret.length ] = value; 1156 } 1157 1158 return ret.concat.apply( [], ret ); 1159 } 1160 }); 1161 1162 // Use of jQuery.browser is deprecated. 1163 // It's included for backwards compatibility and plugins, 1164 // although they should work to migrate away. 1165 1166 var userAgent = navigator.userAgent.toLowerCase(); 1167 1168 // Figure out what browser is being used 1169 jQuery.browser = { 1170 version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [0,'0'])[1], 1171 safari: /webkit/.test( userAgent ), 1172 opera: /opera/.test( userAgent ), 1173 msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ), 1174 mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent ) 1175 }; 1176 1177 jQuery.each({ 1178 parent: function(elem){return elem.parentNode;}, 1179 parents: function(elem){return jQuery.dir(elem,"parentNode");}, 1180 next: function(elem){return jQuery.nth(elem,2,"nextSibling");}, 1181 prev: function(elem){return jQuery.nth(elem,2,"previousSibling");}, 1182 nextAll: function(elem){return jQuery.dir(elem,"nextSibling");}, 1183 prevAll: function(elem){return jQuery.dir(elem,"previousSibling");}, 1184 siblings: function(elem){return jQuery.sibling(elem.parentNode.firstChild,elem);}, 1185 children: function(elem){return jQuery.sibling(elem.firstChild);}, 1186 contents: function(elem){return jQuery.nodeName(elem,"iframe")?elem.contentDocument||elem.contentWindow.document:jQuery.makeArray(elem.childNodes);} 1187 }, function(name, fn){ 1188 jQuery.fn[ name ] = function( selector ) { 1189 var ret = jQuery.map( this, fn ); 1190 1191 if ( selector && typeof selector == "string" ) 1192 ret = jQuery.multiFilter( selector, ret ); 1193 1194 return this.pushStack( jQuery.unique( ret ), name, selector ); 1195 }; 1196 }); 1197 1198 jQuery.each({ 1199 appendTo: "append", 1200 prependTo: "prepend", 1201 insertBefore: "before", 1202 insertAfter: "after", 1203 replaceAll: "replaceWith" 1204 }, function(name, original){ 1205 jQuery.fn[ name ] = function( selector ) { 1206 var ret = [], insert = jQuery( selector ); 1207 1208 for ( var i = 0, l = insert.length; i < l; i++ ) { 1209 var elems = (i > 0 ? this.clone(true) : this).get(); 1210 jQuery.fn[ original ].apply( jQuery(insert[i]), elems ); 1211 ret = ret.concat( elems ); 1212 } 1213 1214 return this.pushStack( ret, name, selector ); 1215 }; 1216 }); 1217 1218 jQuery.each({ 1219 removeAttr: function( name ) { 1220 jQuery.attr( this, name, "" ); 1221 if (this.nodeType == 1) 1222 this.removeAttribute( name ); 1223 }, 1224 1225 addClass: function( classNames ) { 1226 jQuery.className.add( this, classNames ); 1227 }, 1228 1229 removeClass: function( classNames ) { 1230 jQuery.className.remove( this, classNames ); 1231 }, 1232 1233 toggleClass: function( classNames, state ) { 1234 if( typeof state !== "boolean" ) 1235 state = !jQuery.className.has( this, classNames ); 1236 jQuery.className[ state ? "add" : "remove" ]( this, classNames ); 1237 }, 1238 1239 remove: function( selector ) { 1240 if ( !selector || jQuery.filter( selector, [ this ] ).length ) { 1241 // Prevent memory leaks 1242 jQuery( "*", this ).add([this]).each(function(){ 1243 jQuery.event.remove(this); 1244 jQuery.removeData(this); 1245 }); 1246 if (this.parentNode) 1247 this.parentNode.removeChild( this ); 1248 } 1249 }, 1250 1251 empty: function() { 1252 // Remove element nodes and prevent memory leaks 1253 jQuery(this).children().remove(); 1254 1255 // Remove any remaining nodes 1256 while ( this.firstChild ) 1257 this.removeChild( this.firstChild ); 1258 } 1259 }, function(name, fn){ 1260 jQuery.fn[ name ] = function(){ 1261 return this.each( fn, arguments ); 1262 }; 1263 }); 1264 1265 // Helper function used by the dimensions and offset modules 1266 function num(elem, prop) { 1267 return elem[0] && parseInt( jQuery.curCSS(elem[0], prop, true), 10 ) || 0; 1268 } 1269 var expando = "jQuery" + now(), uuid = 0, windowData = {}; 1270 1271 jQuery.extend({ 1272 cache: {}, 1273 1274 data: function( elem, name, data ) { 1275 elem = elem == window ? 1276 windowData : 1277 elem; 1278 1279 var id = elem[ expando ]; 1280 1281 // Compute a unique ID for the element 1282 if ( !id ) 1283 id = elem[ expando ] = ++uuid; 1284 1285 // Only generate the data cache if we're 1286 // trying to access or manipulate it 1287 if ( name && !jQuery.cache[ id ] ) 1288 jQuery.cache[ id ] = {}; 1289 1290 // Prevent overriding the named cache with undefined values 1291 if ( data !== undefined ) 1292 jQuery.cache[ id ][ name ] = data; 1293 1294 // Return the named cache data, or the ID for the element 1295 return name ? 1296 jQuery.cache[ id ][ name ] : 1297 id; 1298 }, 1299 1300 removeData: function( elem, name ) { 1301 elem = elem == window ? 1302 windowData : 1303 elem; 1304 1305 var id = elem[ expando ]; 1306 1307 // If we want to remove a specific section of the element's data 1308 if ( name ) { 1309 if ( jQuery.cache[ id ] ) { 1310 // Remove the section of cache data 1311 delete jQuery.cache[ id ][ name ]; 1312 1313 // If we've removed all the data, remove the element's cache 1314 name = ""; 1315 1316 for ( name in jQuery.cache[ id ] ) 1317 break; 1318 1319 if ( !name ) 1320 jQuery.removeData( elem ); 1321 } 1322 1323 // Otherwise, we want to remove all of the element's data 1324 } else { 1325 // Clean up the element expando 1326 try { 1327 delete elem[ expando ]; 1328 } catch(e){ 1329 // IE has trouble directly removing the expando 1330 // but it's ok with using removeAttribute 1331 if ( elem.removeAttribute ) 1332 elem.removeAttribute( expando ); 1333 } 1334 1335 // Completely remove the data cache 1336 delete jQuery.cache[ id ]; 1337 } 1338 }, 1339 queue: function( elem, type, data ) { 1340 if ( elem ){ 1341 1342 type = (type || "fx") + "queue"; 1343 1344 var q = jQuery.data( elem, type ); 1345 1346 if ( !q || jQuery.isArray(data) ) 1347 q = jQuery.data( elem, type, jQuery.makeArray(data) ); 1348 else if( data ) 1349 q.push( data ); 1350 1351 } 1352 return q; 1353 }, 1354 1355 dequeue: function( elem, type ){ 1356 var queue = jQuery.queue( elem, type ), 1357 fn = queue.shift(); 1358 1359 if( !type || type === "fx" ) 1360 fn = queue[0]; 1361 1362 if( fn !== undefined ) 1363 fn.call(elem); 1364 } 1365 }); 1366 1367 jQuery.fn.extend({ 1368 data: function( key, value ){ 1369 var parts = key.split("."); 1370 parts[1] = parts[1] ? "." + parts[1] : ""; 1371 1372 if ( value === undefined ) { 1373 var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]); 1374 1375 if ( data === undefined && this.length ) 1376 data = jQuery.data( this[0], key ); 1377 1378 return data === undefined && parts[1] ? 1379 this.data( parts[0] ) : 1380 data; 1381 } else 1382 return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function(){ 1383 jQuery.data( this, key, value ); 1384 }); 1385 }, 1386 1387 removeData: function( key ){ 1388 return this.each(function(){ 1389 jQuery.removeData( this, key ); 1390 }); 1391 }, 1392 queue: function(type, data){ 1393 if ( typeof type !== "string" ) { 1394 data = type; 1395 type = "fx"; 1396 } 1397 1398 if ( data === undefined ) 1399 return jQuery.queue( this[0], type ); 1400 1401 return this.each(function(){ 1402 var queue = jQuery.queue( this, type, data ); 1403 1404 if( type == "fx" && queue.length == 1 ) 1405 queue[0].call(this); 1406 }); 1407 }, 1408 dequeue: function(type){ 1409 return this.each(function(){ 1410 jQuery.dequeue( this, type ); 1411 }); 1412 } 1413 });/*! 1414 * Sizzle CSS Selector Engine - v0.9.3 1415 * Copyright 2009, The Dojo Foundation 1416 * Released under the MIT, BSD, and GPL Licenses. 1417 * More information: http://sizzlejs.com/ 1418 */ 1419 (function(){ 1420 1421 var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g, 1422 done = 0, 1423 toString = Object.prototype.toString; 1424 1425 var Sizzle = function(selector, context, results, seed) { 1426 results = results || []; 1427 context = context || document; 1428 1429 if ( context.nodeType !== 1 && context.nodeType !== 9 ) 1430 return []; 1431 1432 if ( !selector || typeof selector !== "string" ) { 1433 return results; 1434 } 1435 1436 var parts = [], m, set, checkSet, check, mode, extra, prune = true; 1437 1438 // Reset the position of the chunker regexp (start from head) 1439 chunker.lastIndex = 0; 1440 1441 while ( (m = chunker.exec(selector)) !== null ) { 1442 parts.push( m[1] ); 1443 1444 if ( m[2] ) { 1445 extra = RegExp.rightContext; 1446 break; 1447 } 1448 } 1449 1450 if ( parts.length > 1 && origPOS.exec( selector ) ) { 1451 if ( parts.length === 2 && Expr.relative[ parts[0] ] ) { 1452 set = posProcess( parts[0] + parts[1], context ); 1453 } else { 1454 set = Expr.relative[ parts[0] ] ? 1455 [ context ] : 1456 Sizzle( parts.shift(), context ); 1457 1458 while ( parts.length ) { 1459 selector = parts.shift(); 1460 1461 if ( Expr.relative[ selector ] ) 1462 selector += parts.shift(); 1463 1464 set = posProcess( selector, set ); 1465 } 1466 } 1467 } else { 1468 var ret = seed ? 1469 { expr: parts.pop(), set: makeArray(seed) } : 1470 Sizzle.find( parts.pop(), parts.length === 1 && context.parentNode ? context.parentNode : context, isXML(context) ); 1471 set = Sizzle.filter( ret.expr, ret.set ); 1472 1473 if ( parts.length > 0 ) { 1474 checkSet = makeArray(set); 1475 } else { 1476 prune = false; 1477 } 1478 1479 while ( parts.length ) { 1480 var cur = parts.pop(), pop = cur; 1481 1482 if ( !Expr.relative[ cur ] ) { 1483 cur = ""; 1484 } else { 1485 pop = parts.pop(); 1486 } 1487 1488 if ( pop == null ) { 1489 pop = context; 1490 } 1491 1492 Expr.relative[ cur ]( checkSet, pop, isXML(context) ); 1493 } 1494 } 1495 1496 if ( !checkSet ) { 1497 checkSet = set; 1498 } 1499 1500 if ( !checkSet ) { 1501 throw "Syntax error, unrecognized expression: " + (cur || selector); 1502 } 1503 1504 if ( toString.call(checkSet) === "[object Array]" ) { 1505 if ( !prune ) { 1506 results.push.apply( results, checkSet ); 1507 } else if ( context.nodeType === 1 ) { 1508 for ( var i = 0; checkSet[i] != null; i++ ) { 1509 if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) { 1510 results.push( set[i] ); 1511 } 1512 } 1513 } else { 1514 for ( var i = 0; checkSet[i] != null; i++ ) { 1515 if ( checkSet[i] && checkSet[i].nodeType === 1 ) { 1516 results.push( set[i] ); 1517 } 1518 } 1519 } 1520 } else { 1521 makeArray( checkSet, results ); 1522 } 1523 1524 if ( extra ) { 1525 Sizzle( extra, context, results, seed ); 1526 1527 if ( sortOrder ) { 1528 hasDuplicate = false; 1529 results.sort(sortOrder); 1530 1531 if ( hasDuplicate ) { 1532 for ( var i = 1; i < results.length; i++ ) { 1533 if ( results[i] === results[i-1] ) { 1534 results.splice(i--, 1); 1535 } 1536 } 1537 } 1538 } 1539 } 1540 1541 return results; 1542 }; 1543 1544 Sizzle.matches = function(expr, set){ 1545 return Sizzle(expr, null, null, set); 1546 }; 1547 1548 Sizzle.find = function(expr, context, isXML){ 1549 var set, match; 1550 1551 if ( !expr ) { 1552 return []; 1553 } 1554 1555 for ( var i = 0, l = Expr.order.length; i < l; i++ ) { 1556 var type = Expr.order[i], match; 1557 1558 if ( (match = Expr.match[ type ].exec( expr )) ) { 1559 var left = RegExp.leftContext; 1560 1561 if ( left.substr( left.length - 1 ) !== "\\" ) { 1562 match[1] = (match[1] || "").replace(/\\/g, ""); 1563 set = Expr.find[ type ]( match, context, isXML ); 1564 if ( set != null ) { 1565 expr = expr.replace( Expr.match[ type ], "" ); 1566 break; 1567 } 1568 } 1569 } 1570 } 1571 1572 if ( !set ) { 1573 set = context.getElementsByTagName("*"); 1574 } 1575 1576 return {set: set, expr: expr}; 1577 }; 1578 1579 Sizzle.filter = function(expr, set, inplace, not){ 1580 var old = expr, result = [], curLoop = set, match, anyFound, 1581 isXMLFilter = set && set[0] && isXML(set[0]); 1582 1583 while ( expr && set.length ) { 1584 for ( var type in Expr.filter ) { 1585 if ( (match = Expr.match[ type ].exec( expr )) != null ) { 1586 var filter = Expr.filter[ type ], found, item; 1587 anyFound = false; 1588 1589 if ( curLoop == result ) { 1590 result = []; 1591 } 1592 1593 if ( Expr.preFilter[ type ] ) { 1594 match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter ); 1595 1596 if ( !match ) { 1597 anyFound = found = true; 1598 } else if ( match === true ) { 1599 continue; 1600 } 1601 } 1602 1603 if ( match ) { 1604 for ( var i = 0; (item = curLoop[i]) != null; i++ ) { 1605 if ( item ) { 1606 found = filter( item, match, i, curLoop ); 1607 var pass = not ^ !!found; 1608 1609 if ( inplace && found != null ) { 1610 if ( pass ) { 1611 anyFound = true; 1612 } else { 1613 curLoop[i] = false; 1614 } 1615 } else if ( pass ) { 1616 result.push( item ); 1617 anyFound = true; 1618 } 1619 } 1620 } 1621 } 1622 1623 if ( found !== undefined ) { 1624 if ( !inplace ) { 1625 curLoop = result; 1626 } 1627 1628 expr = expr.replace( Expr.match[ type ], "" ); 1629 1630 if ( !anyFound ) { 1631 return []; 1632 } 1633 1634 break; 1635 } 1636 } 1637 } 1638 1639 // Improper expression 1640 if ( expr == old ) { 1641 if ( anyFound == null ) { 1642 throw "Syntax error, unrecognized expression: " + expr; 1643 } else { 1644 break; 1645 } 1646 } 1647 1648 old = expr; 1649 } 1650 1651 return curLoop; 1652 }; 1653 1654 var Expr = Sizzle.selectors = { 1655 order: [ "ID", "NAME", "TAG" ], 1656 match: { 1657 ID: /#((?:[\w\u00c0-\uFFFF_-]|\\.)+)/, 1658 CLASS: /\.((?:[\w\u00c0-\uFFFF_-]|\\.)+)/, 1659 NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF_-]|\\.)+)['"]*\]/, 1660 ATTR: /\[\s*((?:[\w\u00c0-\uFFFF_-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/, 1661 TAG: /^((?:[\w\u00c0-\uFFFF\*_-]|\\.)+)/, 1662 CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/, 1663 POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/, 1664 PSEUDO: /:((?:[\w\u00c0-\uFFFF_-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/ 1665 }, 1666 attrMap: { 1667 "class": "className", 1668 "for": "htmlFor" 1669 }, 1670 attrHandle: { 1671 href: function(elem){ 1672 return elem.getAttribute("href"); 1673 } 1674 }, 1675 relative: { 1676 "+": function(checkSet, part, isXML){ 1677 var isPartStr = typeof part === "string", 1678 isTag = isPartStr && !/\W/.test(part), 1679 isPartStrNotTag = isPartStr && !isTag; 1680 1681 if ( isTag && !isXML ) { 1682 part = part.toUpperCase(); 1683 } 1684 1685 for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) { 1686 if ( (elem = checkSet[i]) ) { 1687 while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {} 1688 1689 checkSet[i] = isPartStrNotTag || elem && elem.nodeName === part ? 1690 elem || false : 1691 elem === part; 1692 } 1693 } 1694 1695 if ( isPartStrNotTag ) { 1696 Sizzle.filter( part, checkSet, true ); 1697 } 1698 }, 1699 ">": function(checkSet, part, isXML){ 1700 var isPartStr = typeof part === "string"; 1701 1702 if ( isPartStr && !/\W/.test(part) ) { 1703 part = isXML ? part : part.toUpperCase(); 1704 1705 for ( var i = 0, l = checkSet.length; i < l; i++ ) { 1706 var elem = checkSet[i]; 1707 if ( elem ) { 1708 var parent = elem.parentNode; 1709 checkSet[i] = parent.nodeName === part ? parent : false; 1710 } 1711 } 1712 } else { 1713 for ( var i = 0, l = checkSet.length; i < l; i++ ) { 1714 var elem = checkSet[i]; 1715 if ( elem ) { 1716 checkSet[i] = isPartStr ? 1717 elem.parentNode : 1718 elem.parentNode === part; 1719 } 1720 } 1721 1722 if ( isPartStr ) { 1723 Sizzle.filter( part, checkSet, true ); 1724 } 1725 } 1726 }, 1727 "": function(checkSet, part, isXML){ 1728 var doneName = done++, checkFn = dirCheck; 1729 1730 if ( !part.match(/\W/) ) { 1731 var nodeCheck = part = isXML ? part : part.toUpperCase(); 1732 checkFn = dirNodeCheck; 1733 } 1734 1735 checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML); 1736 }, 1737 "~": function(checkSet, part, isXML){ 1738 var doneName = done++, checkFn = dirCheck; 1739 1740 if ( typeof part === "string" && !part.match(/\W/) ) { 1741 var nodeCheck = part = isXML ? part : part.toUpperCase(); 1742 checkFn = dirNodeCheck; 1743 } 1744 1745 checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML); 1746 } 1747 }, 1748 find: { 1749 ID: function(match, context, isXML){ 1750 if ( typeof context.getElementById !== "undefined" && !isXML ) { 1751 var m = context.getElementById(match[1]); 1752 return m ? [m] : []; 1753 } 1754 }, 1755 NAME: function(match, context, isXML){ 1756 if ( typeof context.getElementsByName !== "undefined" ) { 1757 var ret = [], results = context.getElementsByName(match[1]); 1758 1759 for ( var i = 0, l = results.length; i < l; i++ ) { 1760 if ( results[i].getAttribute("name") === match[1] ) { 1761 ret.push( results[i] ); 1762 } 1763 } 1764 1765 return ret.length === 0 ? null : ret; 1766 } 1767 }, 1768 TAG: function(match, context){ 1769 return context.getElementsByTagName(match[1]); 1770 } 1771 }, 1772 preFilter: { 1773 CLASS: function(match, curLoop, inplace, result, not, isXML){ 1774 match = " " + match[1].replace(/\\/g, "") + " "; 1775 1776 if ( isXML ) { 1777 return match; 1778 } 1779 1780 for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) { 1781 if ( elem ) { 1782 if ( not ^ (elem.className && (" " + elem.className + " ").indexOf(match) >= 0) ) { 1783 if ( !inplace ) 1784 result.push( elem ); 1785 } else if ( inplace ) { 1786 curLoop[i] = false; 1787 } 1788 } 1789 } 1790 1791 return false; 1792 }, 1793 ID: function(match){ 1794 return match[1].replace(/\\/g, ""); 1795 }, 1796 TAG: function(match, curLoop){ 1797 for ( var i = 0; curLoop[i] === false; i++ ){} 1798 return curLoop[i] && isXML(curLoop[i]) ? match[1] : match[1].toUpperCase(); 1799 }, 1800 CHILD: function(match){ 1801 if ( match[1] == "nth" ) { 1802 // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6' 1803 var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec( 1804 match[2] == "even" && "2n" || match[2] == "odd" && "2n+1" || 1805 !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]); 1806 1807 // calculate the numbers (first)n+(last) including if they are negative 1808 match[2] = (test[1] + (test[2] || 1)) - 0; 1809 match[3] = test[3] - 0; 1810 } 1811 1812 // TODO: Move to normal caching system 1813 match[0] = done++; 1814 1815 return match; 1816 }, 1817 ATTR: function(match, curLoop, inplace, result, not, isXML){ 1818 var name = match[1].replace(/\\/g, ""); 1819 1820 if ( !isXML && Expr.attrMap[name] ) { 1821 match[1] = Expr.attrMap[name]; 1822 } 1823 1824 if ( match[2] === "~=" ) { 1825 match[4] = " " + match[4] + " "; 1826 } 1827 1828 return match; 1829 }, 1830 PSEUDO: function(match, curLoop, inplace, result, not){ 1831 if ( match[1] === "not" ) { 1832 // If we're dealing with a complex expression, or a simple one 1833 if ( match[3].match(chunker).length > 1 || /^\w/.test(match[3]) ) { 1834 match[3] = Sizzle(match[3], null, null, curLoop); 1835 } else { 1836 var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not); 1837 if ( !inplace ) { 1838 result.push.apply( result, ret ); 1839 } 1840 return false; 1841 } 1842 } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) { 1843 return true; 1844 } 1845 1846 return match; 1847 }, 1848 POS: function(match){ 1849 match.unshift( true ); 1850 return match; 1851 } 1852 }, 1853 filters: { 1854 enabled: function(elem){ 1855 return elem.disabled === false && elem.type !== "hidden"; 1856 }, 1857 disabled: function(elem){ 1858 return elem.disabled === true; 1859 }, 1860 checked: function(elem){ 1861 return elem.checked === true; 1862 }, 1863 selected: function(elem){ 1864 // Accessing this property makes selected-by-default 1865 // options in Safari work properly 1866 elem.parentNode.selectedIndex; 1867 return elem.selected === true; 1868 }, 1869 parent: function(elem){ 1870 return !!elem.firstChild; 1871 }, 1872 empty: function(elem){ 1873 return !elem.firstChild; 1874 }, 1875 has: function(elem, i, match){ 1876 return !!Sizzle( match[3], elem ).length; 1877 }, 1878 header: function(elem){ 1879 return /h\d/i.test( elem.nodeName ); 1880 }, 1881 text: function(elem){ 1882 return "text" === elem.type; 1883 }, 1884 radio: function(elem){ 1885 return "radio" === elem.type; 1886 }, 1887 checkbox: function(elem){ 1888 return "checkbox" === elem.type; 1889 }, 1890 file: function(elem){ 1891 return "file" === elem.type; 1892 }, 1893 password: function(elem){ 1894 return "password" === elem.type; 1895 }, 1896 submit: function(elem){ 1897 return "submit" === elem.type; 1898 }, 1899 image: function(elem){ 1900 return "image" === elem.type; 1901 }, 1902 reset: function(elem){ 1903 return "reset" === elem.type; 1904 }, 1905 button: function(elem){ 1906 return "button" === elem.type || elem.nodeName.toUpperCase() === "BUTTON"; 1907 }, 1908 input: function(elem){ 1909 return /input|select|textarea|button/i.test(elem.nodeName); 1910 } 1911 }, 1912 setFilters: { 1913 first: function(elem, i){ 1914 return i === 0; 1915 }, 1916 last: function(elem, i, match, array){ 1917 return i === array.length - 1; 1918 }, 1919 even: function(elem, i){ 1920 return i % 2 === 0; 1921 }, 1922 odd: function(elem, i){ 1923 return i % 2 === 1; 1924 }, 1925 lt: function(elem, i, match){ 1926 return i < match[3] - 0; 1927 }, 1928 gt: function(elem, i, match){ 1929 return i > match[3] - 0; 1930 }, 1931 nth: function(elem, i, match){ 1932 return match[3] - 0 == i; 1933 }, 1934 eq: function(elem, i, match){ 1935 return match[3] - 0 == i; 1936 } 1937 }, 1938 filter: { 1939 PSEUDO: function(elem, match, i, array){ 1940 var name = match[1], filter = Expr.filters[ name ]; 1941 1942 if ( filter ) { 1943 return filter( elem, i, match, array ); 1944 } else if ( name === "contains" ) { 1945 return (elem.textContent || elem.innerText || "").indexOf(match[3]) >= 0; 1946 } else if ( name === "not" ) { 1947 var not = match[3]; 1948 1949 for ( var i = 0, l = not.length; i < l; i++ ) { 1950 if ( not[i] === elem ) { 1951 return false; 1952 } 1953 } 1954 1955 return true; 1956 } 1957 }, 1958 CHILD: function(elem, match){ 1959 var type = match[1], node = elem; 1960 switch (type) { 1961 case 'only': 1962 case 'first': 1963 while (node = node.previousSibling) { 1964 if ( node.nodeType === 1 ) return false; 1965 } 1966 if ( type == 'first') return true; 1967 node = elem; 1968 case 'last': 1969 while (node = node.nextSibling) { 1970 if ( node.nodeType === 1 ) return false; 1971 } 1972 return true; 1973 case 'nth': 1974 var first = match[2], last = match[3]; 1975 1976 if ( first == 1 && last == 0 ) { 1977 return true; 1978 } 1979 1980 var doneName = match[0], 1981 parent = elem.parentNode; 1982 1983 if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) { 1984 var count = 0; 1985 for ( node = parent.firstChild; node; node = node.nextSibling ) { 1986 if ( node.nodeType === 1 ) { 1987 node.nodeIndex = ++count; 1988 } 1989 } 1990 parent.sizcache = doneName; 1991 } 1992 1993 var diff = elem.nodeIndex - last; 1994 if ( first == 0 ) { 1995 return diff == 0; 1996 } else { 1997 return ( diff % first == 0 && diff / first >= 0 ); 1998 } 1999 } 2000 }, 2001 ID: function(elem, match){ 2002 return elem.nodeType === 1 && elem.getAttribute("id") === match; 2003 }, 2004 TAG: function(elem, match){ 2005 return (match === "*" && elem.nodeType === 1) || elem.nodeName === match; 2006 }, 2007 CLASS: function(elem, match){ 2008 return (" " + (elem.className || elem.getAttribute("class")) + " ") 2009 .indexOf( match ) > -1; 2010 }, 2011 ATTR: function(elem, match){ 2012 var name = match[1], 2013 result = Expr.attrHandle[ name ] ? 2014 Expr.attrHandle[ name ]( elem ) : 2015 elem[ name ] != null ? 2016 elem[ name ] : 2017 elem.getAttribute( name ), 2018 value = result + "", 2019 type = match[2], 2020 check = match[4]; 2021 2022 return result == null ? 2023 type === "!=" : 2024 type === "=" ? 2025 value === check : 2026 type === "*=" ? 2027 value.indexOf(check) >= 0 : 2028 type === "~=" ? 2029 (" " + value + " ").indexOf(check) >= 0 : 2030 !check ? 2031 value && result !== false : 2032 type === "!=" ? 2033 value != check : 2034 type === "^=" ? 2035 value.indexOf(check) === 0 : 2036 type === "$=" ? 2037 value.substr(value.length - check.length) === check : 2038 type === "|=" ? 2039 value === check || value.substr(0, check.length + 1) === check + "-" : 2040 false; 2041 }, 2042 POS: function(elem, match, i, array){ 2043 var name = match[2], filter = Expr.setFilters[ name ]; 2044 2045 if ( filter ) { 2046 return filter( elem, i, match, array ); 2047 } 2048 } 2049 } 2050 }; 2051 2052 var origPOS = Expr.match.POS; 2053 2054 for ( var type in Expr.match ) { 2055 Expr.match[ type ] = RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source ); 2056 } 2057 2058 var makeArray = function(array, results) { 2059 array = Array.prototype.slice.call( array ); 2060 2061 if ( results ) { 2062 results.push.apply( results, array ); 2063 return results; 2064 } 2065 2066 return array; 2067 }; 2068 2069 // Perform a simple check to determine if the browser is capable of 2070 // converting a NodeList to an array using builtin methods. 2071 try { 2072 Array.prototype.slice.call( document.documentElement.childNodes ); 2073 2074 // Provide a fallback method if it does not work 2075 } catch(e){ 2076 makeArray = function(array, results) { 2077 var ret = results || []; 2078 2079 if ( toString.call(array) === "[object Array]" ) { 2080 Array.prototype.push.apply( ret, array ); 2081 } else { 2082 if ( typeof array.length === "number" ) { 2083 for ( var i = 0, l = array.length; i < l; i++ ) { 2084 ret.push( array[i] ); 2085 } 2086 } else { 2087 for ( var i = 0; array[i]; i++ ) { 2088 ret.push( array[i] ); 2089 } 2090 } 2091 } 2092 2093 return ret; 2094 }; 2095 } 2096 2097 var sortOrder; 2098 2099 if ( document.documentElement.compareDocumentPosition ) { 2100 sortOrder = function( a, b ) { 2101 var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1; 2102 if ( ret === 0 ) { 2103 hasDuplicate = true; 2104 } 2105 return ret; 2106 }; 2107 } else if ( "sourceIndex" in document.documentElement ) { 2108 sortOrder = function( a, b ) { 2109 var ret = a.sourceIndex - b.sourceIndex; 2110 if ( ret === 0 ) { 2111 hasDuplicate = true; 2112 } 2113 return ret; 2114 }; 2115 } else if ( document.createRange ) { 2116 sortOrder = function( a, b ) { 2117 var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange(); 2118 aRange.selectNode(a); 2119 aRange.collapse(true); 2120 bRange.selectNode(b); 2121 bRange.collapse(true); 2122 var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange); 2123 if ( ret === 0 ) { 2124 hasDuplicate = true; 2125 } 2126 return ret; 2127 }; 2128 } 2129 2130 // Check to see if the browser returns elements by name when 2131 // querying by getElementById (and provide a workaround) 2132 (function(){ 2133 // We're going to inject a fake input element with a specified name 2134 var form = document.createElement("form"), 2135 id = "script" + (new Date).getTime(); 2136 form.innerHTML = "<input name='" + id + "'/>"; 2137 2138 // Inject it into the root element, check its status, and remove it quickly 2139 var root = document.documentElement; 2140 root.insertBefore( form, root.firstChild ); 2141 2142 // The workaround has to do additional checks after a getElementById 2143 // Which slows things down for other browsers (hence the branching) 2144 if ( !!document.getElementById( id ) ) { 2145 Expr.find.ID = function(match, context, isXML){ 2146 if ( typeof context.getElementById !== "undefined" && !isXML ) { 2147 var m = context.getElementById(match[1]); 2148 return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : []; 2149 } 2150 }; 2151 2152 Expr.filter.ID = function(elem, match){ 2153 var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); 2154 return elem.nodeType === 1 && node && node.nodeValue === match; 2155 }; 2156 } 2157 2158 root.removeChild( form ); 2159 })(); 2160 2161 (function(){ 2162 // Check to see if the browser returns only elements 2163 // when doing getElementsByTagName("*") 2164 2165 // Create a fake element 2166 var div = document.createElement("div"); 2167 div.appendChild( document.createComment("") ); 2168 2169 // Make sure no comments are found 2170 if ( div.getElementsByTagName("*").length > 0 ) { 2171 Expr.find.TAG = function(match, context){ 2172 var results = context.getElementsByTagName(match[1]); 2173 2174 // Filter out possible comments 2175 if ( match[1] === "*" ) { 2176 var tmp = []; 2177 2178 for ( var i = 0; results[i]; i++ ) { 2179 if ( results[i].nodeType === 1 ) { 2180 tmp.push( results[i] ); 2181 } 2182 } 2183 2184 results = tmp; 2185 } 2186 2187 return results; 2188 }; 2189 } 2190 2191 // Check to see if an attribute returns normalized href attributes 2192 div.innerHTML = "<a href='#'></a>"; 2193 if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" && 2194 div.firstChild.getAttribute("href") !== "#" ) { 2195 Expr.attrHandle.href = function(elem){ 2196 return elem.getAttribute("href", 2); 2197 }; 2198 } 2199 })(); 2200 2201 if ( document.querySelectorAll ) (function(){ 2202 var oldSizzle = Sizzle, div = document.createElement("div"); 2203 div.innerHTML = "<p class='TEST'></p>"; 2204 2205 // Safari can't handle uppercase or unicode characters when 2206 // in quirks mode. 2207 if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) { 2208 return; 2209 } 2210 2211 Sizzle = function(query, context, extra, seed){ 2212 context = context || document; 2213 2214 // Only use querySelectorAll on non-XML documents 2215 // (ID selectors don't work in non-HTML documents) 2216 if ( !seed && context.nodeType === 9 && !isXML(context) ) { 2217 try { 2218 return makeArray( context.querySelectorAll(query), extra ); 2219 } catch(e){} 2220 } 2221 2222 return oldSizzle(query, context, extra, seed); 2223 }; 2224 2225 Sizzle.find = oldSizzle.find; 2226 Sizzle.filter = oldSizzle.filter; 2227 Sizzle.selectors = oldSizzle.selectors; 2228 Sizzle.matches = oldSizzle.matches; 2229 })(); 2230 2231 if ( document.getElementsByClassName && document.documentElement.getElementsByClassName ) (function(){ 2232 var div = document.createElement("div"); 2233 div.innerHTML = "<div class='test e'></div><div class='test'></div>"; 2234 2235 // Opera can't find a second classname (in 9.6) 2236 if ( div.getElementsByClassName("e").length === 0 ) 2237 return; 2238 2239 // Safari caches class attributes, doesn't catch changes (in 3.2) 2240 div.lastChild.className = "e"; 2241 2242 if ( div.getElementsByClassName("e").length === 1 ) 2243 return; 2244 2245 Expr.order.splice(1, 0, "CLASS"); 2246 Expr.find.CLASS = function(match, context, isXML) { 2247 if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) { 2248 return context.getElementsByClassName(match[1]); 2249 } 2250 }; 2251 })(); 2252 2253 function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { 2254 var sibDir = dir == "previousSibling" && !isXML; 2255 for ( var i = 0, l = checkSet.length; i < l; i++ ) { 2256 var elem = checkSet[i]; 2257 if ( elem ) { 2258 if ( sibDir && elem.nodeType === 1 ){ 2259 elem.sizcache = doneName; 2260 elem.sizset = i; 2261 } 2262 elem = elem[dir]; 2263 var match = false; 2264 2265 while ( elem ) { 2266 if ( elem.sizcache === doneName ) { 2267 match = checkSet[elem.sizset]; 2268 break; 2269 } 2270 2271 if ( elem.nodeType === 1 && !isXML ){ 2272 elem.sizcache = doneName; 2273 elem.sizset = i; 2274 } 2275 2276 if ( elem.nodeName === cur ) { 2277 match = elem; 2278 break; 2279 } 2280 2281 elem = elem[dir]; 2282 } 2283 2284 checkSet[i] = match; 2285 } 2286 } 2287 } 2288 2289 function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { 2290 var sibDir = dir == "previousSibling" && !isXML; 2291 for ( var i = 0, l = checkSet.length; i < l; i++ ) { 2292 var elem = checkSet[i]; 2293 if ( elem ) { 2294 if ( sibDir && elem.nodeType === 1 ) { 2295 elem.sizcache = doneName; 2296 elem.sizset = i; 2297 } 2298 elem = elem[dir]; 2299 var match = false; 2300 2301 while ( elem ) { 2302 if ( elem.sizcache === doneName ) { 2303 match = checkSet[elem.sizset]; 2304 break; 2305 } 2306 2307 if ( elem.nodeType === 1 ) { 2308 if ( !isXML ) { 2309 elem.sizcache = doneName; 2310 elem.sizset = i; 2311 } 2312 if ( typeof cur !== "string" ) { 2313 if ( elem === cur ) { 2314 match = true; 2315 break; 2316 } 2317 2318 } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) { 2319 match = elem; 2320 break; 2321 } 2322 } 2323 2324 elem = elem[dir]; 2325 } 2326 2327 checkSet[i] = match; 2328 } 2329 } 2330 } 2331 2332 var contains = document.compareDocumentPosition ? function(a, b){ 2333 return a.compareDocumentPosition(b) & 16; 2334 } : function(a, b){ 2335 return a !== b && (a.contains ? a.contains(b) : true); 2336 }; 2337 2338 var isXML = function(elem){ 2339 return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" || 2340 !!elem.ownerDocument && isXML( elem.ownerDocument ); 2341 }; 2342 2343 var posProcess = function(selector, context){ 2344 var tmpSet = [], later = "", match, 2345 root = context.nodeType ? [context] : context; 2346 2347 // Position selectors must be done after the filter 2348 // And so must :not(positional) so we move all PSEUDOs to the end 2349 while ( (match = Expr.match.PSEUDO.exec( selector )) ) { 2350 later += match[0]; 2351 selector = selector.replace( Expr.match.PSEUDO, "" ); 2352 } 2353 2354 selector = Expr.relative[selector] ? selector + "*" : selector; 2355 2356 for ( var i = 0, l = root.length; i < l; i++ ) { 2357 Sizzle( selector, root[i], tmpSet ); 2358 } 2359 2360 return Sizzle.filter( later, tmpSet ); 2361 }; 2362 2363 // EXPOSE 2364 jQuery.find = Sizzle; 2365 jQuery.filter = Sizzle.filter; 2366 jQuery.expr = Sizzle.selectors; 2367 jQuery.expr[":"] = jQuery.expr.filters; 2368 2369 Sizzle.selectors.filters.hidden = function(elem){ 2370 return elem.offsetWidth === 0 || elem.offsetHeight === 0; 2371 }; 2372 2373 Sizzle.selectors.filters.visible = function(elem){ 2374 return elem.offsetWidth > 0 || elem.offsetHeight > 0; 2375 }; 2376 2377 Sizzle.selectors.filters.animated = function(elem){ 2378 return jQuery.grep(jQuery.timers, function(fn){ 2379 return elem === fn.elem; 2380 }).length; 2381 }; 2382 2383 jQuery.multiFilter = function( expr, elems, not ) { 2384 if ( not ) { 2385 expr = ":not(" + expr + ")"; 2386 } 2387 2388 return Sizzle.matches(expr, elems); 2389 }; 2390 2391 jQuery.dir = function( elem, dir ){ 2392 var matched = [], cur = elem[dir]; 2393 while ( cur && cur != document ) { 2394 if ( cur.nodeType == 1 ) 2395 matched.push( cur ); 2396 cur = cur[dir]; 2397 } 2398 return matched; 2399 }; 2400 2401 jQuery.nth = function(cur, result, dir, elem){ 2402 result = result || 1; 2403 var num = 0; 2404 2405 for ( ; cur; cur = cur[dir] ) 2406 if ( cur.nodeType == 1 && ++num == result ) 2407 break; 2408 2409 return cur; 2410 }; 2411 2412 jQuery.sibling = function(n, elem){ 2413 var r = []; 2414 2415 for ( ; n; n = n.nextSibling ) { 2416 if ( n.nodeType == 1 && n != elem ) 2417 r.push( n ); 2418 } 2419 2420 return r; 2421 }; 2422 2423 return; 2424 2425 window.Sizzle = Sizzle; 2426 2427 })(); 2428 /* 2429 * A number of helper functions used for managing events. 2430 * Many of the ideas behind this code originated from 2431 * Dean Edwards' addEvent library. 2432 */ 2433 jQuery.event = { 2434 2435 // Bind an event to an element 2436 // Original by Dean Edwards 2437 add: function(elem, types, handler, data) { 2438 if ( elem.nodeType == 3 || elem.nodeType == 8 ) 2439 return; 2440 2441 // For whatever reason, IE has trouble passing the window object 2442 // around, causing it to be cloned in the process 2443 if ( elem.setInterval && elem != window ) 2444 elem = window; 2445 2446 // Make sure that the function being executed has a unique ID 2447 if ( !handler.guid ) 2448 handler.guid = this.guid++; 2449 2450 // if data is passed, bind to handler 2451 if ( data !== undefined ) { 2452 // Create temporary function pointer to original handler 2453 var fn = handler; 2454 2455 // Create unique handler function, wrapped around original handler 2456 handler = this.proxy( fn ); 2457 2458 // Store data in unique handler 2459 handler.data = data; 2460 } 2461 2462 // Init the element's event structure 2463 var events = jQuery.data(elem, "events") || jQuery.data(elem, "events", {}), 2464 handle = jQuery.data(elem, "handle") || jQuery.data(elem, "handle", function(){ 2465 // Handle the second event of a trigger and when 2466 // an event is called after a page has unloaded 2467 return typeof jQuery !== "undefined" && !jQuery.event.triggered ? 2468 jQuery.event.handle.apply(arguments.callee.elem, arguments) : 2469 undefined; 2470 }); 2471 // Add elem as a property of the handle function 2472 // This is to prevent a memory leak with non-native 2473 // event in IE. 2474 handle.elem = elem; 2475 2476 // Handle multiple events separated by a space 2477 // jQuery(...).bind("mouseover mouseout", fn); 2478 jQuery.each(types.split(/\s+/), function(index, type) { 2479 // Namespaced event handlers 2480 var namespaces = type.split("."); 2481 type = namespaces.shift(); 2482 handler.type = namespaces.slice().sort().join("."); 2483 2484 // Get the current list of functions bound to this event 2485 var handlers = events[type]; 2486 2487 if ( jQuery.event.specialAll[type] ) 2488 jQuery.event.specialAll[type].setup.call(elem, data, namespaces); 2489 2490 // Init the event handler queue 2491 if (!handlers) { 2492 handlers = events[type] = {}; 2493 2494 // Check for a special event handler 2495 // Only use addEventListener/attachEvent if the special 2496 // events handler returns false 2497 if ( !jQuery.event.special[type] || jQuery.event.special[type].setup.call(elem, data, namespaces) === false ) { 2498 // Bind the global event handler to the element 2499 if (elem.addEventListener) 2500 elem.addEventListener(type, handle, false); 2501 else if (elem.attachEvent) 2502 elem.attachEvent("on" + type, handle); 2503 } 2504 } 2505 2506 // Add the function to the element's handler list 2507 handlers[handler.guid] = handler; 2508 2509 // Keep track of which events have been used, for global triggering 2510 jQuery.event.global[type] = true; 2511 }); 2512 2513 // Nullify elem to prevent memory leaks in IE 2514 elem = null; 2515 }, 2516 2517 guid: 1, 2518 global: {}, 2519 2520 // Detach an event or set of events from an element 2521 remove: function(elem, types, handler) { 2522 // don't do events on text and comment nodes 2523 if ( elem.nodeType == 3 || elem.nodeType == 8 ) 2524 return; 2525 2526 var events = jQuery.data(elem, "events"), ret, index; 2527 2528 if ( events ) { 2529 // Unbind all events for the element 2530 if ( types === undefined || (typeof types === "string" && types.charAt(0) == ".") ) 2531 for ( var type in events ) 2532 this.remove( elem, type + (types || "") ); 2533 else { 2534 // types is actually an event object here 2535 if ( types.type ) { 2536 handler = types.handler; 2537 types = types.type; 2538 } 2539 2540 // Handle multiple events seperated by a space 2541 // jQuery(...).unbind("mouseover mouseout", fn); 2542 jQuery.each(types.split(/\s+/), function(index, type){ 2543 // Namespaced event handlers 2544 var namespaces = type.split("."); 2545 type = namespaces.shift(); 2546 var namespace = RegExp("(^|\\.)" + namespaces.slice().sort().join(".*\\.") + "(\\.|$)"); 2547 2548 if ( events[type] ) { 2549 // remove the given handler for the given type 2550 if ( handler ) 2551 delete events[type][handler.guid]; 2552 2553 // remove all handlers for the given type 2554 else 2555 for ( var handle in events[type] ) 2556 // Handle the removal of namespaced events 2557 if ( namespace.test(events[type][handle].type) ) 2558 delete events[type][handle]; 2559 2560 if ( jQuery.event.specialAll[type] ) 2561 jQuery.event.specialAll[type].teardown.call(elem, namespaces); 2562 2563 // remove generic event handler if no more handlers exist 2564 for ( ret in events[type] ) break; 2565 if ( !ret ) { 2566 if ( !jQuery.event.special[type] || jQuery.event.special[type].teardown.call(elem, namespaces) === false ) { 2567 if (elem.removeEventListener) 2568 elem.removeEventListener(type, jQuery.data(elem, "handle"), false); 2569 else if (elem.detachEvent) 2570 elem.detachEvent("on" + type, jQuery.data(elem, "handle")); 2571 } 2572 ret = null; 2573 delete events[type]; 2574 } 2575 } 2576 }); 2577 } 2578 2579 // Remove the expando if it's no longer used 2580 for ( ret in events ) break; 2581 if ( !ret ) { 2582 var handle = jQuery.data( elem, "handle" ); 2583 if ( handle ) handle.elem = null; 2584 jQuery.removeData( elem, "events" ); 2585 jQuery.removeData( elem, "handle" ); 2586 } 2587 } 2588 }, 2589 2590 // bubbling is internal 2591 trigger: function( event, data, elem, bubbling ) { 2592 // Event object or event type 2593 var type = event.type || event; 2594 2595 if( !bubbling ){ 2596 event = typeof event === "object" ? 2597 // jQuery.Event object 2598 event[expando] ? event : 2599 // Object literal 2600 jQuery.extend( jQuery.Event(type), event ) : 2601 // Just the event type (string) 2602 jQuery.Event(type); 2603 2604 if ( type.indexOf("!") >= 0 ) { 2605 event.type = type = type.slice(0, -1); 2606 event.exclusive = true; 2607 } 2608 2609 // Handle a global trigger 2610 if ( !elem ) { 2611 // Don't bubble custom events when global (to avoid too much overhead) 2612 event.stopPropagation(); 2613 // Only trigger if we've ever bound an event for it 2614 if ( this.global[type] ) 2615 jQuery.each( jQuery.cache, function(){ 2616 if ( this.events && this.events[type] ) 2617 jQuery.event.trigger( event, data, this.handle.elem ); 2618 }); 2619 } 2620 2621 // Handle triggering a single element 2622 2623 // don't do events on text and comment nodes 2624 if ( !elem || elem.nodeType == 3 || elem.nodeType == 8 ) 2625 return undefined; 2626 2627 // Clean up in case it is reused 2628 event.result = undefined; 2629 event.target = elem; 2630 2631 // Clone the incoming data, if any 2632 data = jQuery.makeArray(data); 2633 data.unshift( event ); 2634 } 2635 2636 event.currentTarget = elem; 2637 2638 // Trigger the event, it is assumed that "handle" is a function 2639 var handle = jQuery.data(elem, "handle"); 2640 if ( handle ) 2641 handle.apply( elem, data ); 2642 2643 // Handle triggering native .onfoo handlers (and on links since we don't call .click() for links) 2644 if ( (!elem[type] || (jQuery.nodeName(elem, 'a') && type == "click")) && elem["on"+type] && elem["on"+type].apply( elem, data ) === false ) 2645 event.result = false; 2646 2647 // Trigger the native events (except for clicks on links) 2648 if ( !bubbling && elem[type] && !event.isDefaultPrevented() && !(jQuery.nodeName(elem, 'a') && type == "click") ) { 2649 this.triggered = true; 2650 try { 2651 elem[ type ](); 2652 // prevent IE from throwing an error for some hidden elements 2653 } catch (e) {} 2654 } 2655 2656 this.triggered = false; 2657 2658 if ( !event.isPropagationStopped() ) { 2659 var parent = elem.parentNode || elem.ownerDocument; 2660 if ( parent ) 2661 jQuery.event.trigger(event, data, parent, true); 2662 } 2663 }, 2664 2665 handle: function(event) { 2666 // returned undefined or false 2667 var all, handlers; 2668 2669 event = arguments[0] = jQuery.event.fix( event || window.event ); 2670 event.currentTarget = this; 2671 2672 // Namespaced event handlers 2673 var namespaces = event.type.split("."); 2674 event.type = namespaces.shift(); 2675 2676 // Cache this now, all = true means, any handler 2677 all = !namespaces.length && !event.exclusive; 2678 2679 var namespace = RegExp("(^|\\.)" + namespaces.slice().sort().join(".*\\.") + "(\\.|$)"); 2680 2681 handlers = ( jQuery.data(this, "events") || {} )[event.type]; 2682 2683 for ( var j in handlers ) { 2684 var handler = handlers[j]; 2685 2686 // Filter the functions by class 2687 if ( all || namespace.test(handler.type) ) { 2688 // Pass in a reference to the handler function itself 2689 // So that we can later remove it 2690 event.handler = handler; 2691 event.data = handler.data; 2692 2693 var ret = handler.apply(this, arguments); 2694 2695 if( ret !== undefined ){ 2696 event.result = ret; 2697 if ( ret === false ) { 2698 event.preventDefault(); 2699 event.stopPropagation(); 2700 } 2701 } 2702 2703 if( event.isImmediatePropagationStopped() ) 2704 break; 2705 2706 } 2707 } 2708 }, 2709 2710 props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "), 2711 2712 fix: function(event) { 2713 if ( event[expando] ) 2714 return event; 2715 2716 // store a copy of the original event object 2717 // and "clone" to set read-only properties 2718 var originalEvent = event; 2719 event = jQuery.Event( originalEvent ); 2720 2721 for ( var i = this.props.length, prop; i; ){ 2722 prop = this.props[ --i ]; 2723 event[ prop ] = originalEvent[ prop ]; 2724 } 2725 2726 // Fix target property, if necessary 2727 if ( !event.target ) 2728 event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either 2729 2730 // check if target is a textnode (safari) 2731 if ( event.target.nodeType == 3 ) 2732 event.target = event.target.parentNode; 2733 2734 // Add relatedTarget, if necessary 2735 if ( !event.relatedTarget && event.fromElement ) 2736 event.relatedTarget = event.fromElement == event.target ? event.toElement : event.fromElement; 2737 2738 // Calculate pageX/Y if missing and clientX/Y available 2739 if ( event.pageX == null && event.clientX != null ) { 2740 var doc = document.documentElement, body = document.body; 2741 event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc.clientLeft || 0); 2742 event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc.clientTop || 0); 2743 } 2744 2745 // Add which for key events 2746 if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) ) 2747 event.which = event.charCode || event.keyCode; 2748 2749 // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs) 2750 if ( !event.metaKey && event.ctrlKey ) 2751 event.metaKey = event.ctrlKey; 2752 2753 // Add which for click: 1 == left; 2 == middle; 3 == right 2754 // Note: button is not normalized, so don't use it 2755 if ( !event.which && event.button ) 2756 event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) )); 2757 2758 return event; 2759 }, 2760 2761 proxy: function( fn, proxy ){ 2762 proxy = proxy || function(){ return fn.apply(this, arguments); }; 2763 // Set the guid of unique handler to the same of original handler, so it can be removed 2764 proxy.guid = fn.guid = fn.guid || proxy.guid || this.guid++; 2765 // So proxy can be declared as an argument 2766 return proxy; 2767 }, 2768 2769 special: { 2770 ready: { 2771 // Make sure the ready event is setup 2772 setup: bindReady, 2773 teardown: function() {} 2774 } 2775 }, 2776 2777 specialAll: { 2778 live: { 2779 setup: function( selector, namespaces ){ 2780 jQuery.event.add( this, namespaces[0], liveHandler ); 2781 }, 2782 teardown: function( namespaces ){ 2783 if ( namespaces.length ) { 2784 var remove = 0, name = RegExp("(^|\\.)" + namespaces[0] + "(\\.|$)"); 2785 2786 jQuery.each( (jQuery.data(this, "events").live || {}), function(){ 2787 if ( name.test(this.type) ) 2788 remove++; 2789 }); 2790 2791 if ( remove < 1 ) 2792 jQuery.event.remove( this, namespaces[0], liveHandler ); 2793 } 2794 } 2795 } 2796 } 2797 }; 2798 2799 jQuery.Event = function( src ){ 2800 // Allow instantiation without the 'new' keyword 2801 if( !this.preventDefault ) 2802 return new jQuery.Event(src); 2803 2804 // Event object 2805 if( src && src.type ){ 2806 this.originalEvent = src; 2807 this.type = src.type; 2808 // Event type 2809 }else 2810 this.type = src; 2811 2812 // timeStamp is buggy for some events on Firefox(#3843) 2813 // So we won't rely on the native value 2814 this.timeStamp = now(); 2815 2816 // Mark it as fixed 2817 this[expando] = true; 2818 }; 2819 2820 function returnFalse(){ 2821 return false; 2822 } 2823 function returnTrue(){ 2824 return true; 2825 } 2826 2827 // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding 2828 // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html 2829 jQuery.Event.prototype = { 2830 preventDefault: function() { 2831 this.isDefaultPrevented = returnTrue; 2832 2833 var e = this.originalEvent; 2834 if( !e ) 2835 return; 2836 // if preventDefault exists run it on the original event 2837 if (e.preventDefault) 2838 e.preventDefault(); 2839 // otherwise set the returnValue property of the original event to false (IE) 2840 e.returnValue = false; 2841 }, 2842 stopPropagation: function() { 2843 this.isPropagationStopped = returnTrue; 2844 2845 var e = this.originalEvent; 2846 if( !e ) 2847 return; 2848 // if stopPropagation exists run it on the original event 2849 if (e.stopPropagation) 2850 e.stopPropagation(); 2851 // otherwise set the cancelBubble property of the original event to true (IE) 2852 e.cancelBubble = true; 2853 }, 2854 stopImmediatePropagation:function(){ 2855 this.isImmediatePropagationStopped = returnTrue; 2856 this.stopPropagation(); 2857 }, 2858 isDefaultPrevented: returnFalse, 2859 isPropagationStopped: returnFalse, 2860 isImmediatePropagationStopped: returnFalse 2861 }; 2862 // Checks if an event happened on an element within another element 2863 // Used in jQuery.event.special.mouseenter and mouseleave handlers 2864 var withinElement = function(event) { 2865 // Check if mouse(over|out) are still within the same parent element 2866 var parent = event.relatedTarget; 2867 // Traverse up the tree 2868 while ( parent && parent != this ) 2869 try { parent = parent.parentNode; } 2870 catch(e) { parent = this; } 2871 2872 if( parent != this ){ 2873 // set the correct event type 2874 event.type = event.data; 2875 // handle event if we actually just moused on to a non sub-element 2876 jQuery.event.handle.apply( this, arguments ); 2877 } 2878 }; 2879 2880 jQuery.each({ 2881 mouseover: 'mouseenter', 2882 mouseout: 'mouseleave' 2883 }, function( orig, fix ){ 2884 jQuery.event.special[ fix ] = { 2885 setup: function(){ 2886 jQuery.event.add( this, orig, withinElement, fix ); 2887 }, 2888 teardown: function(){ 2889 jQuery.event.remove( this, orig, withinElement ); 2890 } 2891 }; 2892 }); 2893 2894 jQuery.fn.extend({ 2895 bind: function( type, data, fn ) { 2896 return type == "unload" ? this.one(type, data, fn) : this.each(function(){ 2897 jQuery.event.add( this, type, fn || data, fn && data ); 2898 }); 2899 }, 2900 2901 one: function( type, data, fn ) { 2902 var one = jQuery.event.proxy( fn || data, function(event) { 2903 jQuery(this).unbind(event, one); 2904 return (fn || data).apply( this, arguments ); 2905 }); 2906 return this.each(function(){ 2907 jQuery.event.add( this, type, one, fn && data); 2908 }); 2909 }, 2910 2911 unbind: function( type, fn ) { 2912 return this.each(function(){ 2913 jQuery.event.remove( this, type, fn ); 2914 }); 2915 }, 2916 2917 trigger: function( type, data ) { 2918 return this.each(function(){ 2919 jQuery.event.trigger( type, data, this ); 2920 }); 2921 }, 2922 2923 triggerHandler: function( type, data ) { 2924 if( this[0] ){ 2925 var event = jQuery.Event(type); 2926 event.preventDefault(); 2927 event.stopPropagation(); 2928 jQuery.event.trigger( event, data, this[0] ); 2929 return event.result; 2930 } 2931 }, 2932 2933 toggle: function( fn ) { 2934 // Save reference to arguments for access in closure 2935 var args = arguments, i = 1; 2936 2937 // link all the functions, so any of them can unbind this click handler 2938 while( i < args.length ) 2939 jQuery.event.proxy( fn, args[i++] ); 2940 2941 return this.click( jQuery.event.proxy( fn, function(event) { 2942 // Figure out which function to execute 2943 this.lastToggle = ( this.lastToggle || 0 ) % i; 2944 2945 // Make sure that clicks stop 2946 event.preventDefault(); 2947 2948 // and execute the function 2949 return args[ this.lastToggle++ ].apply( this, arguments ) || false; 2950 })); 2951 }, 2952 2953 hover: function(fnOver, fnOut) { 2954 return this.mouseenter(fnOver).mouseleave(fnOut); 2955 }, 2956 2957 ready: function(fn) { 2958 // Attach the listeners 2959 bindReady(); 2960 2961 // If the DOM is already ready 2962 if ( jQuery.isReady ) 2963 // Execute the function immediately 2964 fn.call( document, jQuery ); 2965 2966 // Otherwise, remember the function for later 2967 else 2968 // Add the function to the wait list 2969 jQuery.readyList.push( fn ); 2970 2971 return this; 2972 }, 2973 2974 live: function( type, fn ){ 2975 var proxy = jQuery.event.proxy( fn ); 2976 proxy.guid += this.selector + type; 2977 2978 jQuery(document).bind( liveConvert(type, this.selector), this.selector, proxy ); 2979 2980 return this; 2981 }, 2982 2983 die: function( type, fn ){ 2984 jQuery(document).unbind( liveConvert(type, this.selector), fn ? { guid: fn.guid + this.selector + type } : null ); 2985 return this; 2986 } 2987 }); 2988 2989 function liveHandler( event ){ 2990 var check = RegExp("(^|\\.)" + event.type + "(\\.|$)"), 2991 stop = true, 2992 elems = []; 2993 2994 jQuery.each(jQuery.data(this, "events").live || [], function(i, fn){ 2995 if ( check.test(fn.type) ) { 2996 var elem = jQuery(event.target).closest(fn.data)[0]; 2997 if ( elem ) 2998 elems.push({ elem: elem, fn: fn }); 2999 } 3000 }); 3001 3002 elems.sort(function(a,b) { 3003 return jQuery.data(a.elem, "closest") - jQuery.data(b.elem, "closest"); 3004 }); 3005 3006 jQuery.each(elems, function(){ 3007 if ( this.fn.call(this.elem, event, this.fn.data) === false ) 3008 return (stop = false); 3009 }); 3010 3011 return stop; 3012 } 3013 3014 function liveConvert(type, selector){ 3015 return ["live", type, selector.replace(/\./g, "`").replace(/ /g, "|")].join("."); 3016 } 3017 3018 jQuery.extend({ 3019 isReady: false, 3020 readyList: [], 3021 // Handle when the DOM is ready 3022 ready: function() { 3023 // Make sure that the DOM is not already loaded 3024 if ( !jQuery.isReady ) { 3025 // Remember that the DOM is ready 3026 jQuery.isReady = true; 3027 3028 // If there are functions bound, to execute 3029 if ( jQuery.readyList ) { 3030 // Execute all of them 3031 jQuery.each( jQuery.readyList, function(){ 3032 this.call( document, jQuery ); 3033 }); 3034 3035 // Reset the list of functions 3036 jQuery.readyList = null; 3037 } 3038 3039 // Trigger any bound ready events 3040 jQuery(document).triggerHandler("ready"); 3041 } 3042 } 3043 }); 3044 3045 var readyBound = false; 3046 3047 function bindReady(){ 3048 if ( readyBound ) return; 3049 readyBound = true; 3050 3051 // Mozilla, Opera and webkit nightlies currently support this event 3052 if ( document.addEventListener ) { 3053 // Use the handy event callback 3054 document.addEventListener( "DOMContentLoaded", function(){ 3055 document.removeEventListener( "DOMContentLoaded", arguments.callee, false ); 3056 jQuery.ready(); 3057 }, false ); 3058 3059 // If IE event model is used 3060 } else if ( document.attachEvent ) { 3061 // ensure firing before onload, 3062 // maybe late but safe also for iframes 3063 document.attachEvent("onreadystatechange", function(){ 3064 if ( document.readyState === "complete" ) { 3065 document.detachEvent( "onreadystatechange", arguments.callee ); 3066 jQuery.ready(); 3067 } 3068 }); 3069 3070 // If IE and not an iframe 3071 // continually check to see if the document is ready 3072 if ( document.documentElement.doScroll && window == window.top ) (function(){ 3073 if ( jQuery.isReady ) return; 3074 3075 try { 3076 // If IE is used, use the trick by Diego Perini 3077 // http://javascript.nwbox.com/IEContentLoaded/ 3078 document.documentElement.doScroll("left"); 3079 } catch( error ) { 3080 setTimeout( arguments.callee, 0 ); 3081 return; 3082 } 3083 3084 // and execute any waiting functions 3085 jQuery.ready(); 3086 })(); 3087 } 3088 3089 // A fallback to window.onload, that will always work 3090 jQuery.event.add( window, "load", jQuery.ready ); 3091 } 3092 3093 jQuery.each( ("blur,focus,load,resize,scroll,unload,click,dblclick," + 3094 "mousedown,mouseup,mousemove,mouseover,mouseout,mouseenter,mouseleave," + 3095 "change,select,submit,keydown,keypress,keyup,error").split(","), function(i, name){ 3096 3097 // Handle event binding 3098 jQuery.fn[name] = function(fn){ 3099 return fn ? this.bind(name, fn) : this.trigger(name); 3100 }; 3101 }); 3102 3103 // Prevent memory leaks in IE 3104 // And prevent errors on refresh with events like mouseover in other browsers 3105 // Window isn't included so as not to unbind existing unload events 3106 jQuery( window ).bind( 'unload', function(){ 3107 for ( var id in jQuery.cache ) 3108 // Skip the window 3109 if ( id != 1 && jQuery.cache[ id ].handle ) 3110 jQuery.event.remove( jQuery.cache[ id ].handle.elem ); 3111 }); 3112 (function(){ 3113 3114 jQuery.support = {}; 3115 3116 var root = document.documentElement, 3117 script = document.createElement("script"), 3118 div = document.createElement("div"), 3119 id = "script" + (new Date).getTime(); 3120 3121 div.style.display = "none"; 3122 div.innerHTML = ' <link/><table></table><a href="/a" style="color:red;float:left;opacity:.5;">a</a><select><option>text</option></select><object><param/></object>'; 3123 3124 var all = div.getElementsByTagName("*"), 3125 a = div.getElementsByTagName("a")[0]; 3126 3127 // Can't get basic test support 3128 if ( !all || !all.length || !a ) { 3129 return; 3130 } 3131 3132 jQuery.support = { 3133 // IE strips leading whitespace when .innerHTML is used 3134 leadingWhitespace: div.firstChild.nodeType == 3, 3135 3136 // Make sure that tbody elements aren't automatically inserted 3137 // IE will insert them into empty tables 3138 tbody: !div.getElementsByTagName("tbody").length, 3139 3140 // Make sure that you can get all elements in an <object> element 3141 // IE 7 always returns no results 3142 objectAll: !!div.getElementsByTagName("object")[0] 3143 .getElementsByTagName("*").length, 3144 3145 // Make sure that link elements get serialized correctly by innerHTML 3146 // This requires a wrapper element in IE 3147 htmlSerialize: !!div.getElementsByTagName("link").length, 3148 3149 // Get the style information from getAttribute 3150 // (IE uses .cssText insted) 3151 style: /red/.test( a.getAttribute("style") ), 3152 3153 // Make sure that URLs aren't manipulated 3154 // (IE normalizes it by default) 3155 hrefNormalized: a.getAttribute("href") === "/a", 3156 3157 // Make sure that element opacity exists 3158 // (IE uses filter instead) 3159 opacity: a.style.opacity === "0.5", 3160 3161 // Verify style float existence 3162 // (IE uses styleFloat instead of cssFloat) 3163 cssFloat: !!a.style.cssFloat, 3164 3165 // Will be defined later 3166 scriptEval: false, 3167 noCloneEvent: true, 3168 boxModel: null 3169 }; 3170 3171 script.type = "text/javascript"; 3172 try { 3173 script.appendChild( document.createTextNode( "window." + id + "=1;" ) ); 3174 } catch(e){} 3175 3176 root.insertBefore( script, root.firstChild ); 3177 3178 // Make sure that the execution of code works by injecting a script 3179 // tag with appendChild/createTextNode 3180 // (IE doesn't support this, fails, and uses .text instead) 3181 if ( window[ id ] ) { 3182 jQuery.support.scriptEval = true; 3183 delete window[ id ]; 3184 } 3185 3186 root.removeChild( script ); 3187 3188 if ( div.attachEvent && div.fireEvent ) { 3189 div.attachEvent("onclick", function(){ 3190 // Cloning a node shouldn't copy over any 3191 // bound event handlers (IE does this) 3192 jQuery.support.noCloneEvent = false; 3193 div.detachEvent("onclick", arguments.callee); 3194 }); 3195 div.cloneNode(true).fireEvent("onclick"); 3196 } 3197 3198 // Figure out if the W3C box model works as expected 3199 // document.body must exist before we can do this 3200 jQuery(function(){ 3201 var div = document.createElement("div"); 3202 div.style.width = div.style.paddingLeft = "1px"; 3203 3204 document.body.appendChild( div ); 3205 jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2; 3206 document.body.removeChild( div ).style.display = 'none'; 3207 }); 3208 })(); 3209 3210 var styleFloat = jQuery.support.cssFloat ? "cssFloat" : "styleFloat"; 3211 3212 jQuery.props = { 3213 "for": "htmlFor", 3214 "class": "className", 3215 "float": styleFloat, 3216 cssFloat: styleFloat, 3217 styleFloat: styleFloat, 3218 readonly: "readOnly", 3219 maxlength: "maxLength", 3220 cellspacing: "cellSpacing", 3221 rowspan: "rowSpan", 3222 tabindex: "tabIndex" 3223 }; 3224 jQuery.fn.extend({ 3225 // Keep a copy of the old load 3226 _load: jQuery.fn.load, 3227 3228 load: function( url, params, callback ) { 3229 if ( typeof url !== "string" ) 3230 return this._load( url ); 3231 3232 var off = url.indexOf(" "); 3233 if ( off >= 0 ) { 3234 var selector = url.slice(off, url.length); 3235 url = url.slice(0, off); 3236 } 3237 3238 // Default to a GET request 3239 var type = "GET"; 3240 3241 // If the second parameter was provided 3242 if ( params ) 3243 // If it's a function 3244 if ( jQuery.isFunction( params ) ) { 3245 // We assume that it's the callback 3246 callback = params; 3247 params = null; 3248 3249 // Otherwise, build a param string 3250 } else if( typeof params === "object" ) { 3251 params = jQuery.param( params ); 3252 type = "POST"; 3253 } 3254 3255 var self = this; 3256 3257 // Request the remote document 3258 jQuery.ajax({ 3259 url: url, 3260 type: type, 3261 dataType: "html", 3262 data: params, 3263 complete: function(res, status){ 3264 // If successful, inject the HTML into all the matched elements 3265 if ( status == "success" || status == "notmodified" ) 3266 // See if a selector was specified 3267 self.html( selector ? 3268 // Create a dummy div to hold the results 3269 jQuery("<div/>") 3270 // inject the contents of the document in, removing the scripts 3271 // to avoid any 'Permission Denied' errors in IE 3272 .append(res.responseText.replace(/<script(.|\s)*?\/script>/g, "")) 3273 3274 // Locate the specified elements 3275 .find(selector) : 3276 3277 // If not, just inject the full result 3278 res.responseText ); 3279 3280 if( callback ) 3281 self.each( callback, [res.responseText, status, res] ); 3282 } 3283 }); 3284 return this; 3285 }, 3286 3287 serialize: function() { 3288 return jQuery.param(this.serializeArray()); 3289 }, 3290 serializeArray: function() { 3291 return this.map(function(){ 3292 return this.elements ? jQuery.makeArray(this.elements) : this; 3293 }) 3294 .filter(function(){ 3295 return this.name && !this.disabled && 3296 (this.checked || /select|textarea/i.test(this.nodeName) || 3297 /text|hidden|password|search/i.test(this.type)); 3298 }) 3299 .map(function(i, elem){ 3300 var val = jQuery(this).val(); 3301 return val == null ? null : 3302 jQuery.isArray(val) ? 3303 jQuery.map( val, function(val, i){ 3304 return {name: elem.name, value: val}; 3305 }) : 3306 {name: elem.name, value: val}; 3307 }).get(); 3308 } 3309 }); 3310 3311 // Attach a bunch of functions for handling common AJAX events 3312 jQuery.each( "ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","), function(i,o){ 3313 jQuery.fn[o] = function(f){ 3314 return this.bind(o, f); 3315 }; 3316 }); 3317 3318 var jsc = now(); 3319 3320 jQuery.extend({ 3321 3322 get: function( url, data, callback, type ) { 3323 // shift arguments if data argument was ommited 3324 if ( jQuery.isFunction( data ) ) { 3325 callback = data; 3326 data = null; 3327 } 3328 3329 return jQuery.ajax({ 3330 type: "GET", 3331 url: url, 3332 data: data, 3333 success: callback, 3334 dataType: type 3335 }); 3336 }, 3337 3338 getScript: function( url, callback ) { 3339 return jQuery.get(url, null, callback, "script"); 3340 }, 3341 3342 getJSON: function( url, data, callback ) { 3343 return jQuery.get(url, data, callback, "json"); 3344 }, 3345 3346 post: function( url, data, callback, type ) { 3347 if ( jQuery.isFunction( data ) ) { 3348 callback = data; 3349 data = {}; 3350 } 3351 3352 return jQuery.ajax({ 3353 type: "POST", 3354 url: url, 3355 data: data, 3356 success: callback, 3357 dataType: type 3358 }); 3359 }, 3360 3361 ajaxSetup: function( settings ) { 3362 jQuery.extend( jQuery.ajaxSettings, settings ); 3363 }, 3364 3365 ajaxSettings: { 3366 url: location.href, 3367 global: true, 3368 type: "GET", 3369 contentType: "application/x-www-form-urlencoded", 3370 processData: true, 3371 async: true, 3372 /* 3373 timeout: 0, 3374 data: null, 3375 username: null, 3376 password: null, 3377 */ 3378 // Create the request object; Microsoft failed to properly 3379 // implement the XMLHttpRequest in IE7, so we use the ActiveXObject when it is available 3380 // This function can be overriden by calling jQuery.ajaxSetup 3381 xhr:function(){ 3382 return window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest(); 3383 }, 3384 accepts: { 3385 xml: "application/xml, text/xml", 3386 html: "text/html", 3387 script: "text/javascript, application/javascript", 3388 json: "application/json, text/javascript", 3389 text: "text/plain", 3390 _default: "*/*" 3391 } 3392 }, 3393 3394 // Last-Modified header cache for next request 3395 lastModified: {}, 3396 3397 ajax: function( s ) { 3398 // Extend the settings, but re-extend 's' so that it can be 3399 // checked again later (in the test suite, specifically) 3400 s = jQuery.extend(true, s, jQuery.extend(true, {}, jQuery.ajaxSettings, s)); 3401 3402 var jsonp, jsre = /=\?(&|$)/g, status, data, 3403 type = s.type.toUpperCase(); 3404 3405 // convert data if not already a string 3406 if ( s.data && s.processData && typeof s.data !== "string" ) 3407 s.data = jQuery.param(s.data); 3408 3409 // Handle JSONP Parameter Callbacks 3410 if ( s.dataType == "jsonp" ) { 3411 if ( type == "GET" ) { 3412 if ( !s.url.match(jsre) ) 3413 s.url += (s.url.match(/\?/) ? "&" : "?") + (s.jsonp || "callback") + "=?"; 3414 } else if ( !s.data || !s.data.match(jsre) ) 3415 s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?"; 3416 s.dataType = "json"; 3417 } 3418 3419 // Build temporary JSONP function 3420 if ( s.dataType == "json" && (s.data && s.data.match(jsre) || s.url.match(jsre)) ) { 3421 jsonp = "jsonp" + jsc++; 3422 3423 // Replace the =? sequence both in the query string and the data 3424 if ( s.data ) 3425 s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1"); 3426 s.url = s.url.replace(jsre, "=" + jsonp + "$1"); 3427 3428 // We need to make sure 3429 // that a JSONP style response is executed properly 3430 s.dataType = "script"; 3431 3432 // Handle JSONP-style loading 3433 window[ jsonp ] = function(tmp){ 3434 data = tmp; 3435 success(); 3436 complete(); 3437 // Garbage collect 3438 window[ jsonp ] = undefined; 3439 try{ delete window[ jsonp ]; } catch(e){} 3440 if ( head ) 3441 head.removeChild( script ); 3442 }; 3443 } 3444 3445 if ( s.dataType == "script" && s.cache == null ) 3446 s.cache = false; 3447 3448 if ( s.cache === false && type == "GET" ) { 3449 var ts = now(); 3450 // try replacing _= if it is there 3451 var ret = s.url.replace(/(\?|&)_=.*?(&|$)/, "$1_=" + ts + "$2"); 3452 // if nothing was replaced, add timestamp to the end 3453 s.url = ret + ((ret == s.url) ? (s.url.match(/\?/) ? "&" : "?") + "_=" + ts : ""); 3454 } 3455 3456 // If data is available, append data to url for get requests 3457 if ( s.data && type == "GET" ) { 3458 s.url += (s.url.match(/\?/) ? "&" : "?") + s.data; 3459 3460 // IE likes to send both get and post data, prevent this 3461 s.data = null; 3462 } 3463 3464 // Watch for a new set of requests 3465 if ( s.global && ! jQuery.active++ ) 3466 jQuery.event.trigger( "ajaxStart" ); 3467 3468 // Matches an absolute URL, and saves the domain 3469 var parts = /^(\w+:)?\/\/([^\/?#]+)/.exec( s.url ); 3470 3471 // If we're requesting a remote document 3472 // and trying to load JSON or Script with a GET 3473 if ( s.dataType == "script" && type == "GET" && parts 3474 && ( parts[1] && parts[1] != location.protocol || parts[2] != location.host )){ 3475 3476 var head = document.getElementsByTagName("head")[0]; 3477 var script = document.createElement("script"); 3478 script.src = s.url; 3479 if (s.scriptCharset) 3480 script.charset = s.scriptCharset; 3481 3482 // Handle Script loading 3483 if ( !jsonp ) { 3484 var done = false; 3485 3486 // Attach handlers for all browsers 3487 script.onload = script.onreadystatechange = function(){ 3488 if ( !done && (!this.readyState || 3489 this.readyState == "loaded" || this.readyState == "complete") ) { 3490 done = true; 3491 success(); 3492 complete(); 3493 3494 // Handle memory leak in IE 3495 script.onload = script.onreadystatechange = null; 3496 head.removeChild( script ); 3497 } 3498 }; 3499 } 3500 3501 head.appendChild(script); 3502 3503 // We handle everything using the script element injection 3504 return undefined; 3505 } 3506 3507 var requestDone = false; 3508 3509 // Create the request object 3510 var xhr = s.xhr(); 3511 3512 // Open the socket 3513 // Passing null username, generates a login popup on Opera (#2865) 3514 if( s.username ) 3515 xhr.open(type, s.url, s.async, s.username, s.password); 3516 else 3517 xhr.open(type, s.url, s.async); 3518 3519 // Need an extra try/catch for cross domain requests in Firefox 3 3520 try { 3521 // Set the correct header, if data is being sent 3522 if ( s.data ) 3523 xhr.setRequestHeader("Content-Type", s.contentType); 3524 3525 // Set the If-Modified-Since header, if ifModified mode. 3526 if ( s.ifModified ) 3527 xhr.setRequestHeader("If-Modified-Since", 3528 jQuery.lastModified[s.url] || "Thu, 01 Jan 1970 00:00:00 GMT" ); 3529 3530 // Set header so the called script knows that it's an XMLHttpRequest 3531 xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); 3532 3533 // Set the Accepts header for the server, depending on the dataType 3534 xhr.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ? 3535 s.accepts[ s.dataType ] + ", */*" : 3536 s.accepts._default ); 3537 } catch(e){} 3538 3539 // Allow custom headers/mimetypes and early abort 3540 if ( s.beforeSend && s.beforeSend(xhr, s) === false ) { 3541 // Handle the global AJAX counter 3542 if ( s.global && ! --jQuery.active ) 3543 jQuery.event.trigger( "ajaxStop" ); 3544 // close opended socket 3545 xhr.abort(); 3546 return false; 3547 } 3548 3549 if ( s.global ) 3550 jQuery.event.trigger("ajaxSend", [xhr, s]); 3551 3552 // Wait for a response to come back 3553 var onreadystatechange = function(isTimeout){ 3554 // The request was aborted, clear the interval and decrement jQuery.active 3555 if (xhr.readyState == 0) { 3556 if (ival) { 3557 // clear poll interval 3558 clearInterval(ival); 3559 ival = null; 3560 // Handle the global AJAX counter 3561 if ( s.global && ! --jQuery.active ) 3562 jQuery.event.trigger( "ajaxStop" ); 3563 } 3564 // The transfer is complete and the data is available, or the request timed out 3565 } else if ( !requestDone && xhr && (xhr.readyState == 4 || isTimeout == "timeout") ) { 3566 requestDone = true; 3567 3568 // clear poll interval 3569 if (ival) { 3570 clearInterval(ival); 3571 ival = null; 3572 } 3573 3574 status = isTimeout == "timeout" ? "timeout" : 3575 !jQuery.httpSuccess( xhr ) ? "error" : 3576 s.ifModified && jQuery.httpNotModified( xhr, s.url ) ? "notmodified" : 3577 "success"; 3578 3579 if ( status == "success" ) { 3580 // Watch for, and catch, XML document parse errors 3581 try { 3582 // process the data (runs the xml through httpData regardless of callback) 3583 data = jQuery.httpData( xhr, s.dataType, s ); 3584 } catch(e) { 3585 status = "parsererror"; 3586 } 3587 } 3588 3589 // Make sure that the request was successful or notmodified 3590 if ( status == "success" ) { 3591 // Cache Last-Modified header, if ifModified mode. 3592 var modRes; 3593 try { 3594 modRes = xhr.getResponseHeader("Last-Modified"); 3595 } catch(e) {} // swallow exception thrown by FF if header is not available 3596 3597 if ( s.ifModified && modRes ) 3598 jQuery.lastModified[s.url] = modRes; 3599 3600 // JSONP handles its own success callback 3601 if ( !jsonp ) 3602 success(); 3603 } else 3604 jQuery.handleError(s, xhr, status); 3605 3606 // Fire the complete handlers 3607 complete(); 3608 3609 if ( isTimeout ) 3610 xhr.abort(); 3611 3612 // Stop memory leaks 3613 if ( s.async ) 3614 xhr = null; 3615 } 3616 }; 3617 3618 if ( s.async ) { 3619 // don't attach the handler to the request, just poll it instead 3620 var ival = setInterval(onreadystatechange, 13); 3621 3622 // Timeout checker 3623 if ( s.timeout > 0 ) 3624 setTimeout(function(){ 3625 // Check to see if the request is still happening 3626 if ( xhr && !requestDone ) 3627 onreadystatechange( "timeout" ); 3628 }, s.timeout); 3629 } 3630 3631 // Send the data 3632 try { 3633 xhr.send(s.data); 3634 } catch(e) { 3635 jQuery.handleError(s, xhr, null, e); 3636 } 3637 3638 // firefox 1.5 doesn't fire statechange for sync requests 3639 if ( !s.async ) 3640 onreadystatechange(); 3641 3642 function success(){ 3643 // If a local callback was specified, fire it and pass it the data 3644 if ( s.success ) 3645 s.success( data, status ); 3646 3647 // Fire the global callback 3648 if ( s.global ) 3649 jQuery.event.trigger( "ajaxSuccess", [xhr, s] ); 3650 } 3651 3652 function complete(){ 3653 // Process result 3654 if ( s.complete ) 3655 s.complete(xhr, status); 3656 3657 // The request was completed 3658 if ( s.global ) 3659 jQuery.event.trigger( "ajaxComplete", [xhr, s] ); 3660 3661 // Handle the global AJAX counter 3662 if ( s.global && ! --jQuery.active ) 3663 jQuery.event.trigger( "ajaxStop" ); 3664 } 3665 3666 // return XMLHttpRequest to allow aborting the request etc. 3667 return xhr; 3668 }, 3669 3670 handleError: function( s, xhr, status, e ) { 3671 // If a local callback was specified, fire it 3672 if ( s.error ) s.error( xhr, status, e ); 3673 3674 // Fire the global callback 3675 if ( s.global ) 3676 jQuery.event.trigger( "ajaxError", [xhr, s, e] ); 3677 }, 3678 3679 // Counter for holding the number of active queries 3680 active: 0, 3681 3682 // Determines if an XMLHttpRequest was successful or not 3683 httpSuccess: function( xhr ) { 3684 try { 3685 // IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450 3686 return !xhr.status && location.protocol == "file:" || 3687 ( xhr.status >= 200 && xhr.status < 300 ) || xhr.status == 304 || xhr.status == 1223; 3688 } catch(e){} 3689 return false; 3690 }, 3691 3692 // Determines if an XMLHttpRequest returns NotModified 3693 httpNotModified: function( xhr, url ) { 3694 try { 3695 var xhrRes = xhr.getResponseHeader("Last-Modified"); 3696 3697 // Firefox always returns 200. check Last-Modified date 3698 return xhr.status == 304 || xhrRes == jQuery.lastModified[url]; 3699 } catch(e){} 3700 return false; 3701 }, 3702 3703 httpData: function( xhr, type, s ) { 3704 var ct = xhr.getResponseHeader("content-type"), 3705 xml = type == "xml" || !type && ct && ct.indexOf("xml") >= 0, 3706 data = xml ? xhr.responseXML : xhr.responseText; 3707 3708 if ( xml && data.documentElement.tagName == "parsererror" ) 3709 throw "parsererror"; 3710 3711 // Allow a pre-filtering function to sanitize the response 3712 // s != null is checked to keep backwards compatibility 3713 if( s && s.dataFilter ) 3714 data = s.dataFilter( data, type ); 3715 3716 // The filter can actually parse the response 3717 if( typeof data === "string" ){ 3718 3719 // If the type is "script", eval it in global context 3720 if ( type == "script" ) 3721 jQuery.globalEval( data ); 3722 3723 // Get the JavaScript object, if JSON is used. 3724 if ( type == "json" ) 3725 data = window["eval"]("(" + data + ")"); 3726 } 3727 3728 return data; 3729 }, 3730 3731 // Serialize an array of form elements or a set of 3732 // key/values into a query string 3733 param: function( a ) { 3734 var s = [ ]; 3735 3736 function add( key, value ){ 3737 s[ s.length ] = encodeURIComponent(key) + '=' + encodeURIComponent(value); 3738 }; 3739 3740 // If an array was passed in, assume that it is an array 3741 // of form elements 3742 if ( jQuery.isArray(a) || a.jquery ) 3743 // Serialize the form elements 3744 jQuery.each( a, function(){ 3745 add( this.name, this.value ); 3746 }); 3747 3748 // Otherwise, assume that it's an object of key/value pairs 3749 else 3750 // Serialize the key/values 3751 for ( var j in a ) 3752 // If the value is an array then the key names need to be repeated 3753 if ( jQuery.isArray(a[j]) ) 3754 jQuery.each( a[j], function(){ 3755 add( j, this ); 3756 }); 3757 else 3758 add( j, jQuery.isFunction(a[j]) ? a[j]() : a[j] ); 3759 3760 // Return the resulting serialization 3761 return s.join("&").replace(/%20/g, "+"); 3762 } 3763 3764 }); 3765 var elemdisplay = {}, 3766 timerId, 3767 fxAttrs = [ 3768 // height animations 3769 [ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ], 3770 // width animations 3771 [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ], 3772 // opacity animations 3773 [ "opacity" ] 3774 ]; 3775 3776 function genFx( type, num ){ 3777 var obj = {}; 3778 jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function(){ 3779 obj[ this ] = type; 3780 }); 3781 return obj; 3782 } 3783 3784 jQuery.fn.extend({ 3785 show: function(speed,callback){ 3786 if ( speed ) { 3787 return this.animate( genFx("show", 3), speed, callback); 3788 } else { 3789 for ( var i = 0, l = this.length; i < l; i++ ){ 3790 var old = jQuery.data(this[i], "olddisplay"); 3791 3792 this[i].style.display = old || ""; 3793 3794 if ( jQuery.css(this[i], "display") === "none" ) { 3795 var tagName = this[i].tagName, display; 3796 3797 if ( elemdisplay[ tagName ] ) { 3798 display = elemdisplay[ tagName ]; 3799 } else { 3800 var elem = jQuery("<" + tagName + " />").appendTo("body"); 3801 3802 display = elem.css("display"); 3803 if ( display === "none" ) 3804 display = "block"; 3805 3806 elem.remove(); 3807 3808 elemdisplay[ tagName ] = display; 3809 } 3810 3811 jQuery.data(this[i], "olddisplay", display); 3812 } 3813 } 3814 3815 // Set the display of the elements in a second loop 3816 // to avoid the constant reflow 3817 for ( var i = 0, l = this.length; i < l; i++ ){ 3818 this[i].style.display = jQuery.data(this[i], "olddisplay") || ""; 3819 } 3820 3821 return this; 3822 } 3823 }, 3824 3825 hide: function(speed,callback){ 3826 if ( speed ) { 3827 return this.animate( genFx("hide", 3), speed, callback); 3828 } else { 3829 for ( var i = 0, l = this.length; i < l; i++ ){ 3830 var old = jQuery.data(this[i], "olddisplay"); 3831 if ( !old && old !== "none" ) 3832 jQuery.data(this[i], "olddisplay", jQuery.css(this[i], "display")); 3833 } 3834 3835 // Set the display of the elements in a second loop 3836 // to avoid the constant reflow 3837 for ( var i = 0, l = this.length; i < l; i++ ){ 3838 this[i].style.display = "none"; 3839 } 3840 3841 return this; 3842 } 3843 }, 3844 3845 // Save the old toggle function 3846 _toggle: jQuery.fn.toggle, 3847 3848 toggle: function( fn, fn2 ){ 3849 var bool = typeof fn === "boolean"; 3850 3851 return jQuery.isFunction(fn) && jQuery.isFunction(fn2) ? 3852 this._toggle.apply( this, arguments ) : 3853 fn == null || bool ? 3854 this.each(function(){ 3855 var state = bool ? fn : jQuery(this).is(":hidden"); 3856 jQuery(this)[ state ? "show" : "hide" ](); 3857 }) : 3858 this.animate(genFx("toggle", 3), fn, fn2); 3859 }, 3860 3861 fadeTo: function(speed,to,callback){ 3862 return this.animate({opacity: to}, speed, callback); 3863 }, 3864 3865 animate: function( prop, speed, easing, callback ) { 3866 var optall = jQuery.speed(speed, easing, callback); 3867 3868 return this[ optall.queue === false ? "each" : "queue" ](function(){ 3869 3870 var opt = jQuery.extend({}, optall), p, 3871 hidden = this.nodeType == 1 && jQuery(this).is(":hidden"), 3872 self = this; 3873 3874 for ( p in prop ) { 3875 if ( prop[p] == "hide" && hidden || prop[p] == "show" && !hidden ) 3876 return opt.complete.call(this); 3877 3878 if ( ( p == "height" || p == "width" ) && this.style ) { 3879 // Store display property 3880 opt.display = jQuery.css(this, "display"); 3881 3882 // Make sure that nothing sneaks out 3883 opt.overflow = this.style.overflow; 3884 } 3885 } 3886 3887 if ( opt.overflow != null ) 3888 this.style.overflow = "hidden"; 3889 3890 opt.curAnim = jQuery.extend({}, prop); 3891 3892 jQuery.each( prop, function(name, val){ 3893 var e = new jQuery.fx( self, opt, name ); 3894 3895 if ( /toggle|show|hide/.test(val) ) 3896 e[ val == "toggle" ? hidden ? "show" : "hide" : val ]( prop ); 3897 else { 3898 var parts = val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/), 3899 start = e.cur(true) || 0; 3900 3901 if ( parts ) { 3902 var end = parseFloat(parts[2]), 3903 unit = parts[3] || "px"; 3904 3905 // We need to compute starting value 3906 if ( unit != "px" ) { 3907 self.style[ name ] = (end || 1) + unit; 3908 start = ((end || 1) / e.cur(true)) * start; 3909 self.style[ name ] = start + unit; 3910 } 3911 3912 // If a +=/-= token was provided, we're doing a relative animation 3913 if ( parts[1] ) 3914 end = ((parts[1] == "-=" ? -1 : 1) * end) + start; 3915 3916 e.custom( start, end, unit ); 3917 } else 3918 e.custom( start, val, "" ); 3919 } 3920 }); 3921 3922 // For JS strict compliance 3923 return true; 3924 }); 3925 }, 3926 3927 stop: function(clearQueue, gotoEnd){ 3928 var timers = jQuery.timers; 3929 3930 if (clearQueue) 3931 this.queue([]); 3932 3933 this.each(function(){ 3934 // go in reverse order so anything added to the queue during the loop is ignored 3935 for ( var i = timers.length - 1; i >= 0; i-- ) 3936 if ( timers[i].elem == this ) { 3937 if (gotoEnd) 3938 // force the next step to be the last 3939 timers[i](true); 3940 timers.splice(i, 1); 3941 } 3942 }); 3943 3944 // start the next in the queue if the last step wasn't forced 3945 if (!gotoEnd) 3946 this.dequeue(); 3947 3948 return this; 3949 } 3950 3951 }); 3952 3953 // Generate shortcuts for custom animations 3954 jQuery.each({ 3955 slideDown: genFx("show", 1), 3956 slideUp: genFx("hide", 1), 3957 slideToggle: genFx("toggle", 1), 3958 fadeIn: { opacity: "show" }, 3959 fadeOut: { opacity: "hide" } 3960 }, function( name, props ){ 3961 jQuery.fn[ name ] = function( speed, callback ){ 3962 return this.animate( props, speed, callback ); 3963 }; 3964 }); 3965 3966 jQuery.extend({ 3967 3968 speed: function(speed, easing, fn) { 3969 var opt = typeof speed === "object" ? speed : { 3970 complete: fn || !fn && easing || 3971 jQuery.isFunction( speed ) && speed, 3972 duration: speed, 3973 easing: fn && easing || easing && !jQuery.isFunction(easing) && easing 3974 }; 3975 3976 opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration : 3977 jQuery.fx.speeds[opt.duration] || jQuery.fx.speeds._default; 3978 3979 // Queueing 3980 opt.old = opt.complete; 3981 opt.complete = function(){ 3982 if ( opt.queue !== false ) 3983 jQuery(this).dequeue(); 3984 if ( jQuery.isFunction( opt.old ) ) 3985 opt.old.call( this ); 3986 }; 3987 3988 return opt; 3989 }, 3990 3991 easing: { 3992 linear: function( p, n, firstNum, diff ) { 3993 return firstNum + diff * p; 3994 }, 3995 swing: function( p, n, firstNum, diff ) { 3996 return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum; 3997 } 3998 }, 3999 4000 timers: [], 4001 4002 fx: function( elem, options, prop ){ 4003 this.options = options; 4004 this.elem = elem; 4005 this.prop = prop; 4006 4007 if ( !options.orig ) 4008 options.orig = {}; 4009 } 4010 4011 }); 4012 4013 jQuery.fx.prototype = { 4014 4015 // Simple function for setting a style value 4016 update: function(){ 4017 if ( this.options.step ) 4018 this.options.step.call( this.elem, this.now, this ); 4019 4020 (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this ); 4021 4022 // Set display property to block for height/width animations 4023 if ( ( this.prop == "height" || this.prop == "width" ) && this.elem.style ) 4024 this.elem.style.display = "block"; 4025 }, 4026 4027 // Get the current size 4028 cur: function(force){ 4029 if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) ) 4030 return this.elem[ this.prop ]; 4031 4032 var r = parseFloat(jQuery.css(this.elem, this.prop, force)); 4033 return r && r > -10000 ? r : parseFloat(jQuery.curCSS(this.elem, this.prop)) || 0; 4034 }, 4035 4036 // Start an animation from one number to another 4037 custom: function(from, to, unit){ 4038 this.startTime = now(); 4039 this.start = from; 4040 this.end = to; 4041 this.unit = unit || this.unit || "px"; 4042 this.now = this.start; 4043 this.pos = this.state = 0; 4044 4045 var self = this; 4046 function t(gotoEnd){ 4047 return self.step(gotoEnd); 4048 } 4049 4050 t.elem = this.elem; 4051 4052 if ( t() && jQuery.timers.push(t) && !timerId ) { 4053 timerId = setInterval(function(){ 4054 var timers = jQuery.timers; 4055 4056 for ( var i = 0; i < timers.length; i++ ) 4057 if ( !timers[i]() ) 4058 timers.splice(i--, 1); 4059 4060 if ( !timers.length ) { 4061 clearInterval( timerId ); 4062 timerId = undefined; 4063 } 4064 }, 13); 4065 } 4066 }, 4067 4068 // Simple 'show' function 4069 show: function(){ 4070 // Remember where we started, so that we can go back to it later 4071 this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop ); 4072 this.options.show = true; 4073 4074 // Begin the animation 4075 // Make sure that we start at a small width/height to avoid any 4076 // flash of content 4077 this.custom(this.prop == "width" || this.prop == "height" ? 1 : 0, this.cur()); 4078 4079 // Start by showing the element 4080 jQuery(this.elem).show(); 4081 }, 4082 4083 // Simple 'hide' function 4084 hide: function(){ 4085 // Remember where we started, so that we can go back to it later 4086 this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop ); 4087 this.options.hide = true; 4088 4089 // Begin the animation 4090 this.custom(this.cur(), 0); 4091 }, 4092 4093 // Each step of an animation 4094 step: function(gotoEnd){ 4095 var t = now(); 4096 4097 if ( gotoEnd || t >= this.options.duration + this.startTime ) { 4098 this.now = this.end; 4099 this.pos = this.state = 1; 4100 this.update(); 4101 4102 this.options.curAnim[ this.prop ] = true; 4103 4104 var done = true; 4105 for ( var i in this.options.curAnim ) 4106 if ( this.options.curAnim[i] !== true ) 4107 done = false; 4108 4109 if ( done ) { 4110 if ( this.options.display != null ) { 4111 // Reset the overflow 4112 this.elem.style.overflow = this.options.overflow; 4113 4114 // Reset the display 4115 this.elem.style.display = this.options.display; 4116 if ( jQuery.css(this.elem, "display") == "none" ) 4117 this.elem.style.display = "block"; 4118 } 4119 4120 // Hide the element if the "hide" operation was done 4121 if ( this.options.hide ) 4122 jQuery(this.elem).hide(); 4123 4124 // Reset the properties, if the item has been hidden or shown 4125 if ( this.options.hide || this.options.show ) 4126 for ( var p in this.options.curAnim ) 4127 jQuery.attr(this.elem.style, p, this.options.orig[p]); 4128 4129 // Execute the complete function 4130 this.options.complete.call( this.elem ); 4131 } 4132 4133 return false; 4134 } else { 4135 var n = t - this.startTime; 4136 this.state = n / this.options.duration; 4137 4138 // Perform the easing function, defaults to swing 4139 this.pos = jQuery.easing[this.options.easing || (jQuery.easing.swing ? "swing" : "linear")](this.state, n, 0, 1, this.options.duration); 4140 this.now = this.start + ((this.end - this.start) * this.pos); 4141 4142 // Perform the next step of the animation 4143 this.update(); 4144 } 4145 4146 return true; 4147 } 4148 4149 }; 4150 4151 jQuery.extend( jQuery.fx, { 4152 speeds:{ 4153 slow: 600, 4154 fast: 200, 4155 // Default speed 4156 _default: 400 4157 }, 4158 step: { 4159 4160 opacity: function(fx){ 4161 jQuery.attr(fx.elem.style, "opacity", fx.now); 4162 }, 4163 4164 _default: function(fx){ 4165 if ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) 4166 fx.elem.style[ fx.prop ] = fx.now + fx.unit; 4167 else 4168 fx.elem[ fx.prop ] = fx.now; 4169 } 4170 } 4171 }); 4172 if ( document.documentElement["getBoundingClientRect"] ) 4173 jQuery.fn.offset = function() { 4174 if ( !this[0] ) return { top: 0, left: 0 }; 4175 if ( this[0] === this[0].ownerDocument.body ) return jQuery.offset.bodyOffset( this[0] ); 4176 var box = this[0].getBoundingClientRect(), doc = this[0].ownerDocument, body = doc.body, docElem = doc.documentElement, 4177 clientTop = docElem.clientTop || body.clientTop || 0, clientLeft = docElem.clientLeft || body.clientLeft || 0, 4178 top = box.top + (self.pageYOffset || jQuery.boxModel && docElem.scrollTop || body.scrollTop ) - clientTop, 4179 left = box.left + (self.pageXOffset || jQuery.boxModel && docElem.scrollLeft || body.scrollLeft) - clientLeft; 4180 return { top: top, left: left }; 4181 }; 4182 else 4183 jQuery.fn.offset = function() { 4184 if ( !this[0] ) return { top: 0, left: 0 }; 4185 if ( this[0] === this[0].ownerDocument.body ) return jQuery.offset.bodyOffset( this[0] ); 4186 jQuery.offset.initialized || jQuery.offset.initialize(); 4187 4188 var elem = this[0], offsetParent = elem.offsetParent, prevOffsetParent = elem, 4189 doc = elem.ownerDocument, computedStyle, docElem = doc.documentElement, 4190 body = doc.body, defaultView = doc.defaultView, 4191 prevComputedStyle = defaultView.getComputedStyle(elem, null), 4192 top = elem.offsetTop, left = elem.offsetLeft; 4193 4194 while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) { 4195 computedStyle = defaultView.getComputedStyle(elem, null); 4196 top -= elem.scrollTop, left -= elem.scrollLeft; 4197 if ( elem === offsetParent ) { 4198 top += elem.offsetTop, left += elem.offsetLeft; 4199 if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && /^t(able|d|h)$/i.test(elem.tagName)) ) 4200 top += parseInt( computedStyle.borderTopWidth, 10) || 0, 4201 left += parseInt( computedStyle.borderLeftWidth, 10) || 0; 4202 prevOffsetParent = offsetParent, offsetParent = elem.offsetParent; 4203 } 4204 if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) 4205 top += parseInt( computedStyle.borderTopWidth, 10) || 0, 4206 left += parseInt( computedStyle.borderLeftWidth, 10) || 0; 4207 prevComputedStyle = computedStyle; 4208 } 4209 4210 if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) 4211 top += body.offsetTop, 4212 left += body.offsetLeft; 4213 4214 if ( prevComputedStyle.position === "fixed" ) 4215 top += Math.max(docElem.scrollTop, body.scrollTop), 4216 left += Math.max(docElem.scrollLeft, body.scrollLeft); 4217 4218 return { top: top, left: left }; 4219 }; 4220 4221 jQuery.offset = { 4222 initialize: function() { 4223 if ( this.initialized ) return; 4224 var body = document.body, container = document.createElement('div'), innerDiv, checkDiv, table, td, rules, prop, bodyMarginTop = body.style.marginTop, 4225 html = '<div style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;"><div></div></div><table style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;" cellpadding="0" cellspacing="0"><tr><td></td></tr></table>'; 4226 4227 rules = { position: 'absolute', top: 0, left: 0, margin: 0, border: 0, width: '1px', height: '1px', visibility: 'hidden' }; 4228 for ( prop in rules ) container.style[prop] = rules[prop]; 4229 4230 container.innerHTML = html; 4231 body.insertBefore(container, body.firstChild); 4232 innerDiv = container.firstChild, checkDiv = innerDiv.firstChild, td = innerDiv.nextSibling.firstChild.firstChild; 4233 4234 this.doesNotAddBorder = (checkDiv.offsetTop !== 5); 4235 this.doesAddBorderForTableAndCells = (td.offsetTop === 5); 4236 4237 innerDiv.style.overflow = 'hidden', innerDiv.style.position = 'relative'; 4238 this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5); 4239 4240 body.style.marginTop = '1px'; 4241 this.doesNotIncludeMarginInBodyOffset = (body.offsetTop === 0); 4242 body.style.marginTop = bodyMarginTop; 4243 4244 body.removeChild(container); 4245 this.initialized = true; 4246 }, 4247 4248 bodyOffset: function(body) { 4249 jQuery.offset.initialized || jQuery.offset.initialize(); 4250 var top = body.offsetTop, left = body.offsetLeft; 4251 if ( jQuery.offset.doesNotIncludeMarginInBodyOffset ) 4252 top += parseInt( jQuery.curCSS(body, 'marginTop', true), 10 ) || 0, 4253 left += parseInt( jQuery.curCSS(body, 'marginLeft', true), 10 ) || 0; 4254 return { top: top, left: left }; 4255 } 4256 }; 4257 4258 4259 jQuery.fn.extend({ 4260 position: function() { 4261 var left = 0, top = 0, results; 4262 4263 if ( this[0] ) { 4264 // Get *real* offsetParent 4265 var offsetParent = this.offsetParent(), 4266 4267 // Get correct offsets 4268 offset = this.offset(), 4269 parentOffset = /^body|html$/i.test(offsetParent[0].tagName) ? { top: 0, left: 0 } : offsetParent.offset(); 4270 4271 // Subtract element margins 4272 // note: when an element has margin: auto the offsetLeft and marginLeft 4273 // are the same in Safari causing offset.left to incorrectly be 0 4274 offset.top -= num( this, 'marginTop' ); 4275 offset.left -= num( this, 'marginLeft' ); 4276 4277 // Add offsetParent borders 4278 parentOffset.top += num( offsetParent, 'borderTopWidth' ); 4279 parentOffset.left += num( offsetParent, 'borderLeftWidth' ); 4280 4281 // Subtract the two offsets 4282 results = { 4283 top: offset.top - parentOffset.top, 4284 left: offset.left - parentOffset.left 4285 }; 4286 } 4287 4288 return results; 4289 }, 4290 4291 offsetParent: function() { 4292 var offsetParent = this[0].offsetParent || document.body; 4293 while ( offsetParent && (!/^body|html$/i.test(offsetParent.tagName) && jQuery.css(offsetParent, 'position') == 'static') ) 4294 offsetParent = offsetParent.offsetParent; 4295 return jQuery(offsetParent); 4296 } 4297 }); 4298 4299 4300 // Create scrollLeft and scrollTop methods 4301 jQuery.each( ['Left', 'Top'], function(i, name) { 4302 var method = 'scroll' + name; 4303 4304 jQuery.fn[ method ] = function(val) { 4305 if (!this[0]) return null; 4306 4307 return val !== undefined ? 4308 4309 // Set the scroll offset 4310 this.each(function() { 4311 this == window || this == document ? 4312 window.scrollTo( 4313 !i ? val : jQuery(window).scrollLeft(), 4314 i ? val : jQuery(window).scrollTop() 4315 ) : 4316 this[ method ] = val; 4317 }) : 4318 4319 // Return the scroll offset 4320 this[0] == window || this[0] == document ? 4321 self[ i ? 'pageYOffset' : 'pageXOffset' ] || 4322 jQuery.boxModel && document.documentElement[ method ] || 4323 document.body[ method ] : 4324 this[0][ method ]; 4325 }; 4326 }); 4327 // Create innerHeight, innerWidth, outerHeight and outerWidth methods 4328 jQuery.each([ "Height", "Width" ], function(i, name){ 4329 4330 var tl = i ? "Left" : "Top", // top or left 4331 br = i ? "Right" : "Bottom", // bottom or right 4332 lower = name.toLowerCase(); 4333 4334 // innerHeight and innerWidth 4335 jQuery.fn["inner" + name] = function(){ 4336 return this[0] ? 4337 jQuery.css( this[0], lower, false, "padding" ) : 4338 null; 4339 }; 4340 4341 // outerHeight and outerWidth 4342 jQuery.fn["outer" + name] = function(margin) { 4343 return this[0] ? 4344 jQuery.css( this[0], lower, false, margin ? "margin" : "border" ) : 4345 null; 4346 }; 4347 4348 var type = name.toLowerCase(); 4349 4350 jQuery.fn[ type ] = function( size ) { 4351 // Get window width or height 4352 return this[0] == window ? 4353 // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode 4354 document.compatMode == "CSS1Compat" && document.documentElement[ "client" + name ] || 4355 document.body[ "client" + name ] : 4356 4357 // Get document width or height 4358 this[0] == document ? 4359 // Either scroll[Width/Height] or offset[Width/Height], whichever is greater 4360 Math.max( 4361 document.documentElement["client" + name], 4362 document.body["scroll" + name], document.documentElement["scroll" + name], 4363 document.body["offset" + name], document.documentElement["offset" + name] 4364 ) : 4365 4366 // Get or set width or height on the element 4367 size === undefined ? 4368 // Get width or height on the element 4369 (this.length ? jQuery.css( this[0], type ) : null) : 4370 4371 // Set the width or height on the element (default to pixels if value is unitless) 4372 this.css( type, typeof size === "string" ? size : size + "px" ); 4373 }; 4374 4375 }); 4376 })(); -

WordPress源代码——jquery(jquery-1.2.6.js)
1 (function(){ 2 /* 3 * jQuery 1.2.6 - New Wave Javascript 4 * 5 * Copyright (c) 2008 John Resig (jquery.com) 6 * Dual licensed under the MIT (MIT-LICENSE.txt) 7 * and GPL (GPL-LICENSE.txt) licenses. 8 * 9 * $Date: 2008-05-24 14:22:17 -0400 (Sat, 24 May 2008) $ 10 * $Rev: 5685 $ 11 */ 12 13 // Map over jQuery in case of overwrite 14 var _jQuery = window.jQuery, 15 // Map over the $ in case of overwrite 16 _$ = window.$; 17 18 var jQuery = window.jQuery = window.$ = function( selector, context ) { 19 // The jQuery object is actually just the init constructor 'enhanced' 20 return new jQuery.fn.init( selector, context ); 21 }; 22 23 // A simple way to check for HTML strings or ID strings 24 // (both of which we optimize for) 25 var quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/, 26 27 // Is it a simple selector 28 isSimple = /^.[^:#\[\.]*$/, 29 30 // Will speed up references to undefined, and allows munging its name. 31 undefined; 32 33 jQuery.fn = jQuery.prototype = { 34 init: function( selector, context ) { 35 // Make sure that a selection was provided 36 selector = selector || document; 37 38 // Handle $(DOMElement) 39 if ( selector.nodeType ) { 40 this[0] = selector; 41 this.length = 1; 42 return this; 43 } 44 // Handle HTML strings 45 if ( typeof selector == "string" ) { 46 // Are we dealing with HTML string or an ID? 47 var match = quickExpr.exec( selector ); 48 49 // Verify a match, and that no context was specified for #id 50 if ( match && (match[1] || !context) ) { 51 52 // HANDLE: $(html) -> $(array) 53 if ( match[1] ) 54 selector = jQuery.clean( [ match[1] ], context ); 55 56 // HANDLE: $("#id") 57 else { 58 var elem = document.getElementById( match[3] ); 59 60 // Make sure an element was located 61 if ( elem ){ 62 // Handle the case where IE and Opera return items 63 // by name instead of ID 64 if ( elem.id != match[3] ) 65 return jQuery().find( selector ); 66 67 // Otherwise, we inject the element directly into the jQuery object 68 return jQuery( elem ); 69 } 70 selector = []; 71 } 72 73 // HANDLE: $(expr, [context]) 74 // (which is just equivalent to: $(content).find(expr) 75 } else 76 return jQuery( context ).find( selector ); 77 78 // HANDLE: $(function) 79 // Shortcut for document ready 80 } else if ( jQuery.isFunction( selector ) ) 81 return jQuery( document )[ jQuery.fn.ready ? "ready" : "load" ]( selector ); 82 83 return this.setArray(jQuery.makeArray(selector)); 84 }, 85 86 // The current version of jQuery being used 87 jquery: "1.2.6", 88 89 // The number of elements contained in the matched element set 90 size: function() { 91 return this.length; 92 }, 93 94 // The number of elements contained in the matched element set 95 length: 0, 96 97 // Get the Nth element in the matched element set OR 98 // Get the whole matched element set as a clean array 99 get: function( num ) { 100 return num == undefined ? 101 102 // Return a 'clean' array 103 jQuery.makeArray( this ) : 104 105 // Return just the object 106 this[ num ]; 107 }, 108 109 // Take an array of elements and push it onto the stack 110 // (returning the new matched element set) 111 pushStack: function( elems ) { 112 // Build a new jQuery matched element set 113 var ret = jQuery( elems ); 114 115 // Add the old object onto the stack (as a reference) 116 ret.prevObject = this; 117 118 // Return the newly-formed element set 119 return ret; 120 }, 121 122 // Force the current matched set of elements to become 123 // the specified array of elements (destroying the stack in the process) 124 // You should use pushStack() in order to do this, but maintain the stack 125 setArray: function( elems ) { 126 // Resetting the length to 0, then using the native Array push 127 // is a super-fast way to populate an object with array-like properties 128 this.length = 0; 129 Array.prototype.push.apply( this, elems ); 130 131 return this; 132 }, 133 134 // Execute a callback for every element in the matched set. 135 // (You can seed the arguments with an array of args, but this is 136 // only used internally.) 137 each: function( callback, args ) { 138 return jQuery.each( this, callback, args ); 139 }, 140 141 // Determine the position of an element within 142 // the matched set of elements 143 index: function( elem ) { 144 var ret = -1; 145 146 // Locate the position of the desired element 147 return jQuery.inArray( 148 // If it receives a jQuery object, the first element is used 149 elem && elem.jquery ? elem[0] : elem 150 , this ); 151 }, 152 153 attr: function( name, value, type ) { 154 var options = name; 155 156 // Look for the case where we're accessing a style value 157 if ( name.constructor == String ) 158 if ( value === undefined ) 159 return this[0] && jQuery[ type || "attr" ]( this[0], name ); 160 161 else { 162 options = {}; 163 options[ name ] = value; 164 } 165 166 // Check to see if we're setting style values 167 return this.each(function(i){ 168 // Set all the styles 169 for ( name in options ) 170 jQuery.attr( 171 type ? 172 this.style : 173 this, 174 name, jQuery.prop( this, options[ name ], type, i, name ) 175 ); 176 }); 177 }, 178 179 css: function( key, value ) { 180 // ignore negative width and height values 181 if ( (key == 'width' || key == 'height') && parseFloat(value) < 0 ) 182 value = undefined; 183 return this.attr( key, value, "curCSS" ); 184 }, 185 186 text: function( text ) { 187 if ( typeof text != "object" && text != null ) 188 return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) ); 189 190 var ret = ""; 191 192 jQuery.each( text || this, function(){ 193 jQuery.each( this.childNodes, function(){ 194 if ( this.nodeType != 8 ) 195 ret += this.nodeType != 1 ? 196 this.nodeValue : 197 jQuery.fn.text( [ this ] ); 198 }); 199 }); 200 201 return ret; 202 }, 203 204 wrapAll: function( html ) { 205 if ( this[0] ) 206 // The elements to wrap the target around 207 jQuery( html, this[0].ownerDocument ) 208 .clone() 209 .insertBefore( this[0] ) 210 .map(function(){ 211 var elem = this; 212 213 while ( elem.firstChild ) 214 elem = elem.firstChild; 215 216 return elem; 217 }) 218 .append(this); 219 220 return this; 221 }, 222 223 wrapInner: function( html ) { 224 return this.each(function(){ 225 jQuery( this ).contents().wrapAll( html ); 226 }); 227 }, 228 229 wrap: function( html ) { 230 return this.each(function(){ 231 jQuery( this ).wrapAll( html ); 232 }); 233 }, 234 235 append: function() { 236 return this.domManip(arguments, true, false, function(elem){ 237 if (this.nodeType == 1) 238 this.appendChild( elem ); 239 }); 240 }, 241 242 prepend: function() { 243 return this.domManip(arguments, true, true, function(elem){ 244 if (this.nodeType == 1) 245 this.insertBefore( elem, this.firstChild ); 246 }); 247 }, 248 249 before: function() { 250 return this.domManip(arguments, false, false, function(elem){ 251 this.parentNode.insertBefore( elem, this ); 252 }); 253 }, 254 255 after: function() { 256 return this.domManip(arguments, false, true, function(elem){ 257 this.parentNode.insertBefore( elem, this.nextSibling ); 258 }); 259 }, 260 261 end: function() { 262 return this.prevObject || jQuery( [] ); 263 }, 264 265 find: function( selector ) { 266 var elems = jQuery.map(this, function(elem){ 267 return jQuery.find( selector, elem ); 268 }); 269 270 return this.pushStack( /[^+>] [^+>]/.test( selector ) || selector.indexOf("..") > -1 ? 271 jQuery.unique( elems ) : 272 elems ); 273 }, 274 275 clone: function( events ) { 276 // Do the clone 277 var ret = this.map(function(){ 278 if ( jQuery.browser.msie && !jQuery.isXMLDoc(this) ) { 279 // IE copies events bound via attachEvent when 280 // using cloneNode. Calling detachEvent on the 281 // clone will also remove the events from the orignal 282 // In order to get around this, we use innerHTML. 283 // Unfortunately, this means some modifications to 284 // attributes in IE that are actually only stored 285 // as properties will not be copied (such as the 286 // the name attribute on an input). 287 var clone = this.cloneNode(true), 288 container = document.createElement("div"); 289 container.appendChild(clone); 290 return jQuery.clean([container.innerHTML])[0]; 291 } else 292 return this.cloneNode(true); 293 }); 294 295 // Need to set the expando to null on the cloned set if it exists 296 // removeData doesn't work here, IE removes it from the original as well 297 // this is primarily for IE but the data expando shouldn't be copied over in any browser 298 var clone = ret.find("*").andSelf().each(function(){ 299 if ( this[ expando ] != undefined ) 300 this[ expando ] = null; 301 }); 302 303 // Copy the events from the original to the clone 304 if ( events === true ) 305 this.find("*").andSelf().each(function(i){ 306 if (this.nodeType == 3) 307 return; 308 var events = jQuery.data( this, "events" ); 309 310 for ( var type in events ) 311 for ( var handler in events[ type ] ) 312 jQuery.event.add( clone[ i ], type, events[ type ][ handler ], events[ type ][ handler ].data ); 313 }); 314 315 // Return the cloned set 316 return ret; 317 }, 318 319 filter: function( selector ) { 320 return this.pushStack( 321 jQuery.isFunction( selector ) && 322 jQuery.grep(this, function(elem, i){ 323 return selector.call( elem, i ); 324 }) || 325 326 jQuery.multiFilter( selector, this ) ); 327 }, 328 329 not: function( selector ) { 330 if ( selector.constructor == String ) 331 // test special case where just one selector is passed in 332 if ( isSimple.test( selector ) ) 333 return this.pushStack( jQuery.multiFilter( selector, this, true ) ); 334 else 335 selector = jQuery.multiFilter( selector, this ); 336 337 var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType; 338 return this.filter(function() { 339 return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector; 340 }); 341 }, 342 343 add: function( selector ) { 344 return this.pushStack( jQuery.unique( jQuery.merge( 345 this.get(), 346 typeof selector == 'string' ? 347 jQuery( selector ) : 348 jQuery.makeArray( selector ) 349 ))); 350 }, 351 352 is: function( selector ) { 353 return !!selector && jQuery.multiFilter( selector, this ).length > 0; 354 }, 355 356 hasClass: function( selector ) { 357 return this.is( "." + selector ); 358 }, 359 360 val: function( value ) { 361 if ( value == undefined ) { 362 363 if ( this.length ) { 364 var elem = this[0]; 365 366 // We need to handle select boxes special 367 if ( jQuery.nodeName( elem, "select" ) ) { 368 var index = elem.selectedIndex, 369 values = [], 370 options = elem.options, 371 one = elem.type == "select-one"; 372 373 // Nothing was selected 374 if ( index < 0 ) 375 return null; 376 377 // Loop through all the selected options 378 for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) { 379 var option = options[ i ]; 380 381 if ( option.selected ) { 382 // Get the specifc value for the option 383 value = jQuery.browser.msie && !option.attributes.value.specified ? option.text : option.value; 384 385 // We don't need an array for one selects 386 if ( one ) 387 return value; 388 389 // Multi-Selects return an array 390 values.push( value ); 391 } 392 } 393 394 return values; 395 396 // Everything else, we just grab the value 397 } else 398 return (this[0].value || "").replace(/\r/g, ""); 399 400 } 401 402 return undefined; 403 } 404 405 if( value.constructor == Number ) 406 value += ''; 407 408 return this.each(function(){ 409 if ( this.nodeType != 1 ) 410 return; 411 412 if ( value.constructor == Array && /radio|checkbox/.test( this.type ) ) 413 this.checked = (jQuery.inArray(this.value, value) >= 0 || 414 jQuery.inArray(this.name, value) >= 0); 415 416 else if ( jQuery.nodeName( this, "select" ) ) { 417 var values = jQuery.makeArray(value); 418 419 jQuery( "option", this ).each(function(){ 420 this.selected = (jQuery.inArray( this.value, values ) >= 0 || 421 jQuery.inArray( this.text, values ) >= 0); 422 }); 423 424 if ( !values.length ) 425 this.selectedIndex = -1; 426 427 } else 428 this.value = value; 429 }); 430 }, 431 432 html: function( value ) { 433 return value == undefined ? 434 (this[0] ? 435 this[0].innerHTML : 436 null) : 437 this.empty().append( value ); 438 }, 439 440 replaceWith: function( value ) { 441 return this.after( value ).remove(); 442 }, 443 444 eq: function( i ) { 445 return this.slice( i, i + 1 ); 446 }, 447 448 slice: function() { 449 return this.pushStack( Array.prototype.slice.apply( this, arguments ) ); 450 }, 451 452 map: function( callback ) { 453 return this.pushStack( jQuery.map(this, function(elem, i){ 454 return callback.call( elem, i, elem ); 455 })); 456 }, 457 458 andSelf: function() { 459 return this.add( this.prevObject ); 460 }, 461 462 data: function( key, value ){ 463 var parts = key.split("."); 464 parts[1] = parts[1] ? "." + parts[1] : ""; 465 466 if ( value === undefined ) { 467 var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]); 468 469 if ( data === undefined && this.length ) 470 data = jQuery.data( this[0], key ); 471 472 return data === undefined && parts[1] ? 473 this.data( parts[0] ) : 474 data; 475 } else 476 return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function(){ 477 jQuery.data( this, key, value ); 478 }); 479 }, 480 481 removeData: function( key ){ 482 return this.each(function(){ 483 jQuery.removeData( this, key ); 484 }); 485 }, 486 487 domManip: function( args, table, reverse, callback ) { 488 var clone = this.length > 1, elems; 489 490 return this.each(function(){ 491 if ( !elems ) { 492 elems = jQuery.clean( args, this.ownerDocument ); 493 494 if ( reverse ) 495 elems.reverse(); 496 } 497 498 var obj = this; 499 500 if ( table && jQuery.nodeName( this, "table" ) && jQuery.nodeName( elems[0], "tr" ) ) 501 obj = this.getElementsByTagName("tbody")[0] || this.appendChild( this.ownerDocument.createElement("tbody") ); 502 503 var scripts = jQuery( [] ); 504 505 jQuery.each(elems, function(){ 506 var elem = clone ? 507 jQuery( this ).clone( true )[0] : 508 this; 509 510 // execute all scripts after the elements have been injected 511 if ( jQuery.nodeName( elem, "script" ) ) 512 scripts = scripts.add( elem ); 513 else { 514 // Remove any inner scripts for later evaluation 515 if ( elem.nodeType == 1 ) 516 scripts = scripts.add( jQuery( "script", elem ).remove() ); 517 518 // Inject the elements into the document 519 callback.call( obj, elem ); 520 } 521 }); 522 523 scripts.each( evalScript ); 524 }); 525 } 526 }; 527 528 // Give the init function the jQuery prototype for later instantiation 529 jQuery.fn.init.prototype = jQuery.fn; 530 531 function evalScript( i, elem ) { 532 if ( elem.src ) 533 jQuery.ajax({ 534 url: elem.src, 535 async: false, 536 dataType: "script" 537 }); 538 539 else 540 jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" ); 541 542 if ( elem.parentNode ) 543 elem.parentNode.removeChild( elem ); 544 } 545 546 function now(){ 547 return +new Date; 548 } 549 550 jQuery.extend = jQuery.fn.extend = function() { 551 // copy reference to target object 552 var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options; 553 554 // Handle a deep copy situation 555 if ( target.constructor == Boolean ) { 556 deep = target; 557 target = arguments[1] || {}; 558 // skip the boolean and the target 559 i = 2; 560 } 561 562 // Handle case when target is a string or something (possible in deep copy) 563 if ( typeof target != "object" && typeof target != "function" ) 564 target = {}; 565 566 // extend jQuery itself if only one argument is passed 567 if ( length == i ) { 568 target = this; 569 --i; 570 } 571 572 for ( ; i < length; i++ ) 573 // Only deal with non-null/undefined values 574 if ( (options = arguments[ i ]) != null ) 575 // Extend the base object 576 for ( var name in options ) { 577 var src = target[ name ], copy = options[ name ]; 578 579 // Prevent never-ending loop 580 if ( target === copy ) 581 continue; 582 583 // Recurse if we're merging object values 584 if ( deep && copy && typeof copy == "object" && !copy.nodeType ) 585 target[ name ] = jQuery.extend( deep, 586 // Never move original objects, clone them 587 src || ( copy.length != null ? [ ] : { } ) 588 , copy ); 589 590 // Don't bring in undefined values 591 else if ( copy !== undefined ) 592 target[ name ] = copy; 593 594 } 595 596 // Return the modified object 597 return target; 598 }; 599 600 var expando = "jQuery" + now(), uuid = 0, windowData = {}, 601 // exclude the following css properties to add px 602 exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i, 603 // cache defaultView 604 defaultView = document.defaultView || {}; 605 606 jQuery.extend({ 607 noConflict: function( deep ) { 608 window.$ = _$; 609 610 if ( deep ) 611 window.jQuery = _jQuery; 612 613 return jQuery; 614 }, 615 616 // See test/unit/core.js for details concerning this function. 617 isFunction: function( fn ) { 618 return !!fn && typeof fn != "string" && !fn.nodeName && 619 fn.constructor != Array && /^[\s[]?function/.test( fn + "" ); 620 }, 621 622 // check if an element is in a (or is an) XML document 623 isXMLDoc: function( elem ) { 624 return elem.documentElement && !elem.body || 625 elem.tagName && elem.ownerDocument && !elem.ownerDocument.body; 626 }, 627 628 // Evalulates a script in a global context 629 globalEval: function( data ) { 630 data = jQuery.trim( data ); 631 632 if ( data ) { 633 // Inspired by code by Andrea Giammarchi 634 // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html 635 var head = document.getElementsByTagName("head")[0] || document.documentElement, 636 script = document.createElement("script"); 637 638 script.type = "text/javascript"; 639 if ( jQuery.browser.msie ) 640 script.text = data; 641 else 642 script.appendChild( document.createTextNode( data ) ); 643 644 // Use insertBefore instead of appendChild to circumvent an IE6 bug. 645 // This arises when a base node is used (#2709). 646 head.insertBefore( script, head.firstChild ); 647 head.removeChild( script ); 648 } 649 }, 650 651 nodeName: function( elem, name ) { 652 return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase(); 653 }, 654 655 cache: {}, 656 657 data: function( elem, name, data ) { 658 elem = elem == window ? 659 windowData : 660 elem; 661 662 var id = elem[ expando ]; 663 664 // Compute a unique ID for the element 665 if ( !id ) 666 id = elem[ expando ] = ++uuid; 667 668 // Only generate the data cache if we're 669 // trying to access or manipulate it 670 if ( name && !jQuery.cache[ id ] ) 671 jQuery.cache[ id ] = {}; 672 673 // Prevent overriding the named cache with undefined values 674 if ( data !== undefined ) 675 jQuery.cache[ id ][ name ] = data; 676 677 // Return the named cache data, or the ID for the element 678 return name ? 679 jQuery.cache[ id ][ name ] : 680 id; 681 }, 682 683 removeData: function( elem, name ) { 684 elem = elem == window ? 685 windowData : 686 elem; 687 688 var id = elem[ expando ]; 689 690 // If we want to remove a specific section of the element's data 691 if ( name ) { 692 if ( jQuery.cache[ id ] ) { 693 // Remove the section of cache data 694 delete jQuery.cache[ id ][ name ]; 695 696 // If we've removed all the data, remove the element's cache 697 name = ""; 698 699 for ( name in jQuery.cache[ id ] ) 700 break; 701 702 if ( !name ) 703 jQuery.removeData( elem ); 704 } 705 706 // Otherwise, we want to remove all of the element's data 707 } else { 708 // Clean up the element expando 709 try { 710 delete elem[ expando ]; 711 } catch(e){ 712 // IE has trouble directly removing the expando 713 // but it's ok with using removeAttribute 714 if ( elem.removeAttribute ) 715 elem.removeAttribute( expando ); 716 } 717 718 // Completely remove the data cache 719 delete jQuery.cache[ id ]; 720 } 721 }, 722 723 // args is for internal usage only 724 each: function( object, callback, args ) { 725 var name, i = 0, length = object.length; 726 727 if ( args ) { 728 if ( length == undefined ) { 729 for ( name in object ) 730 if ( callback.apply( object[ name ], args ) === false ) 731 break; 732 } else 733 for ( ; i < length; ) 734 if ( callback.apply( object[ i++ ], args ) === false ) 735 break; 736 737 // A special, fast, case for the most common use of each 738 } else { 739 if ( length == undefined ) { 740 for ( name in object ) 741 if ( callback.call( object[ name ], name, object[ name ] ) === false ) 742 break; 743 } else 744 for ( var value = object[0]; 745 i < length && callback.call( value, i, value ) !== false; value = object[++i] ){} 746 } 747 748 return object; 749 }, 750 751 prop: function( elem, value, type, i, name ) { 752 // Handle executable functions 753 if ( jQuery.isFunction( value ) ) 754 value = value.call( elem, i ); 755 756 // Handle passing in a number to a CSS property 757 return value && value.constructor == Number && type == "curCSS" && !exclude.test( name ) ? 758 value + "px" : 759 value; 760 }, 761 762 className: { 763 // internal only, use addClass("class") 764 add: function( elem, classNames ) { 765 jQuery.each((classNames || "").split(/\s+/), function(i, className){ 766 if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) ) 767 elem.className += (elem.className ? " " : "") + className; 768 }); 769 }, 770 771 // internal only, use removeClass("class") 772 remove: function( elem, classNames ) { 773 if (elem.nodeType == 1) 774 elem.className = classNames != undefined ? 775 jQuery.grep(elem.className.split(/\s+/), function(className){ 776 return !jQuery.className.has( classNames, className ); 777 }).join(" ") : 778 ""; 779 }, 780 781 // internal only, use hasClass("class") 782 has: function( elem, className ) { 783 return jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1; 784 } 785 }, 786 787 // A method for quickly swapping in/out CSS properties to get correct calculations 788 swap: function( elem, options, callback ) { 789 var old = {}; 790 // Remember the old values, and insert the new ones 791 for ( var name in options ) { 792 old[ name ] = elem.style[ name ]; 793 elem.style[ name ] = options[ name ]; 794 } 795 796 callback.call( elem ); 797 798 // Revert the old values 799 for ( var name in options ) 800 elem.style[ name ] = old[ name ]; 801 }, 802 803 css: function( elem, name, force ) { 804 if ( name == "width" || name == "height" ) { 805 var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ]; 806 807 function getWH() { 808 val = name == "width" ? elem.offsetWidth : elem.offsetHeight; 809 var padding = 0, border = 0; 810 jQuery.each( which, function() { 811 padding += parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0; 812 border += parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0; 813 }); 814 val -= Math.round(padding + border); 815 } 816 817 if ( jQuery(elem).is(":visible") ) 818 getWH(); 819 else 820 jQuery.swap( elem, props, getWH ); 821 822 return Math.max(0, val); 823 } 824 825 return jQuery.curCSS( elem, name, force ); 826 }, 827 828 curCSS: function( elem, name, force ) { 829 var ret, style = elem.style; 830 831 // A helper method for determining if an element's values are broken 832 function color( elem ) { 833 if ( !jQuery.browser.safari ) 834 return false; 835 836 // defaultView is cached 837 var ret = defaultView.getComputedStyle( elem, null ); 838 return !ret || ret.getPropertyValue("color") == ""; 839 } 840 841 // We need to handle opacity special in IE 842 if ( name == "opacity" && jQuery.browser.msie ) { 843 ret = jQuery.attr( style, "opacity" ); 844 845 return ret == "" ? 846 "1" : 847 ret; 848 } 849 // Opera sometimes will give the wrong display answer, this fixes it, see #2037 850 if ( jQuery.browser.opera && name == "display" ) { 851 var save = style.outline; 852 style.outline = "0 solid black"; 853 style.outline = save; 854 } 855 856 // Make sure we're using the right name for getting the float value 857 if ( name.match( /float/i ) ) 858 name = styleFloat; 859 860 if ( !force && style && style[ name ] ) 861 ret = style[ name ]; 862 863 else if ( defaultView.getComputedStyle ) { 864 865 // Only "float" is needed here 866 if ( name.match( /float/i ) ) 867 name = "float"; 868 869 name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase(); 870 871 var computedStyle = defaultView.getComputedStyle( elem, null ); 872 873 if ( computedStyle && !color( elem ) ) 874 ret = computedStyle.getPropertyValue( name ); 875 876 // If the element isn't reporting its values properly in Safari 877 // then some display: none elements are involved 878 else { 879 var swap = [], stack = [], a = elem, i = 0; 880 881 // Locate all of the parent display: none elements 882 for ( ; a && color(a); a = a.parentNode ) 883 stack.unshift(a); 884 885 // Go through and make them visible, but in reverse 886 // (It would be better if we knew the exact display type that they had) 887 for ( ; i < stack.length; i++ ) 888 if ( color( stack[ i ] ) ) { 889 swap[ i ] = stack[ i ].style.display; 890 stack[ i ].style.display = "block"; 891 } 892 893 // Since we flip the display style, we have to handle that 894 // one special, otherwise get the value 895 ret = name == "display" && swap[ stack.length - 1 ] != null ? 896 "none" : 897 ( computedStyle && computedStyle.getPropertyValue( name ) ) || ""; 898 899 // Finally, revert the display styles back 900 for ( i = 0; i < swap.length; i++ ) 901 if ( swap[ i ] != null ) 902 stack[ i ].style.display = swap[ i ]; 903 } 904 905 // We should always get a number back from opacity 906 if ( name == "opacity" && ret == "" ) 907 ret = "1"; 908 909 } else if ( elem.currentStyle ) { 910 var camelCase = name.replace(/\-(\w)/g, function(all, letter){ 911 return letter.toUpperCase(); 912 }); 913 914 ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ]; 915 916 // From the awesome hack by Dean Edwards 917 // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 918 919 // If we're not dealing with a regular pixel number 920 // but a number that has a weird ending, we need to convert it to pixels 921 if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) { 922 // Remember the original values 923 var left = style.left, rsLeft = elem.runtimeStyle.left; 924 925 // Put in the new values to get a computed value out 926 elem.runtimeStyle.left = elem.currentStyle.left; 927 style.left = ret || 0; 928 ret = style.pixelLeft + "px"; 929 930 // Revert the changed values 931 style.left = left; 932 elem.runtimeStyle.left = rsLeft; 933 } 934 } 935 936 return ret; 937 }, 938 939 clean: function( elems, context ) { 940 var ret = []; 941 context = context || document; 942 // !context.createElement fails in IE with an error but returns typeof 'object' 943 if (typeof context.createElement == 'undefined') 944 context = context.ownerDocument || context[0] && context[0].ownerDocument || document; 945 946 jQuery.each(elems, function(i, elem){ 947 if ( !elem ) 948 return; 949 950 if ( elem.constructor == Number ) 951 elem += ''; 952 953 // Convert html string into DOM nodes 954 if ( typeof elem == "string" ) { 955 // Fix "XHTML"-style tags in all browsers 956 elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){ 957 return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ? 958 all : 959 front + "></" + tag + ">"; 960 }); 961 962 // Trim whitespace, otherwise indexOf won't work as expected 963 var tags = jQuery.trim( elem ).toLowerCase(), div = context.createElement("div"); 964 965 var wrap = 966 // option or optgroup 967 !tags.indexOf("<opt") && 968 [ 1, "<select multiple='multiple'>", "</select>" ] || 969 970 !tags.indexOf("<leg") && 971 [ 1, "<fieldset>", "</fieldset>" ] || 972 973 tags.match(/^<(thead|tbody|tfoot|colg|cap)/) && 974 [ 1, "<table>", "</table>" ] || 975 976 !tags.indexOf("<tr") && 977 [ 2, "<table><tbody>", "</tbody></table>" ] || 978 979 // <thead> matched above 980 (!tags.indexOf("<td") || !tags.indexOf("<th")) && 981 [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ] || 982 983 !tags.indexOf("<col") && 984 [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ] || 985 986 // IE can't serialize <link> and <script> tags normally 987 jQuery.browser.msie && 988 [ 1, "div<div>", "</div>" ] || 989 990 [ 0, "", "" ]; 991 992 // Go to html and back, then peel off extra wrappers 993 div.innerHTML = wrap[1] + elem + wrap[2]; 994 995 // Move to the right depth 996 while ( wrap[0]-- ) 997 div = div.lastChild; 998 999 // Remove IE's autoinserted <tbody> from table fragments 1000 if ( jQuery.browser.msie ) { 1001 1002 // String was a <table>, *may* have spurious <tbody> 1003 var tbody = !tags.indexOf("<table") && tags.indexOf("<tbody") < 0 ? 1004 div.firstChild && div.firstChild.childNodes : 1005 1006 // String was a bare <thead> or <tfoot> 1007 wrap[1] == "<table>" && tags.indexOf("<tbody") < 0 ? 1008 div.childNodes : 1009 []; 1010 1011 for ( var j = tbody.length - 1; j >= 0 ; --j ) 1012 if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) 1013 tbody[ j ].parentNode.removeChild( tbody[ j ] ); 1014 1015 // IE completely kills leading whitespace when innerHTML is used 1016 if ( /^\s/.test( elem ) ) 1017 div.insertBefore( context.createTextNode( elem.match(/^\s*/)[0] ), div.firstChild ); 1018 1019 } 1020 1021 elem = jQuery.makeArray( div.childNodes ); 1022 } 1023 1024 if ( elem.length === 0 && (!jQuery.nodeName( elem, "form" ) && !jQuery.nodeName( elem, "select" )) ) 1025 return; 1026 1027 if ( elem[0] == undefined || jQuery.nodeName( elem, "form" ) || elem.options ) 1028 ret.push( elem ); 1029 1030 else 1031 ret = jQuery.merge( ret, elem ); 1032 1033 }); 1034 1035 return ret; 1036 }, 1037 1038 attr: function( elem, name, value ) { 1039 // don't set attributes on text and comment nodes 1040 if (!elem || elem.nodeType == 3 || elem.nodeType == 8) 1041 return undefined; 1042 1043 var notxml = !jQuery.isXMLDoc( elem ), 1044 // Whether we are setting (or getting) 1045 set = value !== undefined, 1046 msie = jQuery.browser.msie; 1047 1048 // Try to normalize/fix the name 1049 name = notxml && jQuery.props[ name ] || name; 1050 1051 // Only do all the following if this is a node (faster for style) 1052 // IE elem.getAttribute passes even for style 1053 if ( elem.tagName ) { 1054 1055 // These attributes require special treatment 1056 var special = /href|src|style/.test( name ); 1057 1058 // Safari mis-reports the default selected property of a hidden option 1059 // Accessing the parent's selectedIndex property fixes it 1060 if ( name == "selected" && jQuery.browser.safari ) 1061 elem.parentNode.selectedIndex; 1062 1063 // If applicable, access the attribute via the DOM 0 way 1064 if ( name in elem && notxml && !special ) { 1065 if ( set ){ 1066 // We can't allow the type property to be changed (since it causes problems in IE) 1067 if ( name == "type" && jQuery.nodeName( elem, "input" ) && elem.parentNode ) 1068 throw "type property can't be changed"; 1069 1070 elem[ name ] = value; 1071 } 1072 1073 // browsers index elements by id/name on forms, give priority to attributes. 1074 if( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) ) 1075 return elem.getAttributeNode( name ).nodeValue; 1076 1077 return elem[ name ]; 1078 } 1079 1080 if ( msie && notxml && name == "style" ) 1081 return jQuery.attr( elem.style, "cssText", value ); 1082 1083 if ( set ) 1084 // convert the value to a string (all browsers do this but IE) see #1070 1085 elem.setAttribute( name, "" + value ); 1086 1087 var attr = msie && notxml && special 1088 // Some attributes require a special call on IE 1089 ? elem.getAttribute( name, 2 ) 1090 : elem.getAttribute( name ); 1091 1092 // Non-existent attributes return null, we normalize to undefined 1093 return attr === null ? undefined : attr; 1094 } 1095 1096 // elem is actually elem.style ... set the style 1097 1098 // IE uses filters for opacity 1099 if ( msie && name == "opacity" ) { 1100 if ( set ) { 1101 // IE has trouble with opacity if it does not have layout 1102 // Force it by setting the zoom level 1103 elem.zoom = 1; 1104 1105 // Set the alpha filter to set the opacity 1106 elem.filter = (elem.filter || "").replace( /alpha\([^)]*\)/, "" ) + 1107 (parseInt( value ) + '' == "NaN" ? "" : "alpha(opacity=" + value * 100 + ")"); 1108 } 1109 1110 return elem.filter && elem.filter.indexOf("opacity=") >= 0 ? 1111 (parseFloat( elem.filter.match(/opacity=([^)]*)/)[1] ) / 100) + '': 1112 ""; 1113 } 1114 1115 name = name.replace(/-([a-z])/ig, function(all, letter){ 1116 return letter.toUpperCase(); 1117 }); 1118 1119 if ( set ) 1120 elem[ name ] = value; 1121 1122 return elem[ name ]; 1123 }, 1124 1125 trim: function( text ) { 1126 return (text || "").replace( /^\s+|\s+$/g, "" ); 1127 }, 1128 1129 makeArray: function( array ) { 1130 var ret = []; 1131 1132 if( array != null ){ 1133 var i = array.length; 1134 //the window, strings and functions also have 'length' 1135 if( i == null || array.split || array.setInterval || array.call ) 1136 ret[0] = array; 1137 else 1138 while( i ) 1139 ret[--i] = array[i]; 1140 } 1141 1142 return ret; 1143 }, 1144 1145 inArray: function( elem, array ) { 1146 for ( var i = 0, length = array.length; i < length; i++ ) 1147 // Use === because on IE, window == document 1148 if ( array[ i ] === elem ) 1149 return i; 1150 1151 return -1; 1152 }, 1153 1154 merge: function( first, second ) { 1155 // We have to loop this way because IE & Opera overwrite the length 1156 // expando of getElementsByTagName 1157 var i = 0, elem, pos = first.length; 1158 // Also, we need to make sure that the correct elements are being returned 1159 // (IE returns comment nodes in a '*' query) 1160 if ( jQuery.browser.msie ) { 1161 while ( elem = second[ i++ ] ) 1162 if ( elem.nodeType != 8 ) 1163 first[ pos++ ] = elem; 1164 1165 } else 1166 while ( elem = second[ i++ ] ) 1167 first[ pos++ ] = elem; 1168 1169 return first; 1170 }, 1171 1172 unique: function( array ) { 1173 var ret = [], done = {}; 1174 1175 try { 1176 1177 for ( var i = 0, length = array.length; i < length; i++ ) { 1178 var id = jQuery.data( array[ i ] ); 1179 1180 if ( !done[ id ] ) { 1181 done[ id ] = true; 1182 ret.push( array[ i ] ); 1183 } 1184 } 1185 1186 } catch( e ) { 1187 ret = array; 1188 } 1189 1190 return ret; 1191 }, 1192 1193 grep: function( elems, callback, inv ) { 1194 var ret = []; 1195 1196 // Go through the array, only saving the items 1197 // that pass the validator function 1198 for ( var i = 0, length = elems.length; i < length; i++ ) 1199 if ( !inv != !callback( elems[ i ], i ) ) 1200 ret.push( elems[ i ] ); 1201 1202 return ret; 1203 }, 1204 1205 map: function( elems, callback ) { 1206 var ret = []; 1207 1208 // Go through the array, translating each of the items to their 1209 // new value (or values). 1210 for ( var i = 0, length = elems.length; i < length; i++ ) { 1211 var value = callback( elems[ i ], i ); 1212 1213 if ( value != null ) 1214 ret[ ret.length ] = value; 1215 } 1216 1217 return ret.concat.apply( [], ret ); 1218 } 1219 }); 1220 1221 var userAgent = navigator.userAgent.toLowerCase(); 1222 1223 // Figure out what browser is being used 1224 jQuery.browser = { 1225 version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [])[1], 1226 safari: /webkit/.test( userAgent ), 1227 opera: /opera/.test( userAgent ), 1228 msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ), 1229 mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent ) 1230 }; 1231 1232 var styleFloat = jQuery.browser.msie ? 1233 "styleFloat" : 1234 "cssFloat"; 1235 1236 jQuery.extend({ 1237 // Check to see if the W3C box model is being used 1238 boxModel: !jQuery.browser.msie || document.compatMode == "CSS1Compat", 1239 1240 props: { 1241 "for": "htmlFor", 1242 "class": "className", 1243 "float": styleFloat, 1244 cssFloat: styleFloat, 1245 styleFloat: styleFloat, 1246 readonly: "readOnly", 1247 maxlength: "maxLength", 1248 cellspacing: "cellSpacing" 1249 } 1250 }); 1251 1252 jQuery.each({ 1253 parent: function(elem){return elem.parentNode;}, 1254 parents: function(elem){return jQuery.dir(elem,"parentNode");}, 1255 next: function(elem){return jQuery.nth(elem,2,"nextSibling");}, 1256 prev: function(elem){return jQuery.nth(elem,2,"previousSibling");}, 1257 nextAll: function(elem){return jQuery.dir(elem,"nextSibling");}, 1258 prevAll: function(elem){return jQuery.dir(elem,"previousSibling");}, 1259 siblings: function(elem){return jQuery.sibling(elem.parentNode.firstChild,elem);}, 1260 children: function(elem){return jQuery.sibling(elem.firstChild);}, 1261 contents: function(elem){return jQuery.nodeName(elem,"iframe")?elem.contentDocument||elem.contentWindow.document:jQuery.makeArray(elem.childNodes);} 1262 }, function(name, fn){ 1263 jQuery.fn[ name ] = function( selector ) { 1264 var ret = jQuery.map( this, fn ); 1265 1266 if ( selector && typeof selector == "string" ) 1267 ret = jQuery.multiFilter( selector, ret ); 1268 1269 return this.pushStack( jQuery.unique( ret ) ); 1270 }; 1271 }); 1272 1273 jQuery.each({ 1274 appendTo: "append", 1275 prependTo: "prepend", 1276 insertBefore: "before", 1277 insertAfter: "after", 1278 replaceAll: "replaceWith" 1279 }, function(name, original){ 1280 jQuery.fn[ name ] = function() { 1281 var args = arguments; 1282 1283 return this.each(function(){ 1284 for ( var i = 0, length = args.length; i < length; i++ ) 1285 jQuery( args[ i ] )[ original ]( this ); 1286 }); 1287 }; 1288 }); 1289 1290 jQuery.each({ 1291 removeAttr: function( name ) { 1292 jQuery.attr( this, name, "" ); 1293 if (this.nodeType == 1) 1294 this.removeAttribute( name ); 1295 }, 1296 1297 addClass: function( classNames ) { 1298 jQuery.className.add( this, classNames ); 1299 }, 1300 1301 removeClass: function( classNames ) { 1302 jQuery.className.remove( this, classNames ); 1303 }, 1304 1305 toggleClass: function( classNames ) { 1306 jQuery.className[ jQuery.className.has( this, classNames ) ? "remove" : "add" ]( this, classNames ); 1307 }, 1308 1309 remove: function( selector ) { 1310 if ( !selector || jQuery.filter( selector, [ this ] ).r.length ) { 1311 // Prevent memory leaks 1312 jQuery( "*", this ).add(this).each(function(){ 1313 jQuery.event.remove(this); 1314 jQuery.removeData(this); 1315 }); 1316 if (this.parentNode) 1317 this.parentNode.removeChild( this ); 1318 } 1319 }, 1320 1321 empty: function() { 1322 // Remove element nodes and prevent memory leaks 1323 jQuery( ">*", this ).remove(); 1324 1325 // Remove any remaining nodes 1326 while ( this.firstChild ) 1327 this.removeChild( this.firstChild ); 1328 } 1329 }, function(name, fn){ 1330 jQuery.fn[ name ] = function(){ 1331 return this.each( fn, arguments ); 1332 }; 1333 }); 1334 1335 jQuery.each([ "Height", "Width" ], function(i, name){ 1336 var type = name.toLowerCase(); 1337 1338 jQuery.fn[ type ] = function( size ) { 1339 // Get window width or height 1340 return this[0] == window ? 1341 // Opera reports document.body.client[Width/Height] properly in both quirks and standards 1342 jQuery.browser.opera && document.body[ "client" + name ] || 1343 1344 // Safari reports inner[Width/Height] just fine (Mozilla and Opera include scroll bar widths) 1345 jQuery.browser.safari && window[ "inner" + name ] || 1346 1347 // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode 1348 document.compatMode == "CSS1Compat" && document.documentElement[ "client" + name ] || document.body[ "client" + name ] : 1349 1350 // Get document width or height 1351 this[0] == document ? 1352 // Either scroll[Width/Height] or offset[Width/Height], whichever is greater 1353 Math.max( 1354 Math.max(document.body["scroll" + name], document.documentElement["scroll" + name]), 1355 Math.max(document.body["offset" + name], document.documentElement["offset" + name]) 1356 ) : 1357 1358 // Get or set width or height on the element 1359 size == undefined ? 1360 // Get width or height on the element 1361 (this.length ? jQuery.css( this[0], type ) : null) : 1362 1363 // Set the width or height on the element (default to pixels if value is unitless) 1364 this.css( type, size.constructor == String ? size : size + "px" ); 1365 }; 1366 }); 1367 1368 // Helper function used by the dimensions and offset modules 1369 function num(elem, prop) { 1370 return elem[0] && parseInt( jQuery.curCSS(elem[0], prop, true), 10 ) || 0; 1371 }var chars = jQuery.browser.safari && parseInt(jQuery.browser.version) < 417 ? 1372 "(?:[\\w*_-]|\\\\.)" : 1373 "(?:[\\w\u0128-\uFFFF*_-]|\\\\.)", 1374 quickChild = new RegExp("^>\\s*(" + chars + "+)"), 1375 quickID = new RegExp("^(" + chars + "+)(#)(" + chars + "+)"), 1376 quickClass = new RegExp("^([#.]?)(" + chars + "*)"); 1377 1378 jQuery.extend({ 1379 expr: { 1380 "": function(a,i,m){return m[2]=="*"||jQuery.nodeName(a,m[2]);}, 1381 "#": function(a,i,m){return a.getAttribute("id")==m[2];}, 1382 ":": { 1383 // Position Checks 1384 lt: function(a,i,m){return i<m[3]-0;}, 1385 gt: function(a,i,m){return i>m[3]-0;}, 1386 nth: function(a,i,m){return m[3]-0==i;}, 1387 eq: function(a,i,m){return m[3]-0==i;}, 1388 first: function(a,i){return i==0;}, 1389 last: function(a,i,m,r){return i==r.length-1;}, 1390 even: function(a,i){return i%2==0;}, 1391 odd: function(a,i){return i%2;}, 1392 1393 // Child Checks 1394 "first-child": function(a){return a.parentNode.getElementsByTagName("*")[0]==a;}, 1395 "last-child": function(a){return jQuery.nth(a.parentNode.lastChild,1,"previousSibling")==a;}, 1396 "only-child": function(a){return !jQuery.nth(a.parentNode.lastChild,2,"previousSibling");}, 1397 1398 // Parent Checks 1399 parent: function(a){return a.firstChild;}, 1400 empty: function(a){return !a.firstChild;}, 1401 1402 // Text Check 1403 contains: function(a,i,m){return (a.textContent||a.innerText||jQuery(a).text()||"").indexOf(m[3])>=0;}, 1404 1405 // Visibility 1406 visible: function(a){return "hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden";}, 1407 hidden: function(a){return "hidden"==a.type||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden";}, 1408 1409 // Form attributes 1410 enabled: function(a){return !a.disabled;}, 1411 disabled: function(a){return a.disabled;}, 1412 checked: function(a){return a.checked;}, 1413 selected: function(a){return a.selected||jQuery.attr(a,"selected");}, 1414 1415 // Form elements 1416 text: function(a){return "text"==a.type;}, 1417 radio: function(a){return "radio"==a.type;}, 1418 checkbox: function(a){return "checkbox"==a.type;}, 1419 file: function(a){return "file"==a.type;}, 1420 password: function(a){return "password"==a.type;}, 1421 submit: function(a){return "submit"==a.type;}, 1422 image: function(a){return "image"==a.type;}, 1423 reset: function(a){return "reset"==a.type;}, 1424 button: function(a){return "button"==a.type||jQuery.nodeName(a,"button");}, 1425 input: function(a){return /input|select|textarea|button/i.test(a.nodeName);}, 1426 1427 // :has() 1428 has: function(a,i,m){return jQuery.find(m[3],a).length;}, 1429 1430 // :header 1431 header: function(a){return /h\d/i.test(a.nodeName);}, 1432 1433 // :animated 1434 animated: function(a){return jQuery.grep(jQuery.timers,function(fn){return a==fn.elem;}).length;} 1435 } 1436 }, 1437 1438 // The regular expressions that power the parsing engine 1439 parse: [ 1440 // Match: [@value='test'], [@foo] 1441 /^(\[) *@?([\w-]+) *([!*$^~=]*) *('?"?)(.*?)\4 *\]/, 1442 1443 // Match: :contains('foo') 1444 /^(:)([\w-]+)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/, 1445 1446 // Match: :even, :last-child, #id, .class 1447 new RegExp("^([:.#]*)(" + chars + "+)") 1448 ], 1449 1450 multiFilter: function( expr, elems, not ) { 1451 var old, cur = []; 1452 1453 while ( expr && expr != old ) { 1454 old = expr; 1455 var f = jQuery.filter( expr, elems, not ); 1456 expr = f.t.replace(/^\s*,\s*/, "" ); 1457 cur = not ? elems = f.r : jQuery.merge( cur, f.r ); 1458 } 1459 1460 return cur; 1461 }, 1462 1463 find: function( t, context ) { 1464 // Quickly handle non-string expressions 1465 if ( typeof t != "string" ) 1466 return [ t ]; 1467 1468 // check to make sure context is a DOM element or a document 1469 if ( context && context.nodeType != 1 && context.nodeType != 9) 1470 return [ ]; 1471 1472 // Set the correct context (if none is provided) 1473 context = context || document; 1474 1475 // Initialize the search 1476 var ret = [context], done = [], last, nodeName; 1477 1478 // Continue while a selector expression exists, and while 1479 // we're no longer looping upon ourselves 1480 while ( t && last != t ) { 1481 var r = []; 1482 last = t; 1483 1484 t = jQuery.trim(t); 1485 1486 var foundToken = false, 1487 1488 // An attempt at speeding up child selectors that 1489 // point to a specific element tag 1490 re = quickChild, 1491 1492 m = re.exec(t); 1493 1494 if ( m ) { 1495 nodeName = m[1].toUpperCase(); 1496 1497 // Perform our own iteration and filter 1498 for ( var i = 0; ret[i]; i++ ) 1499 for ( var c = ret[i].firstChild; c; c = c.nextSibling ) 1500 if ( c.nodeType == 1 && (nodeName == "*" || c.nodeName.toUpperCase() == nodeName) ) 1501 r.push( c ); 1502 1503 ret = r; 1504 t = t.replace( re, "" ); 1505 if ( t.indexOf(" ") == 0 ) continue; 1506 foundToken = true; 1507 } else { 1508 re = /^([>+~])\s*(\w*)/i; 1509 1510 if ( (m = re.exec(t)) != null ) { 1511 r = []; 1512 1513 var merge = {}; 1514 nodeName = m[2].toUpperCase(); 1515 m = m[1]; 1516 1517 for ( var j = 0, rl = ret.length; j < rl; j++ ) { 1518 var n = m == "~" || m == "+" ? ret[j].nextSibling : ret[j].firstChild; 1519 for ( ; n; n = n.nextSibling ) 1520 if ( n.nodeType == 1 ) { 1521 var id = jQuery.data(n); 1522 1523 if ( m == "~" && merge[id] ) break; 1524 1525 if (!nodeName || n.nodeName.toUpperCase() == nodeName ) { 1526 if ( m == "~" ) merge[id] = true; 1527 r.push( n ); 1528 } 1529 1530 if ( m == "+" ) break; 1531 } 1532 } 1533 1534 ret = r; 1535 1536 // And remove the token 1537 t = jQuery.trim( t.replace( re, "" ) ); 1538 foundToken = true; 1539 } 1540 } 1541 1542 // See if there's still an expression, and that we haven't already 1543 // matched a token 1544 if ( t && !foundToken ) { 1545 // Handle multiple expressions 1546 if ( !t.indexOf(",") ) { 1547 // Clean the result set 1548 if ( context == ret[0] ) ret.shift(); 1549 1550 // Merge the result sets 1551 done = jQuery.merge( done, ret ); 1552 1553 // Reset the context 1554 r = ret = [context]; 1555 1556 // Touch up the selector string 1557 t = " " + t.substr(1,t.length); 1558 1559 } else { 1560 // Optimize for the case nodeName#idName 1561 var re2 = quickID; 1562 var m = re2.exec(t); 1563 1564 // Re-organize the results, so that they're consistent 1565 if ( m ) { 1566 m = [ 0, m[2], m[3], m[1] ]; 1567 1568 } else { 1569 // Otherwise, do a traditional filter check for 1570 // ID, class, and element selectors 1571 re2 = quickClass; 1572 m = re2.exec(t); 1573 } 1574 1575 m[2] = m[2].replace(/\\/g, ""); 1576 1577 var elem = ret[ret.length-1]; 1578 1579 // Try to do a global search by ID, where we can 1580 if ( m[1] == "#" && elem && elem.getElementById && !jQuery.isXMLDoc(elem) ) { 1581 // Optimization for HTML document case 1582 var oid = elem.getElementById(m[2]); 1583 1584 // Do a quick check for the existence of the actual ID attribute 1585 // to avoid selecting by the name attribute in IE 1586 // also check to insure id is a string to avoid selecting an element with the name of 'id' inside a form 1587 if ( (jQuery.browser.msie||jQuery.browser.opera) && oid && typeof oid.id == "string" && oid.id != m[2] ) 1588 oid = jQuery('[@id="'+m[2]+'"]', elem)[0]; 1589 1590 // Do a quick check for node name (where applicable) so 1591 // that div#foo searches will be really fast 1592 ret = r = oid && (!m[3] || jQuery.nodeName(oid, m[3])) ? [oid] : []; 1593 } else { 1594 // We need to find all descendant elements 1595 for ( var i = 0; ret[i]; i++ ) { 1596 // Grab the tag name being searched for 1597 var tag = m[1] == "#" && m[3] ? m[3] : m[1] != "" || m[0] == "" ? "*" : m[2]; 1598 1599 // Handle IE7 being really dumb about <object>s 1600 if ( tag == "*" && ret[i].nodeName.toLowerCase() == "object" ) 1601 tag = "param"; 1602 1603 r = jQuery.merge( r, ret[i].getElementsByTagName( tag )); 1604 } 1605 1606 // It's faster to filter by class and be done with it 1607 if ( m[1] == "." ) 1608 r = jQuery.classFilter( r, m[2] ); 1609 1610 // Same with ID filtering 1611 if ( m[1] == "#" ) { 1612 var tmp = []; 1613 1614 // Try to find the element with the ID 1615 for ( var i = 0; r[i]; i++ ) 1616 if ( r[i].getAttribute("id") == m[2] ) { 1617 tmp = [ r[i] ]; 1618 break; 1619 } 1620 1621 r = tmp; 1622 } 1623 1624 ret = r; 1625 } 1626 1627 t = t.replace( re2, "" ); 1628 } 1629 1630 } 1631 1632 // If a selector string still exists 1633 if ( t ) { 1634 // Attempt to filter it 1635 var val = jQuery.filter(t,r); 1636 ret = r = val.r; 1637 t = jQuery.trim(val.t); 1638 } 1639 } 1640 1641 // An error occurred with the selector; 1642 // just return an empty set instead 1643 if ( t ) 1644 ret = []; 1645 1646 // Remove the root context 1647 if ( ret && context == ret[0] ) 1648 ret.shift(); 1649 1650 // And combine the results 1651 done = jQuery.merge( done, ret ); 1652 1653 return done; 1654 }, 1655 1656 classFilter: function(r,m,not){ 1657 m = " " + m + " "; 1658 var tmp = []; 1659 for ( var i = 0; r[i]; i++ ) { 1660 var pass = (" " + r[i].className + " ").indexOf( m ) >= 0; 1661 if ( !not && pass || not && !pass ) 1662 tmp.push( r[i] ); 1663 } 1664 return tmp; 1665 }, 1666 1667 filter: function(t,r,not) { 1668 var last; 1669 1670 // Look for common filter expressions 1671 while ( t && t != last ) { 1672 last = t; 1673 1674 var p = jQuery.parse, m; 1675 1676 for ( var i = 0; p[i]; i++ ) { 1677 m = p[i].exec( t ); 1678 1679 if ( m ) { 1680 // Remove what we just matched 1681 t = t.substring( m[0].length ); 1682 1683 m[2] = m[2].replace(/\\/g, ""); 1684 break; 1685 } 1686 } 1687 1688 if ( !m ) 1689 break; 1690 1691 // :not() is a special case that can be optimized by 1692 // keeping it out of the expression list 1693 if ( m[1] == ":" && m[2] == "not" ) 1694 // optimize if only one selector found (most common case) 1695 r = isSimple.test( m[3] ) ? 1696 jQuery.filter(m[3], r, true).r : 1697 jQuery( r ).not( m[3] ); 1698 1699 // We can get a big speed boost by filtering by class here 1700 else if ( m[1] == "." ) 1701 r = jQuery.classFilter(r, m[2], not); 1702 1703 else if ( m[1] == "[" ) { 1704 var tmp = [], type = m[3]; 1705 1706 for ( var i = 0, rl = r.length; i < rl; i++ ) { 1707 var a = r[i], z = a[ jQuery.props[m[2]] || m[2] ]; 1708 1709 if ( z == null || /href|src|selected/.test(m[2]) ) 1710 z = jQuery.attr(a,m[2]) || ''; 1711 1712 if ( (type == "" && !!z || 1713 type == "=" && z == m[5] || 1714 type == "!=" && z != m[5] || 1715 type == "^=" && z && !z.indexOf(m[5]) || 1716 type == "$=" && z.substr(z.length - m[5].length) == m[5] || 1717 (type == "*=" || type == "~=") && z.indexOf(m[5]) >= 0) ^ not ) 1718 tmp.push( a ); 1719 } 1720 1721 r = tmp; 1722 1723 // We can get a speed boost by handling nth-child here 1724 } else if ( m[1] == ":" && m[2] == "nth-child" ) { 1725 var merge = {}, tmp = [], 1726 // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6' 1727 test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec( 1728 m[3] == "even" && "2n" || m[3] == "odd" && "2n+1" || 1729 !/\D/.test(m[3]) && "0n+" + m[3] || m[3]), 1730 // calculate the numbers (first)n+(last) including if they are negative 1731 first = (test[1] + (test[2] || 1)) - 0, last = test[3] - 0; 1732 1733 // loop through all the elements left in the jQuery object 1734 for ( var i = 0, rl = r.length; i < rl; i++ ) { 1735 var node = r[i], parentNode = node.parentNode, id = jQuery.data(parentNode); 1736 1737 if ( !merge[id] ) { 1738 var c = 1; 1739 1740 for ( var n = parentNode.firstChild; n; n = n.nextSibling ) 1741 if ( n.nodeType == 1 ) 1742 n.nodeIndex = c++; 1743 1744 merge[id] = true; 1745 } 1746 1747 var add = false; 1748 1749 if ( first == 0 ) { 1750 if ( node.nodeIndex == last ) 1751 add = true; 1752 } else if ( (node.nodeIndex - last) % first == 0 && (node.nodeIndex - last) / first >= 0 ) 1753 add = true; 1754 1755 if ( add ^ not ) 1756 tmp.push( node ); 1757 } 1758 1759 r = tmp; 1760 1761 // Otherwise, find the expression to execute 1762 } else { 1763 var fn = jQuery.expr[ m[1] ]; 1764 if ( typeof fn == "object" ) 1765 fn = fn[ m[2] ]; 1766 1767 if ( typeof fn == "string" ) 1768 fn = eval("false||function(a,i){return " + fn + ";}"); 1769 1770 // Execute it against the current filter 1771 r = jQuery.grep( r, function(elem, i){ 1772 return fn(elem, i, m, r); 1773 }, not ); 1774 } 1775 } 1776 1777 // Return an array of filtered elements (r) 1778 // and the modified expression string (t) 1779 return { r: r, t: t }; 1780 }, 1781 1782 dir: function( elem, dir ){ 1783 var matched = [], 1784 cur = elem[dir]; 1785 while ( cur && cur != document ) { 1786 if ( cur.nodeType == 1 ) 1787 matched.push( cur ); 1788 cur = cur[dir]; 1789 } 1790 return matched; 1791 }, 1792 1793 nth: function(cur,result,dir,elem){ 1794 result = result || 1; 1795 var num = 0; 1796 1797 for ( ; cur; cur = cur[dir] ) 1798 if ( cur.nodeType == 1 && ++num == result ) 1799 break; 1800 1801 return cur; 1802 }, 1803 1804 sibling: function( n, elem ) { 1805 var r = []; 1806 1807 for ( ; n; n = n.nextSibling ) { 1808 if ( n.nodeType == 1 && n != elem ) 1809 r.push( n ); 1810 } 1811 1812 return r; 1813 } 1814 }); 1815 /* 1816 * A number of helper functions used for managing events. 1817 * Many of the ideas behind this code orignated from 1818 * Dean Edwards' addEvent library. 1819 */ 1820 jQuery.event = { 1821 1822 // Bind an event to an element 1823 // Original by Dean Edwards 1824 add: function(elem, types, handler, data) { 1825 if ( elem.nodeType == 3 || elem.nodeType == 8 ) 1826 return; 1827 1828 // For whatever reason, IE has trouble passing the window object 1829 // around, causing it to be cloned in the process 1830 if ( jQuery.browser.msie && elem.setInterval ) 1831 elem = window; 1832 1833 // Make sure that the function being executed has a unique ID 1834 if ( !handler.guid ) 1835 handler.guid = this.guid++; 1836 1837 // if data is passed, bind to handler 1838 if( data != undefined ) { 1839 // Create temporary function pointer to original handler 1840 var fn = handler; 1841 1842 // Create unique handler function, wrapped around original handler 1843 handler = this.proxy( fn, function() { 1844 // Pass arguments and context to original handler 1845 return fn.apply(this, arguments); 1846 }); 1847 1848 // Store data in unique handler 1849 handler.data = data; 1850 } 1851 1852 // Init the element's event structure 1853 var events = jQuery.data(elem, "events") || jQuery.data(elem, "events", {}), 1854 handle = jQuery.data(elem, "handle") || jQuery.data(elem, "handle", function(){ 1855 // Handle the second event of a trigger and when 1856 // an event is called after a page has unloaded 1857 if ( typeof jQuery != "undefined" && !jQuery.event.triggered ) 1858 return jQuery.event.handle.apply(arguments.callee.elem, arguments); 1859 }); 1860 // Add elem as a property of the handle function 1861 // This is to prevent a memory leak with non-native 1862 // event in IE. 1863 handle.elem = elem; 1864 1865 // Handle multiple events separated by a space 1866 // jQuery(...).bind("mouseover mouseout", fn); 1867 jQuery.each(types.split(/\s+/), function(index, type) { 1868 // Namespaced event handlers 1869 var parts = type.split("."); 1870 type = parts[0]; 1871 handler.type = parts[1]; 1872 1873 // Get the current list of functions bound to this event 1874 var handlers = events[type]; 1875 1876 // Init the event handler queue 1877 if (!handlers) { 1878 handlers = events[type] = {}; 1879 1880 // Check for a special event handler 1881 // Only use addEventListener/attachEvent if the special 1882 // events handler returns false 1883 if ( !jQuery.event.special[type] || jQuery.event.special[type].setup.call(elem) === false ) { 1884 // Bind the global event handler to the element 1885 if (elem.addEventListener) 1886 elem.addEventListener(type, handle, false); 1887 else if (elem.attachEvent) 1888 elem.attachEvent("on" + type, handle); 1889 } 1890 } 1891 1892 // Add the function to the element's handler list 1893 handlers[handler.guid] = handler; 1894 1895 // Keep track of which events have been used, for global triggering 1896 jQuery.event.global[type] = true; 1897 }); 1898 1899 // Nullify elem to prevent memory leaks in IE 1900 elem = null; 1901 }, 1902 1903 guid: 1, 1904 global: {}, 1905 1906 // Detach an event or set of events from an element 1907 remove: function(elem, types, handler) { 1908 // don't do events on text and comment nodes 1909 if ( elem.nodeType == 3 || elem.nodeType == 8 ) 1910 return; 1911 1912 var events = jQuery.data(elem, "events"), ret, index; 1913 1914 if ( events ) { 1915 // Unbind all events for the element 1916 if ( types == undefined || (typeof types == "string" && types.charAt(0) == ".") ) 1917 for ( var type in events ) 1918 this.remove( elem, type + (types || "") ); 1919 else { 1920 // types is actually an event object here 1921 if ( types.type ) { 1922 handler = types.handler; 1923 types = types.type; 1924 } 1925 1926 // Handle multiple events seperated by a space 1927 // jQuery(...).unbind("mouseover mouseout", fn); 1928 jQuery.each(types.split(/\s+/), function(index, type){ 1929 // Namespaced event handlers 1930 var parts = type.split("."); 1931 type = parts[0]; 1932 1933 if ( events[type] ) { 1934 // remove the given handler for the given type 1935 if ( handler ) 1936 delete events[type][handler.guid]; 1937 1938 // remove all handlers for the given type 1939 else 1940 for ( handler in events[type] ) 1941 // Handle the removal of namespaced events 1942 if ( !parts[1] || events[type][handler].type == parts[1] ) 1943 delete events[type][handler]; 1944 1945 // remove generic event handler if no more handlers exist 1946 for ( ret in events[type] ) break; 1947 if ( !ret ) { 1948 if ( !jQuery.event.special[type] || jQuery.event.special[type].teardown.call(elem) === false ) { 1949 if (elem.removeEventListener) 1950 elem.removeEventListener(type, jQuery.data(elem, "handle"), false); 1951 else if (elem.detachEvent) 1952 elem.detachEvent("on" + type, jQuery.data(elem, "handle")); 1953 } 1954 ret = null; 1955 delete events[type]; 1956 } 1957 } 1958 }); 1959 } 1960 1961 // Remove the expando if it's no longer used 1962 for ( ret in events ) break; 1963 if ( !ret ) { 1964 var handle = jQuery.data( elem, "handle" ); 1965 if ( handle ) handle.elem = null; 1966 jQuery.removeData( elem, "events" ); 1967 jQuery.removeData( elem, "handle" ); 1968 } 1969 } 1970 }, 1971 1972 trigger: function(type, data, elem, donative, extra) { 1973 // Clone the incoming data, if any 1974 data = jQuery.makeArray(data); 1975 1976 if ( type.indexOf("!") >= 0 ) { 1977 type = type.slice(0, -1); 1978 var exclusive = true; 1979 } 1980 1981 // Handle a global trigger 1982 if ( !elem ) { 1983 // Only trigger if we've ever bound an event for it 1984 if ( this.global[type] ) 1985 jQuery("*").add([window, document]).trigger(type, data); 1986 1987 // Handle triggering a single element 1988 } else { 1989 // don't do events on text and comment nodes 1990 if ( elem.nodeType == 3 || elem.nodeType == 8 ) 1991 return undefined; 1992 1993 var val, ret, fn = jQuery.isFunction( elem[ type ] || null ), 1994 // Check to see if we need to provide a fake event, or not 1995 event = !data[0] || !data[0].preventDefault; 1996 1997 // Pass along a fake event 1998 if ( event ) { 1999 data.unshift({ 2000 type: type, 2001 target: elem, 2002 preventDefault: function(){}, 2003 stopPropagation: function(){}, 2004 timeStamp: now() 2005 }); 2006 data[0][expando] = true; // no need to fix fake event 2007 } 2008 2009 // Enforce the right trigger type 2010 data[0].type = type; 2011 if ( exclusive ) 2012 data[0].exclusive = true; 2013 2014 // Trigger the event, it is assumed that "handle" is a function 2015 var handle = jQuery.data(elem, "handle"); 2016 if ( handle ) 2017 val = handle.apply( elem, data ); 2018 2019 // Handle triggering native .onfoo handlers (and on links since we don't call .click() for links) 2020 if ( (!fn || (jQuery.nodeName(elem, 'a') && type == "click")) && elem["on"+type] && elem["on"+type].apply( elem, data ) === false ) 2021 val = false; 2022 2023 // Extra functions don't get the custom event object 2024 if ( event ) 2025 data.shift(); 2026 2027 // Handle triggering of extra function 2028 if ( extra && jQuery.isFunction( extra ) ) { 2029 // call the extra function and tack the current return value on the end for possible inspection 2030 ret = extra.apply( elem, val == null ? data : data.concat( val ) ); 2031 // if anything is returned, give it precedence and have it overwrite the previous value 2032 if (ret !== undefined) 2033 val = ret; 2034 } 2035 2036 // Trigger the native events (except for clicks on links) 2037 if ( fn && donative !== false && val !== false && !(jQuery.nodeName(elem, 'a') && type == "click") ) { 2038 this.triggered = true; 2039 try { 2040 elem[ type ](); 2041 // prevent IE from throwing an error for some hidden elements 2042 } catch (e) {} 2043 } 2044 2045 this.triggered = false; 2046 } 2047 2048 return val; 2049 }, 2050 2051 handle: function(event) { 2052 // returned undefined or false 2053 var val, ret, namespace, all, handlers; 2054 2055 event = arguments[0] = jQuery.event.fix( event || window.event ); 2056 2057 // Namespaced event handlers 2058 namespace = event.type.split("."); 2059 event.type = namespace[0]; 2060 namespace = namespace[1]; 2061 // Cache this now, all = true means, any handler 2062 all = !namespace && !event.exclusive; 2063 2064 handlers = ( jQuery.data(this, "events") || {} )[event.type]; 2065 2066 for ( var j in handlers ) { 2067 var handler = handlers[j]; 2068 2069 // Filter the functions by class 2070 if ( all || handler.type == namespace ) { 2071 // Pass in a reference to the handler function itself 2072 // So that we can later remove it 2073 event.handler = handler; 2074 event.data = handler.data; 2075 2076 ret = handler.apply( this, arguments ); 2077 2078 if ( val !== false ) 2079 val = ret; 2080 2081 if ( ret === false ) { 2082 event.preventDefault(); 2083 event.stopPropagation(); 2084 } 2085 } 2086 } 2087 2088 return val; 2089 }, 2090 2091 fix: function(event) { 2092 if ( event[expando] == true ) 2093 return event; 2094 2095 // store a copy of the original event object 2096 // and "clone" to set read-only properties 2097 var originalEvent = event; 2098 event = { originalEvent: originalEvent }; 2099 var props = "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target timeStamp toElement type view wheelDelta which".split(" "); 2100 for ( var i=props.length; i; i-- ) 2101 event[ props[i] ] = originalEvent[ props[i] ]; 2102 2103 // Mark it as fixed 2104 event[expando] = true; 2105 2106 // add preventDefault and stopPropagation since 2107 // they will not work on the clone 2108 event.preventDefault = function() { 2109 // if preventDefault exists run it on the original event 2110 if (originalEvent.preventDefault) 2111 originalEvent.preventDefault(); 2112 // otherwise set the returnValue property of the original event to false (IE) 2113 originalEvent.returnValue = false; 2114 }; 2115 event.stopPropagation = function() { 2116 // if stopPropagation exists run it on the original event 2117 if (originalEvent.stopPropagation) 2118 originalEvent.stopPropagation(); 2119 // otherwise set the cancelBubble property of the original event to true (IE) 2120 originalEvent.cancelBubble = true; 2121 }; 2122 2123 // Fix timeStamp 2124 event.timeStamp = event.timeStamp || now(); 2125 2126 // Fix target property, if necessary 2127 if ( !event.target ) 2128 event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either 2129 2130 // check if target is a textnode (safari) 2131 if ( event.target.nodeType == 3 ) 2132 event.target = event.target.parentNode; 2133 2134 // Add relatedTarget, if necessary 2135 if ( !event.relatedTarget && event.fromElement ) 2136 event.relatedTarget = event.fromElement == event.target ? event.toElement : event.fromElement; 2137 2138 // Calculate pageX/Y if missing and clientX/Y available 2139 if ( event.pageX == null && event.clientX != null ) { 2140 var doc = document.documentElement, body = document.body; 2141 event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc.clientLeft || 0); 2142 event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc.clientTop || 0); 2143 } 2144 2145 // Add which for key events 2146 if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) ) 2147 event.which = event.charCode || event.keyCode; 2148 2149 // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs) 2150 if ( !event.metaKey && event.ctrlKey ) 2151 event.metaKey = event.ctrlKey; 2152 2153 // Add which for click: 1 == left; 2 == middle; 3 == right 2154 // Note: button is not normalized, so don't use it 2155 if ( !event.which && event.button ) 2156 event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) )); 2157 2158 return event; 2159 }, 2160 2161 proxy: function( fn, proxy ){ 2162 // Set the guid of unique handler to the same of original handler, so it can be removed 2163 proxy.guid = fn.guid = fn.guid || proxy.guid || this.guid++; 2164 // So proxy can be declared as an argument 2165 return proxy; 2166 }, 2167 2168 special: { 2169 ready: { 2170 setup: function() { 2171 // Make sure the ready event is setup 2172 bindReady(); 2173 return; 2174 }, 2175 2176 teardown: function() { return; } 2177 }, 2178 2179 mouseenter: { 2180 setup: function() { 2181 if ( jQuery.browser.msie ) return false; 2182 jQuery(this).bind("mouseover", jQuery.event.special.mouseenter.handler); 2183 return true; 2184 }, 2185 2186 teardown: function() { 2187 if ( jQuery.browser.msie ) return false; 2188 jQuery(this).unbind("mouseover", jQuery.event.special.mouseenter.handler); 2189 return true; 2190 }, 2191 2192 handler: function(event) { 2193 // If we actually just moused on to a sub-element, ignore it 2194 if ( withinElement(event, this) ) return true; 2195 // Execute the right handlers by setting the event type to mouseenter 2196 event.type = "mouseenter"; 2197 return jQuery.event.handle.apply(this, arguments); 2198 } 2199 }, 2200 2201 mouseleave: { 2202 setup: function() { 2203 if ( jQuery.browser.msie ) return false; 2204 jQuery(this).bind("mouseout", jQuery.event.special.mouseleave.handler); 2205 return true; 2206 }, 2207 2208 teardown: function() { 2209 if ( jQuery.browser.msie ) return false; 2210 jQuery(this).unbind("mouseout", jQuery.event.special.mouseleave.handler); 2211 return true; 2212 }, 2213 2214 handler: function(event) { 2215 // If we actually just moused on to a sub-element, ignore it 2216 if ( withinElement(event, this) ) return true; 2217 // Execute the right handlers by setting the event type to mouseleave 2218 event.type = "mouseleave"; 2219 return jQuery.event.handle.apply(this, arguments); 2220 } 2221 } 2222 } 2223 }; 2224 2225 jQuery.fn.extend({ 2226 bind: function( type, data, fn ) { 2227 return type == "unload" ? this.one(type, data, fn) : this.each(function(){ 2228 jQuery.event.add( this, type, fn || data, fn && data ); 2229 }); 2230 }, 2231 2232 one: function( type, data, fn ) { 2233 var one = jQuery.event.proxy( fn || data, function(event) { 2234 jQuery(this).unbind(event, one); 2235 return (fn || data).apply( this, arguments ); 2236 }); 2237 return this.each(function(){ 2238 jQuery.event.add( this, type, one, fn && data); 2239 }); 2240 }, 2241 2242 unbind: function( type, fn ) { 2243 return this.each(function(){ 2244 jQuery.event.remove( this, type, fn ); 2245 }); 2246 }, 2247 2248 trigger: function( type, data, fn ) { 2249 return this.each(function(){ 2250 jQuery.event.trigger( type, data, this, true, fn ); 2251 }); 2252 }, 2253 2254 triggerHandler: function( type, data, fn ) { 2255 return this[0] && jQuery.event.trigger( type, data, this[0], false, fn ); 2256 }, 2257 2258 toggle: function( fn ) { 2259 // Save reference to arguments for access in closure 2260 var args = arguments, i = 1; 2261 2262 // link all the functions, so any of them can unbind this click handler 2263 while( i < args.length ) 2264 jQuery.event.proxy( fn, args[i++] ); 2265 2266 return this.click( jQuery.event.proxy( fn, function(event) { 2267 // Figure out which function to execute 2268 this.lastToggle = ( this.lastToggle || 0 ) % i; 2269 2270 // Make sure that clicks stop 2271 event.preventDefault(); 2272 2273 // and execute the function 2274 return args[ this.lastToggle++ ].apply( this, arguments ) || false; 2275 })); 2276 }, 2277 2278 hover: function(fnOver, fnOut) { 2279 return this.bind('mouseenter', fnOver).bind('mouseleave', fnOut); 2280 }, 2281 2282 ready: function(fn) { 2283 // Attach the listeners 2284 bindReady(); 2285 2286 // If the DOM is already ready 2287 if ( jQuery.isReady ) 2288 // Execute the function immediately 2289 fn.call( document, jQuery ); 2290 2291 // Otherwise, remember the function for later 2292 else 2293 // Add the function to the wait list 2294 jQuery.readyList.push( function() { return fn.call(this, jQuery); } ); 2295 2296 return this; 2297 } 2298 }); 2299 2300 jQuery.extend({ 2301 isReady: false, 2302 readyList: [], 2303 // Handle when the DOM is ready 2304 ready: function() { 2305 // Make sure that the DOM is not already loaded 2306 if ( !jQuery.isReady ) { 2307 // Remember that the DOM is ready 2308 jQuery.isReady = true; 2309 2310 // If there are functions bound, to execute 2311 if ( jQuery.readyList ) { 2312 // Execute all of them 2313 jQuery.each( jQuery.readyList, function(){ 2314 this.call( document ); 2315 }); 2316 2317 // Reset the list of functions 2318 jQuery.readyList = null; 2319 } 2320 2321 // Trigger any bound ready events 2322 jQuery(document).triggerHandler("ready"); 2323 } 2324 } 2325 }); 2326 2327 var readyBound = false; 2328 2329 function bindReady(){ 2330 if ( readyBound ) return; 2331 readyBound = true; 2332 2333 // Mozilla, Opera (see further below for it) and webkit nightlies currently support this event 2334 if ( document.addEventListener && !jQuery.browser.opera) 2335 // Use the handy event callback 2336 document.addEventListener( "DOMContentLoaded", jQuery.ready, false ); 2337 2338 // If IE is used and is not in a frame 2339 // Continually check to see if the document is ready 2340 if ( jQuery.browser.msie && window == top ) (function(){ 2341 if (jQuery.isReady) return; 2342 try { 2343 // If IE is used, use the trick by Diego Perini 2344 // http://javascript.nwbox.com/IEContentLoaded/ 2345 document.documentElement.doScroll("left"); 2346 } catch( error ) { 2347 setTimeout( arguments.callee, 0 ); 2348 return; 2349 } 2350 // and execute any waiting functions 2351 jQuery.ready(); 2352 })(); 2353 2354 if ( jQuery.browser.opera ) 2355 document.addEventListener( "DOMContentLoaded", function () { 2356 if (jQuery.isReady) return; 2357 for (var i = 0; i < document.styleSheets.length; i++) 2358 if (document.styleSheets[i].disabled) { 2359 setTimeout( arguments.callee, 0 ); 2360 return; 2361 } 2362 // and execute any waiting functions 2363 jQuery.ready(); 2364 }, false); 2365 2366 if ( jQuery.browser.safari ) { 2367 var numStyles; 2368 (function(){ 2369 if (jQuery.isReady) return; 2370 if ( document.readyState != "loaded" && document.readyState != "complete" ) { 2371 setTimeout( arguments.callee, 0 ); 2372 return; 2373 } 2374 if ( numStyles === undefined ) 2375 numStyles = jQuery("style, link[rel=stylesheet]").length; 2376 if ( document.styleSheets.length != numStyles ) { 2377 setTimeout( arguments.callee, 0 ); 2378 return; 2379 } 2380 // and execute any waiting functions 2381 jQuery.ready(); 2382 })(); 2383 } 2384 2385 // A fallback to window.onload, that will always work 2386 jQuery.event.add( window, "load", jQuery.ready ); 2387 } 2388 2389 jQuery.each( ("blur,focus,load,resize,scroll,unload,click,dblclick," + 2390 "mousedown,mouseup,mousemove,mouseover,mouseout,change,select," + 2391 "submit,keydown,keypress,keyup,error").split(","), function(i, name){ 2392 2393 // Handle event binding 2394 jQuery.fn[name] = function(fn){ 2395 return fn ? this.bind(name, fn) : this.trigger(name); 2396 }; 2397 }); 2398 2399 // Checks if an event happened on an element within another element 2400 // Used in jQuery.event.special.mouseenter and mouseleave handlers 2401 var withinElement = function(event, elem) { 2402 // Check if mouse(over|out) are still within the same parent element 2403 var parent = event.relatedTarget; 2404 // Traverse up the tree 2405 while ( parent && parent != elem ) try { parent = parent.parentNode; } catch(error) { parent = elem; } 2406 // Return true if we actually just moused on to a sub-element 2407 return parent == elem; 2408 }; 2409 2410 // Prevent memory leaks in IE 2411 // And prevent errors on refresh with events like mouseover in other browsers 2412 // Window isn't included so as not to unbind existing unload events 2413 jQuery(window).bind("unload", function() { 2414 jQuery("*").add(document).unbind(); 2415 }); 2416 jQuery.fn.extend({ 2417 // Keep a copy of the old load 2418 _load: jQuery.fn.load, 2419 2420 load: function( url, params, callback ) { 2421 if ( typeof url != 'string' ) 2422 return this._load( url ); 2423 2424 var off = url.indexOf(" "); 2425 if ( off >= 0 ) { 2426 var selector = url.slice(off, url.length); 2427 url = url.slice(0, off); 2428 } 2429 2430 callback = callback || function(){}; 2431 2432 // Default to a GET request 2433 var type = "GET"; 2434 2435 // If the second parameter was provided 2436 if ( params ) 2437 // If it's a function 2438 if ( jQuery.isFunction( params ) ) { 2439 // We assume that it's the callback 2440 callback = params; 2441 params = null; 2442 2443 // Otherwise, build a param string 2444 } else { 2445 params = jQuery.param( params ); 2446 type = "POST"; 2447 } 2448 2449 var self = this; 2450 2451 // Request the remote document 2452 jQuery.ajax({ 2453 url: url, 2454 type: type, 2455 dataType: "html", 2456 data: params, 2457 complete: function(res, status){ 2458 // If successful, inject the HTML into all the matched elements 2459 if ( status == "success" || status == "notmodified" ) 2460 // See if a selector was specified 2461 self.html( selector ? 2462 // Create a dummy div to hold the results 2463 jQuery("<div/>") 2464 // inject the contents of the document in, removing the scripts 2465 // to avoid any 'Permission Denied' errors in IE 2466 .append(res.responseText.replace(/<script(.|\s)*?\/script>/g, "")) 2467 2468 // Locate the specified elements 2469 .find(selector) : 2470 2471 // If not, just inject the full result 2472 res.responseText ); 2473 2474 self.each( callback, [res.responseText, status, res] ); 2475 } 2476 }); 2477 return this; 2478 }, 2479 2480 serialize: function() { 2481 return jQuery.param(this.serializeArray()); 2482 }, 2483 serializeArray: function() { 2484 return this.map(function(){ 2485 return jQuery.nodeName(this, "form") ? 2486 jQuery.makeArray(this.elements) : this; 2487 }) 2488 .filter(function(){ 2489 return this.name && !this.disabled && 2490 (this.checked || /select|textarea/i.test(this.nodeName) || 2491 /text|hidden|password/i.test(this.type)); 2492 }) 2493 .map(function(i, elem){ 2494 var val = jQuery(this).val(); 2495 return val == null ? null : 2496 val.constructor == Array ? 2497 jQuery.map( val, function(val, i){ 2498 return {name: elem.name, value: val}; 2499 }) : 2500 {name: elem.name, value: val}; 2501 }).get(); 2502 } 2503 }); 2504 2505 // Attach a bunch of functions for handling common AJAX events 2506 jQuery.each( "ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","), function(i,o){ 2507 jQuery.fn[o] = function(f){ 2508 return this.bind(o, f); 2509 }; 2510 }); 2511 2512 var jsc = now(); 2513 2514 jQuery.extend({ 2515 get: function( url, data, callback, type ) { 2516 // shift arguments if data argument was ommited 2517 if ( jQuery.isFunction( data ) ) { 2518 callback = data; 2519 data = null; 2520 } 2521 2522 return jQuery.ajax({ 2523 type: "GET", 2524 url: url, 2525 data: data, 2526 success: callback, 2527 dataType: type 2528 }); 2529 }, 2530 2531 getScript: function( url, callback ) { 2532 return jQuery.get(url, null, callback, "script"); 2533 }, 2534 2535 getJSON: function( url, data, callback ) { 2536 return jQuery.get(url, data, callback, "json"); 2537 }, 2538 2539 post: function( url, data, callback, type ) { 2540 if ( jQuery.isFunction( data ) ) { 2541 callback = data; 2542 data = {}; 2543 } 2544 2545 return jQuery.ajax({ 2546 type: "POST", 2547 url: url, 2548 data: data, 2549 success: callback, 2550 dataType: type 2551 }); 2552 }, 2553 2554 ajaxSetup: function( settings ) { 2555 jQuery.extend( jQuery.ajaxSettings, settings ); 2556 }, 2557 2558 ajaxSettings: { 2559 url: location.href, 2560 global: true, 2561 type: "GET", 2562 timeout: 0, 2563 contentType: "application/x-www-form-urlencoded", 2564 processData: true, 2565 async: true, 2566 data: null, 2567 username: null, 2568 password: null, 2569 accepts: { 2570 xml: "application/xml, text/xml", 2571 html: "text/html", 2572 script: "text/javascript, application/javascript", 2573 json: "application/json, text/javascript", 2574 text: "text/plain", 2575 _default: "*/*" 2576 } 2577 }, 2578 2579 // Last-Modified header cache for next request 2580 lastModified: {}, 2581 2582 ajax: function( s ) { 2583 // Extend the settings, but re-extend 's' so that it can be 2584 // checked again later (in the test suite, specifically) 2585 s = jQuery.extend(true, s, jQuery.extend(true, {}, jQuery.ajaxSettings, s)); 2586 2587 var jsonp, jsre = /=\?(&|$)/g, status, data, 2588 type = s.type.toUpperCase(); 2589 2590 // convert data if not already a string 2591 if ( s.data && s.processData && typeof s.data != "string" ) 2592 s.data = jQuery.param(s.data); 2593 2594 // Handle JSONP Parameter Callbacks 2595 if ( s.dataType == "jsonp" ) { 2596 if ( type == "GET" ) { 2597 if ( !s.url.match(jsre) ) 2598 s.url += (s.url.match(/\?/) ? "&" : "?") + (s.jsonp || "callback") + "=?"; 2599 } else if ( !s.data || !s.data.match(jsre) ) 2600 s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?"; 2601 s.dataType = "json"; 2602 } 2603 2604 // Build temporary JSONP function 2605 if ( s.dataType == "json" && (s.data && s.data.match(jsre) || s.url.match(jsre)) ) { 2606 jsonp = "jsonp" + jsc++; 2607 2608 // Replace the =? sequence both in the query string and the data 2609 if ( s.data ) 2610 s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1"); 2611 s.url = s.url.replace(jsre, "=" + jsonp + "$1"); 2612 2613 // We need to make sure 2614 // that a JSONP style response is executed properly 2615 s.dataType = "script"; 2616 2617 // Handle JSONP-style loading 2618 window[ jsonp ] = function(tmp){ 2619 data = tmp; 2620 success(); 2621 complete(); 2622 // Garbage collect 2623 window[ jsonp ] = undefined; 2624 try{ delete window[ jsonp ]; } catch(e){} 2625 if ( head ) 2626 head.removeChild( script ); 2627 }; 2628 } 2629 2630 if ( s.dataType == "script" && s.cache == null ) 2631 s.cache = false; 2632 2633 if ( s.cache === false && type == "GET" ) { 2634 var ts = now(); 2635 // try replacing _= if it is there 2636 var ret = s.url.replace(/(\?|&)_=.*?(&|$)/, "$1_=" + ts + "$2"); 2637 // if nothing was replaced, add timestamp to the end 2638 s.url = ret + ((ret == s.url) ? (s.url.match(/\?/) ? "&" : "?") + "_=" + ts : ""); 2639 } 2640 2641 // If data is available, append data to url for get requests 2642 if ( s.data && type == "GET" ) { 2643 s.url += (s.url.match(/\?/) ? "&" : "?") + s.data; 2644 2645 // IE likes to send both get and post data, prevent this 2646 s.data = null; 2647 } 2648 2649 // Watch for a new set of requests 2650 if ( s.global && ! jQuery.active++ ) 2651 jQuery.event.trigger( "ajaxStart" ); 2652 2653 // Matches an absolute URL, and saves the domain 2654 var remote = /^(?:\w+:)?\/\/([^\/?#]+)/; 2655 2656 // If we're requesting a remote document 2657 // and trying to load JSON or Script with a GET 2658 if ( s.dataType == "script" && type == "GET" 2659 && remote.test(s.url) && remote.exec(s.url)[1] != location.host ){ 2660 var head = document.getElementsByTagName("head")[0]; 2661 var script = document.createElement("script"); 2662 script.src = s.url; 2663 if (s.scriptCharset) 2664 script.charset = s.scriptCharset; 2665 2666 // Handle Script loading 2667 if ( !jsonp ) { 2668 var done = false; 2669 2670 // Attach handlers for all browsers 2671 script.onload = script.onreadystatechange = function(){ 2672 if ( !done && (!this.readyState || 2673 this.readyState == "loaded" || this.readyState == "complete") ) { 2674 done = true; 2675 success(); 2676 complete(); 2677 head.removeChild( script ); 2678 } 2679 }; 2680 } 2681 2682 head.appendChild(script); 2683 2684 // We handle everything using the script element injection 2685 return undefined; 2686 } 2687 2688 var requestDone = false; 2689 2690 // Create the request object; Microsoft failed to properly 2691 // implement the XMLHttpRequest in IE7, so we use the ActiveXObject when it is available 2692 var xhr = window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest(); 2693 2694 // Open the socket 2695 // Passing null username, generates a login popup on Opera (#2865) 2696 if( s.username ) 2697 xhr.open(type, s.url, s.async, s.username, s.password); 2698 else 2699 xhr.open(type, s.url, s.async); 2700 2701 // Need an extra try/catch for cross domain requests in Firefox 3 2702 try { 2703 // Set the correct header, if data is being sent 2704 if ( s.data ) 2705 xhr.setRequestHeader("Content-Type", s.contentType); 2706 2707 // Set the If-Modified-Since header, if ifModified mode. 2708 if ( s.ifModified ) 2709 xhr.setRequestHeader("If-Modified-Since", 2710 jQuery.lastModified[s.url] || "Thu, 01 Jan 1970 00:00:00 GMT" ); 2711 2712 // Set header so the called script knows that it's an XMLHttpRequest 2713 xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); 2714 2715 // Set the Accepts header for the server, depending on the dataType 2716 xhr.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ? 2717 s.accepts[ s.dataType ] + ", */*" : 2718 s.accepts._default ); 2719 } catch(e){} 2720 2721 // Allow custom headers/mimetypes 2722 if ( s.beforeSend && s.beforeSend(xhr, s) === false ) { 2723 // cleanup active request counter 2724 s.global && jQuery.active--; 2725 // close opended socket 2726 xhr.abort(); 2727 return false; 2728 } 2729 2730 if ( s.global ) 2731 jQuery.event.trigger("ajaxSend", [xhr, s]); 2732 2733 // Wait for a response to come back 2734 var onreadystatechange = function(isTimeout){ 2735 // The transfer is complete and the data is available, or the request timed out 2736 if ( !requestDone && xhr && (xhr.readyState == 4 || isTimeout == "timeout") ) { 2737 requestDone = true; 2738 2739 // clear poll interval 2740 if (ival) { 2741 clearInterval(ival); 2742 ival = null; 2743 } 2744 2745 status = isTimeout == "timeout" && "timeout" || 2746 !jQuery.httpSuccess( xhr ) && "error" || 2747 s.ifModified && jQuery.httpNotModified( xhr, s.url ) && "notmodified" || 2748 "success"; 2749 2750 if ( status == "success" ) { 2751 // Watch for, and catch, XML document parse errors 2752 try { 2753 // process the data (runs the xml through httpData regardless of callback) 2754 data = jQuery.httpData( xhr, s.dataType, s.dataFilter ); 2755 } catch(e) { 2756 status = "parsererror"; 2757 } 2758 } 2759 2760 // Make sure that the request was successful or notmodified 2761 if ( status == "success" ) { 2762 // Cache Last-Modified header, if ifModified mode. 2763 var modRes; 2764 try { 2765 modRes = xhr.getResponseHeader("Last-Modified"); 2766 } catch(e) {} // swallow exception thrown by FF if header is not available 2767 2768 if ( s.ifModified && modRes ) 2769 jQuery.lastModified[s.url] = modRes; 2770 2771 // JSONP handles its own success callback 2772 if ( !jsonp ) 2773 success(); 2774 } else 2775 jQuery.handleError(s, xhr, status); 2776 2777 // Fire the complete handlers 2778 complete(); 2779 2780 // Stop memory leaks 2781 if ( s.async ) 2782 xhr = null; 2783 } 2784 }; 2785 2786 if ( s.async ) { 2787 // don't attach the handler to the request, just poll it instead 2788 var ival = setInterval(onreadystatechange, 13); 2789 2790 // Timeout checker 2791 if ( s.timeout > 0 ) 2792 setTimeout(function(){ 2793 // Check to see if the request is still happening 2794 if ( xhr ) { 2795 // Cancel the request 2796 xhr.abort(); 2797 2798 if( !requestDone ) 2799 onreadystatechange( "timeout" ); 2800 } 2801 }, s.timeout); 2802 } 2803 2804 // Send the data 2805 try { 2806 xhr.send(s.data); 2807 } catch(e) { 2808 jQuery.handleError(s, xhr, null, e); 2809 } 2810 2811 // firefox 1.5 doesn't fire statechange for sync requests 2812 if ( !s.async ) 2813 onreadystatechange(); 2814 2815 function success(){ 2816 // If a local callback was specified, fire it and pass it the data 2817 if ( s.success ) 2818 s.success( data, status ); 2819 2820 // Fire the global callback 2821 if ( s.global ) 2822 jQuery.event.trigger( "ajaxSuccess", [xhr, s] ); 2823 } 2824 2825 function complete(){ 2826 // Process result 2827 if ( s.complete ) 2828 s.complete(xhr, status); 2829 2830 // The request was completed 2831 if ( s.global ) 2832 jQuery.event.trigger( "ajaxComplete", [xhr, s] ); 2833 2834 // Handle the global AJAX counter 2835 if ( s.global && ! --jQuery.active ) 2836 jQuery.event.trigger( "ajaxStop" ); 2837 } 2838 2839 // return XMLHttpRequest to allow aborting the request etc. 2840 return xhr; 2841 }, 2842 2843 handleError: function( s, xhr, status, e ) { 2844 // If a local callback was specified, fire it 2845 if ( s.error ) s.error( xhr, status, e ); 2846 2847 // Fire the global callback 2848 if ( s.global ) 2849 jQuery.event.trigger( "ajaxError", [xhr, s, e] ); 2850 }, 2851 2852 // Counter for holding the number of active queries 2853 active: 0, 2854 2855 // Determines if an XMLHttpRequest was successful or not 2856 httpSuccess: function( xhr ) { 2857 try { 2858 // IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450 2859 return !xhr.status && location.protocol == "file:" || 2860 ( xhr.status >= 200 && xhr.status < 300 ) || xhr.status == 304 || xhr.status == 1223 || 2861 jQuery.browser.safari && xhr.status == undefined; 2862 } catch(e){} 2863 return false; 2864 }, 2865 2866 // Determines if an XMLHttpRequest returns NotModified 2867 httpNotModified: function( xhr, url ) { 2868 try { 2869 var xhrRes = xhr.getResponseHeader("Last-Modified"); 2870 2871 // Firefox always returns 200. check Last-Modified date 2872 return xhr.status == 304 || xhrRes == jQuery.lastModified[url] || 2873 jQuery.browser.safari && xhr.status == undefined; 2874 } catch(e){} 2875 return false; 2876 }, 2877 2878 httpData: function( xhr, type, filter ) { 2879 var ct = xhr.getResponseHeader("content-type"), 2880 xml = type == "xml" || !type && ct && ct.indexOf("xml") >= 0, 2881 data = xml ? xhr.responseXML : xhr.responseText; 2882 2883 if ( xml && data.documentElement.tagName == "parsererror" ) 2884 throw "parsererror"; 2885 2886 // Allow a pre-filtering function to sanitize the response 2887 if( filter ) 2888 data = filter( data, type ); 2889 2890 // If the type is "script", eval it in global context 2891 if ( type == "script" ) 2892 jQuery.globalEval( data ); 2893 2894 // Get the JavaScript object, if JSON is used. 2895 if ( type == "json" ) 2896 data = eval("(" + data + ")"); 2897 2898 return data; 2899 }, 2900 2901 // Serialize an array of form elements or a set of 2902 // key/values into a query string 2903 param: function( a ) { 2904 var s = []; 2905 2906 // If an array was passed in, assume that it is an array 2907 // of form elements 2908 if ( a.constructor == Array || a.jquery ) 2909 // Serialize the form elements 2910 jQuery.each( a, function(){ 2911 s.push( encodeURIComponent(this.name) + "=" + encodeURIComponent( this.value ) ); 2912 }); 2913 2914 // Otherwise, assume that it's an object of key/value pairs 2915 else 2916 // Serialize the key/values 2917 for ( var j in a ) 2918 // If the value is an array then the key names need to be repeated 2919 if ( a[j] && a[j].constructor == Array ) 2920 jQuery.each( a[j], function(){ 2921 s.push( encodeURIComponent(j) + "=" + encodeURIComponent( this ) ); 2922 }); 2923 else 2924 s.push( encodeURIComponent(j) + "=" + encodeURIComponent( jQuery.isFunction(a[j]) ? a[j]() : a[j] ) ); 2925 2926 // Return the resulting serialization 2927 return s.join("&").replace(/%20/g, "+"); 2928 } 2929 2930 }); 2931 jQuery.fn.extend({ 2932 show: function(speed,callback){ 2933 return speed ? 2934 this.animate({ 2935 height: "show", width: "show", opacity: "show" 2936 }, speed, callback) : 2937 2938 this.filter(":hidden").each(function(){ 2939 this.style.display = this.oldblock || ""; 2940 if ( jQuery.css(this,"display") == "none" ) { 2941 var elem = jQuery("<" + this.tagName + " />").appendTo("body"); 2942 this.style.display = elem.css("display"); 2943 // handle an edge condition where css is - div { display:none; } or similar 2944 if (this.style.display == "none") 2945 this.style.display = "block"; 2946 elem.remove(); 2947 } 2948 }).end(); 2949 }, 2950 2951 hide: function(speed,callback){ 2952 return speed ? 2953 this.animate({ 2954 height: "hide", width: "hide", opacity: "hide" 2955 }, speed, callback) : 2956 2957 this.filter(":visible").each(function(){ 2958 this.oldblock = this.oldblock || jQuery.css(this,"display"); 2959 this.style.display = "none"; 2960 }).end(); 2961 }, 2962 2963 // Save the old toggle function 2964 _toggle: jQuery.fn.toggle, 2965 2966 toggle: function( fn, fn2 ){ 2967 return jQuery.isFunction(fn) && jQuery.isFunction(fn2) ? 2968 this._toggle.apply( this, arguments ) : 2969 fn ? 2970 this.animate({ 2971 height: "toggle", width: "toggle", opacity: "toggle" 2972 }, fn, fn2) : 2973 this.each(function(){ 2974 jQuery(this)[ jQuery(this).is(":hidden") ? "show" : "hide" ](); 2975 }); 2976 }, 2977 2978 slideDown: function(speed,callback){ 2979 return this.animate({height: "show"}, speed, callback); 2980 }, 2981 2982 slideUp: function(speed,callback){ 2983 return this.animate({height: "hide"}, speed, callback); 2984 }, 2985 2986 slideToggle: function(speed, callback){ 2987 return this.animate({height: "toggle"}, speed, callback); 2988 }, 2989 2990 fadeIn: function(speed, callback){ 2991 return this.animate({opacity: "show"}, speed, callback); 2992 }, 2993 2994 fadeOut: function(speed, callback){ 2995 return this.animate({opacity: "hide"}, speed, callback); 2996 }, 2997 2998 fadeTo: function(speed,to,callback){ 2999 return this.animate({opacity: to}, speed, callback); 3000 }, 3001 3002 animate: function( prop, speed, easing, callback ) { 3003 var optall = jQuery.speed(speed, easing, callback); 3004 3005 return this[ optall.queue === false ? "each" : "queue" ](function(){ 3006 if ( this.nodeType != 1) 3007 return false; 3008 3009 var opt = jQuery.extend({}, optall), p, 3010 hidden = jQuery(this).is(":hidden"), self = this; 3011 3012 for ( p in prop ) { 3013 if ( prop[p] == "hide" && hidden || prop[p] == "show" && !hidden ) 3014 return opt.complete.call(this); 3015 3016 if ( p == "height" || p == "width" ) { 3017 // Store display property 3018 opt.display = jQuery.css(this, "display"); 3019 3020 // Make sure that nothing sneaks out 3021 opt.overflow = this.style.overflow; 3022 } 3023 } 3024 3025 if ( opt.overflow != null ) 3026 this.style.overflow = "hidden"; 3027 3028 opt.curAnim = jQuery.extend({}, prop); 3029 3030 jQuery.each( prop, function(name, val){ 3031 var e = new jQuery.fx( self, opt, name ); 3032 3033 if ( /toggle|show|hide/.test(val) ) 3034 e[ val == "toggle" ? hidden ? "show" : "hide" : val ]( prop ); 3035 else { 3036 var parts = val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/), 3037 start = e.cur(true) || 0; 3038 3039 if ( parts ) { 3040 var end = parseFloat(parts[2]), 3041 unit = parts[3] || "px"; 3042 3043 // We need to compute starting value 3044 if ( unit != "px" ) { 3045 self.style[ name ] = (end || 1) + unit; 3046 start = ((end || 1) / e.cur(true)) * start; 3047 self.style[ name ] = start + unit; 3048 } 3049 3050 // If a +=/-= token was provided, we're doing a relative animation 3051 if ( parts[1] ) 3052 end = ((parts[1] == "-=" ? -1 : 1) * end) + start; 3053 3054 e.custom( start, end, unit ); 3055 } else 3056 e.custom( start, val, "" ); 3057 } 3058 }); 3059 3060 // For JS strict compliance 3061 return true; 3062 }); 3063 }, 3064 3065 queue: function(type, fn){ 3066 if ( jQuery.isFunction(type) || ( type && type.constructor == Array )) { 3067 fn = type; 3068 type = "fx"; 3069 } 3070 3071 if ( !type || (typeof type == "string" && !fn) ) 3072 return queue( this[0], type ); 3073 3074 return this.each(function(){ 3075 if ( fn.constructor == Array ) 3076 queue(this, type, fn); 3077 else { 3078 queue(this, type).push( fn ); 3079 3080 if ( queue(this, type).length == 1 ) 3081 fn.call(this); 3082 } 3083 }); 3084 }, 3085 3086 stop: function(clearQueue, gotoEnd){ 3087 var timers = jQuery.timers; 3088 3089 if (clearQueue) 3090 this.queue([]); 3091 3092 this.each(function(){ 3093 // go in reverse order so anything added to the queue during the loop is ignored 3094 for ( var i = timers.length - 1; i >= 0; i-- ) 3095 if ( timers[i].elem == this ) { 3096 if (gotoEnd) 3097 // force the next step to be the last 3098 timers[i](true); 3099 timers.splice(i, 1); 3100 } 3101 }); 3102 3103 // start the next in the queue if the last step wasn't forced 3104 if (!gotoEnd) 3105 this.dequeue(); 3106 3107 return this; 3108 } 3109 3110 }); 3111 3112 var queue = function( elem, type, array ) { 3113 if ( elem ){ 3114 3115 type = type || "fx"; 3116 3117 var q = jQuery.data( elem, type + "queue" ); 3118 3119 if ( !q || array ) 3120 q = jQuery.data( elem, type + "queue", jQuery.makeArray(array) ); 3121 3122 } 3123 return q; 3124 }; 3125 3126 jQuery.fn.dequeue = function(type){ 3127 type = type || "fx"; 3128 3129 return this.each(function(){ 3130 var q = queue(this, type); 3131 3132 q.shift(); 3133 3134 if ( q.length ) 3135 q[0].call( this ); 3136 }); 3137 }; 3138 3139 jQuery.extend({ 3140 3141 speed: function(speed, easing, fn) { 3142 var opt = speed && speed.constructor == Object ? speed : { 3143 complete: fn || !fn && easing || 3144 jQuery.isFunction( speed ) && speed, 3145 duration: speed, 3146 easing: fn && easing || easing && easing.constructor != Function && easing 3147 }; 3148 3149 opt.duration = (opt.duration && opt.duration.constructor == Number ? 3150 opt.duration : 3151 jQuery.fx.speeds[opt.duration]) || jQuery.fx.speeds.def; 3152 3153 // Queueing 3154 opt.old = opt.complete; 3155 opt.complete = function(){ 3156 if ( opt.queue !== false ) 3157 jQuery(this).dequeue(); 3158 if ( jQuery.isFunction( opt.old ) ) 3159 opt.old.call( this ); 3160 }; 3161 3162 return opt; 3163 }, 3164 3165 easing: { 3166 linear: function( p, n, firstNum, diff ) { 3167 return firstNum + diff * p; 3168 }, 3169 swing: function( p, n, firstNum, diff ) { 3170 return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum; 3171 } 3172 }, 3173 3174 timers: [], 3175 timerId: null, 3176 3177 fx: function( elem, options, prop ){ 3178 this.options = options; 3179 this.elem = elem; 3180 this.prop = prop; 3181 3182 if ( !options.orig ) 3183 options.orig = {}; 3184 } 3185 3186 }); 3187 3188 jQuery.fx.prototype = { 3189 3190 // Simple function for setting a style value 3191 update: function(){ 3192 if ( this.options.step ) 3193 this.options.step.call( this.elem, this.now, this ); 3194 3195 (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this ); 3196 3197 // Set display property to block for height/width animations 3198 if ( this.prop == "height" || this.prop == "width" ) 3199 this.elem.style.display = "block"; 3200 }, 3201 3202 // Get the current size 3203 cur: function(force){ 3204 if ( this.elem[this.prop] != null && this.elem.style[this.prop] == null ) 3205 return this.elem[ this.prop ]; 3206 3207 var r = parseFloat(jQuery.css(this.elem, this.prop, force)); 3208 return r && r > -10000 ? r : parseFloat(jQuery.curCSS(this.elem, this.prop)) || 0; 3209 }, 3210 3211 // Start an animation from one number to another 3212 custom: function(from, to, unit){ 3213 this.startTime = now(); 3214 this.start = from; 3215 this.end = to; 3216 this.unit = unit || this.unit || "px"; 3217 this.now = this.start; 3218 this.pos = this.state = 0; 3219 this.update(); 3220 3221 var self = this; 3222 function t(gotoEnd){ 3223 return self.step(gotoEnd); 3224 } 3225 3226 t.elem = this.elem; 3227 3228 jQuery.timers.push(t); 3229 3230 if ( jQuery.timerId == null ) { 3231 jQuery.timerId = setInterval(function(){ 3232 var timers = jQuery.timers; 3233 3234 for ( var i = 0; i < timers.length; i++ ) 3235 if ( !timers[i]() ) 3236 timers.splice(i--, 1); 3237 3238 if ( !timers.length ) { 3239 clearInterval( jQuery.timerId ); 3240 jQuery.timerId = null; 3241 } 3242 }, 13); 3243 } 3244 }, 3245 3246 // Simple 'show' function 3247 show: function(){ 3248 // Remember where we started, so that we can go back to it later 3249 this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop ); 3250 this.options.show = true; 3251 3252 // Begin the animation 3253 this.custom(0, this.cur()); 3254 3255 // Make sure that we start at a small width/height to avoid any 3256 // flash of content 3257 if ( this.prop == "width" || this.prop == "height" ) 3258 this.elem.style[this.prop] = "1px"; 3259 3260 // Start by showing the element 3261 jQuery(this.elem).show(); 3262 }, 3263 3264 // Simple 'hide' function 3265 hide: function(){ 3266 // Remember where we started, so that we can go back to it later 3267 this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop ); 3268 this.options.hide = true; 3269 3270 // Begin the animation 3271 this.custom(this.cur(), 0); 3272 }, 3273 3274 // Each step of an animation 3275 step: function(gotoEnd){ 3276 var t = now(); 3277 3278 if ( gotoEnd || t > this.options.duration + this.startTime ) { 3279 this.now = this.end; 3280 this.pos = this.state = 1; 3281 this.update(); 3282 3283 this.options.curAnim[ this.prop ] = true; 3284 3285 var done = true; 3286 for ( var i in this.options.curAnim ) 3287 if ( this.options.curAnim[i] !== true ) 3288 done = false; 3289 3290 if ( done ) { 3291 if ( this.options.display != null ) { 3292 // Reset the overflow 3293 this.elem.style.overflow = this.options.overflow; 3294 3295 // Reset the display 3296 this.elem.style.display = this.options.display; 3297 if ( jQuery.css(this.elem, "display") == "none" ) 3298 this.elem.style.display = "block"; 3299 } 3300 3301 // Hide the element if the "hide" operation was done 3302 if ( this.options.hide ) 3303 this.elem.style.display = "none"; 3304 3305 // Reset the properties, if the item has been hidden or shown 3306 if ( this.options.hide || this.options.show ) 3307 for ( var p in this.options.curAnim ) 3308 jQuery.attr(this.elem.style, p, this.options.orig[p]); 3309 } 3310 3311 if ( done ) 3312 // Execute the complete function 3313 this.options.complete.call( this.elem ); 3314 3315 return false; 3316 } else { 3317 var n = t - this.startTime; 3318 this.state = n / this.options.duration; 3319 3320 // Perform the easing function, defaults to swing 3321 this.pos = jQuery.easing[this.options.easing || (jQuery.easing.swing ? "swing" : "linear")](this.state, n, 0, 1, this.options.duration); 3322 this.now = this.start + ((this.end - this.start) * this.pos); 3323 3324 // Perform the next step of the animation 3325 this.update(); 3326 } 3327 3328 return true; 3329 } 3330 3331 }; 3332 3333 jQuery.extend( jQuery.fx, { 3334 speeds:{ 3335 slow: 600, 3336 fast: 200, 3337 // Default speed 3338 def: 400 3339 }, 3340 step: { 3341 scrollLeft: function(fx){ 3342 fx.elem.scrollLeft = fx.now; 3343 }, 3344 3345 scrollTop: function(fx){ 3346 fx.elem.scrollTop = fx.now; 3347 }, 3348 3349 opacity: function(fx){ 3350 jQuery.attr(fx.elem.style, "opacity", fx.now); 3351 }, 3352 3353 _default: function(fx){ 3354 fx.elem.style[ fx.prop ] = fx.now + fx.unit; 3355 } 3356 } 3357 }); 3358 // The Offset Method 3359 // Originally By Brandon Aaron, part of the Dimension Plugin 3360 // http://jquery.com/plugins/project/dimensions 3361 jQuery.fn.offset = function() { 3362 var left = 0, top = 0, elem = this[0], results; 3363 3364 if ( elem ) with ( jQuery.browser ) { 3365 var parent = elem.parentNode, 3366 offsetChild = elem, 3367 offsetParent = elem.offsetParent, 3368 doc = elem.ownerDocument, 3369 safari2 = safari && parseInt(version) < 522 && !/adobeair/i.test(userAgent), 3370 css = jQuery.curCSS, 3371 fixed = css(elem, "position") == "fixed"; 3372 3373 // Use getBoundingClientRect if available 3374 if ( elem.getBoundingClientRect ) { 3375 var box = elem.getBoundingClientRect(); 3376 3377 // Add the document scroll offsets 3378 add(box.left + Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft), 3379 box.top + Math.max(doc.documentElement.scrollTop, doc.body.scrollTop)); 3380 3381 // IE adds the HTML element's border, by default it is medium which is 2px 3382 // IE 6 and 7 quirks mode the border width is overwritable by the following css html { border: 0; } 3383 // IE 7 standards mode, the border is always 2px 3384 // This border/offset is typically represented by the clientLeft and clientTop properties 3385 // However, in IE6 and 7 quirks mode the clientLeft and clientTop properties are not updated when overwriting it via CSS 3386 // Therefore this method will be off by 2px in IE while in quirksmode 3387 add( -doc.documentElement.clientLeft, -doc.documentElement.clientTop ); 3388 3389 // Otherwise loop through the offsetParents and parentNodes 3390 } else { 3391 3392 // Initial element offsets 3393 add( elem.offsetLeft, elem.offsetTop ); 3394 3395 // Get parent offsets 3396 while ( offsetParent ) { 3397 // Add offsetParent offsets 3398 add( offsetParent.offsetLeft, offsetParent.offsetTop ); 3399 3400 // Mozilla and Safari > 2 does not include the border on offset parents 3401 // However Mozilla adds the border for table or table cells 3402 if ( mozilla && !/^t(able|d|h)$/i.test(offsetParent.tagName) || safari && !safari2 ) 3403 border( offsetParent ); 3404 3405 // Add the document scroll offsets if position is fixed on any offsetParent 3406 if ( !fixed && css(offsetParent, "position") == "fixed" ) 3407 fixed = true; 3408 3409 // Set offsetChild to previous offsetParent unless it is the body element 3410 offsetChild = /^body$/i.test(offsetParent.tagName) ? offsetChild : offsetParent; 3411 // Get next offsetParent 3412 offsetParent = offsetParent.offsetParent; 3413 } 3414 3415 // Get parent scroll offsets 3416 while ( parent && parent.tagName && !/^body|html$/i.test(parent.tagName) ) { 3417 // Remove parent scroll UNLESS that parent is inline or a table to work around Opera inline/table scrollLeft/Top bug 3418 if ( !/^inline|table.*$/i.test(css(parent, "display")) ) 3419 // Subtract parent scroll offsets 3420 add( -parent.scrollLeft, -parent.scrollTop ); 3421 3422 // Mozilla does not add the border for a parent that has overflow != visible 3423 if ( mozilla && css(parent, "overflow") != "visible" ) 3424 border( parent ); 3425 3426 // Get next parent 3427 parent = parent.parentNode; 3428 } 3429 3430 // Safari <= 2 doubles body offsets with a fixed position element/offsetParent or absolutely positioned offsetChild 3431 // Mozilla doubles body offsets with a non-absolutely positioned offsetChild 3432 if ( (safari2 && (fixed || css(offsetChild, "position") == "absolute")) || 3433 (mozilla && css(offsetChild, "position") != "absolute") ) 3434 add( -doc.body.offsetLeft, -doc.body.offsetTop ); 3435 3436 // Add the document scroll offsets if position is fixed 3437 if ( fixed ) 3438 add(Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft), 3439 Math.max(doc.documentElement.scrollTop, doc.body.scrollTop)); 3440 } 3441 3442 // Return an object with top and left properties 3443 results = { top: top, left: left }; 3444 } 3445 3446 function border(elem) { 3447 add( jQuery.curCSS(elem, "borderLeftWidth", true), jQuery.curCSS(elem, "borderTopWidth", true) ); 3448 } 3449 3450 function add(l, t) { 3451 left += parseInt(l, 10) || 0; 3452 top += parseInt(t, 10) || 0; 3453 } 3454 3455 return results; 3456 }; 3457 3458 3459 jQuery.fn.extend({ 3460 position: function() { 3461 var left = 0, top = 0, results; 3462 3463 if ( this[0] ) { 3464 // Get *real* offsetParent 3465 var offsetParent = this.offsetParent(), 3466 3467 // Get correct offsets 3468 offset = this.offset(), 3469 parentOffset = /^body|html$/i.test(offsetParent[0].tagName) ? { top: 0, left: 0 } : offsetParent.offset(); 3470 3471 // Subtract element margins 3472 // note: when an element has margin: auto the offsetLeft and marginLeft 3473 // are the same in Safari causing offset.left to incorrectly be 0 3474 offset.top -= num( this, 'marginTop' ); 3475 offset.left -= num( this, 'marginLeft' ); 3476 3477 // Add offsetParent borders 3478 parentOffset.top += num( offsetParent, 'borderTopWidth' ); 3479 parentOffset.left += num( offsetParent, 'borderLeftWidth' ); 3480 3481 // Subtract the two offsets 3482 results = { 3483 top: offset.top - parentOffset.top, 3484 left: offset.left - parentOffset.left 3485 }; 3486 } 3487 3488 return results; 3489 }, 3490 3491 offsetParent: function() { 3492 var offsetParent = this[0].offsetParent; 3493 while ( offsetParent && (!/^body|html$/i.test(offsetParent.tagName) && jQuery.css(offsetParent, 'position') == 'static') ) 3494 offsetParent = offsetParent.offsetParent; 3495 return jQuery(offsetParent); 3496 } 3497 }); 3498 3499 3500 // Create scrollLeft and scrollTop methods 3501 jQuery.each( ['Left', 'Top'], function(i, name) { 3502 var method = 'scroll' + name; 3503 3504 jQuery.fn[ method ] = function(val) { 3505 if (!this[0]) return; 3506 3507 return val != undefined ? 3508 3509 // Set the scroll offset 3510 this.each(function() { 3511 this == window || this == document ? 3512 window.scrollTo( 3513 !i ? val : jQuery(window).scrollLeft(), 3514 i ? val : jQuery(window).scrollTop() 3515 ) : 3516 this[ method ] = val; 3517 }) : 3518 3519 // Return the scroll offset 3520 this[0] == window || this[0] == document ? 3521 self[ i ? 'pageYOffset' : 'pageXOffset' ] || 3522 jQuery.boxModel && document.documentElement[ method ] || 3523 document.body[ method ] : 3524 this[0][ method ]; 3525 }; 3526 }); 3527 // Create innerHeight, innerWidth, outerHeight and outerWidth methods 3528 jQuery.each([ "Height", "Width" ], function(i, name){ 3529 3530 var tl = i ? "Left" : "Top", // top or left 3531 br = i ? "Right" : "Bottom"; // bottom or right 3532 3533 // innerHeight and innerWidth 3534 jQuery.fn["inner" + name] = function(){ 3535 return this[ name.toLowerCase() ]() + 3536 num(this, "padding" + tl) + 3537 num(this, "padding" + br); 3538 }; 3539 3540 // outerHeight and outerWidth 3541 jQuery.fn["outer" + name] = function(margin) { 3542 return this["inner" + name]() + 3543 num(this, "border" + tl + "Width") + 3544 num(this, "border" + br + "Width") + 3545 (margin ? 3546 num(this, "margin" + tl) + num(this, "margin" + br) : 0); 3547 }; 3548 3549 });})(); -

WordPress源代码——jquery(jquery-1.2.3.js)
1(function(){ 2 /* 3 * jQuery 1.2.3 - New Wave Javascript 4 * 5 * Copyright (c) 2008 John Resig (jquery.com) 6 * Dual licensed under the MIT (MIT-LICENSE.txt) 7 * and GPL (GPL-LICENSE.txt) licenses. 8 * 9 * $Date: 2008-02-06 00:21:25 -0500 (Wed, 06 Feb 2008) $ 10 * $Rev: 4663 $ 11 */ 12 13 // Map over jQuery in case of overwrite 14 if ( window.jQuery ) 15 var _jQuery = window.jQuery; 16 17 var jQuery = window.jQuery = function( selector, context ) { 18 // The jQuery object is actually just the init constructor 'enhanced' 19 return new jQuery.prototype.init( selector, context ); 20 }; 21 22 // Map over the $ in case of overwrite 23 if ( window.$ ) 24 var _$ = window.$; 25 26 // Map the jQuery namespace to the '$' one 27 window.$ = jQuery; 28 29 // A simple way to check for HTML strings or ID strings 30 // (both of which we optimize for) 31 var quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/; 32 33 // Is it a simple selector 34 var isSimple = /^.[^:#\[\.]*$/; 35 36 jQuery.fn = jQuery.prototype = { 37 init: function( selector, context ) { 38 // Make sure that a selection was provided 39 selector = selector || document; 40 41 // Handle $(DOMElement) 42 if ( selector.nodeType ) { 43 this[0] = selector; 44 this.length = 1; 45 return this; 46 47 // Handle HTML strings 48 } else if ( typeof selector == "string" ) { 49 // Are we dealing with HTML string or an ID? 50 var match = quickExpr.exec( selector ); 51 52 // Verify a match, and that no context was specified for #id 53 if ( match && (match[1] || !context) ) { 54 55 // HANDLE: $(html) -> $(array) 56 if ( match[1] ) 57 selector = jQuery.clean( [ match[1] ], context ); 58 59 // HANDLE: $("#id") 60 else { 61 var elem = document.getElementById( match[3] ); 62 63 // Make sure an element was located 64 if ( elem ) 65 // Handle the case where IE and Opera return items 66 // by name instead of ID 67 if ( elem.id != match[3] ) 68 return jQuery().find( selector ); 69 70 // Otherwise, we inject the element directly into the jQuery object 71 else { 72 this[0] = elem; 73 this.length = 1; 74 return this; 75 } 76 77 else 78 selector = []; 79 } 80 81 // HANDLE: $(expr, [context]) 82 // (which is just equivalent to: $(content).find(expr) 83 } else 84 return new jQuery( context ).find( selector ); 85 86 // HANDLE: $(function) 87 // Shortcut for document ready 88 } else if ( jQuery.isFunction( selector ) ) 89 return new jQuery( document )[ jQuery.fn.ready ? "ready" : "load" ]( selector ); 90 91 return this.setArray( 92 // HANDLE: $(array) 93 selector.constructor == Array && selector || 94 95 // HANDLE: $(arraylike) 96 // Watch for when an array-like object, contains DOM nodes, is passed in as the selector 97 (selector.jquery || selector.length && selector != window && !selector.nodeType && selector[0] != undefined && selector[0].nodeType) && jQuery.makeArray( selector ) || 98 99 // HANDLE: $(*) 100 [ selector ] ); 101 }, 102 103 // The current version of jQuery being used 104 jquery: "1.2.3", 105 106 // The number of elements contained in the matched element set 107 size: function() { 108 return this.length; 109 }, 110 111 // The number of elements contained in the matched element set 112 length: 0, 113 114 // Get the Nth element in the matched element set OR 115 // Get the whole matched element set as a clean array 116 get: function( num ) { 117 return num == undefined ? 118 119 // Return a 'clean' array 120 jQuery.makeArray( this ) : 121 122 // Return just the object 123 this[ num ]; 124 }, 125 126 // Take an array of elements and push it onto the stack 127 // (returning the new matched element set) 128 pushStack: function( elems ) { 129 // Build a new jQuery matched element set 130 var ret = jQuery( elems ); 131 132 // Add the old object onto the stack (as a reference) 133 ret.prevObject = this; 134 135 // Return the newly-formed element set 136 return ret; 137 }, 138 139 // Force the current matched set of elements to become 140 // the specified array of elements (destroying the stack in the process) 141 // You should use pushStack() in order to do this, but maintain the stack 142 setArray: function( elems ) { 143 // Resetting the length to 0, then using the native Array push 144 // is a super-fast way to populate an object with array-like properties 145 this.length = 0; 146 Array.prototype.push.apply( this, elems ); 147 148 return this; 149 }, 150 151 // Execute a callback for every element in the matched set. 152 // (You can seed the arguments with an array of args, but this is 153 // only used internally.) 154 each: function( callback, args ) { 155 return jQuery.each( this, callback, args ); 156 }, 157 158 // Determine the position of an element within 159 // the matched set of elements 160 index: function( elem ) { 161 var ret = -1; 162 163 // Locate the position of the desired element 164 this.each(function(i){ 165 if ( this == elem ) 166 ret = i; 167 }); 168 169 return ret; 170 }, 171 172 attr: function( name, value, type ) { 173 var options = name; 174 175 // Look for the case where we're accessing a style value 176 if ( name.constructor == String ) 177 if ( value == undefined ) 178 return this.length && jQuery[ type || "attr" ]( this[0], name ) || undefined; 179 180 else { 181 options = {}; 182 options[ name ] = value; 183 } 184 185 // Check to see if we're setting style values 186 return this.each(function(i){ 187 // Set all the styles 188 for ( name in options ) 189 jQuery.attr( 190 type ? 191 this.style : 192 this, 193 name, jQuery.prop( this, options[ name ], type, i, name ) 194 ); 195 }); 196 }, 197 198 css: function( key, value ) { 199 // ignore negative width and height values 200 if ( (key == 'width' || key == 'height') && parseFloat(value) < 0 ) 201 value = undefined; 202 return this.attr( key, value, "curCSS" ); 203 }, 204 205 text: function( text ) { 206 if ( typeof text != "object" && text != null ) 207 return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) ); 208 209 var ret = ""; 210 211 jQuery.each( text || this, function(){ 212 jQuery.each( this.childNodes, function(){ 213 if ( this.nodeType != 8 ) 214 ret += this.nodeType != 1 ? 215 this.nodeValue : 216 jQuery.fn.text( [ this ] ); 217 }); 218 }); 219 220 return ret; 221 }, 222 223 wrapAll: function( html ) { 224 if ( this[0] ) 225 // The elements to wrap the target around 226 jQuery( html, this[0].ownerDocument ) 227 .clone() 228 .insertBefore( this[0] ) 229 .map(function(){ 230 var elem = this; 231 232 while ( elem.firstChild ) 233 elem = elem.firstChild; 234 235 return elem; 236 }) 237 .append(this); 238 239 return this; 240 }, 241 242 wrapInner: function( html ) { 243 return this.each(function(){ 244 jQuery( this ).contents().wrapAll( html ); 245 }); 246 }, 247 248 wrap: function( html ) { 249 return this.each(function(){ 250 jQuery( this ).wrapAll( html ); 251 }); 252 }, 253 254 append: function() { 255 return this.domManip(arguments, true, false, function(elem){ 256 if (this.nodeType == 1) 257 this.appendChild( elem ); 258 }); 259 }, 260 261 prepend: function() { 262 return this.domManip(arguments, true, true, function(elem){ 263 if (this.nodeType == 1) 264 this.insertBefore( elem, this.firstChild ); 265 }); 266 }, 267 268 before: function() { 269 return this.domManip(arguments, false, false, function(elem){ 270 this.parentNode.insertBefore( elem, this ); 271 }); 272 }, 273 274 after: function() { 275 return this.domManip(arguments, false, true, function(elem){ 276 this.parentNode.insertBefore( elem, this.nextSibling ); 277 }); 278 }, 279 280 end: function() { 281 return this.prevObject || jQuery( [] ); 282 }, 283 284 find: function( selector ) { 285 var elems = jQuery.map(this, function(elem){ 286 return jQuery.find( selector, elem ); 287 }); 288 289 return this.pushStack( /[^+>] [^+>]/.test( selector ) || selector.indexOf("..") > -1 ? 290 jQuery.unique( elems ) : 291 elems ); 292 }, 293 294 clone: function( events ) { 295 // Do the clone 296 var ret = this.map(function(){ 297 if ( jQuery.browser.msie && !jQuery.isXMLDoc(this) ) { 298 // IE copies events bound via attachEvent when 299 // using cloneNode. Calling detachEvent on the 300 // clone will also remove the events from the orignal 301 // In order to get around this, we use innerHTML. 302 // Unfortunately, this means some modifications to 303 // attributes in IE that are actually only stored 304 // as properties will not be copied (such as the 305 // the name attribute on an input). 306 var clone = this.cloneNode(true), 307 container = document.createElement("div"); 308 container.appendChild(clone); 309 return jQuery.clean([container.innerHTML])[0]; 310 } else 311 return this.cloneNode(true); 312 }); 313 314 // Need to set the expando to null on the cloned set if it exists 315 // removeData doesn't work here, IE removes it from the original as well 316 // this is primarily for IE but the data expando shouldn't be copied over in any browser 317 var clone = ret.find("*").andSelf().each(function(){ 318 if ( this[ expando ] != undefined ) 319 this[ expando ] = null; 320 }); 321 322 // Copy the events from the original to the clone 323 if ( events === true ) 324 this.find("*").andSelf().each(function(i){ 325 if (this.nodeType == 3) 326 return; 327 var events = jQuery.data( this, "events" ); 328 329 for ( var type in events ) 330 for ( var handler in events[ type ] ) 331 jQuery.event.add( clone[ i ], type, events[ type ][ handler ], events[ type ][ handler ].data ); 332 }); 333 334 // Return the cloned set 335 return ret; 336 }, 337 338 filter: function( selector ) { 339 return this.pushStack( 340 jQuery.isFunction( selector ) && 341 jQuery.grep(this, function(elem, i){ 342 return selector.call( elem, i ); 343 }) || 344 345 jQuery.multiFilter( selector, this ) ); 346 }, 347 348 not: function( selector ) { 349 if ( selector.constructor == String ) 350 // test special case where just one selector is passed in 351 if ( isSimple.test( selector ) ) 352 return this.pushStack( jQuery.multiFilter( selector, this, true ) ); 353 else 354 selector = jQuery.multiFilter( selector, this ); 355 356 var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType; 357 return this.filter(function() { 358 return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector; 359 }); 360 }, 361 362 add: function( selector ) { 363 return !selector ? this : this.pushStack( jQuery.merge( 364 this.get(), 365 selector.constructor == String ? 366 jQuery( selector ).get() : 367 selector.length != undefined && (!selector.nodeName || jQuery.nodeName(selector, "form")) ? 368 selector : [selector] ) ); 369 }, 370 371 is: function( selector ) { 372 return selector ? 373 jQuery.multiFilter( selector, this ).length > 0 : 374 false; 375 }, 376 377 hasClass: function( selector ) { 378 return this.is( "." + selector ); 379 }, 380 381 val: function( value ) { 382 if ( value == undefined ) { 383 384 if ( this.length ) { 385 var elem = this[0]; 386 387 // We need to handle select boxes special 388 if ( jQuery.nodeName( elem, "select" ) ) { 389 var index = elem.selectedIndex, 390 values = [], 391 options = elem.options, 392 one = elem.type == "select-one"; 393 394 // Nothing was selected 395 if ( index < 0 ) 396 return null; 397 398 // Loop through all the selected options 399 for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) { 400 var option = options[ i ]; 401 402 if ( option.selected ) { 403 // Get the specifc value for the option 404 value = jQuery.browser.msie && !option.attributes.value.specified ? option.text : option.value; 405 406 // We don't need an array for one selects 407 if ( one ) 408 return value; 409 410 // Multi-Selects return an array 411 values.push( value ); 412 } 413 } 414 415 return values; 416 417 // Everything else, we just grab the value 418 } else 419 return (this[0].value || "").replace(/\r/g, ""); 420 421 } 422 423 return undefined; 424 } 425 426 return this.each(function(){ 427 if ( this.nodeType != 1 ) 428 return; 429 430 if ( value.constructor == Array && /radio|checkbox/.test( this.type ) ) 431 this.checked = (jQuery.inArray(this.value, value) >= 0 || 432 jQuery.inArray(this.name, value) >= 0); 433 434 else if ( jQuery.nodeName( this, "select" ) ) { 435 var values = value.constructor == Array ? 436 value : 437 [ value ]; 438 439 jQuery( "option", this ).each(function(){ 440 this.selected = (jQuery.inArray( this.value, values ) >= 0 || 441 jQuery.inArray( this.text, values ) >= 0); 442 }); 443 444 if ( !values.length ) 445 this.selectedIndex = -1; 446 447 } else 448 this.value = value; 449 }); 450 }, 451 452 html: function( value ) { 453 return value == undefined ? 454 (this.length ? 455 this[0].innerHTML : 456 null) : 457 this.empty().append( value ); 458 }, 459 460 replaceWith: function( value ) { 461 return this.after( value ).remove(); 462 }, 463 464 eq: function( i ) { 465 return this.slice( i, i + 1 ); 466 }, 467 468 slice: function() { 469 return this.pushStack( Array.prototype.slice.apply( this, arguments ) ); 470 }, 471 472 map: function( callback ) { 473 return this.pushStack( jQuery.map(this, function(elem, i){ 474 return callback.call( elem, i, elem ); 475 })); 476 }, 477 478 andSelf: function() { 479 return this.add( this.prevObject ); 480 }, 481 482 data: function( key, value ){ 483 var parts = key.split("."); 484 parts[1] = parts[1] ? "." + parts[1] : ""; 485 486 if ( value == null ) { 487 var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]); 488 489 if ( data == undefined && this.length ) 490 data = jQuery.data( this[0], key ); 491 492 return data == null && parts[1] ? 493 this.data( parts[0] ) : 494 data; 495 } else 496 return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function(){ 497 jQuery.data( this, key, value ); 498 }); 499 }, 500 501 removeData: function( key ){ 502 return this.each(function(){ 503 jQuery.removeData( this, key ); 504 }); 505 }, 506 507 domManip: function( args, table, reverse, callback ) { 508 var clone = this.length > 1, elems; 509 510 return this.each(function(){ 511 if ( !elems ) { 512 elems = jQuery.clean( args, this.ownerDocument ); 513 514 if ( reverse ) 515 elems.reverse(); 516 } 517 518 var obj = this; 519 520 if ( table && jQuery.nodeName( this, "table" ) && jQuery.nodeName( elems[0], "tr" ) ) 521 obj = this.getElementsByTagName("tbody")[0] || this.appendChild( this.ownerDocument.createElement("tbody") ); 522 523 var scripts = jQuery( [] ); 524 525 jQuery.each(elems, function(){ 526 var elem = clone ? 527 jQuery( this ).clone( true )[0] : 528 this; 529 530 // execute all scripts after the elements have been injected 531 if ( jQuery.nodeName( elem, "script" ) ) { 532 scripts = scripts.add( elem ); 533 } else { 534 // Remove any inner scripts for later evaluation 535 if ( elem.nodeType == 1 ) 536 scripts = scripts.add( jQuery( "script", elem ).remove() ); 537 538 // Inject the elements into the document 539 callback.call( obj, elem ); 540 } 541 }); 542 543 scripts.each( evalScript ); 544 }); 545 } 546 }; 547 548 // Give the init function the jQuery prototype for later instantiation 549 jQuery.prototype.init.prototype = jQuery.prototype; 550 551 function evalScript( i, elem ) { 552 if ( elem.src ) 553 jQuery.ajax({ 554 url: elem.src, 555 async: false, 556 dataType: "script" 557 }); 558 559 else 560 jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" ); 561 562 if ( elem.parentNode ) 563 elem.parentNode.removeChild( elem ); 564 } 565 566 jQuery.extend = jQuery.fn.extend = function() { 567 // copy reference to target object 568 var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options; 569 570 // Handle a deep copy situation 571 if ( target.constructor == Boolean ) { 572 deep = target; 573 target = arguments[1] || {}; 574 // skip the boolean and the target 575 i = 2; 576 } 577 578 // Handle case when target is a string or something (possible in deep copy) 579 if ( typeof target != "object" && typeof target != "function" ) 580 target = {}; 581 582 // extend jQuery itself if only one argument is passed 583 if ( length == 1 ) { 584 target = this; 585 i = 0; 586 } 587 588 for ( ; i < length; i++ ) 589 // Only deal with non-null/undefined values 590 if ( (options = arguments[ i ]) != null ) 591 // Extend the base object 592 for ( var name in options ) { 593 // Prevent never-ending loop 594 if ( target === options[ name ] ) 595 continue; 596 597 // Recurse if we're merging object values 598 if ( deep && options[ name ] && typeof options[ name ] == "object" && target[ name ] && !options[ name ].nodeType ) 599 target[ name ] = jQuery.extend( target[ name ], options[ name ] ); 600 601 // Don't bring in undefined values 602 else if ( options[ name ] != undefined ) 603 target[ name ] = options[ name ]; 604 605 } 606 607 // Return the modified object 608 return target; 609 }; 610 611 var expando = "jQuery" + (new Date()).getTime(), uuid = 0, windowData = {}; 612 613 // exclude the following css properties to add px 614 var exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i; 615 616 jQuery.extend({ 617 noConflict: function( deep ) { 618 window.$ = _$; 619 620 if ( deep ) 621 window.jQuery = _jQuery; 622 623 return jQuery; 624 }, 625 626 // See test/unit/core.js for details concerning this function. 627 isFunction: function( fn ) { 628 return !!fn && typeof fn != "string" && !fn.nodeName && 629 fn.constructor != Array && /function/i.test( fn + "" ); 630 }, 631 632 // check if an element is in a (or is an) XML document 633 isXMLDoc: function( elem ) { 634 return elem.documentElement && !elem.body || 635 elem.tagName && elem.ownerDocument && !elem.ownerDocument.body; 636 }, 637 638 // Evalulates a script in a global context 639 globalEval: function( data ) { 640 data = jQuery.trim( data ); 641 642 if ( data ) { 643 // Inspired by code by Andrea Giammarchi 644 // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html 645 var head = document.getElementsByTagName("head")[0] || document.documentElement, 646 script = document.createElement("script"); 647 648 script.type = "text/javascript"; 649 if ( jQuery.browser.msie ) 650 script.text = data; 651 else 652 script.appendChild( document.createTextNode( data ) ); 653 654 head.appendChild( script ); 655 head.removeChild( script ); 656 } 657 }, 658 659 nodeName: function( elem, name ) { 660 return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase(); 661 }, 662 663 cache: {}, 664 665 data: function( elem, name, data ) { 666 elem = elem == window ? 667 windowData : 668 elem; 669 670 var id = elem[ expando ]; 671 672 // Compute a unique ID for the element 673 if ( !id ) 674 id = elem[ expando ] = ++uuid; 675 676 // Only generate the data cache if we're 677 // trying to access or manipulate it 678 if ( name && !jQuery.cache[ id ] ) 679 jQuery.cache[ id ] = {}; 680 681 // Prevent overriding the named cache with undefined values 682 if ( data != undefined ) 683 jQuery.cache[ id ][ name ] = data; 684 685 // Return the named cache data, or the ID for the element 686 return name ? 687 jQuery.cache[ id ][ name ] : 688 id; 689 }, 690 691 removeData: function( elem, name ) { 692 elem = elem == window ? 693 windowData : 694 elem; 695 696 var id = elem[ expando ]; 697 698 // If we want to remove a specific section of the element's data 699 if ( name ) { 700 if ( jQuery.cache[ id ] ) { 701 // Remove the section of cache data 702 delete jQuery.cache[ id ][ name ]; 703 704 // If we've removed all the data, remove the element's cache 705 name = ""; 706 707 for ( name in jQuery.cache[ id ] ) 708 break; 709 710 if ( !name ) 711 jQuery.removeData( elem ); 712 } 713 714 // Otherwise, we want to remove all of the element's data 715 } else { 716 // Clean up the element expando 717 try { 718 delete elem[ expando ]; 719 } catch(e){ 720 // IE has trouble directly removing the expando 721 // but it's ok with using removeAttribute 722 if ( elem.removeAttribute ) 723 elem.removeAttribute( expando ); 724 } 725 726 // Completely remove the data cache 727 delete jQuery.cache[ id ]; 728 } 729 }, 730 731 // args is for internal usage only 732 each: function( object, callback, args ) { 733 if ( args ) { 734 if ( object.length == undefined ) { 735 for ( var name in object ) 736 if ( callback.apply( object[ name ], args ) === false ) 737 break; 738 } else 739 for ( var i = 0, length = object.length; i < length; i++ ) 740 if ( callback.apply( object[ i ], args ) === false ) 741 break; 742 743 // A special, fast, case for the most common use of each 744 } else { 745 if ( object.length == undefined ) { 746 for ( var name in object ) 747 if ( callback.call( object[ name ], name, object[ name ] ) === false ) 748 break; 749 } else 750 for ( var i = 0, length = object.length, value = object[0]; 751 i < length && callback.call( value, i, value ) !== false; value = object[++i] ){} 752 } 753 754 return object; 755 }, 756 757 prop: function( elem, value, type, i, name ) { 758 // Handle executable functions 759 if ( jQuery.isFunction( value ) ) 760 value = value.call( elem, i ); 761 762 // Handle passing in a number to a CSS property 763 return value && value.constructor == Number && type == "curCSS" && !exclude.test( name ) ? 764 value + "px" : 765 value; 766 }, 767 768 className: { 769 // internal only, use addClass("class") 770 add: function( elem, classNames ) { 771 jQuery.each((classNames || "").split(/\s+/), function(i, className){ 772 if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) ) 773 elem.className += (elem.className ? " " : "") + className; 774 }); 775 }, 776 777 // internal only, use removeClass("class") 778 remove: function( elem, classNames ) { 779 if (elem.nodeType == 1) 780 elem.className = classNames != undefined ? 781 jQuery.grep(elem.className.split(/\s+/), function(className){ 782 return !jQuery.className.has( classNames, className ); 783 }).join(" ") : 784 ""; 785 }, 786 787 // internal only, use is(".class") 788 has: function( elem, className ) { 789 return jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1; 790 } 791 }, 792 793 // A method for quickly swapping in/out CSS properties to get correct calculations 794 swap: function( elem, options, callback ) { 795 var old = {}; 796 // Remember the old values, and insert the new ones 797 for ( var name in options ) { 798 old[ name ] = elem.style[ name ]; 799 elem.style[ name ] = options[ name ]; 800 } 801 802 callback.call( elem ); 803 804 // Revert the old values 805 for ( var name in options ) 806 elem.style[ name ] = old[ name ]; 807 }, 808 809 css: function( elem, name, force ) { 810 if ( name == "width" || name == "height" ) { 811 var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ]; 812 813 function getWH() { 814 val = name == "width" ? elem.offsetWidth : elem.offsetHeight; 815 var padding = 0, border = 0; 816 jQuery.each( which, function() { 817 padding += parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0; 818 border += parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0; 819 }); 820 val -= Math.round(padding + border); 821 } 822 823 if ( jQuery(elem).is(":visible") ) 824 getWH(); 825 else 826 jQuery.swap( elem, props, getWH ); 827 828 return Math.max(0, val); 829 } 830 831 return jQuery.curCSS( elem, name, force ); 832 }, 833 834 curCSS: function( elem, name, force ) { 835 var ret; 836 837 // A helper method for determining if an element's values are broken 838 function color( elem ) { 839 if ( !jQuery.browser.safari ) 840 return false; 841 842 var ret = document.defaultView.getComputedStyle( elem, null ); 843 return !ret || ret.getPropertyValue("color") == ""; 844 } 845 846 // We need to handle opacity special in IE 847 if ( name == "opacity" && jQuery.browser.msie ) { 848 ret = jQuery.attr( elem.style, "opacity" ); 849 850 return ret == "" ? 851 "1" : 852 ret; 853 } 854 // Opera sometimes will give the wrong display answer, this fixes it, see #2037 855 if ( jQuery.browser.opera && name == "display" ) { 856 var save = elem.style.outline; 857 elem.style.outline = "0 solid black"; 858 elem.style.outline = save; 859 } 860 861 // Make sure we're using the right name for getting the float value 862 if ( name.match( /float/i ) ) 863 name = styleFloat; 864 865 if ( !force && elem.style && elem.style[ name ] ) 866 ret = elem.style[ name ]; 867 868 else if ( document.defaultView && document.defaultView.getComputedStyle ) { 869 870 // Only "float" is needed here 871 if ( name.match( /float/i ) ) 872 name = "float"; 873 874 name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase(); 875 876 var getComputedStyle = document.defaultView.getComputedStyle( elem, null ); 877 878 if ( getComputedStyle && !color( elem ) ) 879 ret = getComputedStyle.getPropertyValue( name ); 880 881 // If the element isn't reporting its values properly in Safari 882 // then some display: none elements are involved 883 else { 884 var swap = [], stack = []; 885 886 // Locate all of the parent display: none elements 887 for ( var a = elem; a && color(a); a = a.parentNode ) 888 stack.unshift(a); 889 890 // Go through and make them visible, but in reverse 891 // (It would be better if we knew the exact display type that they had) 892 for ( var i = 0; i < stack.length; i++ ) 893 if ( color( stack[ i ] ) ) { 894 swap[ i ] = stack[ i ].style.display; 895 stack[ i ].style.display = "block"; 896 } 897 898 // Since we flip the display style, we have to handle that 899 // one special, otherwise get the value 900 ret = name == "display" && swap[ stack.length - 1 ] != null ? 901 "none" : 902 ( getComputedStyle && getComputedStyle.getPropertyValue( name ) ) || ""; 903 904 // Finally, revert the display styles back 905 for ( var i = 0; i < swap.length; i++ ) 906 if ( swap[ i ] != null ) 907 stack[ i ].style.display = swap[ i ]; 908 } 909 910 // We should always get a number back from opacity 911 if ( name == "opacity" && ret == "" ) 912 ret = "1"; 913 914 } else if ( elem.currentStyle ) { 915 var camelCase = name.replace(/\-(\w)/g, function(all, letter){ 916 return letter.toUpperCase(); 917 }); 918 919 ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ]; 920 921 // From the awesome hack by Dean Edwards 922 // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 923 924 // If we're not dealing with a regular pixel number 925 // but a number that has a weird ending, we need to convert it to pixels 926 if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) { 927 // Remember the original values 928 var style = elem.style.left, runtimeStyle = elem.runtimeStyle.left; 929 930 // Put in the new values to get a computed value out 931 elem.runtimeStyle.left = elem.currentStyle.left; 932 elem.style.left = ret || 0; 933 ret = elem.style.pixelLeft + "px"; 934 935 // Revert the changed values 936 elem.style.left = style; 937 elem.runtimeStyle.left = runtimeStyle; 938 } 939 } 940 941 return ret; 942 }, 943 944 clean: function( elems, context ) { 945 var ret = []; 946 context = context || document; 947 // !context.createElement fails in IE with an error but returns typeof 'object' 948 if (typeof context.createElement == 'undefined') 949 context = context.ownerDocument || context[0] && context[0].ownerDocument || document; 950 951 jQuery.each(elems, function(i, elem){ 952 if ( !elem ) 953 return; 954 955 if ( elem.constructor == Number ) 956 elem = elem.toString(); 957 958 // Convert html string into DOM nodes 959 if ( typeof elem == "string" ) { 960 // Fix "XHTML"-style tags in all browsers 961 elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){ 962 return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ? 963 all : 964 front + "></" + tag + ">"; 965 }); 966 967 // Trim whitespace, otherwise indexOf won't work as expected 968 var tags = jQuery.trim( elem ).toLowerCase(), div = context.createElement("div"); 969 970 var wrap = 971 // option or optgroup 972 !tags.indexOf("<opt") && 973 [ 1, "<select multiple='multiple'>", "</select>" ] || 974 975 !tags.indexOf("<leg") && 976 [ 1, "<fieldset>", "</fieldset>" ] || 977 978 tags.match(/^<(thead|tbody|tfoot|colg|cap)/) && 979 [ 1, "<table>", "</table>" ] || 980 981 !tags.indexOf("<tr") && 982 [ 2, "<table><tbody>", "</tbody></table>" ] || 983 984 // <thead> matched above 985 (!tags.indexOf("<td") || !tags.indexOf("<th")) && 986 [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ] || 987 988 !tags.indexOf("<col") && 989 [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ] || 990 991 // IE can't serialize <link> and <script> tags normally 992 jQuery.browser.msie && 993 [ 1, "div<div>", "</div>" ] || 994 995 [ 0, "", "" ]; 996 997 // Go to html and back, then peel off extra wrappers 998 div.innerHTML = wrap[1] + elem + wrap[2]; 999 1000 // Move to the right depth 1001 while ( wrap[0]-- ) 1002 div = div.lastChild; 1003 1004 // Remove IE's autoinserted <tbody> from table fragments 1005 if ( jQuery.browser.msie ) { 1006 1007 // String was a <table>, *may* have spurious <tbody> 1008 var tbody = !tags.indexOf("<table") && tags.indexOf("<tbody") < 0 ? 1009 div.firstChild && div.firstChild.childNodes : 1010 1011 // String was a bare <thead> or <tfoot> 1012 wrap[1] == "<table>" && tags.indexOf("<tbody") < 0 ? 1013 div.childNodes : 1014 []; 1015 1016 for ( var j = tbody.length - 1; j >= 0 ; --j ) 1017 if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) 1018 tbody[ j ].parentNode.removeChild( tbody[ j ] ); 1019 1020 // IE completely kills leading whitespace when innerHTML is used 1021 if ( /^\s/.test( elem ) ) 1022 div.insertBefore( context.createTextNode( elem.match(/^\s*/)[0] ), div.firstChild ); 1023 1024 } 1025 1026 elem = jQuery.makeArray( div.childNodes ); 1027 } 1028 1029 if ( elem.length === 0 && (!jQuery.nodeName( elem, "form" ) && !jQuery.nodeName( elem, "select" )) ) 1030 return; 1031 1032 if ( elem[0] == undefined || jQuery.nodeName( elem, "form" ) || elem.options ) 1033 ret.push( elem ); 1034 1035 else 1036 ret = jQuery.merge( ret, elem ); 1037 1038 }); 1039 1040 return ret; 1041 }, 1042 1043 attr: function( elem, name, value ) { 1044 // don't set attributes on text and comment nodes 1045 if (!elem || elem.nodeType == 3 || elem.nodeType == 8) 1046 return undefined; 1047 1048 var fix = jQuery.isXMLDoc( elem ) ? 1049 {} : 1050 jQuery.props; 1051 1052 // Safari mis-reports the default selected property of a hidden option 1053 // Accessing the parent's selectedIndex property fixes it 1054 if ( name == "selected" && jQuery.browser.safari ) 1055 elem.parentNode.selectedIndex; 1056 1057 // Certain attributes only work when accessed via the old DOM 0 way 1058 if ( fix[ name ] ) { 1059 if ( value != undefined ) 1060 elem[ fix[ name ] ] = value; 1061 1062 return elem[ fix[ name ] ]; 1063 1064 } else if ( jQuery.browser.msie && name == "style" ) 1065 return jQuery.attr( elem.style, "cssText", value ); 1066 1067 else if ( value == undefined && jQuery.browser.msie && jQuery.nodeName( elem, "form" ) && (name == "action" || name == "method") ) 1068 return elem.getAttributeNode( name ).nodeValue; 1069 1070 // IE elem.getAttribute passes even for style 1071 else if ( elem.tagName ) { 1072 1073 if ( value != undefined ) { 1074 // We can't allow the type property to be changed (since it causes problems in IE) 1075 if ( name == "type" && jQuery.nodeName( elem, "input" ) && elem.parentNode ) 1076 throw "type property can't be changed"; 1077 1078 // convert the value to a string (all browsers do this but IE) see #1070 1079 elem.setAttribute( name, "" + value ); 1080 } 1081 1082 if ( jQuery.browser.msie && /href|src/.test( name ) && !jQuery.isXMLDoc( elem ) ) 1083 return elem.getAttribute( name, 2 ); 1084 1085 return elem.getAttribute( name ); 1086 1087 // elem is actually elem.style ... set the style 1088 } else { 1089 // IE actually uses filters for opacity 1090 if ( name == "opacity" && jQuery.browser.msie ) { 1091 if ( value != undefined ) { 1092 // IE has trouble with opacity if it does not have layout 1093 // Force it by setting the zoom level 1094 elem.zoom = 1; 1095 1096 // Set the alpha filter to set the opacity 1097 elem.filter = (elem.filter || "").replace( /alpha\([^)]*\)/, "" ) + 1098 (parseFloat( value ).toString() == "NaN" ? "" : "alpha(opacity=" + value * 100 + ")"); 1099 } 1100 1101 return elem.filter && elem.filter.indexOf("opacity=") >= 0 ? 1102 (parseFloat( elem.filter.match(/opacity=([^)]*)/)[1] ) / 100).toString() : 1103 ""; 1104 } 1105 1106 name = name.replace(/-([a-z])/ig, function(all, letter){ 1107 return letter.toUpperCase(); 1108 }); 1109 1110 if ( value != undefined ) 1111 elem[ name ] = value; 1112 1113 return elem[ name ]; 1114 } 1115 }, 1116 1117 trim: function( text ) { 1118 return (text || "").replace( /^\s+|\s+$/g, "" ); 1119 }, 1120 1121 makeArray: function( array ) { 1122 var ret = []; 1123 1124 // Need to use typeof to fight Safari childNodes crashes 1125 if ( typeof array != "array" ) 1126 for ( var i = 0, length = array.length; i < length; i++ ) 1127 ret.push( array[ i ] ); 1128 else 1129 ret = array.slice( 0 ); 1130 1131 return ret; 1132 }, 1133 1134 inArray: function( elem, array ) { 1135 for ( var i = 0, length = array.length; i < length; i++ ) 1136 if ( array[ i ] == elem ) 1137 return i; 1138 1139 return -1; 1140 }, 1141 1142 merge: function( first, second ) { 1143 // We have to loop this way because IE & Opera overwrite the length 1144 // expando of getElementsByTagName 1145 1146 // Also, we need to make sure that the correct elements are being returned 1147 // (IE returns comment nodes in a '*' query) 1148 if ( jQuery.browser.msie ) { 1149 for ( var i = 0; second[ i ]; i++ ) 1150 if ( second[ i ].nodeType != 8 ) 1151 first.push( second[ i ] ); 1152 1153 } else 1154 for ( var i = 0; second[ i ]; i++ ) 1155 first.push( second[ i ] ); 1156 1157 return first; 1158 }, 1159 1160 unique: function( array ) { 1161 var ret = [], done = {}; 1162 1163 try { 1164 1165 for ( var i = 0, length = array.length; i < length; i++ ) { 1166 var id = jQuery.data( array[ i ] ); 1167 1168 if ( !done[ id ] ) { 1169 done[ id ] = true; 1170 ret.push( array[ i ] ); 1171 } 1172 } 1173 1174 } catch( e ) { 1175 ret = array; 1176 } 1177 1178 return ret; 1179 }, 1180 1181 grep: function( elems, callback, inv ) { 1182 var ret = []; 1183 1184 // Go through the array, only saving the items 1185 // that pass the validator function 1186 for ( var i = 0, length = elems.length; i < length; i++ ) 1187 if ( !inv && callback( elems[ i ], i ) || inv && !callback( elems[ i ], i ) ) 1188 ret.push( elems[ i ] ); 1189 1190 return ret; 1191 }, 1192 1193 map: function( elems, callback ) { 1194 var ret = []; 1195 1196 // Go through the array, translating each of the items to their 1197 // new value (or values). 1198 for ( var i = 0, length = elems.length; i < length; i++ ) { 1199 var value = callback( elems[ i ], i ); 1200 1201 if ( value !== null && value != undefined ) { 1202 if ( value.constructor != Array ) 1203 value = [ value ]; 1204 1205 ret = ret.concat( value ); 1206 } 1207 } 1208 1209 return ret; 1210 } 1211 }); 1212 1213 var userAgent = navigator.userAgent.toLowerCase(); 1214 1215 // Figure out what browser is being used 1216 jQuery.browser = { 1217 version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [])[1], 1218 safari: /webkit/.test( userAgent ), 1219 opera: /opera/.test( userAgent ), 1220 msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ), 1221 mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent ) 1222 }; 1223 1224 var styleFloat = jQuery.browser.msie ? 1225 "styleFloat" : 1226 "cssFloat"; 1227 1228 jQuery.extend({ 1229 // Check to see if the W3C box model is being used 1230 boxModel: !jQuery.browser.msie || document.compatMode == "CSS1Compat", 1231 1232 props: { 1233 "for": "htmlFor", 1234 "class": "className", 1235 "float": styleFloat, 1236 cssFloat: styleFloat, 1237 styleFloat: styleFloat, 1238 innerHTML: "innerHTML", 1239 className: "className", 1240 value: "value", 1241 disabled: "disabled", 1242 checked: "checked", 1243 readonly: "readOnly", 1244 selected: "selected", 1245 maxlength: "maxLength", 1246 selectedIndex: "selectedIndex", 1247 defaultValue: "defaultValue", 1248 tagName: "tagName", 1249 nodeName: "nodeName" 1250 } 1251 }); 1252 1253 jQuery.each({ 1254 parent: function(elem){return elem.parentNode;}, 1255 parents: function(elem){return jQuery.dir(elem,"parentNode");}, 1256 next: function(elem){return jQuery.nth(elem,2,"nextSibling");}, 1257 prev: function(elem){return jQuery.nth(elem,2,"previousSibling");}, 1258 nextAll: function(elem){return jQuery.dir(elem,"nextSibling");}, 1259 prevAll: function(elem){return jQuery.dir(elem,"previousSibling");}, 1260 siblings: function(elem){return jQuery.sibling(elem.parentNode.firstChild,elem);}, 1261 children: function(elem){return jQuery.sibling(elem.firstChild);}, 1262 contents: function(elem){return jQuery.nodeName(elem,"iframe")?elem.contentDocument||elem.contentWindow.document:jQuery.makeArray(elem.childNodes);} 1263 }, function(name, fn){ 1264 jQuery.fn[ name ] = function( selector ) { 1265 var ret = jQuery.map( this, fn ); 1266 1267 if ( selector && typeof selector == "string" ) 1268 ret = jQuery.multiFilter( selector, ret ); 1269 1270 return this.pushStack( jQuery.unique( ret ) ); 1271 }; 1272 }); 1273 1274 jQuery.each({ 1275 appendTo: "append", 1276 prependTo: "prepend", 1277 insertBefore: "before", 1278 insertAfter: "after", 1279 replaceAll: "replaceWith" 1280 }, function(name, original){ 1281 jQuery.fn[ name ] = function() { 1282 var args = arguments; 1283 1284 return this.each(function(){ 1285 for ( var i = 0, length = args.length; i < length; i++ ) 1286 jQuery( args[ i ] )[ original ]( this ); 1287 }); 1288 }; 1289 }); 1290 1291 jQuery.each({ 1292 removeAttr: function( name ) { 1293 jQuery.attr( this, name, "" ); 1294 if (this.nodeType == 1) 1295 this.removeAttribute( name ); 1296 }, 1297 1298 addClass: function( classNames ) { 1299 jQuery.className.add( this, classNames ); 1300 }, 1301 1302 removeClass: function( classNames ) { 1303 jQuery.className.remove( this, classNames ); 1304 }, 1305 1306 toggleClass: function( classNames ) { 1307 jQuery.className[ jQuery.className.has( this, classNames ) ? "remove" : "add" ]( this, classNames ); 1308 }, 1309 1310 remove: function( selector ) { 1311 if ( !selector || jQuery.filter( selector, [ this ] ).r.length ) { 1312 // Prevent memory leaks 1313 jQuery( "*", this ).add(this).each(function(){ 1314 jQuery.event.remove(this); 1315 jQuery.removeData(this); 1316 }); 1317 if (this.parentNode) 1318 this.parentNode.removeChild( this ); 1319 } 1320 }, 1321 1322 empty: function() { 1323 // Remove element nodes and prevent memory leaks 1324 jQuery( ">*", this ).remove(); 1325 1326 // Remove any remaining nodes 1327 while ( this.firstChild ) 1328 this.removeChild( this.firstChild ); 1329 } 1330 }, function(name, fn){ 1331 jQuery.fn[ name ] = function(){ 1332 return this.each( fn, arguments ); 1333 }; 1334 }); 1335 1336 jQuery.each([ "Height", "Width" ], function(i, name){ 1337 var type = name.toLowerCase(); 1338 1339 jQuery.fn[ type ] = function( size ) { 1340 // Get window width or height 1341 return this[0] == window ? 1342 // Opera reports document.body.client[Width/Height] properly in both quirks and standards 1343 jQuery.browser.opera && document.body[ "client" + name ] || 1344 1345 // Safari reports inner[Width/Height] just fine (Mozilla and Opera include scroll bar widths) 1346 jQuery.browser.safari && window[ "inner" + name ] || 1347 1348 // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode 1349 document.compatMode == "CSS1Compat" && document.documentElement[ "client" + name ] || document.body[ "client" + name ] : 1350 1351 // Get document width or height 1352 this[0] == document ? 1353 // Either scroll[Width/Height] or offset[Width/Height], whichever is greater 1354 Math.max( 1355 Math.max(document.body["scroll" + name], document.documentElement["scroll" + name]), 1356 Math.max(document.body["offset" + name], document.documentElement["offset" + name]) 1357 ) : 1358 1359 // Get or set width or height on the element 1360 size == undefined ? 1361 // Get width or height on the element 1362 (this.length ? jQuery.css( this[0], type ) : null) : 1363 1364 // Set the width or height on the element (default to pixels if value is unitless) 1365 this.css( type, size.constructor == String ? size : size + "px" ); 1366 }; 1367 }); 1368 1369 var chars = jQuery.browser.safari && parseInt(jQuery.browser.version) < 417 ? 1370 "(?:[\\w*_-]|\\\\.)" : 1371 "(?:[\\w\u0128-\uFFFF*_-]|\\\\.)", 1372 quickChild = new RegExp("^>\\s*(" + chars + "+)"), 1373 quickID = new RegExp("^(" + chars + "+)(#)(" + chars + "+)"), 1374 quickClass = new RegExp("^([#.]?)(" + chars + "*)"); 1375 1376 jQuery.extend({ 1377 expr: { 1378 "": function(a,i,m){return m[2]=="*"||jQuery.nodeName(a,m[2]);}, 1379 "#": function(a,i,m){return a.getAttribute("id")==m[2];}, 1380 ":": { 1381 // Position Checks 1382 lt: function(a,i,m){return i<m[3]-0;}, 1383 gt: function(a,i,m){return i>m[3]-0;}, 1384 nth: function(a,i,m){return m[3]-0==i;}, 1385 eq: function(a,i,m){return m[3]-0==i;}, 1386 first: function(a,i){return i==0;}, 1387 last: function(a,i,m,r){return i==r.length-1;}, 1388 even: function(a,i){return i%2==0;}, 1389 odd: function(a,i){return i%2;}, 1390 1391 // Child Checks 1392 "first-child": function(a){return a.parentNode.getElementsByTagName("*")[0]==a;}, 1393 "last-child": function(a){return jQuery.nth(a.parentNode.lastChild,1,"previousSibling")==a;}, 1394 "only-child": function(a){return !jQuery.nth(a.parentNode.lastChild,2,"previousSibling");}, 1395 1396 // Parent Checks 1397 parent: function(a){return a.firstChild;}, 1398 empty: function(a){return !a.firstChild;}, 1399 1400 // Text Check 1401 contains: function(a,i,m){return (a.textContent||a.innerText||jQuery(a).text()||"").indexOf(m[3])>=0;}, 1402 1403 // Visibility 1404 visible: function(a){return "hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden";}, 1405 hidden: function(a){return "hidden"==a.type||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden";}, 1406 1407 // Form attributes 1408 enabled: function(a){return !a.disabled;}, 1409 disabled: function(a){return a.disabled;}, 1410 checked: function(a){return a.checked;}, 1411 selected: function(a){return a.selected||jQuery.attr(a,"selected");}, 1412 1413 // Form elements 1414 text: function(a){return "text"==a.type;}, 1415 radio: function(a){return "radio"==a.type;}, 1416 checkbox: function(a){return "checkbox"==a.type;}, 1417 file: function(a){return "file"==a.type;}, 1418 password: function(a){return "password"==a.type;}, 1419 submit: function(a){return "submit"==a.type;}, 1420 image: function(a){return "image"==a.type;}, 1421 reset: function(a){return "reset"==a.type;}, 1422 button: function(a){return "button"==a.type||jQuery.nodeName(a,"button");}, 1423 input: function(a){return /input|select|textarea|button/i.test(a.nodeName);}, 1424 1425 // :has() 1426 has: function(a,i,m){return jQuery.find(m[3],a).length;}, 1427 1428 // :header 1429 header: function(a){return /h\d/i.test(a.nodeName);}, 1430 1431 // :animated 1432 animated: function(a){return jQuery.grep(jQuery.timers,function(fn){return a==fn.elem;}).length;} 1433 } 1434 }, 1435 1436 // The regular expressions that power the parsing engine 1437 parse: [ 1438 // Match: [@value='test'], [@foo] 1439 /^(\[) *@?([\w-]+) *([!*$^~=]*) *('?"?)(.*?)\4 *\]/, 1440 1441 // Match: :contains('foo') 1442 /^(:)([\w-]+)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/, 1443 1444 // Match: :even, :last-chlid, #id, .class 1445 new RegExp("^([:.#]*)(" + chars + "+)") 1446 ], 1447 1448 multiFilter: function( expr, elems, not ) { 1449 var old, cur = []; 1450 1451 while ( expr && expr != old ) { 1452 old = expr; 1453 var f = jQuery.filter( expr, elems, not ); 1454 expr = f.t.replace(/^\s*,\s*/, "" ); 1455 cur = not ? elems = f.r : jQuery.merge( cur, f.r ); 1456 } 1457 1458 return cur; 1459 }, 1460 1461 find: function( t, context ) { 1462 // Quickly handle non-string expressions 1463 if ( typeof t != "string" ) 1464 return [ t ]; 1465 1466 // check to make sure context is a DOM element or a document 1467 if ( context && context.nodeType != 1 && context.nodeType != 9) 1468 return [ ]; 1469 1470 // Set the correct context (if none is provided) 1471 context = context || document; 1472 1473 // Initialize the search 1474 var ret = [context], done = [], last, nodeName; 1475 1476 // Continue while a selector expression exists, and while 1477 // we're no longer looping upon ourselves 1478 while ( t && last != t ) { 1479 var r = []; 1480 last = t; 1481 1482 t = jQuery.trim(t); 1483 1484 var foundToken = false; 1485 1486 // An attempt at speeding up child selectors that 1487 // point to a specific element tag 1488 var re = quickChild; 1489 var m = re.exec(t); 1490 1491 if ( m ) { 1492 nodeName = m[1].toUpperCase(); 1493 1494 // Perform our own iteration and filter 1495 for ( var i = 0; ret[i]; i++ ) 1496 for ( var c = ret[i].firstChild; c; c = c.nextSibling ) 1497 if ( c.nodeType == 1 && (nodeName == "*" || c.nodeName.toUpperCase() == nodeName) ) 1498 r.push( c ); 1499 1500 ret = r; 1501 t = t.replace( re, "" ); 1502 if ( t.indexOf(" ") == 0 ) continue; 1503 foundToken = true; 1504 } else { 1505 re = /^([>+~])\s*(\w*)/i; 1506 1507 if ( (m = re.exec(t)) != null ) { 1508 r = []; 1509 1510 var merge = {}; 1511 nodeName = m[2].toUpperCase(); 1512 m = m[1]; 1513 1514 for ( var j = 0, rl = ret.length; j < rl; j++ ) { 1515 var n = m == "~" || m == "+" ? ret[j].nextSibling : ret[j].firstChild; 1516 for ( ; n; n = n.nextSibling ) 1517 if ( n.nodeType == 1 ) { 1518 var id = jQuery.data(n); 1519 1520 if ( m == "~" && merge[id] ) break; 1521 1522 if (!nodeName || n.nodeName.toUpperCase() == nodeName ) { 1523 if ( m == "~" ) merge[id] = true; 1524 r.push( n ); 1525 } 1526 1527 if ( m == "+" ) break; 1528 } 1529 } 1530 1531 ret = r; 1532 1533 // And remove the token 1534 t = jQuery.trim( t.replace( re, "" ) ); 1535 foundToken = true; 1536 } 1537 } 1538 1539 // See if there's still an expression, and that we haven't already 1540 // matched a token 1541 if ( t && !foundToken ) { 1542 // Handle multiple expressions 1543 if ( !t.indexOf(",") ) { 1544 // Clean the result set 1545 if ( context == ret[0] ) ret.shift(); 1546 1547 // Merge the result sets 1548 done = jQuery.merge( done, ret ); 1549 1550 // Reset the context 1551 r = ret = [context]; 1552 1553 // Touch up the selector string 1554 t = " " + t.substr(1,t.length); 1555 1556 } else { 1557 // Optimize for the case nodeName#idName 1558 var re2 = quickID; 1559 var m = re2.exec(t); 1560 1561 // Re-organize the results, so that they're consistent 1562 if ( m ) { 1563 m = [ 0, m[2], m[3], m[1] ]; 1564 1565 } else { 1566 // Otherwise, do a traditional filter check for 1567 // ID, class, and element selectors 1568 re2 = quickClass; 1569 m = re2.exec(t); 1570 } 1571 1572 m[2] = m[2].replace(/\\/g, ""); 1573 1574 var elem = ret[ret.length-1]; 1575 1576 // Try to do a global search by ID, where we can 1577 if ( m[1] == "#" && elem && elem.getElementById && !jQuery.isXMLDoc(elem) ) { 1578 // Optimization for HTML document case 1579 var oid = elem.getElementById(m[2]); 1580 1581 // Do a quick check for the existence of the actual ID attribute 1582 // to avoid selecting by the name attribute in IE 1583 // also check to insure id is a string to avoid selecting an element with the name of 'id' inside a form 1584 if ( (jQuery.browser.msie||jQuery.browser.opera) && oid && typeof oid.id == "string" && oid.id != m[2] ) 1585 oid = jQuery('[@id="'+m[2]+'"]', elem)[0]; 1586 1587 // Do a quick check for node name (where applicable) so 1588 // that div#foo searches will be really fast 1589 ret = r = oid && (!m[3] || jQuery.nodeName(oid, m[3])) ? [oid] : []; 1590 } else { 1591 // We need to find all descendant elements 1592 for ( var i = 0; ret[i]; i++ ) { 1593 // Grab the tag name being searched for 1594 var tag = m[1] == "#" && m[3] ? m[3] : m[1] != "" || m[0] == "" ? "*" : m[2]; 1595 1596 // Handle IE7 being really dumb about <object>s 1597 if ( tag == "*" && ret[i].nodeName.toLowerCase() == "object" ) 1598 tag = "param"; 1599 1600 r = jQuery.merge( r, ret[i].getElementsByTagName( tag )); 1601 } 1602 1603 // It's faster to filter by class and be done with it 1604 if ( m[1] == "." ) 1605 r = jQuery.classFilter( r, m[2] ); 1606 1607 // Same with ID filtering 1608 if ( m[1] == "#" ) { 1609 var tmp = []; 1610 1611 // Try to find the element with the ID 1612 for ( var i = 0; r[i]; i++ ) 1613 if ( r[i].getAttribute("id") == m[2] ) { 1614 tmp = [ r[i] ]; 1615 break; 1616 } 1617 1618 r = tmp; 1619 } 1620 1621 ret = r; 1622 } 1623 1624 t = t.replace( re2, "" ); 1625 } 1626 1627 } 1628 1629 // If a selector string still exists 1630 if ( t ) { 1631 // Attempt to filter it 1632 var val = jQuery.filter(t,r); 1633 ret = r = val.r; 1634 t = jQuery.trim(val.t); 1635 } 1636 } 1637 1638 // An error occurred with the selector; 1639 // just return an empty set instead 1640 if ( t ) 1641 ret = []; 1642 1643 // Remove the root context 1644 if ( ret && context == ret[0] ) 1645 ret.shift(); 1646 1647 // And combine the results 1648 done = jQuery.merge( done, ret ); 1649 1650 return done; 1651 }, 1652 1653 classFilter: function(r,m,not){ 1654 m = " " + m + " "; 1655 var tmp = []; 1656 for ( var i = 0; r[i]; i++ ) { 1657 var pass = (" " + r[i].className + " ").indexOf( m ) >= 0; 1658 if ( !not && pass || not && !pass ) 1659 tmp.push( r[i] ); 1660 } 1661 return tmp; 1662 }, 1663 1664 filter: function(t,r,not) { 1665 var last; 1666 1667 // Look for common filter expressions 1668 while ( t && t != last ) { 1669 last = t; 1670 1671 var p = jQuery.parse, m; 1672 1673 for ( var i = 0; p[i]; i++ ) { 1674 m = p[i].exec( t ); 1675 1676 if ( m ) { 1677 // Remove what we just matched 1678 t = t.substring( m[0].length ); 1679 1680 m[2] = m[2].replace(/\\/g, ""); 1681 break; 1682 } 1683 } 1684 1685 if ( !m ) 1686 break; 1687 1688 // :not() is a special case that can be optimized by 1689 // keeping it out of the expression list 1690 if ( m[1] == ":" && m[2] == "not" ) 1691 // optimize if only one selector found (most common case) 1692 r = isSimple.test( m[3] ) ? 1693 jQuery.filter(m[3], r, true).r : 1694 jQuery( r ).not( m[3] ); 1695 1696 // We can get a big speed boost by filtering by class here 1697 else if ( m[1] == "." ) 1698 r = jQuery.classFilter(r, m[2], not); 1699 1700 else if ( m[1] == "[" ) { 1701 var tmp = [], type = m[3]; 1702 1703 for ( var i = 0, rl = r.length; i < rl; i++ ) { 1704 var a = r[i], z = a[ jQuery.props[m[2]] || m[2] ]; 1705 1706 if ( z == null || /href|src|selected/.test(m[2]) ) 1707 z = jQuery.attr(a,m[2]) || ''; 1708 1709 if ( (type == "" && !!z || 1710 type == "=" && z == m[5] || 1711 type == "!=" && z != m[5] || 1712 type == "^=" && z && !z.indexOf(m[5]) || 1713 type == "$=" && z.substr(z.length - m[5].length) == m[5] || 1714 (type == "*=" || type == "~=") && z.indexOf(m[5]) >= 0) ^ not ) 1715 tmp.push( a ); 1716 } 1717 1718 r = tmp; 1719 1720 // We can get a speed boost by handling nth-child here 1721 } else if ( m[1] == ":" && m[2] == "nth-child" ) { 1722 var merge = {}, tmp = [], 1723 // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6' 1724 test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec( 1725 m[3] == "even" && "2n" || m[3] == "odd" && "2n+1" || 1726 !/\D/.test(m[3]) && "0n+" + m[3] || m[3]), 1727 // calculate the numbers (first)n+(last) including if they are negative 1728 first = (test[1] + (test[2] || 1)) - 0, last = test[3] - 0; 1729 1730 // loop through all the elements left in the jQuery object 1731 for ( var i = 0, rl = r.length; i < rl; i++ ) { 1732 var node = r[i], parentNode = node.parentNode, id = jQuery.data(parentNode); 1733 1734 if ( !merge[id] ) { 1735 var c = 1; 1736 1737 for ( var n = parentNode.firstChild; n; n = n.nextSibling ) 1738 if ( n.nodeType == 1 ) 1739 n.nodeIndex = c++; 1740 1741 merge[id] = true; 1742 } 1743 1744 var add = false; 1745 1746 if ( first == 0 ) { 1747 if ( node.nodeIndex == last ) 1748 add = true; 1749 } else if ( (node.nodeIndex - last) % first == 0 && (node.nodeIndex - last) / first >= 0 ) 1750 add = true; 1751 1752 if ( add ^ not ) 1753 tmp.push( node ); 1754 } 1755 1756 r = tmp; 1757 1758 // Otherwise, find the expression to execute 1759 } else { 1760 var fn = jQuery.expr[ m[1] ]; 1761 if ( typeof fn == "object" ) 1762 fn = fn[ m[2] ]; 1763 1764 if ( typeof fn == "string" ) 1765 fn = eval("false||function(a,i){return " + fn + ";}"); 1766 1767 // Execute it against the current filter 1768 r = jQuery.grep( r, function(elem, i){ 1769 return fn(elem, i, m, r); 1770 }, not ); 1771 } 1772 } 1773 1774 // Return an array of filtered elements (r) 1775 // and the modified expression string (t) 1776 return { r: r, t: t }; 1777 }, 1778 1779 dir: function( elem, dir ){ 1780 var matched = []; 1781 var cur = elem[dir]; 1782 while ( cur && cur != document ) { 1783 if ( cur.nodeType == 1 ) 1784 matched.push( cur ); 1785 cur = cur[dir]; 1786 } 1787 return matched; 1788 }, 1789 1790 nth: function(cur,result,dir,elem){ 1791 result = result || 1; 1792 var num = 0; 1793 1794 for ( ; cur; cur = cur[dir] ) 1795 if ( cur.nodeType == 1 && ++num == result ) 1796 break; 1797 1798 return cur; 1799 }, 1800 1801 sibling: function( n, elem ) { 1802 var r = []; 1803 1804 for ( ; n; n = n.nextSibling ) { 1805 if ( n.nodeType == 1 && (!elem || n != elem) ) 1806 r.push( n ); 1807 } 1808 1809 return r; 1810 } 1811 }); 1812 1813 /* 1814 * A number of helper functions used for managing events. 1815 * Many of the ideas behind this code orignated from 1816 * Dean Edwards' addEvent library. 1817 */ 1818 jQuery.event = { 1819 1820 // Bind an event to an element 1821 // Original by Dean Edwards 1822 add: function(elem, types, handler, data) { 1823 if ( elem.nodeType == 3 || elem.nodeType == 8 ) 1824 return; 1825 1826 // For whatever reason, IE has trouble passing the window object 1827 // around, causing it to be cloned in the process 1828 if ( jQuery.browser.msie && elem.setInterval != undefined ) 1829 elem = window; 1830 1831 // Make sure that the function being executed has a unique ID 1832 if ( !handler.guid ) 1833 handler.guid = this.guid++; 1834 1835 // if data is passed, bind to handler 1836 if( data != undefined ) { 1837 // Create temporary function pointer to original handler 1838 var fn = handler; 1839 1840 // Create unique handler function, wrapped around original handler 1841 handler = function() { 1842 // Pass arguments and context to original handler 1843 return fn.apply(this, arguments); 1844 }; 1845 1846 // Store data in unique handler 1847 handler.data = data; 1848 1849 // Set the guid of unique handler to the same of original handler, so it can be removed 1850 handler.guid = fn.guid; 1851 } 1852 1853 // Init the element's event structure 1854 var events = jQuery.data(elem, "events") || jQuery.data(elem, "events", {}), 1855 handle = jQuery.data(elem, "handle") || jQuery.data(elem, "handle", function(){ 1856 // returned undefined or false 1857 var val; 1858 1859 // Handle the second event of a trigger and when 1860 // an event is called after a page has unloaded 1861 if ( typeof jQuery == "undefined" || jQuery.event.triggered ) 1862 return val; 1863 1864 val = jQuery.event.handle.apply(arguments.callee.elem, arguments); 1865 1866 return val; 1867 }); 1868 // Add elem as a property of the handle function 1869 // This is to prevent a memory leak with non-native 1870 // event in IE. 1871 handle.elem = elem; 1872 1873 // Handle multiple events seperated by a space 1874 // jQuery(...).bind("mouseover mouseout", fn); 1875 jQuery.each(types.split(/\s+/), function(index, type) { 1876 // Namespaced event handlers 1877 var parts = type.split("."); 1878 type = parts[0]; 1879 handler.type = parts[1]; 1880 1881 // Get the current list of functions bound to this event 1882 var handlers = events[type]; 1883 1884 // Init the event handler queue 1885 if (!handlers) { 1886 handlers = events[type] = {}; 1887 1888 // Check for a special event handler 1889 // Only use addEventListener/attachEvent if the special 1890 // events handler returns false 1891 if ( !jQuery.event.special[type] || jQuery.event.special[type].setup.call(elem) === false ) { 1892 // Bind the global event handler to the element 1893 if (elem.addEventListener) 1894 elem.addEventListener(type, handle, false); 1895 else if (elem.attachEvent) 1896 elem.attachEvent("on" + type, handle); 1897 } 1898 } 1899 1900 // Add the function to the element's handler list 1901 handlers[handler.guid] = handler; 1902 1903 // Keep track of which events have been used, for global triggering 1904 jQuery.event.global[type] = true; 1905 }); 1906 1907 // Nullify elem to prevent memory leaks in IE 1908 elem = null; 1909 }, 1910 1911 guid: 1, 1912 global: {}, 1913 1914 // Detach an event or set of events from an element 1915 remove: function(elem, types, handler) { 1916 // don't do events on text and comment nodes 1917 if ( elem.nodeType == 3 || elem.nodeType == 8 ) 1918 return; 1919 1920 var events = jQuery.data(elem, "events"), ret, index; 1921 1922 if ( events ) { 1923 // Unbind all events for the element 1924 if ( types == undefined || (typeof types == "string" && types.charAt(0) == ".") ) 1925 for ( var type in events ) 1926 this.remove( elem, type + (types || "") ); 1927 else { 1928 // types is actually an event object here 1929 if ( types.type ) { 1930 handler = types.handler; 1931 types = types.type; 1932 } 1933 1934 // Handle multiple events seperated by a space 1935 // jQuery(...).unbind("mouseover mouseout", fn); 1936 jQuery.each(types.split(/\s+/), function(index, type){ 1937 // Namespaced event handlers 1938 var parts = type.split("."); 1939 type = parts[0]; 1940 1941 if ( events[type] ) { 1942 // remove the given handler for the given type 1943 if ( handler ) 1944 delete events[type][handler.guid]; 1945 1946 // remove all handlers for the given type 1947 else 1948 for ( handler in events[type] ) 1949 // Handle the removal of namespaced events 1950 if ( !parts[1] || events[type][handler].type == parts[1] ) 1951 delete events[type][handler]; 1952 1953 // remove generic event handler if no more handlers exist 1954 for ( ret in events[type] ) break; 1955 if ( !ret ) { 1956 if ( !jQuery.event.special[type] || jQuery.event.special[type].teardown.call(elem) === false ) { 1957 if (elem.removeEventListener) 1958 elem.removeEventListener(type, jQuery.data(elem, "handle"), false); 1959 else if (elem.detachEvent) 1960 elem.detachEvent("on" + type, jQuery.data(elem, "handle")); 1961 } 1962 ret = null; 1963 delete events[type]; 1964 } 1965 } 1966 }); 1967 } 1968 1969 // Remove the expando if it's no longer used 1970 for ( ret in events ) break; 1971 if ( !ret ) { 1972 var handle = jQuery.data( elem, "handle" ); 1973 if ( handle ) handle.elem = null; 1974 jQuery.removeData( elem, "events" ); 1975 jQuery.removeData( elem, "handle" ); 1976 } 1977 } 1978 }, 1979 1980 trigger: function(type, data, elem, donative, extra) { 1981 // Clone the incoming data, if any 1982 data = jQuery.makeArray(data || []); 1983 1984 if ( type.indexOf("!") >= 0 ) { 1985 type = type.slice(0, -1); 1986 var exclusive = true; 1987 } 1988 1989 // Handle a global trigger 1990 if ( !elem ) { 1991 // Only trigger if we've ever bound an event for it 1992 if ( this.global[type] ) 1993 jQuery("*").add([window, document]).trigger(type, data); 1994 1995 // Handle triggering a single element 1996 } else { 1997 // don't do events on text and comment nodes 1998 if ( elem.nodeType == 3 || elem.nodeType == 8 ) 1999 return undefined; 2000 2001 var val, ret, fn = jQuery.isFunction( elem[ type ] || null ), 2002 // Check to see if we need to provide a fake event, or not 2003 event = !data[0] || !data[0].preventDefault; 2004 2005 // Pass along a fake event 2006 if ( event ) 2007 data.unshift( this.fix({ type: type, target: elem }) ); 2008 2009 // Enforce the right trigger type 2010 data[0].type = type; 2011 if ( exclusive ) 2012 data[0].exclusive = true; 2013 2014 // Trigger the event 2015 if ( jQuery.isFunction( jQuery.data(elem, "handle") ) ) 2016 val = jQuery.data(elem, "handle").apply( elem, data ); 2017 2018 // Handle triggering native .onfoo handlers 2019 if ( !fn && elem["on"+type] && elem["on"+type].apply( elem, data ) === false ) 2020 val = false; 2021 2022 // Extra functions don't get the custom event object 2023 if ( event ) 2024 data.shift(); 2025 2026 // Handle triggering of extra function 2027 if ( extra && jQuery.isFunction( extra ) ) { 2028 // call the extra function and tack the current return value on the end for possible inspection 2029 ret = extra.apply( elem, val == null ? data : data.concat( val ) ); 2030 // if anything is returned, give it precedence and have it overwrite the previous value 2031 if (ret !== undefined) 2032 val = ret; 2033 } 2034 2035 // Trigger the native events (except for clicks on links) 2036 if ( fn && donative !== false && val !== false && !(jQuery.nodeName(elem, 'a') && type == "click") ) { 2037 this.triggered = true; 2038 try { 2039 elem[ type ](); 2040 // prevent IE from throwing an error for some hidden elements 2041 } catch (e) {} 2042 } 2043 2044 this.triggered = false; 2045 } 2046 2047 return val; 2048 }, 2049 2050 handle: function(event) { 2051 // returned undefined or false 2052 var val; 2053 2054 // Empty object is for triggered events with no data 2055 event = jQuery.event.fix( event || window.event || {} ); 2056 2057 // Namespaced event handlers 2058 var parts = event.type.split("."); 2059 event.type = parts[0]; 2060 2061 var handlers = jQuery.data(this, "events") && jQuery.data(this, "events")[event.type], args = Array.prototype.slice.call( arguments, 1 ); 2062 args.unshift( event ); 2063 2064 for ( var j in handlers ) { 2065 var handler = handlers[j]; 2066 // Pass in a reference to the handler function itself 2067 // So that we can later remove it 2068 args[0].handler = handler; 2069 args[0].data = handler.data; 2070 2071 // Filter the functions by class 2072 if ( !parts[1] && !event.exclusive || handler.type == parts[1] ) { 2073 var ret = handler.apply( this, args ); 2074 2075 if ( val !== false ) 2076 val = ret; 2077 2078 if ( ret === false ) { 2079 event.preventDefault(); 2080 event.stopPropagation(); 2081 } 2082 } 2083 } 2084 2085 // Clean up added properties in IE to prevent memory leak 2086 if (jQuery.browser.msie) 2087 event.target = event.preventDefault = event.stopPropagation = 2088 event.handler = event.data = null; 2089 2090 return val; 2091 }, 2092 2093 fix: function(event) { 2094 // store a copy of the original event object 2095 // and clone to set read-only properties 2096 var originalEvent = event; 2097 event = jQuery.extend({}, originalEvent); 2098 2099 // add preventDefault and stopPropagation since 2100 // they will not work on the clone 2101 event.preventDefault = function() { 2102 // if preventDefault exists run it on the original event 2103 if (originalEvent.preventDefault) 2104 originalEvent.preventDefault(); 2105 // otherwise set the returnValue property of the original event to false (IE) 2106 originalEvent.returnValue = false; 2107 }; 2108 event.stopPropagation = function() { 2109 // if stopPropagation exists run it on the original event 2110 if (originalEvent.stopPropagation) 2111 originalEvent.stopPropagation(); 2112 // otherwise set the cancelBubble property of the original event to true (IE) 2113 originalEvent.cancelBubble = true; 2114 }; 2115 2116 // Fix target property, if necessary 2117 if ( !event.target ) 2118 event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either 2119 2120 // check if target is a textnode (safari) 2121 if ( event.target.nodeType == 3 ) 2122 event.target = originalEvent.target.parentNode; 2123 2124 // Add relatedTarget, if necessary 2125 if ( !event.relatedTarget && event.fromElement ) 2126 event.relatedTarget = event.fromElement == event.target ? event.toElement : event.fromElement; 2127 2128 // Calculate pageX/Y if missing and clientX/Y available 2129 if ( event.pageX == null && event.clientX != null ) { 2130 var doc = document.documentElement, body = document.body; 2131 event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc.clientLeft || 0); 2132 event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc.clientTop || 0); 2133 } 2134 2135 // Add which for key events 2136 if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) ) 2137 event.which = event.charCode || event.keyCode; 2138 2139 // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs) 2140 if ( !event.metaKey && event.ctrlKey ) 2141 event.metaKey = event.ctrlKey; 2142 2143 // Add which for click: 1 == left; 2 == middle; 3 == right 2144 // Note: button is not normalized, so don't use it 2145 if ( !event.which && event.button ) 2146 event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) )); 2147 2148 return event; 2149 }, 2150 2151 special: { 2152 ready: { 2153 setup: function() { 2154 // Make sure the ready event is setup 2155 bindReady(); 2156 return; 2157 }, 2158 2159 teardown: function() { return; } 2160 }, 2161 2162 mouseenter: { 2163 setup: function() { 2164 if ( jQuery.browser.msie ) return false; 2165 jQuery(this).bind("mouseover", jQuery.event.special.mouseenter.handler); 2166 return true; 2167 }, 2168 2169 teardown: function() { 2170 if ( jQuery.browser.msie ) return false; 2171 jQuery(this).unbind("mouseover", jQuery.event.special.mouseenter.handler); 2172 return true; 2173 }, 2174 2175 handler: function(event) { 2176 // If we actually just moused on to a sub-element, ignore it 2177 if ( withinElement(event, this) ) return true; 2178 // Execute the right handlers by setting the event type to mouseenter 2179 arguments[0].type = "mouseenter"; 2180 return jQuery.event.handle.apply(this, arguments); 2181 } 2182 }, 2183 2184 mouseleave: { 2185 setup: function() { 2186 if ( jQuery.browser.msie ) return false; 2187 jQuery(this).bind("mouseout", jQuery.event.special.mouseleave.handler); 2188 return true; 2189 }, 2190 2191 teardown: function() { 2192 if ( jQuery.browser.msie ) return false; 2193 jQuery(this).unbind("mouseout", jQuery.event.special.mouseleave.handler); 2194 return true; 2195 }, 2196 2197 handler: function(event) { 2198 // If we actually just moused on to a sub-element, ignore it 2199 if ( withinElement(event, this) ) return true; 2200 // Execute the right handlers by setting the event type to mouseleave 2201 arguments[0].type = "mouseleave"; 2202 return jQuery.event.handle.apply(this, arguments); 2203 } 2204 } 2205 } 2206 }; 2207 2208 jQuery.fn.extend({ 2209 bind: function( type, data, fn ) { 2210 return type == "unload" ? this.one(type, data, fn) : this.each(function(){ 2211 jQuery.event.add( this, type, fn || data, fn && data ); 2212 }); 2213 }, 2214 2215 one: function( type, data, fn ) { 2216 return this.each(function(){ 2217 jQuery.event.add( this, type, function(event) { 2218 jQuery(this).unbind(event); 2219 return (fn || data).apply( this, arguments); 2220 }, fn && data); 2221 }); 2222 }, 2223 2224 unbind: function( type, fn ) { 2225 return this.each(function(){ 2226 jQuery.event.remove( this, type, fn ); 2227 }); 2228 }, 2229 2230 trigger: function( type, data, fn ) { 2231 return this.each(function(){ 2232 jQuery.event.trigger( type, data, this, true, fn ); 2233 }); 2234 }, 2235 2236 triggerHandler: function( type, data, fn ) { 2237 if ( this[0] ) 2238 return jQuery.event.trigger( type, data, this[0], false, fn ); 2239 return undefined; 2240 }, 2241 2242 toggle: function() { 2243 // Save reference to arguments for access in closure 2244 var args = arguments; 2245 2246 return this.click(function(event) { 2247 // Figure out which function to execute 2248 this.lastToggle = 0 == this.lastToggle ? 1 : 0; 2249 2250 // Make sure that clicks stop 2251 event.preventDefault(); 2252 2253 // and execute the function 2254 return args[this.lastToggle].apply( this, arguments ) || false; 2255 }); 2256 }, 2257 2258 hover: function(fnOver, fnOut) { 2259 return this.bind('mouseenter', fnOver).bind('mouseleave', fnOut); 2260 }, 2261 2262 ready: function(fn) { 2263 // Attach the listeners 2264 bindReady(); 2265 2266 // If the DOM is already ready 2267 if ( jQuery.isReady ) 2268 // Execute the function immediately 2269 fn.call( document, jQuery ); 2270 2271 // Otherwise, remember the function for later 2272 else 2273 // Add the function to the wait list 2274 jQuery.readyList.push( function() { return fn.call(this, jQuery); } ); 2275 2276 return this; 2277 } 2278 }); 2279 2280 jQuery.extend({ 2281 isReady: false, 2282 readyList: [], 2283 // Handle when the DOM is ready 2284 ready: function() { 2285 // Make sure that the DOM is not already loaded 2286 if ( !jQuery.isReady ) { 2287 // Remember that the DOM is ready 2288 jQuery.isReady = true; 2289 2290 // If there are functions bound, to execute 2291 if ( jQuery.readyList ) { 2292 // Execute all of them 2293 jQuery.each( jQuery.readyList, function(){ 2294 this.apply( document ); 2295 }); 2296 2297 // Reset the list of functions 2298 jQuery.readyList = null; 2299 } 2300 2301 // Trigger any bound ready events 2302 jQuery(document).triggerHandler("ready"); 2303 } 2304 } 2305 }); 2306 2307 var readyBound = false; 2308 2309 function bindReady(){ 2310 if ( readyBound ) return; 2311 readyBound = true; 2312 2313 // Mozilla, Opera (see further below for it) and webkit nightlies currently support this event 2314 if ( document.addEventListener && !jQuery.browser.opera) 2315 // Use the handy event callback 2316 document.addEventListener( "DOMContentLoaded", jQuery.ready, false ); 2317 2318 // If IE is used and is not in a frame 2319 // Continually check to see if the document is ready 2320 if ( jQuery.browser.msie && window == top ) (function(){ 2321 if (jQuery.isReady) return; 2322 try { 2323 // If IE is used, use the trick by Diego Perini 2324 // http://javascript.nwbox.com/IEContentLoaded/ 2325 document.documentElement.doScroll("left"); 2326 } catch( error ) { 2327 setTimeout( arguments.callee, 0 ); 2328 return; 2329 } 2330 // and execute any waiting functions 2331 jQuery.ready(); 2332 })(); 2333 2334 if ( jQuery.browser.opera ) 2335 document.addEventListener( "DOMContentLoaded", function () { 2336 if (jQuery.isReady) return; 2337 for (var i = 0; i < document.styleSheets.length; i++) 2338 if (document.styleSheets[i].disabled) { 2339 setTimeout( arguments.callee, 0 ); 2340 return; 2341 } 2342 // and execute any waiting functions 2343 jQuery.ready(); 2344 }, false); 2345 2346 if ( jQuery.browser.safari ) { 2347 var numStyles; 2348 (function(){ 2349 if (jQuery.isReady) return; 2350 if ( document.readyState != "loaded" && document.readyState != "complete" ) { 2351 setTimeout( arguments.callee, 0 ); 2352 return; 2353 } 2354 if ( numStyles === undefined ) 2355 numStyles = jQuery("style, link[rel=stylesheet]").length; 2356 if ( document.styleSheets.length != numStyles ) { 2357 setTimeout( arguments.callee, 0 ); 2358 return; 2359 } 2360 // and execute any waiting functions 2361 jQuery.ready(); 2362 })(); 2363 } 2364 2365 // A fallback to window.onload, that will always work 2366 jQuery.event.add( window, "load", jQuery.ready ); 2367 } 2368 2369 jQuery.each( ("blur,focus,load,resize,scroll,unload,click,dblclick," + 2370 "mousedown,mouseup,mousemove,mouseover,mouseout,change,select," + 2371 "submit,keydown,keypress,keyup,error").split(","), function(i, name){ 2372 2373 // Handle event binding 2374 jQuery.fn[name] = function(fn){ 2375 return fn ? this.bind(name, fn) : this.trigger(name); 2376 }; 2377 }); 2378 2379 // Checks if an event happened on an element within another element 2380 // Used in jQuery.event.special.mouseenter and mouseleave handlers 2381 var withinElement = function(event, elem) { 2382 // Check if mouse(over|out) are still within the same parent element 2383 var parent = event.relatedTarget; 2384 // Traverse up the tree 2385 while ( parent && parent != elem ) try { parent = parent.parentNode; } catch(error) { parent = elem; } 2386 // Return true if we actually just moused on to a sub-element 2387 return parent == elem; 2388 }; 2389 2390 // Prevent memory leaks in IE 2391 // And prevent errors on refresh with events like mouseover in other browsers 2392 // Window isn't included so as not to unbind existing unload events 2393 jQuery(window).bind("unload", function() { 2394 jQuery("*").add(document).unbind(); 2395 }); 2396 jQuery.fn.extend({ 2397 load: function( url, params, callback ) { 2398 if ( jQuery.isFunction( url ) ) 2399 return this.bind("load", url); 2400 2401 var off = url.indexOf(" "); 2402 if ( off >= 0 ) { 2403 var selector = url.slice(off, url.length); 2404 url = url.slice(0, off); 2405 } 2406 2407 callback = callback || function(){}; 2408 2409 // Default to a GET request 2410 var type = "GET"; 2411 2412 // If the second parameter was provided 2413 if ( params ) 2414 // If it's a function 2415 if ( jQuery.isFunction( params ) ) { 2416 // We assume that it's the callback 2417 callback = params; 2418 params = null; 2419 2420 // Otherwise, build a param string 2421 } else { 2422 params = jQuery.param( params ); 2423 type = "POST"; 2424 } 2425 2426 var self = this; 2427 2428 // Request the remote document 2429 jQuery.ajax({ 2430 url: url, 2431 type: type, 2432 dataType: "html", 2433 data: params, 2434 complete: function(res, status){ 2435 // If successful, inject the HTML into all the matched elements 2436 if ( status == "success" || status == "notmodified" ) 2437 // See if a selector was specified 2438 self.html( selector ? 2439 // Create a dummy div to hold the results 2440 jQuery("<div/>") 2441 // inject the contents of the document in, removing the scripts 2442 // to avoid any 'Permission Denied' errors in IE 2443 .append(res.responseText.replace(/<script(.|\s)*?\/script>/g, "")) 2444 2445 // Locate the specified elements 2446 .find(selector) : 2447 2448 // If not, just inject the full result 2449 res.responseText ); 2450 2451 self.each( callback, [res.responseText, status, res] ); 2452 } 2453 }); 2454 return this; 2455 }, 2456 2457 serialize: function() { 2458 return jQuery.param(this.serializeArray()); 2459 }, 2460 serializeArray: function() { 2461 return this.map(function(){ 2462 return jQuery.nodeName(this, "form") ? 2463 jQuery.makeArray(this.elements) : this; 2464 }) 2465 .filter(function(){ 2466 return this.name && !this.disabled && 2467 (this.checked || /select|textarea/i.test(this.nodeName) || 2468 /text|hidden|password/i.test(this.type)); 2469 }) 2470 .map(function(i, elem){ 2471 var val = jQuery(this).val(); 2472 return val == null ? null : 2473 val.constructor == Array ? 2474 jQuery.map( val, function(val, i){ 2475 return {name: elem.name, value: val}; 2476 }) : 2477 {name: elem.name, value: val}; 2478 }).get(); 2479 } 2480 }); 2481 2482 // Attach a bunch of functions for handling common AJAX events 2483 jQuery.each( "ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","), function(i,o){ 2484 jQuery.fn[o] = function(f){ 2485 return this.bind(o, f); 2486 }; 2487 }); 2488 2489 var jsc = (new Date).getTime(); 2490 2491 jQuery.extend({ 2492 get: function( url, data, callback, type ) { 2493 // shift arguments if data argument was ommited 2494 if ( jQuery.isFunction( data ) ) { 2495 callback = data; 2496 data = null; 2497 } 2498 2499 return jQuery.ajax({ 2500 type: "GET", 2501 url: url, 2502 data: data, 2503 success: callback, 2504 dataType: type 2505 }); 2506 }, 2507 2508 getScript: function( url, callback ) { 2509 return jQuery.get(url, null, callback, "script"); 2510 }, 2511 2512 getJSON: function( url, data, callback ) { 2513 return jQuery.get(url, data, callback, "json"); 2514 }, 2515 2516 post: function( url, data, callback, type ) { 2517 if ( jQuery.isFunction( data ) ) { 2518 callback = data; 2519 data = {}; 2520 } 2521 2522 return jQuery.ajax({ 2523 type: "POST", 2524 url: url, 2525 data: data, 2526 success: callback, 2527 dataType: type 2528 }); 2529 }, 2530 2531 ajaxSetup: function( settings ) { 2532 jQuery.extend( jQuery.ajaxSettings, settings ); 2533 }, 2534 2535 ajaxSettings: { 2536 global: true, 2537 type: "GET", 2538 timeout: 0, 2539 contentType: "application/x-www-form-urlencoded", 2540 processData: true, 2541 async: true, 2542 data: null, 2543 username: null, 2544 password: null, 2545 accepts: { 2546 xml: "application/xml, text/xml", 2547 html: "text/html", 2548 script: "text/javascript, application/javascript", 2549 json: "application/json, text/javascript", 2550 text: "text/plain", 2551 _default: "*/*" 2552 } 2553 }, 2554 2555 // Last-Modified header cache for next request 2556 lastModified: {}, 2557 2558 ajax: function( s ) { 2559 var jsonp, jsre = /=\?(&|$)/g, status, data; 2560 2561 // Extend the settings, but re-extend 's' so that it can be 2562 // checked again later (in the test suite, specifically) 2563 s = jQuery.extend(true, s, jQuery.extend(true, {}, jQuery.ajaxSettings, s)); 2564 2565 // convert data if not already a string 2566 if ( s.data && s.processData && typeof s.data != "string" ) 2567 s.data = jQuery.param(s.data); 2568 2569 // Handle JSONP Parameter Callbacks 2570 if ( s.dataType == "jsonp" ) { 2571 if ( s.type.toLowerCase() == "get" ) { 2572 if ( !s.url.match(jsre) ) 2573 s.url += (s.url.match(/\?/) ? "&" : "?") + (s.jsonp || "callback") + "=?"; 2574 } else if ( !s.data || !s.data.match(jsre) ) 2575 s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?"; 2576 s.dataType = "json"; 2577 } 2578 2579 // Build temporary JSONP function 2580 if ( s.dataType == "json" && (s.data && s.data.match(jsre) || s.url.match(jsre)) ) { 2581 jsonp = "jsonp" + jsc++; 2582 2583 // Replace the =? sequence both in the query string and the data 2584 if ( s.data ) 2585 s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1"); 2586 s.url = s.url.replace(jsre, "=" + jsonp + "$1"); 2587 2588 // We need to make sure 2589 // that a JSONP style response is executed properly 2590 s.dataType = "script"; 2591 2592 // Handle JSONP-style loading 2593 window[ jsonp ] = function(tmp){ 2594 data = tmp; 2595 success(); 2596 complete(); 2597 // Garbage collect 2598 window[ jsonp ] = undefined; 2599 try{ delete window[ jsonp ]; } catch(e){} 2600 if ( head ) 2601 head.removeChild( script ); 2602 }; 2603 } 2604 2605 if ( s.dataType == "script" && s.cache == null ) 2606 s.cache = false; 2607 2608 if ( s.cache === false && s.type.toLowerCase() == "get" ) { 2609 var ts = (new Date()).getTime(); 2610 // try replacing _= if it is there 2611 var ret = s.url.replace(/(\?|&)_=.*?(&|$)/, "$1_=" + ts + "$2"); 2612 // if nothing was replaced, add timestamp to the end 2613 s.url = ret + ((ret == s.url) ? (s.url.match(/\?/) ? "&" : "?") + "_=" + ts : ""); 2614 } 2615 2616 // If data is available, append data to url for get requests 2617 if ( s.data && s.type.toLowerCase() == "get" ) { 2618 s.url += (s.url.match(/\?/) ? "&" : "?") + s.data; 2619 2620 // IE likes to send both get and post data, prevent this 2621 s.data = null; 2622 } 2623 2624 // Watch for a new set of requests 2625 if ( s.global && ! jQuery.active++ ) 2626 jQuery.event.trigger( "ajaxStart" ); 2627 2628 // If we're requesting a remote document 2629 // and trying to load JSON or Script with a GET 2630 if ( (!s.url.indexOf("http") || !s.url.indexOf("//")) && s.dataType == "script" && s.type.toLowerCase() == "get" ) { 2631 var head = document.getElementsByTagName("head")[0]; 2632 var script = document.createElement("script"); 2633 script.src = s.url; 2634 if (s.scriptCharset) 2635 script.charset = s.scriptCharset; 2636 2637 // Handle Script loading 2638 if ( !jsonp ) { 2639 var done = false; 2640 2641 // Attach handlers for all browsers 2642 script.onload = script.onreadystatechange = function(){ 2643 if ( !done && (!this.readyState || 2644 this.readyState == "loaded" || this.readyState == "complete") ) { 2645 done = true; 2646 success(); 2647 complete(); 2648 head.removeChild( script ); 2649 } 2650 }; 2651 } 2652 2653 head.appendChild(script); 2654 2655 // We handle everything using the script element injection 2656 return undefined; 2657 } 2658 2659 var requestDone = false; 2660 2661 // Create the request object; Microsoft failed to properly 2662 // implement the XMLHttpRequest in IE7, so we use the ActiveXObject when it is available 2663 var xml = window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest(); 2664 2665 // Open the socket 2666 xml.open(s.type, s.url, s.async, s.username, s.password); 2667 2668 // Need an extra try/catch for cross domain requests in Firefox 3 2669 try { 2670 // Set the correct header, if data is being sent 2671 if ( s.data ) 2672 xml.setRequestHeader("Content-Type", s.contentType); 2673 2674 // Set the If-Modified-Since header, if ifModified mode. 2675 if ( s.ifModified ) 2676 xml.setRequestHeader("If-Modified-Since", 2677 jQuery.lastModified[s.url] || "Thu, 01 Jan 1970 00:00:00 GMT" ); 2678 2679 // Set header so the called script knows that it's an XMLHttpRequest 2680 xml.setRequestHeader("X-Requested-With", "XMLHttpRequest"); 2681 2682 // Set the Accepts header for the server, depending on the dataType 2683 xml.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ? 2684 s.accepts[ s.dataType ] + ", */*" : 2685 s.accepts._default ); 2686 } catch(e){} 2687 2688 // Allow custom headers/mimetypes 2689 if ( s.beforeSend ) 2690 s.beforeSend(xml); 2691 2692 if ( s.global ) 2693 jQuery.event.trigger("ajaxSend", [xml, s]); 2694 2695 // Wait for a response to come back 2696 var onreadystatechange = function(isTimeout){ 2697 // The transfer is complete and the data is available, or the request timed out 2698 if ( !requestDone && xml && (xml.readyState == 4 || isTimeout == "timeout") ) { 2699 requestDone = true; 2700 2701 // clear poll interval 2702 if (ival) { 2703 clearInterval(ival); 2704 ival = null; 2705 } 2706 2707 status = isTimeout == "timeout" && "timeout" || 2708 !jQuery.httpSuccess( xml ) && "error" || 2709 s.ifModified && jQuery.httpNotModified( xml, s.url ) && "notmodified" || 2710 "success"; 2711 2712 if ( status == "success" ) { 2713 // Watch for, and catch, XML document parse errors 2714 try { 2715 // process the data (runs the xml through httpData regardless of callback) 2716 data = jQuery.httpData( xml, s.dataType ); 2717 } catch(e) { 2718 status = "parsererror"; 2719 } 2720 } 2721 2722 // Make sure that the request was successful or notmodified 2723 if ( status == "success" ) { 2724 // Cache Last-Modified header, if ifModified mode. 2725 var modRes; 2726 try { 2727 modRes = xml.getResponseHeader("Last-Modified"); 2728 } catch(e) {} // swallow exception thrown by FF if header is not available 2729 2730 if ( s.ifModified && modRes ) 2731 jQuery.lastModified[s.url] = modRes; 2732 2733 // JSONP handles its own success callback 2734 if ( !jsonp ) 2735 success(); 2736 } else 2737 jQuery.handleError(s, xml, status); 2738 2739 // Fire the complete handlers 2740 complete(); 2741 2742 // Stop memory leaks 2743 if ( s.async ) 2744 xml = null; 2745 } 2746 }; 2747 2748 if ( s.async ) { 2749 // don't attach the handler to the request, just poll it instead 2750 var ival = setInterval(onreadystatechange, 13); 2751 2752 // Timeout checker 2753 if ( s.timeout > 0 ) 2754 setTimeout(function(){ 2755 // Check to see if the request is still happening 2756 if ( xml ) { 2757 // Cancel the request 2758 xml.abort(); 2759 2760 if( !requestDone ) 2761 onreadystatechange( "timeout" ); 2762 } 2763 }, s.timeout); 2764 } 2765 2766 // Send the data 2767 try { 2768 xml.send(s.data); 2769 } catch(e) { 2770 jQuery.handleError(s, xml, null, e); 2771 } 2772 2773 // firefox 1.5 doesn't fire statechange for sync requests 2774 if ( !s.async ) 2775 onreadystatechange(); 2776 2777 function success(){ 2778 // If a local callback was specified, fire it and pass it the data 2779 if ( s.success ) 2780 s.success( data, status ); 2781 2782 // Fire the global callback 2783 if ( s.global ) 2784 jQuery.event.trigger( "ajaxSuccess", [xml, s] ); 2785 } 2786 2787 function complete(){ 2788 // Process result 2789 if ( s.complete ) 2790 s.complete(xml, status); 2791 2792 // The request was completed 2793 if ( s.global ) 2794 jQuery.event.trigger( "ajaxComplete", [xml, s] ); 2795 2796 // Handle the global AJAX counter 2797 if ( s.global && ! --jQuery.active ) 2798 jQuery.event.trigger( "ajaxStop" ); 2799 } 2800 2801 // return XMLHttpRequest to allow aborting the request etc. 2802 return xml; 2803 }, 2804 2805 handleError: function( s, xml, status, e ) { 2806 // If a local callback was specified, fire it 2807 if ( s.error ) s.error( xml, status, e ); 2808 2809 // Fire the global callback 2810 if ( s.global ) 2811 jQuery.event.trigger( "ajaxError", [xml, s, e] ); 2812 }, 2813 2814 // Counter for holding the number of active queries 2815 active: 0, 2816 2817 // Determines if an XMLHttpRequest was successful or not 2818 httpSuccess: function( r ) { 2819 try { 2820 // IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450 2821 return !r.status && location.protocol == "file:" || 2822 ( r.status >= 200 && r.status < 300 ) || r.status == 304 || r.status == 1223 || 2823 jQuery.browser.safari && r.status == undefined; 2824 } catch(e){} 2825 return false; 2826 }, 2827 2828 // Determines if an XMLHttpRequest returns NotModified 2829 httpNotModified: function( xml, url ) { 2830 try { 2831 var xmlRes = xml.getResponseHeader("Last-Modified"); 2832 2833 // Firefox always returns 200. check Last-Modified date 2834 return xml.status == 304 || xmlRes == jQuery.lastModified[url] || 2835 jQuery.browser.safari && xml.status == undefined; 2836 } catch(e){} 2837 return false; 2838 }, 2839 2840 httpData: function( r, type ) { 2841 var ct = r.getResponseHeader("content-type"); 2842 var xml = type == "xml" || !type && ct && ct.indexOf("xml") >= 0; 2843 var data = xml ? r.responseXML : r.responseText; 2844 2845 if ( xml && data.documentElement.tagName == "parsererror" ) 2846 throw "parsererror"; 2847 2848 // If the type is "script", eval it in global context 2849 if ( type == "script" ) 2850 jQuery.globalEval( data ); 2851 2852 // Get the JavaScript object, if JSON is used. 2853 if ( type == "json" ) 2854 data = eval("(" + data + ")"); 2855 2856 return data; 2857 }, 2858 2859 // Serialize an array of form elements or a set of 2860 // key/values into a query string 2861 param: function( a ) { 2862 var s = []; 2863 2864 // If an array was passed in, assume that it is an array 2865 // of form elements 2866 if ( a.constructor == Array || a.jquery ) 2867 // Serialize the form elements 2868 jQuery.each( a, function(){ 2869 s.push( encodeURIComponent(this.name) + "=" + encodeURIComponent( this.value ) ); 2870 }); 2871 2872 // Otherwise, assume that it's an object of key/value pairs 2873 else 2874 // Serialize the key/values 2875 for ( var j in a ) 2876 // If the value is an array then the key names need to be repeated 2877 if ( a[j] && a[j].constructor == Array ) 2878 jQuery.each( a[j], function(){ 2879 s.push( encodeURIComponent(j) + "=" + encodeURIComponent( this ) ); 2880 }); 2881 else 2882 s.push( encodeURIComponent(j) + "=" + encodeURIComponent( a[j] ) ); 2883 2884 // Return the resulting serialization 2885 return s.join("&").replace(/%20/g, "+"); 2886 } 2887 2888 }); 2889 jQuery.fn.extend({ 2890 show: function(speed,callback){ 2891 return speed ? 2892 this.animate({ 2893 height: "show", width: "show", opacity: "show" 2894 }, speed, callback) : 2895 2896 this.filter(":hidden").each(function(){ 2897 this.style.display = this.oldblock || ""; 2898 if ( jQuery.css(this,"display") == "none" ) { 2899 var elem = jQuery("<" + this.tagName + " />").appendTo("body"); 2900 this.style.display = elem.css("display"); 2901 // handle an edge condition where css is - div { display:none; } or similar 2902 if (this.style.display == "none") 2903 this.style.display = "block"; 2904 elem.remove(); 2905 } 2906 }).end(); 2907 }, 2908 2909 hide: function(speed,callback){ 2910 return speed ? 2911 this.animate({ 2912 height: "hide", width: "hide", opacity: "hide" 2913 }, speed, callback) : 2914 2915 this.filter(":visible").each(function(){ 2916 this.oldblock = this.oldblock || jQuery.css(this,"display"); 2917 this.style.display = "none"; 2918 }).end(); 2919 }, 2920 2921 // Save the old toggle function 2922 _toggle: jQuery.fn.toggle, 2923 2924 toggle: function( fn, fn2 ){ 2925 return jQuery.isFunction(fn) && jQuery.isFunction(fn2) ? 2926 this._toggle( fn, fn2 ) : 2927 fn ? 2928 this.animate({ 2929 height: "toggle", width: "toggle", opacity: "toggle" 2930 }, fn, fn2) : 2931 this.each(function(){ 2932 jQuery(this)[ jQuery(this).is(":hidden") ? "show" : "hide" ](); 2933 }); 2934 }, 2935 2936 slideDown: function(speed,callback){ 2937 return this.animate({height: "show"}, speed, callback); 2938 }, 2939 2940 slideUp: function(speed,callback){ 2941 return this.animate({height: "hide"}, speed, callback); 2942 }, 2943 2944 slideToggle: function(speed, callback){ 2945 return this.animate({height: "toggle"}, speed, callback); 2946 }, 2947 2948 fadeIn: function(speed, callback){ 2949 return this.animate({opacity: "show"}, speed, callback); 2950 }, 2951 2952 fadeOut: function(speed, callback){ 2953 return this.animate({opacity: "hide"}, speed, callback); 2954 }, 2955 2956 fadeTo: function(speed,to,callback){ 2957 return this.animate({opacity: to}, speed, callback); 2958 }, 2959 2960 animate: function( prop, speed, easing, callback ) { 2961 var optall = jQuery.speed(speed, easing, callback); 2962 2963 return this[ optall.queue === false ? "each" : "queue" ](function(){ 2964 if ( this.nodeType != 1) 2965 return false; 2966 2967 var opt = jQuery.extend({}, optall); 2968 var hidden = jQuery(this).is(":hidden"), self = this; 2969 2970 for ( var p in prop ) { 2971 if ( prop[p] == "hide" && hidden || prop[p] == "show" && !hidden ) 2972 return jQuery.isFunction(opt.complete) && opt.complete.apply(this); 2973 2974 if ( p == "height" || p == "width" ) { 2975 // Store display property 2976 opt.display = jQuery.css(this, "display"); 2977 2978 // Make sure that nothing sneaks out 2979 opt.overflow = this.style.overflow; 2980 } 2981 } 2982 2983 if ( opt.overflow != null ) 2984 this.style.overflow = "hidden"; 2985 2986 opt.curAnim = jQuery.extend({}, prop); 2987 2988 jQuery.each( prop, function(name, val){ 2989 var e = new jQuery.fx( self, opt, name ); 2990 2991 if ( /toggle|show|hide/.test(val) ) 2992 e[ val == "toggle" ? hidden ? "show" : "hide" : val ]( prop ); 2993 else { 2994 var parts = val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/), 2995 start = e.cur(true) || 0; 2996 2997 if ( parts ) { 2998 var end = parseFloat(parts[2]), 2999 unit = parts[3] || "px"; 3000 3001 // We need to compute starting value 3002 if ( unit != "px" ) { 3003 self.style[ name ] = (end || 1) + unit; 3004 start = ((end || 1) / e.cur(true)) * start; 3005 self.style[ name ] = start + unit; 3006 } 3007 3008 // If a +=/-= token was provided, we're doing a relative animation 3009 if ( parts[1] ) 3010 end = ((parts[1] == "-=" ? -1 : 1) * end) + start; 3011 3012 e.custom( start, end, unit ); 3013 } else 3014 e.custom( start, val, "" ); 3015 } 3016 }); 3017 3018 // For JS strict compliance 3019 return true; 3020 }); 3021 }, 3022 3023 queue: function(type, fn){ 3024 if ( jQuery.isFunction(type) || ( type && type.constructor == Array )) { 3025 fn = type; 3026 type = "fx"; 3027 } 3028 3029 if ( !type || (typeof type == "string" && !fn) ) 3030 return queue( this[0], type ); 3031 3032 return this.each(function(){ 3033 if ( fn.constructor == Array ) 3034 queue(this, type, fn); 3035 else { 3036 queue(this, type).push( fn ); 3037 3038 if ( queue(this, type).length == 1 ) 3039 fn.apply(this); 3040 } 3041 }); 3042 }, 3043 3044 stop: function(clearQueue, gotoEnd){ 3045 var timers = jQuery.timers; 3046 3047 if (clearQueue) 3048 this.queue([]); 3049 3050 this.each(function(){ 3051 // go in reverse order so anything added to the queue during the loop is ignored 3052 for ( var i = timers.length - 1; i >= 0; i-- ) 3053 if ( timers[i].elem == this ) { 3054 if (gotoEnd) 3055 // force the next step to be the last 3056 timers[i](true); 3057 timers.splice(i, 1); 3058 } 3059 }); 3060 3061 // start the next in the queue if the last step wasn't forced 3062 if (!gotoEnd) 3063 this.dequeue(); 3064 3065 return this; 3066 } 3067 3068 }); 3069 3070 var queue = function( elem, type, array ) { 3071 if ( !elem ) 3072 return undefined; 3073 3074 type = type || "fx"; 3075 3076 var q = jQuery.data( elem, type + "queue" ); 3077 3078 if ( !q || array ) 3079 q = jQuery.data( elem, type + "queue", 3080 array ? jQuery.makeArray(array) : [] ); 3081 3082 return q; 3083 }; 3084 3085 jQuery.fn.dequeue = function(type){ 3086 type = type || "fx"; 3087 3088 return this.each(function(){ 3089 var q = queue(this, type); 3090 3091 q.shift(); 3092 3093 if ( q.length ) 3094 q[0].apply( this ); 3095 }); 3096 }; 3097 3098 jQuery.extend({ 3099 3100 speed: function(speed, easing, fn) { 3101 var opt = speed && speed.constructor == Object ? speed : { 3102 complete: fn || !fn && easing || 3103 jQuery.isFunction( speed ) && speed, 3104 duration: speed, 3105 easing: fn && easing || easing && easing.constructor != Function && easing 3106 }; 3107 3108 opt.duration = (opt.duration && opt.duration.constructor == Number ? 3109 opt.duration : 3110 { slow: 600, fast: 200 }[opt.duration]) || 400; 3111 3112 // Queueing 3113 opt.old = opt.complete; 3114 opt.complete = function(){ 3115 if ( opt.queue !== false ) 3116 jQuery(this).dequeue(); 3117 if ( jQuery.isFunction( opt.old ) ) 3118 opt.old.apply( this ); 3119 }; 3120 3121 return opt; 3122 }, 3123 3124 easing: { 3125 linear: function( p, n, firstNum, diff ) { 3126 return firstNum + diff * p; 3127 }, 3128 swing: function( p, n, firstNum, diff ) { 3129 return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum; 3130 } 3131 }, 3132 3133 timers: [], 3134 timerId: null, 3135 3136 fx: function( elem, options, prop ){ 3137 this.options = options; 3138 this.elem = elem; 3139 this.prop = prop; 3140 3141 if ( !options.orig ) 3142 options.orig = {}; 3143 } 3144 3145 }); 3146 3147 jQuery.fx.prototype = { 3148 3149 // Simple function for setting a style value 3150 update: function(){ 3151 if ( this.options.step ) 3152 this.options.step.apply( this.elem, [ this.now, this ] ); 3153 3154 (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this ); 3155 3156 // Set display property to block for height/width animations 3157 if ( this.prop == "height" || this.prop == "width" ) 3158 this.elem.style.display = "block"; 3159 }, 3160 3161 // Get the current size 3162 cur: function(force){ 3163 if ( this.elem[this.prop] != null && this.elem.style[this.prop] == null ) 3164 return this.elem[ this.prop ]; 3165 3166 var r = parseFloat(jQuery.css(this.elem, this.prop, force)); 3167 return r && r > -10000 ? r : parseFloat(jQuery.curCSS(this.elem, this.prop)) || 0; 3168 }, 3169 3170 // Start an animation from one number to another 3171 custom: function(from, to, unit){ 3172 this.startTime = (new Date()).getTime(); 3173 this.start = from; 3174 this.end = to; 3175 this.unit = unit || this.unit || "px"; 3176 this.now = this.start; 3177 this.pos = this.state = 0; 3178 this.update(); 3179 3180 var self = this; 3181 function t(gotoEnd){ 3182 return self.step(gotoEnd); 3183 } 3184 3185 t.elem = this.elem; 3186 3187 jQuery.timers.push(t); 3188 3189 if ( jQuery.timerId == null ) { 3190 jQuery.timerId = setInterval(function(){ 3191 var timers = jQuery.timers; 3192 3193 for ( var i = 0; i < timers.length; i++ ) 3194 if ( !timers[i]() ) 3195 timers.splice(i--, 1); 3196 3197 if ( !timers.length ) { 3198 clearInterval( jQuery.timerId ); 3199 jQuery.timerId = null; 3200 } 3201 }, 13); 3202 } 3203 }, 3204 3205 // Simple 'show' function 3206 show: function(){ 3207 // Remember where we started, so that we can go back to it later 3208 this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop ); 3209 this.options.show = true; 3210 3211 // Begin the animation 3212 this.custom(0, this.cur()); 3213 3214 // Make sure that we start at a small width/height to avoid any 3215 // flash of content 3216 if ( this.prop == "width" || this.prop == "height" ) 3217 this.elem.style[this.prop] = "1px"; 3218 3219 // Start by showing the element 3220 jQuery(this.elem).show(); 3221 }, 3222 3223 // Simple 'hide' function 3224 hide: function(){ 3225 // Remember where we started, so that we can go back to it later 3226 this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop ); 3227 this.options.hide = true; 3228 3229 // Begin the animation 3230 this.custom(this.cur(), 0); 3231 }, 3232 3233 // Each step of an animation 3234 step: function(gotoEnd){ 3235 var t = (new Date()).getTime(); 3236 3237 if ( gotoEnd || t > this.options.duration + this.startTime ) { 3238 this.now = this.end; 3239 this.pos = this.state = 1; 3240 this.update(); 3241 3242 this.options.curAnim[ this.prop ] = true; 3243 3244 var done = true; 3245 for ( var i in this.options.curAnim ) 3246 if ( this.options.curAnim[i] !== true ) 3247 done = false; 3248 3249 if ( done ) { 3250 if ( this.options.display != null ) { 3251 // Reset the overflow 3252 this.elem.style.overflow = this.options.overflow; 3253 3254 // Reset the display 3255 this.elem.style.display = this.options.display; 3256 if ( jQuery.css(this.elem, "display") == "none" ) 3257 this.elem.style.display = "block"; 3258 } 3259 3260 // Hide the element if the "hide" operation was done 3261 if ( this.options.hide ) 3262 this.elem.style.display = "none"; 3263 3264 // Reset the properties, if the item has been hidden or shown 3265 if ( this.options.hide || this.options.show ) 3266 for ( var p in this.options.curAnim ) 3267 jQuery.attr(this.elem.style, p, this.options.orig[p]); 3268 } 3269 3270 // If a callback was provided, execute it 3271 if ( done && jQuery.isFunction( this.options.complete ) ) 3272 // Execute the complete function 3273 this.options.complete.apply( this.elem ); 3274 3275 return false; 3276 } else { 3277 var n = t - this.startTime; 3278 this.state = n / this.options.duration; 3279 3280 // Perform the easing function, defaults to swing 3281 this.pos = jQuery.easing[this.options.easing || (jQuery.easing.swing ? "swing" : "linear")](this.state, n, 0, 1, this.options.duration); 3282 this.now = this.start + ((this.end - this.start) * this.pos); 3283 3284 // Perform the next step of the animation 3285 this.update(); 3286 } 3287 3288 return true; 3289 } 3290 3291 }; 3292 3293 jQuery.fx.step = { 3294 scrollLeft: function(fx){ 3295 fx.elem.scrollLeft = fx.now; 3296 }, 3297 3298 scrollTop: function(fx){ 3299 fx.elem.scrollTop = fx.now; 3300 }, 3301 3302 opacity: function(fx){ 3303 jQuery.attr(fx.elem.style, "opacity", fx.now); 3304 }, 3305 3306 _default: function(fx){ 3307 fx.elem.style[ fx.prop ] = fx.now + fx.unit; 3308 } 3309 }; 3310 // The Offset Method 3311 // Originally By Brandon Aaron, part of the Dimension Plugin 3312 // http://jquery.com/plugins/project/dimensions 3313 jQuery.fn.offset = function() { 3314 var left = 0, top = 0, elem = this[0], results; 3315 3316 if ( elem ) with ( jQuery.browser ) { 3317 var parent = elem.parentNode, 3318 offsetChild = elem, 3319 offsetParent = elem.offsetParent, 3320 doc = elem.ownerDocument, 3321 safari2 = safari && parseInt(version) < 522 && !/adobeair/i.test(userAgent), 3322 fixed = jQuery.css(elem, "position") == "fixed"; 3323 3324 // Use getBoundingClientRect if available 3325 if ( elem.getBoundingClientRect ) { 3326 var box = elem.getBoundingClientRect(); 3327 3328 // Add the document scroll offsets 3329 add(box.left + Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft), 3330 box.top + Math.max(doc.documentElement.scrollTop, doc.body.scrollTop)); 3331 3332 // IE adds the HTML element's border, by default it is medium which is 2px 3333 // IE 6 and 7 quirks mode the border width is overwritable by the following css html { border: 0; } 3334 // IE 7 standards mode, the border is always 2px 3335 // This border/offset is typically represented by the clientLeft and clientTop properties 3336 // However, in IE6 and 7 quirks mode the clientLeft and clientTop properties are not updated when overwriting it via CSS 3337 // Therefore this method will be off by 2px in IE while in quirksmode 3338 add( -doc.documentElement.clientLeft, -doc.documentElement.clientTop ); 3339 3340 // Otherwise loop through the offsetParents and parentNodes 3341 } else { 3342 3343 // Initial element offsets 3344 add( elem.offsetLeft, elem.offsetTop ); 3345 3346 // Get parent offsets 3347 while ( offsetParent ) { 3348 // Add offsetParent offsets 3349 add( offsetParent.offsetLeft, offsetParent.offsetTop ); 3350 3351 // Mozilla and Safari > 2 does not include the border on offset parents 3352 // However Mozilla adds the border for table or table cells 3353 if ( mozilla && !/^t(able|d|h)$/i.test(offsetParent.tagName) || safari && !safari2 ) 3354 border( offsetParent ); 3355 3356 // Add the document scroll offsets if position is fixed on any offsetParent 3357 if ( !fixed && jQuery.css(offsetParent, "position") == "fixed" ) 3358 fixed = true; 3359 3360 // Set offsetChild to previous offsetParent unless it is the body element 3361 offsetChild = /^body$/i.test(offsetParent.tagName) ? offsetChild : offsetParent; 3362 // Get next offsetParent 3363 offsetParent = offsetParent.offsetParent; 3364 } 3365 3366 // Get parent scroll offsets 3367 while ( parent && parent.tagName && !/^body|html$/i.test(parent.tagName) ) { 3368 // Remove parent scroll UNLESS that parent is inline or a table to work around Opera inline/table scrollLeft/Top bug 3369 if ( !/^inline|table.*$/i.test(jQuery.css(parent, "display")) ) 3370 // Subtract parent scroll offsets 3371 add( -parent.scrollLeft, -parent.scrollTop ); 3372 3373 // Mozilla does not add the border for a parent that has overflow != visible 3374 if ( mozilla && jQuery.css(parent, "overflow") != "visible" ) 3375 border( parent ); 3376 3377 // Get next parent 3378 parent = parent.parentNode; 3379 } 3380 3381 // Safari <= 2 doubles body offsets with a fixed position element/offsetParent or absolutely positioned offsetChild 3382 // Mozilla doubles body offsets with a non-absolutely positioned offsetChild 3383 if ( (safari2 && (fixed || jQuery.css(offsetChild, "position") == "absolute")) || 3384 (mozilla && jQuery.css(offsetChild, "position") != "absolute") ) 3385 add( -doc.body.offsetLeft, -doc.body.offsetTop ); 3386 3387 // Add the document scroll offsets if position is fixed 3388 if ( fixed ) 3389 add(Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft), 3390 Math.max(doc.documentElement.scrollTop, doc.body.scrollTop)); 3391 } 3392 3393 // Return an object with top and left properties 3394 results = { top: top, left: left }; 3395 } 3396 3397 function border(elem) { 3398 add( jQuery.curCSS(elem, "borderLeftWidth", true), jQuery.curCSS(elem, "borderTopWidth", true) ); 3399 } 3400 3401 function add(l, t) { 3402 left += parseInt(l) || 0; 3403 top += parseInt(t) || 0; 3404 } 3405 3406 return results; 3407 }; 3408 })();