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