comparison static/jquery-1.6.2.js @ 0:2d9ee2b3ae82

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