WordPress source code - jquery (jquery-1.6.1.js)

1 /*!
2 * jQuery JavaScript Library v1.6.1
3 * http://jquery.com/
4 *
5 * Copyright 2011, John Resig
6 * Dual licensed under the MIT or GPL Version 2 licenses.
7 * http://jquery.org/license
8 *
9 * Includes Sizzle.js
10 * http://sizzlejs.com/
11 * Copyright 2011, The Dojo Foundation
12 * Released under the MIT, BSD, and GPL Licenses.
13 *
14 * Date: Thu May 12 15:04:36 2011 -0400
15 */
16 (function( window, undefined ) {
17
18 // Use the correct document accordingly with window argument (sandbox)
19 var document = window.document,
20 navigator = window.navigator,
21 location = window.location;
22 var jQuery = (function() {
23
24 // Define a local copy of jQuery
25 var jQuery = function( selector, context ) {
26 // The jQuery object is actually just the init constructor 'enhanced'
27 return new jQuery.fn.init( selector, context, rootjQuery );
28 },
29
30 // Map over jQuery in case of overwrite
31 _jQuery = window.jQuery,
32
33 // Map over the $ in case of overwrite
34 _$ = window.$,
35
36 // A central reference to the root jQuery(document)
37 rootjQuery,
38
39 // A simple way to check for HTML strings or ID strings
40 // (both of which we optimize for)
41 quickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,
42
43 // Check if a string has a non-whitespace character in it
44 rnotwhite = /\S/,
45
46 // Used for trimming whitespace
47 trimLeft = /^\s+/,
48 trimRight = /\s+$/,
49
50 // Check for digits
51 rdigit = /\d/,
52
53 // Match a standalone tag
54 rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/,
55
56 // JSON RegExp
57 rvalidchars = /^[\],:{}\s]*$/,
58 rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,
59 rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
60 rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g,
61
62 // Useragent RegExp
63 rwebkit = /(webkit)[ \/]([\w.]+)/,
64 ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/,
65 rmsie = /(msie) ([\w.]+)/,
66 rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/,
67
68 // Keep a UserAgent string for use with jQuery.browser
69 userAgent = navigator.userAgent,
70
71 // For matching the engine and version of the browser
72 browserMatch,
73
74 // The deferred used on DOM ready
75 readyList,
76
77 // The ready event handler
78 DOMContentLoaded,
79
80 // Save a reference to some core methods
81 toString = Object.prototype.toString,
82 hasOwn = Object.prototype.hasOwnProperty,
83 push = Array.prototype.push,
84 slice = Array.prototype.slice,
85 trim = String.prototype.trim,
86 indexOf = Array.prototype.indexOf,
87
88 // [[Class]] -> type pairs
89 class2type = {};
90
91 jQuery.fn = jQuery.prototype = {
92 constructor: jQuery,
93 init: function( selector, context, rootjQuery ) {
94 var match, elem, ret, doc;
95
96 // Handle $(""), $(null), or $(undefined)
97 if ( !selector ) {
98 return this;
99 }
100
101 // Handle $(DOMElement)
102 if ( selector.nodeType ) {
103 this.context = this[0] = selector;
104 this.length = 1;
105 return this;
106 }
107
108 // The body element only exists once, optimize finding it
109 if ( selector === "body" && !context && document.body ) {
110 this.context = document;
111 this[0] = document.body;
112 this.selector = selector;
113 this.length = 1;
114 return this;
115 }
116
117 // Handle HTML strings
118 if ( typeof selector === "string" ) {
119 // Are we dealing with HTML string or an ID?
120 if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
121 // Assume that strings that start and end with <> are HTML and skip the regex check
122 match = [ null, selector, null ];
123
124 } else {
125 match = quickExpr.exec( selector );
126 }
127
128 // Verify a match, and that no context was specified for #id
129 if ( match && (match[1] || !context) ) {
130
131 // HANDLE: $(html) -> $(array)
132 if ( match[1] ) {
133 context = context instanceof jQuery ? context[0] : context;
134 doc = (context ? context.ownerDocument || context : document);
135
136 // If a single string is passed in and it's a single tag
137 // just do a createElement and skip the rest
138 ret = rsingleTag.exec( selector );
139
140 if ( ret ) {
141 if ( jQuery.isPlainObject( context ) ) {
142 selector = [ document.createElement( ret[1] ) ];
143 jQuery.fn.attr.call( selector, context, true );
144
145 } else {
146 selector = [ doc.createElement( ret[1] ) ];
147 }
148
149 } else {
150 ret = jQuery.buildFragment( [ match[1] ], [ doc ] );
151 selector = (ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment).childNodes;
152 }
153
154 return jQuery.merge( this, selector );
155
156 // HANDLE: $("#id")
157 } else {
158 elem = document.getElementById( match[2] );
159
160 // Check parentNode to catch when Blackberry 4.6 returns
161 // nodes that are no longer in the document #6963
162 if ( elem && elem.parentNode ) {
163 // Handle the case where IE and Opera return items
164 // by name instead of ID
165 if ( elem.id !== match[2] ) {
166 return rootjQuery.find( selector );
167 }
168
169 // Otherwise, we inject the element directly into the jQuery object
170 this.length = 1;
171 this[0] = elem;
172 }
173
174 this.context = document;
175 this.selector = selector;
176 return this;
177 }
178
179 // HANDLE: $(expr, $(...))
180 } else if ( !context || context.jquery ) {
181 return (context || rootjQuery).find( selector );
182
183 // HANDLE: $(expr, context)
184 // (which is just equivalent to: $(context).find(expr)
185 } else {
186 return this.constructor( context ).find( selector );
187 }
188
189 // HANDLE: $(function)
190 // Shortcut for document ready
191 } else if ( jQuery.isFunction( selector ) ) {
192 return rootjQuery.ready( selector );
193 }
194
195 if (selector.selector !== undefined) {
196 this.selector = selector.selector;
197 this.context = selector.context;
198 }
199
200 return jQuery.makeArray( selector, this );
201 },
202
203 // Start with an empty selector
204 selector: "",
205
206 // The current version of jQuery being used
207 jquery: "1.6.1",
208
209 // The default length of a jQuery object is 0
210 length: 0,
211
212 // The number of elements contained in the matched element set
213 size: function() {
214 return this.length;
215 },
216
217 toArray: function() {
218 return slice.call( this, 0 );
219 },
220
221 // Get the Nth element in the matched element set OR
222 // Get the whole matched element set as a clean array
223 get: function( num ) {
224 return num == null ?
225
226 // Return a 'clean' array
227 this.toArray() :
228
229 // Return just the object
230 ( num < 0 ? this[ this.length + num ] : this[ num ] );
231 },
232
233 // Take an array of elements and push it onto the stack
234 // (returning the new matched element set)
235 pushStack: function( elems, name, selector ) {
236 // Build a new jQuery matched element set
237 var ret = this.constructor();
238
239 if ( jQuery.isArray( elems ) ) {
240 push.apply( ret, elems );
241
242 } else {
243 jQuery.merge( ret, elems );
244 }
245
246 // Add the old object onto the stack (as a reference)
247 ret.prevObject = this;
248
249 ret.context = this.context;
250
251 if ( name === "find" ) {
252 ret.selector = this.selector + (this.selector ? " " : "") + selector;
253 } else if ( name ) {
254 ret.selector = this.selector + "." + name + "(" + selector + ")";
255 }
256
257 // Return the newly-formed element set
258 return ret;
259 },
260
261 // Execute a callback for every element in the matched set.
262 // (You can seed the arguments with an array of args, but this is
263 // only used internally.)
264 each: function( callback, args ) {
265 return jQuery.each( this, callback, args );
266 },
267
268 ready: function( fn ) {
269 // Attach the listeners
270 jQuery.bindReady();
271
272 // Add the callback
273 readyList.done( fn );
274
275 return this;
276 },
277
278 eq: function( i ) {
279 return i === -1 ?
280 this.slice( i ) :
281 this.slice( i, +i + 1 );
282 },
283
284 first: function() {
285 return this.eq( 0 );
286 },
287
288 last: function() {
289 return this.eq( -1 );
290 },
291
292 slice: function() {
293 return this.pushStack( slice.apply( this, arguments ),
294 "slice", slice.call(arguments).join(",") );
295 },
296
297 map: function( callback ) {
298 return this.pushStack( jQuery.map(this, function( elem, i ) {
299 return callback.call( elem, i, elem );
300 }));
301 },
302
303 end: function() {
304 return this.prevObject || this.constructor(null);
305 },
306
307 // For internal use only.
308 // Behaves like an Array's method, not like a jQuery method.
309 push: push,
310 sort: [].sort,
311 splice: [].splice
312 };
313
314 // Give the init function the jQuery prototype for later instantiation
315 jQuery.fn.init.prototype = jQuery.fn;
316
317 jQuery.extend = jQuery.fn.extend = function() {
318 var options, name, src, copy, copyIsArray, clone,
319 target = arguments[0] || {},
320 i = 1,
321 length = arguments.length,
322 deep = false;
323
324 // Handle a deep copy situation
325 if ( typeof target === "boolean" ) {
326 deep = target;
327 target = arguments[1] || {};
328 // skip the boolean and the target
329 i = 2;
330 }
331
332 // Handle case when target is a string or something (possible in deep copy)
333 if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
334 target = {};
335 }
336
337 // extend jQuery itself if only one argument is passed
338 if ( length === i ) {
339 target = this;
340 --i;
341 }
342
343 for ( ; i < length; i++ ) {
344 // Only deal with non-null/undefined values
345 if ( (options = arguments[ i ]) != null ) {
346 // Extend the base object
347 for ( name in options ) {
348 src = target[ name ];
349 copy = options[ name ];
350
351 // Prevent never-ending loop
352 if ( target === copy ) {
353 continue;
354 }
355
356 // Recurse if we're merging plain objects or arrays
357 if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
358 if ( copyIsArray ) {
359 copyIsArray = false;
360 clone = src && jQuery.isArray(src) ? src : [];
361
362 } else {
363 clone = src && jQuery.isPlainObject(src) ? src : {};
364 }
365
366 // Never move original objects, clone them
367 target[ name ] = jQuery.extend( deep, clone, copy );
368
369 // Don't bring in undefined values
370 } else if ( copy !== undefined ) {
371 target[ name ] = copy;
372 }
373 }
374 }
375 }
376
377 // Return the modified object
378 return target;
379 };
380
381 jQuery.extend({
382 noConflict: function( deep ) {
383 if ( window.$ === jQuery ) {
384 window.$ = _$;
385 }
386
387 if ( deep && window.jQuery === jQuery ) {
388 window.jQuery = _jQuery;
389 }
390
391 return jQuery;
392 },
393
394 // Is the DOM ready to be used? Set to true once it occurs.
395 isReady: false,
396
397 // A counter to track how many items to wait for before
398 // the ready event fires. See #6781
399 readyWait: 1,
400
401 // Hold (or release) the ready event
402 holdReady: function( hold ) {
403 if ( hold ) {
404 jQuery.readyWait++;
405 } else {
406 jQuery.ready( true );
407 }
408 },
409
410 // Handle when the DOM is ready
411 ready: function( wait ) {
412 // Either a released hold or an DOMready/load event and not yet ready
413 if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) {
414 // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
415 if ( !document.body ) {
416 return setTimeout( jQuery.ready, 1 );
417 }
418
419 // Remember that the DOM is ready
420 jQuery.isReady = true;
421
422 // If a normal DOM Ready event fired, decrement, and wait if need be
423 if ( wait !== true && --jQuery.readyWait > 0 ) {
424 return;
425 }
426
427 // If there are functions bound, to execute
428 readyList.resolveWith( document, [ jQuery ] );
429
430 // Trigger any bound ready events
431 if ( jQuery.fn.trigger ) {
432 jQuery( document ).trigger( "ready" ).unbind( "ready" );
433 }
434 }
435 },
436
437 bindReady: function() {
438 if ( readyList ) {
439 return;
440 }
441
442 readyList = jQuery._Deferred();
443
444 // Catch cases where $(document).ready() is called after the
445 // browser event has already occurred.
446 if ( document.readyState === "complete" ) {
447 // Handle it asynchronously to allow scripts the opportunity to delay ready
448 return setTimeout( jQuery.ready, 1 );
449 }
450
451 // Mozilla, Opera and webkit nightlies currently support this event
452 if ( document.addEventListener ) {
453 // Use the handy event callback
454 document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
455
456 // A fallback to window.onload, that will always work
457 window.addEventListener( "load", jQuery.ready, false );
458
459 // If IE event model is used
460 } else if ( document.attachEvent ) {
461 // ensure firing before onload,
462 // maybe late but safe also for iframes
463 document.attachEvent( "onreadystatechange", DOMContentLoaded );
464
465 // A fallback to window.onload, that will always work
466 window.attachEvent( "onload", jQuery.ready );
467
468 // If IE and not a frame
469 // continually check to see if the document is ready
470 var toplevel = false;
471
472 try {
473 toplevel = window.frameElement == null;
474 } catch(e) {}
475
476 if ( document.documentElement.doScroll && toplevel ) {
477 doScrollCheck();
478 }
479 }
480 },
481
482 // See test/unit/core.js for details concerning isFunction.
483 // Since version 1.3, DOM methods and functions like alert
484 // aren't supported. They return false on IE (#2968).
485 isFunction: function( obj ) {
486 return jQuery.type(obj) === "function";
487 },
488
489 isArray: Array.isArray || function( obj ) {
490 return jQuery.type(obj) === "array";
491 },
492
493 // A crude way of determining if an object is a window
494 isWindow: function( obj ) {
495 return obj && typeof obj === "object" && "setInterval" in obj;
496 },
497
498 isNaN: function( obj ) {
499 return obj == null || !rdigit.test( obj ) || isNaN( obj );
500 },
501
502 type: function( obj ) {
503 return obj == null ?
504 String( obj ) :
505 class2type[ toString.call(obj) ] || "object";
506 },
507
508 isPlainObject: function( obj ) {
509 // Must be an Object.
510 // Because of IE, we also have to check the presence of the constructor property.
511 // Make sure that DOM nodes and window objects don't pass through, as well
512 if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
513 return false;
514 }
515
516 // Not own constructor property must be Object
517 if ( obj.constructor &&
518 !hasOwn.call(obj, "constructor") &&
519 !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
520 return false;
521 }
522
523 // Own properties are enumerated firstly, so to speed up,
524 // if last one is own, then all properties are own.
525
526 var key;
527 for ( key in obj ) {}
528
529 return key === undefined || hasOwn.call( obj, key );
530 },
531
532 isEmptyObject: function( obj ) {
533 for ( var name in obj ) {
534 return false;
535 }
536 return true;
537 },
538
539 error: function( msg ) {
540 throw msg;
541 },
542
543 parseJSON: function( data ) {
544 if ( typeof data !== "string" || !data ) {
545 return null;
546 }
547
548 // Make sure leading/trailing whitespace is removed (IE can't handle it)
549 data = jQuery.trim( data );
550
551 // Attempt to parse using the native JSON parser first
552 if ( window.JSON && window.JSON.parse ) {
553 return window.JSON.parse( data );
554 }
555
556 // Make sure the incoming data is actual JSON
557 // Logic borrowed from http://json.org/json2.js
558 if ( rvalidchars.test( data.replace( rvalidescape, "@" )
559 .replace( rvalidtokens, "]" )
560 .replace( rvalidbraces, "")) ) {
561
562 return (new Function( "return " + data ))();
563
564 }
565 jQuery.error( "Invalid JSON: " + data );
566 },
567
568 // Cross-browser xml parsing
569 // (xml & tmp used internally)
570 parseXML: function( data , xml , tmp ) {
571
572 if ( window.DOMParser ) { // Standard
573 tmp = new DOMParser();
574 xml = tmp.parseFromString( data , "text/xml" );
575 } else { // IE
576 xml = new ActiveXObject( "Microsoft.XMLDOM" );
577 xml.async = "false";
578 xml.loadXML( data );
579 }
580
581 tmp = xml.documentElement;
582
583 if ( ! tmp || ! tmp.nodeName || tmp.nodeName === "parsererror" ) {
584 jQuery.error( "Invalid XML: " + data );
585 }
586
587 return xml;
588 },
589
590 noop: function() {},
591
592 // Evaluates a script in a global context
593 // Workarounds based on findings by Jim Driscoll
594 // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
595 globalEval: function( data ) {
596 if ( data && rnotwhite.test( data ) ) {
597 // We use execScript on Internet Explorer
598 // We use an anonymous function so that context is window
599 // rather than jQuery in Firefox
600 ( window.execScript || function( data ) {
601 window[ "eval" ].call( window, data );
602 } )( data );
603 }
604 },
605
606 nodeName: function( elem, name ) {
607 return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
608 },
609
610 // args is for internal usage only
611 each: function( object, callback, args ) {
612 var name, i = 0,
613 length = object.length,
614 isObj = length === undefined || jQuery.isFunction( object );
615
616 if ( args ) {
617 if ( isObj ) {
618 for ( name in object ) {
619 if ( callback.apply( object[ name ], args ) === false ) {
620 break;
621 }
622 }
623 } else {
624 for ( ; i < length; ) {
625 if ( callback.apply( object[ i++ ], args ) === false ) {
626 break;
627 }
628 }
629 }
630
631 // A special, fast, case for the most common use of each
632 } else {
633 if ( isObj ) {
634 for ( name in object ) {
635 if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
636 break;
637 }
638 }
639 } else {
640 for ( ; i < length; ) {
641 if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) {
642 break;
643 }
644 }
645 }
646 }
647
648 return object;
649 },
650
651 // Use native String.trim function wherever possible
652 trim: trim ?
653 function( text ) {
654 return text == null ?
655 "" :
656 trim.call( text );
657 } :
658
659 // Otherwise use our own trimming functionality
660 function( text ) {
661 return text == null ?
662 "" :
663 text.toString().replace( trimLeft, "" ).replace( trimRight, "" );
664 },
665
666 // results is for internal usage only
667 makeArray: function( array, results ) {
668 var ret = results || [];
669
670 if ( array != null ) {
671 // The window, strings (and functions) also have 'length'
672 // The extra typeof function check is to prevent crashes
673 // in Safari 2 (See: #3039)
674 // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930
675 var type = jQuery.type( array );
676
677 if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) {
678 push.call( ret, array );
679 } else {
680 jQuery.merge( ret, array );
681 }
682 }
683
684 return ret;
685 },
686
687 inArray: function( elem, array ) {
688
689 if ( indexOf ) {
690 return indexOf.call( array, elem );
691 }
692
693 for ( var i = 0, length = array.length; i < length; i++ ) {
694 if ( array[ i ] === elem ) {
695 return i;
696 }
697 }
698
699 return -1;
700 },
701
702 merge: function( first, second ) {
703 var i = first.length,
704 j = 0;
705
706 if ( typeof second.length === "number" ) {
707 for ( var l = second.length; j < l; j++ ) {
708 first[ i++ ] = second[ j ];
709 }
710
711 } else {
712 while ( second[j] !== undefined ) {
713 first[ i++ ] = second[ j++ ];
714 }
715 }
716
717 first.length = i;
718
719 return first;
720 },
721
722 grep: function( elems, callback, inv ) {
723 var ret = [], retVal;
724 inv = !!inv;
725
726 // Go through the array, only saving the items
727 // that pass the validator function
728 for ( var i = 0, length = elems.length; i < length; i++ ) {
729 retVal = !!callback( elems[ i ], i );
730 if ( inv !== retVal ) {
731 ret.push( elems[ i ] );
732 }
733 }
734
735 return ret;
736 },
737
738 // arg is for internal usage only
739 map: function( elems, callback, arg ) {
740 var value, key, ret = [],
741 i = 0,
742 length = elems.length,
743 // jquery objects are treated as arrays
744 isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ;
745
746 // Go through the array, translating each of the items to their
747 if ( isArray ) {
748 for ( ; i < length; i++ ) {
749 value = callback( elems[ i ], i, arg );
750
751 if ( value != null ) {
752 ret[ ret.length ] = value;
753 }
754 }
755
756 // Go through every key on the object,
757 } else {
758 for ( key in elems ) {
759 value = callback( elems[ key ], key, arg );
760
761 if ( value != null ) {
762 ret[ ret.length ] = value;
763 }
764 }
765 }
766
767 // Flatten any nested arrays
768 return ret.concat.apply( [], ret );
769 },
770
771 // A global GUID counter for objects
772 guid: 1,
773
774 // Bind a function to a context, optionally partially applying any
775 // arguments.
776 proxy: function( fn, context ) {
777 if ( typeof context === "string" ) {
778 var tmp = fn[ context ];
779 context = fn;
780 fn = tmp;
781 }
782
783 // Quick check to determine if target is callable, in the spec
784 // this throws a TypeError, but we will just return undefined.
785 if ( !jQuery.isFunction( fn ) ) {
786 return undefined;
787 }
788
789 // Simulated bind
790 var args = slice.call( arguments, 2 ),
791 proxy = function() {
792 return fn.apply( context, args.concat( slice.call( arguments ) ) );
793 };
794
795 // Set the guid of unique handler to the same of original handler, so it can be removed
796 proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
797
798 return proxy;
799 },
800
801 // Mutifunctional method to get and set values to a collection
802 // The value/s can be optionally by executed if its a function
803 access: function( elems, key, value, exec, fn, pass ) {
804 var length = elems.length;
805
806 // Setting many attributes
807 if ( typeof key === "object" ) {
808 for ( var k in key ) {
809 jQuery.access( elems, k, key[k], exec, fn, value );
810 }
811 return elems;
812 }
813
814 // Setting one attribute
815 if ( value !== undefined ) {
816 // Optionally, function values get executed if exec is true
817 exec = !pass && exec && jQuery.isFunction(value);
818
819 for ( var i = 0; i < length; i++ ) {
820 fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
821 }
822
823 return elems;
824 }
825
826 // Getting an attribute
827 return length ? fn( elems[0], key ) : undefined;
828 },
829
830 now: function() {
831 return (new Date()).getTime();
832 },
833
834 // Use of jQuery.browser is frowned upon.
835 // More details: http://docs.jquery.com/Utilities/jQuery.browser
836 uaMatch: function( ua ) {
837 ua = ua.toLowerCase();
838
839 var match = rwebkit.exec( ua ) ||
840 ropera.exec( ua ) ||
841 rmsie.exec( ua ) ||
842 ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) ||
843 [];
844
845 return { browser: match[1] || "", version: match[2] || "0" };
846 },
847
848 sub: function() {
849 function jQuerySub( selector, context ) {
850 return new jQuerySub.fn.init( selector, context );
851 }
852 jQuery.extend( true, jQuerySub, this );
853 jQuerySub.superclass = this;
854 jQuerySub.fn = jQuerySub.prototype = this();
855 jQuerySub.fn.constructor = jQuerySub;
856 jQuerySub.sub = this.sub;
857 jQuerySub.fn.init = function init( selector, context ) {
858 if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) {
859 context = jQuerySub( context );
860 }
861
862 return jQuery.fn.init.call( this, selector, context, rootjQuerySub );
863 };
864 jQuerySub.fn.init.prototype = jQuerySub.fn;
865 var rootjQuerySub = jQuerySub(document);
866 return jQuerySub;
867 },
868
869 browser: {}
870 });
871
872 // Populate the class2type map
873 jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) {
874 class2type[ "[object " + name + "]" ] = name.toLowerCase();
875 });
876
877 browserMatch = jQuery.uaMatch( userAgent );
878 if ( browserMatch.browser ) {
879 jQuery.browser[ browserMatch.browser ] = true;
880 jQuery.browser.version = browserMatch.version;
881 }
882
883 // Deprecated, use jQuery.browser.webkit instead
884 if ( jQuery.browser.webkit ) {
885 jQuery.browser.safari = true;
886 }
887
888 // IE doesn't match non-breaking spaces with \s
889 if ( rnotwhite.test( "\xA0" ) ) {
890 trimLeft = /^[\s\xA0]+/;
891 trimRight = /[\s\xA0]+$/;
892 }
893
894 // All jQuery objects should point back to these
895 rootjQuery = jQuery(document);
896
897 // Cleanup functions for the document ready method
898 if ( document.addEventListener ) {
899 DOMContentLoaded = function() {
900 document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
901 jQuery.ready();
902 };
903
904 } else if ( document.attachEvent ) {
905 DOMContentLoaded = function() {
906 // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
907 if ( document.readyState === "complete" ) {
908 document.detachEvent( "onreadystatechange", DOMContentLoaded );
909 jQuery.ready();
910 }
911 };
912 }
913
914 // The DOM ready check for Internet Explorer
915 function doScrollCheck() {
916 if ( jQuery.isReady ) {
917 return;
918 }
919
920 try {
921 // If IE is used, use the trick by Diego Perini
922 // http://javascript.nwbox.com/IEContentLoaded/
923 document.documentElement.doScroll("left");
924 } catch(e) {
925 setTimeout( doScrollCheck, 1 );
926 return;
927 }
928
929 // and execute any waiting functions
930 jQuery.ready();
931 }
932
933 // Expose jQuery to the global object
934 return jQuery;
935
936 })();
937
938
939 var // Promise methods
940 promiseMethods = "done fail isResolved isRejected promise then always pipe".split( " " ),
941 // Static reference to slice
942 sliceDeferred = [].slice;
943
944 jQuery.extend({
945 // Create a simple deferred (one callbacks list)
946 _Deferred: function() {
947 var // callbacks list
948 callbacks = [],
949 // stored [ context , args ]
950 fired,
951 // to avoid firing when already doing so
952 firing,
953 // flag to know if the deferred has been cancelled
954 cancelled,
955 // the deferred itself
956 deferred = {
957
958 // done( f1, f2, ...)
959 done: function() {
960 if ( !cancelled ) {
961 var args = arguments,
962 i,
963 length,
964 elem,
965 type,
966 _fired;
967 if ( fired ) {
968 _fired = fired;
969 fired = 0;
970 }
971 for ( i = 0, length = args.length; i < length; i++ ) {
972 elem = args[ i ];
973 type = jQuery.type( elem );
974 if ( type === "array" ) {
975 deferred.done.apply( deferred, elem );
976 } else if ( type === "function" ) {
977 callbacks.push( elem );
978 }
979 }
980 if ( _fired ) {
981 deferred.resolveWith( _fired[ 0 ], _fired[ 1 ] );
982 }
983 }
984 return this;
985 },
986
987 // resolve with given context and args
988 resolveWith: function( context, args ) {
989 if ( !cancelled && !fired && !firing ) {
990 // make sure args are available (#8421)
991 args = args || [];
992 firing = 1;
993 try {
994 while( callbacks[ 0 ] ) {
995 callbacks.shift().apply( context, args );
996 }
997 }
998 finally {
999 fired = [ context, args ];
1000 firing = 0;
1001 }
1002 }
1003 return this;
1004 },
1005
1006 // resolve with this as context and given arguments
1007 resolve: function() {
1008 deferred.resolveWith( this, arguments );
1009 return this;
1010 },
1011
1012 // Has this deferred been resolved?
1013 isResolved: function() {
1014 return !!( firing || fired );
1015 },
1016
1017 // Cancel
1018 cancel: function() {
1019 cancelled = 1;
1020 callbacks = [];
1021 return this;
1022 }
1023 };
1024
1025 return deferred;
1026 },
1027
1028 // Full fledged deferred (two callbacks list)
1029 Deferred: function( func ) {
1030 var deferred = jQuery._Deferred(),
1031 failDeferred = jQuery._Deferred(),
1032 promise;
1033 // Add errorDeferred methods, then and promise
1034 jQuery.extend( deferred, {
1035 then: function( doneCallbacks, failCallbacks ) {
1036 deferred.done( doneCallbacks ).fail( failCallbacks );
1037 return this;
1038 },
1039 always: function() {
1040 return deferred.done.apply( deferred, arguments ).fail.apply( this, arguments );
1041 },
1042 fail: failDeferred.done,
1043 rejectWith: failDeferred.resolveWith,
1044 reject: failDeferred.resolve,
1045 isRejected: failDeferred.isResolved,
1046 pipe: function( fnDone, fnFail ) {
1047 return jQuery.Deferred(function( newDefer ) {
1048 jQuery.each( {
1049 done: [ fnDone, "resolve" ],
1050 fail: [ fnFail, "reject" ]
1051 }, function( handler, data ) {
1052 var fn = data[ 0 ],
1053 action = data[ 1 ],
1054 returned;
1055 if ( jQuery.isFunction( fn ) ) {
1056 deferred[ handler ](function() {
1057 returned = fn.apply( this, arguments );
1058 if ( returned && jQuery.isFunction( returned.promise ) ) {
1059 returned.promise().then( newDefer.resolve, newDefer.reject );
1060 } else {
1061 newDefer[ action ]( returned );
1062 }
1063 });
1064 } else {
1065 deferred[ handler ]( newDefer[ action ] );
1066 }
1067 });
1068 }).promise();
1069 },
1070 // Get a promise for this deferred
1071 // If obj is provided, the promise aspect is added to the object
1072 promise: function( obj ) {
1073 if ( obj == null ) {
1074 if ( promise ) {
1075 return promise;
1076 }
1077 promise = obj = {};
1078 }
1079 var i = promiseMethods.length;
1080 while( i-- ) {
1081 obj[ promiseMethods[i] ] = deferred[ promiseMethods[i] ];
1082 }
1083 return obj;
1084 }
1085 });
1086 // Make sure only one callback list will be used
1087 deferred.done( failDeferred.cancel ).fail( deferred.cancel );
1088 // Unexpose cancel
1089 delete deferred.cancel;
1090 // Call given func if any
1091 if ( func ) {
1092 func.call( deferred, deferred );
1093 }
1094 return deferred;
1095 },
1096
1097 // Deferred helper
1098 when: function( firstParam ) {
1099 var args = arguments,
1100 i = 0,
1101 length = args.length,
1102 count = length,
1103 deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ?
1104 firstParam :
1105 jQuery.Deferred();
1106 function resolveFunc( i ) {
1107 return function( value ) {
1108 args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value;
1109 if ( !( --count ) ) {
1110 // Strange bug in FF4:
1111 // Values changed onto the arguments object sometimes end up as undefined values
1112 // outside the $.when method. Cloning the object into a fresh array solves the issue
1113 deferred.resolveWith( deferred, sliceDeferred.call( args, 0 ) );
1114 }
1115 };
1116 }
1117 if ( length > 1 ) {
1118 for( ; i < length; i++ ) {
1119 if ( args[ i ] && jQuery.isFunction( args[ i ].promise ) ) {
1120 args[ i ].promise().then( resolveFunc(i), deferred.reject );
1121 } else {
1122 --count;
1123 }
1124 }
1125 if ( !count ) {
1126 deferred.resolveWith( deferred, args );
1127 }
1128 } else if ( deferred !== firstParam ) {
1129 deferred.resolveWith( deferred, length ? [ firstParam ] : [] );
1130 }
1131 return deferred.promise();
1132 }
1133 });
1134
1135
1136
1137 jQuery.support = (function() {
1138
1139 var div = document.createElement( "div" ),
1140 documentElement = document.documentElement,
1141 all,
1142 a,
1143 select,
1144 opt,
1145 input,
1146 marginDiv,
1147 support,
1148 fragment,
1149 body,
1150 bodyStyle,
1151 tds,
1152 events,
1153 eventName,
1154 i,
1155 isSupported;
1156
1157 // Preliminary tests
1158 div.setAttribute("className", "t");
1159 div.innerHTML = " <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
1160
1161 all = div.getElementsByTagName( "*" );
1162 a = div.getElementsByTagName( "a" )[ 0 ];
1163
1164 // Can't get basic test support
1165 if ( !all || !all.length || !a ) {
1166 return {};
1167 }
1168
1169 // First batch of supports tests
1170 select = document.createElement( "select" );
1171 opt = select.appendChild( document.createElement("option") );
1172 input = div.getElementsByTagName( "input" )[ 0 ];
1173
1174 support = {
1175 // IE strips leading whitespace when .innerHTML is used
1176 leadingWhitespace: ( div.firstChild.nodeType === 3 ),
1177
1178 // Make sure that tbody elements aren't automatically inserted
1179 // IE will insert them into empty tables
1180 tbody: !div.getElementsByTagName( "tbody" ).length,
1181
1182 // Make sure that link elements get serialized correctly by innerHTML
1183 // This requires a wrapper element in IE
1184 htmlSerialize: !!div.getElementsByTagName( "link" ).length,
1185
1186 // Get the style information from getAttribute
1187 // (IE uses .cssText instead)
1188 style: /top/.test( a.getAttribute("style") ),
1189
1190 // Make sure that URLs aren't manipulated
1191 // (IE normalizes it by default)
1192 hrefNormalized: ( a.getAttribute( "href" ) === "/a" ),
1193
1194 // Make sure that element opacity exists
1195 // (IE uses filter instead)
1196 // Use a regex to work around a WebKit issue. See #5145
1197 opacity: /^0.55$/.test( a.style.opacity ),
1198
1199 // Verify style float existence
1200 // (IE uses styleFloat instead of cssFloat)
1201 cssFloat: !!a.style.cssFloat,
1202
1203 // Make sure that if no value is specified for a checkbox
1204 // that it defaults to "on".
1205 // (WebKit defaults to "" instead)
1206 checkOn: ( input.value === "on" ),
1207
1208 // Make sure that a selected-by-default option has a working selected property.
1209 // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
1210 optSelected: opt.selected,
1211
1212 // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)
1213 getSetAttribute: div.className !== "t",
1214
1215 // Will be defined later
1216 submitBubbles: true,
1217 changeBubbles: true,
1218 focusinBubbles: false,
1219 deleteExpando: true,
1220 noCloneEvent: true,
1221 inlineBlockNeedsLayout: false,
1222 shrinkWrapBlocks: false,
1223 reliableMarginRight: true
1224 };
1225
1226 // Make sure checked status is properly cloned
1227 input.checked = true;
1228 support.noCloneChecked = input.cloneNode( true ).checked;
1229
1230 // Make sure that the options inside disabled selects aren't marked as disabled
1231 // (WebKit marks them as disabled)
1232 select.disabled = true;
1233 support.optDisabled = !opt.disabled;
1234
1235 // Test to see if it's possible to delete an expando from an element
1236 // Fails in Internet Explorer
1237 try {
1238 delete div.test;
1239 } catch( e ) {
1240 support.deleteExpando = false;
1241 }
1242
1243 if ( !div.addEventListener && div.attachEvent && div.fireEvent ) {
1244 div.attachEvent( "onclick", function click() {
1245 // Cloning a node shouldn't copy over any
1246 // bound event handlers (IE does this)
1247 support.noCloneEvent = false;
1248 div.detachEvent( "onclick", click );
1249 });
1250 div.cloneNode( true ).fireEvent( "onclick" );
1251 }
1252
1253 // Check if a radio maintains it's value
1254 // after being appended to the DOM
1255 input = document.createElement("input");
1256 input.value = "t";
1257 input.setAttribute("type", "radio");
1258 support.radioValue = input.value === "t";
1259
1260 input.setAttribute("checked", "checked");
1261 div.appendChild( input );
1262 fragment = document.createDocumentFragment();
1263 fragment.appendChild( div.firstChild );
1264
1265 // WebKit doesn't clone checked state correctly in fragments
1266 support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;
1267
1268 div.innerHTML = "";
1269
1270 // Figure out if the W3C box model works as expected
1271 div.style.width = div.style.paddingLeft = "1px";
1272
1273 // We use our own, invisible, body
1274 body = document.createElement( "body" );
1275 bodyStyle = {
1276 visibility: "hidden",
1277 width: 0,
1278 height: 0,
1279 border: 0,
1280 margin: 0,
1281 // Set background to avoid IE crashes when removing (#9028)
1282 background: "none"
1283 };
1284 for ( i in bodyStyle ) {
1285 body.style[ i ] = bodyStyle[ i ];
1286 }
1287 body.appendChild( div );
1288 documentElement.insertBefore( body, documentElement.firstChild );
1289
1290 // Check if a disconnected checkbox will retain its checked
1291 // value of true after appended to the DOM (IE6/7)
1292 support.appendChecked = input.checked;
1293
1294 support.boxModel = div.offsetWidth === 2;
1295
1296 if ( "zoom" in div.style ) {
1297 // Check if natively block-level elements act like inline-block
1298 // elements when setting their display to 'inline' and giving
1299 // them layout
1300 // (IE < 8 does this)
1301 div.style.display = "inline";
1302 div.style.zoom = 1;
1303 support.inlineBlockNeedsLayout = ( div.offsetWidth === 2 );
1304
1305 // Check if elements with layout shrink-wrap their children
1306 // (IE 6 does this)
1307 div.style.display = "";
1308 div.innerHTML = "<div style='width:4px;'></div>";
1309 support.shrinkWrapBlocks = ( div.offsetWidth !== 2 );
1310 }
1311
1312 div.innerHTML = "<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>";
1313 tds = div.getElementsByTagName( "td" );
1314
1315 // Check if table cells still have offsetWidth/Height when they are set
1316 // to display:none and there are still other visible table cells in a
1317 // table row; if so, offsetWidth/Height are not reliable for use when
1318 // determining if an element has been hidden directly using
1319 // display:none (it is still safe to use offsets if a parent element is
1320 // hidden; don safety goggles and see bug #4512 for more information).
1321 // (only IE 8 fails this test)
1322 isSupported = ( tds[ 0 ].offsetHeight === 0 );
1323
1324 tds[ 0 ].style.display = "";
1325 tds[ 1 ].style.display = "none";
1326
1327 // Check if empty table cells still have offsetWidth/Height
1328 // (IE < 8 fail this test)
1329 support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );
1330 div.innerHTML = "";
1331
1332 // Check if div with explicit width and no margin-right incorrectly
1333 // gets computed margin-right based on width of container. For more
1334 // info see bug #3333
1335 // Fails in WebKit before Feb 2011 nightlies
1336 // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
1337 if ( document.defaultView && document.defaultView.getComputedStyle ) {
1338 marginDiv = document.createElement( "div" );
1339 marginDiv.style.width = "0";
1340 marginDiv.style.marginRight = "0";
1341 div.appendChild( marginDiv );
1342 support.reliableMarginRight =
1343 ( parseInt( ( document.defaultView.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0;
1344 }
1345
1346 // Remove the body element we added
1347 body.innerHTML = "";
1348 documentElement.removeChild( body );
1349
1350 // Technique from Juriy Zaytsev
1351 // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
1352 // We only care about the case where non-standard event systems
1353 // are used, namely in IE. Short-circuiting here helps us to
1354 // avoid an eval call (in setAttribute) which can cause CSP
1355 // to go haywire. See: https://developer.mozilla.org/en/Security/CSP
1356 if ( div.attachEvent ) {
1357 for( i in {
1358 submit: 1,
1359 change: 1,
1360 focusin: 1
1361 } ) {
1362 eventName = "on" + i;
1363 isSupported = ( eventName in div );
1364 if ( !isSupported ) {
1365 div.setAttribute( eventName, "return;" );
1366 isSupported = ( typeof div[ eventName ] === "function" );
1367 }
1368 support[ i + "Bubbles" ] = isSupported;
1369 }
1370 }
1371
1372 return support;
1373 })();
1374
1375 // Keep track of boxModel
1376 jQuery.boxModel = jQuery.support.boxModel;
1377
1378
1379
1380
1381 var rbrace = /^(?:\{.*\}|\[.*\])$/,
1382 rmultiDash = /([a-z])([A-Z])/g;
1383
1384 jQuery.extend({
1385 cache: {},
1386
1387 // Please use with caution
1388 uuid: 0,
1389
1390 // Unique for each copy of jQuery on the page
1391 // Non-digits removed to match rinlinejQuery
1392 expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ),
1393
1394 // The following elements throw uncatchable exceptions if you
1395 // attempt to add expando properties to them.
1396 noData: {
1397 "embed": true,
1398 // Ban all objects except for Flash (which handle expandos)
1399 "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",
1400 "applet": true
1401 },
1402
1403 hasData: function( elem ) {
1404 elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];
1405
1406 return !!elem && !isEmptyDataObject( elem );
1407 },
1408
1409 data: function( elem, name, data, pvt /* Internal Use Only */ ) {
1410 if ( !jQuery.acceptData( elem ) ) {
1411 return;
1412 }
1413
1414 var internalKey = jQuery.expando, getByName = typeof name === "string", thisCache,
1415
1416 // We have to handle DOM nodes and JS objects differently because IE6-7
1417 // can't GC object references properly across the DOM-JS boundary
1418 isNode = elem.nodeType,
1419
1420 // Only DOM nodes need the global jQuery cache; JS object data is
1421 // attached directly to the object so GC can occur automatically
1422 cache = isNode ? jQuery.cache : elem,
1423
1424 // Only defining an ID for JS objects if its cache already exists allows
1425 // the code to shortcut on the same path as a DOM node with no cache
1426 id = isNode ? elem[ jQuery.expando ] : elem[ jQuery.expando ] && jQuery.expando;
1427
1428 // Avoid doing any more work than we need to when trying to get data on an
1429 // object that has no data at all
1430 if ( (!id || (pvt && id && !cache[ id ][ internalKey ])) && getByName && data === undefined ) {
1431 return;
1432 }
1433
1434 if ( !id ) {
1435 // Only DOM nodes need a new unique ID for each element since their data
1436 // ends up in the global cache
1437 if ( isNode ) {
1438 elem[ jQuery.expando ] = id = ++jQuery.uuid;
1439 } else {
1440 id = jQuery.expando;
1441 }
1442 }
1443
1444 if ( !cache[ id ] ) {
1445 cache[ id ] = {};
1446
1447 // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery
1448 // metadata on plain JS objects when the object is serialized using
1449 // JSON.stringify
1450 if ( !isNode ) {
1451 cache[ id ].toJSON = jQuery.noop;
1452 }
1453 }
1454
1455 // An object can be passed to jQuery.data instead of a key/value pair; this gets
1456 // shallow copied over onto the existing cache
1457 if ( typeof name === "object" || typeof name === "function" ) {
1458 if ( pvt ) {
1459 cache[ id ][ internalKey ] = jQuery.extend(cache[ id ][ internalKey ], name);
1460 } else {
1461 cache[ id ] = jQuery.extend(cache[ id ], name);
1462 }
1463 }
1464
1465 thisCache = cache[ id ];
1466
1467 // Internal jQuery data is stored in a separate object inside the object's data
1468 // cache in order to avoid key collisions between internal data and user-defined
1469 // data
1470 if ( pvt ) {
1471 if ( !thisCache[ internalKey ] ) {
1472 thisCache[ internalKey ] = {};
1473 }
1474
1475 thisCache = thisCache[ internalKey ];
1476 }
1477
1478 if ( data !== undefined ) {
1479 thisCache[ jQuery.camelCase( name ) ] = data;
1480 }
1481
1482 // TODO: This is a hack for 1.5 ONLY. It will be removed in 1.6. Users should
1483 // not attempt to inspect the internal events object using jQuery.data, as this
1484 // internal data object is undocumented and subject to change.
1485 if ( name === "events" && !thisCache[name] ) {
1486 return thisCache[ internalKey ] && thisCache[ internalKey ].events;
1487 }
1488
1489 return getByName ? thisCache[ jQuery.camelCase( name ) ] : thisCache;
1490 },
1491
1492 removeData: function( elem, name, pvt /* Internal Use Only */ ) {
1493 if ( !jQuery.acceptData( elem ) ) {
1494 return;
1495 }
1496
1497 var internalKey = jQuery.expando, isNode = elem.nodeType,
1498
1499 // See jQuery.data for more information
1500 cache = isNode ? jQuery.cache : elem,
1501
1502 // See jQuery.data for more information
1503 id = isNode ? elem[ jQuery.expando ] : jQuery.expando;
1504
1505 // If there is already no cache entry for this object, there is no
1506 // purpose in continuing
1507 if ( !cache[ id ] ) {
1508 return;
1509 }
1510
1511 if ( name ) {
1512 var thisCache = pvt ? cache[ id ][ internalKey ] : cache[ id ];
1513
1514 if ( thisCache ) {
1515 delete thisCache[ name ];
1516
1517 // If there is no data left in the cache, we want to continue
1518 // and let the cache object itself get destroyed
1519 if ( !isEmptyDataObject(thisCache) ) {
1520 return;
1521 }
1522 }
1523 }
1524
1525 // See jQuery.data for more information
1526 if ( pvt ) {
1527 delete cache[ id ][ internalKey ];
1528
1529 // Don't destroy the parent cache unless the internal data object
1530 // had been the only thing left in it
1531 if ( !isEmptyDataObject(cache[ id ]) ) {
1532 return;
1533 }
1534 }
1535
1536 var internalCache = cache[ id ][ internalKey ];
1537
1538 // Browsers that fail expando deletion also refuse to delete expandos on
1539 // the window, but it will allow it on all other JS objects; other browsers
1540 // don't care
1541 if ( jQuery.support.deleteExpando || cache != window ) {
1542 delete cache[ id ];
1543 } else {
1544 cache[ id ] = null;
1545 }
1546
1547 // We destroyed the entire user cache at once because it's faster than
1548 // iterating through each key, but we need to continue to persist internal
1549 // data if it existed
1550 if ( internalCache ) {
1551 cache[ id ] = {};
1552 // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery
1553 // metadata on plain JS objects when the object is serialized using
1554 // JSON.stringify
1555 if ( !isNode ) {
1556 cache[ id ].toJSON = jQuery.noop;
1557 }
1558
1559 cache[ id ][ internalKey ] = internalCache;
1560
1561 // Otherwise, we need to eliminate the expando on the node to avoid
1562 // false lookups in the cache for entries that no longer exist
1563 } else if ( isNode ) {
1564 // IE does not allow us to delete expando properties from nodes,
1565 // nor does it have a removeAttribute function on Document nodes;
1566 // we must handle all of these cases
1567 if ( jQuery.support.deleteExpando ) {
1568 delete elem[ jQuery.expando ];
1569 } else if ( elem.removeAttribute ) {
1570 elem.removeAttribute( jQuery.expando );
1571 } else {
1572 elem[ jQuery.expando ] = null;
1573 }
1574 }
1575 },
1576
1577 // For internal use only.
1578 _data: function( elem, name, data ) {
1579 return jQuery.data( elem, name, data, true );
1580 },
1581
1582 // A method for determining if a DOM node can handle the data expando
1583 acceptData: function( elem ) {
1584 if ( elem.nodeName ) {
1585 var match = jQuery.noData[ elem.nodeName.toLowerCase() ];
1586
1587 if ( match ) {
1588 return !(match === true || elem.getAttribute("classid") !== match);
1589 }
1590 }
1591
1592 return true;
1593 }
1594 });
1595
1596 jQuery.fn.extend({
1597 data: function( key, value ) {
1598 var data = null;
1599
1600 if ( typeof key === "undefined" ) {
1601 if ( this.length ) {
1602 data = jQuery.data( this[0] );
1603
1604 if ( this[0].nodeType === 1 ) {
1605 var attr = this[0].attributes, name;
1606 for ( var i = 0, l = attr.length; i < l; i++ ) {
1607 name = attr[i].name;
1608
1609 if ( name.indexOf( "data-" ) === 0 ) {
1610 name = jQuery.camelCase( name.substring(5) );
1611
1612 dataAttr( this[0], name, data[ name ] );
1613 }
1614 }
1615 }
1616 }
1617
1618 return data;
1619
1620 } else if ( typeof key === "object" ) {
1621 return this.each(function() {
1622 jQuery.data( this, key );
1623 });
1624 }
1625
1626 var parts = key.split(".");
1627 parts[1] = parts[1] ? "." + parts[1] : "";
1628
1629 if ( value === undefined ) {
1630 data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
1631
1632 // Try to fetch any internally stored data first
1633 if ( data === undefined && this.length ) {
1634 data = jQuery.data( this[0], key );
1635 data = dataAttr( this[0], key, data );
1636 }
1637
1638 return data === undefined && parts[1] ?
1639 this.data( parts[0] ) :
1640 data;
1641
1642 } else {
1643 return this.each(function() {
1644 var $this = jQuery( this ),
1645 args = [ parts[0], value ];
1646
1647 $this.triggerHandler( "setData" + parts[1] + "!", args );
1648 jQuery.data( this, key, value );
1649 $this.triggerHandler( "changeData" + parts[1] + "!", args );
1650 });
1651 }
1652 },
1653
1654 removeData: function( key ) {
1655 return this.each(function() {
1656 jQuery.removeData( this, key );
1657 });
1658 }
1659 });
1660
1661 function dataAttr( elem, key, data ) {
1662 // If nothing was found internally, try to fetch any
1663 // data from the HTML5 data-* attribute
1664 if ( data === undefined && elem.nodeType === 1 ) {
1665 var name = "data-" + key.replace( rmultiDash, "$1-$2" ).toLowerCase();
1666
1667 data = elem.getAttribute( name );
1668
1669 if ( typeof data === "string" ) {
1670 try {
1671 data = data === "true" ? true :
1672 data === "false" ? false :
1673 data === "null" ? null :
1674 !jQuery.isNaN( data ) ? parseFloat( data ) :
1675 rbrace.test( data ) ? jQuery.parseJSON( data ) :
1676 data;
1677 } catch( e ) {}
1678
1679 // Make sure we set the data so it isn't changed later
1680 jQuery.data( elem, key, data );
1681
1682 } else {
1683 data = undefined;
1684 }
1685 }
1686
1687 return data;
1688 }
1689
1690 // TODO: This is a hack for 1.5 ONLY to allow objects with a single toJSON
1691 // property to be considered empty objects; this property always exists in
1692 // order to make sure JSON.stringify does not expose internal metadata
1693 function isEmptyDataObject( obj ) {
1694 for ( var name in obj ) {
1695 if ( name !== "toJSON" ) {
1696 return false;
1697 }
1698 }
1699
1700 return true;
1701 }
1702
1703
1704
1705
1706 function handleQueueMarkDefer( elem, type, src ) {
1707 var deferDataKey = type + "defer",
1708 queueDataKey = type + "queue",
1709 markDataKey = type + "mark",
1710 defer = jQuery.data( elem, deferDataKey, undefined, true );
1711 if ( defer &&
1712 ( src === "queue" || !jQuery.data( elem, queueDataKey, undefined, true ) ) &&
1713 ( src === "mark" || !jQuery.data( elem, markDataKey, undefined, true ) ) ) {
1714 // Give room for hard-coded callbacks to fire first
1715 // and eventually mark/queue something else on the element
1716 setTimeout( function() {
1717 if ( !jQuery.data( elem, queueDataKey, undefined, true ) &&
1718 !jQuery.data( elem, markDataKey, undefined, true ) ) {
1719 jQuery.removeData( elem, deferDataKey, true );
1720 defer.resolve();
1721 }
1722 }, 0 );
1723 }
1724 }
1725
1726 jQuery.extend({
1727
1728 _mark: function( elem, type ) {
1729 if ( elem ) {
1730 type = (type || "fx") + "mark";
1731 jQuery.data( elem, type, (jQuery.data(elem,type,undefined,true) || 0) + 1, true );
1732 }
1733 },
1734
1735 _unmark: function( force, elem, type ) {
1736 if ( force !== true ) {
1737 type = elem;
1738 elem = force;
1739 force = false;
1740 }
1741 if ( elem ) {
1742 type = type || "fx";
1743 var key = type + "mark",
1744 count = force ? 0 : ( (jQuery.data( elem, key, undefined, true) || 1 ) - 1 );
1745 if ( count ) {
1746 jQuery.data( elem, key, count, true );
1747 } else {
1748 jQuery.removeData( elem, key, true );
1749 handleQueueMarkDefer( elem, type, "mark" );
1750 }
1751 }
1752 },
1753
1754 queue: function( elem, type, data ) {
1755 if ( elem ) {
1756 type = (type || "fx") + "queue";
1757 var q = jQuery.data( elem, type, undefined, true );
1758 // Speed up dequeue by getting out quickly if this is just a lookup
1759 if ( data ) {
1760 if ( !q || jQuery.isArray(data) ) {
1761 q = jQuery.data( elem, type, jQuery.makeArray(data), true );
1762 } else {
1763 q.push( data );
1764 }
1765 }
1766 return q || [];
1767 }
1768 },
1769
1770 dequeue: function( elem, type ) {
1771 type = type || "fx";
1772
1773 var queue = jQuery.queue( elem, type ),
1774 fn = queue.shift(),
1775 defer;
1776
1777 // If the fx queue is dequeued, always remove the progress sentinel
1778 if ( fn === "inprogress" ) {
1779 fn = queue.shift();
1780 }
1781
1782 if ( fn ) {
1783 // Add a progress sentinel to prevent the fx queue from being
1784 // automatically dequeued
1785 if ( type === "fx" ) {
1786 queue.unshift("inprogress");
1787 }
1788
1789 fn.call(elem, function() {
1790 jQuery.dequeue(elem, type);
1791 });
1792 }
1793
1794 if ( !queue.length ) {
1795 jQuery.removeData( elem, type + "queue", true );
1796 handleQueueMarkDefer( elem, type, "queue" );
1797 }
1798 }
1799 });
1800
1801 jQuery.fn.extend({
1802 queue: function( type, data ) {
1803 if ( typeof type !== "string" ) {
1804 data = type;
1805 type = "fx";
1806 }
1807
1808 if ( data === undefined ) {
1809 return jQuery.queue( this[0], type );
1810 }
1811 return this.each(function() {
1812 var queue = jQuery.queue( this, type, data );
1813
1814 if ( type === "fx" && queue[0] !== "inprogress" ) {
1815 jQuery.dequeue( this, type );
1816 }
1817 });
1818 },
1819 dequeue: function( type ) {
1820 return this.each(function() {
1821 jQuery.dequeue( this, type );
1822 });
1823 },
1824 // Based off of the plugin by Clint Helfers, with permission.
1825 // http://blindsignals.com/index.php/2009/07/jquery-delay/
1826 delay: function( time, type ) {
1827 time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
1828 type = type || "fx";
1829
1830 return this.queue( type, function() {
1831 var elem = this;
1832 setTimeout(function() {
1833 jQuery.dequeue( elem, type );
1834 }, time );
1835 });
1836 },
1837 clearQueue: function( type ) {
1838 return this.queue( type || "fx", [] );
1839 },
1840 // Get a promise resolved when queues of a certain type
1841 // are emptied (fx is the type by default)
1842 promise: function( type, object ) {
1843 if ( typeof type !== "string" ) {
1844 object = type;
1845 type = undefined;
1846 }
1847 type = type || "fx";
1848 var defer = jQuery.Deferred(),
1849 elements = this,
1850 i = elements.length,
1851 count = 1,
1852 deferDataKey = type + "defer",
1853 queueDataKey = type + "queue",
1854 markDataKey = type + "mark",
1855 tmp;
1856 function resolve() {
1857 if ( !( --count ) ) {
1858 defer.resolveWith( elements, [ elements ] );
1859 }
1860 }
1861 while( i-- ) {
1862 if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) ||
1863 ( jQuery.data( elements[ i ], queueDataKey, undefined, true ) ||
1864 jQuery.data( elements[ i ], markDataKey, undefined, true ) ) &&
1865 jQuery.data( elements[ i ], deferDataKey, jQuery._Deferred(), true ) )) {
1866 count++;
1867 tmp.done( resolve );
1868 }
1869 }
1870 resolve();
1871 return defer.promise();
1872 }
1873 });
1874
1875
1876
1877
1878 var rclass = /[\n\t\r]/g,
1879 rspace = /\s+/,
1880 rreturn = /\r/g,
1881 rtype = /^(?:button|input)$/i,
1882 rfocusable = /^(?:button|input|object|select|textarea)$/i,
1883 rclickable = /^a(?:rea)?$/i,
1884 rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,
1885 rinvalidChar = /\:/,
1886 formHook, boolHook;
1887
1888 jQuery.fn.extend({
1889 attr: function( name, value ) {
1890 return jQuery.access( this, name, value, true, jQuery.attr );
1891 },
1892
1893 removeAttr: function( name ) {
1894 return this.each(function() {
1895 jQuery.removeAttr( this, name );
1896 });
1897 },
1898
1899 prop: function( name, value ) {
1900 return jQuery.access( this, name, value, true, jQuery.prop );
1901 },
1902
1903 removeProp: function( name ) {
1904 name = jQuery.propFix[ name ] || name;
1905 return this.each(function() {
1906 // try/catch handles cases where IE balks (such as removing a property on window)
1907 try {
1908 this[ name ] = undefined;
1909 delete this[ name ];
1910 } catch( e ) {}
1911 });
1912 },
1913
1914 addClass: function( value ) {
1915 if ( jQuery.isFunction( value ) ) {
1916 return this.each(function(i) {
1917 var self = jQuery(this);
1918 self.addClass( value.call(this, i, self.attr("class") || "") );
1919 });
1920 }
1921
1922 if ( value && typeof value === "string" ) {
1923 var classNames = (value || "").split( rspace );
1924
1925 for ( var i = 0, l = this.length; i < l; i++ ) {
1926 var elem = this[i];
1927
1928 if ( elem.nodeType === 1 ) {
1929 if ( !elem.className ) {
1930 elem.className = value;
1931
1932 } else {
1933 var className = " " + elem.className + " ",
1934 setClass = elem.className;
1935
1936 for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
1937 if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) {
1938 setClass += " " + classNames[c];
1939 }
1940 }
1941 elem.className = jQuery.trim( setClass );
1942 }
1943 }
1944 }
1945 }
1946
1947 return this;
1948 },
1949
1950 removeClass: function( value ) {
1951 if ( jQuery.isFunction(value) ) {
1952 return this.each(function(i) {
1953 var self = jQuery(this);
1954 self.removeClass( value.call(this, i, self.attr("class")) );
1955 });
1956 }
1957
1958 if ( (value && typeof value === "string") || value === undefined ) {
1959 var classNames = (value || "").split( rspace );
1960
1961 for ( var i = 0, l = this.length; i < l; i++ ) {
1962 var elem = this[i];
1963
1964 if ( elem.nodeType === 1 && elem.className ) {
1965 if ( value ) {
1966 var className = (" " + elem.className + " ").replace(rclass, " ");
1967 for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
1968 className = className.replace(" " + classNames[c] + " ", " ");
1969 }
1970 elem.className = jQuery.trim( className );
1971
1972 } else {
1973 elem.className = "";
1974 }
1975 }
1976 }
1977 }
1978
1979 return this;
1980 },
1981
1982 toggleClass: function( value, stateVal ) {
1983 var type = typeof value,
1984 isBool = typeof stateVal === "boolean";
1985
1986 if ( jQuery.isFunction( value ) ) {
1987 return this.each(function(i) {
1988 var self = jQuery(this);
1989 self.toggleClass( value.call(this, i, self.attr("class"), stateVal), stateVal );
1990 });
1991 }
1992
1993 return this.each(function() {
1994 if ( type === "string" ) {
1995 // toggle individual class names
1996 var className,
1997 i = 0,
1998 self = jQuery( this ),
1999 state = stateVal,
2000 classNames = value.split( rspace );
2001
2002 while ( (className = classNames[ i++ ]) ) {
2003 // check each className given, space seperated list
2004 state = isBool ? state : !self.hasClass( className );
2005 self[ state ? "addClass" : "removeClass" ]( className );
2006 }
2007
2008 } else if ( type === "undefined" || type === "boolean" ) {
2009 if ( this.className ) {
2010 // store className if set
2011 jQuery._data( this, "__className__", this.className );
2012 }
2013
2014 // toggle whole className
2015 this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || "";
2016 }
2017 });
2018 },
2019
2020 hasClass: function( selector ) {
2021 var className = " " + selector + " ";
2022 for ( var i = 0, l = this.length; i < l; i++ ) {
2023 if ( (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {
2024 return true;
2025 }
2026 }
2027
2028 return false;
2029 },
2030
2031 val: function( value ) {
2032 var hooks, ret,
2033 elem = this[0];
2034
2035 if ( !arguments.length ) {
2036 if ( elem ) {
2037 hooks = jQuery.valHooks[ elem.nodeName.toLowerCase() ] || jQuery.valHooks[ elem.type ];
2038
2039 if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
2040 return ret;
2041 }
2042
2043 return (elem.value || "").replace(rreturn, "");
2044 }
2045
2046 return undefined;
2047 }
2048
2049 var isFunction = jQuery.isFunction( value );
2050
2051 return this.each(function( i ) {
2052 var self = jQuery(this), val;
2053
2054 if ( this.nodeType !== 1 ) {
2055 return;
2056 }
2057
2058 if ( isFunction ) {
2059 val = value.call( this, i, self.val() );
2060 } else {
2061 val = value;
2062 }
2063
2064 // Treat null/undefined as ""; convert numbers to string
2065 if ( val == null ) {
2066 val = "";
2067 } else if ( typeof val === "number" ) {
2068 val += "";
2069 } else if ( jQuery.isArray( val ) ) {
2070 val = jQuery.map(val, function ( value ) {
2071 return value == null ? "" : value + "";
2072 });
2073 }
2074
2075 hooks = jQuery.valHooks[ this.nodeName.toLowerCase() ] || jQuery.valHooks[ this.type ];
2076
2077 // If set returns undefined, fall back to normal setting
2078 if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
2079 this.value = val;
2080 }
2081 });
2082 }
2083 });
2084
2085 jQuery.extend({
2086 valHooks: {
2087 option: {
2088 get: function( elem ) {
2089 // attributes.value is undefined in Blackberry 4.7 but
2090 // uses .value. See #6932
2091 var val = elem.attributes.value;
2092 return !val || val.specified ? elem.value : elem.text;
2093 }
2094 },
2095 select: {
2096 get: function( elem ) {
2097 var value,
2098 index = elem.selectedIndex,
2099 values = [],
2100 options = elem.options,
2101 one = elem.type === "select-one";
2102
2103 // Nothing was selected
2104 if ( index < 0 ) {
2105 return null;
2106 }
2107
2108 // Loop through all the selected options
2109 for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
2110 var option = options[ i ];
2111
2112 // Don't return options that are disabled or in a disabled optgroup
2113 if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) &&
2114 (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) {
2115
2116 // Get the specific value for the option
2117 value = jQuery( option ).val();
2118
2119 // We don't need an array for one selects
2120 if ( one ) {
2121 return value;
2122 }
2123
2124 // Multi-Selects return an array
2125 values.push( value );
2126 }
2127 }
2128
2129 // Fixes Bug #2551 -- select.val() broken in IE after form.reset()
2130 if ( one && !values.length && options.length ) {
2131 return jQuery( options[ index ] ).val();
2132 }
2133
2134 return values;
2135 },
2136
2137 set: function( elem, value ) {
2138 var values = jQuery.makeArray( value );
2139
2140 jQuery(elem).find("option").each(function() {
2141 this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
2142 });
2143
2144 if ( !values.length ) {
2145 elem.selectedIndex = -1;
2146 }
2147 return values;
2148 }
2149 }
2150 },
2151
2152 attrFn: {
2153 val: true,
2154 css: true,
2155 html: true,
2156 text: true,
2157 data: true,
2158 width: true,
2159 height: true,
2160 offset: true
2161 },
2162
2163 attrFix: {
2164 // Always normalize to ensure hook usage
2165 tabindex: "tabIndex"
2166 },
2167
2168 attr: function( elem, name, value, pass ) {
2169 var nType = elem.nodeType;
2170
2171 // don't get/set attributes on text, comment and attribute nodes
2172 if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
2173 return undefined;
2174 }
2175
2176 if ( pass && name in jQuery.attrFn ) {
2177 return jQuery( elem )[ name ]( value );
2178 }
2179
2180 // Fallback to prop when attributes are not supported
2181 if ( !("getAttribute" in elem) ) {
2182 return jQuery.prop( elem, name, value );
2183 }
2184
2185 var ret, hooks,
2186 notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
2187
2188 // Normalize the name if needed
2189 name = notxml && jQuery.attrFix[ name ] || name;
2190
2191 hooks = jQuery.attrHooks[ name ];
2192
2193 if ( !hooks ) {
2194 // Use boolHook for boolean attributes
2195 if ( rboolean.test( name ) &&
2196 (typeof value === "boolean" || value === undefined || value.toLowerCase() === name.toLowerCase()) ) {
2197
2198 hooks = boolHook;
2199
2200 // Use formHook for forms and if the name contains certain characters
2201 } else if ( formHook && (jQuery.nodeName( elem, "form" ) || rinvalidChar.test( name )) ) {
2202 hooks = formHook;
2203 }
2204 }
2205
2206 if ( value !== undefined ) {
2207
2208 if ( value === null ) {
2209 jQuery.removeAttr( elem, name );
2210 return undefined;
2211
2212 } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) {
2213 return ret;
2214
2215 } else {
2216 elem.setAttribute( name, "" + value );
2217 return value;
2218 }
2219
2220 } else if ( hooks && "get" in hooks && notxml ) {
2221 return hooks.get( elem, name );
2222
2223 } else {
2224
2225 ret = elem.getAttribute( name );
2226
2227 // Non-existent attributes return null, we normalize to undefined
2228 return ret === null ?
2229 undefined :
2230 ret;
2231 }
2232 },
2233
2234 removeAttr: function( elem, name ) {
2235 var propName;
2236 if ( elem.nodeType === 1 ) {
2237 name = jQuery.attrFix[ name ] || name;
2238
2239 if ( jQuery.support.getSetAttribute ) {
2240 // Use removeAttribute in browsers that support it
2241 elem.removeAttribute( name );
2242 } else {
2243 jQuery.attr( elem, name, "" );
2244 elem.removeAttributeNode( elem.getAttributeNode( name ) );
2245 }
2246
2247 // Set corresponding property to false for boolean attributes
2248 if ( rboolean.test( name ) && (propName = jQuery.propFix[ name ] || name) in elem ) {
2249 elem[ propName ] = false;
2250 }
2251 }
2252 },
2253
2254 attrHooks: {
2255 type: {
2256 set: function( elem, value ) {
2257 // We can't allow the type property to be changed (since it causes problems in IE)
2258 if ( rtype.test( elem.nodeName ) && elem.parentNode ) {
2259 jQuery.error( "type property can't be changed" );
2260 } else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) {
2261 // Setting the type on a radio button after the value resets the value in IE6-9
2262 // Reset value to it's default in case type is set after value
2263 // This is for element creation
2264 var val = elem.value;
2265 elem.setAttribute( "type", value );
2266 if ( val ) {
2267 elem.value = val;
2268 }
2269 return value;
2270 }
2271 }
2272 },
2273 tabIndex: {
2274 get: function( elem ) {
2275 // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
2276 // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
2277 var attributeNode = elem.getAttributeNode("tabIndex");
2278
2279 return attributeNode && attributeNode.specified ?
2280 parseInt( attributeNode.value, 10 ) :
2281 rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
2282 0 :
2283 undefined;
2284 }
2285 }
2286 },
2287
2288 propFix: {
2289 tabindex: "tabIndex",
2290 readonly: "readOnly",
2291 "for": "htmlFor",
2292 "class": "className",
2293 maxlength: "maxLength",
2294 cellspacing: "cellSpacing",
2295 cellpadding: "cellPadding",
2296 rowspan: "rowSpan",
2297 colspan: "colSpan",
2298 usemap: "useMap",
2299 frameborder: "frameBorder",
2300 contenteditable: "contentEditable"
2301 },
2302
2303 prop: function( elem, name, value ) {
2304 var nType = elem.nodeType;
2305
2306 // don't get/set properties on text, comment and attribute nodes
2307 if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
2308 return undefined;
2309 }
2310
2311 var ret, hooks,
2312 notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
2313
2314 // Try to normalize/fix the name
2315 name = notxml && jQuery.propFix[ name ] || name;
2316
2317 hooks = jQuery.propHooks[ name ];
2318
2319 if ( value !== undefined ) {
2320 if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
2321 return ret;
2322
2323 } else {
2324 return (elem[ name ] = value);
2325 }
2326
2327 } else {
2328 if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== undefined ) {
2329 return ret;
2330
2331 } else {
2332 return elem[ name ];
2333 }
2334 }
2335 },
2336
2337 propHooks: {}
2338 });
2339
2340 // Hook for boolean attributes
2341 boolHook = {
2342 get: function( elem, name ) {
2343 // Align boolean attributes with corresponding properties
2344 return elem[ jQuery.propFix[ name ] || name ] ?
2345 name.toLowerCase() :
2346 undefined;
2347 },
2348 set: function( elem, value, name ) {
2349 var propName;
2350 if ( value === false ) {
2351 // Remove boolean attributes when set to false
2352 jQuery.removeAttr( elem, name );
2353 } else {
2354 // value is true since we know at this point it's type boolean and not false
2355 // Set boolean attributes to the same name and set the DOM property
2356 propName = jQuery.propFix[ name ] || name;
2357 if ( propName in elem ) {
2358 // Only set the IDL specifically if it already exists on the element
2359 elem[ propName ] = value;
2360 }
2361
2362 elem.setAttribute( name, name.toLowerCase() );
2363 }
2364 return name;
2365 }
2366 };
2367
2368 // Use the value property for back compat
2369 // Use the formHook for button elements in IE6/7 (#1954)
2370 jQuery.attrHooks.value = {
2371 get: function( elem, name ) {
2372 if ( formHook && jQuery.nodeName( elem, "button" ) ) {
2373 return formHook.get( elem, name );
2374 }
2375 return elem.value;
2376 },
2377 set: function( elem, value, name ) {
2378 if ( formHook && jQuery.nodeName( elem, "button" ) ) {
2379 return formHook.set( elem, value, name );
2380 }
2381 // Does not return so that setAttribute is also used
2382 elem.value = value;
2383 }
2384 };
2385
2386 // IE6/7 do not support getting/setting some attributes with get/setAttribute
2387 if ( !jQuery.support.getSetAttribute ) {
2388
2389 // propFix is more comprehensive and contains all fixes
2390 jQuery.attrFix = jQuery.propFix;
2391
2392 // Use this for any attribute on a form in IE6/7
2393 formHook = jQuery.attrHooks.name = jQuery.valHooks.button = {
2394 get: function( elem, name ) {
2395 var ret;
2396 ret = elem.getAttributeNode( name );
2397 // Return undefined if nodeValue is empty string
2398 return ret && ret.nodeValue !== "" ?
2399 ret.nodeValue :
2400 undefined;
2401 },
2402 set: function( elem, value, name ) {
2403 // Check form objects in IE (multiple bugs related)
2404 // Only use nodeValue if the attribute node exists on the form
2405 var ret = elem.getAttributeNode( name );
2406 if ( ret ) {
2407 ret.nodeValue = value;
2408 return value;
2409 }
2410 }
2411 };
2412
2413 // Set width and height to auto instead of 0 on empty string( Bug #8150 )
2414 // This is for removals
2415 jQuery.each([ "width", "height" ], function( i, name ) {
2416 jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
2417 set: function( elem, value ) {
2418 if ( value === "" ) {
2419 elem.setAttribute( name, "auto" );
2420 return value;
2421 }
2422 }
2423 });
2424 });
2425 }
2426
2427
2428 // Some attributes require a special call on IE
2429 if ( !jQuery.support.hrefNormalized ) {
2430 jQuery.each([ "href", "src", "width", "height" ], function( i, name ) {
2431 jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
2432 get: function( elem ) {
2433 var ret = elem.getAttribute( name, 2 );
2434 return ret === null ? undefined : ret;
2435 }
2436 });
2437 });
2438 }
2439
2440 if ( !jQuery.support.style ) {
2441 jQuery.attrHooks.style = {
2442 get: function( elem ) {
2443 // Return undefined in the case of empty string
2444 // Normalize to lowercase since IE uppercases css property names
2445 return elem.style.cssText.toLowerCase() || undefined;
2446 },
2447 set: function( elem, value ) {
2448 return (elem.style.cssText = "" + value);
2449 }
2450 };
2451 }
2452
2453 // Safari mis-reports the default selected property of an option
2454 // Accessing the parent's selectedIndex property fixes it
2455 if ( !jQuery.support.optSelected ) {
2456 jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, {
2457 get: function( elem ) {
2458 var parent = elem.parentNode;
2459
2460 if ( parent ) {
2461 parent.selectedIndex;
2462
2463 // Make sure that it also works with optgroups, see #5701
2464 if ( parent.parentNode ) {
2465 parent.parentNode.selectedIndex;
2466 }
2467 }
2468 }
2469 });
2470 }
2471
2472 // Radios and checkboxes getter/setter
2473 if ( !jQuery.support.checkOn ) {
2474 jQuery.each([ "radio", "checkbox" ], function() {
2475 jQuery.valHooks[ this ] = {
2476 get: function( elem ) {
2477 // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
2478 return elem.getAttribute("value") === null ? "on" : elem.value;
2479 }
2480 };
2481 });
2482 }
2483 jQuery.each([ "radio", "checkbox" ], function() {
2484 jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], {
2485 set: function( elem, value ) {
2486 if ( jQuery.isArray( value ) ) {
2487 return (elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0);
2488 }
2489 }
2490 });
2491 });
2492
2493
2494
2495
2496 var hasOwn = Object.prototype.hasOwnProperty,
2497 rnamespaces = /\.(.*)$/,
2498 rformElems = /^(?:textarea|input|select)$/i,
2499 rperiod = /\./g,
2500 rspaces = / /g,
2501 rescape = /[^\w\s.|`]/g,
2502 fcleanup = function( nm ) {
2503 return nm.replace(rescape, "\\$&");
2504 };
2505
2506 /*
2507 * A number of helper functions used for managing events.
2508 * Many of the ideas behind this code originated from
2509 * Dean Edwards' addEvent library.
2510 */
2511 jQuery.event = {
2512
2513 // Bind an event to an element
2514 // Original by Dean Edwards
2515 add: function( elem, types, handler, data ) {
2516 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
2517 return;
2518 }
2519
2520 if ( handler === false ) {
2521 handler = returnFalse;
2522 } else if ( !handler ) {
2523 // Fixes bug #7229. Fix recommended by jdalton
2524 return;
2525 }
2526
2527 var handleObjIn, handleObj;
2528
2529 if ( handler.handler ) {
2530 handleObjIn = handler;
2531 handler = handleObjIn.handler;
2532 }
2533
2534 // Make sure that the function being executed has a unique ID
2535 if ( !handler.guid ) {
2536 handler.guid = jQuery.guid++;
2537 }
2538
2539 // Init the element's event structure
2540 var elemData = jQuery._data( elem );
2541
2542 // If no elemData is found then we must be trying to bind to one of the
2543 // banned noData elements
2544 if ( !elemData ) {
2545 return;
2546 }
2547
2548 var events = elemData.events,
2549 eventHandle = elemData.handle;
2550
2551 if ( !events ) {
2552 elemData.events = events = {};
2553 }
2554
2555 if ( !eventHandle ) {
2556 elemData.handle = eventHandle = function( e ) {
2557 // Discard the second event of a jQuery.event.trigger() and
2558 // when an event is called after a page has unloaded
2559 return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ?
2560 jQuery.event.handle.apply( eventHandle.elem, arguments ) :
2561 undefined;
2562 };
2563 }
2564
2565 // Add elem as a property of the handle function
2566 // This is to prevent a memory leak with non-native events in IE.
2567 eventHandle.elem = elem;
2568
2569 // Handle multiple events separated by a space
2570 // jQuery(...).bind("mouseover mouseout", fn);
2571 types = types.split(" ");
2572
2573 var type, i = 0, namespaces;
2574
2575 while ( (type = types[ i++ ]) ) {
2576 handleObj = handleObjIn ?
2577 jQuery.extend({}, handleObjIn) :
2578 { handler: handler, data: data };
2579
2580 // Namespaced event handlers
2581 if ( type.indexOf(".") > -1 ) {
2582 namespaces = type.split(".");
2583 type = namespaces.shift();
2584 handleObj.namespace = namespaces.slice(0).sort().join(".");
2585
2586 } else {
2587 namespaces = [];
2588 handleObj.namespace = "";
2589 }
2590
2591 handleObj.type = type;
2592 if ( !handleObj.guid ) {
2593 handleObj.guid = handler.guid;
2594 }
2595
2596 // Get the current list of functions bound to this event
2597 var handlers = events[ type ],
2598 special = jQuery.event.special[ type ] || {};
2599
2600 // Init the event handler queue
2601 if ( !handlers ) {
2602 handlers = events[ type ] = [];
2603
2604 // Check for a special event handler
2605 // Only use addEventListener/attachEvent if the special
2606 // events handler returns false
2607 if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
2608 // Bind the global event handler to the element
2609 if ( elem.addEventListener ) {
2610 elem.addEventListener( type, eventHandle, false );
2611
2612 } else if ( elem.attachEvent ) {
2613 elem.attachEvent( "on" + type, eventHandle );
2614 }
2615 }
2616 }
2617
2618 if ( special.add ) {
2619 special.add.call( elem, handleObj );
2620
2621 if ( !handleObj.handler.guid ) {
2622 handleObj.handler.guid = handler.guid;
2623 }
2624 }
2625
2626 // Add the function to the element's handler list
2627 handlers.push( handleObj );
2628
2629 // Keep track of which events have been used, for event optimization
2630 jQuery.event.global[ type ] = true;
2631 }
2632
2633 // Nullify elem to prevent memory leaks in IE
2634 elem = null;
2635 },
2636
2637 global: {},
2638
2639 // Detach an event or set of events from an element
2640 remove: function( elem, types, handler, pos ) {
2641 // don't do events on text and comment nodes
2642 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
2643 return;
2644 }
2645
2646 if ( handler === false ) {
2647 handler = returnFalse;
2648 }
2649
2650 var ret, type, fn, j, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType,
2651 elemData = jQuery.hasData( elem ) && jQuery._data( elem ),
2652 events = elemData && elemData.events;
2653
2654 if ( !elemData || !events ) {
2655 return;
2656 }
2657
2658 // types is actually an event object here
2659 if ( types && types.type ) {
2660 handler = types.handler;
2661 types = types.type;
2662 }
2663
2664 // Unbind all events for the element
2665 if ( !types || typeof types === "string" && types.charAt(0) === "." ) {
2666 types = types || "";
2667
2668 for ( type in events ) {
2669 jQuery.event.remove( elem, type + types );
2670 }
2671
2672 return;
2673 }
2674
2675 // Handle multiple events separated by a space
2676 // jQuery(...).unbind("mouseover mouseout", fn);
2677 types = types.split(" ");
2678
2679 while ( (type = types[ i++ ]) ) {
2680 origType = type;
2681 handleObj = null;
2682 all = type.indexOf(".") < 0;
2683 namespaces = [];
2684
2685 if ( !all ) {
2686 // Namespaced event handlers
2687 namespaces = type.split(".");
2688 type = namespaces.shift();
2689
2690 namespace = new RegExp("(^|\\.)" +
2691 jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)");
2692 }
2693
2694 eventType = events[ type ];
2695
2696 if ( !eventType ) {
2697 continue;
2698 }
2699
2700 if ( !handler ) {
2701 for ( j = 0; j < eventType.length; j++ ) {
2702 handleObj = eventType[ j ];
2703
2704 if ( all || namespace.test( handleObj.namespace ) ) {
2705 jQuery.event.remove( elem, origType, handleObj.handler, j );
2706 eventType.splice( j--, 1 );
2707 }
2708 }
2709
2710 continue;
2711 }
2712
2713 special = jQuery.event.special[ type ] || {};
2714
2715 for ( j = pos || 0; j < eventType.length; j++ ) {
2716 handleObj = eventType[ j ];
2717
2718 if ( handler.guid === handleObj.guid ) {
2719 // remove the given handler for the given type
2720 if ( all || namespace.test( handleObj.namespace ) ) {
2721 if ( pos == null ) {
2722 eventType.splice( j--, 1 );
2723 }
2724
2725 if ( special.remove ) {
2726 special.remove.call( elem, handleObj );
2727 }
2728 }
2729
2730 if ( pos != null ) {
2731 break;
2732 }
2733 }
2734 }
2735
2736 // remove generic event handler if no more handlers exist
2737 if ( eventType.length === 0 || pos != null && eventType.length === 1 ) {
2738 if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
2739 jQuery.removeEvent( elem, type, elemData.handle );
2740 }
2741
2742 ret = null;
2743 delete events[ type ];
2744 }
2745 }
2746
2747 // Remove the expando if it's no longer used
2748 if ( jQuery.isEmptyObject( events ) ) {
2749 var handle = elemData.handle;
2750 if ( handle ) {
2751 handle.elem = null;
2752 }
2753
2754 delete elemData.events;
2755 delete elemData.handle;
2756
2757 if ( jQuery.isEmptyObject( elemData ) ) {
2758 jQuery.removeData( elem, undefined, true );
2759 }
2760 }
2761 },
2762
2763 // Events that are safe to short-circuit if no handlers are attached.
2764 // Native DOM events should not be added, they may have inline handlers.
2765 customEvent: {
2766 "getData": true,
2767 "setData": true,
2768 "changeData": true
2769 },
2770
2771 trigger: function( event, data, elem, onlyHandlers ) {
2772 // Event object or event type
2773 var type = event.type || event,
2774 namespaces = [],
2775 exclusive;
2776
2777 if ( type.indexOf("!") >= 0 ) {
2778 // Exclusive events trigger only for the exact event (no namespaces)
2779 type = type.slice(0, -1);
2780 exclusive = true;
2781 }
2782
2783 if ( type.indexOf(".") >= 0 ) {
2784 // Namespaced trigger; create a regexp to match event type in handle()
2785 namespaces = type.split(".");
2786 type = namespaces.shift();
2787 namespaces.sort();
2788 }
2789
2790 if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) {
2791 // No jQuery handlers for this event type, and it can't have inline handlers
2792 return;
2793 }
2794
2795 // Caller can pass in an Event, Object, or just an event type string
2796 event = typeof event === "object" ?
2797 // jQuery.Event object
2798 event[ jQuery.expando ] ? event :
2799 // Object literal
2800 new jQuery.Event( type, event ) :
2801 // Just the event type (string)
2802 new jQuery.Event( type );
2803
2804 event.type = type;
2805 event.exclusive = exclusive;
2806 event.namespace = namespaces.join(".");
2807 event.namespace_re = new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)");
2808
2809 // triggerHandler() and global events don't bubble or run the default action
2810 if ( onlyHandlers || !elem ) {
2811 event.preventDefault();
2812 event.stopPropagation();
2813 }
2814
2815 // Handle a global trigger
2816 if ( !elem ) {
2817 // TODO: Stop taunting the data cache; remove global events and always attach to document
2818 jQuery.each( jQuery.cache, function() {
2819 // internalKey variable is just used to make it easier to find
2820 // and potentially change this stuff later; currently it just
2821 // points to jQuery.expando
2822 var internalKey = jQuery.expando,
2823 internalCache = this[ internalKey ];
2824 if ( internalCache && internalCache.events && internalCache.events[ type ] ) {
2825 jQuery.event.trigger( event, data, internalCache.handle.elem );
2826 }
2827 });
2828 return;
2829 }
2830
2831 // Don't do events on text and comment nodes
2832 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
2833 return;
2834 }
2835
2836 // Clean up the event in case it is being reused
2837 event.result = undefined;
2838 event.target = elem;
2839
2840 // Clone any incoming data and prepend the event, creating the handler arg list
2841 data = data ? jQuery.makeArray( data ) : [];
2842 data.unshift( event );
2843
2844 var cur = elem,
2845 // IE doesn't like method names with a colon (#3533, #8272)
2846 ontype = type.indexOf(":") < 0 ? "on" + type : "";
2847
2848 // Fire event on the current element, then bubble up the DOM tree
2849 do {
2850 var handle = jQuery._data( cur, "handle" );
2851
2852 event.currentTarget = cur;
2853 if ( handle ) {
2854 handle.apply( cur, data );
2855 }
2856
2857 // Trigger an inline bound script
2858 if ( ontype && jQuery.acceptData( cur ) && cur[ ontype ] && cur[ ontype ].apply( cur, data ) === false ) {
2859 event.result = false;
2860 event.preventDefault();
2861 }
2862
2863 // Bubble up to document, then to window
2864 cur = cur.parentNode || cur.ownerDocument || cur === event.target.ownerDocument && window;
2865 } while ( cur && !event.isPropagationStopped() );
2866
2867 // If nobody prevented the default action, do it now
2868 if ( !event.isDefaultPrevented() ) {
2869 var old,
2870 special = jQuery.event.special[ type ] || {};
2871
2872 if ( (!special._default || special._default.call( elem.ownerDocument, event ) === false) &&
2873 !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) {
2874
2875 // Call a native DOM method on the target with the same name name as the event.
2876 // Can't use an .isFunction)() check here because IE6/7 fails that test.
2877 // IE<9 dies on focus to hidden element (#1486), may want to revisit a try/catch.
2878 try {
2879 if ( ontype && elem[ type ] ) {
2880 // Don't re-trigger an onFOO event when we call its FOO() method
2881 old = elem[ ontype ];
2882
2883 if ( old ) {
2884 elem[ ontype ] = null;
2885 }
2886
2887 jQuery.event.triggered = type;
2888 elem[ type ]();
2889 }
2890 } catch ( ieError ) {}
2891
2892 if ( old ) {
2893 elem[ ontype ] = old;
2894 }
2895
2896 jQuery.event.triggered = undefined;
2897 }
2898 }
2899
2900 return event.result;
2901 },
2902
2903 handle: function( event ) {
2904 event = jQuery.event.fix( event || window.event );
2905 // Snapshot the handlers list since a called handler may add/remove events.
2906 var handlers = ((jQuery._data( this, "events" ) || {})[ event.type ] || []).slice(0),
2907 run_all = !event.exclusive && !event.namespace,
2908 args = Array.prototype.slice.call( arguments, 0 );
2909
2910 // Use the fix-ed Event rather than the (read-only) native event
2911 args[0] = event;
2912 event.currentTarget = this;
2913
2914 for ( var j = 0, l = handlers.length; j < l; j++ ) {
2915 var handleObj = handlers[ j ];
2916
2917 // Triggered event must 1) be non-exclusive and have no namespace, or
2918 // 2) have namespace(s) a subset or equal to those in the bound event.
2919 if ( run_all || event.namespace_re.test( handleObj.namespace ) ) {
2920 // Pass in a reference to the handler function itself
2921 // So that we can later remove it
2922 event.handler = handleObj.handler;
2923 event.data = handleObj.data;
2924 event.handleObj = handleObj;
2925
2926 var ret = handleObj.handler.apply( this, args );
2927
2928 if ( ret !== undefined ) {
2929 event.result = ret;
2930 if ( ret === false ) {
2931 event.preventDefault();
2932 event.stopPropagation();
2933 }
2934 }
2935
2936 if ( event.isImmediatePropagationStopped() ) {
2937 break;
2938 }
2939 }
2940 }
2941 return event.result;
2942 },
2943
2944 props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
2945
2946 fix: function( event ) {
2947 if ( event[ jQuery.expando ] ) {
2948 return event;
2949 }
2950
2951 // store a copy of the original event object
2952 // and "clone" to set read-only properties
2953 var originalEvent = event;
2954 event = jQuery.Event( originalEvent );
2955
2956 for ( var i = this.props.length, prop; i; ) {
2957 prop = this.props[ --i ];
2958 event[ prop ] = originalEvent[ prop ];
2959 }
2960
2961 // Fix target property, if necessary
2962 if ( !event.target ) {
2963 // Fixes #1925 where srcElement might not be defined either
2964 event.target = event.srcElement || document;
2965 }
2966
2967 // check if target is a textnode (safari)
2968 if ( event.target.nodeType === 3 ) {
2969 event.target = event.target.parentNode;
2970 }
2971
2972 // Add relatedTarget, if necessary
2973 if ( !event.relatedTarget && event.fromElement ) {
2974 event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
2975 }
2976
2977 // Calculate pageX/Y if missing and clientX/Y available
2978 if ( event.pageX == null && event.clientX != null ) {
2979 var eventDocument = event.target.ownerDocument || document,
2980 doc = eventDocument.documentElement,
2981 body = eventDocument.body;
2982
2983 event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
2984 event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
2985 }
2986
2987 // Add which for key events
2988 if ( event.which == null && (event.charCode != null || event.keyCode != null) ) {
2989 event.which = event.charCode != null ? event.charCode : event.keyCode;
2990 }
2991
2992 // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
2993 if ( !event.metaKey && event.ctrlKey ) {
2994 event.metaKey = event.ctrlKey;
2995 }
2996
2997 // Add which for click: 1 === left; 2 === middle; 3 === right
2998 // Note: button is not normalized, so don't use it
2999 if ( !event.which && event.button !== undefined ) {
3000 event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
3001 }
3002
3003 return event;
3004 },
3005
3006 // Deprecated, use jQuery.guid instead
3007 guid: 1E8,
3008
3009 // Deprecated, use jQuery.proxy instead
3010 proxy: jQuery.proxy,
3011
3012 special: {
3013 ready: {
3014 // Make sure the ready event is setup
3015 setup: jQuery.bindReady,
3016 teardown: jQuery.noop
3017 },
3018
3019 live: {
3020 add: function( handleObj ) {
3021 jQuery.event.add( this,
3022 liveConvert( handleObj.origType, handleObj.selector ),
3023 jQuery.extend({}, handleObj, {handler: liveHandler, guid: handleObj.handler.guid}) );
3024 },
3025
3026 remove: function( handleObj ) {
3027 jQuery.event.remove( this, liveConvert( handleObj.origType, handleObj.selector ), handleObj );
3028 }
3029 },
3030
3031 beforeunload: {
3032 setup: function( data, namespaces, eventHandle ) {
3033 // We only want to do this special case on windows
3034 if ( jQuery.isWindow( this ) ) {
3035 this.onbeforeunload = eventHandle;
3036 }
3037 },
3038
3039 teardown: function( namespaces, eventHandle ) {
3040 if ( this.onbeforeunload === eventHandle ) {
3041 this.onbeforeunload = null;
3042 }
3043 }
3044 }
3045 }
3046 };
3047
3048 jQuery.removeEvent = document.removeEventListener ?
3049 function( elem, type, handle ) {
3050 if ( elem.removeEventListener ) {
3051 elem.removeEventListener( type, handle, false );
3052 }
3053 } :
3054 function( elem, type, handle ) {
3055 if ( elem.detachEvent ) {
3056 elem.detachEvent( "on" + type, handle );
3057 }
3058 };
3059
3060 jQuery.Event = function( src, props ) {
3061 // Allow instantiation without the 'new' keyword
3062 if ( !this.preventDefault ) {
3063 return new jQuery.Event( src, props );
3064 }
3065
3066 // Event object
3067 if ( src && src.type ) {
3068 this.originalEvent = src;
3069 this.type = src.type;
3070
3071 // Events bubbling up the document may have been marked as prevented
3072 // by a handler lower down the tree; reflect the correct value.
3073 this.isDefaultPrevented = (src.defaultPrevented || src.returnValue === false ||
3074 src.getPreventDefault && src.getPreventDefault()) ? returnTrue : returnFalse;
3075
3076 // Event type
3077 } else {
3078 this.type = src;
3079 }
3080
3081 // Put explicitly provided properties onto the event object
3082 if ( props ) {
3083 jQuery.extend( this, props );
3084 }
3085
3086 // timeStamp is buggy for some events on Firefox(#3843)
3087 // So we won't rely on the native value
3088 this.timeStamp = jQuery.now();
3089
3090 // Mark it as fixed
3091 this[ jQuery.expando ] = true;
3092 };
3093
3094 function returnFalse() {
3095 return false;
3096 }
3097 function returnTrue() {
3098 return true;
3099 }
3100
3101 // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
3102 // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
3103 jQuery.Event.prototype = {
3104 preventDefault: function() {
3105 this.isDefaultPrevented = returnTrue;
3106
3107 var e = this.originalEvent;
3108 if ( !e ) {
3109 return;
3110 }
3111
3112 // if preventDefault exists run it on the original event
3113 if ( e.preventDefault ) {
3114 e.preventDefault();
3115
3116 // otherwise set the returnValue property of the original event to false (IE)
3117 } else {
3118 e.returnValue = false;
3119 }
3120 },
3121 stopPropagation: function() {
3122 this.isPropagationStopped = returnTrue;
3123
3124 var e = this.originalEvent;
3125 if ( !e ) {
3126 return;
3127 }
3128 // if stopPropagation exists run it on the original event
3129 if ( e.stopPropagation ) {
3130 e.stopPropagation();
3131 }
3132 // otherwise set the cancelBubble property of the original event to true (IE)
3133 e.cancelBubble = true;
3134 },
3135 stopImmediatePropagation: function() {
3136 this.isImmediatePropagationStopped = returnTrue;
3137 this.stopPropagation();
3138 },
3139 isDefaultPrevented: returnFalse,
3140 isPropagationStopped: returnFalse,
3141 isImmediatePropagationStopped: returnFalse
3142 };
3143
3144 // Checks if an event happened on an element within another element
3145 // Used in jQuery.event.special.mouseenter and mouseleave handlers
3146 var withinElement = function( event ) {
3147 // Check if mouse(over|out) are still within the same parent element
3148 var parent = event.relatedTarget;
3149
3150 // set the correct event type
3151 event.type = event.data;
3152
3153 // Firefox sometimes assigns relatedTarget a XUL element
3154 // which we cannot access the parentNode property of
3155 try {
3156
3157 // Chrome does something similar, the parentNode property
3158 // can be accessed but is null.
3159 if ( parent && parent !== document && !parent.parentNode ) {
3160 return;
3161 }
3162
3163 // Traverse up the tree
3164 while ( parent && parent !== this ) {
3165 parent = parent.parentNode;
3166 }
3167
3168 if ( parent !== this ) {
3169 // handle event if we actually just moused on to a non sub-element
3170 jQuery.event.handle.apply( this, arguments );
3171 }
3172
3173 // assuming we've left the element since we most likely mousedover a xul element
3174 } catch(e) { }
3175 },
3176
3177 // In case of event delegation, we only need to rename the event.type,
3178 // liveHandler will take care of the rest.
3179 delegate = function( event ) {
3180 event.type = event.data;
3181 jQuery.event.handle.apply( this, arguments );
3182 };
3183
3184 // Create mouseenter and mouseleave events
3185 jQuery.each({
3186 mouseenter: "mouseover",
3187 mouseleave: "mouseout"
3188 }, function( orig, fix ) {
3189 jQuery.event.special[ orig ] = {
3190 setup: function( data ) {
3191 jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig );
3192 },
3193 teardown: function( data ) {
3194 jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement );
3195 }
3196 };
3197 });
3198
3199 // submit delegation
3200 if ( !jQuery.support.submitBubbles ) {
3201
3202 jQuery.event.special.submit = {
3203 setup: function( data, namespaces ) {
3204 if ( !jQuery.nodeName( this, "form" ) ) {
3205 jQuery.event.add(this, "click.specialSubmit", function( e ) {
3206 var elem = e.target,
3207 type = elem.type;
3208
3209 if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) {
3210 trigger( "submit", this, arguments );
3211 }
3212 });
3213
3214 jQuery.event.add(this, "keypress.specialSubmit", function( e ) {
3215 var elem = e.target,
3216 type = elem.type;
3217
3218 if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) {
3219 trigger( "submit", this, arguments );
3220 }
3221 });
3222
3223 } else {
3224 return false;
3225 }
3226 },
3227
3228 teardown: function( namespaces ) {
3229 jQuery.event.remove( this, ".specialSubmit" );
3230 }
3231 };
3232
3233 }
3234
3235 // change delegation, happens here so we have bind.
3236 if ( !jQuery.support.changeBubbles ) {
3237
3238 var changeFilters,
3239
3240 getVal = function( elem ) {
3241 var type = elem.type, val = elem.value;
3242
3243 if ( type === "radio" || type === "checkbox" ) {
3244 val = elem.checked;
3245
3246 } else if ( type === "select-multiple" ) {
3247 val = elem.selectedIndex > -1 ?
3248 jQuery.map( elem.options, function( elem ) {
3249 return elem.selected;
3250 }).join("-") :
3251 "";
3252
3253 } else if ( jQuery.nodeName( elem, "select" ) ) {
3254 val = elem.selectedIndex;
3255 }
3256
3257 return val;
3258 },
3259
3260 testChange = function testChange( e ) {
3261 var elem = e.target, data, val;
3262
3263 if ( !rformElems.test( elem.nodeName ) || elem.readOnly ) {
3264 return;
3265 }
3266
3267 data = jQuery._data( elem, "_change_data" );
3268 val = getVal(elem);
3269
3270 // the current data will be also retrieved by beforeactivate
3271 if ( e.type !== "focusout" || elem.type !== "radio" ) {
3272 jQuery._data( elem, "_change_data", val );
3273 }
3274
3275 if ( data === undefined || val === data ) {
3276 return;
3277 }
3278
3279 if ( data != null || val ) {
3280 e.type = "change";
3281 e.liveFired = undefined;
3282 jQuery.event.trigger( e, arguments[1], elem );
3283 }
3284 };
3285
3286 jQuery.event.special.change = {
3287 filters: {
3288 focusout: testChange,
3289
3290 beforedeactivate: testChange,
3291
3292 click: function( e ) {
3293 var elem = e.target, type = jQuery.nodeName( elem, "input" ) ? elem.type : "";
3294
3295 if ( type === "radio" || type === "checkbox" || jQuery.nodeName( elem, "select" ) ) {
3296 testChange.call( this, e );
3297 }
3298 },
3299
3300 // Change has to be called before submit
3301 // Keydown will be called before keypress, which is used in submit-event delegation
3302 keydown: function( e ) {
3303 var elem = e.target, type = jQuery.nodeName( elem, "input" ) ? elem.type : "";
3304
3305 if ( (e.keyCode === 13 && !jQuery.nodeName( elem, "textarea" ) ) ||
3306 (e.keyCode === 32 && (type === "checkbox" || type === "radio")) ||
3307 type === "select-multiple" ) {
3308 testChange.call( this, e );
3309 }
3310 },
3311
3312 // Beforeactivate happens also before the previous element is blurred
3313 // with this event you can't trigger a change event, but you can store
3314 // information
3315 beforeactivate: function( e ) {
3316 var elem = e.target;
3317 jQuery._data( elem, "_change_data", getVal(elem) );
3318 }
3319 },
3320
3321 setup: function( data, namespaces ) {
3322 if ( this.type === "file" ) {
3323 return false;
3324 }
3325
3326 for ( var type in changeFilters ) {
3327 jQuery.event.add( this, type + ".specialChange", changeFilters[type] );
3328 }
3329
3330 return rformElems.test( this.nodeName );
3331 },
3332
3333 teardown: function( namespaces ) {
3334 jQuery.event.remove( this, ".specialChange" );
3335
3336 return rformElems.test( this.nodeName );
3337 }
3338 };
3339
3340 changeFilters = jQuery.event.special.change.filters;
3341
3342 // Handle when the input is .focus()'d
3343 changeFilters.focus = changeFilters.beforeactivate;
3344 }
3345
3346 function trigger( type, elem, args ) {
3347 // Piggyback on a donor event to simulate a different one.
3348 // Fake originalEvent to avoid donor's stopPropagation, but if the
3349 // simulated event prevents default then we do the same on the donor.
3350 // Don't pass args or remember liveFired; they apply to the donor event.
3351 var event = jQuery.extend( {}, args[ 0 ] );
3352 event.type = type;
3353 event.originalEvent = {};
3354 event.liveFired = undefined;
3355 jQuery.event.handle.call( elem, event );
3356 if ( event.isDefaultPrevented() ) {
3357 args[ 0 ].preventDefault();
3358 }
3359 }
3360
3361 // Create "bubbling" focus and blur events
3362 if ( !jQuery.support.focusinBubbles ) {
3363 jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
3364
3365 // Attach a single capturing handler while someone wants focusin/focusout
3366 var attaches = 0;
3367
3368 jQuery.event.special[ fix ] = {
3369 setup: function() {
3370 if ( attaches++ === 0 ) {
3371 document.addEventListener( orig, handler, true );
3372 }
3373 },
3374 teardown: function() {
3375 if ( --attaches === 0 ) {
3376 document.removeEventListener( orig, handler, true );
3377 }
3378 }
3379 };
3380
3381 function handler( donor ) {
3382 // Donor event is always a native one; fix it and switch its type.
3383 // Let focusin/out handler cancel the donor focus/blur event.
3384 var e = jQuery.event.fix( donor );
3385 e.type = fix;
3386 e.originalEvent = {};
3387 jQuery.event.trigger( e, null, e.target );
3388 if ( e.isDefaultPrevented() ) {
3389 donor.preventDefault();
3390 }
3391 }
3392 });
3393 }
3394
3395 jQuery.each(["bind", "one"], function( i, name ) {
3396 jQuery.fn[ name ] = function( type, data, fn ) {
3397 var handler;
3398
3399 // Handle object literals
3400 if ( typeof type === "object" ) {
3401 for ( var key in type ) {
3402 this[ name ](key, data, type[key], fn);
3403 }
3404 return this;
3405 }
3406
3407 if ( arguments.length === 2 || data === false ) {
3408 fn = data;
3409 data = undefined;
3410 }
3411
3412 if ( name === "one" ) {
3413 handler = function( event ) {
3414 jQuery( this ).unbind( event, handler );
3415 return fn.apply( this, arguments );
3416 };
3417 handler.guid = fn.guid || jQuery.guid++;
3418 } else {
3419 handler = fn;
3420 }
3421
3422 if ( type === "unload" && name !== "one" ) {
3423 this.one( type, data, fn );
3424
3425 } else {
3426 for ( var i = 0, l = this.length; i < l; i++ ) {
3427 jQuery.event.add( this[i], type, handler, data );
3428 }
3429 }
3430
3431 return this;
3432 };
3433 });
3434
3435 jQuery.fn.extend({
3436 unbind: function( type, fn ) {
3437 // Handle object literals
3438 if ( typeof type === "object" && !type.preventDefault ) {
3439 for ( var key in type ) {
3440 this.unbind(key, type[key]);
3441 }
3442
3443 } else {
3444 for ( var i = 0, l = this.length; i < l; i++ ) {
3445 jQuery.event.remove( this[i], type, fn );
3446 }
3447 }
3448
3449 return this;
3450 },
3451
3452 delegate: function( selector, types, data, fn ) {
3453 return this.live( types, data, fn, selector );
3454 },
3455
3456 undelegate: function( selector, types, fn ) {
3457 if ( arguments.length === 0 ) {
3458 return this.unbind( "live" );
3459
3460 } else {
3461 return this.die( types, null, fn, selector );
3462 }
3463 },
3464
3465 trigger: function( type, data ) {
3466 return this.each(function() {
3467 jQuery.event.trigger( type, data, this );
3468 });
3469 },
3470
3471 triggerHandler: function( type, data ) {
3472 if ( this[0] ) {
3473 return jQuery.event.trigger( type, data, this[0], true );
3474 }
3475 },
3476
3477 toggle: function( fn ) {
3478 // Save reference to arguments for access in closure
3479 var args = arguments,
3480 guid = fn.guid || jQuery.guid++,
3481 i = 0,
3482 toggler = function( event ) {
3483 // Figure out which function to execute
3484 var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i;
3485 jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 );
3486
3487 // Make sure that clicks stop
3488 event.preventDefault();
3489
3490 // and execute the function
3491 return args[ lastToggle ].apply( this, arguments ) || false;
3492 };
3493
3494 // link all the functions, so any of them can unbind this click handler
3495 toggler.guid = guid;
3496 while ( i < args.length ) {
3497 args[ i++ ].guid = guid;
3498 }
3499
3500 return this.click( toggler );
3501 },
3502
3503 hover: function( fnOver, fnOut ) {
3504 return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
3505 }
3506 });
3507
3508 var liveMap = {
3509 focus: "focusin",
3510 blur: "focusout",
3511 mouseenter: "mouseover",
3512 mouseleave: "mouseout"
3513 };
3514
3515 jQuery.each(["live", "die"], function( i, name ) {
3516 jQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) {
3517 var type, i = 0, match, namespaces, preType,
3518 selector = origSelector || this.selector,
3519 context = origSelector ? this : jQuery( this.context );
3520
3521 if ( typeof types === "object" && !types.preventDefault ) {
3522 for ( var key in types ) {
3523 context[ name ]( key, data, types[key], selector );
3524 }
3525
3526 return this;
3527 }
3528
3529 if ( name === "die" && !types &&
3530 origSelector && origSelector.charAt(0) === "." ) {
3531
3532 context.unbind( origSelector );
3533
3534 return this;
3535 }
3536
3537 if ( data === false || jQuery.isFunction( data ) ) {
3538 fn = data || returnFalse;
3539 data = undefined;
3540 }
3541
3542 types = (types || "").split(" ");
3543
3544 while ( (type = types[ i++ ]) != null ) {
3545 match = rnamespaces.exec( type );
3546 namespaces = "";
3547
3548 if ( match ) {
3549 namespaces = match[0];
3550 type = type.replace( rnamespaces, "" );
3551 }
3552
3553 if ( type === "hover" ) {
3554 types.push( "mouseenter" + namespaces, "mouseleave" + namespaces );
3555 continue;
3556 }
3557
3558 preType = type;
3559
3560 if ( liveMap[ type ] ) {
3561 types.push( liveMap[ type ] + namespaces );
3562 type = type + namespaces;
3563
3564 } else {
3565 type = (liveMap[ type ] || type) + namespaces;
3566 }
3567
3568 if ( name === "live" ) {
3569 // bind live handler
3570 for ( var j = 0, l = context.length; j < l; j++ ) {
3571 jQuery.event.add( context[j], "live." + liveConvert( type, selector ),
3572 { data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } );
3573 }
3574
3575 } else {
3576 // unbind live handler
3577 context.unbind( "live." + liveConvert( type, selector ), fn );
3578 }
3579 }
3580
3581 return this;
3582 };
3583 });
3584
3585 function liveHandler( event ) {
3586 var stop, maxLevel, related, match, handleObj, elem, j, i, l, data, close, namespace, ret,
3587 elems = [],
3588 selectors = [],
3589 events = jQuery._data( this, "events" );
3590
3591 // Make sure we avoid non-left-click bubbling in Firefox (#3861) and disabled elements in IE (#6911)
3592 if ( event.liveFired === this || !events || !events.live || event.target.disabled || event.button && event.type === "click" ) {
3593 return;
3594 }
3595
3596 if ( event.namespace ) {
3597 namespace = new RegExp("(^|\\.)" + event.namespace.split(".").join("\\.(?:.*\\.)?") + "(\\.|$)");
3598 }
3599
3600 event.liveFired = this;
3601
3602 var live = events.live.slice(0);
3603
3604 for ( j = 0; j < live.length; j++ ) {
3605 handleObj = live[j];
3606
3607 if ( handleObj.origType.replace( rnamespaces, "" ) === event.type ) {
3608 selectors.push( handleObj.selector );
3609
3610 } else {
3611 live.splice( j--, 1 );
3612 }
3613 }
3614
3615 match = jQuery( event.target ).closest( selectors, event.currentTarget );
3616
3617 for ( i = 0, l = match.length; i < l; i++ ) {
3618 close = match[i];
3619
3620 for ( j = 0; j < live.length; j++ ) {
3621 handleObj = live[j];
3622
3623 if ( close.selector === handleObj.selector && (!namespace || namespace.test( handleObj.namespace )) && !close.elem.disabled ) {
3624 elem = close.elem;
3625 related = null;
3626
3627 // Those two events require additional checking
3628 if ( handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave" ) {
3629 event.type = handleObj.preType;
3630 related = jQuery( event.relatedTarget ).closest( handleObj.selector )[0];
3631
3632 // Make sure not to accidentally match a child element with the same selector
3633 if ( related && jQuery.contains( elem, related ) ) {
3634 related = elem;
3635 }
3636 }
3637
3638 if ( !related || related !== elem ) {
3639 elems.push({ elem: elem, handleObj: handleObj, level: close.level });
3640 }
3641 }
3642 }
3643 }
3644
3645 for ( i = 0, l = elems.length; i < l; i++ ) {
3646 match = elems[i];
3647
3648 if ( maxLevel && match.level > maxLevel ) {
3649 break;
3650 }
3651
3652 event.currentTarget = match.elem;
3653 event.data = match.handleObj.data;
3654 event.handleObj = match.handleObj;
3655
3656 ret = match.handleObj.origHandler.apply( match.elem, arguments );
3657
3658 if ( ret === false || event.isPropagationStopped() ) {
3659 maxLevel = match.level;
3660
3661 if ( ret === false ) {
3662 stop = false;
3663 }
3664 if ( event.isImmediatePropagationStopped() ) {
3665 break;
3666 }
3667 }
3668 }
3669
3670 return stop;
3671 }
3672
3673 function liveConvert( type, selector ) {
3674 return (type && type !== "*" ? type + "." : "") + selector.replace(rperiod, "`").replace(rspaces, "&");
3675 }
3676
3677 jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
3678 "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
3679 "change select submit keydown keypress keyup error").split(" "), function( i, name ) {
3680
3681 // Handle event binding
3682 jQuery.fn[ name ] = function( data, fn ) {
3683 if ( fn == null ) {
3684 fn = data;
3685 data = null;
3686 }
3687
3688 return arguments.length > 0 ?
3689 this.bind( name, data, fn ) :
3690 this.trigger( name );
3691 };
3692
3693 if ( jQuery.attrFn ) {
3694 jQuery.attrFn[ name ] = true;
3695 }
3696 });
3697
3698
3699
3700 /*!
3701 * Sizzle CSS Selector Engine
3702 * Copyright 2011, The Dojo Foundation
3703 * Released under the MIT, BSD, and GPL Licenses.
3704 * More information: http://sizzlejs.com/
3705 */
3706 (function(){
3707
3708 var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
3709 done = 0,
3710 toString = Object.prototype.toString,
3711 hasDuplicate = false,
3712 baseHasDuplicate = true,
3713 rBackslash = /\\/g,
3714 rNonWord = /\W/;
3715
3716 // Here we check if the JavaScript engine is using some sort of
3717 // optimization where it does not always call our comparision
3718 // function. If that is the case, discard the hasDuplicate value.
3719 // Thus far that includes Google Chrome.
3720 [0, 0].sort(function() {
3721 baseHasDuplicate = false;
3722 return 0;
3723 });
3724
3725 var Sizzle = function( selector, context, results, seed ) {
3726 results = results || [];
3727 context = context || document;
3728
3729 var origContext = context;
3730
3731 if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
3732 return [];
3733 }
3734
3735 if ( !selector || typeof selector !== "string" ) {
3736 return results;
3737 }
3738
3739 var m, set, checkSet, extra, ret, cur, pop, i,
3740 prune = true,
3741 contextXML = Sizzle.isXML( context ),
3742 parts = [],
3743 soFar = selector;
3744
3745 // Reset the position of the chunker regexp (start from head)
3746 do {
3747 chunker.exec( "" );
3748 m = chunker.exec( soFar );
3749
3750 if ( m ) {
3751 soFar = m[3];
3752
3753 parts.push( m[1] );
3754
3755 if ( m[2] ) {
3756 extra = m[3];
3757 break;
3758 }
3759 }
3760 } while ( m );
3761
3762 if ( parts.length > 1 && origPOS.exec( selector ) ) {
3763
3764 if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
3765 set = posProcess( parts[0] + parts[1], context );
3766
3767 } else {
3768 set = Expr.relative[ parts[0] ] ?
3769 [ context ] :
3770 Sizzle( parts.shift(), context );
3771
3772 while ( parts.length ) {
3773 selector = parts.shift();
3774
3775 if ( Expr.relative[ selector ] ) {
3776 selector += parts.shift();
3777 }
3778
3779 set = posProcess( selector, set );
3780 }
3781 }
3782
3783 } else {
3784 // Take a shortcut and set the context if the root selector is an ID
3785 // (but not if it'll be faster if the inner selector is an ID)
3786 if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
3787 Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
3788
3789 ret = Sizzle.find( parts.shift(), context, contextXML );
3790 context = ret.expr ?
3791 Sizzle.filter( ret.expr, ret.set )[0] :
3792 ret.set[0];
3793 }
3794
3795 if ( context ) {
3796 ret = seed ?
3797 { expr: parts.pop(), set: makeArray(seed) } :
3798 Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
3799
3800 set = ret.expr ?
3801 Sizzle.filter( ret.expr, ret.set ) :
3802 ret.set;
3803
3804 if ( parts.length > 0 ) {
3805 checkSet = makeArray( set );
3806
3807 } else {
3808 prune = false;
3809 }
3810
3811 while ( parts.length ) {
3812 cur = parts.pop();
3813 pop = cur;
3814
3815 if ( !Expr.relative[ cur ] ) {
3816 cur = "";
3817 } else {
3818 pop = parts.pop();
3819 }
3820
3821 if ( pop == null ) {
3822 pop = context;
3823 }
3824
3825 Expr.relative[ cur ]( checkSet, pop, contextXML );
3826 }
3827
3828 } else {
3829 checkSet = parts = [];
3830 }
3831 }
3832
3833 if ( !checkSet ) {
3834 checkSet = set;
3835 }
3836
3837 if ( !checkSet ) {
3838 Sizzle.error( cur || selector );
3839 }
3840
3841 if ( toString.call(checkSet) === "[object Array]" ) {
3842 if ( !prune ) {
3843 results.push.apply( results, checkSet );
3844
3845 } else if ( context && context.nodeType === 1 ) {
3846 for ( i = 0; checkSet[i] != null; i++ ) {
3847 if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) {
3848 results.push( set[i] );
3849 }
3850 }
3851
3852 } else {
3853 for ( i = 0; checkSet[i] != null; i++ ) {
3854 if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
3855 results.push( set[i] );
3856 }
3857 }
3858 }
3859
3860 } else {
3861 makeArray( checkSet, results );
3862 }
3863
3864 if ( extra ) {
3865 Sizzle( extra, origContext, results, seed );
3866 Sizzle.uniqueSort( results );
3867 }
3868
3869 return results;
3870 };
3871
3872 Sizzle.uniqueSort = function( results ) {
3873 if ( sortOrder ) {
3874 hasDuplicate = baseHasDuplicate;
3875 results.sort( sortOrder );
3876
3877 if ( hasDuplicate ) {
3878 for ( var i = 1; i < results.length; i++ ) {
3879 if ( results[i] === results[ i - 1 ] ) {
3880 results.splice( i--, 1 );
3881 }
3882 }
3883 }
3884 }
3885
3886 return results;
3887 };
3888
3889 Sizzle.matches = function( expr, set ) {
3890 return Sizzle( expr, null, null, set );
3891 };
3892
3893 Sizzle.matchesSelector = function( node, expr ) {
3894 return Sizzle( expr, null, null, [node] ).length > 0;
3895 };
3896
3897 Sizzle.find = function( expr, context, isXML ) {
3898 var set;
3899
3900 if ( !expr ) {
3901 return [];
3902 }
3903
3904 for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
3905 var match,
3906 type = Expr.order[i];
3907
3908 if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
3909 var left = match[1];
3910 match.splice( 1, 1 );
3911
3912 if ( left.substr( left.length - 1 ) !== "\\" ) {
3913 match[1] = (match[1] || "").replace( rBackslash, "" );
3914 set = Expr.find[ type ]( match, context, isXML );
3915
3916 if ( set != null ) {
3917 expr = expr.replace( Expr.match[ type ], "" );
3918 break;
3919 }
3920 }
3921 }
3922 }
3923
3924 if ( !set ) {
3925 set = typeof context.getElementsByTagName !== "undefined" ?
3926 context.getElementsByTagName( "*" ) :
3927 [];
3928 }
3929
3930 return { set: set, expr: expr };
3931 };
3932
3933 Sizzle.filter = function( expr, set, inplace, not ) {
3934 var match, anyFound,
3935 old = expr,
3936 result = [],
3937 curLoop = set,
3938 isXMLFilter = set && set[0] && Sizzle.isXML( set[0] );
3939
3940 while ( expr && set.length ) {
3941 for ( var type in Expr.filter ) {
3942 if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {
3943 var found, item,
3944 filter = Expr.filter[ type ],
3945 left = match[1];
3946
3947 anyFound = false;
3948
3949 match.splice(1,1);
3950
3951 if ( left.substr( left.length - 1 ) === "\\" ) {
3952 continue;
3953 }
3954
3955 if ( curLoop === result ) {
3956 result = [];
3957 }
3958
3959 if ( Expr.preFilter[ type ] ) {
3960 match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
3961
3962 if ( !match ) {
3963 anyFound = found = true;
3964
3965 } else if ( match === true ) {
3966 continue;
3967 }
3968 }
3969
3970 if ( match ) {
3971 for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
3972 if ( item ) {
3973 found = filter( item, match, i, curLoop );
3974 var pass = not ^ !!found;
3975
3976 if ( inplace && found != null ) {
3977 if ( pass ) {
3978 anyFound = true;
3979
3980 } else {
3981 curLoop[i] = false;
3982 }
3983
3984 } else if ( pass ) {
3985 result.push( item );
3986 anyFound = true;
3987 }
3988 }
3989 }
3990 }
3991
3992 if ( found !== undefined ) {
3993 if ( !inplace ) {
3994 curLoop = result;
3995 }
3996
3997 expr = expr.replace( Expr.match[ type ], "" );
3998
3999 if ( !anyFound ) {
4000 return [];
4001 }
4002
4003 break;
4004 }
4005 }
4006 }
4007
4008 // Improper expression
4009 if ( expr === old ) {
4010 if ( anyFound == null ) {
4011 Sizzle.error( expr );
4012
4013 } else {
4014 break;
4015 }
4016 }
4017
4018 old = expr;
4019 }
4020
4021 return curLoop;
4022 };
4023
4024 Sizzle.error = function( msg ) {
4025 throw "Syntax error, unrecognized expression: " + msg;
4026 };
4027
4028 var Expr = Sizzle.selectors = {
4029 order: [ "ID", "NAME", "TAG" ],
4030
4031 match: {
4032 ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
4033 CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
4034 NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,
4035 ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,
4036 TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,
4037 CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,
4038 POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,
4039 PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/
4040 },
4041
4042 leftMatch: {},
4043
4044 attrMap: {
4045 "class": "className",
4046 "for": "htmlFor"
4047 },
4048
4049 attrHandle: {
4050 href: function( elem ) {
4051 return elem.getAttribute( "href" );
4052 },
4053 type: function( elem ) {
4054 return elem.getAttribute( "type" );
4055 }
4056 },
4057
4058 relative: {
4059 "+": function(checkSet, part){
4060 var isPartStr = typeof part === "string",
4061 isTag = isPartStr && !rNonWord.test( part ),
4062 isPartStrNotTag = isPartStr && !isTag;
4063
4064 if ( isTag ) {
4065 part = part.toLowerCase();
4066 }
4067
4068 for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
4069 if ( (elem = checkSet[i]) ) {
4070 while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
4071
4072 checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?
4073 elem || false :
4074 elem === part;
4075 }
4076 }
4077
4078 if ( isPartStrNotTag ) {
4079 Sizzle.filter( part, checkSet, true );
4080 }
4081 },
4082
4083 ">": function( checkSet, part ) {
4084 var elem,
4085 isPartStr = typeof part === "string",
4086 i = 0,
4087 l = checkSet.length;
4088
4089 if ( isPartStr && !rNonWord.test( part ) ) {
4090 part = part.toLowerCase();
4091
4092 for ( ; i < l; i++ ) {
4093 elem = checkSet[i];
4094
4095 if ( elem ) {
4096 var parent = elem.parentNode;
4097 checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;
4098 }
4099 }
4100
4101 } else {
4102 for ( ; i < l; i++ ) {
4103 elem = checkSet[i];
4104
4105 if ( elem ) {
4106 checkSet[i] = isPartStr ?
4107 elem.parentNode :
4108 elem.parentNode === part;
4109 }
4110 }
4111
4112 if ( isPartStr ) {
4113 Sizzle.filter( part, checkSet, true );
4114 }
4115 }
4116 },
4117
4118 "": function(checkSet, part, isXML){
4119 var nodeCheck,
4120 doneName = done++,
4121 checkFn = dirCheck;
4122
4123 if ( typeof part === "string" && !rNonWord.test( part ) ) {
4124 part = part.toLowerCase();
4125 nodeCheck = part;
4126 checkFn = dirNodeCheck;
4127 }
4128
4129 checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML );
4130 },
4131
4132 "~": function( checkSet, part, isXML ) {
4133 var nodeCheck,
4134 doneName = done++,
4135 checkFn = dirCheck;
4136
4137 if ( typeof part === "string" && !rNonWord.test( part ) ) {
4138 part = part.toLowerCase();
4139 nodeCheck = part;
4140 checkFn = dirNodeCheck;
4141 }
4142
4143 checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML );
4144 }
4145 },
4146
4147 find: {
4148 ID: function( match, context, isXML ) {
4149 if ( typeof context.getElementById !== "undefined" && !isXML ) {
4150 var m = context.getElementById(match[1]);
4151 // Check parentNode to catch when Blackberry 4.6 returns
4152 // nodes that are no longer in the document #6963
4153 return m && m.parentNode ? [m] : [];
4154 }
4155 },
4156
4157 NAME: function( match, context ) {
4158 if ( typeof context.getElementsByName !== "undefined" ) {
4159 var ret = [],
4160 results = context.getElementsByName( match[1] );
4161
4162 for ( var i = 0, l = results.length; i < l; i++ ) {
4163 if ( results[i].getAttribute("name") === match[1] ) {
4164 ret.push( results[i] );
4165 }
4166 }
4167
4168 return ret.length === 0 ? null : ret;
4169 }
4170 },
4171
4172 TAG: function( match, context ) {
4173 if ( typeof context.getElementsByTagName !== "undefined" ) {
4174 return context.getElementsByTagName( match[1] );
4175 }
4176 }
4177 },
4178 preFilter: {
4179 CLASS: function( match, curLoop, inplace, result, not, isXML ) {
4180 match = " " + match[1].replace( rBackslash, "" ) + " ";
4181
4182 if ( isXML ) {
4183 return match;
4184 }
4185
4186 for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
4187 if ( elem ) {
4188 if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) {
4189 if ( !inplace ) {
4190 result.push( elem );
4191 }
4192
4193 } else if ( inplace ) {
4194 curLoop[i] = false;
4195 }
4196 }
4197 }
4198
4199 return false;
4200 },
4201
4202 ID: function( match ) {
4203 return match[1].replace( rBackslash, "" );
4204 },
4205
4206 TAG: function( match, curLoop ) {
4207 return match[1].replace( rBackslash, "" ).toLowerCase();
4208 },
4209
4210 CHILD: function( match ) {
4211 if ( match[1] === "nth" ) {
4212 if ( !match[2] ) {
4213 Sizzle.error( match[0] );
4214 }
4215
4216 match[2] = match[2].replace(/^\+|\s*/g, '');
4217
4218 // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
4219 var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec(
4220 match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||
4221 !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
4222
4223 // calculate the numbers (first)n+(last) including if they are negative
4224 match[2] = (test[1] + (test[2] || 1)) - 0;
4225 match[3] = test[3] - 0;
4226 }
4227 else if ( match[2] ) {
4228 Sizzle.error( match[0] );
4229 }
4230
4231 // TODO: Move to normal caching system
4232 match[0] = done++;
4233
4234 return match;
4235 },
4236
4237 ATTR: function( match, curLoop, inplace, result, not, isXML ) {
4238 var name = match[1] = match[1].replace( rBackslash, "" );
4239
4240 if ( !isXML && Expr.attrMap[name] ) {
4241 match[1] = Expr.attrMap[name];
4242 }
4243
4244 // Handle if an un-quoted value was used
4245 match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" );
4246
4247 if ( match[2] === "~=" ) {
4248 match[4] = " " + match[4] + " ";
4249 }
4250
4251 return match;
4252 },
4253
4254 PSEUDO: function( match, curLoop, inplace, result, not ) {
4255 if ( match[1] === "not" ) {
4256 // If we're dealing with a complex expression, or a simple one
4257 if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
4258 match[3] = Sizzle(match[3], null, null, curLoop);
4259
4260 } else {
4261 var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
4262
4263 if ( !inplace ) {
4264 result.push.apply( result, ret );
4265 }
4266
4267 return false;
4268 }
4269
4270 } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
4271 return true;
4272 }
4273
4274 return match;
4275 },
4276
4277 POS: function( match ) {
4278 match.unshift( true );
4279
4280 return match;
4281 }
4282 },
4283
4284 filters: {
4285 enabled: function( elem ) {
4286 return elem.disabled === false && elem.type !== "hidden";
4287 },
4288
4289 disabled: function( elem ) {
4290 return elem.disabled === true;
4291 },
4292
4293 checked: function( elem ) {
4294 return elem.checked === true;
4295 },
4296
4297 selected: function( elem ) {
4298 // Accessing this property makes selected-by-default
4299 // options in Safari work properly
4300 if ( elem.parentNode ) {
4301 elem.parentNode.selectedIndex;
4302 }
4303
4304 return elem.selected === true;
4305 },
4306
4307 parent: function( elem ) {
4308 return !!elem.firstChild;
4309 },
4310
4311 empty: function( elem ) {
4312 return !elem.firstChild;
4313 },
4314
4315 has: function( elem, i, match ) {
4316 return !!Sizzle( match[3], elem ).length;
4317 },
4318
4319 header: function( elem ) {
4320 return (/h\d/i).test( elem.nodeName );
4321 },
4322
4323 text: function( elem ) {
4324 var attr = elem.getAttribute( "type" ), type = elem.type;
4325 // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)
4326 // use getAttribute instead to test this case
4327 return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null );
4328 },
4329
4330 radio: function( elem ) {
4331 return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type;
4332 },
4333
4334 checkbox: function( elem ) {
4335 return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type;
4336 },
4337
4338 file: function( elem ) {
4339 return elem.nodeName.toLowerCase() === "input" && "file" === elem.type;
4340 },
4341
4342 password: function( elem ) {
4343 return elem.nodeName.toLowerCase() === "input" && "password" === elem.type;
4344 },
4345
4346 submit: function( elem ) {
4347 var name = elem.nodeName.toLowerCase();
4348 return (name === "input" || name === "button") && "submit" === elem.type;
4349 },
4350
4351 image: function( elem ) {
4352 return elem.nodeName.toLowerCase() === "input" && "image" === elem.type;
4353 },
4354
4355 reset: function( elem ) {
4356 var name = elem.nodeName.toLowerCase();
4357 return (name === "input" || name === "button") && "reset" === elem.type;
4358 },
4359
4360 button: function( elem ) {
4361 var name = elem.nodeName.toLowerCase();
4362 return name === "input" && "button" === elem.type || name === "button";
4363 },
4364
4365 input: function( elem ) {
4366 return (/input|select|textarea|button/i).test( elem.nodeName );
4367 },
4368
4369 focus: function( elem ) {
4370 return elem === elem.ownerDocument.activeElement;
4371 }
4372 },
4373 setFilters: {
4374 first: function( elem, i ) {
4375 return i === 0;
4376 },
4377
4378 last: function( elem, i, match, array ) {
4379 return i === array.length - 1;
4380 },
4381
4382 even: function( elem, i ) {
4383 return i % 2 === 0;
4384 },
4385
4386 odd: function( elem, i ) {
4387 return i % 2 === 1;
4388 },
4389
4390 lt: function( elem, i, match ) {
4391 return i < match[3] - 0;
4392 },
4393
4394 gt: function( elem, i, match ) {
4395 return i > match[3] - 0;
4396 },
4397
4398 nth: function( elem, i, match ) {
4399 return match[3] - 0 === i;
4400 },
4401
4402 eq: function( elem, i, match ) {
4403 return match[3] - 0 === i;
4404 }
4405 },
4406 filter: {
4407 PSEUDO: function( elem, match, i, array ) {
4408 var name = match[1],
4409 filter = Expr.filters[ name ];
4410
4411 if ( filter ) {
4412 return filter( elem, i, match, array );
4413
4414 } else if ( name === "contains" ) {
4415 return (elem.textContent || elem.innerText || Sizzle.getText([ elem ]) || "").indexOf(match[3]) >= 0;
4416
4417 } else if ( name === "not" ) {
4418 var not = match[3];
4419
4420 for ( var j = 0, l = not.length; j < l; j++ ) {
4421 if ( not[j] === elem ) {
4422 return false;
4423 }
4424 }
4425
4426 return true;
4427
4428 } else {
4429 Sizzle.error( name );
4430 }
4431 },
4432
4433 CHILD: function( elem, match ) {
4434 var type = match[1],
4435 node = elem;
4436
4437 switch ( type ) {
4438 case "only":
4439 case "first":
4440 while ( (node = node.previousSibling) ) {
4441 if ( node.nodeType === 1 ) {
4442 return false;
4443 }
4444 }
4445
4446 if ( type === "first" ) {
4447 return true;
4448 }
4449
4450 node = elem;
4451
4452 case "last":
4453 while ( (node = node.nextSibling) ) {
4454 if ( node.nodeType === 1 ) {
4455 return false;
4456 }
4457 }
4458
4459 return true;
4460
4461 case "nth":
4462 var first = match[2],
4463 last = match[3];
4464
4465 if ( first === 1 && last === 0 ) {
4466 return true;
4467 }
4468
4469 var doneName = match[0],
4470 parent = elem.parentNode;
4471
4472 if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
4473 var count = 0;
4474
4475 for ( node = parent.firstChild; node; node = node.nextSibling ) {
4476 if ( node.nodeType === 1 ) {
4477 node.nodeIndex = ++count;
4478 }
4479 }
4480
4481 parent.sizcache = doneName;
4482 }
4483
4484 var diff = elem.nodeIndex - last;
4485
4486 if ( first === 0 ) {
4487 return diff === 0;
4488
4489 } else {
4490 return ( diff % first === 0 && diff / first >= 0 );
4491 }
4492 }
4493 },
4494
4495 ID: function( elem, match ) {
4496 return elem.nodeType === 1 && elem.getAttribute("id") === match;
4497 },
4498
4499 TAG: function( elem, match ) {
4500 return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match;
4501 },
4502
4503 CLASS: function( elem, match ) {
4504 return (" " + (elem.className || elem.getAttribute("class")) + " ")
4505 .indexOf( match ) > -1;
4506 },
4507
4508 ATTR: function( elem, match ) {
4509 var name = match[1],
4510 result = Expr.attrHandle[ name ] ?
4511 Expr.attrHandle[ name ]( elem ) :
4512 elem[ name ] != null ?
4513 elem[ name ] :
4514 elem.getAttribute( name ),
4515 value = result + "",
4516 type = match[2],
4517 check = match[4];
4518
4519 return result == null ?
4520 type === "!=" :
4521 type === "=" ?
4522 value === check :
4523 type === "*=" ?
4524 value.indexOf(check) >= 0 :
4525 type === "~=" ?
4526 (" " + value + " ").indexOf(check) >= 0 :
4527 !check ?
4528 value && result !== false :
4529 type === "!=" ?
4530 value !== check :
4531 type === "^=" ?
4532 value.indexOf(check) === 0 :
4533 type === "$=" ?
4534 value.substr(value.length - check.length) === check :
4535 type === "|=" ?
4536 value === check || value.substr(0, check.length + 1) === check + "-" :
4537 false;
4538 },
4539
4540 POS: function( elem, match, i, array ) {
4541 var name = match[2],
4542 filter = Expr.setFilters[ name ];
4543
4544 if ( filter ) {
4545 return filter( elem, i, match, array );
4546 }
4547 }
4548 }
4549 };
4550
4551 var origPOS = Expr.match.POS,
4552 fescape = function(all, num){
4553 return "\\" + (num - 0 + 1);
4554 };
4555
4556 for ( var type in Expr.match ) {
4557 Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) );
4558 Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) );
4559 }
4560
4561 var makeArray = function( array, results ) {
4562 array = Array.prototype.slice.call( array, 0 );
4563
4564 if ( results ) {
4565 results.push.apply( results, array );
4566 return results;
4567 }
4568
4569 return array;
4570 };
4571
4572 // Perform a simple check to determine if the browser is capable of
4573 // converting a NodeList to an array using builtin methods.
4574 // Also verifies that the returned array holds DOM nodes
4575 // (which is not the case in the Blackberry browser)
4576 try {
4577 Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType;
4578
4579 // Provide a fallback method if it does not work
4580 } catch( e ) {
4581 makeArray = function( array, results ) {
4582 var i = 0,
4583 ret = results || [];
4584
4585 if ( toString.call(array) === "[object Array]" ) {
4586 Array.prototype.push.apply( ret, array );
4587
4588 } else {
4589 if ( typeof array.length === "number" ) {
4590 for ( var l = array.length; i < l; i++ ) {
4591 ret.push( array[i] );
4592 }
4593
4594 } else {
4595 for ( ; array[i]; i++ ) {
4596 ret.push( array[i] );
4597 }
4598 }
4599 }
4600
4601 return ret;
4602 };
4603 }
4604
4605 var sortOrder, siblingCheck;
4606
4607 if ( document.documentElement.compareDocumentPosition ) {
4608 sortOrder = function( a, b ) {
4609 if ( a === b ) {
4610 hasDuplicate = true;
4611 return 0;
4612 }
4613
4614 if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
4615 return a.compareDocumentPosition ? -1 : 1;
4616 }
4617
4618 return a.compareDocumentPosition(b) & 4 ? -1 : 1;
4619 };
4620
4621 } else {
4622 sortOrder = function( a, b ) {
4623 // The nodes are identical, we can exit early
4624 if ( a === b ) {
4625 hasDuplicate = true;
4626 return 0;
4627
4628 // Fallback to using sourceIndex (in IE) if it's available on both nodes
4629 } else if ( a.sourceIndex && b.sourceIndex ) {
4630 return a.sourceIndex - b.sourceIndex;
4631 }
4632
4633 var al, bl,
4634 ap = [],
4635 bp = [],
4636 aup = a.parentNode,
4637 bup = b.parentNode,
4638 cur = aup;
4639
4640 // If the nodes are siblings (or identical) we can do a quick check
4641 if ( aup === bup ) {
4642 return siblingCheck( a, b );
4643
4644 // If no parents were found then the nodes are disconnected
4645 } else if ( !aup ) {
4646 return -1;
4647
4648 } else if ( !bup ) {
4649 return 1;
4650 }
4651
4652 // Otherwise they're somewhere else in the tree so we need
4653 // to build up a full list of the parentNodes for comparison
4654 while ( cur ) {
4655 ap.unshift( cur );
4656 cur = cur.parentNode;
4657 }
4658
4659 cur = bup;
4660
4661 while ( cur ) {
4662 bp.unshift( cur );
4663 cur = cur.parentNode;
4664 }
4665
4666 al = ap.length;
4667 bl = bp.length;
4668
4669 // Start walking down the tree looking for a discrepancy
4670 for ( var i = 0; i < al && i < bl; i++ ) {
4671 if ( ap[i] !== bp[i] ) {
4672 return siblingCheck( ap[i], bp[i] );
4673 }
4674 }
4675
4676 // We ended someplace up the tree so do a sibling check
4677 return i === al ?
4678 siblingCheck( a, bp[i], -1 ) :
4679 siblingCheck( ap[i], b, 1 );
4680 };
4681
4682 siblingCheck = function( a, b, ret ) {
4683 if ( a === b ) {
4684 return ret;
4685 }
4686
4687 var cur = a.nextSibling;
4688
4689 while ( cur ) {
4690 if ( cur === b ) {
4691 return -1;
4692 }
4693
4694 cur = cur.nextSibling;
4695 }
4696
4697 return 1;
4698 };
4699 }
4700
4701 // Utility function for retreiving the text value of an array of DOM nodes
4702 Sizzle.getText = function( elems ) {
4703 var ret = "", elem;
4704
4705 for ( var i = 0; elems[i]; i++ ) {
4706 elem = elems[i];
4707
4708 // Get the text from text nodes and CDATA nodes
4709 if ( elem.nodeType === 3 || elem.nodeType === 4 ) {
4710 ret += elem.nodeValue;
4711
4712 // Traverse everything else, except comment nodes
4713 } else if ( elem.nodeType !== 8 ) {
4714 ret += Sizzle.getText( elem.childNodes );
4715 }
4716 }
4717
4718 return ret;
4719 };
4720
4721 // Check to see if the browser returns elements by name when
4722 // querying by getElementById (and provide a workaround)
4723 (function(){
4724 // We're going to inject a fake input element with a specified name
4725 var form = document.createElement("div"),
4726 id = "script" + (new Date()).getTime(),
4727 root = document.documentElement;
4728
4729 form.innerHTML = "<a name='" + id + "'/>";
4730
4731 // Inject it into the root element, check its status, and remove it quickly
4732 root.insertBefore( form, root.firstChild );
4733
4734 // The workaround has to do additional checks after a getElementById
4735 // Which slows things down for other browsers (hence the branching)
4736 if ( document.getElementById( id ) ) {
4737 Expr.find.ID = function( match, context, isXML ) {
4738 if ( typeof context.getElementById !== "undefined" && !isXML ) {
4739 var m = context.getElementById(match[1]);
4740
4741 return m ?
4742 m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ?
4743 [m] :
4744 undefined :
4745 [];
4746 }
4747 };
4748
4749 Expr.filter.ID = function( elem, match ) {
4750 var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
4751
4752 return elem.nodeType === 1 && node && node.nodeValue === match;
4753 };
4754 }
4755
4756 root.removeChild( form );
4757
4758 // release memory in IE
4759 root = form = null;
4760 })();
4761
4762 (function(){
4763 // Check to see if the browser returns only elements
4764 // when doing getElementsByTagName("*")
4765
4766 // Create a fake element
4767 var div = document.createElement("div");
4768 div.appendChild( document.createComment("") );
4769
4770 // Make sure no comments are found
4771 if ( div.getElementsByTagName("*").length > 0 ) {
4772 Expr.find.TAG = function( match, context ) {
4773 var results = context.getElementsByTagName( match[1] );
4774
4775 // Filter out possible comments
4776 if ( match[1] === "*" ) {
4777 var tmp = [];
4778
4779 for ( var i = 0; results[i]; i++ ) {
4780 if ( results[i].nodeType === 1 ) {
4781 tmp.push( results[i] );
4782 }
4783 }
4784
4785 results = tmp;
4786 }
4787
4788 return results;
4789 };
4790 }
4791
4792 // Check to see if an attribute returns normalized href attributes
4793 div.innerHTML = "<a href='#'></a>";
4794
4795 if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
4796 div.firstChild.getAttribute("href") !== "#" ) {
4797
4798 Expr.attrHandle.href = function( elem ) {
4799 return elem.getAttribute( "href", 2 );
4800 };
4801 }
4802
4803 // release memory in IE
4804 div = null;
4805 })();
4806
4807 if ( document.querySelectorAll ) {
4808 (function(){
4809 var oldSizzle = Sizzle,
4810 div = document.createElement("div"),
4811 id = "__sizzle__";
4812
4813 div.innerHTML = "<p class='TEST'></p>";
4814
4815 // Safari can't handle uppercase or unicode characters when
4816 // in quirks mode.
4817 if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
4818 return;
4819 }
4820
4821 Sizzle = function( query, context, extra, seed ) {
4822 context = context || document;
4823
4824 // Only use querySelectorAll on non-XML documents
4825 // (ID selectors don't work in non-HTML documents)
4826 if ( !seed && !Sizzle.isXML(context) ) {
4827 // See if we find a selector to speed up
4828 var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query );
4829
4830 if ( match && (context.nodeType === 1 || context.nodeType === 9) ) {
4831 // Speed-up: Sizzle("TAG")
4832 if ( match[1] ) {
4833 return makeArray( context.getElementsByTagName( query ), extra );
4834
4835 // Speed-up: Sizzle(".CLASS")
4836 } else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) {
4837 return makeArray( context.getElementsByClassName( match[2] ), extra );
4838 }
4839 }
4840
4841 if ( context.nodeType === 9 ) {
4842 // Speed-up: Sizzle("body")
4843 // The body element only exists once, optimize finding it
4844 if ( query === "body" && context.body ) {
4845 return makeArray( [ context.body ], extra );
4846
4847 // Speed-up: Sizzle("#ID")
4848 } else if ( match && match[3] ) {
4849 var elem = context.getElementById( match[3] );
4850
4851 // Check parentNode to catch when Blackberry 4.6 returns
4852 // nodes that are no longer in the document #6963
4853 if ( elem && elem.parentNode ) {
4854 // Handle the case where IE and Opera return items
4855 // by name instead of ID
4856 if ( elem.id === match[3] ) {
4857 return makeArray( [ elem ], extra );
4858 }
4859
4860 } else {
4861 return makeArray( [], extra );
4862 }
4863 }
4864
4865 try {
4866 return makeArray( context.querySelectorAll(query), extra );
4867 } catch(qsaError) {}
4868
4869 // qSA works strangely on Element-rooted queries
4870 // We can work around this by specifying an extra ID on the root
4871 // and working up from there (Thanks to Andrew Dupont for the technique)
4872 // IE 8 doesn't work on object elements
4873 } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
4874 var oldContext = context,
4875 old = context.getAttribute( "id" ),
4876 nid = old || id,
4877 hasParent = context.parentNode,
4878 relativeHierarchySelector = /^\s*[+~]/.test( query );
4879
4880 if ( !old ) {
4881 context.setAttribute( "id", nid );
4882 } else {
4883 nid = nid.replace( /'/g, "\\$&" );
4884 }
4885 if ( relativeHierarchySelector && hasParent ) {
4886 context = context.parentNode;
4887 }
4888
4889 try {
4890 if ( !relativeHierarchySelector || hasParent ) {
4891 return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra );
4892 }
4893
4894 } catch(pseudoError) {
4895 } finally {
4896 if ( !old ) {
4897 oldContext.removeAttribute( "id" );
4898 }
4899 }
4900 }
4901 }
4902
4903 return oldSizzle(query, context, extra, seed);
4904 };
4905
4906 for ( var prop in oldSizzle ) {
4907 Sizzle[ prop ] = oldSizzle[ prop ];
4908 }
4909
4910 // release memory in IE
4911 div = null;
4912 })();
4913 }
4914
4915 (function(){
4916 var html = document.documentElement,
4917 matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector;
4918
4919 if ( matches ) {
4920 // Check to see if it's possible to do matchesSelector
4921 // on a disconnected node (IE 9 fails this)
4922 var disconnectedMatch = !matches.call( document.createElement( "div" ), "div" ),
4923 pseudoWorks = false;
4924
4925 try {
4926 // This should fail with an exception
4927 // Gecko does not error, returns false instead
4928 matches.call( document.documentElement, "[test!='']:sizzle" );
4929
4930 } catch( pseudoError ) {
4931 pseudoWorks = true;
4932 }
4933
4934 Sizzle.matchesSelector = function( node, expr ) {
4935 // Make sure that attribute selectors are quoted
4936 expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']");
4937
4938 if ( !Sizzle.isXML( node ) ) {
4939 try {
4940 if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) {
4941 var ret = matches.call( node, expr );
4942
4943 // IE 9's matchesSelector returns false on disconnected nodes
4944 if ( ret || !disconnectedMatch ||
4945 // As well, disconnected nodes are said to be in a document
4946 // fragment in IE 9, so check for that
4947 node.document && node.document.nodeType !== 11 ) {
4948 return ret;
4949 }
4950 }
4951 } catch(e) {}
4952 }
4953
4954 return Sizzle(expr, null, null, [node]).length > 0;
4955 };
4956 }
4957 })();
4958
4959 (function(){
4960 var div = document.createElement("div");
4961
4962 div.innerHTML = "<div class='test e'></div><div class='test'></div>";
4963
4964 // Opera can't find a second classname (in 9.6)
4965 // Also, make sure that getElementsByClassName actually exists
4966 if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) {
4967 return;
4968 }
4969
4970 // Safari caches class attributes, doesn't catch changes (in 3.2)
4971 div.lastChild.className = "e";
4972
4973 if ( div.getElementsByClassName("e").length === 1 ) {
4974 return;
4975 }
4976
4977 Expr.order.splice(1, 0, "CLASS");
4978 Expr.find.CLASS = function( match, context, isXML ) {
4979 if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
4980 return context.getElementsByClassName(match[1]);
4981 }
4982 };
4983
4984 // release memory in IE
4985 div = null;
4986 })();
4987
4988 function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
4989 for ( var i = 0, l = checkSet.length; i < l; i++ ) {
4990 var elem = checkSet[i];
4991
4992 if ( elem ) {
4993 var match = false;
4994
4995 elem = elem[dir];
4996
4997 while ( elem ) {
4998 if ( elem.sizcache === doneName ) {
4999 match = checkSet[elem.sizset];
5000 break;
5001 }
5002
5003 if ( elem.nodeType === 1 && !isXML ){
5004 elem.sizcache = doneName;
5005 elem.sizset = i;
5006 }
5007
5008 if ( elem.nodeName.toLowerCase() === cur ) {
5009 match = elem;
5010 break;
5011 }
5012
5013 elem = elem[dir];
5014 }
5015
5016 checkSet[i] = match;
5017 }
5018 }
5019 }
5020
5021 function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
5022 for ( var i = 0, l = checkSet.length; i < l; i++ ) {
5023 var elem = checkSet[i];
5024
5025 if ( elem ) {
5026 var match = false;
5027
5028 elem = elem[dir];
5029
5030 while ( elem ) {
5031 if ( elem.sizcache === doneName ) {
5032 match = checkSet[elem.sizset];
5033 break;
5034 }
5035
5036 if ( elem.nodeType === 1 ) {
5037 if ( !isXML ) {
5038 elem.sizcache = doneName;
5039 elem.sizset = i;
5040 }
5041
5042 if ( typeof cur !== "string" ) {
5043 if ( elem === cur ) {
5044 match = true;
5045 break;
5046 }
5047
5048 } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
5049 match = elem;
5050 break;
5051 }
5052 }
5053
5054 elem = elem[dir];
5055 }
5056
5057 checkSet[i] = match;
5058 }
5059 }
5060 }
5061
5062 if ( document.documentElement.contains ) {
5063 Sizzle.contains = function( a, b ) {
5064 return a !== b && (a.contains ? a.contains(b) : true);
5065 };
5066
5067 } else if ( document.documentElement.compareDocumentPosition ) {
5068 Sizzle.contains = function( a, b ) {
5069 return !!(a.compareDocumentPosition(b) & 16);
5070 };
5071
5072 } else {
5073 Sizzle.contains = function() {
5074 return false;
5075 };
5076 }
5077
5078 Sizzle.isXML = function( elem ) {
5079 // documentElement is verified for cases where it doesn't yet exist
5080 // (such as loading iframes in IE - #4833)
5081 var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
5082
5083 return documentElement ? documentElement.nodeName !== "HTML" : false;
5084 };
5085
5086 var posProcess = function( selector, context ) {
5087 var match,
5088 tmpSet = [],
5089 later = "",
5090 root = context.nodeType ? [context] : context;
5091
5092 // Position selectors must be done after the filter
5093 // And so must :not(positional) so we move all PSEUDOs to the end
5094 while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
5095 later += match[0];
5096 selector = selector.replace( Expr.match.PSEUDO, "" );
5097 }
5098
5099 selector = Expr.relative[selector] ? selector + "*" : selector;
5100
5101 for ( var i = 0, l = root.length; i < l; i++ ) {
5102 Sizzle( selector, root[i], tmpSet );
5103 }
5104
5105 return Sizzle.filter( later, tmpSet );
5106 };
5107
5108 // EXPOSE
5109 jQuery.find = Sizzle;
5110 jQuery.expr = Sizzle.selectors;
5111 jQuery.expr[":"] = jQuery.expr.filters;
5112 jQuery.unique = Sizzle.uniqueSort;
5113 jQuery.text = Sizzle.getText;
5114 jQuery.isXMLDoc = Sizzle.isXML;
5115 jQuery.contains = Sizzle.contains;
5116
5117
5118 })();
5119
5120
5121 var runtil = /Until$/,
5122 rparentsprev = /^(?:parents|prevUntil|prevAll)/,
5123 // Note: This RegExp should be improved, or likely pulled from Sizzle
5124 rmultiselector = /,/,
5125 isSimple = /^.[^:#\[\.,]*$/,
5126 slice = Array.prototype.slice,
5127 POS = jQuery.expr.match.POS,
5128 // methods guaranteed to produce a unique set when starting from a unique set
5129 guaranteedUnique = {
5130 children: true,
5131 contents: true,
5132 next: true,
5133 prev: true
5134 };
5135
5136 jQuery.fn.extend({
5137 find: function( selector ) {
5138 var self = this,
5139 i, l;
5140
5141 if ( typeof selector !== "string" ) {
5142 return jQuery( selector ).filter(function() {
5143 for ( i = 0, l = self.length; i < l; i++ ) {
5144 if ( jQuery.contains( self[ i ], this ) ) {
5145 return true;
5146 }
5147 }
5148 });
5149 }
5150
5151 var ret = this.pushStack( "", "find", selector ),
5152 length, n, r;
5153
5154 for ( i = 0, l = this.length; i < l; i++ ) {
5155 length = ret.length;
5156 jQuery.find( selector, this[i], ret );
5157
5158 if ( i > 0 ) {
5159 // Make sure that the results are unique
5160 for ( n = length; n < ret.length; n++ ) {
5161 for ( r = 0; r < length; r++ ) {
5162 if ( ret[r] === ret[n] ) {
5163 ret.splice(n--, 1);
5164 break;
5165 }
5166 }
5167 }
5168 }
5169 }
5170
5171 return ret;
5172 },
5173
5174 has: function( target ) {
5175 var targets = jQuery( target );
5176 return this.filter(function() {
5177 for ( var i = 0, l = targets.length; i < l; i++ ) {
5178 if ( jQuery.contains( this, targets[i] ) ) {
5179 return true;
5180 }
5181 }
5182 });
5183 },
5184
5185 not: function( selector ) {
5186 return this.pushStack( winnow(this, selector, false), "not", selector);
5187 },
5188
5189 filter: function( selector ) {
5190 return this.pushStack( winnow(this, selector, true), "filter", selector );
5191 },
5192
5193 is: function( selector ) {
5194 return !!selector && ( typeof selector === "string" ?
5195 jQuery.filter( selector, this ).length > 0 :
5196 this.filter( selector ).length > 0 );
5197 },
5198
5199 closest: function( selectors, context ) {
5200 var ret = [], i, l, cur = this[0];
5201
5202 // Array
5203 if ( jQuery.isArray( selectors ) ) {
5204 var match, selector,
5205 matches = {},
5206 level = 1;
5207
5208 if ( cur && selectors.length ) {
5209 for ( i = 0, l = selectors.length; i < l; i++ ) {
5210 selector = selectors[i];
5211
5212 if ( !matches[ selector ] ) {
5213 matches[ selector ] = POS.test( selector ) ?
5214 jQuery( selector, context || this.context ) :
5215 selector;
5216 }
5217 }
5218
5219 while ( cur && cur.ownerDocument && cur !== context ) {
5220 for ( selector in matches ) {
5221 match = matches[ selector ];
5222
5223 if ( match.jquery ? match.index( cur ) > -1 : jQuery( cur ).is( match ) ) {
5224 ret.push({ selector: selector, elem: cur, level: level });
5225 }
5226 }
5227
5228 cur = cur.parentNode;
5229 level++;
5230 }
5231 }
5232
5233 return ret;
5234 }
5235
5236 // String
5237 var pos = POS.test( selectors ) || typeof selectors !== "string" ?
5238 jQuery( selectors, context || this.context ) :
5239 0;
5240
5241 for ( i = 0, l = this.length; i < l; i++ ) {
5242 cur = this[i];
5243
5244 while ( cur ) {
5245 if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {
5246 ret.push( cur );
5247 break;
5248
5249 } else {
5250 cur = cur.parentNode;
5251 if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) {
5252 break;
5253 }
5254 }
5255 }
5256 }
5257
5258 ret = ret.length > 1 ? jQuery.unique( ret ) : ret;
5259
5260 return this.pushStack( ret, "closest", selectors );
5261 },
5262
5263 // Determine the position of an element within
5264 // the matched set of elements
5265 index: function( elem ) {
5266 if ( !elem || typeof elem === "string" ) {
5267 return jQuery.inArray( this[0],
5268 // If it receives a string, the selector is used
5269 // If it receives nothing, the siblings are used
5270 elem ? jQuery( elem ) : this.parent().children() );
5271 }
5272 // Locate the position of the desired element
5273 return jQuery.inArray(
5274 // If it receives a jQuery object, the first element is used
5275 elem.jquery ? elem[0] : elem, this );
5276 },
5277
5278 add: function( selector, context ) {
5279 var set = typeof selector === "string" ?
5280 jQuery( selector, context ) :
5281 jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ),
5282 all = jQuery.merge( this.get(), set );
5283
5284 return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?
5285 all :
5286 jQuery.unique( all ) );
5287 },
5288
5289 andSelf: function() {
5290 return this.add( this.prevObject );
5291 }
5292 });
5293
5294 // A painfully simple check to see if an element is disconnected
5295 // from a document (should be improved, where feasible).
5296 function isDisconnected( node ) {
5297 return !node || !node.parentNode || node.parentNode.nodeType === 11;
5298 }
5299
5300 jQuery.each({
5301 parent: function( elem ) {
5302 var parent = elem.parentNode;
5303 return parent && parent.nodeType !== 11 ? parent : null;
5304 },
5305 parents: function( elem ) {
5306 return jQuery.dir( elem, "parentNode" );
5307 },
5308 parentsUntil: function( elem, i, until ) {
5309 return jQuery.dir( elem, "parentNode", until );
5310 },
5311 next: function( elem ) {
5312 return jQuery.nth( elem, 2, "nextSibling" );
5313 },
5314 prev: function( elem ) {
5315 return jQuery.nth( elem, 2, "previousSibling" );
5316 },
5317 nextAll: function( elem ) {
5318 return jQuery.dir( elem, "nextSibling" );
5319 },
5320 prevAll: function( elem ) {
5321 return jQuery.dir( elem, "previousSibling" );
5322 },
5323 nextUntil: function( elem, i, until ) {
5324 return jQuery.dir( elem, "nextSibling", until );
5325 },
5326 prevUntil: function( elem, i, until ) {
5327 return jQuery.dir( elem, "previousSibling", until );
5328 },
5329 siblings: function( elem ) {
5330 return jQuery.sibling( elem.parentNode.firstChild, elem );
5331 },
5332 children: function( elem ) {
5333 return jQuery.sibling( elem.firstChild );
5334 },
5335 contents: function( elem ) {
5336 return jQuery.nodeName( elem, "iframe" ) ?
5337 elem.contentDocument || elem.contentWindow.document :
5338 jQuery.makeArray( elem.childNodes );
5339 }
5340 }, function( name, fn ) {
5341 jQuery.fn[ name ] = function( until, selector ) {
5342 var ret = jQuery.map( this, fn, until ),
5343 // The variable 'args' was introduced in
5344 // https://github.com/jquery/jquery/commit/52a0238
5345 // to work around a bug in Chrome 10 (Dev) and should be removed when the bug is fixed.
5346 // http://code.google.com/p/v8/issues/detail?id=1050
5347 args = slice.call(arguments);
5348
5349 if ( !runtil.test( name ) ) {
5350 selector = until;
5351 }
5352
5353 if ( selector && typeof selector === "string" ) {
5354 ret = jQuery.filter( selector, ret );
5355 }
5356
5357 ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret;
5358
5359 if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) {
5360 ret = ret.reverse();
5361 }
5362
5363 return this.pushStack( ret, name, args.join(",") );
5364 };
5365 });
5366
5367 jQuery.extend({
5368 filter: function( expr, elems, not ) {
5369 if ( not ) {
5370 expr = ":not(" + expr + ")";
5371 }
5372
5373 return elems.length === 1 ?
5374 jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :
5375 jQuery.find.matches(expr, elems);
5376 },
5377
5378 dir: function( elem, dir, until ) {
5379 var matched = [],
5380 cur = elem[ dir ];
5381
5382 while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
5383 if ( cur.nodeType === 1 ) {
5384 matched.push( cur );
5385 }
5386 cur = cur[dir];
5387 }
5388 return matched;
5389 },
5390
5391 nth: function( cur, result, dir, elem ) {
5392 result = result || 1;
5393 var num = 0;
5394
5395 for ( ; cur; cur = cur[dir] ) {
5396 if ( cur.nodeType === 1 && ++num === result ) {
5397 break;
5398 }
5399 }
5400
5401 return cur;
5402 },
5403
5404 sibling: function( n, elem ) {
5405 var r = [];
5406
5407 for ( ; n; n = n.nextSibling ) {
5408 if ( n.nodeType === 1 && n !== elem ) {
5409 r.push( n );
5410 }
5411 }
5412
5413 return r;
5414 }
5415 });
5416
5417 // Implement the identical functionality for filter and not
5418 function winnow( elements, qualifier, keep ) {
5419
5420 // Can't pass null or undefined to indexOf in Firefox 4
5421 // Set to 0 to skip string check
5422 qualifier = qualifier || 0;
5423
5424 if ( jQuery.isFunction( qualifier ) ) {
5425 return jQuery.grep(elements, function( elem, i ) {
5426 var retVal = !!qualifier.call( elem, i, elem );
5427 return retVal === keep;
5428 });
5429
5430 } else if ( qualifier.nodeType ) {
5431 return jQuery.grep(elements, function( elem, i ) {
5432 return (elem === qualifier) === keep;
5433 });
5434
5435 } else if ( typeof qualifier === "string" ) {
5436 var filtered = jQuery.grep(elements, function( elem ) {
5437 return elem.nodeType === 1;
5438 });
5439
5440 if ( isSimple.test( qualifier ) ) {
5441 return jQuery.filter(qualifier, filtered, !keep);
5442 } else {
5443 qualifier = jQuery.filter( qualifier, filtered );
5444 }
5445 }
5446
5447 return jQuery.grep(elements, function( elem, i ) {
5448 return (jQuery.inArray( elem, qualifier ) >= 0) === keep;
5449 });
5450 }
5451
5452
5453
5454
5455 var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g,
5456 rleadingWhitespace = /^\s+/,
5457 rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,
5458 rtagName = /<([\w:]+)/,
5459 rtbody = /<tbody/i,
5460 rhtml = /<|&#?\w+;/,
5461 rnocache = /<(?:script|object|embed|option|style)/i,
5462 // checked="checked" or checked
5463 rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
5464 rscriptType = /\/(java|ecma)script/i,
5465 rcleanScript = /^\s*<!(?:\[CDATA\[|\-\-)/,
5466 wrapMap = {
5467 option: [ 1, "<select multiple='multiple'>", "</select>" ],
5468 legend: [ 1, "<fieldset>", "</fieldset>" ],
5469 thead: [ 1, "<table>", "</table>" ],
5470 tr: [ 2, "<table><tbody>", "</tbody></table>" ],
5471 td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
5472 col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
5473 area: [ 1, "<map>", "</map>" ],
5474 _default: [ 0, "", "" ]
5475 };
5476
5477 wrapMap.optgroup = wrapMap.option;
5478 wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
5479 wrapMap.th = wrapMap.td;
5480
5481 // IE can't serialize <link> and <script> tags normally
5482 if ( !jQuery.support.htmlSerialize ) {
5483 wrapMap._default = [ 1, "div<div>", "</div>" ];
5484 }
5485
5486 jQuery.fn.extend({
5487 text: function( text ) {
5488 if ( jQuery.isFunction(text) ) {
5489 return this.each(function(i) {
5490 var self = jQuery( this );
5491
5492 self.text( text.call(this, i, self.text()) );
5493 });
5494 }
5495
5496 if ( typeof text !== "object" && text !== undefined ) {
5497 return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
5498 }
5499
5500 return jQuery.text( this );
5501 },
5502
5503 wrapAll: function( html ) {
5504 if ( jQuery.isFunction( html ) ) {
5505 return this.each(function(i) {
5506 jQuery(this).wrapAll( html.call(this, i) );
5507 });
5508 }
5509
5510 if ( this[0] ) {
5511 // The elements to wrap the target around
5512 var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
5513
5514 if ( this[0].parentNode ) {
5515 wrap.insertBefore( this[0] );
5516 }
5517
5518 wrap.map(function() {
5519 var elem = this;
5520
5521 while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
5522 elem = elem.firstChild;
5523 }
5524
5525 return elem;
5526 }).append( this );
5527 }
5528
5529 return this;
5530 },
5531
5532 wrapInner: function( html ) {
5533 if ( jQuery.isFunction( html ) ) {
5534 return this.each(function(i) {
5535 jQuery(this).wrapInner( html.call(this, i) );
5536 });
5537 }
5538
5539 return this.each(function() {
5540 var self = jQuery( this ),
5541 contents = self.contents();
5542
5543 if ( contents.length ) {
5544 contents.wrapAll( html );
5545
5546 } else {
5547 self.append( html );
5548 }
5549 });
5550 },
5551
5552 wrap: function( html ) {
5553 return this.each(function() {
5554 jQuery( this ).wrapAll( html );
5555 });
5556 },
5557
5558 unwrap: function() {
5559 return this.parent().each(function() {
5560 if ( !jQuery.nodeName( this, "body" ) ) {
5561 jQuery( this ).replaceWith( this.childNodes );
5562 }
5563 }).end();
5564 },
5565
5566 append: function() {
5567 return this.domManip(arguments, true, function( elem ) {
5568 if ( this.nodeType === 1 ) {
5569 this.appendChild( elem );
5570 }
5571 });
5572 },
5573
5574 prepend: function() {
5575 return this.domManip(arguments, true, function( elem ) {
5576 if ( this.nodeType === 1 ) {
5577 this.insertBefore( elem, this.firstChild );
5578 }
5579 });
5580 },
5581
5582 before: function() {
5583 if ( this[0] && this[0].parentNode ) {
5584 return this.domManip(arguments, false, function( elem ) {
5585 this.parentNode.insertBefore( elem, this );
5586 });
5587 } else if ( arguments.length ) {
5588 var set = jQuery(arguments[0]);
5589 set.push.apply( set, this.toArray() );
5590 return this.pushStack( set, "before", arguments );
5591 }
5592 },
5593
5594 after: function() {
5595 if ( this[0] && this[0].parentNode ) {
5596 return this.domManip(arguments, false, function( elem ) {
5597 this.parentNode.insertBefore( elem, this.nextSibling );
5598 });
5599 } else if ( arguments.length ) {
5600 var set = this.pushStack( this, "after", arguments );
5601 set.push.apply( set, jQuery(arguments[0]).toArray() );
5602 return set;
5603 }
5604 },
5605
5606 // keepData is for internal use only--do not document
5607 remove: function( selector, keepData ) {
5608 for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
5609 if ( !selector || jQuery.filter( selector, [ elem ] ).length ) {
5610 if ( !keepData && elem.nodeType === 1 ) {
5611 jQuery.cleanData( elem.getElementsByTagName("*") );
5612 jQuery.cleanData( [ elem ] );
5613 }
5614
5615 if ( elem.parentNode ) {
5616 elem.parentNode.removeChild( elem );
5617 }
5618 }
5619 }
5620
5621 return this;
5622 },
5623
5624 empty: function() {
5625 for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
5626 // Remove element nodes and prevent memory leaks
5627 if ( elem.nodeType === 1 ) {
5628 jQuery.cleanData( elem.getElementsByTagName("*") );
5629 }
5630
5631 // Remove any remaining nodes
5632 while ( elem.firstChild ) {
5633 elem.removeChild( elem.firstChild );
5634 }
5635 }
5636
5637 return this;
5638 },
5639
5640 clone: function( dataAndEvents, deepDataAndEvents ) {
5641 dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
5642 deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
5643
5644 return this.map( function () {
5645 return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
5646 });
5647 },
5648
5649 html: function( value ) {
5650 if ( value === undefined ) {
5651 return this[0] && this[0].nodeType === 1 ?
5652 this[0].innerHTML.replace(rinlinejQuery, "") :
5653 null;
5654
5655 // See if we can take a shortcut and just use innerHTML
5656 } else if ( typeof value === "string" && !rnocache.test( value ) &&
5657 (jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) &&
5658 !wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) {
5659
5660 value = value.replace(rxhtmlTag, "<$1></$2>");
5661
5662 try {
5663 for ( var i = 0, l = this.length; i < l; i++ ) {
5664 // Remove element nodes and prevent memory leaks
5665 if ( this[i].nodeType === 1 ) {
5666 jQuery.cleanData( this[i].getElementsByTagName("*") );
5667 this[i].innerHTML = value;
5668 }
5669 }
5670
5671 // If using innerHTML throws an exception, use the fallback method
5672 } catch(e) {
5673 this.empty().append( value );
5674 }
5675
5676 } else if ( jQuery.isFunction( value ) ) {
5677 this.each(function(i){
5678 var self = jQuery( this );
5679
5680 self.html( value.call(this, i, self.html()) );
5681 });
5682
5683 } else {
5684 this.empty().append( value );
5685 }
5686
5687 return this;
5688 },
5689
5690 replaceWith: function( value ) {
5691 if ( this[0] && this[0].parentNode ) {
5692 // Make sure that the elements are removed from the DOM before they are inserted
5693 // this can help fix replacing a parent with child elements
5694 if ( jQuery.isFunction( value ) ) {
5695 return this.each(function(i) {
5696 var self = jQuery(this), old = self.html();
5697 self.replaceWith( value.call( this, i, old ) );
5698 });
5699 }
5700
5701 if ( typeof value !== "string" ) {
5702 value = jQuery( value ).detach();
5703 }
5704
5705 return this.each(function() {
5706 var next = this.nextSibling,
5707 parent = this.parentNode;
5708
5709 jQuery( this ).remove();
5710
5711 if ( next ) {
5712 jQuery(next).before( value );
5713 } else {
5714 jQuery(parent).append( value );
5715 }
5716 });
5717 } else {
5718 return this.length ?
5719 this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value ) :
5720 this;
5721 }
5722 },
5723
5724 detach: function( selector ) {
5725 return this.remove( selector, true );
5726 },
5727
5728 domManip: function( args, table, callback ) {
5729 var results, first, fragment, parent,
5730 value = args[0],
5731 scripts = [];
5732
5733 // We can't cloneNode fragments that contain checked, in WebKit
5734 if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) {
5735 return this.each(function() {
5736 jQuery(this).domManip( args, table, callback, true );
5737 });
5738 }
5739
5740 if ( jQuery.isFunction(value) ) {
5741 return this.each(function(i) {
5742 var self = jQuery(this);
5743 args[0] = value.call(this, i, table ? self.html() : undefined);
5744 self.domManip( args, table, callback );
5745 });
5746 }
5747
5748 if ( this[0] ) {
5749 parent = value && value.parentNode;
5750
5751 // If we're in a fragment, just use that instead of building a new one
5752 if ( jQuery.support.parentNode && parent && parent.nodeType === 11 && parent.childNodes.length === this.length ) {
5753 results = { fragment: parent };
5754
5755 } else {
5756 results = jQuery.buildFragment( args, this, scripts );
5757 }
5758
5759 fragment = results.fragment;
5760
5761 if ( fragment.childNodes.length === 1 ) {
5762 first = fragment = fragment.firstChild;
5763 } else {
5764 first = fragment.firstChild;
5765 }
5766
5767 if ( first ) {
5768 table = table && jQuery.nodeName( first, "tr" );
5769
5770 for ( var i = 0, l = this.length, lastIndex = l - 1; i < l; i++ ) {
5771 callback.call(
5772 table ?
5773 root(this[i], first) :
5774 this[i],
5775 // Make sure that we do not leak memory by inadvertently discarding
5776 // the original fragment (which might have attached data) instead of
5777 // using it; in addition, use the original fragment object for the last
5778 // item instead of first because it can end up being emptied incorrectly
5779 // in certain situations (Bug #8070).
5780 // Fragments from the fragment cache must always be cloned and never used
5781 // in place.
5782 results.cacheable || (l > 1 && i < lastIndex) ?
5783 jQuery.clone( fragment, true, true ) :
5784 fragment
5785 );
5786 }
5787 }
5788
5789 if ( scripts.length ) {
5790 jQuery.each( scripts, evalScript );
5791 }
5792 }
5793
5794 return this;
5795 }
5796 });
5797
5798 function root( elem, cur ) {
5799 return jQuery.nodeName(elem, "table") ?
5800 (elem.getElementsByTagName("tbody")[0] ||
5801 elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
5802 elem;
5803 }
5804
5805 function cloneCopyEvent( src, dest ) {
5806
5807 if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {
5808 return;
5809 }
5810
5811 var internalKey = jQuery.expando,
5812 oldData = jQuery.data( src ),
5813 curData = jQuery.data( dest, oldData );
5814
5815 // Switch to use the internal data object, if it exists, for the next
5816 // stage of data copying
5817 if ( (oldData = oldData[ internalKey ]) ) {
5818 var events = oldData.events;
5819 curData = curData[ internalKey ] = jQuery.extend({}, oldData);
5820
5821 if ( events ) {
5822 delete curData.handle;
5823 curData.events = {};
5824
5825 for ( var type in events ) {
5826 for ( var i = 0, l = events[ type ].length; i < l; i++ ) {
5827 jQuery.event.add( dest, type + ( events[ type ][ i ].namespace ? "." : "" ) + events[ type ][ i ].namespace, events[ type ][ i ], events[ type ][ i ].data );
5828 }
5829 }
5830 }
5831 }
5832 }
5833
5834 function cloneFixAttributes( src, dest ) {
5835 var nodeName;
5836
5837 // We do not need to do anything for non-Elements
5838 if ( dest.nodeType !== 1 ) {
5839 return;
5840 }
5841
5842 // clearAttributes removes the attributes, which we don't want,
5843 // but also removes the attachEvent events, which we *do* want
5844 if ( dest.clearAttributes ) {
5845 dest.clearAttributes();
5846 }
5847
5848 // mergeAttributes, in contrast, only merges back on the
5849 // original attributes, not the events
5850 if ( dest.mergeAttributes ) {
5851 dest.mergeAttributes( src );
5852 }
5853
5854 nodeName = dest.nodeName.toLowerCase();
5855
5856 // IE6-8 fail to clone children inside object elements that use
5857 // the proprietary classid attribute value (rather than the type
5858 // attribute) to identify the type of content to display
5859 if ( nodeName === "object" ) {
5860 dest.outerHTML = src.outerHTML;
5861
5862 } else if ( nodeName === "input" && (src.type === "checkbox" || src.type === "radio") ) {
5863 // IE6-8 fails to persist the checked state of a cloned checkbox
5864 // or radio button. Worse, IE6-7 fail to give the cloned element
5865 // a checked appearance if the defaultChecked value isn't also set
5866 if ( src.checked ) {
5867 dest.defaultChecked = dest.checked = src.checked;
5868 }
5869
5870 // IE6-7 get confused and end up setting the value of a cloned
5871 // checkbox/radio button to an empty string instead of "on"
5872 if ( dest.value !== src.value ) {
5873 dest.value = src.value;
5874 }
5875
5876 // IE6-8 fails to return the selected option to the default selected
5877 // state when cloning options
5878 } else if ( nodeName === "option" ) {
5879 dest.selected = src.defaultSelected;
5880
5881 // IE6-8 fails to set the defaultValue to the correct value when
5882 // cloning other types of input fields
5883 } else if ( nodeName === "input" || nodeName === "textarea" ) {
5884 dest.defaultValue = src.defaultValue;
5885 }
5886
5887 // Event data gets referenced instead of copied if the expando
5888 // gets copied too
5889 dest.removeAttribute( jQuery.expando );
5890 }
5891
5892 jQuery.buildFragment = function( args, nodes, scripts ) {
5893 var fragment, cacheable, cacheresults,
5894 doc = (nodes && nodes[0] ? nodes[0].ownerDocument || nodes[0] : document);
5895
5896 // Only cache "small" (1/2 KB) HTML strings that are associated with the main document
5897 // Cloning options loses the selected state, so don't cache them
5898 // IE 6 doesn't like it when you put <object> or <embed> elements in a fragment
5899 // Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache
5900 if ( args.length === 1 && typeof args[0] === "string" && args[0].length < 512 && doc === document &&
5901 args[0].charAt(0) === "<" && !rnocache.test( args[0] ) && (jQuery.support.checkClone || !rchecked.test( args[0] )) ) {
5902
5903 cacheable = true;
5904
5905 cacheresults = jQuery.fragments[ args[0] ];
5906 if ( cacheresults && cacheresults !== 1 ) {
5907 fragment = cacheresults;
5908 }
5909 }
5910
5911 if ( !fragment ) {
5912 fragment = doc.createDocumentFragment();
5913 jQuery.clean( args, doc, fragment, scripts );
5914 }
5915
5916 if ( cacheable ) {
5917 jQuery.fragments[ args[0] ] = cacheresults ? fragment : 1;
5918 }
5919
5920 return { fragment: fragment, cacheable: cacheable };
5921 };
5922
5923 jQuery.fragments = {};
5924
5925 jQuery.each({
5926 appendTo: "append",
5927 prependTo: "prepend",
5928 insertBefore: "before",
5929 insertAfter: "after",
5930 replaceAll: "replaceWith"
5931 }, function( name, original ) {
5932 jQuery.fn[ name ] = function( selector ) {
5933 var ret = [],
5934 insert = jQuery( selector ),
5935 parent = this.length === 1 && this[0].parentNode;
5936
5937 if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) {
5938 insert[ original ]( this[0] );
5939 return this;
5940
5941 } else {
5942 for ( var i = 0, l = insert.length; i < l; i++ ) {
5943 var elems = (i > 0 ? this.clone(true) : this).get();
5944 jQuery( insert[i] )[ original ]( elems );
5945 ret = ret.concat( elems );
5946 }
5947
5948 return this.pushStack( ret, name, insert.selector );
5949 }
5950 };
5951 });
5952
5953 function getAll( elem ) {
5954 if ( "getElementsByTagName" in elem ) {
5955 return elem.getElementsByTagName( "*" );
5956
5957 } else if ( "querySelectorAll" in elem ) {
5958 return elem.querySelectorAll( "*" );
5959
5960 } else {
5961 return [];
5962 }
5963 }
5964
5965 // Used in clean, fixes the defaultChecked property
5966 function fixDefaultChecked( elem ) {
5967 if ( elem.type === "checkbox" || elem.type === "radio" ) {
5968 elem.defaultChecked = elem.checked;
5969 }
5970 }
5971 // Finds all inputs and passes them to fixDefaultChecked
5972 function findInputs( elem ) {
5973 if ( jQuery.nodeName( elem, "input" ) ) {
5974 fixDefaultChecked( elem );
5975 } else if ( elem.getElementsByTagName ) {
5976 jQuery.grep( elem.getElementsByTagName("input"), fixDefaultChecked );
5977 }
5978 }
5979
5980 jQuery.extend({
5981 clone: function( elem, dataAndEvents, deepDataAndEvents ) {
5982 var clone = elem.cloneNode(true),
5983 srcElements,
5984 destElements,
5985 i;
5986
5987 if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) &&
5988 (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {
5989 // IE copies events bound via attachEvent when using cloneNode.
5990 // Calling detachEvent on the clone will also remove the events
5991 // from the original. In order to get around this, we use some
5992 // proprietary methods to clear the events. Thanks to MooTools
5993 // guys for this hotness.
5994
5995 cloneFixAttributes( elem, clone );
5996
5997 // Using Sizzle here is crazy slow, so we use getElementsByTagName
5998 // instead
5999 srcElements = getAll( elem );
6000 destElements = getAll( clone );
6001
6002 // Weird iteration because IE will replace the length property
6003 // with an element if you are cloning the body and one of the
6004 // elements on the page has a name or id of "length"
6005 for ( i = 0; srcElements[i]; ++i ) {
6006 cloneFixAttributes( srcElements[i], destElements[i] );
6007 }
6008 }
6009
6010 // Copy the events from the original to the clone
6011 if ( dataAndEvents ) {
6012 cloneCopyEvent( elem, clone );
6013
6014 if ( deepDataAndEvents ) {
6015 srcElements = getAll( elem );
6016 destElements = getAll( clone );
6017
6018 for ( i = 0; srcElements[i]; ++i ) {
6019 cloneCopyEvent( srcElements[i], destElements[i] );
6020 }
6021 }
6022 }
6023
6024 // Return the cloned set
6025 return clone;
6026 },
6027
6028 clean: function( elems, context, fragment, scripts ) {
6029 var checkScriptType;
6030
6031 context = context || document;
6032
6033 // !context.createElement fails in IE with an error but returns typeof 'object'
6034 if ( typeof context.createElement === "undefined" ) {
6035 context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
6036 }
6037
6038 var ret = [], j;
6039
6040 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
6041 if ( typeof elem === "number" ) {
6042 elem += "";
6043 }
6044
6045 if ( !elem ) {
6046 continue;
6047 }
6048
6049 // Convert html string into DOM nodes
6050 if ( typeof elem === "string" ) {
6051 if ( !rhtml.test( elem ) ) {
6052 elem = context.createTextNode( elem );
6053 } else {
6054 // Fix "XHTML"-style tags in all browsers
6055 elem = elem.replace(rxhtmlTag, "<$1></$2>");
6056
6057 // Trim whitespace, otherwise indexOf won't work as expected
6058 var tag = (rtagName.exec( elem ) || ["", ""])[1].toLowerCase(),
6059 wrap = wrapMap[ tag ] || wrapMap._default,
6060 depth = wrap[0],
6061 div = context.createElement("div");
6062
6063 // Go to html and back, then peel off extra wrappers
6064 div.innerHTML = wrap[1] + elem + wrap[2];
6065
6066 // Move to the right depth
6067 while ( depth-- ) {
6068 div = div.lastChild;
6069 }
6070
6071 // Remove IE's autoinserted <tbody> from table fragments
6072 if ( !jQuery.support.tbody ) {
6073
6074 // String was a <table>, *may* have spurious <tbody>
6075 var hasBody = rtbody.test(elem),
6076 tbody = tag === "table" && !hasBody ?
6077 div.firstChild && div.firstChild.childNodes :
6078
6079 // String was a bare <thead> or <tfoot>
6080 wrap[1] === "<table>" && !hasBody ?
6081 div.childNodes :
6082 [];
6083
6084 for ( j = tbody.length - 1; j >= 0 ; --j ) {
6085 if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) {
6086 tbody[ j ].parentNode.removeChild( tbody[ j ] );
6087 }
6088 }
6089 }
6090
6091 // IE completely kills leading whitespace when innerHTML is used
6092 if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
6093 div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );
6094 }
6095
6096 elem = div.childNodes;
6097 }
6098 }
6099
6100 // Resets defaultChecked for any radios and checkboxes
6101 // about to be appended to the DOM in IE 6/7 (#8060)
6102 var len;
6103 if ( !jQuery.support.appendChecked ) {
6104 if ( elem[0] && typeof (len = elem.length) === "number" ) {
6105 for ( j = 0; j < len; j++ ) {
6106 findInputs( elem[j] );
6107 }
6108 } else {
6109 findInputs( elem );
6110 }
6111 }
6112
6113 if ( elem.nodeType ) {
6114 ret.push( elem );
6115 } else {
6116 ret = jQuery.merge( ret, elem );
6117 }
6118 }
6119
6120 if ( fragment ) {
6121 checkScriptType = function( elem ) {
6122 return !elem.type || rscriptType.test( elem.type );
6123 };
6124 for ( i = 0; ret[i]; i++ ) {
6125 if ( scripts && jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
6126 scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
6127
6128 } else {
6129 if ( ret[i].nodeType === 1 ) {
6130 var jsTags = jQuery.grep( ret[i].getElementsByTagName( "script" ), checkScriptType );
6131
6132 ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) );
6133 }
6134 fragment.appendChild( ret[i] );
6135 }
6136 }
6137 }
6138
6139 return ret;
6140 },
6141
6142 cleanData: function( elems ) {
6143 var data, id, cache = jQuery.cache, internalKey = jQuery.expando, special = jQuery.event.special,
6144 deleteExpando = jQuery.support.deleteExpando;
6145
6146 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
6147 if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
6148 continue;
6149 }
6150
6151 id = elem[ jQuery.expando ];
6152
6153 if ( id ) {
6154 data = cache[ id ] && cache[ id ][ internalKey ];
6155
6156 if ( data && data.events ) {
6157 for ( var type in data.events ) {
6158 if ( special[ type ] ) {
6159 jQuery.event.remove( elem, type );
6160
6161 // This is a shortcut to avoid jQuery.event.remove's overhead
6162 } else {
6163 jQuery.removeEvent( elem, type, data.handle );
6164 }
6165 }
6166
6167 // Null the DOM reference to avoid IE6/7/8 leak (#7054)
6168 if ( data.handle ) {
6169 data.handle.elem = null;
6170 }
6171 }
6172
6173 if ( deleteExpando ) {
6174 delete elem[ jQuery.expando ];
6175
6176 } else if ( elem.removeAttribute ) {
6177 elem.removeAttribute( jQuery.expando );
6178 }
6179
6180 delete cache[ id ];
6181 }
6182 }
6183 }
6184 });
6185
6186 function evalScript( i, elem ) {
6187 if ( elem.src ) {
6188 jQuery.ajax({
6189 url: elem.src,
6190 async: false,
6191 dataType: "script"
6192 });
6193 } else {
6194 jQuery.globalEval( ( elem.text || elem.textContent || elem.innerHTML || "" ).replace( rcleanScript, "/*$0*/" ) );
6195 }
6196
6197 if ( elem.parentNode ) {
6198 elem.parentNode.removeChild( elem );
6199 }
6200 }
6201
6202
6203
6204
6205 var ralpha = /alpha\([^)]*\)/i,
6206 ropacity = /opacity=([^)]*)/,
6207 rdashAlpha = /-([a-z])/ig,
6208 // fixed for IE9, see #8346
6209 rupper = /([A-Z]|^ms)/g,
6210 rnumpx = /^-?\d+(?:px)?$/i,
6211 rnum = /^-?\d/,
6212 rrelNum = /^[+\-]=/,
6213 rrelNumFilter = /[^+\-\.\de]+/g,
6214
6215 cssShow = { position: "absolute", visibility: "hidden", display: "block" },
6216 cssWidth = [ "Left", "Right" ],
6217 cssHeight = [ "Top", "Bottom" ],
6218 curCSS,
6219
6220 getComputedStyle,
6221 currentStyle,
6222
6223 fcamelCase = function( all, letter ) {
6224 return letter.toUpperCase();
6225 };
6226
6227 jQuery.fn.css = function( name, value ) {
6228 // Setting 'undefined' is a no-op
6229 if ( arguments.length === 2 && value === undefined ) {
6230 return this;
6231 }
6232
6233 return jQuery.access( this, name, value, true, function( elem, name, value ) {
6234 return value !== undefined ?
6235 jQuery.style( elem, name, value ) :
6236 jQuery.css( elem, name );
6237 });
6238 };
6239
6240 jQuery.extend({
6241 // Add in style property hooks for overriding the default
6242 // behavior of getting and setting a style property
6243 cssHooks: {
6244 opacity: {
6245 get: function( elem, computed ) {
6246 if ( computed ) {
6247 // We should always get a number back from opacity
6248 var ret = curCSS( elem, "opacity", "opacity" );
6249 return ret === "" ? "1" : ret;
6250
6251 } else {
6252 return elem.style.opacity;
6253 }
6254 }
6255 }
6256 },
6257
6258 // Exclude the following css properties to add px
6259 cssNumber: {
6260 "zIndex": true,
6261 "fontWeight": true,
6262 "opacity": true,
6263 "zoom": true,
6264 "lineHeight": true,
6265 "widows": true,
6266 "orphans": true
6267 },
6268
6269 // Add in properties whose names you wish to fix before
6270 // setting or getting the value
6271 cssProps: {
6272 // normalize float css property
6273 "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat"
6274 },
6275
6276 // Get and set the style property on a DOM Node
6277 style: function( elem, name, value, extra ) {
6278 // Don't set styles on text and comment nodes
6279 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
6280 return;
6281 }
6282
6283 // Make sure that we're working with the right name
6284 var ret, type, origName = jQuery.camelCase( name ),
6285 style = elem.style, hooks = jQuery.cssHooks[ origName ];
6286
6287 name = jQuery.cssProps[ origName ] || origName;
6288
6289 // Check if we're setting a value
6290 if ( value !== undefined ) {
6291 type = typeof value;
6292
6293 // Make sure that NaN and null values aren't set. See: #7116
6294 if ( type === "number" && isNaN( value ) || value == null ) {
6295 return;
6296 }
6297
6298 // convert relative number strings (+= or -=) to relative numbers. #7345
6299 if ( type === "string" && rrelNum.test( value ) ) {
6300 value = +value.replace( rrelNumFilter, "" ) + parseFloat( jQuery.css( elem, name ) );
6301 }
6302
6303 // If a number was passed in, add 'px' to the (except for certain CSS properties)
6304 if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
6305 value += "px";
6306 }
6307
6308 // If a hook was provided, use that value, otherwise just set the specified value
6309 if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value )) !== undefined ) {
6310 // Wrapped to prevent IE from throwing errors when 'invalid' values are provided
6311 // Fixes bug #5509
6312 try {
6313 style[ name ] = value;
6314 } catch(e) {}
6315 }
6316
6317 } else {
6318 // If a hook was provided get the non-computed value from there
6319 if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
6320 return ret;
6321 }
6322
6323 // Otherwise just get the value from the style object
6324 return style[ name ];
6325 }
6326 },
6327
6328 css: function( elem, name, extra ) {
6329 var ret, hooks;
6330
6331 // Make sure that we're working with the right name
6332 name = jQuery.camelCase( name );
6333 hooks = jQuery.cssHooks[ name ];
6334 name = jQuery.cssProps[ name ] || name;
6335
6336 // cssFloat needs a special treatment
6337 if ( name === "cssFloat" ) {
6338 name = "float";
6339 }
6340
6341 // If a hook was provided get the computed value from there
6342 if ( hooks && "get" in hooks && (ret = hooks.get( elem, true, extra )) !== undefined ) {
6343 return ret;
6344
6345 // Otherwise, if a way to get the computed value exists, use that
6346 } else if ( curCSS ) {
6347 return curCSS( elem, name );
6348 }
6349 },
6350
6351 // A method for quickly swapping in/out CSS properties to get correct calculations
6352 swap: function( elem, options, callback ) {
6353 var old = {};
6354
6355 // Remember the old values, and insert the new ones
6356 for ( var name in options ) {
6357 old[ name ] = elem.style[ name ];
6358 elem.style[ name ] = options[ name ];
6359 }
6360
6361 callback.call( elem );
6362
6363 // Revert the old values
6364 for ( name in options ) {
6365 elem.style[ name ] = old[ name ];
6366 }
6367 },
6368
6369 camelCase: function( string ) {
6370 return string.replace( rdashAlpha, fcamelCase );
6371 }
6372 });
6373
6374 // DEPRECATED, Use jQuery.css() instead
6375 jQuery.curCSS = jQuery.css;
6376
6377 jQuery.each(["height", "width"], function( i, name ) {
6378 jQuery.cssHooks[ name ] = {
6379 get: function( elem, computed, extra ) {
6380 var val;
6381
6382 if ( computed ) {
6383 if ( elem.offsetWidth !== 0 ) {
6384 val = getWH( elem, name, extra );
6385
6386 } else {
6387 jQuery.swap( elem, cssShow, function() {
6388 val = getWH( elem, name, extra );
6389 });
6390 }
6391
6392 if ( val <= 0 ) {
6393 val = curCSS( elem, name, name );
6394
6395 if ( val === "0px" && currentStyle ) {
6396 val = currentStyle( elem, name, name );
6397 }
6398
6399 if ( val != null ) {
6400 // Should return "auto" instead of 0, use 0 for
6401 // temporary backwards-compat
6402 return val === "" || val === "auto" ? "0px" : val;
6403 }
6404 }
6405
6406 if ( val < 0 || val == null ) {
6407 val = elem.style[ name ];
6408
6409 // Should return "auto" instead of 0, use 0 for
6410 // temporary backwards-compat
6411 return val === "" || val === "auto" ? "0px" : val;
6412 }
6413
6414 return typeof val === "string" ? val : val + "px";
6415 }
6416 },
6417
6418 set: function( elem, value ) {
6419 if ( rnumpx.test( value ) ) {
6420 // ignore negative width and height values #1599
6421 value = parseFloat(value);
6422
6423 if ( value >= 0 ) {
6424 return value + "px";
6425 }
6426
6427 } else {
6428 return value;
6429 }
6430 }
6431 };
6432 });
6433
6434 if ( !jQuery.support.opacity ) {
6435 jQuery.cssHooks.opacity = {
6436 get: function( elem, computed ) {
6437 // IE uses filters for opacity
6438 return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ?
6439 ( parseFloat( RegExp.$1 ) / 100 ) + "" :
6440 computed ? "1" : "";
6441 },
6442
6443 set: function( elem, value ) {
6444 var style = elem.style,
6445 currentStyle = elem.currentStyle;
6446
6447 // IE has trouble with opacity if it does not have layout
6448 // Force it by setting the zoom level
6449 style.zoom = 1;
6450
6451 // Set the alpha filter to set the opacity
6452 var opacity = jQuery.isNaN( value ) ?
6453 "" :
6454 "alpha(opacity=" + value * 100 + ")",
6455 filter = currentStyle && currentStyle.filter || style.filter || "";
6456
6457 style.filter = ralpha.test( filter ) ?
6458 filter.replace( ralpha, opacity ) :
6459 filter + " " + opacity;
6460 }
6461 };
6462 }
6463
6464 jQuery(function() {
6465 // This hook cannot be added until DOM ready because the support test
6466 // for it is not run until after DOM ready
6467 if ( !jQuery.support.reliableMarginRight ) {
6468 jQuery.cssHooks.marginRight = {
6469 get: function( elem, computed ) {
6470 // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
6471 // Work around by temporarily setting element display to inline-block
6472 var ret;
6473 jQuery.swap( elem, { "display": "inline-block" }, function() {
6474 if ( computed ) {
6475 ret = curCSS( elem, "margin-right", "marginRight" );
6476 } else {
6477 ret = elem.style.marginRight;
6478 }
6479 });
6480 return ret;
6481 }
6482 };
6483 }
6484 });
6485
6486 if ( document.defaultView && document.defaultView.getComputedStyle ) {
6487 getComputedStyle = function( elem, name ) {
6488 var ret, defaultView, computedStyle;
6489
6490 name = name.replace( rupper, "-$1" ).toLowerCase();
6491
6492 if ( !(defaultView = elem.ownerDocument.defaultView) ) {
6493 return undefined;
6494 }
6495
6496 if ( (computedStyle = defaultView.getComputedStyle( elem, null )) ) {
6497 ret = computedStyle.getPropertyValue( name );
6498 if ( ret === "" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) {
6499 ret = jQuery.style( elem, name );
6500 }
6501 }
6502
6503 return ret;
6504 };
6505 }
6506
6507 if ( document.documentElement.currentStyle ) {
6508 currentStyle = function( elem, name ) {
6509 var left,
6510 ret = elem.currentStyle && elem.currentStyle[ name ],
6511 rsLeft = elem.runtimeStyle && elem.runtimeStyle[ name ],
6512 style = elem.style;
6513
6514 // From the awesome hack by Dean Edwards
6515 // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
6516
6517 // If we're not dealing with a regular pixel number
6518 // but a number that has a weird ending, we need to convert it to pixels
6519 if ( !rnumpx.test( ret ) && rnum.test( ret ) ) {
6520 // Remember the original values
6521 left = style.left;
6522
6523 // Put in the new values to get a computed value out
6524 if ( rsLeft ) {
6525 elem.runtimeStyle.left = elem.currentStyle.left;
6526 }
6527 style.left = name === "fontSize" ? "1em" : (ret || 0);
6528 ret = style.pixelLeft + "px";
6529
6530 // Revert the changed values
6531 style.left = left;
6532 if ( rsLeft ) {
6533 elem.runtimeStyle.left = rsLeft;
6534 }
6535 }
6536
6537 return ret === "" ? "auto" : ret;
6538 };
6539 }
6540
6541 curCSS = getComputedStyle || currentStyle;
6542
6543 function getWH( elem, name, extra ) {
6544 var which = name === "width" ? cssWidth : cssHeight,
6545 val = name === "width" ? elem.offsetWidth : elem.offsetHeight;
6546
6547 if ( extra === "border" ) {
6548 return val;
6549 }
6550
6551 jQuery.each( which, function() {
6552 if ( !extra ) {
6553 val -= parseFloat(jQuery.css( elem, "padding" + this )) || 0;
6554 }
6555
6556 if ( extra === "margin" ) {
6557 val += parseFloat(jQuery.css( elem, "margin" + this )) || 0;
6558
6559 } else {
6560 val -= parseFloat(jQuery.css( elem, "border" + this + "Width" )) || 0;
6561 }
6562 });
6563
6564 return val;
6565 }
6566
6567 if ( jQuery.expr && jQuery.expr.filters ) {
6568 jQuery.expr.filters.hidden = function( elem ) {
6569 var width = elem.offsetWidth,
6570 height = elem.offsetHeight;
6571
6572 return (width === 0 && height === 0) || (!jQuery.support.reliableHiddenOffsets && (elem.style.display || jQuery.css( elem, "display" )) === "none");
6573 };
6574
6575 jQuery.expr.filters.visible = function( elem ) {
6576 return !jQuery.expr.filters.hidden( elem );
6577 };
6578 }
6579
6580
6581
6582
6583 var r20 = /%20/g,
6584 rbracket = /\[\]$/,
6585 rCRLF = /\r?\n/g,
6586 rhash = /#.*$/,
6587 rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL
6588 rinput = /^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,
6589 // #7653, #8125, #8152: local protocol detection
6590 rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|widget):$/,
6591 rnoContent = /^(?:GET|HEAD)$/,
6592 rprotocol = /^\/\//,
6593 rquery = /\?/,
6594 rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
6595 rselectTextarea = /^(?:select|textarea)/i,
6596 rspacesAjax = /\s+/,
6597 rts = /([?&])_=[^&]*/,
6598 rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,
6599
6600 // Keep a copy of the old load method
6601 _load = jQuery.fn.load,
6602
6603 /* Prefilters
6604 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
6605 * 2) These are called:
6606 * - BEFORE asking for a transport
6607 * - AFTER param serialization (s.data is a string if s.processData is true)
6608 * 3) key is the dataType
6609 * 4) the catchall symbol "*" can be used
6610 * 5) execution will start with transport dataType and THEN continue down to "*" if needed
6611 */
6612 prefilters = {},
6613
6614 /* Transports bindings
6615 * 1) key is the dataType
6616 * 2) the catchall symbol "*" can be used
6617 * 3) selection will start with transport dataType and THEN go to "*" if needed
6618 */
6619 transports = {},
6620
6621 // Document location
6622 ajaxLocation,
6623
6624 // Document location segments
6625 ajaxLocParts;
6626
6627 // #8138, IE may throw an exception when accessing
6628 // a field from window.location if document.domain has been set
6629 try {
6630 ajaxLocation = location.href;
6631 } catch( e ) {
6632 // Use the href attribute of an A element
6633 // since IE will modify it given document.location
6634 ajaxLocation = document.createElement( "a" );
6635 ajaxLocation.href = "";
6636 ajaxLocation = ajaxLocation.href;
6637 }
6638
6639 // Segment location into parts
6640 ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
6641
6642 // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
6643 function addToPrefiltersOrTransports( structure ) {
6644
6645 // dataTypeExpression is optional and defaults to "*"
6646 return function( dataTypeExpression, func ) {
6647
6648 if ( typeof dataTypeExpression !== "string" ) {
6649 func = dataTypeExpression;
6650 dataTypeExpression = "*";
6651 }
6652
6653 if ( jQuery.isFunction( func ) ) {
6654 var dataTypes = dataTypeExpression.toLowerCase().split( rspacesAjax ),
6655 i = 0,
6656 length = dataTypes.length,
6657 dataType,
6658 list,
6659 placeBefore;
6660
6661 // For each dataType in the dataTypeExpression
6662 for(; i < length; i++ ) {
6663 dataType = dataTypes[ i ];
6664 // We control if we're asked to add before
6665 // any existing element
6666 placeBefore = /^\+/.test( dataType );
6667 if ( placeBefore ) {
6668 dataType = dataType.substr( 1 ) || "*";
6669 }
6670 list = structure[ dataType ] = structure[ dataType ] || [];
6671 // then we add to the structure accordingly
6672 list[ placeBefore ? "unshift" : "push" ]( func );
6673 }
6674 }
6675 };
6676 }
6677
6678 // Base inspection function for prefilters and transports
6679 function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR,
6680 dataType /* internal */, inspected /* internal */ ) {
6681
6682 dataType = dataType || options.dataTypes[ 0 ];
6683 inspected = inspected || {};
6684
6685 inspected[ dataType ] = true;
6686
6687 var list = structure[ dataType ],
6688 i = 0,
6689 length = list ? list.length : 0,
6690 executeOnly = ( structure === prefilters ),
6691 selection;
6692
6693 for(; i < length && ( executeOnly || !selection ); i++ ) {
6694 selection = list[ i ]( options, originalOptions, jqXHR );
6695 // If we got redirected to another dataType
6696 // we try there if executing only and not done already
6697 if ( typeof selection === "string" ) {
6698 if ( !executeOnly || inspected[ selection ] ) {
6699 selection = undefined;
6700 } else {
6701 options.dataTypes.unshift( selection );
6702 selection = inspectPrefiltersOrTransports(
6703 structure, options, originalOptions, jqXHR, selection, inspected );
6704 }
6705 }
6706 }
6707 // If we're only executing or nothing was selected
6708 // we try the catchall dataType if not done already
6709 if ( ( executeOnly || !selection ) && !inspected[ "*" ] ) {
6710 selection = inspectPrefiltersOrTransports(
6711 structure, options, originalOptions, jqXHR, "*", inspected );
6712 }
6713 // unnecessary when only executing (prefilters)
6714 // but it'll be ignored by the caller in that case
6715 return selection;
6716 }
6717
6718 jQuery.fn.extend({
6719 load: function( url, params, callback ) {
6720 if ( typeof url !== "string" && _load ) {
6721 return _load.apply( this, arguments );
6722
6723 // Don't do a request if no elements are being requested
6724 } else if ( !this.length ) {
6725 return this;
6726 }
6727
6728 var off = url.indexOf( " " );
6729 if ( off >= 0 ) {
6730 var selector = url.slice( off, url.length );
6731 url = url.slice( 0, off );
6732 }
6733
6734 // Default to a GET request
6735 var type = "GET";
6736
6737 // If the second parameter was provided
6738 if ( params ) {
6739 // If it's a function
6740 if ( jQuery.isFunction( params ) ) {
6741 // We assume that it's the callback
6742 callback = params;
6743 params = undefined;
6744
6745 // Otherwise, build a param string
6746 } else if ( typeof params === "object" ) {
6747 params = jQuery.param( params, jQuery.ajaxSettings.traditional );
6748 type = "POST";
6749 }
6750 }
6751
6752 var self = this;
6753
6754 // Request the remote document
6755 jQuery.ajax({
6756 url: url,
6757 type: type,
6758 dataType: "html",
6759 data: params,
6760 // Complete callback (responseText is used internally)
6761 complete: function( jqXHR, status, responseText ) {
6762 // Store the response as specified by the jqXHR object
6763 responseText = jqXHR.responseText;
6764 // If successful, inject the HTML into all the matched elements
6765 if ( jqXHR.isResolved() ) {
6766 // #4825: Get the actual response in case
6767 // a dataFilter is present in ajaxSettings
6768 jqXHR.done(function( r ) {
6769 responseText = r;
6770 });
6771 // See if a selector was specified
6772 self.html( selector ?
6773 // Create a dummy div to hold the results
6774 jQuery("<div>")
6775 // inject the contents of the document in, removing the scripts
6776 // to avoid any 'Permission Denied' errors in IE
6777 .append(responseText.replace(rscript, ""))
6778
6779 // Locate the specified elements
6780 .find(selector) :
6781
6782 // If not, just inject the full result
6783 responseText );
6784 }
6785
6786 if ( callback ) {
6787 self.each( callback, [ responseText, status, jqXHR ] );
6788 }
6789 }
6790 });
6791
6792 return this;
6793 },
6794
6795 serialize: function() {
6796 return jQuery.param( this.serializeArray() );
6797 },
6798
6799 serializeArray: function() {
6800 return this.map(function(){
6801 return this.elements ? jQuery.makeArray( this.elements ) : this;
6802 })
6803 .filter(function(){
6804 return this.name && !this.disabled &&
6805 ( this.checked || rselectTextarea.test( this.nodeName ) ||
6806 rinput.test( this.type ) );
6807 })
6808 .map(function( i, elem ){
6809 var val = jQuery( this ).val();
6810
6811 return val == null ?
6812 null :
6813 jQuery.isArray( val ) ?
6814 jQuery.map( val, function( val, i ){
6815 return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
6816 }) :
6817 { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
6818 }).get();
6819 }
6820 });
6821
6822 // Attach a bunch of functions for handling common AJAX events
6823 jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split( " " ), function( i, o ){
6824 jQuery.fn[ o ] = function( f ){
6825 return this.bind( o, f );
6826 };
6827 });
6828
6829 jQuery.each( [ "get", "post" ], function( i, method ) {
6830 jQuery[ method ] = function( url, data, callback, type ) {
6831 // shift arguments if data argument was omitted
6832 if ( jQuery.isFunction( data ) ) {
6833 type = type || callback;
6834 callback = data;
6835 data = undefined;
6836 }
6837
6838 return jQuery.ajax({
6839 type: method,
6840 url: url,
6841 data: data,
6842 success: callback,
6843 dataType: type
6844 });
6845 };
6846 });
6847
6848 jQuery.extend({
6849
6850 getScript: function( url, callback ) {
6851 return jQuery.get( url, undefined, callback, "script" );
6852 },
6853
6854 getJSON: function( url, data, callback ) {
6855 return jQuery.get( url, data, callback, "json" );
6856 },
6857
6858 // Creates a full fledged settings object into target
6859 // with both ajaxSettings and settings fields.
6860 // If target is omitted, writes into ajaxSettings.
6861 ajaxSetup: function ( target, settings ) {
6862 if ( !settings ) {
6863 // Only one parameter, we extend ajaxSettings
6864 settings = target;
6865 target = jQuery.extend( true, jQuery.ajaxSettings, settings );
6866 } else {
6867 // target was provided, we extend into it
6868 jQuery.extend( true, target, jQuery.ajaxSettings, settings );
6869 }
6870 // Flatten fields we don't want deep extended
6871 for( var field in { context: 1, url: 1 } ) {
6872 if ( field in settings ) {
6873 target[ field ] = settings[ field ];
6874 } else if( field in jQuery.ajaxSettings ) {
6875 target[ field ] = jQuery.ajaxSettings[ field ];
6876 }
6877 }
6878 return target;
6879 },
6880
6881 ajaxSettings: {
6882 url: ajaxLocation,
6883 isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
6884 global: true,
6885 type: "GET",
6886 contentType: "application/x-www-form-urlencoded",
6887 processData: true,
6888 async: true,
6889 /*
6890 timeout: 0,
6891 data: null,
6892 dataType: null,
6893 username: null,
6894 password: null,
6895 cache: null,
6896 traditional: false,
6897 headers: {},
6898 */
6899
6900 accepts: {
6901 xml: "application/xml, text/xml",
6902 html: "text/html",
6903 text: "text/plain",
6904 json: "application/json, text/javascript",
6905 "*": "*/*"
6906 },
6907
6908 contents: {
6909 xml: /xml/,
6910 html: /html/,
6911 json: /json/
6912 },
6913
6914 responseFields: {
6915 xml: "responseXML",
6916 text: "responseText"
6917 },
6918
6919 // List of data converters
6920 // 1) key format is "source_type destination_type" (a single space in-between)
6921 // 2) the catchall symbol "*" can be used for source_type
6922 converters: {
6923
6924 // Convert anything to text
6925 "* text": window.String,
6926
6927 // Text to html (true = no transformation)
6928 "text html": true,
6929
6930 // Evaluate text as a json expression
6931 "text json": jQuery.parseJSON,
6932
6933 // Parse text as xml
6934 "text xml": jQuery.parseXML
6935 }
6936 },
6937
6938 ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
6939 ajaxTransport: addToPrefiltersOrTransports( transports ),
6940
6941 // Main method
6942 ajax: function( url, options ) {
6943
6944 // If url is an object, simulate pre-1.5 signature
6945 if ( typeof url === "object" ) {
6946 options = url;
6947 url = undefined;
6948 }
6949
6950 // Force options to be an object
6951 options = options || {};
6952
6953 var // Create the final options object
6954 s = jQuery.ajaxSetup( {}, options ),
6955 // Callbacks context
6956 callbackContext = s.context || s,
6957 // Context for global events
6958 // It's the callbackContext if one was provided in the options
6959 // and if it's a DOM node or a jQuery collection
6960 globalEventContext = callbackContext !== s &&
6961 ( callbackContext.nodeType || callbackContext instanceof jQuery ) ?
6962 jQuery( callbackContext ) : jQuery.event,
6963 // Deferreds
6964 deferred = jQuery.Deferred(),
6965 completeDeferred = jQuery._Deferred(),
6966 // Status-dependent callbacks
6967 statusCode = s.statusCode || {},
6968 // ifModified key
6969 ifModifiedKey,
6970 // Headers (they are sent all at once)
6971 requestHeaders = {},
6972 requestHeadersNames = {},
6973 // Response headers
6974 responseHeadersString,
6975 responseHeaders,
6976 // transport
6977 transport,
6978 // timeout handle
6979 timeoutTimer,
6980 // Cross-domain detection vars
6981 parts,
6982 // The jqXHR state
6983 state = 0,
6984 // To know if global events are to be dispatched
6985 fireGlobals,
6986 // Loop variable
6987 i,
6988 // Fake xhr
6989 jqXHR = {
6990
6991 readyState: 0,
6992
6993 // Caches the header
6994 setRequestHeader: function( name, value ) {
6995 if ( !state ) {
6996 var lname = name.toLowerCase();
6997 name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
6998 requestHeaders[ name ] = value;
6999 }
7000 return this;
7001 },
7002
7003 // Raw string
7004 getAllResponseHeaders: function() {
7005 return state === 2 ? responseHeadersString : null;
7006 },
7007
7008 // Builds headers hashtable if needed
7009 getResponseHeader: function( key ) {
7010 var match;
7011 if ( state === 2 ) {
7012 if ( !responseHeaders ) {
7013 responseHeaders = {};
7014 while( ( match = rheaders.exec( responseHeadersString ) ) ) {
7015 responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
7016 }
7017 }
7018 match = responseHeaders[ key.toLowerCase() ];
7019 }
7020 return match === undefined ? null : match;
7021 },
7022
7023 // Overrides response content-type header
7024 overrideMimeType: function( type ) {
7025 if ( !state ) {
7026 s.mimeType = type;
7027 }
7028 return this;
7029 },
7030
7031 // Cancel the request
7032 abort: function( statusText ) {
7033 statusText = statusText || "abort";
7034 if ( transport ) {
7035 transport.abort( statusText );
7036 }
7037 done( 0, statusText );
7038 return this;
7039 }
7040 };
7041
7042 // Callback for when everything is done
7043 // It is defined here because jslint complains if it is declared
7044 // at the end of the function (which would be more logical and readable)
7045 function done( status, statusText, responses, headers ) {
7046
7047 // Called once
7048 if ( state === 2 ) {
7049 return;
7050 }
7051
7052 // State is "done" now
7053 state = 2;
7054
7055 // Clear timeout if it exists
7056 if ( timeoutTimer ) {
7057 clearTimeout( timeoutTimer );
7058 }
7059
7060 // Dereference transport for early garbage collection
7061 // (no matter how long the jqXHR object will be used)
7062 transport = undefined;
7063
7064 // Cache response headers
7065 responseHeadersString = headers || "";
7066
7067 // Set readyState
7068 jqXHR.readyState = status ? 4 : 0;
7069
7070 var isSuccess,
7071 success,
7072 error,
7073 response = responses ? ajaxHandleResponses( s, jqXHR, responses ) : undefined,
7074 lastModified,
7075 etag;
7076
7077 // If successful, handle type chaining
7078 if ( status >= 200 && status < 300 || status === 304 ) {
7079
7080 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
7081 if ( s.ifModified ) {
7082
7083 if ( ( lastModified = jqXHR.getResponseHeader( "Last-Modified" ) ) ) {
7084 jQuery.lastModified[ ifModifiedKey ] = lastModified;
7085 }
7086 if ( ( etag = jqXHR.getResponseHeader( "Etag" ) ) ) {
7087 jQuery.etag[ ifModifiedKey ] = etag;
7088 }
7089 }
7090
7091 // If not modified
7092 if ( status === 304 ) {
7093
7094 statusText = "notmodified";
7095 isSuccess = true;
7096
7097 // If we have data
7098 } else {
7099
7100 try {
7101 success = ajaxConvert( s, response );
7102 statusText = "success";
7103 isSuccess = true;
7104 } catch(e) {
7105 // We have a parsererror
7106 statusText = "parsererror";
7107 error = e;
7108 }
7109 }
7110 } else {
7111 // We extract error from statusText
7112 // then normalize statusText and status for non-aborts
7113 error = statusText;
7114 if( !statusText || status ) {
7115 statusText = "error";
7116 if ( status < 0 ) {
7117 status = 0;
7118 }
7119 }
7120 }
7121
7122 // Set data for the fake xhr object
7123 jqXHR.status = status;
7124 jqXHR.statusText = statusText;
7125
7126 // Success/Error
7127 if ( isSuccess ) {
7128 deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
7129 } else {
7130 deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
7131 }
7132
7133 // Status-dependent callbacks
7134 jqXHR.statusCode( statusCode );
7135 statusCode = undefined;
7136
7137 if ( fireGlobals ) {
7138 globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ),
7139 [ jqXHR, s, isSuccess ? success : error ] );
7140 }
7141
7142 // Complete
7143 completeDeferred.resolveWith( callbackContext, [ jqXHR, statusText ] );
7144
7145 if ( fireGlobals ) {
7146 globalEventContext.trigger( "ajaxComplete", [ jqXHR, s] );
7147 // Handle the global AJAX counter
7148 if ( !( --jQuery.active ) ) {
7149 jQuery.event.trigger( "ajaxStop" );
7150 }
7151 }
7152 }
7153
7154 // Attach deferreds
7155 deferred.promise( jqXHR );
7156 jqXHR.success = jqXHR.done;
7157 jqXHR.error = jqXHR.fail;
7158 jqXHR.complete = completeDeferred.done;
7159
7160 // Status-dependent callbacks
7161 jqXHR.statusCode = function( map ) {
7162 if ( map ) {
7163 var tmp;
7164 if ( state < 2 ) {
7165 for( tmp in map ) {
7166 statusCode[ tmp ] = [ statusCode[tmp], map[tmp] ];
7167 }
7168 } else {
7169 tmp = map[ jqXHR.status ];
7170 jqXHR.then( tmp, tmp );
7171 }
7172 }
7173 return this;
7174 };
7175
7176 // Remove hash character (#7531: and string promotion)
7177 // Add protocol if not provided (#5866: IE7 issue with protocol-less urls)
7178 // We also use the url parameter if available
7179 s.url = ( ( url || s.url ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
7180
7181 // Extract dataTypes list
7182 s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( rspacesAjax );
7183
7184 // Determine if a cross-domain request is in order
7185 if ( s.crossDomain == null ) {
7186 parts = rurl.exec( s.url.toLowerCase() );
7187 s.crossDomain = !!( parts &&
7188 ( parts[ 1 ] != ajaxLocParts[ 1 ] || parts[ 2 ] != ajaxLocParts[ 2 ] ||
7189 ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? 80 : 443 ) ) !=
7190 ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? 80 : 443 ) ) )
7191 );
7192 }
7193
7194 // Convert data if not already a string
7195 if ( s.data && s.processData && typeof s.data !== "string" ) {
7196 s.data = jQuery.param( s.data, s.traditional );
7197 }
7198
7199 // Apply prefilters
7200 inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
7201
7202 // If request was aborted inside a prefiler, stop there
7203 if ( state === 2 ) {
7204 return false;
7205 }
7206
7207 // We can fire global events as of now if asked to
7208 fireGlobals = s.global;
7209
7210 // Uppercase the type
7211 s.type = s.type.toUpperCase();
7212
7213 // Determine if request has content
7214 s.hasContent = !rnoContent.test( s.type );
7215
7216 // Watch for a new set of requests
7217 if ( fireGlobals && jQuery.active++ === 0 ) {
7218 jQuery.event.trigger( "ajaxStart" );
7219 }
7220
7221 // More options handling for requests with no content
7222 if ( !s.hasContent ) {
7223
7224 // If data is available, append data to url
7225 if ( s.data ) {
7226 s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data;
7227 }
7228
7229 // Get ifModifiedKey before adding the anti-cache parameter
7230 ifModifiedKey = s.url;
7231
7232 // Add anti-cache in url if needed
7233 if ( s.cache === false ) {
7234
7235 var ts = jQuery.now(),
7236 // try replacing _= if it is there
7237 ret = s.url.replace( rts, "$1_=" + ts );
7238
7239 // if nothing was replaced, add timestamp to the end
7240 s.url = ret + ( (ret === s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : "" );
7241 }
7242 }
7243
7244 // Set the correct header, if data is being sent
7245 if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
7246 jqXHR.setRequestHeader( "Content-Type", s.contentType );
7247 }
7248
7249 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
7250 if ( s.ifModified ) {
7251 ifModifiedKey = ifModifiedKey || s.url;
7252 if ( jQuery.lastModified[ ifModifiedKey ] ) {
7253 jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ ifModifiedKey ] );
7254 }
7255 if ( jQuery.etag[ ifModifiedKey ] ) {
7256 jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ ifModifiedKey ] );
7257 }
7258 }
7259
7260 // Set the Accepts header for the server, depending on the dataType
7261 jqXHR.setRequestHeader(
7262 "Accept",
7263 s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?
7264 s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", */*; q=0.01" : "" ) :
7265 s.accepts[ "*" ]
7266 );
7267
7268 // Check for headers option
7269 for ( i in s.headers ) {
7270 jqXHR.setRequestHeader( i, s.headers[ i ] );
7271 }
7272
7273 // Allow custom headers/mimetypes and early abort
7274 if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
7275 // Abort if not done already
7276 jqXHR.abort();
7277 return false;
7278
7279 }
7280
7281 // Install callbacks on deferreds
7282 for ( i in { success: 1, error: 1, complete: 1 } ) {
7283 jqXHR[ i ]( s[ i ] );
7284 }
7285
7286 // Get transport
7287 transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
7288
7289 // If no transport, we auto-abort
7290 if ( !transport ) {
7291 done( -1, "No Transport" );
7292 } else {
7293 jqXHR.readyState = 1;
7294 // Send global event
7295 if ( fireGlobals ) {
7296 globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
7297 }
7298 // Timeout
7299 if ( s.async && s.timeout > 0 ) {
7300 timeoutTimer = setTimeout( function(){
7301 jqXHR.abort( "timeout" );
7302 }, s.timeout );
7303 }
7304
7305 try {
7306 state = 1;
7307 transport.send( requestHeaders, done );
7308 } catch (e) {
7309 // Propagate exception as error if not done
7310 if ( status < 2 ) {
7311 done( -1, e );
7312 // Simply rethrow otherwise
7313 } else {
7314 jQuery.error( e );
7315 }
7316 }
7317 }
7318
7319 return jqXHR;
7320 },
7321
7322 // Serialize an array of form elements or a set of
7323 // key/values into a query string
7324 param: function( a, traditional ) {
7325 var s = [],
7326 add = function( key, value ) {
7327 // If value is a function, invoke it and return its value
7328 value = jQuery.isFunction( value ) ? value() : value;
7329 s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
7330 };
7331
7332 // Set traditional to true for jQuery <= 1.3.2 behavior.
7333 if ( traditional === undefined ) {
7334 traditional = jQuery.ajaxSettings.traditional;
7335 }
7336
7337 // If an array was passed in, assume that it is an array of form elements.
7338 if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
7339 // Serialize the form elements
7340 jQuery.each( a, function() {
7341 add( this.name, this.value );
7342 });
7343
7344 } else {
7345 // If traditional, encode the "old" way (the way 1.3.2 or older
7346 // did it), otherwise encode params recursively.
7347 for ( var prefix in a ) {
7348 buildParams( prefix, a[ prefix ], traditional, add );
7349 }
7350 }
7351
7352 // Return the resulting serialization
7353 return s.join( "&" ).replace( r20, "+" );
7354 }
7355 });
7356
7357 function buildParams( prefix, obj, traditional, add ) {
7358 if ( jQuery.isArray( obj ) ) {
7359 // Serialize array item.
7360 jQuery.each( obj, function( i, v ) {
7361 if ( traditional || rbracket.test( prefix ) ) {
7362 // Treat each array item as a scalar.
7363 add( prefix, v );
7364
7365 } else {
7366 // If array item is non-scalar (array or object), encode its
7367 // numeric index to resolve deserialization ambiguity issues.
7368 // Note that rack (as of 1.0.0) can't currently deserialize
7369 // nested arrays properly, and attempting to do so may cause
7370 // a server error. Possible fixes are to modify rack's
7371 // deserialization algorithm or to provide an option or flag
7372 // to force array serialization to be shallow.
7373 buildParams( prefix + "[" + ( typeof v === "object" || jQuery.isArray(v) ? i : "" ) + "]", v, traditional, add );
7374 }
7375 });
7376
7377 } else if ( !traditional && obj != null && typeof obj === "object" ) {
7378 // Serialize object item.
7379 for ( var name in obj ) {
7380 buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
7381 }
7382
7383 } else {
7384 // Serialize scalar item.
7385 add( prefix, obj );
7386 }
7387 }
7388
7389 // This is still on the jQuery object... for now
7390 // Want to move this to jQuery.ajax some day
7391 jQuery.extend({
7392
7393 // Counter for holding the number of active queries
7394 active: 0,
7395
7396 // Last-Modified header cache for next request
7397 lastModified: {},
7398 etag: {}
7399
7400 });
7401
7402 /* Handles responses to an ajax request:
7403 * - sets all responseXXX fields accordingly
7404 * - finds the right dataType (mediates between content-type and expected dataType)
7405 * - returns the corresponding response
7406 */
7407 function ajaxHandleResponses( s, jqXHR, responses ) {
7408
7409 var contents = s.contents,
7410 dataTypes = s.dataTypes,
7411 responseFields = s.responseFields,
7412 ct,
7413 type,
7414 finalDataType,
7415 firstDataType;
7416
7417 // Fill responseXXX fields
7418 for( type in responseFields ) {
7419 if ( type in responses ) {
7420 jqXHR[ responseFields[type] ] = responses[ type ];
7421 }
7422 }
7423
7424 // Remove auto dataType and get content-type in the process
7425 while( dataTypes[ 0 ] === "*" ) {
7426 dataTypes.shift();
7427 if ( ct === undefined ) {
7428 ct = s.mimeType || jqXHR.getResponseHeader( "content-type" );
7429 }
7430 }
7431
7432 // Check if we're dealing with a known content-type
7433 if ( ct ) {
7434 for ( type in contents ) {
7435 if ( contents[ type ] && contents[ type ].test( ct ) ) {
7436 dataTypes.unshift( type );
7437 break;
7438 }
7439 }
7440 }
7441
7442 // Check to see if we have a response for the expected dataType
7443 if ( dataTypes[ 0 ] in responses ) {
7444 finalDataType = dataTypes[ 0 ];
7445 } else {
7446 // Try convertible dataTypes
7447 for ( type in responses ) {
7448 if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {
7449 finalDataType = type;
7450 break;
7451 }
7452 if ( !firstDataType ) {
7453 firstDataType = type;
7454 }
7455 }
7456 // Or just use first one
7457 finalDataType = finalDataType || firstDataType;
7458 }
7459
7460 // If we found a dataType
7461 // We add the dataType to the list if needed
7462 // and return the corresponding response
7463 if ( finalDataType ) {
7464 if ( finalDataType !== dataTypes[ 0 ] ) {
7465 dataTypes.unshift( finalDataType );
7466 }
7467 return responses[ finalDataType ];
7468 }
7469 }
7470
7471 // Chain conversions given the request and the original response
7472 function ajaxConvert( s, response ) {
7473
7474 // Apply the dataFilter if provided
7475 if ( s.dataFilter ) {
7476 response = s.dataFilter( response, s.dataType );
7477 }
7478
7479 var dataTypes = s.dataTypes,
7480 converters = {},
7481 i,
7482 key,
7483 length = dataTypes.length,
7484 tmp,
7485 // Current and previous dataTypes
7486 current = dataTypes[ 0 ],
7487 prev,
7488 // Conversion expression
7489 conversion,
7490 // Conversion function
7491 conv,
7492 // Conversion functions (transitive conversion)
7493 conv1,
7494 conv2;
7495
7496 // For each dataType in the chain
7497 for( i = 1; i < length; i++ ) {
7498
7499 // Create converters map
7500 // with lowercased keys
7501 if ( i === 1 ) {
7502 for( key in s.converters ) {
7503 if( typeof key === "string" ) {
7504 converters[ key.toLowerCase() ] = s.converters[ key ];
7505 }
7506 }
7507 }
7508
7509 // Get the dataTypes
7510 prev = current;
7511 current = dataTypes[ i ];
7512
7513 // If current is auto dataType, update it to prev
7514 if( current === "*" ) {
7515 current = prev;
7516 // If no auto and dataTypes are actually different
7517 } else if ( prev !== "*" && prev !== current ) {
7518
7519 // Get the converter
7520 conversion = prev + " " + current;
7521 conv = converters[ conversion ] || converters[ "* " + current ];
7522
7523 // If there is no direct converter, search transitively
7524 if ( !conv ) {
7525 conv2 = undefined;
7526 for( conv1 in converters ) {
7527 tmp = conv1.split( " " );
7528 if ( tmp[ 0 ] === prev || tmp[ 0 ] === "*" ) {
7529 conv2 = converters[ tmp[1] + " " + current ];
7530 if ( conv2 ) {
7531 conv1 = converters[ conv1 ];
7532 if ( conv1 === true ) {
7533 conv = conv2;
7534 } else if ( conv2 === true ) {
7535 conv = conv1;
7536 }
7537 break;
7538 }
7539 }
7540 }
7541 }
7542 // If we found no converter, dispatch an error
7543 if ( !( conv || conv2 ) ) {
7544 jQuery.error( "No conversion from " + conversion.replace(" "," to ") );
7545 }
7546 // If found converter is not an equivalence
7547 if ( conv !== true ) {
7548 // Convert with 1 or 2 converters accordingly
7549 response = conv ? conv( response ) : conv2( conv1(response) );
7550 }
7551 }
7552 }
7553 return response;
7554 }
7555
7556
7557
7558
7559 var jsc = jQuery.now(),
7560 jsre = /(\=)\?(&|$)|\?\?/i;
7561
7562 // Default jsonp settings
7563 jQuery.ajaxSetup({
7564 jsonp: "callback",
7565 jsonpCallback: function() {
7566 return jQuery.expando + "_" + ( jsc++ );
7567 }
7568 });
7569
7570 // Detect, normalize options and install callbacks for jsonp requests
7571 jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
7572
7573 var inspectData = s.contentType === "application/x-www-form-urlencoded" &&
7574 ( typeof s.data === "string" );
7575
7576 if ( s.dataTypes[ 0 ] === "jsonp" ||
7577 s.jsonp !== false && ( jsre.test( s.url ) ||
7578 inspectData && jsre.test( s.data ) ) ) {
7579
7580 var responseContainer,
7581 jsonpCallback = s.jsonpCallback =
7582 jQuery.isFunction( s.jsonpCallback ) ? s.jsonpCallback() : s.jsonpCallback,
7583 previous = window[ jsonpCallback ],
7584 url = s.url,
7585 data = s.data,
7586 replace = "$1" + jsonpCallback + "$2";
7587
7588 if ( s.jsonp !== false ) {
7589 url = url.replace( jsre, replace );
7590 if ( s.url === url ) {
7591 if ( inspectData ) {
7592 data = data.replace( jsre, replace );
7593 }
7594 if ( s.data === data ) {
7595 // Add callback manually
7596 url += (/\?/.test( url ) ? "&" : "?") + s.jsonp + "=" + jsonpCallback;
7597 }
7598 }
7599 }
7600
7601 s.url = url;
7602 s.data = data;
7603
7604 // Install callback
7605 window[ jsonpCallback ] = function( response ) {
7606 responseContainer = [ response ];
7607 };
7608
7609 // Clean-up function
7610 jqXHR.always(function() {
7611 // Set callback back to previous value
7612 window[ jsonpCallback ] = previous;
7613 // Call if it was a function and we have a response
7614 if ( responseContainer && jQuery.isFunction( previous ) ) {
7615 window[ jsonpCallback ]( responseContainer[ 0 ] );
7616 }
7617 });
7618
7619 // Use data converter to retrieve json after script execution
7620 s.converters["script json"] = function() {
7621 if ( !responseContainer ) {
7622 jQuery.error( jsonpCallback + " was not called" );
7623 }
7624 return responseContainer[ 0 ];
7625 };
7626
7627 // force json dataType
7628 s.dataTypes[ 0 ] = "json";
7629
7630 // Delegate to script
7631 return "script";
7632 }
7633 });
7634
7635
7636
7637
7638 // Install script dataType
7639 jQuery.ajaxSetup({
7640 accepts: {
7641 script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
7642 },
7643 contents: {
7644 script: /javascript|ecmascript/
7645 },
7646 converters: {
7647 "text script": function( text ) {
7648 jQuery.globalEval( text );
7649 return text;
7650 }
7651 }
7652 });
7653
7654 // Handle cache's special case and global
7655 jQuery.ajaxPrefilter( "script", function( s ) {
7656 if ( s.cache === undefined ) {
7657 s.cache = false;
7658 }
7659 if ( s.crossDomain ) {
7660 s.type = "GET";
7661 s.global = false;
7662 }
7663 });
7664
7665 // Bind script tag hack transport
7666 jQuery.ajaxTransport( "script", function(s) {
7667
7668 // This transport only deals with cross domain requests
7669 if ( s.crossDomain ) {
7670
7671 var script,
7672 head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement;
7673
7674 return {
7675
7676 send: function( _, callback ) {
7677
7678 script = document.createElement( "script" );
7679
7680 script.async = "async";
7681
7682 if ( s.scriptCharset ) {
7683 script.charset = s.scriptCharset;
7684 }
7685
7686 script.src = s.url;
7687
7688 // Attach handlers for all browsers
7689 script.onload = script.onreadystatechange = function( _, isAbort ) {
7690
7691 if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {
7692
7693 // Handle memory leak in IE
7694 script.onload = script.onreadystatechange = null;
7695
7696 // Remove the script
7697 if ( head && script.parentNode ) {
7698 head.removeChild( script );
7699 }
7700
7701 // Dereference the script
7702 script = undefined;
7703
7704 // Callback if not abort
7705 if ( !isAbort ) {
7706 callback( 200, "success" );
7707 }
7708 }
7709 };
7710 // Use insertBefore instead of appendChild to circumvent an IE6 bug.
7711 // This arises when a base node is used (#2709 and #4378).
7712 head.insertBefore( script, head.firstChild );
7713 },
7714
7715 abort: function() {
7716 if ( script ) {
7717 script.onload( 0, 1 );
7718 }
7719 }
7720 };
7721 }
7722 });
7723
7724
7725
7726
7727 var // #5280: Internet Explorer will keep connections alive if we don't abort on unload
7728 xhrOnUnloadAbort = window.ActiveXObject ? function() {
7729 // Abort all pending requests
7730 for ( var key in xhrCallbacks ) {
7731 xhrCallbacks[ key ]( 0, 1 );
7732 }
7733 } : false,
7734 xhrId = 0,
7735 xhrCallbacks;
7736
7737 // Functions to create xhrs
7738 function createStandardXHR() {
7739 try {
7740 return new window.XMLHttpRequest();
7741 } catch( e ) {}
7742 }
7743
7744 function createActiveXHR() {
7745 try {
7746 return new window.ActiveXObject( "Microsoft.XMLHTTP" );
7747 } catch( e ) {}
7748 }
7749
7750 // Create the request object
7751 // (This is still attached to ajaxSettings for backward compatibility)
7752 jQuery.ajaxSettings.xhr = window.ActiveXObject ?
7753 /* Microsoft failed to properly
7754 * implement the XMLHttpRequest in IE7 (can't request local files),
7755 * so we use the ActiveXObject when it is available
7756 * Additionally XMLHttpRequest can be disabled in IE7/IE8 so
7757 * we need a fallback.
7758 */
7759 function() {
7760 return !this.isLocal && createStandardXHR() || createActiveXHR();
7761 } :
7762 // For all other browsers, use the standard XMLHttpRequest object
7763 createStandardXHR;
7764
7765 // Determine support properties
7766 (function( xhr ) {
7767 jQuery.extend( jQuery.support, {
7768 ajax: !!xhr,
7769 cors: !!xhr && ( "withCredentials" in xhr )
7770 });
7771 })( jQuery.ajaxSettings.xhr() );
7772
7773 // Create transport if the browser can provide an xhr
7774 if ( jQuery.support.ajax ) {
7775
7776 jQuery.ajaxTransport(function( s ) {
7777 // Cross domain only allowed if supported through XMLHttpRequest
7778 if ( !s.crossDomain || jQuery.support.cors ) {
7779
7780 var callback;
7781
7782 return {
7783 send: function( headers, complete ) {
7784
7785 // Get a new xhr
7786 var xhr = s.xhr(),
7787 handle,
7788 i;
7789
7790 // Open the socket
7791 // Passing null username, generates a login popup on Opera (#2865)
7792 if ( s.username ) {
7793 xhr.open( s.type, s.url, s.async, s.username, s.password );
7794 } else {
7795 xhr.open( s.type, s.url, s.async );
7796 }
7797
7798 // Apply custom fields if provided
7799 if ( s.xhrFields ) {
7800 for ( i in s.xhrFields ) {
7801 xhr[ i ] = s.xhrFields[ i ];
7802 }
7803 }
7804
7805 // Override mime type if needed
7806 if ( s.mimeType && xhr.overrideMimeType ) {
7807 xhr.overrideMimeType( s.mimeType );
7808 }
7809
7810 // X-Requested-With header
7811 // For cross-domain requests, seeing as conditions for a preflight are
7812 // akin to a jigsaw puzzle, we simply never set it to be sure.
7813 // (it can always be set on a per-request basis or even using ajaxSetup)
7814 // For same-domain requests, won't change header if already provided.
7815 if ( !s.crossDomain && !headers["X-Requested-With"] ) {
7816 headers[ "X-Requested-With" ] = "XMLHttpRequest";
7817 }
7818
7819 // Need an extra try/catch for cross domain requests in Firefox 3
7820 try {
7821 for ( i in headers ) {
7822 xhr.setRequestHeader( i, headers[ i ] );
7823 }
7824 } catch( _ ) {}
7825
7826 // Do send the request
7827 // This may raise an exception which is actually
7828 // handled in jQuery.ajax (so no try/catch here)
7829 xhr.send( ( s.hasContent && s.data ) || null );
7830
7831 // Listener
7832 callback = function( _, isAbort ) {
7833
7834 var status,
7835 statusText,
7836 responseHeaders,
7837 responses,
7838 xml;
7839
7840 // Firefox throws exceptions when accessing properties
7841 // of an xhr when a network error occured
7842 // http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE)
7843 try {
7844
7845 // Was never called and is aborted or complete
7846 if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
7847
7848 // Only called once
7849 callback = undefined;
7850
7851 // Do not keep as active anymore
7852 if ( handle ) {
7853 xhr.onreadystatechange = jQuery.noop;
7854 if ( xhrOnUnloadAbort ) {
7855 delete xhrCallbacks[ handle ];
7856 }
7857 }
7858
7859 // If it's an abort
7860 if ( isAbort ) {
7861 // Abort it manually if needed
7862 if ( xhr.readyState !== 4 ) {
7863 xhr.abort();
7864 }
7865 } else {
7866 status = xhr.status;
7867 responseHeaders = xhr.getAllResponseHeaders();
7868 responses = {};
7869 xml = xhr.responseXML;
7870
7871 // Construct response list
7872 if ( xml && xml.documentElement /* #4958 */ ) {
7873 responses.xml = xml;
7874 }
7875 responses.text = xhr.responseText;
7876
7877 // Firefox throws an exception when accessing
7878 // statusText for faulty cross-domain requests
7879 try {
7880 statusText = xhr.statusText;
7881 } catch( e ) {
7882 // We normalize with Webkit giving an empty statusText
7883 statusText = "";
7884 }
7885
7886 // Filter status for non standard behaviors
7887
7888 // If the request is local and we have data: assume a success
7889 // (success with no data won't get notified, that's the best we
7890 // can do given current implementations)
7891 if ( !status && s.isLocal && !s.crossDomain ) {
7892 status = responses.text ? 200 : 404;
7893 // IE - #1450: sometimes returns 1223 when it should be 204
7894 } else if ( status === 1223 ) {
7895 status = 204;
7896 }
7897 }
7898 }
7899 } catch( firefoxAccessException ) {
7900 if ( !isAbort ) {
7901 complete( -1, firefoxAccessException );
7902 }
7903 }
7904
7905 // Call complete if needed
7906 if ( responses ) {
7907 complete( status, statusText, responses, responseHeaders );
7908 }
7909 };
7910
7911 // if we're in sync mode or it's in cache
7912 // and has been retrieved directly (IE6 & IE7)
7913 // we need to manually fire the callback
7914 if ( !s.async || xhr.readyState === 4 ) {
7915 callback();
7916 } else {
7917 handle = ++xhrId;
7918 if ( xhrOnUnloadAbort ) {
7919 // Create the active xhrs callbacks list if needed
7920 // and attach the unload handler
7921 if ( !xhrCallbacks ) {
7922 xhrCallbacks = {};
7923 jQuery( window ).unload( xhrOnUnloadAbort );
7924 }
7925 // Add to list of active xhrs callbacks
7926 xhrCallbacks[ handle ] = callback;
7927 }
7928 xhr.onreadystatechange = callback;
7929 }
7930 },
7931
7932 abort: function() {
7933 if ( callback ) {
7934 callback(0,1);
7935 }
7936 }
7937 };
7938 }
7939 });
7940 }
7941
7942
7943
7944
7945 var elemdisplay = {},
7946 iframe, iframeDoc,
7947 rfxtypes = /^(?:toggle|show|hide)$/,
7948 rfxnum = /^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,
7949 timerId,
7950 fxAttrs = [
7951 // height animations
7952 [ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
7953 // width animations
7954 [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
7955 // opacity animations
7956 [ "opacity" ]
7957 ],
7958 fxNow,
7959 requestAnimationFrame = window.webkitRequestAnimationFrame ||
7960 window.mozRequestAnimationFrame ||
7961 window.oRequestAnimationFrame;
7962
7963 jQuery.fn.extend({
7964 show: function( speed, easing, callback ) {
7965 var elem, display;
7966
7967 if ( speed || speed === 0 ) {
7968 return this.animate( genFx("show", 3), speed, easing, callback);
7969
7970 } else {
7971 for ( var i = 0, j = this.length; i < j; i++ ) {
7972 elem = this[i];
7973
7974 if ( elem.style ) {
7975 display = elem.style.display;
7976
7977 // Reset the inline display of this element to learn if it is
7978 // being hidden by cascaded rules or not
7979 if ( !jQuery._data(elem, "olddisplay") && display === "none" ) {
7980 display = elem.style.display = "";
7981 }
7982
7983 // Set elements which have been overridden with display: none
7984 // in a stylesheet to whatever the default browser style is
7985 // for such an element
7986 if ( display === "" && jQuery.css( elem, "display" ) === "none" ) {
7987 jQuery._data(elem, "olddisplay", defaultDisplay(elem.nodeName));
7988 }
7989 }
7990 }
7991
7992 // Set the display of most of the elements in a second loop
7993 // to avoid the constant reflow
7994 for ( i = 0; i < j; i++ ) {
7995 elem = this[i];
7996
7997 if ( elem.style ) {
7998 display = elem.style.display;
7999
8000 if ( display === "" || display === "none" ) {
8001 elem.style.display = jQuery._data(elem, "olddisplay") || "";
8002 }
8003 }
8004 }
8005
8006 return this;
8007 }
8008 },
8009
8010 hide: function( speed, easing, callback ) {
8011 if ( speed || speed === 0 ) {
8012 return this.animate( genFx("hide", 3), speed, easing, callback);
8013
8014 } else {
8015 for ( var i = 0, j = this.length; i < j; i++ ) {
8016 if ( this[i].style ) {
8017 var display = jQuery.css( this[i], "display" );
8018
8019 if ( display !== "none" && !jQuery._data( this[i], "olddisplay" ) ) {
8020 jQuery._data( this[i], "olddisplay", display );
8021 }
8022 }
8023 }
8024
8025 // Set the display of the elements in a second loop
8026 // to avoid the constant reflow
8027 for ( i = 0; i < j; i++ ) {
8028 if ( this[i].style ) {
8029 this[i].style.display = "none";
8030 }
8031 }
8032
8033 return this;
8034 }
8035 },
8036
8037 // Save the old toggle function
8038 _toggle: jQuery.fn.toggle,
8039
8040 toggle: function( fn, fn2, callback ) {
8041 var bool = typeof fn === "boolean";
8042
8043 if ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) {
8044 this._toggle.apply( this, arguments );
8045
8046 } else if ( fn == null || bool ) {
8047 this.each(function() {
8048 var state = bool ? fn : jQuery(this).is(":hidden");
8049 jQuery(this)[ state ? "show" : "hide" ]();
8050 });
8051
8052 } else {
8053 this.animate(genFx("toggle", 3), fn, fn2, callback);
8054 }
8055
8056 return this;
8057 },
8058
8059 fadeTo: function( speed, to, easing, callback ) {
8060 return this.filter(":hidden").css("opacity", 0).show().end()
8061 .animate({opacity: to}, speed, easing, callback);
8062 },
8063
8064 animate: function( prop, speed, easing, callback ) {
8065 var optall = jQuery.speed(speed, easing, callback);
8066
8067 if ( jQuery.isEmptyObject( prop ) ) {
8068 return this.each( optall.complete, [ false ] );
8069 }
8070
8071 // Do not change referenced properties as per-property easing will be lost
8072 prop = jQuery.extend( {}, prop );
8073
8074 return this[ optall.queue === false ? "each" : "queue" ](function() {
8075 // XXX 'this' does not always have a nodeName when running the
8076 // test suite
8077
8078 if ( optall.queue === false ) {
8079 jQuery._mark( this );
8080 }
8081
8082 var opt = jQuery.extend( {}, optall ),
8083 isElement = this.nodeType === 1,
8084 hidden = isElement && jQuery(this).is(":hidden"),
8085 name, val, p,
8086 display, e,
8087 parts, start, end, unit;
8088
8089 // will store per property easing and be used to determine when an animation is complete
8090 opt.animatedProperties = {};
8091
8092 for ( p in prop ) {
8093
8094 // property name normalization
8095 name = jQuery.camelCase( p );
8096 if ( p !== name ) {
8097 prop[ name ] = prop[ p ];
8098 delete prop[ p ];
8099 }
8100
8101 val = prop[ name ];
8102
8103 // easing resolution: per property > opt.specialEasing > opt.easing > 'swing' (default)
8104 if ( jQuery.isArray( val ) ) {
8105 opt.animatedProperties[ name ] = val[ 1 ];
8106 val = prop[ name ] = val[ 0 ];
8107 } else {
8108 opt.animatedProperties[ name ] = opt.specialEasing && opt.specialEasing[ name ] || opt.easing || 'swing';
8109 }
8110
8111 if ( val === "hide" && hidden || val === "show" && !hidden ) {
8112 return opt.complete.call( this );
8113 }
8114
8115 if ( isElement && ( name === "height" || name === "width" ) ) {
8116 // Make sure that nothing sneaks out
8117 // Record all 3 overflow attributes because IE does not
8118 // change the overflow attribute when overflowX and
8119 // overflowY are set to the same value
8120 opt.overflow = [ this.style.overflow, this.style.overflowX, this.style.overflowY ];
8121
8122 // Set display property to inline-block for height/width
8123 // animations on inline elements that are having width/height
8124 // animated
8125 if ( jQuery.css( this, "display" ) === "inline" &&
8126 jQuery.css( this, "float" ) === "none" ) {
8127 if ( !jQuery.support.inlineBlockNeedsLayout ) {
8128 this.style.display = "inline-block";
8129
8130 } else {
8131 display = defaultDisplay( this.nodeName );
8132
8133 // inline-level elements accept inline-block;
8134 // block-level elements need to be inline with layout
8135 if ( display === "inline" ) {
8136 this.style.display = "inline-block";
8137
8138 } else {
8139 this.style.display = "inline";
8140 this.style.zoom = 1;
8141 }
8142 }
8143 }
8144 }
8145 }
8146
8147 if ( opt.overflow != null ) {
8148 this.style.overflow = "hidden";
8149 }
8150
8151 for ( p in prop ) {
8152 e = new jQuery.fx( this, opt, p );
8153 val = prop[ p ];
8154
8155 if ( rfxtypes.test(val) ) {
8156 e[ val === "toggle" ? hidden ? "show" : "hide" : val ]();
8157
8158 } else {
8159 parts = rfxnum.exec( val );
8160 start = e.cur();
8161
8162 if ( parts ) {
8163 end = parseFloat( parts[2] );
8164 unit = parts[3] || ( jQuery.cssNumber[ p ] ? "" : "px" );
8165
8166 // We need to compute starting value
8167 if ( unit !== "px" ) {
8168 jQuery.style( this, p, (end || 1) + unit);
8169 start = ((end || 1) / e.cur()) * start;
8170 jQuery.style( this, p, start + unit);
8171 }
8172
8173 // If a +=/-= token was provided, we're doing a relative animation
8174 if ( parts[1] ) {
8175 end = ( (parts[ 1 ] === "-=" ? -1 : 1) * end ) + start;
8176 }
8177
8178 e.custom( start, end, unit );
8179
8180 } else {
8181 e.custom( start, val, "" );
8182 }
8183 }
8184 }
8185
8186 // For JS strict compliance
8187 return true;
8188 });
8189 },
8190
8191 stop: function( clearQueue, gotoEnd ) {
8192 if ( clearQueue ) {
8193 this.queue([]);
8194 }
8195
8196 this.each(function() {
8197 var timers = jQuery.timers,
8198 i = timers.length;
8199 // clear marker counters if we know they won't be
8200 if ( !gotoEnd ) {
8201 jQuery._unmark( true, this );
8202 }
8203 while ( i-- ) {
8204 if ( timers[i].elem === this ) {
8205 if (gotoEnd) {
8206 // force the next step to be the last
8207 timers[i](true);
8208 }
8209
8210 timers.splice(i, 1);
8211 }
8212 }
8213 });
8214
8215 // start the next in the queue if the last step wasn't forced
8216 if ( !gotoEnd ) {
8217 this.dequeue();
8218 }
8219
8220 return this;
8221 }
8222
8223 });
8224
8225 // Animations created synchronously will run synchronously
8226 function createFxNow() {
8227 setTimeout( clearFxNow, 0 );
8228 return ( fxNow = jQuery.now() );
8229 }
8230
8231 function clearFxNow() {
8232 fxNow = undefined;
8233 }
8234
8235 // Generate parameters to create a standard animation
8236 function genFx( type, num ) {
8237 var obj = {};
8238
8239 jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function() {
8240 obj[ this ] = type;
8241 });
8242
8243 return obj;
8244 }
8245
8246 // Generate shortcuts for custom animations
8247 jQuery.each({
8248 slideDown: genFx("show", 1),
8249 slideUp: genFx("hide", 1),
8250 slideToggle: genFx("toggle", 1),
8251 fadeIn: { opacity: "show" },
8252 fadeOut: { opacity: "hide" },
8253 fadeToggle: { opacity: "toggle" }
8254 }, function( name, props ) {
8255 jQuery.fn[ name ] = function( speed, easing, callback ) {
8256 return this.animate( props, speed, easing, callback );
8257 };
8258 });
8259
8260 jQuery.extend({
8261 speed: function( speed, easing, fn ) {
8262 var opt = speed && typeof speed === "object" ? jQuery.extend({}, speed) : {
8263 complete: fn || !fn && easing ||
8264 jQuery.isFunction( speed ) && speed,
8265 duration: speed,
8266 easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
8267 };
8268
8269 opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
8270 opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[opt.duration] : jQuery.fx.speeds._default;
8271
8272 // Queueing
8273 opt.old = opt.complete;
8274 opt.complete = function( noUnmark ) {
8275 if ( opt.queue !== false ) {
8276 jQuery.dequeue( this );
8277 } else if ( noUnmark !== false ) {
8278 jQuery._unmark( this );
8279 }
8280
8281 if ( jQuery.isFunction( opt.old ) ) {
8282 opt.old.call( this );
8283 }
8284 };
8285
8286 return opt;
8287 },
8288
8289 easing: {
8290 linear: function( p, n, firstNum, diff ) {
8291 return firstNum + diff * p;
8292 },
8293 swing: function( p, n, firstNum, diff ) {
8294 return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
8295 }
8296 },
8297
8298 timers: [],
8299
8300 fx: function( elem, options, prop ) {
8301 this.options = options;
8302 this.elem = elem;
8303 this.prop = prop;
8304
8305 options.orig = options.orig || {};
8306 }
8307
8308 });
8309
8310 jQuery.fx.prototype = {
8311 // Simple function for setting a style value
8312 update: function() {
8313 if ( this.options.step ) {
8314 this.options.step.call( this.elem, this.now, this );
8315 }
8316
8317 (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
8318 },
8319
8320 // Get the current size
8321 cur: function() {
8322 if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) ) {
8323 return this.elem[ this.prop ];
8324 }
8325
8326 var parsed,
8327 r = jQuery.css( this.elem, this.prop );
8328 // Empty strings, null, undefined and "auto" are converted to 0,
8329 // complex values such as "rotate(1rad)" are returned as is,
8330 // simple values such as "10px" are parsed to Float.
8331 return isNaN( parsed = parseFloat( r ) ) ? !r || r === "auto" ? 0 : r : parsed;
8332 },
8333
8334 // Start an animation from one number to another
8335 custom: function( from, to, unit ) {
8336 var self = this,
8337 fx = jQuery.fx,
8338 raf;
8339
8340 this.startTime = fxNow || createFxNow();
8341 this.start = from;
8342 this.end = to;
8343 this.unit = unit || this.unit || ( jQuery.cssNumber[ this.prop ] ? "" : "px" );
8344 this.now = this.start;
8345 this.pos = this.state = 0;
8346
8347 function t( gotoEnd ) {
8348 return self.step(gotoEnd);
8349 }
8350
8351 t.elem = this.elem;
8352
8353 if ( t() && jQuery.timers.push(t) && !timerId ) {
8354 // Use requestAnimationFrame instead of setInterval if available
8355 if ( requestAnimationFrame ) {
8356 timerId = 1;
8357 raf = function() {
8358 // When timerId gets set to null at any point, this stops
8359 if ( timerId ) {
8360 requestAnimationFrame( raf );
8361 fx.tick();
8362 }
8363 };
8364 requestAnimationFrame( raf );
8365 } else {
8366 timerId = setInterval( fx.tick, fx.interval );
8367 }
8368 }
8369 },
8370
8371 // Simple 'show' function
8372 show: function() {
8373 // Remember where we started, so that we can go back to it later
8374 this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
8375 this.options.show = true;
8376
8377 // Begin the animation
8378 // Make sure that we start at a small width/height to avoid any
8379 // flash of content
8380 this.custom(this.prop === "width" || this.prop === "height" ? 1 : 0, this.cur());
8381
8382 // Start by showing the element
8383 jQuery( this.elem ).show();
8384 },
8385
8386 // Simple 'hide' function
8387 hide: function() {
8388 // Remember where we started, so that we can go back to it later
8389 this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
8390 this.options.hide = true;
8391
8392 // Begin the animation
8393 this.custom(this.cur(), 0);
8394 },
8395
8396 // Each step of an animation
8397 step: function( gotoEnd ) {
8398 var t = fxNow || createFxNow(),
8399 done = true,
8400 elem = this.elem,
8401 options = this.options,
8402 i, n;
8403
8404 if ( gotoEnd || t >= options.duration + this.startTime ) {
8405 this.now = this.end;
8406 this.pos = this.state = 1;
8407 this.update();
8408
8409 options.animatedProperties[ this.prop ] = true;
8410
8411 for ( i in options.animatedProperties ) {
8412 if ( options.animatedProperties[i] !== true ) {
8413 done = false;
8414 }
8415 }
8416
8417 if ( done ) {
8418 // Reset the overflow
8419 if ( options.overflow != null && !jQuery.support.shrinkWrapBlocks ) {
8420
8421 jQuery.each( [ "", "X", "Y" ], function (index, value) {
8422 elem.style[ "overflow" + value ] = options.overflow[index];
8423 });
8424 }
8425
8426 // Hide the element if the "hide" operation was done
8427 if ( options.hide ) {
8428 jQuery(elem).hide();
8429 }
8430
8431 // Reset the properties, if the item has been hidden or shown
8432 if ( options.hide || options.show ) {
8433 for ( var p in options.animatedProperties ) {
8434 jQuery.style( elem, p, options.orig[p] );
8435 }
8436 }
8437
8438 // Execute the complete function
8439 options.complete.call( elem );
8440 }
8441
8442 return false;
8443
8444 } else {
8445 // classical easing cannot be used with an Infinity duration
8446 if ( options.duration == Infinity ) {
8447 this.now = t;
8448 } else {
8449 n = t - this.startTime;
8450 this.state = n / options.duration;
8451
8452 // Perform the easing function, defaults to swing
8453 this.pos = jQuery.easing[ options.animatedProperties[ this.prop ] ]( this.state, n, 0, 1, options.duration );
8454 this.now = this.start + ((this.end - this.start) * this.pos);
8455 }
8456 // Perform the next step of the animation
8457 this.update();
8458 }
8459
8460 return true;
8461 }
8462 };
8463
8464 jQuery.extend( jQuery.fx, {
8465 tick: function() {
8466 for ( var timers = jQuery.timers, i = 0 ; i < timers.length ; ++i ) {
8467 if ( !timers[i]() ) {
8468 timers.splice(i--, 1);
8469 }
8470 }
8471
8472 if ( !timers.length ) {
8473 jQuery.fx.stop();
8474 }
8475 },
8476
8477 interval: 13,
8478
8479 stop: function() {
8480 clearInterval( timerId );
8481 timerId = null;
8482 },
8483
8484 speeds: {
8485 slow: 600,
8486 fast: 200,
8487 // Default speed
8488 _default: 400
8489 },
8490
8491 step: {
8492 opacity: function( fx ) {
8493 jQuery.style( fx.elem, "opacity", fx.now );
8494 },
8495
8496 _default: function( fx ) {
8497 if ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) {
8498 fx.elem.style[ fx.prop ] = (fx.prop === "width" || fx.prop === "height" ? Math.max(0, fx.now) : fx.now) + fx.unit;
8499 } else {
8500 fx.elem[ fx.prop ] = fx.now;
8501 }
8502 }
8503 }
8504 });
8505
8506 if ( jQuery.expr && jQuery.expr.filters ) {
8507 jQuery.expr.filters.animated = function( elem ) {
8508 return jQuery.grep(jQuery.timers, function( fn ) {
8509 return elem === fn.elem;
8510 }).length;
8511 };
8512 }
8513
8514 // Try to restore the default display value of an element
8515 function defaultDisplay( nodeName ) {
8516
8517 if ( !elemdisplay[ nodeName ] ) {
8518
8519 var elem = jQuery( "<" + nodeName + ">" ).appendTo( "body" ),
8520 display = elem.css( "display" );
8521
8522 elem.remove();
8523
8524 // If the simple way fails,
8525 // get element's real default display by attaching it to a temp iframe
8526 if ( display === "none" || display === "" ) {
8527 // No iframe to use yet, so create it
8528 if ( !iframe ) {
8529 iframe = document.createElement( "iframe" );
8530 iframe.frameBorder = iframe.width = iframe.height = 0;
8531 }
8532
8533 document.body.appendChild( iframe );
8534
8535 // Create a cacheable copy of the iframe document on first call.
8536 // IE and Opera will allow us to reuse the iframeDoc without re-writing the fake html
8537 // document to it, Webkit & Firefox won't allow reusing the iframe document
8538 if ( !iframeDoc || !iframe.createElement ) {
8539 iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document;
8540 iframeDoc.write( "<!doctype><html><body></body></html>" );
8541 }
8542
8543 elem = iframeDoc.createElement( nodeName );
8544
8545 iframeDoc.body.appendChild( elem );
8546
8547 display = jQuery.css( elem, "display" );
8548
8549 document.body.removeChild( iframe );
8550 }
8551
8552 // Store the correct default display
8553 elemdisplay[ nodeName ] = display;
8554 }
8555
8556 return elemdisplay[ nodeName ];
8557 }
8558
8559
8560
8561
8562 var rtable = /^t(?:able|d|h)$/i,
8563 rroot = /^(?:body|html)$/i;
8564
8565 if ( "getBoundingClientRect" in document.documentElement ) {
8566 jQuery.fn.offset = function( options ) {
8567 var elem = this[0], box;
8568
8569 if ( options ) {
8570 return this.each(function( i ) {
8571 jQuery.offset.setOffset( this, options, i );
8572 });
8573 }
8574
8575 if ( !elem || !elem.ownerDocument ) {
8576 return null;
8577 }
8578
8579 if ( elem === elem.ownerDocument.body ) {
8580 return jQuery.offset.bodyOffset( elem );
8581 }
8582
8583 try {
8584 box = elem.getBoundingClientRect();
8585 } catch(e) {}
8586
8587 var doc = elem.ownerDocument,
8588 docElem = doc.documentElement;
8589
8590 // Make sure we're not dealing with a disconnected DOM node
8591 if ( !box || !jQuery.contains( docElem, elem ) ) {
8592 return box ? { top: box.top, left: box.left } : { top: 0, left: 0 };
8593 }
8594
8595 var body = doc.body,
8596 win = getWindow(doc),
8597 clientTop = docElem.clientTop || body.clientTop || 0,
8598 clientLeft = docElem.clientLeft || body.clientLeft || 0,
8599 scrollTop = win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop || body.scrollTop,
8600 scrollLeft = win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft,
8601 top = box.top + scrollTop - clientTop,
8602 left = box.left + scrollLeft - clientLeft;
8603
8604 return { top: top, left: left };
8605 };
8606
8607 } else {
8608 jQuery.fn.offset = function( options ) {
8609 var elem = this[0];
8610
8611 if ( options ) {
8612 return this.each(function( i ) {
8613 jQuery.offset.setOffset( this, options, i );
8614 });
8615 }
8616
8617 if ( !elem || !elem.ownerDocument ) {
8618 return null;
8619 }
8620
8621 if ( elem === elem.ownerDocument.body ) {
8622 return jQuery.offset.bodyOffset( elem );
8623 }
8624
8625 jQuery.offset.initialize();
8626
8627 var computedStyle,
8628 offsetParent = elem.offsetParent,
8629 prevOffsetParent = elem,
8630 doc = elem.ownerDocument,
8631 docElem = doc.documentElement,
8632 body = doc.body,
8633 defaultView = doc.defaultView,
8634 prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle,
8635 top = elem.offsetTop,
8636 left = elem.offsetLeft;
8637
8638 while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
8639 if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
8640 break;
8641 }
8642
8643 computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle;
8644 top -= elem.scrollTop;
8645 left -= elem.scrollLeft;
8646
8647 if ( elem === offsetParent ) {
8648 top += elem.offsetTop;
8649 left += elem.offsetLeft;
8650
8651 if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && rtable.test(elem.nodeName)) ) {
8652 top += parseFloat( computedStyle.borderTopWidth ) || 0;
8653 left += parseFloat( computedStyle.borderLeftWidth ) || 0;
8654 }
8655
8656 prevOffsetParent = offsetParent;
8657 offsetParent = elem.offsetParent;
8658 }
8659
8660 if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) {
8661 top += parseFloat( computedStyle.borderTopWidth ) || 0;
8662 left += parseFloat( computedStyle.borderLeftWidth ) || 0;
8663 }
8664
8665 prevComputedStyle = computedStyle;
8666 }
8667
8668 if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) {
8669 top += body.offsetTop;
8670 left += body.offsetLeft;
8671 }
8672
8673 if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
8674 top += Math.max( docElem.scrollTop, body.scrollTop );
8675 left += Math.max( docElem.scrollLeft, body.scrollLeft );
8676 }
8677
8678 return { top: top, left: left };
8679 };
8680 }
8681
8682 jQuery.offset = {
8683 initialize: function() {
8684 var body = document.body, container = document.createElement("div"), innerDiv, checkDiv, table, td, bodyMarginTop = parseFloat( jQuery.css(body, "marginTop") ) || 0,
8685 html = "<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";
8686
8687 jQuery.extend( container.style, { position: "absolute", top: 0, left: 0, margin: 0, border: 0, width: "1px", height: "1px", visibility: "hidden" } );
8688
8689 container.innerHTML = html;
8690 body.insertBefore( container, body.firstChild );
8691 innerDiv = container.firstChild;
8692 checkDiv = innerDiv.firstChild;
8693 td = innerDiv.nextSibling.firstChild.firstChild;
8694
8695 this.doesNotAddBorder = (checkDiv.offsetTop !== 5);
8696 this.doesAddBorderForTableAndCells = (td.offsetTop === 5);
8697
8698 checkDiv.style.position = "fixed";
8699 checkDiv.style.top = "20px";
8700
8701 // safari subtracts parent border width here which is 5px
8702 this.supportsFixedPosition = (checkDiv.offsetTop === 20 || checkDiv.offsetTop === 15);
8703 checkDiv.style.position = checkDiv.style.top = "";
8704
8705 innerDiv.style.overflow = "hidden";
8706 innerDiv.style.position = "relative";
8707
8708 this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5);
8709
8710 this.doesNotIncludeMarginInBodyOffset = (body.offsetTop !== bodyMarginTop);
8711
8712 body.removeChild( container );
8713 jQuery.offset.initialize = jQuery.noop;
8714 },
8715
8716 bodyOffset: function( body ) {
8717 var top = body.offsetTop,
8718 left = body.offsetLeft;
8719
8720 jQuery.offset.initialize();
8721
8722 if ( jQuery.offset.doesNotIncludeMarginInBodyOffset ) {
8723 top += parseFloat( jQuery.css(body, "marginTop") ) || 0;
8724 left += parseFloat( jQuery.css(body, "marginLeft") ) || 0;
8725 }
8726
8727 return { top: top, left: left };
8728 },
8729
8730 setOffset: function( elem, options, i ) {
8731 var position = jQuery.css( elem, "position" );
8732
8733 // set position first, in-case top/left are set even on static elem
8734 if ( position === "static" ) {
8735 elem.style.position = "relative";
8736 }
8737
8738 var curElem = jQuery( elem ),
8739 curOffset = curElem.offset(),
8740 curCSSTop = jQuery.css( elem, "top" ),
8741 curCSSLeft = jQuery.css( elem, "left" ),
8742 calculatePosition = (position === "absolute" || position === "fixed") && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1,
8743 props = {}, curPosition = {}, curTop, curLeft;
8744
8745 // need to be able to calculate position if either top or left is auto and position is either absolute or fixed
8746 if ( calculatePosition ) {
8747 curPosition = curElem.position();
8748 curTop = curPosition.top;
8749 curLeft = curPosition.left;
8750 } else {
8751 curTop = parseFloat( curCSSTop ) || 0;
8752 curLeft = parseFloat( curCSSLeft ) || 0;
8753 }
8754
8755 if ( jQuery.isFunction( options ) ) {
8756 options = options.call( elem, i, curOffset );
8757 }
8758
8759 if (options.top != null) {
8760 props.top = (options.top - curOffset.top) + curTop;
8761 }
8762 if (options.left != null) {
8763 props.left = (options.left - curOffset.left) + curLeft;
8764 }
8765
8766 if ( "using" in options ) {
8767 options.using.call( elem, props );
8768 } else {
8769 curElem.css( props );
8770 }
8771 }
8772 };
8773
8774
8775 jQuery.fn.extend({
8776 position: function() {
8777 if ( !this[0] ) {
8778 return null;
8779 }
8780
8781 var elem = this[0],
8782
8783 // Get *real* offsetParent
8784 offsetParent = this.offsetParent(),
8785
8786 // Get correct offsets
8787 offset = this.offset(),
8788 parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();
8789
8790 // Subtract element margins
8791 // note: when an element has margin: auto the offsetLeft and marginLeft
8792 // are the same in Safari causing offset.left to incorrectly be 0
8793 offset.top -= parseFloat( jQuery.css(elem, "marginTop") ) || 0;
8794 offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0;
8795
8796 // Add offsetParent borders
8797 parentOffset.top += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0;
8798 parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0;
8799
8800 // Subtract the two offsets
8801 return {
8802 top: offset.top - parentOffset.top,
8803 left: offset.left - parentOffset.left
8804 };
8805 },
8806
8807 offsetParent: function() {
8808 return this.map(function() {
8809 var offsetParent = this.offsetParent || document.body;
8810 while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) {
8811 offsetParent = offsetParent.offsetParent;
8812 }
8813 return offsetParent;
8814 });
8815 }
8816 });
8817
8818
8819 // Create scrollLeft and scrollTop methods
8820 jQuery.each( ["Left", "Top"], function( i, name ) {
8821 var method = "scroll" + name;
8822
8823 jQuery.fn[ method ] = function( val ) {
8824 var elem, win;
8825
8826 if ( val === undefined ) {
8827 elem = this[ 0 ];
8828
8829 if ( !elem ) {
8830 return null;
8831 }
8832
8833 win = getWindow( elem );
8834
8835 // Return the scroll offset
8836 return win ? ("pageXOffset" in win) ? win[ i ? "pageYOffset" : "pageXOffset" ] :
8837 jQuery.support.boxModel && win.document.documentElement[ method ] ||
8838 win.document.body[ method ] :
8839 elem[ method ];
8840 }
8841
8842 // Set the scroll offset
8843 return this.each(function() {
8844 win = getWindow( this );
8845
8846 if ( win ) {
8847 win.scrollTo(
8848 !i ? val : jQuery( win ).scrollLeft(),
8849 i ? val : jQuery( win ).scrollTop()
8850 );
8851
8852 } else {
8853 this[ method ] = val;
8854 }
8855 });
8856 };
8857 });
8858
8859 function getWindow( elem ) {
8860 return jQuery.isWindow( elem ) ?
8861 elem :
8862 elem.nodeType === 9 ?
8863 elem.defaultView || elem.parentWindow :
8864 false;
8865 }
8866
8867
8868
8869
8870 // Create innerHeight, innerWidth, outerHeight and outerWidth methods
8871 jQuery.each([ "Height", "Width" ], function( i, name ) {
8872
8873 var type = name.toLowerCase();
8874
8875 // innerHeight and innerWidth
8876 jQuery.fn["inner" + name] = function() {
8877 return this[0] ?
8878 parseFloat( jQuery.css( this[0], type, "padding" ) ) :
8879 null;
8880 };
8881
8882 // outerHeight and outerWidth
8883 jQuery.fn["outer" + name] = function( margin ) {
8884 return this[0] ?
8885 parseFloat( jQuery.css( this[0], type, margin ? "margin" : "border" ) ) :
8886 null;
8887 };
8888
8889 jQuery.fn[ type ] = function( size ) {
8890 // Get window width or height
8891 var elem = this[0];
8892 if ( !elem ) {
8893 return size == null ? null : this;
8894 }
8895
8896 if ( jQuery.isFunction( size ) ) {
8897 return this.each(function( i ) {
8898 var self = jQuery( this );
8899 self[ type ]( size.call( this, i, self[ type ]() ) );
8900 });
8901 }
8902
8903 if ( jQuery.isWindow( elem ) ) {
8904 // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
8905 // 3rd condition allows Nokia support, as it supports the docElem prop but not CSS1Compat
8906 var docElemProp = elem.document.documentElement[ "client" + name ];
8907 return elem.document.compatMode === "CSS1Compat" && docElemProp ||
8908 elem.document.body[ "client" + name ] || docElemProp;
8909
8910 // Get document width or height
8911 } else if ( elem.nodeType === 9 ) {
8912 // Either scroll[Width/Height] or offset[Width/Height], whichever is greater
8913 return Math.max(
8914 elem.documentElement["client" + name],
8915 elem.body["scroll" + name], elem.documentElement["scroll" + name],
8916 elem.body["offset" + name], elem.documentElement["offset" + name]
8917 );
8918
8919 // Get or set width or height on the element
8920 } else if ( size === undefined ) {
8921 var orig = jQuery.css( elem, type ),
8922 ret = parseFloat( orig );
8923
8924 return jQuery.isNaN( ret ) ? orig : ret;
8925
8926 // Set the width or height on the element (default to pixels if value is unitless)
8927 } else {
8928 return this.css( type, typeof size === "string" ? size : size + "px" );
8929 }
8930 };
8931
8932 });
8933
8934
8935 window.jQuery = window.$ = jQuery;
8936 })(window);
1  /*!
2   * jQuery JavaScript Library v1.6.1
3   * http://jquery.com/
4   *
5   * Copyright 2011, John Resig
6   * Dual licensed under the MIT or GPL Version 2 licenses.
7   * http://jquery.org/license
8   *
9   * Includes Sizzle.js
10   * http://sizzlejs.com/
11   * Copyright 2011, The Dojo Foundation
12   * Released under the MIT, BSD, and GPL Licenses.
13   *
14   * Date: Thu May 12 15:04:36 2011 -0400
15   */
16  (function( window, undefined ) {
17  
18  // Use the correct document accordingly with window argument (sandbox)
19  var document = window.document,
20          navigator = window.navigator,
21          location = window.location;
22  var jQuery = (function() {
23  
24  // Define a local copy of jQuery
25  var jQuery = function( selector, context ) {
26                  // The jQuery object is actually just the init constructor 'enhanced'
27                  return new jQuery.fn.init( selector, context, rootjQuery );
28          },
29  
30          // Map over jQuery in case of overwrite
31          _jQuery = window.jQuery,
32  
33          // Map over the $ in case of overwrite
34          _$ = window.$,
35  
36          // A central reference to the root jQuery(document)
37          rootjQuery,
38  
39          // A simple way to check for HTML strings or ID strings
40          // (both of which we optimize for)
41          quickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,
42  
43          // Check if a string has a non-whitespace character in it
44          rnotwhite = /\S/,
45  
46          // Used for trimming whitespace
47          trimLeft = /^\s+/,
48          trimRight = /\s+$/,
49  
50          // Check for digits
51          rdigit = /\d/,
52  
53          // Match a standalone tag
54          rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/,
55  
56          // JSON RegExp
57          rvalidchars = /^[\],:{}\s]*$/,
58          rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,
59          rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
60          rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g,
61  
62          // Useragent RegExp
63          rwebkit = /(webkit)[ \/]([\w.]+)/,
64          ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/,
65          rmsie = /(msie) ([\w.]+)/,
66          rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/,
67  
68          // Keep a UserAgent string for use with jQuery.browser
69          userAgent = navigator.userAgent,
70  
71          // For matching the engine and version of the browser
72          browserMatch,
73  
74          // The deferred used on DOM ready
75          readyList,
76  
77          // The ready event handler
78          DOMContentLoaded,
79  
80          // Save a reference to some core methods
81          toString = Object.prototype.toString,
82          hasOwn = Object.prototype.hasOwnProperty,
83          push = Array.prototype.push,
84          slice = Array.prototype.slice,
85          trim = String.prototype.trim,
86          indexOf = Array.prototype.indexOf,
87  
88          // [[Class]] -> type pairs
89          class2type = {};
90  
91  jQuery.fn = jQuery.prototype = {
92          constructor: jQuery,
93          init: function( selector, context, rootjQuery ) {
94                  var match, elem, ret, doc;
95  
96                  // Handle $(""), $(null), or $(undefined)
97                  if ( !selector ) {
98                          return this;
99                  }
100  
101                  // Handle $(DOMElement)
102                  if ( selector.nodeType ) {
103                          this.context = this[0] = selector;
104                          this.length = 1;
105                          return this;
106                  }
107  
108                  // The body element only exists once, optimize finding it
109                  if ( selector === "body" && !context && document.body ) {
110                          this.context = document;
111                          this[0] = document.body;
112                          this.selector = selector;
113                          this.length = 1;
114                          return this;
115                  }
116  
117                  // Handle HTML strings
118                  if ( typeof selector === "string" ) {
119                          // Are we dealing with HTML string or an ID?
120                          if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
121                                  // Assume that strings that start and end with <> are HTML and skip the regex check
122                                  match = [ null, selector, null ];
123  
124                          } else {
125                                  match = quickExpr.exec( selector );
126                          }
127  
128                          // Verify a match, and that no context was specified for #id
129                          if ( match && (match[1] || !context) ) {
130  
131                                  // HANDLE: $(html) -> $(array)
132                                  if ( match[1] ) {
133                                          context = context instanceof jQuery ? context[0] : context;
134                                          doc = (context ? context.ownerDocument || context : document);
135  
136                                          // If a single string is passed in and it's a single tag
137                                          // just do a createElement and skip the rest
138                                          ret = rsingleTag.exec( selector );
139  
140                                          if ( ret ) {
141                                                  if ( jQuery.isPlainObject( context ) ) {
142                                                          selector = [ document.createElement( ret[1] ) ];
143                                                          jQuery.fn.attr.call( selector, context, true );
144  
145                                                  } else {
146                                                          selector = [ doc.createElement( ret[1] ) ];
147                                                  }
148  
149                                          } else {
150                                                  ret = jQuery.buildFragment( [ match[1] ], [ doc ] );
151                                                  selector = (ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment).childNodes;
152                                          }
153  
154                                          return jQuery.merge( this, selector );
155  
156                                  // HANDLE: $("#id")
157                                  } else {
158                                          elem = document.getElementById( match[2] );
159  
160                                          // Check parentNode to catch when Blackberry 4.6 returns
161                                          // nodes that are no longer in the document #6963
162                                          if ( elem && elem.parentNode ) {
163                                                  // Handle the case where IE and Opera return items
164                                                  // by name instead of ID
165                                                  if ( elem.id !== match[2] ) {
166                                                          return rootjQuery.find( selector );
167                                                  }
168  
169                                                  // Otherwise, we inject the element directly into the jQuery object
170                                                  this.length = 1;
171                                                  this[0] = elem;
172                                          }
173  
174                                          this.context = document;
175                                          this.selector = selector;
176                                          return this;
177                                  }
178  
179                          // HANDLE: $(expr, $(...))
180                          } else if ( !context || context.jquery ) {
181                                  return (context || rootjQuery).find( selector );
182  
183                          // HANDLE: $(expr, context)
184                          // (which is just equivalent to: $(context).find(expr)
185                          } else {
186                                  return this.constructor( context ).find( selector );
187                          }
188  
189                  // HANDLE: $(function)
190                  // Shortcut for document ready
191                  } else if ( jQuery.isFunction( selector ) ) {
192                          return rootjQuery.ready( selector );
193                  }
194  
195                  if (selector.selector !== undefined) {
196                          this.selector = selector.selector;
197                          this.context = selector.context;
198                  }
199  
200                  return jQuery.makeArray( selector, this );
201          },
202  
203          // Start with an empty selector
204          selector: "",
205  
206          // The current version of jQuery being used
207          jquery: "1.6.1",
208  
209          // The default length of a jQuery object is 0
210          length: 0,
211  
212          // The number of elements contained in the matched element set
213          size: function() {
214                  return this.length;
215          },
216  
217          toArray: function() {
218                  return slice.call( this, 0 );
219          },
220  
221          // Get the Nth element in the matched element set OR
222          // Get the whole matched element set as a clean array
223          get: function( num ) {
224                  return num == null ?
225  
226                          // Return a 'clean' array
227                          this.toArray() :
228  
229                          // Return just the object
230                          ( num < 0 ? this[ this.length + num ] : this[ num ] );
231          },
232  
233          // Take an array of elements and push it onto the stack
234          // (returning the new matched element set)
235          pushStack: function( elems, name, selector ) {
236                  // Build a new jQuery matched element set
237                  var ret = this.constructor();
238  
239                  if ( jQuery.isArray( elems ) ) {
240                          push.apply( ret, elems );
241  
242                  } else {
243                          jQuery.merge( ret, elems );
244                  }
245  
246                  // Add the old object onto the stack (as a reference)
247                  ret.prevObject = this;
248  
249                  ret.context = this.context;
250  
251                  if ( name === "find" ) {
252                          ret.selector = this.selector + (this.selector ? " " : "") + selector;
253                  } else if ( name ) {
254                          ret.selector = this.selector + "." + name + "(" + selector + ")";
255                  }
256  
257                  // Return the newly-formed element set
258                  return ret;
259          },
260  
261          // Execute a callback for every element in the matched set.
262          // (You can seed the arguments with an array of args, but this is
263          // only used internally.)
264          each: function( callback, args ) {
265                  return jQuery.each( this, callback, args );
266          },
267  
268          ready: function( fn ) {
269                  // Attach the listeners
270                  jQuery.bindReady();
271  
272                  // Add the callback
273                  readyList.done( fn );
274  
275                  return this;
276          },
277  
278          eq: function( i ) {
279                  return i === -1 ?
280                          this.slice( i ) :
281                          this.slice( i, +i + 1 );
282          },
283  
284          first: function() {
285                  return this.eq( 0 );
286          },
287  
288          last: function() {
289                  return this.eq( -1 );
290          },
291  
292          slice: function() {
293                  return this.pushStack( slice.apply( this, arguments ),
294                          "slice", slice.call(arguments).join(",") );
295          },
296  
297          map: function( callback ) {
298                  return this.pushStack( jQuery.map(this, function( elem, i ) {
299                          return callback.call( elem, i, elem );
300                  }));
301          },
302  
303          end: function() {
304                  return this.prevObject || this.constructor(null);
305          },
306  
307          // For internal use only.
308          // Behaves like an Array's method, not like a jQuery method.
309          push: push,
310          sort: [].sort,
311          splice: [].splice
312  };
313  
314  // Give the init function the jQuery prototype for later instantiation
315  jQuery.fn.init.prototype = jQuery.fn;
316  
317  jQuery.extend = jQuery.fn.extend = function() {
318          var options, name, src, copy, copyIsArray, clone,
319                  target = arguments[0] || {},
320                  i = 1,
321                  length = arguments.length,
322                  deep = false;
323  
324          // Handle a deep copy situation
325          if ( typeof target === "boolean" ) {
326                  deep = target;
327                  target = arguments[1] || {};
328                  // skip the boolean and the target
329                  i = 2;
330          }
331  
332          // Handle case when target is a string or something (possible in deep copy)
333          if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
334                  target = {};
335          }
336  
337          // extend jQuery itself if only one argument is passed
338          if ( length === i ) {
339                  target = this;
340                  --i;
341          }
342  
343          for ( ; i < length; i++ ) {
344                  // Only deal with non-null/undefined values
345                  if ( (options = arguments[ i ]) != null ) {
346                          // Extend the base object
347                          for ( name in options ) {
348                                  src = target[ name ];
349                                  copy = options[ name ];
350  
351                                  // Prevent never-ending loop
352                                  if ( target === copy ) {
353                                          continue;
354                                  }
355  
356                                  // Recurse if we're merging plain objects or arrays
357                                  if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
358                                          if ( copyIsArray ) {
359                                                  copyIsArray = false;
360                                                  clone = src && jQuery.isArray(src) ? src : [];
361  
362                                          } else {
363                                                  clone = src && jQuery.isPlainObject(src) ? src : {};
364                                          }
365  
366                                          // Never move original objects, clone them
367                                          target[ name ] = jQuery.extend( deep, clone, copy );
368  
369                                  // Don't bring in undefined values
370                                  } else if ( copy !== undefined ) {
371                                          target[ name ] = copy;
372                                  }
373                          }
374                  }
375          }
376  
377          // Return the modified object
378          return target;
379  };
380  
381  jQuery.extend({
382          noConflict: function( deep ) {
383                  if ( window.$ === jQuery ) {
384                          window.$ = _$;
385                  }
386  
387                  if ( deep && window.jQuery === jQuery ) {
388                          window.jQuery = _jQuery;
389                  }
390  
391                  return jQuery;
392          },
393  
394          // Is the DOM ready to be used? Set to true once it occurs.
395          isReady: false,
396  
397          // A counter to track how many items to wait for before
398          // the ready event fires. See #6781
399          readyWait: 1,
400  
401          // Hold (or release) the ready event
402          holdReady: function( hold ) {
403                  if ( hold ) {
404                          jQuery.readyWait++;
405                  } else {
406                          jQuery.ready( true );
407                  }
408          },
409  
410          // Handle when the DOM is ready
411          ready: function( wait ) {
412                  // Either a released hold or an DOMready/load event and not yet ready
413                  if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) {
414                          // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
415                          if ( !document.body ) {
416                                  return setTimeout( jQuery.ready, 1 );
417                          }
418  
419                          // Remember that the DOM is ready
420                          jQuery.isReady = true;
421  
422                          // If a normal DOM Ready event fired, decrement, and wait if need be
423                          if ( wait !== true && --jQuery.readyWait > 0 ) {
424                                  return;
425                          }
426  
427                          // If there are functions bound, to execute
428                          readyList.resolveWith( document, [ jQuery ] );
429  
430                          // Trigger any bound ready events
431                          if ( jQuery.fn.trigger ) {
432                                  jQuery( document ).trigger( "ready" ).unbind( "ready" );
433                          }
434                  }
435          },
436  
437          bindReady: function() {
438                  if ( readyList ) {
439                          return;
440                  }
441  
442                  readyList = jQuery._Deferred();
443  
444                  // Catch cases where $(document).ready() is called after the
445                  // browser event has already occurred.
446                  if ( document.readyState === "complete" ) {
447                          // Handle it asynchronously to allow scripts the opportunity to delay ready
448                          return setTimeout( jQuery.ready, 1 );
449                  }
450  
451                  // Mozilla, Opera and webkit nightlies currently support this event
452                  if ( document.addEventListener ) {
453                          // Use the handy event callback
454                          document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
455  
456                          // A fallback to window.onload, that will always work
457                          window.addEventListener( "load", jQuery.ready, false );
458  
459                  // If IE event model is used
460                  } else if ( document.attachEvent ) {
461                          // ensure firing before onload,
462                          // maybe late but safe also for iframes
463                          document.attachEvent( "onreadystatechange", DOMContentLoaded );
464  
465                          // A fallback to window.onload, that will always work
466                          window.attachEvent( "onload", jQuery.ready );
467  
468                          // If IE and not a frame
469                          // continually check to see if the document is ready
470                          var toplevel = false;
471  
472                          try {
473                                  toplevel = window.frameElement == null;
474                          } catch(e) {}
475  
476                          if ( document.documentElement.doScroll && toplevel ) {
477                                  doScrollCheck();
478                          }
479                  }
480          },
481  
482          // See test/unit/core.js for details concerning isFunction.
483          // Since version 1.3, DOM methods and functions like alert
484          // aren't supported. They return false on IE (#2968).
485          isFunction: function( obj ) {
486                  return jQuery.type(obj) === "function";
487          },
488  
489          isArray: Array.isArray || function( obj ) {
490                  return jQuery.type(obj) === "array";
491          },
492  
493          // A crude way of determining if an object is a window
494          isWindow: function( obj ) {
495                  return obj && typeof obj === "object" && "setInterval" in obj;
496          },
497  
498          isNaN: function( obj ) {
499                  return obj == null || !rdigit.test( obj ) || isNaN( obj );
500          },
501  
502          type: function( obj ) {
503                  return obj == null ?
504                          String( obj ) :
505                          class2type[ toString.call(obj) ] || "object";
506          },
507  
508          isPlainObject: function( obj ) {
509                  // Must be an Object.
510                  // Because of IE, we also have to check the presence of the constructor property.
511                  // Make sure that DOM nodes and window objects don't pass through, as well
512                  if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
513                          return false;
514                  }
515  
516                  // Not own constructor property must be Object
517                  if ( obj.constructor &&
518                          !hasOwn.call(obj, "constructor") &&
519                          !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
520                          return false;
521                  }
522  
523                  // Own properties are enumerated firstly, so to speed up,
524                  // if last one is own, then all properties are own.
525  
526                  var key;
527                  for ( key in obj ) {}
528  
529                  return key === undefined || hasOwn.call( obj, key );
530          },
531  
532          isEmptyObject: function( obj ) {
533                  for ( var name in obj ) {
534                          return false;
535                  }
536                  return true;
537          },
538  
539          error: function( msg ) {
540                  throw msg;
541          },
542  
543          parseJSON: function( data ) {
544                  if ( typeof data !== "string" || !data ) {
545                          return null;
546                  }
547  
548                  // Make sure leading/trailing whitespace is removed (IE can't handle it)
549                  data = jQuery.trim( data );
550  
551                  // Attempt to parse using the native JSON parser first
552                  if ( window.JSON && window.JSON.parse ) {
553                          return window.JSON.parse( data );
554                  }
555  
556                  // Make sure the incoming data is actual JSON
557                  // Logic borrowed from http://json.org/json2.js
558                  if ( rvalidchars.test( data.replace( rvalidescape, "@" )
559                          .replace( rvalidtokens, "]" )
560                          .replace( rvalidbraces, "")) ) {
561  
562                          return (new Function( "return " + data ))();
563  
564                  }
565                  jQuery.error( "Invalid JSON: " + data );
566          },
567  
568          // Cross-browser xml parsing
569          // (xml & tmp used internally)
570          parseXML: function( data , xml , tmp ) {
571  
572                  if ( window.DOMParser ) { // Standard
573                          tmp = new DOMParser();
574                          xml = tmp.parseFromString( data , "text/xml" );
575                  } else { // IE
576                          xml = new ActiveXObject( "Microsoft.XMLDOM" );
577                          xml.async = "false";
578                          xml.loadXML( data );
579                  }
580  
581                  tmp = xml.documentElement;
582  
583                  if ( ! tmp || ! tmp.nodeName || tmp.nodeName === "parsererror" ) {
584                          jQuery.error( "Invalid XML: " + data );
585                  }
586  
587                  return xml;
588          },
589  
590          noop: function() {},
591  
592          // Evaluates a script in a global context
593          // Workarounds based on findings by Jim Driscoll
594          // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
595          globalEval: function( data ) {
596                  if ( data && rnotwhite.test( data ) ) {
597                          // We use execScript on Internet Explorer
598                          // We use an anonymous function so that context is window
599                          // rather than jQuery in Firefox
600                          ( window.execScript || function( data ) {
601                                  window[ "eval" ].call( window, data );
602                          } )( data );
603                  }
604          },
605  
606          nodeName: function( elem, name ) {
607                  return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
608          },
609  
610          // args is for internal usage only
611          each: function( object, callback, args ) {
612                  var name, i = 0,
613                          length = object.length,
614                          isObj = length === undefined || jQuery.isFunction( object );
615  
616                  if ( args ) {
617                          if ( isObj ) {
618                                  for ( name in object ) {
619                                          if ( callback.apply( object[ name ], args ) === false ) {
620                                                  break;
621                                          }
622                                  }
623                          } else {
624                                  for ( ; i < length; ) {
625                                          if ( callback.apply( object[ i++ ], args ) === false ) {
626                                                  break;
627                                          }
628                                  }
629                          }
630  
631                  // A special, fast, case for the most common use of each
632                  } else {
633                          if ( isObj ) {
634                                  for ( name in object ) {
635                                          if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
636                                                  break;
637                                          }
638                                  }
639                          } else {
640                                  for ( ; i < length; ) {
641                                          if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) {
642                                                  break;
643                                          }
644                                  }
645                          }
646                  }
647  
648                  return object;
649          },
650  
651          // Use native String.trim function wherever possible
652          trim: trim ?
653                  function( text ) {
654                          return text == null ?
655                                  "" :
656                                  trim.call( text );
657                  } :
658  
659                  // Otherwise use our own trimming functionality
660                  function( text ) {
661                          return text == null ?
662                                  "" :
663                                  text.toString().replace( trimLeft, "" ).replace( trimRight, "" );
664                  },
665  
666          // results is for internal usage only
667          makeArray: function( array, results ) {
668                  var ret = results || [];
669  
670                  if ( array != null ) {
671                          // The window, strings (and functions) also have 'length'
672                          // The extra typeof function check is to prevent crashes
673                          // in Safari 2 (See: #3039)
674                          // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930
675                          var type = jQuery.type( array );
676  
677                          if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) {
678                                  push.call( ret, array );
679                          } else {
680                                  jQuery.merge( ret, array );
681                          }
682                  }
683  
684                  return ret;
685          },
686  
687          inArray: function( elem, array ) {
688  
689                  if ( indexOf ) {
690                          return indexOf.call( array, elem );
691                  }
692  
693                  for ( var i = 0, length = array.length; i < length; i++ ) {
694                          if ( array[ i ] === elem ) {
695                                  return i;
696                          }
697                  }
698  
699                  return -1;
700          },
701  
702          merge: function( first, second ) {
703                  var i = first.length,
704                          j = 0;
705  
706                  if ( typeof second.length === "number" ) {
707                          for ( var l = second.length; j < l; j++ ) {
708                                  first[ i++ ] = second[ j ];
709                          }
710  
711                  } else {
712                          while ( second[j] !== undefined ) {
713                                  first[ i++ ] = second[ j++ ];
714                          }
715                  }
716  
717                  first.length = i;
718  
719                  return first;
720          },
721  
722          grep: function( elems, callback, inv ) {
723                  var ret = [], retVal;
724                  inv = !!inv;
725  
726                  // Go through the array, only saving the items
727                  // that pass the validator function
728                  for ( var i = 0, length = elems.length; i < length; i++ ) {
729                          retVal = !!callback( elems[ i ], i );
730                          if ( inv !== retVal ) {
731                                  ret.push( elems[ i ] );
732                          }
733                  }
734  
735                  return ret;
736          },
737  
738          // arg is for internal usage only
739          map: function( elems, callback, arg ) {
740                  var value, key, ret = [],
741                          i = 0,
742                          length = elems.length,
743                          // jquery objects are treated as arrays
744                          isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ;
745  
746                  // Go through the array, translating each of the items to their
747                  if ( isArray ) {
748                          for ( ; i < length; i++ ) {
749                                  value = callback( elems[ i ], i, arg );
750  
751                                  if ( value != null ) {
752                                          ret[ ret.length ] = value;
753                                  }
754                          }
755  
756                  // Go through every key on the object,
757                  } else {
758                          for ( key in elems ) {
759                                  value = callback( elems[ key ], key, arg );
760  
761                                  if ( value != null ) {
762                                          ret[ ret.length ] = value;
763                                  }
764                          }
765                  }
766  
767                  // Flatten any nested arrays
768                  return ret.concat.apply( [], ret );
769          },
770  
771          // A global GUID counter for objects
772          guid: 1,
773  
774          // Bind a function to a context, optionally partially applying any
775          // arguments.
776          proxy: function( fn, context ) {
777                  if ( typeof context === "string" ) {
778                          var tmp = fn[ context ];
779                          context = fn;
780                          fn = tmp;
781                  }
782  
783                  // Quick check to determine if target is callable, in the spec
784                  // this throws a TypeError, but we will just return undefined.
785                  if ( !jQuery.isFunction( fn ) ) {
786                          return undefined;
787                  }
788  
789                  // Simulated bind
790                  var args = slice.call( arguments, 2 ),
791                          proxy = function() {
792                                  return fn.apply( context, args.concat( slice.call( arguments ) ) );
793                          };
794  
795                  // Set the guid of unique handler to the same of original handler, so it can be removed
796                  proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
797  
798                  return proxy;
799          },
800  
801          // Mutifunctional method to get and set values to a collection
802          // The value/s can be optionally by executed if its a function
803          access: function( elems, key, value, exec, fn, pass ) {
804                  var length = elems.length;
805  
806                  // Setting many attributes
807                  if ( typeof key === "object" ) {
808                          for ( var k in key ) {
809                                  jQuery.access( elems, k, key[k], exec, fn, value );
810                          }
811                          return elems;
812                  }
813  
814                  // Setting one attribute
815                  if ( value !== undefined ) {
816                          // Optionally, function values get executed if exec is true
817                          exec = !pass && exec && jQuery.isFunction(value);
818  
819                          for ( var i = 0; i < length; i++ ) {
820                                  fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
821                          }
822  
823                          return elems;
824                  }
825  
826                  // Getting an attribute
827                  return length ? fn( elems[0], key ) : undefined;
828          },
829  
830          now: function() {
831                  return (new Date()).getTime();
832          },
833  
834          // Use of jQuery.browser is frowned upon.
835          // More details: http://docs.jquery.com/Utilities/jQuery.browser
836          uaMatch: function( ua ) {
837                  ua = ua.toLowerCase();
838  
839                  var match = rwebkit.exec( ua ) ||
840                          ropera.exec( ua ) ||
841                          rmsie.exec( ua ) ||
842                          ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) ||
843                          [];
844  
845                  return { browser: match[1] || "", version: match[2] || "0" };
846          },
847  
848          sub: function() {
849                  function jQuerySub( selector, context ) {
850                          return new jQuerySub.fn.init( selector, context );
851                  }
852                  jQuery.extend( true, jQuerySub, this );
853                  jQuerySub.superclass = this;
854                  jQuerySub.fn = jQuerySub.prototype = this();
855                  jQuerySub.fn.constructor = jQuerySub;
856                  jQuerySub.sub = this.sub;
857                  jQuerySub.fn.init = function init( selector, context ) {
858                          if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) {
859                                  context = jQuerySub( context );
860                          }
861  
862                          return jQuery.fn.init.call( this, selector, context, rootjQuerySub );
863                  };
864                  jQuerySub.fn.init.prototype = jQuerySub.fn;
865                  var rootjQuerySub = jQuerySub(document);
866                  return jQuerySub;
867          },
868  
869          browser: {}
870  });
871  
872  // Populate the class2type map
873  jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) {
874          class2type[ "[object " + name + "]" ] = name.toLowerCase();
875  });
876  
877  browserMatch = jQuery.uaMatch( userAgent );
878  if ( browserMatch.browser ) {
879          jQuery.browser[ browserMatch.browser ] = true;
880          jQuery.browser.version = browserMatch.version;
881  }
882  
883  // Deprecated, use jQuery.browser.webkit instead
884  if ( jQuery.browser.webkit ) {
885          jQuery.browser.safari = true;
886  }
887  
888  // IE doesn't match non-breaking spaces with \s
889  if ( rnotwhite.test( "\xA0" ) ) {
890          trimLeft = /^[\s\xA0]+/;
891          trimRight = /[\s\xA0]+$/;
892  }
893  
894  // All jQuery objects should point back to these
895  rootjQuery = jQuery(document);
896  
897  // Cleanup functions for the document ready method
898  if ( document.addEventListener ) {
899          DOMContentLoaded = function() {
900                  document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
901                  jQuery.ready();
902          };
903  
904  } else if ( document.attachEvent ) {
905          DOMContentLoaded = function() {
906                  // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
907                  if ( document.readyState === "complete" ) {
908                          document.detachEvent( "onreadystatechange", DOMContentLoaded );
909                          jQuery.ready();
910                  }
911          };
912  }
913  
914  // The DOM ready check for Internet Explorer
915  function doScrollCheck() {
916          if ( jQuery.isReady ) {
917                  return;
918          }
919  
920          try {
921                  // If IE is used, use the trick by Diego Perini
922                  // http://javascript.nwbox.com/IEContentLoaded/
923                  document.documentElement.doScroll("left");
924          } catch(e) {
925                  setTimeout( doScrollCheck, 1 );
926                  return;
927          }
928  
929          // and execute any waiting functions
930          jQuery.ready();
931  }
932  
933  // Expose jQuery to the global object
934  return jQuery;
935  
936  })();
937  
938  
939  var // Promise methods
940          promiseMethods = "done fail isResolved isRejected promise then always pipe".split( " " ),
941          // Static reference to slice
942          sliceDeferred = [].slice;
943  
944  jQuery.extend({
945          // Create a simple deferred (one callbacks list)
946          _Deferred: function() {
947                  var // callbacks list
948                          callbacks = [],
949                          // stored [ context , args ]
950                          fired,
951                          // to avoid firing when already doing so
952                          firing,
953                          // flag to know if the deferred has been cancelled
954                          cancelled,
955                          // the deferred itself
956                          deferred  = {
957  
958                                  // done( f1, f2, ...)
959                                  done: function() {
960                                          if ( !cancelled ) {
961                                                  var args = arguments,
962                                                          i,
963                                                          length,
964                                                          elem,
965                                                          type,
966                                                          _fired;
967                                                  if ( fired ) {
968                                                          _fired = fired;
969                                                          fired = 0;
970                                                  }
971                                                  for ( i = 0, length = args.length; i < length; i++ ) {
972                                                          elem = args[ i ];
973                                                          type = jQuery.type( elem );
974                                                          if ( type === "array" ) {
975                                                                  deferred.done.apply( deferred, elem );
976                                                          } else if ( type === "function" ) {
977                                                                  callbacks.push( elem );
978                                                          }
979                                                  }
980                                                  if ( _fired ) {
981                                                          deferred.resolveWith( _fired[ 0 ], _fired[ 1 ] );
982                                                  }
983                                          }
984                                          return this;
985                                  },
986  
987                                  // resolve with given context and args
988                                  resolveWith: function( context, args ) {
989                                          if ( !cancelled && !fired && !firing ) {
990                                                  // make sure args are available (#8421)
991                                                  args = args || [];
992                                                  firing = 1;
993                                                  try {
994                                                          while( callbacks[ 0 ] ) {
995                                                                  callbacks.shift().apply( context, args );
996                                                          }
997                                                  }
998                                                  finally {
999                                                          fired = [ context, args ];
1000                                                          firing = 0;
1001                                                  }
1002                                          }
1003                                          return this;
1004                                  },
1005  
1006                                  // resolve with this as context and given arguments
1007                                  resolve: function() {
1008                                          deferred.resolveWith( this, arguments );
1009                                          return this;
1010                                  },
1011  
1012                                  // Has this deferred been resolved?
1013                                  isResolved: function() {
1014                                          return !!( firing || fired );
1015                                  },
1016  
1017                                  // Cancel
1018                                  cancel: function() {
1019                                          cancelled = 1;
1020                                          callbacks = [];
1021                                          return this;
1022                                  }
1023                          };
1024  
1025                  return deferred;
1026          },
1027  
1028          // Full fledged deferred (two callbacks list)
1029          Deferred: function( func ) {
1030                  var deferred = jQuery._Deferred(),
1031                          failDeferred = jQuery._Deferred(),
1032                          promise;
1033                  // Add errorDeferred methods, then and promise
1034                  jQuery.extend( deferred, {
1035                          then: function( doneCallbacks, failCallbacks ) {
1036                                  deferred.done( doneCallbacks ).fail( failCallbacks );
1037                                  return this;
1038                          },
1039                          always: function() {
1040                                  return deferred.done.apply( deferred, arguments ).fail.apply( this, arguments );
1041                          },
1042                          fail: failDeferred.done,
1043                          rejectWith: failDeferred.resolveWith,
1044                          reject: failDeferred.resolve,
1045                          isRejected: failDeferred.isResolved,
1046                          pipe: function( fnDone, fnFail ) {
1047                                  return jQuery.Deferred(function( newDefer ) {
1048                                          jQuery.each( {
1049                                                  done: [ fnDone, "resolve" ],
1050                                                  fail: [ fnFail, "reject" ]
1051                                          }, function( handler, data ) {
1052                                                  var fn = data[ 0 ],
1053                                                          action = data[ 1 ],
1054                                                          returned;
1055                                                  if ( jQuery.isFunction( fn ) ) {
1056                                                          deferred[ handler ](function() {
1057                                                                  returned = fn.apply( this, arguments );
1058                                                                  if ( returned && jQuery.isFunction( returned.promise ) ) {
1059                                                                          returned.promise().then( newDefer.resolve, newDefer.reject );
1060                                                                  } else {
1061                                                                          newDefer[ action ]( returned );
1062                                                                  }
1063                                                          });
1064                                                  } else {
1065                                                          deferred[ handler ]( newDefer[ action ] );
1066                                                  }
1067                                          });
1068                                  }).promise();
1069                          },
1070                          // Get a promise for this deferred
1071                          // If obj is provided, the promise aspect is added to the object
1072                          promise: function( obj ) {
1073                                  if ( obj == null ) {
1074                                          if ( promise ) {
1075                                                  return promise;
1076                                          }
1077                                          promise = obj = {};
1078                                  }
1079                                  var i = promiseMethods.length;
1080                                  while( i-- ) {
1081                                          obj[ promiseMethods[i] ] = deferred[ promiseMethods[i] ];
1082                                  }
1083                                  return obj;
1084                          }
1085                  });
1086                  // Make sure only one callback list will be used
1087                  deferred.done( failDeferred.cancel ).fail( deferred.cancel );
1088                  // Unexpose cancel
1089                  delete deferred.cancel;
1090                  // Call given func if any
1091                  if ( func ) {
1092                          func.call( deferred, deferred );
1093                  }
1094                  return deferred;
1095          },
1096  
1097          // Deferred helper
1098          when: function( firstParam ) {
1099                  var args = arguments,
1100                          i = 0,
1101                          length = args.length,
1102                          count = length,
1103                          deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ?
1104                                  firstParam :
1105                                  jQuery.Deferred();
1106                  function resolveFunc( i ) {
1107                          return function( value ) {
1108                                  args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value;
1109                                  if ( !( --count ) ) {
1110                                          // Strange bug in FF4:
1111                                          // Values changed onto the arguments object sometimes end up as undefined values
1112                                          // outside the $.when method. Cloning the object into a fresh array solves the issue
1113                                          deferred.resolveWith( deferred, sliceDeferred.call( args, 0 ) );
1114                                  }
1115                          };
1116                  }
1117                  if ( length > 1 ) {
1118                          for( ; i < length; i++ ) {
1119                                  if ( args[ i ] && jQuery.isFunction( args[ i ].promise ) ) {
1120                                          args[ i ].promise().then( resolveFunc(i), deferred.reject );
1121                                  } else {
1122                                          --count;
1123                                  }
1124                          }
1125                          if ( !count ) {
1126                                  deferred.resolveWith( deferred, args );
1127                          }
1128                  } else if ( deferred !== firstParam ) {
1129                          deferred.resolveWith( deferred, length ? [ firstParam ] : [] );
1130                  }
1131                  return deferred.promise();
1132          }
1133  });
1134  
1135  
1136  
1137  jQuery.support = (function() {
1138  
1139          var div = document.createElement( "div" ),
1140                  documentElement = document.documentElement,
1141                  all,
1142                  a,
1143                  select,
1144                  opt,
1145                  input,
1146                  marginDiv,
1147                  support,
1148                  fragment,
1149                  body,
1150                  bodyStyle,
1151                  tds,
1152                  events,
1153                  eventName,
1154                  i,
1155                  isSupported;
1156  
1157          // Preliminary tests
1158          div.setAttribute("className", "t");
1159          div.innerHTML = "   <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
1160  
1161          all = div.getElementsByTagName( "*" );
1162          a = div.getElementsByTagName( "a" )[ 0 ];
1163  
1164          // Can't get basic test support
1165          if ( !all || !all.length || !a ) {
1166                  return {};
1167          }
1168  
1169          // First batch of supports tests
1170          select = document.createElement( "select" );
1171          opt = select.appendChild( document.createElement("option") );
1172          input = div.getElementsByTagName( "input" )[ 0 ];
1173  
1174          support = {
1175                  // IE strips leading whitespace when .innerHTML is used
1176                  leadingWhitespace: ( div.firstChild.nodeType === 3 ),
1177  
1178                  // Make sure that tbody elements aren't automatically inserted
1179                  // IE will insert them into empty tables
1180                  tbody: !div.getElementsByTagName( "tbody" ).length,
1181  
1182                  // Make sure that link elements get serialized correctly by innerHTML
1183                  // This requires a wrapper element in IE
1184                  htmlSerialize: !!div.getElementsByTagName( "link" ).length,
1185  
1186                  // Get the style information from getAttribute
1187                  // (IE uses .cssText instead)
1188                  style: /top/.test( a.getAttribute("style") ),
1189  
1190                  // Make sure that URLs aren't manipulated
1191                  // (IE normalizes it by default)
1192                  hrefNormalized: ( a.getAttribute( "href" ) === "/a" ),
1193  
1194                  // Make sure that element opacity exists
1195                  // (IE uses filter instead)
1196                  // Use a regex to work around a WebKit issue. See #5145
1197                  opacity: /^0.55$/.test( a.style.opacity ),
1198  
1199                  // Verify style float existence
1200                  // (IE uses styleFloat instead of cssFloat)
1201                  cssFloat: !!a.style.cssFloat,
1202  
1203                  // Make sure that if no value is specified for a checkbox
1204                  // that it defaults to "on".
1205                  // (WebKit defaults to "" instead)
1206                  checkOn: ( input.value === "on" ),
1207  
1208                  // Make sure that a selected-by-default option has a working selected property.
1209                  // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
1210                  optSelected: opt.selected,
1211  
1212                  // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)
1213                  getSetAttribute: div.className !== "t",
1214  
1215                  // Will be defined later
1216                  submitBubbles: true,
1217                  changeBubbles: true,
1218                  focusinBubbles: false,
1219                  deleteExpando: true,
1220                  noCloneEvent: true,
1221                  inlineBlockNeedsLayout: false,
1222                  shrinkWrapBlocks: false,
1223                  reliableMarginRight: true
1224          };
1225  
1226          // Make sure checked status is properly cloned
1227          input.checked = true;
1228          support.noCloneChecked = input.cloneNode( true ).checked;
1229  
1230          // Make sure that the options inside disabled selects aren't marked as disabled
1231          // (WebKit marks them as disabled)
1232          select.disabled = true;
1233          support.optDisabled = !opt.disabled;
1234  
1235          // Test to see if it's possible to delete an expando from an element
1236          // Fails in Internet Explorer
1237          try {
1238                  delete div.test;
1239          } catch( e ) {
1240                  support.deleteExpando = false;
1241          }
1242  
1243          if ( !div.addEventListener && div.attachEvent && div.fireEvent ) {
1244                  div.attachEvent( "onclick", function click() {
1245                          // Cloning a node shouldn't copy over any
1246                          // bound event handlers (IE does this)
1247                          support.noCloneEvent = false;
1248                          div.detachEvent( "onclick", click );
1249                  });
1250                  div.cloneNode( true ).fireEvent( "onclick" );
1251          }
1252  
1253          // Check if a radio maintains it's value
1254          // after being appended to the DOM
1255          input = document.createElement("input");
1256          input.value = "t";
1257          input.setAttribute("type", "radio");
1258          support.radioValue = input.value === "t";
1259  
1260          input.setAttribute("checked", "checked");
1261          div.appendChild( input );
1262          fragment = document.createDocumentFragment();
1263          fragment.appendChild( div.firstChild );
1264  
1265          // WebKit doesn't clone checked state correctly in fragments
1266          support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;
1267  
1268          div.innerHTML = "";
1269  
1270          // Figure out if the W3C box model works as expected
1271          div.style.width = div.style.paddingLeft = "1px";
1272  
1273          // We use our own, invisible, body
1274          body = document.createElement( "body" );
1275          bodyStyle = {
1276                  visibility: "hidden",
1277                  width: 0,
1278                  height: 0,
1279                  border: 0,
1280                  margin: 0,
1281                  // Set background to avoid IE crashes when removing (#9028)
1282                  background: "none"
1283          };
1284          for ( i in bodyStyle ) {
1285                  body.style[ i ] = bodyStyle[ i ];
1286          }
1287          body.appendChild( div );
1288          documentElement.insertBefore( body, documentElement.firstChild );
1289  
1290          // Check if a disconnected checkbox will retain its checked
1291          // value of true after appended to the DOM (IE6/7)
1292          support.appendChecked = input.checked;
1293  
1294          support.boxModel = div.offsetWidth === 2;
1295  
1296          if ( "zoom" in div.style ) {
1297                  // Check if natively block-level elements act like inline-block
1298                  // elements when setting their display to 'inline' and giving
1299                  // them layout
1300                  // (IE < 8 does this)
1301                  div.style.display = "inline";
1302                  div.style.zoom = 1;
1303                  support.inlineBlockNeedsLayout = ( div.offsetWidth === 2 );
1304  
1305                  // Check if elements with layout shrink-wrap their children
1306                  // (IE 6 does this)
1307                  div.style.display = "";
1308                  div.innerHTML = "<div style='width:4px;'></div>";
1309                  support.shrinkWrapBlocks = ( div.offsetWidth !== 2 );
1310          }
1311  
1312          div.innerHTML = "<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>";
1313          tds = div.getElementsByTagName( "td" );
1314  
1315          // Check if table cells still have offsetWidth/Height when they are set
1316          // to display:none and there are still other visible table cells in a
1317          // table row; if so, offsetWidth/Height are not reliable for use when
1318          // determining if an element has been hidden directly using
1319          // display:none (it is still safe to use offsets if a parent element is
1320          // hidden; don safety goggles and see bug #4512 for more information).
1321          // (only IE 8 fails this test)
1322          isSupported = ( tds[ 0 ].offsetHeight === 0 );
1323  
1324          tds[ 0 ].style.display = "";
1325          tds[ 1 ].style.display = "none";
1326  
1327          // Check if empty table cells still have offsetWidth/Height
1328          // (IE < 8 fail this test)
1329          support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );
1330          div.innerHTML = "";
1331  
1332          // Check if div with explicit width and no margin-right incorrectly
1333          // gets computed margin-right based on width of container. For more
1334          // info see bug #3333
1335          // Fails in WebKit before Feb 2011 nightlies
1336          // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
1337          if ( document.defaultView && document.defaultView.getComputedStyle ) {
1338                  marginDiv = document.createElement( "div" );
1339                  marginDiv.style.width = "0";
1340                  marginDiv.style.marginRight = "0";
1341                  div.appendChild( marginDiv );
1342                  support.reliableMarginRight =
1343                          ( parseInt( ( document.defaultView.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0;
1344          }
1345  
1346          // Remove the body element we added
1347          body.innerHTML = "";
1348          documentElement.removeChild( body );
1349  
1350          // Technique from Juriy Zaytsev
1351          // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
1352          // We only care about the case where non-standard event systems
1353          // are used, namely in IE. Short-circuiting here helps us to
1354          // avoid an eval call (in setAttribute) which can cause CSP
1355          // to go haywire. See: https://developer.mozilla.org/en/Security/CSP
1356          if ( div.attachEvent ) {
1357                  for( i in {
1358                          submit: 1,
1359                          change: 1,
1360                          focusin: 1
1361                  } ) {
1362                          eventName = "on" + i;
1363                          isSupported = ( eventName in div );
1364                          if ( !isSupported ) {
1365                                  div.setAttribute( eventName, "return;" );
1366                                  isSupported = ( typeof div[ eventName ] === "function" );
1367                          }
1368                          support[ i + "Bubbles" ] = isSupported;
1369                  }
1370          }
1371  
1372          return support;
1373  })();
1374  
1375  // Keep track of boxModel
1376  jQuery.boxModel = jQuery.support.boxModel;
1377  
1378  
1379  
1380  
1381  var rbrace = /^(?:\{.*\}|\[.*\])$/,
1382          rmultiDash = /([a-z])([A-Z])/g;
1383  
1384  jQuery.extend({
1385          cache: {},
1386  
1387          // Please use with caution
1388          uuid: 0,
1389  
1390          // Unique for each copy of jQuery on the page
1391          // Non-digits removed to match rinlinejQuery
1392          expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ),
1393  
1394          // The following elements throw uncatchable exceptions if you
1395          // attempt to add expando properties to them.
1396          noData: {
1397                  "embed": true,
1398                  // Ban all objects except for Flash (which handle expandos)
1399                  "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",
1400                  "applet": true
1401          },
1402  
1403          hasData: function( elem ) {
1404                  elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];
1405  
1406                  return !!elem && !isEmptyDataObject( elem );
1407          },
1408  
1409          data: function( elem, name, data, pvt /* Internal Use Only */ ) {
1410                  if ( !jQuery.acceptData( elem ) ) {
1411                          return;
1412                  }
1413  
1414                  var internalKey = jQuery.expando, getByName = typeof name === "string", thisCache,
1415  
1416                          // We have to handle DOM nodes and JS objects differently because IE6-7
1417                          // can't GC object references properly across the DOM-JS boundary
1418                          isNode = elem.nodeType,
1419  
1420                          // Only DOM nodes need the global jQuery cache; JS object data is
1421                          // attached directly to the object so GC can occur automatically
1422                          cache = isNode ? jQuery.cache : elem,
1423  
1424                          // Only defining an ID for JS objects if its cache already exists allows
1425                          // the code to shortcut on the same path as a DOM node with no cache
1426                          id = isNode ? elem[ jQuery.expando ] : elem[ jQuery.expando ] && jQuery.expando;
1427  
1428                  // Avoid doing any more work than we need to when trying to get data on an
1429                  // object that has no data at all
1430                  if ( (!id || (pvt && id && !cache[ id ][ internalKey ])) && getByName && data === undefined ) {
1431                          return;
1432                  }
1433  
1434                  if ( !id ) {
1435                          // Only DOM nodes need a new unique ID for each element since their data
1436                          // ends up in the global cache
1437                          if ( isNode ) {
1438                                  elem[ jQuery.expando ] = id = ++jQuery.uuid;
1439                          } else {
1440                                  id = jQuery.expando;
1441                          }
1442                  }
1443  
1444                  if ( !cache[ id ] ) {
1445                          cache[ id ] = {};
1446  
1447                          // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery
1448                          // metadata on plain JS objects when the object is serialized using
1449                          // JSON.stringify
1450                          if ( !isNode ) {
1451                                  cache[ id ].toJSON = jQuery.noop;
1452                          }
1453                  }
1454  
1455                  // An object can be passed to jQuery.data instead of a key/value pair; this gets
1456                  // shallow copied over onto the existing cache
1457                  if ( typeof name === "object" || typeof name === "function" ) {
1458                          if ( pvt ) {
1459                                  cache[ id ][ internalKey ] = jQuery.extend(cache[ id ][ internalKey ], name);
1460                          } else {
1461                                  cache[ id ] = jQuery.extend(cache[ id ], name);
1462                          }
1463                  }
1464  
1465                  thisCache = cache[ id ];
1466  
1467                  // Internal jQuery data is stored in a separate object inside the object's data
1468                  // cache in order to avoid key collisions between internal data and user-defined
1469                  // data
1470                  if ( pvt ) {
1471                          if ( !thisCache[ internalKey ] ) {
1472                                  thisCache[ internalKey ] = {};
1473                          }
1474  
1475                          thisCache = thisCache[ internalKey ];
1476                  }
1477  
1478                  if ( data !== undefined ) {
1479                          thisCache[ jQuery.camelCase( name ) ] = data;
1480                  }
1481  
1482                  // TODO: This is a hack for 1.5 ONLY. It will be removed in 1.6. Users should
1483                  // not attempt to inspect the internal events object using jQuery.data, as this
1484                  // internal data object is undocumented and subject to change.
1485                  if ( name === "events" && !thisCache[name] ) {
1486                          return thisCache[ internalKey ] && thisCache[ internalKey ].events;
1487                  }
1488  
1489                  return getByName ? thisCache[ jQuery.camelCase( name ) ] : thisCache;
1490          },
1491  
1492          removeData: function( elem, name, pvt /* Internal Use Only */ ) {
1493                  if ( !jQuery.acceptData( elem ) ) {
1494                          return;
1495                  }
1496  
1497                  var internalKey = jQuery.expando, isNode = elem.nodeType,
1498  
1499                          // See jQuery.data for more information
1500                          cache = isNode ? jQuery.cache : elem,
1501  
1502                          // See jQuery.data for more information
1503                          id = isNode ? elem[ jQuery.expando ] : jQuery.expando;
1504  
1505                  // If there is already no cache entry for this object, there is no
1506                  // purpose in continuing
1507                  if ( !cache[ id ] ) {
1508                          return;
1509                  }
1510  
1511                  if ( name ) {
1512                          var thisCache = pvt ? cache[ id ][ internalKey ] : cache[ id ];
1513  
1514                          if ( thisCache ) {
1515                                  delete thisCache[ name ];
1516  
1517                                  // If there is no data left in the cache, we want to continue
1518                                  // and let the cache object itself get destroyed
1519                                  if ( !isEmptyDataObject(thisCache) ) {
1520                                          return;
1521                                  }
1522                          }
1523                  }
1524  
1525                  // See jQuery.data for more information
1526                  if ( pvt ) {
1527                          delete cache[ id ][ internalKey ];
1528  
1529                          // Don't destroy the parent cache unless the internal data object
1530                          // had been the only thing left in it
1531                          if ( !isEmptyDataObject(cache[ id ]) ) {
1532                                  return;
1533                          }
1534                  }
1535  
1536                  var internalCache = cache[ id ][ internalKey ];
1537  
1538                  // Browsers that fail expando deletion also refuse to delete expandos on
1539                  // the window, but it will allow it on all other JS objects; other browsers
1540                  // don't care
1541                  if ( jQuery.support.deleteExpando || cache != window ) {
1542                          delete cache[ id ];
1543                  } else {
1544                          cache[ id ] = null;
1545                  }
1546  
1547                  // We destroyed the entire user cache at once because it's faster than
1548                  // iterating through each key, but we need to continue to persist internal
1549                  // data if it existed
1550                  if ( internalCache ) {
1551                          cache[ id ] = {};
1552                          // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery
1553                          // metadata on plain JS objects when the object is serialized using
1554                          // JSON.stringify
1555                          if ( !isNode ) {
1556                                  cache[ id ].toJSON = jQuery.noop;
1557                          }
1558  
1559                          cache[ id ][ internalKey ] = internalCache;
1560  
1561                  // Otherwise, we need to eliminate the expando on the node to avoid
1562                  // false lookups in the cache for entries that no longer exist
1563                  } else if ( isNode ) {
1564                          // IE does not allow us to delete expando properties from nodes,
1565                          // nor does it have a removeAttribute function on Document nodes;
1566                          // we must handle all of these cases
1567                          if ( jQuery.support.deleteExpando ) {
1568                                  delete elem[ jQuery.expando ];
1569                          } else if ( elem.removeAttribute ) {
1570                                  elem.removeAttribute( jQuery.expando );
1571                          } else {
1572                                  elem[ jQuery.expando ] = null;
1573                          }
1574                  }
1575          },
1576  
1577          // For internal use only.
1578          _data: function( elem, name, data ) {
1579                  return jQuery.data( elem, name, data, true );
1580          },
1581  
1582          // A method for determining if a DOM node can handle the data expando
1583          acceptData: function( elem ) {
1584                  if ( elem.nodeName ) {
1585                          var match = jQuery.noData[ elem.nodeName.toLowerCase() ];
1586  
1587                          if ( match ) {
1588                                  return !(match === true || elem.getAttribute("classid") !== match);
1589                          }
1590                  }
1591  
1592                  return true;
1593          }
1594  });
1595  
1596  jQuery.fn.extend({
1597          data: function( key, value ) {
1598                  var data = null;
1599  
1600                  if ( typeof key === "undefined" ) {
1601                          if ( this.length ) {
1602                                  data = jQuery.data( this[0] );
1603  
1604                                  if ( this[0].nodeType === 1 ) {
1605                              var attr = this[0].attributes, name;
1606                                          for ( var i = 0, l = attr.length; i < l; i++ ) {
1607                                                  name = attr[i].name;
1608  
1609                                                  if ( name.indexOf( "data-" ) === 0 ) {
1610                                                          name = jQuery.camelCase( name.substring(5) );
1611  
1612                                                          dataAttr( this[0], name, data[ name ] );
1613                                                  }
1614                                          }
1615                                  }
1616                          }
1617  
1618                          return data;
1619  
1620                  } else if ( typeof key === "object" ) {
1621                          return this.each(function() {
1622                                  jQuery.data( this, key );
1623                          });
1624                  }
1625  
1626                  var parts = key.split(".");
1627                  parts[1] = parts[1] ? "." + parts[1] : "";
1628  
1629                  if ( value === undefined ) {
1630                          data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
1631  
1632                          // Try to fetch any internally stored data first
1633                          if ( data === undefined && this.length ) {
1634                                  data = jQuery.data( this[0], key );
1635                                  data = dataAttr( this[0], key, data );
1636                          }
1637  
1638                          return data === undefined && parts[1] ?
1639                                  this.data( parts[0] ) :
1640                                  data;
1641  
1642                  } else {
1643                          return this.each(function() {
1644                                  var $this = jQuery( this ),
1645                                          args = [ parts[0], value ];
1646  
1647                                  $this.triggerHandler( "setData" + parts[1] + "!", args );
1648                                  jQuery.data( this, key, value );
1649                                  $this.triggerHandler( "changeData" + parts[1] + "!", args );
1650                          });
1651                  }
1652          },
1653  
1654          removeData: function( key ) {
1655                  return this.each(function() {
1656                          jQuery.removeData( this, key );
1657                  });
1658          }
1659  });
1660  
1661  function dataAttr( elem, key, data ) {
1662          // If nothing was found internally, try to fetch any
1663          // data from the HTML5 data-* attribute
1664          if ( data === undefined && elem.nodeType === 1 ) {
1665                  var name = "data-" + key.replace( rmultiDash, "$1-$2" ).toLowerCase();
1666  
1667                  data = elem.getAttribute( name );
1668  
1669                  if ( typeof data === "string" ) {
1670                          try {
1671                                  data = data === "true" ? true :
1672                                  data === "false" ? false :
1673                                  data === "null" ? null :
1674                                  !jQuery.isNaN( data ) ? parseFloat( data ) :
1675                                          rbrace.test( data ) ? jQuery.parseJSON( data ) :
1676                                          data;
1677                          } catch( e ) {}
1678  
1679                          // Make sure we set the data so it isn't changed later
1680                          jQuery.data( elem, key, data );
1681  
1682                  } else {
1683                          data = undefined;
1684                  }
1685          }
1686  
1687          return data;
1688  }
1689  
1690  // TODO: This is a hack for 1.5 ONLY to allow objects with a single toJSON
1691  // property to be considered empty objects; this property always exists in
1692  // order to make sure JSON.stringify does not expose internal metadata
1693  function isEmptyDataObject( obj ) {
1694          for ( var name in obj ) {
1695                  if ( name !== "toJSON" ) {
1696                          return false;
1697                  }
1698          }
1699  
1700          return true;
1701  }
1702  
1703  
1704  
1705  
1706  function handleQueueMarkDefer( elem, type, src ) {
1707          var deferDataKey = type + "defer",
1708                  queueDataKey = type + "queue",
1709                  markDataKey = type + "mark",
1710                  defer = jQuery.data( elem, deferDataKey, undefined, true );
1711          if ( defer &&
1712                  ( src === "queue" || !jQuery.data( elem, queueDataKey, undefined, true ) ) &&
1713                  ( src === "mark" || !jQuery.data( elem, markDataKey, undefined, true ) ) ) {
1714                  // Give room for hard-coded callbacks to fire first
1715                  // and eventually mark/queue something else on the element
1716                  setTimeout( function() {
1717                          if ( !jQuery.data( elem, queueDataKey, undefined, true ) &&
1718                                  !jQuery.data( elem, markDataKey, undefined, true ) ) {
1719                                  jQuery.removeData( elem, deferDataKey, true );
1720                                  defer.resolve();
1721                          }
1722                  }, 0 );
1723          }
1724  }
1725  
1726  jQuery.extend({
1727  
1728          _mark: function( elem, type ) {
1729                  if ( elem ) {
1730                          type = (type || "fx") + "mark";
1731                          jQuery.data( elem, type, (jQuery.data(elem,type,undefined,true) || 0) + 1, true );
1732                  }
1733          },
1734  
1735          _unmark: function( force, elem, type ) {
1736                  if ( force !== true ) {
1737                          type = elem;
1738                          elem = force;
1739                          force = false;
1740                  }
1741                  if ( elem ) {
1742                          type = type || "fx";
1743                          var key = type + "mark",
1744                                  count = force ? 0 : ( (jQuery.data( elem, key, undefined, true) || 1 ) - 1 );
1745                          if ( count ) {
1746                                  jQuery.data( elem, key, count, true );
1747                          } else {
1748                                  jQuery.removeData( elem, key, true );
1749                                  handleQueueMarkDefer( elem, type, "mark" );
1750                          }
1751                  }
1752          },
1753  
1754          queue: function( elem, type, data ) {
1755                  if ( elem ) {
1756                          type = (type || "fx") + "queue";
1757                          var q = jQuery.data( elem, type, undefined, true );
1758                          // Speed up dequeue by getting out quickly if this is just a lookup
1759                          if ( data ) {
1760                                  if ( !q || jQuery.isArray(data) ) {
1761                                          q = jQuery.data( elem, type, jQuery.makeArray(data), true );
1762                                  } else {
1763                                          q.push( data );
1764                                  }
1765                          }
1766                          return q || [];
1767                  }
1768          },
1769  
1770          dequeue: function( elem, type ) {
1771                  type = type || "fx";
1772  
1773                  var queue = jQuery.queue( elem, type ),
1774                          fn = queue.shift(),
1775                          defer;
1776  
1777                  // If the fx queue is dequeued, always remove the progress sentinel
1778                  if ( fn === "inprogress" ) {
1779                          fn = queue.shift();
1780                  }
1781  
1782                  if ( fn ) {
1783                          // Add a progress sentinel to prevent the fx queue from being
1784                          // automatically dequeued
1785                          if ( type === "fx" ) {
1786                                  queue.unshift("inprogress");
1787                          }
1788  
1789                          fn.call(elem, function() {
1790                                  jQuery.dequeue(elem, type);
1791                          });
1792                  }
1793  
1794                  if ( !queue.length ) {
1795                          jQuery.removeData( elem, type + "queue", true );
1796                          handleQueueMarkDefer( elem, type, "queue" );
1797                  }
1798          }
1799  });
1800  
1801  jQuery.fn.extend({
1802          queue: function( type, data ) {
1803                  if ( typeof type !== "string" ) {
1804                          data = type;
1805                          type = "fx";
1806                  }
1807  
1808                  if ( data === undefined ) {
1809                          return jQuery.queue( this[0], type );
1810                  }
1811                  return this.each(function() {
1812                          var queue = jQuery.queue( this, type, data );
1813  
1814                          if ( type === "fx" && queue[0] !== "inprogress" ) {
1815                                  jQuery.dequeue( this, type );
1816                          }
1817                  });
1818          },
1819          dequeue: function( type ) {
1820                  return this.each(function() {
1821                          jQuery.dequeue( this, type );
1822                  });
1823          },
1824          // Based off of the plugin by Clint Helfers, with permission.
1825          // http://blindsignals.com/index.php/2009/07/jquery-delay/
1826          delay: function( time, type ) {
1827                  time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
1828                  type = type || "fx";
1829  
1830                  return this.queue( type, function() {
1831                          var elem = this;
1832                          setTimeout(function() {
1833                                  jQuery.dequeue( elem, type );
1834                          }, time );
1835                  });
1836          },
1837          clearQueue: function( type ) {
1838                  return this.queue( type || "fx", [] );
1839          },
1840          // Get a promise resolved when queues of a certain type
1841          // are emptied (fx is the type by default)
1842          promise: function( type, object ) {
1843                  if ( typeof type !== "string" ) {
1844                          object = type;
1845                          type = undefined;
1846                  }
1847                  type = type || "fx";
1848                  var defer = jQuery.Deferred(),
1849                          elements = this,
1850                          i = elements.length,
1851                          count = 1,
1852                          deferDataKey = type + "defer",
1853                          queueDataKey = type + "queue",
1854                          markDataKey = type + "mark",
1855                          tmp;
1856                  function resolve() {
1857                          if ( !( --count ) ) {
1858                                  defer.resolveWith( elements, [ elements ] );
1859                          }
1860                  }
1861                  while( i-- ) {
1862                          if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) ||
1863                                          ( jQuery.data( elements[ i ], queueDataKey, undefined, true ) ||
1864                                                  jQuery.data( elements[ i ], markDataKey, undefined, true ) ) &&
1865                                          jQuery.data( elements[ i ], deferDataKey, jQuery._Deferred(), true ) )) {
1866                                  count++;
1867                                  tmp.done( resolve );
1868                          }
1869                  }
1870                  resolve();
1871                  return defer.promise();
1872          }
1873  });
1874  
1875  
1876  
1877  
1878  var rclass = /[\n\t\r]/g,
1879          rspace = /\s+/,
1880          rreturn = /\r/g,
1881          rtype = /^(?:button|input)$/i,
1882          rfocusable = /^(?:button|input|object|select|textarea)$/i,
1883          rclickable = /^a(?:rea)?$/i,
1884          rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,
1885          rinvalidChar = /\:/,
1886          formHook, boolHook;
1887  
1888  jQuery.fn.extend({
1889          attr: function( name, value ) {
1890                  return jQuery.access( this, name, value, true, jQuery.attr );
1891          },
1892  
1893          removeAttr: function( name ) {
1894                  return this.each(function() {
1895                          jQuery.removeAttr( this, name );
1896                  });
1897          },
1898         
1899          prop: function( name, value ) {
1900                  return jQuery.access( this, name, value, true, jQuery.prop );
1901          },
1902         
1903          removeProp: function( name ) {
1904                  name = jQuery.propFix[ name ] || name;
1905                  return this.each(function() {
1906                          // try/catch handles cases where IE balks (such as removing a property on window)
1907                          try {
1908                                  this[ name ] = undefined;
1909                                  delete this[ name ];
1910                          } catch( e ) {}
1911                  });
1912          },
1913  
1914          addClass: function( value ) {
1915                  if ( jQuery.isFunction( value ) ) {
1916                          return this.each(function(i) {
1917                                  var self = jQuery(this);
1918                                  self.addClass( value.call(this, i, self.attr("class") || "") );
1919                          });
1920                  }
1921  
1922                  if ( value && typeof value === "string" ) {
1923                          var classNames = (value || "").split( rspace );
1924  
1925                          for ( var i = 0, l = this.length; i < l; i++ ) {
1926                                  var elem = this[i];
1927  
1928                                  if ( elem.nodeType === 1 ) {
1929                                          if ( !elem.className ) {
1930                                                  elem.className = value;
1931  
1932                                          } else {
1933                                                  var className = " " + elem.className + " ",
1934                                                          setClass = elem.className;
1935  
1936                                                  for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
1937                                                          if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) {
1938                                                                  setClass += " " + classNames[c];
1939                                                          }
1940                                                  }
1941                                                  elem.className = jQuery.trim( setClass );
1942                                          }
1943                                  }
1944                          }
1945                  }
1946  
1947                  return this;
1948          },
1949  
1950          removeClass: function( value ) {
1951                  if ( jQuery.isFunction(value) ) {
1952                          return this.each(function(i) {
1953                                  var self = jQuery(this);
1954                                  self.removeClass( value.call(this, i, self.attr("class")) );
1955                          });
1956                  }
1957  
1958                  if ( (value && typeof value === "string") || value === undefined ) {
1959                          var classNames = (value || "").split( rspace );
1960  
1961                          for ( var i = 0, l = this.length; i < l; i++ ) {
1962                                  var elem = this[i];
1963  
1964                                  if ( elem.nodeType === 1 && elem.className ) {
1965                                          if ( value ) {
1966                                                  var className = (" " + elem.className + " ").replace(rclass, " ");
1967                                                  for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
1968                                                          className = className.replace(" " + classNames[c] + " ", " ");
1969                                                  }
1970                                                  elem.className = jQuery.trim( className );
1971  
1972                                          } else {
1973                                                  elem.className = "";
1974                                          }
1975                                  }
1976                          }
1977                  }
1978  
1979                  return this;
1980          },
1981  
1982          toggleClass: function( value, stateVal ) {
1983                  var type = typeof value,
1984                          isBool = typeof stateVal === "boolean";
1985  
1986                  if ( jQuery.isFunction( value ) ) {
1987                          return this.each(function(i) {
1988                                  var self = jQuery(this);
1989                                  self.toggleClass( value.call(this, i, self.attr("class"), stateVal), stateVal );
1990                          });
1991                  }
1992  
1993                  return this.each(function() {
1994                          if ( type === "string" ) {
1995                                  // toggle individual class names
1996                                  var className,
1997                                          i = 0,
1998                                          self = jQuery( this ),
1999                                          state = stateVal,
2000                                          classNames = value.split( rspace );
2001  
2002                                  while ( (className = classNames[ i++ ]) ) {
2003                                          // check each className given, space seperated list
2004                                          state = isBool ? state : !self.hasClass( className );
2005                                          self[ state ? "addClass" : "removeClass" ]( className );
2006                                  }
2007  
2008                          } else if ( type === "undefined" || type === "boolean" ) {
2009                                  if ( this.className ) {
2010                                          // store className if set
2011                                          jQuery._data( this, "__className__", this.className );
2012                                  }
2013  
2014                                  // toggle whole className
2015                                  this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || "";
2016                          }
2017                  });
2018          },
2019  
2020          hasClass: function( selector ) {
2021                  var className = " " + selector + " ";
2022                  for ( var i = 0, l = this.length; i < l; i++ ) {
2023                          if ( (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {
2024                                  return true;
2025                          }
2026                  }
2027  
2028                  return false;
2029          },
2030  
2031          val: function( value ) {
2032                  var hooks, ret,
2033                          elem = this[0];
2034                 
2035                  if ( !arguments.length ) {
2036                          if ( elem ) {
2037                                  hooks = jQuery.valHooks[ elem.nodeName.toLowerCase() ] || jQuery.valHooks[ elem.type ];
2038  
2039                                  if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
2040                                          return ret;
2041                                  }
2042  
2043                                  return (elem.value || "").replace(rreturn, "");
2044                          }
2045  
2046                          return undefined;
2047                  }
2048  
2049                  var isFunction = jQuery.isFunction( value );
2050  
2051                  return this.each(function( i ) {
2052                          var self = jQuery(this), val;
2053  
2054                          if ( this.nodeType !== 1 ) {
2055                                  return;
2056                          }
2057  
2058                          if ( isFunction ) {
2059                                  val = value.call( this, i, self.val() );
2060                          } else {
2061                                  val = value;
2062                          }
2063  
2064                          // Treat null/undefined as ""; convert numbers to string
2065                          if ( val == null ) {
2066                                  val = "";
2067                          } else if ( typeof val === "number" ) {
2068                                  val += "";
2069                          } else if ( jQuery.isArray( val ) ) {
2070                                  val = jQuery.map(val, function ( value ) {
2071                                          return value == null ? "" : value + "";
2072                                  });
2073                          }
2074  
2075                          hooks = jQuery.valHooks[ this.nodeName.toLowerCase() ] || jQuery.valHooks[ this.type ];
2076  
2077                          // If set returns undefined, fall back to normal setting
2078                          if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
2079                                  this.value = val;
2080                          }
2081                  });
2082          }
2083  });
2084  
2085  jQuery.extend({
2086          valHooks: {
2087                  option: {
2088                          get: function( elem ) {
2089                                  // attributes.value is undefined in Blackberry 4.7 but
2090                                  // uses .value. See #6932
2091                                  var val = elem.attributes.value;
2092                                  return !val || val.specified ? elem.value : elem.text;
2093                          }
2094                  },
2095                  select: {
2096                          get: function( elem ) {
2097                                  var value,
2098                                          index = elem.selectedIndex,
2099                                          values = [],
2100                                          options = elem.options,
2101                                          one = elem.type === "select-one";
2102  
2103                                  // Nothing was selected
2104                                  if ( index < 0 ) {
2105                                          return null;
2106                                  }
2107  
2108                                  // Loop through all the selected options
2109                                  for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
2110                                          var option = options[ i ];
2111  
2112                                          // Don't return options that are disabled or in a disabled optgroup
2113                                          if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) &&
2114                                                          (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) {
2115  
2116                                                  // Get the specific value for the option
2117                                                  value = jQuery( option ).val();
2118  
2119                                                  // We don't need an array for one selects
2120                                                  if ( one ) {
2121                                                          return value;
2122                                                  }
2123  
2124                                                  // Multi-Selects return an array
2125                                                  values.push( value );
2126                                          }
2127                                  }
2128  
2129                                  // Fixes Bug #2551 -- select.val() broken in IE after form.reset()
2130                                  if ( one && !values.length && options.length ) {
2131                                          return jQuery( options[ index ] ).val();
2132                                  }
2133  
2134                                  return values;
2135                          },
2136  
2137                          set: function( elem, value ) {
2138                                  var values = jQuery.makeArray( value );
2139  
2140                                  jQuery(elem).find("option").each(function() {
2141                                          this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
2142                                  });
2143  
2144                                  if ( !values.length ) {
2145                                          elem.selectedIndex = -1;
2146                                  }
2147                                  return values;
2148                          }
2149                  }
2150          },
2151  
2152          attrFn: {
2153                  val: true,
2154                  css: true,
2155                  html: true,
2156                  text: true,
2157                  data: true,
2158                  width: true,
2159                  height: true,
2160                  offset: true
2161          },
2162         
2163          attrFix: {
2164                  // Always normalize to ensure hook usage
2165                  tabindex: "tabIndex"
2166          },
2167         
2168          attr: function( elem, name, value, pass ) {
2169                  var nType = elem.nodeType;
2170                 
2171                  // don't get/set attributes on text, comment and attribute nodes
2172                  if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
2173                          return undefined;
2174                  }
2175  
2176                  if ( pass && name in jQuery.attrFn ) {
2177                          return jQuery( elem )[ name ]( value );
2178                  }
2179  
2180                  // Fallback to prop when attributes are not supported
2181                  if ( !("getAttribute" in elem) ) {
2182                          return jQuery.prop( elem, name, value );
2183                  }
2184  
2185                  var ret, hooks,
2186                          notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
2187  
2188                  // Normalize the name if needed
2189                  name = notxml && jQuery.attrFix[ name ] || name;
2190  
2191                  hooks = jQuery.attrHooks[ name ];
2192  
2193                  if ( !hooks ) {
2194                          // Use boolHook for boolean attributes
2195                          if ( rboolean.test( name ) &&
2196                                  (typeof value === "boolean" || value === undefined || value.toLowerCase() === name.toLowerCase()) ) {
2197  
2198                                  hooks = boolHook;
2199  
2200                          // Use formHook for forms and if the name contains certain characters
2201                          } else if ( formHook && (jQuery.nodeName( elem, "form" ) || rinvalidChar.test( name )) ) {
2202                                  hooks = formHook;
2203                          }
2204                  }
2205  
2206                  if ( value !== undefined ) {
2207  
2208                          if ( value === null ) {
2209                                  jQuery.removeAttr( elem, name );
2210                                  return undefined;
2211  
2212                          } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) {
2213                                  return ret;
2214  
2215                          } else {
2216                                  elem.setAttribute( name, "" + value );
2217                                  return value;
2218                          }
2219  
2220                  } else if ( hooks && "get" in hooks && notxml ) {
2221                          return hooks.get( elem, name );
2222  
2223                  } else {
2224  
2225                          ret = elem.getAttribute( name );
2226  
2227                          // Non-existent attributes return null, we normalize to undefined
2228                          return ret === null ?
2229                                  undefined :
2230                                  ret;
2231                  }
2232          },
2233  
2234          removeAttr: function( elem, name ) {
2235                  var propName;
2236                  if ( elem.nodeType === 1 ) {
2237                          name = jQuery.attrFix[ name ] || name;
2238                 
2239                          if ( jQuery.support.getSetAttribute ) {
2240                                  // Use removeAttribute in browsers that support it
2241                                  elem.removeAttribute( name );
2242                          } else {
2243                                  jQuery.attr( elem, name, "" );
2244                                  elem.removeAttributeNode( elem.getAttributeNode( name ) );
2245                          }
2246  
2247                          // Set corresponding property to false for boolean attributes
2248                          if ( rboolean.test( name ) && (propName = jQuery.propFix[ name ] || name) in elem ) {
2249                                  elem[ propName ] = false;
2250                          }
2251                  }
2252          },
2253  
2254          attrHooks: {
2255                  type: {
2256                          set: function( elem, value ) {
2257                                  // We can't allow the type property to be changed (since it causes problems in IE)
2258                                  if ( rtype.test( elem.nodeName ) && elem.parentNode ) {
2259                                          jQuery.error( "type property can't be changed" );
2260                                  } else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) {
2261                                          // Setting the type on a radio button after the value resets the value in IE6-9
2262                                          // Reset value to it's default in case type is set after value
2263                                          // This is for element creation
2264                                          var val = elem.value;
2265                                          elem.setAttribute( "type", value );
2266                                          if ( val ) {
2267                                                  elem.value = val;
2268                                          }
2269                                          return value;
2270                                  }
2271                          }
2272                  },
2273                  tabIndex: {
2274                          get: function( elem ) {
2275                                  // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
2276                                  // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
2277                                  var attributeNode = elem.getAttributeNode("tabIndex");
2278  
2279                                  return attributeNode && attributeNode.specified ?
2280                                          parseInt( attributeNode.value, 10 ) :
2281                                          rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
2282                                                  0 :
2283                                                  undefined;
2284                          }
2285                  }
2286          },
2287  
2288          propFix: {
2289                  tabindex: "tabIndex",
2290                  readonly: "readOnly",
2291                  "for": "htmlFor",
2292                  "class": "className",
2293                  maxlength: "maxLength",
2294                  cellspacing: "cellSpacing",
2295                  cellpadding: "cellPadding",
2296                  rowspan: "rowSpan",
2297                  colspan: "colSpan",
2298                  usemap: "useMap",
2299                  frameborder: "frameBorder",
2300                  contenteditable: "contentEditable"
2301          },
2302         
2303          prop: function( elem, name, value ) {
2304                  var nType = elem.nodeType;
2305  
2306                  // don't get/set properties on text, comment and attribute nodes
2307                  if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
2308                          return undefined;
2309                  }
2310  
2311                  var ret, hooks,
2312                          notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
2313  
2314                  // Try to normalize/fix the name
2315                  name = notxml && jQuery.propFix[ name ] || name;
2316                 
2317                  hooks = jQuery.propHooks[ name ];
2318  
2319                  if ( value !== undefined ) {
2320                          if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
2321                                  return ret;
2322  
2323                          } else {
2324                                  return (elem[ name ] = value);
2325                          }
2326  
2327                  } else {
2328                          if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== undefined ) {
2329                                  return ret;
2330  
2331                          } else {
2332                                  return elem[ name ];
2333                          }
2334                  }
2335          },
2336         
2337          propHooks: {}
2338  });
2339  
2340  // Hook for boolean attributes
2341  boolHook = {
2342          get: function( elem, name ) {
2343                  // Align boolean attributes with corresponding properties
2344                  return elem[ jQuery.propFix[ name ] || name ] ?
2345                          name.toLowerCase() :
2346                          undefined;
2347          },
2348          set: function( elem, value, name ) {
2349                  var propName;
2350                  if ( value === false ) {
2351                          // Remove boolean attributes when set to false
2352                          jQuery.removeAttr( elem, name );
2353                  } else {
2354                          // value is true since we know at this point it's type boolean and not false
2355                          // Set boolean attributes to the same name and set the DOM property
2356                          propName = jQuery.propFix[ name ] || name;
2357                          if ( propName in elem ) {
2358                                  // Only set the IDL specifically if it already exists on the element
2359                                  elem[ propName ] = value;
2360                          }
2361  
2362                          elem.setAttribute( name, name.toLowerCase() );
2363                  }
2364                  return name;
2365          }
2366  };
2367  
2368  // Use the value property for back compat
2369  // Use the formHook for button elements in IE6/7 (#1954)
2370  jQuery.attrHooks.value = {
2371          get: function( elem, name ) {
2372                  if ( formHook && jQuery.nodeName( elem, "button" ) ) {
2373                          return formHook.get( elem, name );
2374                  }
2375                  return elem.value;
2376          },
2377          set: function( elem, value, name ) {
2378                  if ( formHook && jQuery.nodeName( elem, "button" ) ) {
2379                          return formHook.set( elem, value, name );
2380                  }
2381                  // Does not return so that setAttribute is also used
2382                  elem.value = value;
2383          }
2384  };
2385  
2386  // IE6/7 do not support getting/setting some attributes with get/setAttribute
2387  if ( !jQuery.support.getSetAttribute ) {
2388  
2389          // propFix is more comprehensive and contains all fixes
2390          jQuery.attrFix = jQuery.propFix;
2391         
2392          // Use this for any attribute on a form in IE6/7
2393          formHook = jQuery.attrHooks.name = jQuery.valHooks.button = {
2394                  get: function( elem, name ) {
2395                          var ret;
2396                          ret = elem.getAttributeNode( name );
2397                          // Return undefined if nodeValue is empty string
2398                          return ret && ret.nodeValue !== "" ?
2399                                  ret.nodeValue :
2400                                  undefined;
2401                  },
2402                  set: function( elem, value, name ) {
2403                          // Check form objects in IE (multiple bugs related)
2404                          // Only use nodeValue if the attribute node exists on the form
2405                          var ret = elem.getAttributeNode( name );
2406                          if ( ret ) {
2407                                  ret.nodeValue = value;
2408                                  return value;
2409                          }
2410                  }
2411          };
2412  
2413          // Set width and height to auto instead of 0 on empty string( Bug #8150 )
2414          // This is for removals
2415          jQuery.each([ "width", "height" ], function( i, name ) {
2416                  jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
2417                          set: function( elem, value ) {
2418                                  if ( value === "" ) {
2419                                          elem.setAttribute( name, "auto" );
2420                                          return value;
2421                                  }
2422                          }
2423                  });
2424          });
2425  }
2426  
2427  
2428  // Some attributes require a special call on IE
2429  if ( !jQuery.support.hrefNormalized ) {
2430          jQuery.each([ "href", "src", "width", "height" ], function( i, name ) {
2431                  jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
2432                          get: function( elem ) {
2433                                  var ret = elem.getAttribute( name, 2 );
2434                                  return ret === null ? undefined : ret;
2435                          }
2436                  });
2437          });
2438  }
2439  
2440  if ( !jQuery.support.style ) {
2441          jQuery.attrHooks.style = {
2442                  get: function( elem ) {
2443                          // Return undefined in the case of empty string
2444                          // Normalize to lowercase since IE uppercases css property names
2445                          return elem.style.cssText.toLowerCase() || undefined;
2446                  },
2447                  set: function( elem, value ) {
2448                          return (elem.style.cssText = "" + value);
2449                  }
2450          };
2451  }
2452  
2453  // Safari mis-reports the default selected property of an option
2454  // Accessing the parent's selectedIndex property fixes it
2455  if ( !jQuery.support.optSelected ) {
2456          jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, {
2457                  get: function( elem ) {
2458                          var parent = elem.parentNode;
2459  
2460                          if ( parent ) {
2461                                  parent.selectedIndex;
2462  
2463                                  // Make sure that it also works with optgroups, see #5701
2464                                  if ( parent.parentNode ) {
2465                                          parent.parentNode.selectedIndex;
2466                                  }
2467                          }
2468                  }
2469          });
2470  }
2471  
2472  // Radios and checkboxes getter/setter
2473  if ( !jQuery.support.checkOn ) {
2474          jQuery.each([ "radio", "checkbox" ], function() {
2475                  jQuery.valHooks[ this ] = {
2476                          get: function( elem ) {
2477                                  // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
2478                                  return elem.getAttribute("value") === null ? "on" : elem.value;
2479                          }
2480                  };
2481          });
2482  }
2483  jQuery.each([ "radio", "checkbox" ], function() {
2484          jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], {
2485                  set: function( elem, value ) {
2486                          if ( jQuery.isArray( value ) ) {
2487                                  return (elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0);
2488                          }
2489                  }
2490          });
2491  });
2492  
2493  
2494  
2495  
2496  var hasOwn = Object.prototype.hasOwnProperty,
2497          rnamespaces = /\.(.*)$/,
2498          rformElems = /^(?:textarea|input|select)$/i,
2499          rperiod = /\./g,
2500          rspaces = / /g,
2501          rescape = /[^\w\s.|`]/g,
2502          fcleanup = function( nm ) {
2503                  return nm.replace(rescape, "\\$&");
2504          };
2505  
2506  /*
2507   * A number of helper functions used for managing events.
2508   * Many of the ideas behind this code originated from
2509   * Dean Edwards' addEvent library.
2510   */
2511  jQuery.event = {
2512  
2513          // Bind an event to an element
2514          // Original by Dean Edwards
2515          add: function( elem, types, handler, data ) {
2516                  if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
2517                          return;
2518                  }
2519  
2520                  if ( handler === false ) {
2521                          handler = returnFalse;
2522                  } else if ( !handler ) {
2523                          // Fixes bug #7229. Fix recommended by jdalton
2524                          return;
2525                  }
2526  
2527                  var handleObjIn, handleObj;
2528  
2529                  if ( handler.handler ) {
2530                          handleObjIn = handler;
2531                          handler = handleObjIn.handler;
2532                  }
2533  
2534                  // Make sure that the function being executed has a unique ID
2535                  if ( !handler.guid ) {
2536                          handler.guid = jQuery.guid++;
2537                  }
2538  
2539                  // Init the element's event structure
2540                  var elemData = jQuery._data( elem );
2541  
2542                  // If no elemData is found then we must be trying to bind to one of the
2543                  // banned noData elements
2544                  if ( !elemData ) {
2545                          return;
2546                  }
2547  
2548                  var events = elemData.events,
2549                          eventHandle = elemData.handle;
2550  
2551                  if ( !events ) {
2552                          elemData.events = events = {};
2553                  }
2554  
2555                  if ( !eventHandle ) {
2556                          elemData.handle = eventHandle = function( e ) {
2557                                  // Discard the second event of a jQuery.event.trigger() and
2558                                  // when an event is called after a page has unloaded
2559                                  return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ?
2560                                          jQuery.event.handle.apply( eventHandle.elem, arguments ) :
2561                                          undefined;
2562                          };
2563                  }
2564  
2565                  // Add elem as a property of the handle function
2566                  // This is to prevent a memory leak with non-native events in IE.
2567                  eventHandle.elem = elem;
2568  
2569                  // Handle multiple events separated by a space
2570                  // jQuery(...).bind("mouseover mouseout", fn);
2571                  types = types.split(" ");
2572  
2573                  var type, i = 0, namespaces;
2574  
2575                  while ( (type = types[ i++ ]) ) {
2576                          handleObj = handleObjIn ?
2577                                  jQuery.extend({}, handleObjIn) :
2578                                  { handler: handler, data: data };
2579  
2580                          // Namespaced event handlers
2581                          if ( type.indexOf(".") > -1 ) {
2582                                  namespaces = type.split(".");
2583                                  type = namespaces.shift();
2584                                  handleObj.namespace = namespaces.slice(0).sort().join(".");
2585  
2586                          } else {
2587                                  namespaces = [];
2588                                  handleObj.namespace = "";
2589                          }
2590  
2591                          handleObj.type = type;
2592                          if ( !handleObj.guid ) {
2593                                  handleObj.guid = handler.guid;
2594                          }
2595  
2596                          // Get the current list of functions bound to this event
2597                          var handlers = events[ type ],
2598                                  special = jQuery.event.special[ type ] || {};
2599  
2600                          // Init the event handler queue
2601                          if ( !handlers ) {
2602                                  handlers = events[ type ] = [];
2603  
2604                                  // Check for a special event handler
2605                                  // Only use addEventListener/attachEvent if the special
2606                                  // events handler returns false
2607                                  if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
2608                                          // Bind the global event handler to the element
2609                                          if ( elem.addEventListener ) {
2610                                                  elem.addEventListener( type, eventHandle, false );
2611  
2612                                          } else if ( elem.attachEvent ) {
2613                                                  elem.attachEvent( "on" + type, eventHandle );
2614                                          }
2615                                  }
2616                          }
2617  
2618                          if ( special.add ) {
2619                                  special.add.call( elem, handleObj );
2620  
2621                                  if ( !handleObj.handler.guid ) {
2622                                          handleObj.handler.guid = handler.guid;
2623                                  }
2624                          }
2625  
2626                          // Add the function to the element's handler list
2627                          handlers.push( handleObj );
2628  
2629                          // Keep track of which events have been used, for event optimization
2630                          jQuery.event.global[ type ] = true;
2631                  }
2632  
2633                  // Nullify elem to prevent memory leaks in IE
2634                  elem = null;
2635          },
2636  
2637          global: {},
2638  
2639          // Detach an event or set of events from an element
2640          remove: function( elem, types, handler, pos ) {
2641                  // don't do events on text and comment nodes
2642                  if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
2643                          return;
2644                  }
2645  
2646                  if ( handler === false ) {
2647                          handler = returnFalse;
2648                  }
2649  
2650                  var ret, type, fn, j, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType,
2651                          elemData = jQuery.hasData( elem ) && jQuery._data( elem ),
2652                          events = elemData && elemData.events;
2653  
2654                  if ( !elemData || !events ) {
2655                          return;
2656                  }
2657  
2658                  // types is actually an event object here
2659                  if ( types && types.type ) {
2660                          handler = types.handler;
2661                          types = types.type;
2662                  }
2663  
2664                  // Unbind all events for the element
2665                  if ( !types || typeof types === "string" && types.charAt(0) === "." ) {
2666                          types = types || "";
2667  
2668                          for ( type in events ) {
2669                                  jQuery.event.remove( elem, type + types );
2670                          }
2671  
2672                          return;
2673                  }
2674  
2675                  // Handle multiple events separated by a space
2676                  // jQuery(...).unbind("mouseover mouseout", fn);
2677                  types = types.split(" ");
2678  
2679                  while ( (type = types[ i++ ]) ) {
2680                          origType = type;
2681                          handleObj = null;
2682                          all = type.indexOf(".") < 0;
2683                          namespaces = [];
2684  
2685                          if ( !all ) {
2686                                  // Namespaced event handlers
2687                                  namespaces = type.split(".");
2688                                  type = namespaces.shift();
2689  
2690                                  namespace = new RegExp("(^|\\.)" +
2691                                          jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)");
2692                          }
2693  
2694                          eventType = events[ type ];
2695  
2696                          if ( !eventType ) {
2697                                  continue;
2698                          }
2699  
2700                          if ( !handler ) {
2701                                  for ( j = 0; j < eventType.length; j++ ) {
2702                                          handleObj = eventType[ j ];
2703  
2704                                          if ( all || namespace.test( handleObj.namespace ) ) {
2705                                                  jQuery.event.remove( elem, origType, handleObj.handler, j );
2706                                                  eventType.splice( j--, 1 );
2707                                          }
2708                                  }
2709  
2710                                  continue;
2711                          }
2712  
2713                          special = jQuery.event.special[ type ] || {};
2714  
2715                          for ( j = pos || 0; j < eventType.length; j++ ) {
2716                                  handleObj = eventType[ j ];
2717  
2718                                  if ( handler.guid === handleObj.guid ) {
2719                                          // remove the given handler for the given type
2720                                          if ( all || namespace.test( handleObj.namespace ) ) {
2721                                                  if ( pos == null ) {
2722                                                          eventType.splice( j--, 1 );
2723                                                  }
2724  
2725                                                  if ( special.remove ) {
2726                                                          special.remove.call( elem, handleObj );
2727                                                  }
2728                                          }
2729  
2730                                          if ( pos != null ) {
2731                                                  break;
2732                                          }
2733                                  }
2734                          }
2735  
2736                          // remove generic event handler if no more handlers exist
2737                          if ( eventType.length === 0 || pos != null && eventType.length === 1 ) {
2738                                  if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
2739                                          jQuery.removeEvent( elem, type, elemData.handle );
2740                                  }
2741  
2742                                  ret = null;
2743                                  delete events[ type ];
2744                          }
2745                  }
2746  
2747                  // Remove the expando if it's no longer used
2748                  if ( jQuery.isEmptyObject( events ) ) {
2749                          var handle = elemData.handle;
2750                          if ( handle ) {
2751                                  handle.elem = null;
2752                          }
2753  
2754                          delete elemData.events;
2755                          delete elemData.handle;
2756  
2757                          if ( jQuery.isEmptyObject( elemData ) ) {
2758                                  jQuery.removeData( elem, undefined, true );
2759                          }
2760                  }
2761          },
2762         
2763          // Events that are safe to short-circuit if no handlers are attached.
2764          // Native DOM events should not be added, they may have inline handlers.
2765          customEvent: {
2766                  "getData": true,
2767                  "setData": true,
2768                  "changeData": true
2769          },
2770  
2771          trigger: function( event, data, elem, onlyHandlers ) {
2772                  // Event object or event type
2773                  var type = event.type || event,
2774                          namespaces = [],
2775                          exclusive;
2776  
2777                  if ( type.indexOf("!") >= 0 ) {
2778                          // Exclusive events trigger only for the exact event (no namespaces)
2779                          type = type.slice(0, -1);
2780                          exclusive = true;
2781                  }
2782  
2783                  if ( type.indexOf(".") >= 0 ) {
2784                          // Namespaced trigger; create a regexp to match event type in handle()
2785                          namespaces = type.split(".");
2786                          type = namespaces.shift();
2787                          namespaces.sort();
2788                  }
2789  
2790                  if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) {
2791                          // No jQuery handlers for this event type, and it can't have inline handlers
2792                          return;
2793                  }
2794  
2795                  // Caller can pass in an Event, Object, or just an event type string
2796                  event = typeof event === "object" ?
2797                          // jQuery.Event object
2798                          event[ jQuery.expando ] ? event :
2799                          // Object literal
2800                          new jQuery.Event( type, event ) :
2801                          // Just the event type (string)
2802                          new jQuery.Event( type );
2803  
2804                  event.type = type;
2805                  event.exclusive = exclusive;
2806                  event.namespace = namespaces.join(".");
2807                  event.namespace_re = new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)");
2808                 
2809                  // triggerHandler() and global events don't bubble or run the default action
2810                  if ( onlyHandlers || !elem ) {
2811                          event.preventDefault();
2812                          event.stopPropagation();
2813                  }
2814  
2815                  // Handle a global trigger
2816                  if ( !elem ) {
2817                          // TODO: Stop taunting the data cache; remove global events and always attach to document
2818                          jQuery.each( jQuery.cache, function() {
2819                                  // internalKey variable is just used to make it easier to find
2820                                  // and potentially change this stuff later; currently it just
2821                                  // points to jQuery.expando
2822                                  var internalKey = jQuery.expando,
2823                                          internalCache = this[ internalKey ];
2824                                  if ( internalCache && internalCache.events && internalCache.events[ type ] ) {
2825                                          jQuery.event.trigger( event, data, internalCache.handle.elem );
2826                                  }
2827                          });
2828                          return;
2829                  }
2830  
2831                  // Don't do events on text and comment nodes
2832                  if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
2833                          return;
2834                  }
2835  
2836                  // Clean up the event in case it is being reused
2837                  event.result = undefined;
2838                  event.target = elem;
2839  
2840                  // Clone any incoming data and prepend the event, creating the handler arg list
2841                  data = data ? jQuery.makeArray( data ) : [];
2842                  data.unshift( event );
2843  
2844                  var cur = elem,
2845                          // IE doesn't like method names with a colon (#3533, #8272)
2846                          ontype = type.indexOf(":") < 0 ? "on" + type : "";
2847  
2848                  // Fire event on the current element, then bubble up the DOM tree
2849                  do {
2850                          var handle = jQuery._data( cur, "handle" );
2851  
2852                          event.currentTarget = cur;
2853                          if ( handle ) {
2854                                  handle.apply( cur, data );
2855                          }
2856  
2857                          // Trigger an inline bound script
2858                          if ( ontype && jQuery.acceptData( cur ) && cur[ ontype ] && cur[ ontype ].apply( cur, data ) === false ) {
2859                                  event.result = false;
2860                                  event.preventDefault();
2861                          }
2862  
2863                          // Bubble up to document, then to window
2864                          cur = cur.parentNode || cur.ownerDocument || cur === event.target.ownerDocument && window;
2865                  } while ( cur && !event.isPropagationStopped() );
2866  
2867                  // If nobody prevented the default action, do it now
2868                  if ( !event.isDefaultPrevented() ) {
2869                          var old,
2870                                  special = jQuery.event.special[ type ] || {};
2871  
2872                          if ( (!special._default || special._default.call( elem.ownerDocument, event ) === false) &&
2873                                  !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) {
2874  
2875                                  // Call a native DOM method on the target with the same name name as the event.
2876                                  // Can't use an .isFunction)() check here because IE6/7 fails that test.
2877                                  // IE<9 dies on focus to hidden element (#1486), may want to revisit a try/catch.
2878                                  try {
2879                                          if ( ontype && elem[ type ] ) {
2880                                                  // Don't re-trigger an onFOO event when we call its FOO() method
2881                                                  old = elem[ ontype ];
2882  
2883                                                  if ( old ) {
2884                                                          elem[ ontype ] = null;
2885                                                  }
2886  
2887                                                  jQuery.event.triggered = type;
2888                                                  elem[ type ]();
2889                                          }
2890                                  } catch ( ieError ) {}
2891  
2892                                  if ( old ) {
2893                                          elem[ ontype ] = old;
2894                                  }
2895  
2896                                  jQuery.event.triggered = undefined;
2897                          }
2898                  }
2899                 
2900                  return event.result;
2901          },
2902  
2903          handle: function( event ) {
2904                  event = jQuery.event.fix( event || window.event );
2905                  // Snapshot the handlers list since a called handler may add/remove events.
2906                  var handlers = ((jQuery._data( this, "events" ) || {})[ event.type ] || []).slice(0),
2907                          run_all = !event.exclusive && !event.namespace,
2908                          args = Array.prototype.slice.call( arguments, 0 );
2909  
2910                  // Use the fix-ed Event rather than the (read-only) native event
2911                  args[0] = event;
2912                  event.currentTarget = this;
2913  
2914                  for ( var j = 0, l = handlers.length; j < l; j++ ) {
2915                          var handleObj = handlers[ j ];
2916  
2917                          // Triggered event must 1) be non-exclusive and have no namespace, or
2918                          // 2) have namespace(s) a subset or equal to those in the bound event.
2919                          if ( run_all || event.namespace_re.test( handleObj.namespace ) ) {
2920                                  // Pass in a reference to the handler function itself
2921                                  // So that we can later remove it
2922                                  event.handler = handleObj.handler;
2923                                  event.data = handleObj.data;
2924                                  event.handleObj = handleObj;
2925  
2926                                  var ret = handleObj.handler.apply( this, args );
2927  
2928                                  if ( ret !== undefined ) {
2929                                          event.result = ret;
2930                                          if ( ret === false ) {
2931                                                  event.preventDefault();
2932                                                  event.stopPropagation();
2933                                          }
2934                                  }
2935  
2936                                  if ( event.isImmediatePropagationStopped() ) {
2937                                          break;
2938                                  }
2939                          }
2940                  }
2941                  return event.result;
2942          },
2943  
2944          props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
2945  
2946          fix: function( event ) {
2947                  if ( event[ jQuery.expando ] ) {
2948                          return event;
2949                  }
2950  
2951                  // store a copy of the original event object
2952                  // and "clone" to set read-only properties
2953                  var originalEvent = event;
2954                  event = jQuery.Event( originalEvent );
2955  
2956                  for ( var i = this.props.length, prop; i; ) {
2957                          prop = this.props[ --i ];
2958                          event[ prop ] = originalEvent[ prop ];
2959                  }
2960  
2961                  // Fix target property, if necessary
2962                  if ( !event.target ) {
2963                          // Fixes #1925 where srcElement might not be defined either
2964                          event.target = event.srcElement || document;
2965                  }
2966  
2967                  // check if target is a textnode (safari)
2968                  if ( event.target.nodeType === 3 ) {
2969                          event.target = event.target.parentNode;
2970                  }
2971  
2972                  // Add relatedTarget, if necessary
2973                  if ( !event.relatedTarget && event.fromElement ) {
2974                          event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
2975                  }
2976  
2977                  // Calculate pageX/Y if missing and clientX/Y available
2978                  if ( event.pageX == null && event.clientX != null ) {
2979                          var eventDocument = event.target.ownerDocument || document,
2980                                  doc = eventDocument.documentElement,
2981                                  body = eventDocument.body;
2982  
2983                          event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
2984                          event.pageY = event.clientY + (doc && doc.scrollTop  || body && body.scrollTop  || 0) - (doc && doc.clientTop  || body && body.clientTop  || 0);
2985                  }
2986  
2987                  // Add which for key events
2988                  if ( event.which == null && (event.charCode != null || event.keyCode != null) ) {
2989                          event.which = event.charCode != null ? event.charCode : event.keyCode;
2990                  }
2991  
2992                  // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
2993                  if ( !event.metaKey && event.ctrlKey ) {
2994                          event.metaKey = event.ctrlKey;
2995                  }
2996  
2997                  // Add which for click: 1 === left; 2 === middle; 3 === right
2998                  // Note: button is not normalized, so don't use it
2999                  if ( !event.which && event.button !== undefined ) {
3000                          event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
3001                  }
3002  
3003                  return event;
3004          },
3005  
3006          // Deprecated, use jQuery.guid instead
3007          guid: 1E8,
3008  
3009          // Deprecated, use jQuery.proxy instead
3010          proxy: jQuery.proxy,
3011  
3012          special: {
3013                  ready: {
3014                          // Make sure the ready event is setup
3015                          setup: jQuery.bindReady,
3016                          teardown: jQuery.noop
3017                  },
3018  
3019                  live: {
3020                          add: function( handleObj ) {
3021                                  jQuery.event.add( this,
3022                                          liveConvert( handleObj.origType, handleObj.selector ),
3023                                          jQuery.extend({}, handleObj, {handler: liveHandler, guid: handleObj.handler.guid}) );
3024                          },
3025  
3026                          remove: function( handleObj ) {
3027                                  jQuery.event.remove( this, liveConvert( handleObj.origType, handleObj.selector ), handleObj );
3028                          }
3029                  },
3030  
3031                  beforeunload: {
3032                          setup: function( data, namespaces, eventHandle ) {
3033                                  // We only want to do this special case on windows
3034                                  if ( jQuery.isWindow( this ) ) {
3035                                          this.onbeforeunload = eventHandle;
3036                                  }
3037                          },
3038  
3039                          teardown: function( namespaces, eventHandle ) {
3040                                  if ( this.onbeforeunload === eventHandle ) {
3041                                          this.onbeforeunload = null;
3042                                  }
3043                          }
3044                  }
3045          }
3046  };
3047  
3048  jQuery.removeEvent = document.removeEventListener ?
3049          function( elem, type, handle ) {
3050                  if ( elem.removeEventListener ) {
3051                          elem.removeEventListener( type, handle, false );
3052                  }
3053          } :
3054          function( elem, type, handle ) {
3055                  if ( elem.detachEvent ) {
3056                          elem.detachEvent( "on" + type, handle );
3057                  }
3058          };
3059  
3060  jQuery.Event = function( src, props ) {
3061          // Allow instantiation without the 'new' keyword
3062          if ( !this.preventDefault ) {
3063                  return new jQuery.Event( src, props );
3064          }
3065  
3066          // Event object
3067          if ( src && src.type ) {
3068                  this.originalEvent = src;
3069                  this.type = src.type;
3070  
3071                  // Events bubbling up the document may have been marked as prevented
3072                  // by a handler lower down the tree; reflect the correct value.
3073                  this.isDefaultPrevented = (src.defaultPrevented || src.returnValue === false ||
3074                          src.getPreventDefault && src.getPreventDefault()) ? returnTrue : returnFalse;
3075  
3076          // Event type
3077          } else {
3078                  this.type = src;
3079          }
3080  
3081          // Put explicitly provided properties onto the event object
3082          if ( props ) {
3083                  jQuery.extend( this, props );
3084          }
3085  
3086          // timeStamp is buggy for some events on Firefox(#3843)
3087          // So we won't rely on the native value
3088          this.timeStamp = jQuery.now();
3089  
3090          // Mark it as fixed
3091          this[ jQuery.expando ] = true;
3092  };
3093  
3094  function returnFalse() {
3095          return false;
3096  }
3097  function returnTrue() {
3098          return true;
3099  }
3100  
3101  // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
3102  // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
3103  jQuery.Event.prototype = {
3104          preventDefault: function() {
3105                  this.isDefaultPrevented = returnTrue;
3106  
3107                  var e = this.originalEvent;
3108                  if ( !e ) {
3109                          return;
3110                  }
3111  
3112                  // if preventDefault exists run it on the original event
3113                  if ( e.preventDefault ) {
3114                          e.preventDefault();
3115  
3116                  // otherwise set the returnValue property of the original event to false (IE)
3117                  } else {
3118                          e.returnValue = false;
3119                  }
3120          },
3121          stopPropagation: function() {
3122                  this.isPropagationStopped = returnTrue;
3123  
3124                  var e = this.originalEvent;
3125                  if ( !e ) {
3126                          return;
3127                  }
3128                  // if stopPropagation exists run it on the original event
3129                  if ( e.stopPropagation ) {
3130                          e.stopPropagation();
3131                  }
3132                  // otherwise set the cancelBubble property of the original event to true (IE)
3133                  e.cancelBubble = true;
3134          },
3135          stopImmediatePropagation: function() {
3136                  this.isImmediatePropagationStopped = returnTrue;
3137                  this.stopPropagation();
3138          },
3139          isDefaultPrevented: returnFalse,
3140          isPropagationStopped: returnFalse,
3141          isImmediatePropagationStopped: returnFalse
3142  };
3143  
3144  // Checks if an event happened on an element within another element
3145  // Used in jQuery.event.special.mouseenter and mouseleave handlers
3146  var withinElement = function( event ) {
3147          // Check if mouse(over|out) are still within the same parent element
3148          var parent = event.relatedTarget;
3149  
3150          // set the correct event type
3151          event.type = event.data;
3152  
3153          // Firefox sometimes assigns relatedTarget a XUL element
3154          // which we cannot access the parentNode property of
3155          try {
3156  
3157                  // Chrome does something similar, the parentNode property
3158                  // can be accessed but is null.
3159                  if ( parent && parent !== document && !parent.parentNode ) {
3160                          return;
3161                  }
3162  
3163                  // Traverse up the tree
3164                  while ( parent && parent !== this ) {
3165                          parent = parent.parentNode;
3166                  }
3167  
3168                  if ( parent !== this ) {
3169                          // handle event if we actually just moused on to a non sub-element
3170                          jQuery.event.handle.apply( this, arguments );
3171                  }
3172  
3173          // assuming we've left the element since we most likely mousedover a xul element
3174          } catch(e) { }
3175  },
3176  
3177  // In case of event delegation, we only need to rename the event.type,
3178  // liveHandler will take care of the rest.
3179  delegate = function( event ) {
3180          event.type = event.data;
3181          jQuery.event.handle.apply( this, arguments );
3182  };
3183  
3184  // Create mouseenter and mouseleave events
3185  jQuery.each({
3186          mouseenter: "mouseover",
3187          mouseleave: "mouseout"
3188  }, function( orig, fix ) {
3189          jQuery.event.special[ orig ] = {
3190                  setup: function( data ) {
3191                          jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig );
3192                  },
3193                  teardown: function( data ) {
3194                          jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement );
3195                  }
3196          };
3197  });
3198  
3199  // submit delegation
3200  if ( !jQuery.support.submitBubbles ) {
3201  
3202          jQuery.event.special.submit = {
3203                  setup: function( data, namespaces ) {
3204                          if ( !jQuery.nodeName( this, "form" ) ) {
3205                                  jQuery.event.add(this, "click.specialSubmit", function( e ) {
3206                                          var elem = e.target,
3207                                                  type = elem.type;
3208  
3209                                          if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) {
3210                                                  trigger( "submit", this, arguments );
3211                                          }
3212                                  });
3213  
3214                                  jQuery.event.add(this, "keypress.specialSubmit", function( e ) {
3215                                          var elem = e.target,
3216                                                  type = elem.type;
3217  
3218                                          if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) {
3219                                                  trigger( "submit", this, arguments );
3220                                          }
3221                                  });
3222  
3223                          } else {
3224                                  return false;
3225                          }
3226                  },
3227  
3228                  teardown: function( namespaces ) {
3229                          jQuery.event.remove( this, ".specialSubmit" );
3230                  }
3231          };
3232  
3233  }
3234  
3235  // change delegation, happens here so we have bind.
3236  if ( !jQuery.support.changeBubbles ) {
3237  
3238          var changeFilters,
3239  
3240          getVal = function( elem ) {
3241                  var type = elem.type, val = elem.value;
3242  
3243                  if ( type === "radio" || type === "checkbox" ) {
3244                          val = elem.checked;
3245  
3246                  } else if ( type === "select-multiple" ) {
3247                          val = elem.selectedIndex > -1 ?
3248                                  jQuery.map( elem.options, function( elem ) {
3249                                          return elem.selected;
3250                                  }).join("-") :
3251                                  "";
3252  
3253                  } else if ( jQuery.nodeName( elem, "select" ) ) {
3254                          val = elem.selectedIndex;
3255                  }
3256  
3257                  return val;
3258          },
3259  
3260          testChange = function testChange( e ) {
3261                  var elem = e.target, data, val;
3262  
3263                  if ( !rformElems.test( elem.nodeName ) || elem.readOnly ) {
3264                          return;
3265                  }
3266  
3267                  data = jQuery._data( elem, "_change_data" );
3268                  val = getVal(elem);
3269  
3270                  // the current data will be also retrieved by beforeactivate
3271                  if ( e.type !== "focusout" || elem.type !== "radio" ) {
3272                          jQuery._data( elem, "_change_data", val );
3273                  }
3274  
3275                  if ( data === undefined || val === data ) {
3276                          return;
3277                  }
3278  
3279                  if ( data != null || val ) {
3280                          e.type = "change";
3281                          e.liveFired = undefined;
3282                          jQuery.event.trigger( e, arguments[1], elem );
3283                  }
3284          };
3285  
3286          jQuery.event.special.change = {
3287                  filters: {
3288                          focusout: testChange,
3289  
3290                          beforedeactivate: testChange,
3291  
3292                          click: function( e ) {
3293                                  var elem = e.target, type = jQuery.nodeName( elem, "input" ) ? elem.type : "";
3294  
3295                                  if ( type === "radio" || type === "checkbox" || jQuery.nodeName( elem, "select" ) ) {
3296                                          testChange.call( this, e );
3297                                  }
3298                          },
3299  
3300                          // Change has to be called before submit
3301                          // Keydown will be called before keypress, which is used in submit-event delegation
3302                          keydown: function( e ) {
3303                                  var elem = e.target, type = jQuery.nodeName( elem, "input" ) ? elem.type : "";
3304  
3305                                  if ( (e.keyCode === 13 && !jQuery.nodeName( elem, "textarea" ) ) ||
3306                                          (e.keyCode === 32 && (type === "checkbox" || type === "radio")) ||
3307                                          type === "select-multiple" ) {
3308                                          testChange.call( this, e );
3309                                  }
3310                          },
3311  
3312                          // Beforeactivate happens also before the previous element is blurred
3313                          // with this event you can't trigger a change event, but you can store
3314                          // information
3315                          beforeactivate: function( e ) {
3316                                  var elem = e.target;
3317                                  jQuery._data( elem, "_change_data", getVal(elem) );
3318                          }
3319                  },
3320  
3321                  setup: function( data, namespaces ) {
3322                          if ( this.type === "file" ) {
3323                                  return false;
3324                          }
3325  
3326                          for ( var type in changeFilters ) {
3327                                  jQuery.event.add( this, type + ".specialChange", changeFilters[type] );
3328                          }
3329  
3330                          return rformElems.test( this.nodeName );
3331                  },
3332  
3333                  teardown: function( namespaces ) {
3334                          jQuery.event.remove( this, ".specialChange" );
3335  
3336                          return rformElems.test( this.nodeName );
3337                  }
3338          };
3339  
3340          changeFilters = jQuery.event.special.change.filters;
3341  
3342          // Handle when the input is .focus()'d
3343          changeFilters.focus = changeFilters.beforeactivate;
3344  }
3345  
3346  function trigger( type, elem, args ) {
3347          // Piggyback on a donor event to simulate a different one.
3348          // Fake originalEvent to avoid donor's stopPropagation, but if the
3349          // simulated event prevents default then we do the same on the donor.
3350          // Don't pass args or remember liveFired; they apply to the donor event.
3351          var event = jQuery.extend( {}, args[ 0 ] );
3352          event.type = type;
3353          event.originalEvent = {};
3354          event.liveFired = undefined;
3355          jQuery.event.handle.call( elem, event );
3356          if ( event.isDefaultPrevented() ) {
3357                  args[ 0 ].preventDefault();
3358          }
3359  }
3360  
3361  // Create "bubbling" focus and blur events
3362  if ( !jQuery.support.focusinBubbles ) {
3363          jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
3364  
3365                  // Attach a single capturing handler while someone wants focusin/focusout
3366                  var attaches = 0;
3367  
3368                  jQuery.event.special[ fix ] = {
3369                          setup: function() {
3370                                  if ( attaches++ === 0 ) {
3371                                          document.addEventListener( orig, handler, true );
3372                                  }
3373                          },
3374                          teardown: function() {
3375                                  if ( --attaches === 0 ) {
3376                                          document.removeEventListener( orig, handler, true );
3377                                  }
3378                          }
3379                  };
3380  
3381                  function handler( donor ) {
3382                          // Donor event is always a native one; fix it and switch its type.
3383                          // Let focusin/out handler cancel the donor focus/blur event.
3384                          var e = jQuery.event.fix( donor );
3385                          e.type = fix;
3386                          e.originalEvent = {};
3387                          jQuery.event.trigger( e, null, e.target );
3388                          if ( e.isDefaultPrevented() ) {
3389                                  donor.preventDefault();
3390                          }
3391                  }
3392          });
3393  }
3394  
3395  jQuery.each(["bind", "one"], function( i, name ) {
3396          jQuery.fn[ name ] = function( type, data, fn ) {
3397                  var handler;
3398  
3399                  // Handle object literals
3400                  if ( typeof type === "object" ) {
3401                          for ( var key in type ) {
3402                                  this[ name ](key, data, type[key], fn);
3403                          }
3404                          return this;
3405                  }
3406  
3407                  if ( arguments.length === 2 || data === false ) {
3408                          fn = data;
3409                          data = undefined;
3410                  }
3411  
3412                  if ( name === "one" ) {
3413                          handler = function( event ) {
3414                                  jQuery( this ).unbind( event, handler );
3415                                  return fn.apply( this, arguments );
3416                          };
3417                          handler.guid = fn.guid || jQuery.guid++;
3418                  } else {
3419                          handler = fn;
3420                  }
3421  
3422                  if ( type === "unload" && name !== "one" ) {
3423                          this.one( type, data, fn );
3424  
3425                  } else {
3426                          for ( var i = 0, l = this.length; i < l; i++ ) {
3427                                  jQuery.event.add( this[i], type, handler, data );
3428                          }
3429                  }
3430  
3431                  return this;
3432          };
3433  });
3434  
3435  jQuery.fn.extend({
3436          unbind: function( type, fn ) {
3437                  // Handle object literals
3438                  if ( typeof type === "object" && !type.preventDefault ) {
3439                          for ( var key in type ) {
3440                                  this.unbind(key, type[key]);
3441                          }
3442  
3443                  } else {
3444                          for ( var i = 0, l = this.length; i < l; i++ ) {
3445                                  jQuery.event.remove( this[i], type, fn );
3446                          }
3447                  }
3448  
3449                  return this;
3450          },
3451  
3452          delegate: function( selector, types, data, fn ) {
3453                  return this.live( types, data, fn, selector );
3454          },
3455  
3456          undelegate: function( selector, types, fn ) {
3457                  if ( arguments.length === 0 ) {
3458                          return this.unbind( "live" );
3459  
3460                  } else {
3461                          return this.die( types, null, fn, selector );
3462                  }
3463          },
3464  
3465          trigger: function( type, data ) {
3466                  return this.each(function() {
3467                          jQuery.event.trigger( type, data, this );
3468                  });
3469          },
3470  
3471          triggerHandler: function( type, data ) {
3472                  if ( this[0] ) {
3473                          return jQuery.event.trigger( type, data, this[0], true );
3474                  }
3475          },
3476  
3477          toggle: function( fn ) {
3478                  // Save reference to arguments for access in closure
3479                  var args = arguments,
3480                          guid = fn.guid || jQuery.guid++,
3481                          i = 0,
3482                          toggler = function( event ) {
3483                                  // Figure out which function to execute
3484                                  var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i;
3485                                  jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 );
3486  
3487                                  // Make sure that clicks stop
3488                                  event.preventDefault();
3489  
3490                                  // and execute the function
3491                                  return args[ lastToggle ].apply( this, arguments ) || false;
3492                          };
3493  
3494                  // link all the functions, so any of them can unbind this click handler
3495                  toggler.guid = guid;
3496                  while ( i < args.length ) {
3497                          args[ i++ ].guid = guid;
3498                  }
3499  
3500                  return this.click( toggler );
3501          },
3502  
3503          hover: function( fnOver, fnOut ) {
3504                  return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
3505          }
3506  });
3507  
3508  var liveMap = {
3509          focus: "focusin",
3510          blur: "focusout",
3511          mouseenter: "mouseover",
3512          mouseleave: "mouseout"
3513  };
3514  
3515  jQuery.each(["live", "die"], function( i, name ) {
3516          jQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) {
3517                  var type, i = 0, match, namespaces, preType,
3518                          selector = origSelector || this.selector,
3519                          context = origSelector ? this : jQuery( this.context );
3520  
3521                  if ( typeof types === "object" && !types.preventDefault ) {
3522                          for ( var key in types ) {
3523                                  context[ name ]( key, data, types[key], selector );
3524                          }
3525  
3526                          return this;
3527                  }
3528  
3529                  if ( name === "die" && !types &&
3530                                          origSelector && origSelector.charAt(0) === "." ) {
3531  
3532                          context.unbind( origSelector );
3533  
3534                          return this;
3535                  }
3536  
3537                  if ( data === false || jQuery.isFunction( data ) ) {
3538                          fn = data || returnFalse;
3539                          data = undefined;
3540                  }
3541  
3542                  types = (types || "").split(" ");
3543  
3544                  while ( (type = types[ i++ ]) != null ) {
3545                          match = rnamespaces.exec( type );
3546                          namespaces = "";
3547  
3548                          if ( match )  {
3549                                  namespaces = match[0];
3550                                  type = type.replace( rnamespaces, "" );
3551                          }
3552  
3553                          if ( type === "hover" ) {
3554                                  types.push( "mouseenter" + namespaces, "mouseleave" + namespaces );
3555                                  continue;
3556                          }
3557  
3558                          preType = type;
3559  
3560                          if ( liveMap[ type ] ) {
3561                                  types.push( liveMap[ type ] + namespaces );
3562                                  type = type + namespaces;
3563  
3564                          } else {
3565                                  type = (liveMap[ type ] || type) + namespaces;
3566                          }
3567  
3568                          if ( name === "live" ) {
3569                                  // bind live handler
3570                                  for ( var j = 0, l = context.length; j < l; j++ ) {
3571                                          jQuery.event.add( context[j], "live." + liveConvert( type, selector ),
3572                                                  { data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } );
3573                                  }
3574  
3575                          } else {
3576                                  // unbind live handler
3577                                  context.unbind( "live." + liveConvert( type, selector ), fn );
3578                          }
3579                  }
3580  
3581                  return this;
3582          };
3583  });
3584  
3585  function liveHandler( event ) {
3586          var stop, maxLevel, related, match, handleObj, elem, j, i, l, data, close, namespace, ret,
3587                  elems = [],
3588                  selectors = [],
3589                  events = jQuery._data( this, "events" );
3590  
3591          // Make sure we avoid non-left-click bubbling in Firefox (#3861) and disabled elements in IE (#6911)
3592          if ( event.liveFired === this || !events || !events.live || event.target.disabled || event.button && event.type === "click" ) {
3593                  return;
3594          }
3595  
3596          if ( event.namespace ) {
3597                  namespace = new RegExp("(^|\\.)" + event.namespace.split(".").join("\\.(?:.*\\.)?") + "(\\.|$)");
3598          }
3599  
3600          event.liveFired = this;
3601  
3602          var live = events.live.slice(0);
3603  
3604          for ( j = 0; j < live.length; j++ ) {
3605                  handleObj = live[j];
3606  
3607                  if ( handleObj.origType.replace( rnamespaces, "" ) === event.type ) {
3608                          selectors.push( handleObj.selector );
3609  
3610                  } else {
3611                          live.splice( j--, 1 );
3612                  }
3613          }
3614  
3615          match = jQuery( event.target ).closest( selectors, event.currentTarget );
3616  
3617          for ( i = 0, l = match.length; i < l; i++ ) {
3618                  close = match[i];
3619  
3620                  for ( j = 0; j < live.length; j++ ) {
3621                          handleObj = live[j];
3622  
3623                          if ( close.selector === handleObj.selector && (!namespace || namespace.test( handleObj.namespace )) && !close.elem.disabled ) {
3624                                  elem = close.elem;
3625                                  related = null;
3626  
3627                                  // Those two events require additional checking
3628                                  if ( handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave" ) {
3629                                          event.type = handleObj.preType;
3630                                          related = jQuery( event.relatedTarget ).closest( handleObj.selector )[0];
3631  
3632                                          // Make sure not to accidentally match a child element with the same selector
3633                                          if ( related && jQuery.contains( elem, related ) ) {
3634                                                  related = elem;
3635                                          }
3636                                  }
3637  
3638                                  if ( !related || related !== elem ) {
3639                                          elems.push({ elem: elem, handleObj: handleObj, level: close.level });
3640                                  }
3641                          }
3642                  }
3643          }
3644  
3645          for ( i = 0, l = elems.length; i < l; i++ ) {
3646                  match = elems[i];
3647  
3648                  if ( maxLevel && match.level > maxLevel ) {
3649                          break;
3650                  }
3651  
3652                  event.currentTarget = match.elem;
3653                  event.data = match.handleObj.data;
3654                  event.handleObj = match.handleObj;
3655  
3656                  ret = match.handleObj.origHandler.apply( match.elem, arguments );
3657  
3658                  if ( ret === false || event.isPropagationStopped() ) {
3659                          maxLevel = match.level;
3660  
3661                          if ( ret === false ) {
3662                                  stop = false;
3663                          }
3664                          if ( event.isImmediatePropagationStopped() ) {
3665                                  break;
3666                          }
3667                  }
3668          }
3669  
3670          return stop;
3671  }
3672  
3673  function liveConvert( type, selector ) {
3674          return (type && type !== "*" ? type + "." : "") + selector.replace(rperiod, "`").replace(rspaces, "&");
3675  }
3676  
3677  jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
3678          "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
3679          "change select submit keydown keypress keyup error").split(" "), function( i, name ) {
3680  
3681          // Handle event binding
3682          jQuery.fn[ name ] = function( data, fn ) {
3683                  if ( fn == null ) {
3684                          fn = data;
3685                          data = null;
3686                  }
3687  
3688                  return arguments.length > 0 ?
3689                          this.bind( name, data, fn ) :
3690                          this.trigger( name );
3691          };
3692  
3693          if ( jQuery.attrFn ) {
3694                  jQuery.attrFn[ name ] = true;
3695          }
3696  });
3697  
3698  
3699  
3700  /*!
3701   * Sizzle CSS Selector Engine
3702   *  Copyright 2011, The Dojo Foundation
3703   *  Released under the MIT, BSD, and GPL Licenses.
3704   *  More information: http://sizzlejs.com/
3705   */
3706  (function(){
3707  
3708  var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
3709          done = 0,
3710          toString = Object.prototype.toString,
3711          hasDuplicate = false,
3712          baseHasDuplicate = true,
3713          rBackslash = /\\/g,
3714          rNonWord = /\W/;
3715  
3716  // Here we check if the JavaScript engine is using some sort of
3717  // optimization where it does not always call our comparision
3718  // function. If that is the case, discard the hasDuplicate value.
3719  //   Thus far that includes Google Chrome.
3720  [0, 0].sort(function() {
3721          baseHasDuplicate = false;
3722          return 0;
3723  });
3724  
3725  var Sizzle = function( selector, context, results, seed ) {
3726          results = results || [];
3727          context = context || document;
3728  
3729          var origContext = context;
3730  
3731          if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
3732                  return [];
3733          }
3734         
3735          if ( !selector || typeof selector !== "string" ) {
3736                  return results;
3737          }
3738  
3739          var m, set, checkSet, extra, ret, cur, pop, i,
3740                  prune = true,
3741                  contextXML = Sizzle.isXML( context ),
3742                  parts = [],
3743                  soFar = selector;
3744         
3745          // Reset the position of the chunker regexp (start from head)
3746          do {
3747                  chunker.exec( "" );
3748                  m = chunker.exec( soFar );
3749  
3750                  if ( m ) {
3751                          soFar = m[3];
3752                 
3753                          parts.push( m[1] );
3754                 
3755                          if ( m[2] ) {
3756                                  extra = m[3];
3757                                  break;
3758                          }
3759                  }
3760          } while ( m );
3761  
3762          if ( parts.length > 1 && origPOS.exec( selector ) ) {
3763  
3764                  if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
3765                          set = posProcess( parts[0] + parts[1], context );
3766  
3767                  } else {
3768                          set = Expr.relative[ parts[0] ] ?
3769                                  [ context ] :
3770                                  Sizzle( parts.shift(), context );
3771  
3772                          while ( parts.length ) {
3773                                  selector = parts.shift();
3774  
3775                                  if ( Expr.relative[ selector ] ) {
3776                                          selector += parts.shift();
3777                                  }
3778                                 
3779                                  set = posProcess( selector, set );
3780                          }
3781                  }
3782  
3783          } else {
3784                  // Take a shortcut and set the context if the root selector is an ID
3785                  // (but not if it'll be faster if the inner selector is an ID)
3786                  if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
3787                                  Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
3788  
3789                          ret = Sizzle.find( parts.shift(), context, contextXML );
3790                          context = ret.expr ?
3791                                  Sizzle.filter( ret.expr, ret.set )[0] :
3792                                  ret.set[0];
3793                  }
3794  
3795                  if ( context ) {
3796                          ret = seed ?
3797                                  { expr: parts.pop(), set: makeArray(seed) } :
3798                                  Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
3799  
3800                          set = ret.expr ?
3801                                  Sizzle.filter( ret.expr, ret.set ) :
3802                                  ret.set;
3803  
3804                          if ( parts.length > 0 ) {
3805                                  checkSet = makeArray( set );
3806  
3807                          } else {
3808                                  prune = false;
3809                          }
3810  
3811                          while ( parts.length ) {
3812                                  cur = parts.pop();
3813                                  pop = cur;
3814  
3815                                  if ( !Expr.relative[ cur ] ) {
3816                                          cur = "";
3817                                  } else {
3818                                          pop = parts.pop();
3819                                  }
3820  
3821                                  if ( pop == null ) {
3822                                          pop = context;
3823                                  }
3824  
3825                                  Expr.relative[ cur ]( checkSet, pop, contextXML );
3826                          }
3827  
3828                  } else {
3829                          checkSet = parts = [];
3830                  }
3831          }
3832  
3833          if ( !checkSet ) {
3834                  checkSet = set;
3835          }
3836  
3837          if ( !checkSet ) {
3838                  Sizzle.error( cur || selector );
3839          }
3840  
3841          if ( toString.call(checkSet) === "[object Array]" ) {
3842                  if ( !prune ) {
3843                          results.push.apply( results, checkSet );
3844  
3845                  } else if ( context && context.nodeType === 1 ) {
3846                          for ( i = 0; checkSet[i] != null; i++ ) {
3847                                  if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) {
3848                                          results.push( set[i] );
3849                                  }
3850                          }
3851  
3852                  } else {
3853                          for ( i = 0; checkSet[i] != null; i++ ) {
3854                                  if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
3855                                          results.push( set[i] );
3856                                  }
3857                          }
3858                  }
3859  
3860          } else {
3861                  makeArray( checkSet, results );
3862          }
3863  
3864          if ( extra ) {
3865                  Sizzle( extra, origContext, results, seed );
3866                  Sizzle.uniqueSort( results );
3867          }
3868  
3869          return results;
3870  };
3871  
3872  Sizzle.uniqueSort = function( results ) {
3873          if ( sortOrder ) {
3874                  hasDuplicate = baseHasDuplicate;
3875                  results.sort( sortOrder );
3876  
3877                  if ( hasDuplicate ) {
3878                          for ( var i = 1; i < results.length; i++ ) {
3879                                  if ( results[i] === results[ i - 1 ] ) {
3880                                          results.splice( i--, 1 );
3881                                  }
3882                          }
3883                  }
3884          }
3885  
3886          return results;
3887  };
3888  
3889  Sizzle.matches = function( expr, set ) {
3890          return Sizzle( expr, null, null, set );
3891  };
3892  
3893  Sizzle.matchesSelector = function( node, expr ) {
3894          return Sizzle( expr, null, null, [node] ).length > 0;
3895  };
3896  
3897  Sizzle.find = function( expr, context, isXML ) {
3898          var set;
3899  
3900          if ( !expr ) {
3901                  return [];
3902          }
3903  
3904          for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
3905                  var match,
3906                          type = Expr.order[i];
3907                 
3908                  if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
3909                          var left = match[1];
3910                          match.splice( 1, 1 );
3911  
3912                          if ( left.substr( left.length - 1 ) !== "\\" ) {
3913                                  match[1] = (match[1] || "").replace( rBackslash, "" );
3914                                  set = Expr.find[ type ]( match, context, isXML );
3915  
3916                                  if ( set != null ) {
3917                                          expr = expr.replace( Expr.match[ type ], "" );
3918                                          break;
3919                                  }
3920                          }
3921                  }
3922          }
3923  
3924          if ( !set ) {
3925                  set = typeof context.getElementsByTagName !== "undefined" ?
3926                          context.getElementsByTagName( "*" ) :
3927                          [];
3928          }
3929  
3930          return { set: set, expr: expr };
3931  };
3932  
3933  Sizzle.filter = function( expr, set, inplace, not ) {
3934          var match, anyFound,
3935                  old = expr,
3936                  result = [],
3937                  curLoop = set,
3938                  isXMLFilter = set && set[0] && Sizzle.isXML( set[0] );
3939  
3940          while ( expr && set.length ) {
3941                  for ( var type in Expr.filter ) {
3942                          if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {
3943                                  var found, item,
3944                                          filter = Expr.filter[ type ],
3945                                          left = match[1];
3946  
3947                                  anyFound = false;
3948  
3949                                  match.splice(1,1);
3950  
3951                                  if ( left.substr( left.length - 1 ) === "\\" ) {
3952                                          continue;
3953                                  }
3954  
3955                                  if ( curLoop === result ) {
3956                                          result = [];
3957                                  }
3958  
3959                                  if ( Expr.preFilter[ type ] ) {
3960                                          match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
3961  
3962                                          if ( !match ) {
3963                                                  anyFound = found = true;
3964  
3965                                          } else if ( match === true ) {
3966                                                  continue;
3967                                          }
3968                                  }
3969  
3970                                  if ( match ) {
3971                                          for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
3972                                                  if ( item ) {
3973                                                          found = filter( item, match, i, curLoop );
3974                                                          var pass = not ^ !!found;
3975  
3976                                                          if ( inplace && found != null ) {
3977                                                                  if ( pass ) {
3978                                                                          anyFound = true;
3979  
3980                                                                  } else {
3981                                                                          curLoop[i] = false;
3982                                                                  }
3983  
3984                                                          } else if ( pass ) {
3985                                                                  result.push( item );
3986                                                                  anyFound = true;
3987                                                          }
3988                                                  }
3989                                          }
3990                                  }
3991  
3992                                  if ( found !== undefined ) {
3993                                          if ( !inplace ) {
3994                                                  curLoop = result;
3995                                          }
3996  
3997                                          expr = expr.replace( Expr.match[ type ], "" );
3998  
3999                                          if ( !anyFound ) {
4000                                                  return [];
4001                                          }
4002  
4003                                          break;
4004                                  }
4005                          }
4006                  }
4007  
4008                  // Improper expression
4009                  if ( expr === old ) {
4010                          if ( anyFound == null ) {
4011                                  Sizzle.error( expr );
4012  
4013                          } else {
4014                                  break;
4015                          }
4016                  }
4017  
4018                  old = expr;
4019          }
4020  
4021          return curLoop;
4022  };
4023  
4024  Sizzle.error = function( msg ) {
4025          throw "Syntax error, unrecognized expression: " + msg;
4026  };
4027  
4028  var Expr = Sizzle.selectors = {
4029          order: [ "ID", "NAME", "TAG" ],
4030  
4031          match: {
4032                  ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
4033                  CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
4034                  NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,
4035                  ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,
4036                  TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,
4037                  CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,
4038                  POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,
4039                  PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/
4040          },
4041  
4042          leftMatch: {},
4043  
4044          attrMap: {
4045                  "class": "className",
4046                  "for": "htmlFor"
4047          },
4048  
4049          attrHandle: {
4050                  href: function( elem ) {
4051                          return elem.getAttribute( "href" );
4052                  },
4053                  type: function( elem ) {
4054                          return elem.getAttribute( "type" );
4055                  }
4056          },
4057  
4058          relative: {
4059                  "+": function(checkSet, part){
4060                          var isPartStr = typeof part === "string",
4061                                  isTag = isPartStr && !rNonWord.test( part ),
4062                                  isPartStrNotTag = isPartStr && !isTag;
4063  
4064                          if ( isTag ) {
4065                                  part = part.toLowerCase();
4066                          }
4067  
4068                          for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
4069                                  if ( (elem = checkSet[i]) ) {
4070                                          while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
4071  
4072                                          checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?
4073                                                  elem || false :
4074                                                  elem === part;
4075                                  }
4076                          }
4077  
4078                          if ( isPartStrNotTag ) {
4079                                  Sizzle.filter( part, checkSet, true );
4080                          }
4081                  },
4082  
4083                  ">": function( checkSet, part ) {
4084                          var elem,
4085                                  isPartStr = typeof part === "string",
4086                                  i = 0,
4087                                  l = checkSet.length;
4088  
4089                          if ( isPartStr && !rNonWord.test( part ) ) {
4090                                  part = part.toLowerCase();
4091  
4092                                  for ( ; i < l; i++ ) {
4093                                          elem = checkSet[i];
4094  
4095                                          if ( elem ) {
4096                                                  var parent = elem.parentNode;
4097                                                  checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;
4098                                          }
4099                                  }
4100  
4101                          } else {
4102                                  for ( ; i < l; i++ ) {
4103                                          elem = checkSet[i];
4104  
4105                                          if ( elem ) {
4106                                                  checkSet[i] = isPartStr ?
4107                                                          elem.parentNode :
4108                                                          elem.parentNode === part;
4109                                          }
4110                                  }
4111  
4112                                  if ( isPartStr ) {
4113                                          Sizzle.filter( part, checkSet, true );
4114                                  }
4115                          }
4116                  },
4117  
4118                  "": function(checkSet, part, isXML){
4119                          var nodeCheck,
4120                                  doneName = done++,
4121                                  checkFn = dirCheck;
4122  
4123                          if ( typeof part === "string" && !rNonWord.test( part ) ) {
4124                                  part = part.toLowerCase();
4125                                  nodeCheck = part;
4126                                  checkFn = dirNodeCheck;
4127                          }
4128  
4129                          checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML );
4130                  },
4131  
4132                  "~": function( checkSet, part, isXML ) {
4133                          var nodeCheck,
4134                                  doneName = done++,
4135                                  checkFn = dirCheck;
4136  
4137                          if ( typeof part === "string" && !rNonWord.test( part ) ) {
4138                                  part = part.toLowerCase();
4139                                  nodeCheck = part;
4140                                  checkFn = dirNodeCheck;
4141                          }
4142  
4143                          checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML );
4144                  }
4145          },
4146  
4147          find: {
4148                  ID: function( match, context, isXML ) {
4149                          if ( typeof context.getElementById !== "undefined" && !isXML ) {
4150                                  var m = context.getElementById(match[1]);
4151                                  // Check parentNode to catch when Blackberry 4.6 returns
4152                                  // nodes that are no longer in the document #6963
4153                                  return m && m.parentNode ? [m] : [];
4154                          }
4155                  },
4156  
4157                  NAME: function( match, context ) {
4158                          if ( typeof context.getElementsByName !== "undefined" ) {
4159                                  var ret = [],
4160                                          results = context.getElementsByName( match[1] );
4161  
4162                                  for ( var i = 0, l = results.length; i < l; i++ ) {
4163                                          if ( results[i].getAttribute("name") === match[1] ) {
4164                                                  ret.push( results[i] );
4165                                          }
4166                                  }
4167  
4168                                  return ret.length === 0 ? null : ret;
4169                          }
4170                  },
4171  
4172                  TAG: function( match, context ) {
4173                          if ( typeof context.getElementsByTagName !== "undefined" ) {
4174                                  return context.getElementsByTagName( match[1] );
4175                          }
4176                  }
4177          },
4178          preFilter: {
4179                  CLASS: function( match, curLoop, inplace, result, not, isXML ) {
4180                          match = " " + match[1].replace( rBackslash, "" ) + " ";
4181  
4182                          if ( isXML ) {
4183                                  return match;
4184                          }
4185  
4186                          for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
4187                                  if ( elem ) {
4188                                          if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) {
4189                                                  if ( !inplace ) {
4190                                                          result.push( elem );
4191                                                  }
4192  
4193                                          } else if ( inplace ) {
4194                                                  curLoop[i] = false;
4195                                          }
4196                                  }
4197                          }
4198  
4199                          return false;
4200                  },
4201  
4202                  ID: function( match ) {
4203                          return match[1].replace( rBackslash, "" );
4204                  },
4205  
4206                  TAG: function( match, curLoop ) {
4207                          return match[1].replace( rBackslash, "" ).toLowerCase();
4208                  },
4209  
4210                  CHILD: function( match ) {
4211                          if ( match[1] === "nth" ) {
4212                                  if ( !match[2] ) {
4213                                          Sizzle.error( match[0] );
4214                                  }
4215  
4216                                  match[2] = match[2].replace(/^\+|\s*/g, '');
4217  
4218                                  // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
4219                                  var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec(
4220                                          match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||
4221                                          !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
4222  
4223                                  // calculate the numbers (first)n+(last) including if they are negative
4224                                  match[2] = (test[1] + (test[2] || 1)) - 0;
4225                                  match[3] = test[3] - 0;
4226                          }
4227                          else if ( match[2] ) {
4228                                  Sizzle.error( match[0] );
4229                          }
4230  
4231                          // TODO: Move to normal caching system
4232                          match[0] = done++;
4233  
4234                          return match;
4235                  },
4236  
4237                  ATTR: function( match, curLoop, inplace, result, not, isXML ) {
4238                          var name = match[1] = match[1].replace( rBackslash, "" );
4239                         
4240                          if ( !isXML && Expr.attrMap[name] ) {
4241                                  match[1] = Expr.attrMap[name];
4242                          }
4243  
4244                          // Handle if an un-quoted value was used
4245                          match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" );
4246  
4247                          if ( match[2] === "~=" ) {
4248                                  match[4] = " " + match[4] + " ";
4249                          }
4250  
4251                          return match;
4252                  },
4253  
4254                  PSEUDO: function( match, curLoop, inplace, result, not ) {
4255                          if ( match[1] === "not" ) {
4256                                  // If we're dealing with a complex expression, or a simple one
4257                                  if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
4258                                          match[3] = Sizzle(match[3], null, null, curLoop);
4259  
4260                                  } else {
4261                                          var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
4262  
4263                                          if ( !inplace ) {
4264                                                  result.push.apply( result, ret );
4265                                          }
4266  
4267                                          return false;
4268                                  }
4269  
4270                          } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
4271                                  return true;
4272                          }
4273                         
4274                          return match;
4275                  },
4276  
4277                  POS: function( match ) {
4278                          match.unshift( true );
4279  
4280                          return match;
4281                  }
4282          },
4283         
4284          filters: {
4285                  enabled: function( elem ) {
4286                          return elem.disabled === false && elem.type !== "hidden";
4287                  },
4288  
4289                  disabled: function( elem ) {
4290                          return elem.disabled === true;
4291                  },
4292  
4293                  checked: function( elem ) {
4294                          return elem.checked === true;
4295                  },
4296                 
4297                  selected: function( elem ) {
4298                          // Accessing this property makes selected-by-default
4299                          // options in Safari work properly
4300                          if ( elem.parentNode ) {
4301                                  elem.parentNode.selectedIndex;
4302                          }
4303                         
4304                          return elem.selected === true;
4305                  },
4306  
4307                  parent: function( elem ) {
4308                          return !!elem.firstChild;
4309                  },
4310  
4311                  empty: function( elem ) {
4312                          return !elem.firstChild;
4313                  },
4314  
4315                  has: function( elem, i, match ) {
4316                          return !!Sizzle( match[3], elem ).length;
4317                  },
4318  
4319                  header: function( elem ) {
4320                          return (/h\d/i).test( elem.nodeName );
4321                  },
4322  
4323                  text: function( elem ) {
4324                          var attr = elem.getAttribute( "type" ), type = elem.type;
4325                          // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)
4326                          // use getAttribute instead to test this case
4327                          return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null );
4328                  },
4329  
4330                  radio: function( elem ) {
4331                          return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type;
4332                  },
4333  
4334                  checkbox: function( elem ) {
4335                          return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type;
4336                  },
4337  
4338                  file: function( elem ) {
4339                          return elem.nodeName.toLowerCase() === "input" && "file" === elem.type;
4340                  },
4341  
4342                  password: function( elem ) {
4343                          return elem.nodeName.toLowerCase() === "input" && "password" === elem.type;
4344                  },
4345  
4346                  submit: function( elem ) {
4347                          var name = elem.nodeName.toLowerCase();
4348                          return (name === "input" || name === "button") && "submit" === elem.type;
4349                  },
4350  
4351                  image: function( elem ) {
4352                          return elem.nodeName.toLowerCase() === "input" && "image" === elem.type;
4353                  },
4354  
4355                  reset: function( elem ) {
4356                          var name = elem.nodeName.toLowerCase();
4357                          return (name === "input" || name === "button") && "reset" === elem.type;
4358                  },
4359  
4360                  button: function( elem ) {
4361                          var name = elem.nodeName.toLowerCase();
4362                          return name === "input" && "button" === elem.type || name === "button";
4363                  },
4364  
4365                  input: function( elem ) {
4366                          return (/input|select|textarea|button/i).test( elem.nodeName );
4367                  },
4368  
4369                  focus: function( elem ) {
4370                          return elem === elem.ownerDocument.activeElement;
4371                  }
4372          },
4373          setFilters: {
4374                  first: function( elem, i ) {
4375                          return i === 0;
4376                  },
4377  
4378                  last: function( elem, i, match, array ) {
4379                          return i === array.length - 1;
4380                  },
4381  
4382                  even: function( elem, i ) {
4383                          return i % 2 === 0;
4384                  },
4385  
4386                  odd: function( elem, i ) {
4387                          return i % 2 === 1;
4388                  },
4389  
4390                  lt: function( elem, i, match ) {
4391                          return i < match[3] - 0;
4392                  },
4393  
4394                  gt: function( elem, i, match ) {
4395                          return i > match[3] - 0;
4396                  },
4397  
4398                  nth: function( elem, i, match ) {
4399                          return match[3] - 0 === i;
4400                  },
4401  
4402                  eq: function( elem, i, match ) {
4403                          return match[3] - 0 === i;
4404                  }
4405          },
4406          filter: {
4407                  PSEUDO: function( elem, match, i, array ) {
4408                          var name = match[1],
4409                                  filter = Expr.filters[ name ];
4410  
4411                          if ( filter ) {
4412                                  return filter( elem, i, match, array );
4413  
4414                          } else if ( name === "contains" ) {
4415                                  return (elem.textContent || elem.innerText || Sizzle.getText([ elem ]) || "").indexOf(match[3]) >= 0;
4416  
4417                          } else if ( name === "not" ) {
4418                                  var not = match[3];
4419  
4420                                  for ( var j = 0, l = not.length; j < l; j++ ) {
4421                                          if ( not[j] === elem ) {
4422                                                  return false;
4423                                          }
4424                                  }
4425  
4426                                  return true;
4427  
4428                          } else {
4429                                  Sizzle.error( name );
4430                          }
4431                  },
4432  
4433                  CHILD: function( elem, match ) {
4434                          var type = match[1],
4435                                  node = elem;
4436  
4437                          switch ( type ) {
4438                                  case "only":
4439                                  case "first":
4440                                          while ( (node = node.previousSibling) )  {
4441                                                  if ( node.nodeType === 1 ) { 
4442                                                          return false; 
4443                                                  }
4444                                          }
4445  
4446                                          if ( type === "first" ) { 
4447                                                  return true; 
4448                                          }
4449  
4450                                          node = elem;
4451  
4452                                  case "last":
4453                                          while ( (node = node.nextSibling) )      {
4454                                                  if ( node.nodeType === 1 ) { 
4455                                                          return false; 
4456                                                  }
4457                                          }
4458  
4459                                          return true;
4460  
4461                                  case "nth":
4462                                          var first = match[2],
4463                                                  last = match[3];
4464  
4465                                          if ( first === 1 && last === 0 ) {
4466                                                  return true;
4467                                          }
4468                                         
4469                                          var doneName = match[0],
4470                                                  parent = elem.parentNode;
4471         
4472                                          if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
4473                                                  var count = 0;
4474                                                 
4475                                                  for ( node = parent.firstChild; node; node = node.nextSibling ) {
4476                                                          if ( node.nodeType === 1 ) {
4477                                                                  node.nodeIndex = ++count;
4478                                                          }
4479                                                  } 
4480  
4481                                                  parent.sizcache = doneName;
4482                                          }
4483                                         
4484                                          var diff = elem.nodeIndex - last;
4485  
4486                                          if ( first === 0 ) {
4487                                                  return diff === 0;
4488  
4489                                          } else {
4490                                                  return ( diff % first === 0 && diff / first >= 0 );
4491                                          }
4492                          }
4493                  },
4494  
4495                  ID: function( elem, match ) {
4496                          return elem.nodeType === 1 && elem.getAttribute("id") === match;
4497                  },
4498  
4499                  TAG: function( elem, match ) {
4500                          return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match;
4501                  },
4502                 
4503                  CLASS: function( elem, match ) {
4504                          return (" " + (elem.className || elem.getAttribute("class")) + " ")
4505                                  .indexOf( match ) > -1;
4506                  },
4507  
4508                  ATTR: function( elem, match ) {
4509                          var name = match[1],
4510                                  result = Expr.attrHandle[ name ] ?
4511                                          Expr.attrHandle[ name ]( elem ) :
4512                                          elem[ name ] != null ?
4513                                                  elem[ name ] :
4514                                                  elem.getAttribute( name ),
4515                                  value = result + "",
4516                                  type = match[2],
4517                                  check = match[4];
4518  
4519                          return result == null ?
4520                                  type === "!=" :
4521                                  type === "=" ?
4522                                  value === check :
4523                                  type === "*=" ?
4524                                  value.indexOf(check) >= 0 :
4525                                  type === "~=" ?
4526                                  (" " + value + " ").indexOf(check) >= 0 :
4527                                  !check ?
4528                                  value && result !== false :
4529                                  type === "!=" ?
4530                                  value !== check :
4531                                  type === "^=" ?
4532                                  value.indexOf(check) === 0 :
4533                                  type === "$=" ?
4534                                  value.substr(value.length - check.length) === check :
4535                                  type === "|=" ?
4536                                  value === check || value.substr(0, check.length + 1) === check + "-" :
4537                                  false;
4538                  },
4539  
4540                  POS: function( elem, match, i, array ) {
4541                          var name = match[2],
4542                                  filter = Expr.setFilters[ name ];
4543  
4544                          if ( filter ) {
4545                                  return filter( elem, i, match, array );
4546                          }
4547                  }
4548          }
4549  };
4550  
4551  var origPOS = Expr.match.POS,
4552          fescape = function(all, num){
4553                  return "\\" + (num - 0 + 1);
4554          };
4555  
4556  for ( var type in Expr.match ) {
4557          Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) );
4558          Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) );
4559  }
4560  
4561  var makeArray = function( array, results ) {
4562          array = Array.prototype.slice.call( array, 0 );
4563  
4564          if ( results ) {
4565                  results.push.apply( results, array );
4566                  return results;
4567          }
4568         
4569          return array;
4570  };
4571  
4572  // Perform a simple check to determine if the browser is capable of
4573  // converting a NodeList to an array using builtin methods.
4574  // Also verifies that the returned array holds DOM nodes
4575  // (which is not the case in the Blackberry browser)
4576  try {
4577          Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType;
4578  
4579  // Provide a fallback method if it does not work
4580  } catch( e ) {
4581          makeArray = function( array, results ) {
4582                  var i = 0,
4583                          ret = results || [];
4584  
4585                  if ( toString.call(array) === "[object Array]" ) {
4586                          Array.prototype.push.apply( ret, array );
4587  
4588                  } else {
4589                          if ( typeof array.length === "number" ) {
4590                                  for ( var l = array.length; i < l; i++ ) {
4591                                          ret.push( array[i] );
4592                                  }
4593  
4594                          } else {
4595                                  for ( ; array[i]; i++ ) {
4596                                          ret.push( array[i] );
4597                                  }
4598                          }
4599                  }
4600  
4601                  return ret;
4602          };
4603  }
4604  
4605  var sortOrder, siblingCheck;
4606  
4607  if ( document.documentElement.compareDocumentPosition ) {
4608          sortOrder = function( a, b ) {
4609                  if ( a === b ) {
4610                          hasDuplicate = true;
4611                          return 0;
4612                  }
4613  
4614                  if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
4615                          return a.compareDocumentPosition ? -1 : 1;
4616                  }
4617  
4618                  return a.compareDocumentPosition(b) & 4 ? -1 : 1;
4619          };
4620  
4621  } else {
4622          sortOrder = function( a, b ) {
4623                  // The nodes are identical, we can exit early
4624                  if ( a === b ) {
4625                          hasDuplicate = true;
4626                          return 0;
4627  
4628                  // Fallback to using sourceIndex (in IE) if it's available on both nodes
4629                  } else if ( a.sourceIndex && b.sourceIndex ) {
4630                          return a.sourceIndex - b.sourceIndex;
4631                  }
4632  
4633                  var al, bl,
4634                          ap = [],
4635                          bp = [],
4636                          aup = a.parentNode,
4637                          bup = b.parentNode,
4638                          cur = aup;
4639  
4640                  // If the nodes are siblings (or identical) we can do a quick check
4641                  if ( aup === bup ) {
4642                          return siblingCheck( a, b );
4643  
4644                  // If no parents were found then the nodes are disconnected
4645                  } else if ( !aup ) {
4646                          return -1;
4647  
4648                  } else if ( !bup ) {
4649                          return 1;
4650                  }
4651  
4652                  // Otherwise they're somewhere else in the tree so we need
4653                  // to build up a full list of the parentNodes for comparison
4654                  while ( cur ) {
4655                          ap.unshift( cur );
4656                          cur = cur.parentNode;
4657                  }
4658  
4659                  cur = bup;
4660  
4661                  while ( cur ) {
4662                          bp.unshift( cur );
4663                          cur = cur.parentNode;
4664                  }
4665  
4666                  al = ap.length;
4667                  bl = bp.length;
4668  
4669                  // Start walking down the tree looking for a discrepancy
4670                  for ( var i = 0; i < al && i < bl; i++ ) {
4671                          if ( ap[i] !== bp[i] ) {
4672                                  return siblingCheck( ap[i], bp[i] );
4673                          }
4674                  }
4675  
4676                  // We ended someplace up the tree so do a sibling check
4677                  return i === al ?
4678                          siblingCheck( a, bp[i], -1 ) :
4679                          siblingCheck( ap[i], b, 1 );
4680          };
4681  
4682          siblingCheck = function( a, b, ret ) {
4683                  if ( a === b ) {
4684                          return ret;
4685                  }
4686  
4687                  var cur = a.nextSibling;
4688  
4689                  while ( cur ) {
4690                          if ( cur === b ) {
4691                                  return -1;
4692                          }
4693  
4694                          cur = cur.nextSibling;
4695                  }
4696  
4697                  return 1;
4698          };
4699  }
4700  
4701  // Utility function for retreiving the text value of an array of DOM nodes
4702  Sizzle.getText = function( elems ) {
4703          var ret = "", elem;
4704  
4705          for ( var i = 0; elems[i]; i++ ) {
4706                  elem = elems[i];
4707  
4708                  // Get the text from text nodes and CDATA nodes
4709                  if ( elem.nodeType === 3 || elem.nodeType === 4 ) {
4710                          ret += elem.nodeValue;
4711  
4712                  // Traverse everything else, except comment nodes
4713                  } else if ( elem.nodeType !== 8 ) {
4714                          ret += Sizzle.getText( elem.childNodes );
4715                  }
4716          }
4717  
4718          return ret;
4719  };
4720  
4721  // Check to see if the browser returns elements by name when
4722  // querying by getElementById (and provide a workaround)
4723  (function(){
4724          // We're going to inject a fake input element with a specified name
4725          var form = document.createElement("div"),
4726                  id = "script" + (new Date()).getTime(),
4727                  root = document.documentElement;
4728  
4729          form.innerHTML = "<a name='" + id + "'/>";
4730  
4731          // Inject it into the root element, check its status, and remove it quickly
4732          root.insertBefore( form, root.firstChild );
4733  
4734          // The workaround has to do additional checks after a getElementById
4735          // Which slows things down for other browsers (hence the branching)
4736          if ( document.getElementById( id ) ) {
4737                  Expr.find.ID = function( match, context, isXML ) {
4738                          if ( typeof context.getElementById !== "undefined" && !isXML ) {
4739                                  var m = context.getElementById(match[1]);
4740  
4741                                  return m ?
4742                                          m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ?
4743                                                  [m] :
4744                                                  undefined :
4745                                          [];
4746                          }
4747                  };
4748  
4749                  Expr.filter.ID = function( elem, match ) {
4750                          var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
4751  
4752                          return elem.nodeType === 1 && node && node.nodeValue === match;
4753                  };
4754          }
4755  
4756          root.removeChild( form );
4757  
4758          // release memory in IE
4759          root = form = null;
4760  })();
4761  
4762  (function(){
4763          // Check to see if the browser returns only elements
4764          // when doing getElementsByTagName("*")
4765  
4766          // Create a fake element
4767          var div = document.createElement("div");
4768          div.appendChild( document.createComment("") );
4769  
4770          // Make sure no comments are found
4771          if ( div.getElementsByTagName("*").length > 0 ) {
4772                  Expr.find.TAG = function( match, context ) {
4773                          var results = context.getElementsByTagName( match[1] );
4774  
4775                          // Filter out possible comments
4776                          if ( match[1] === "*" ) {
4777                                  var tmp = [];
4778  
4779                                  for ( var i = 0; results[i]; i++ ) {
4780                                          if ( results[i].nodeType === 1 ) {
4781                                                  tmp.push( results[i] );
4782                                          }
4783                                  }
4784  
4785                                  results = tmp;
4786                          }
4787  
4788                          return results;
4789                  };
4790          }
4791  
4792          // Check to see if an attribute returns normalized href attributes
4793          div.innerHTML = "<a href='#'></a>";
4794  
4795          if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
4796                          div.firstChild.getAttribute("href") !== "#" ) {
4797  
4798                  Expr.attrHandle.href = function( elem ) {
4799                          return elem.getAttribute( "href", 2 );
4800                  };
4801          }
4802  
4803          // release memory in IE
4804          div = null;
4805  })();
4806  
4807  if ( document.querySelectorAll ) {
4808          (function(){
4809                  var oldSizzle = Sizzle,
4810                          div = document.createElement("div"),
4811                          id = "__sizzle__";
4812  
4813                  div.innerHTML = "<p class='TEST'></p>";
4814  
4815                  // Safari can't handle uppercase or unicode characters when
4816                  // in quirks mode.
4817                  if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
4818                          return;
4819                  }
4820         
4821                  Sizzle = function( query, context, extra, seed ) {
4822                          context = context || document;
4823  
4824                          // Only use querySelectorAll on non-XML documents
4825                          // (ID selectors don't work in non-HTML documents)
4826                          if ( !seed && !Sizzle.isXML(context) ) {
4827                                  // See if we find a selector to speed up
4828                                  var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query );
4829                                 
4830                                  if ( match && (context.nodeType === 1 || context.nodeType === 9) ) {
4831                                          // Speed-up: Sizzle("TAG")
4832                                          if ( match[1] ) {
4833                                                  return makeArray( context.getElementsByTagName( query ), extra );
4834                                         
4835                                          // Speed-up: Sizzle(".CLASS")
4836                                          } else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) {
4837                                                  return makeArray( context.getElementsByClassName( match[2] ), extra );
4838                                          }
4839                                  }
4840                                 
4841                                  if ( context.nodeType === 9 ) {
4842                                          // Speed-up: Sizzle("body")
4843                                          // The body element only exists once, optimize finding it
4844                                          if ( query === "body" && context.body ) {
4845                                                  return makeArray( [ context.body ], extra );
4846                                                 
4847                                          // Speed-up: Sizzle("#ID")
4848                                          } else if ( match && match[3] ) {
4849                                                  var elem = context.getElementById( match[3] );
4850  
4851                                                  // Check parentNode to catch when Blackberry 4.6 returns
4852                                                  // nodes that are no longer in the document #6963
4853                                                  if ( elem && elem.parentNode ) {
4854                                                          // Handle the case where IE and Opera return items
4855                                                          // by name instead of ID
4856                                                          if ( elem.id === match[3] ) {
4857                                                                  return makeArray( [ elem ], extra );
4858                                                          }
4859                                                         
4860                                                  } else {
4861                                                          return makeArray( [], extra );
4862                                                  }
4863                                          }
4864                                         
4865                                          try {
4866                                                  return makeArray( context.querySelectorAll(query), extra );
4867                                          } catch(qsaError) {}
4868  
4869                                  // qSA works strangely on Element-rooted queries
4870                                  // We can work around this by specifying an extra ID on the root
4871                                  // and working up from there (Thanks to Andrew Dupont for the technique)
4872                                  // IE 8 doesn't work on object elements
4873                                  } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
4874                                          var oldContext = context,
4875                                                  old = context.getAttribute( "id" ),
4876                                                  nid = old || id,
4877                                                  hasParent = context.parentNode,
4878                                                  relativeHierarchySelector = /^\s*[+~]/.test( query );
4879  
4880                                          if ( !old ) {
4881                                                  context.setAttribute( "id", nid );
4882                                          } else {
4883                                                  nid = nid.replace( /'/g, "\\$&" );
4884                                          }
4885                                          if ( relativeHierarchySelector && hasParent ) {
4886                                                  context = context.parentNode;
4887                                          }
4888  
4889                                          try {
4890                                                  if ( !relativeHierarchySelector || hasParent ) {
4891                                                          return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra );
4892                                                  }
4893  
4894                                          } catch(pseudoError) {
4895                                          } finally {
4896                                                  if ( !old ) {
4897                                                          oldContext.removeAttribute( "id" );
4898                                                  }
4899                                          }
4900                                  }
4901                          }
4902                 
4903                          return oldSizzle(query, context, extra, seed);
4904                  };
4905  
4906                  for ( var prop in oldSizzle ) {
4907                          Sizzle[ prop ] = oldSizzle[ prop ];
4908                  }
4909  
4910                  // release memory in IE
4911                  div = null;
4912          })();
4913  }
4914  
4915  (function(){
4916          var html = document.documentElement,
4917                  matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector;
4918  
4919          if ( matches ) {
4920                  // Check to see if it's possible to do matchesSelector
4921                  // on a disconnected node (IE 9 fails this)
4922                  var disconnectedMatch = !matches.call( document.createElement( "div" ), "div" ),
4923                          pseudoWorks = false;
4924  
4925                  try {
4926                          // This should fail with an exception
4927                          // Gecko does not error, returns false instead
4928                          matches.call( document.documentElement, "[test!='']:sizzle" );
4929         
4930                  } catch( pseudoError ) {
4931                          pseudoWorks = true;
4932                  }
4933  
4934                  Sizzle.matchesSelector = function( node, expr ) {
4935                          // Make sure that attribute selectors are quoted
4936                          expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']");
4937  
4938                          if ( !Sizzle.isXML( node ) ) {
4939                                  try { 
4940                                          if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) {
4941                                                  var ret = matches.call( node, expr );
4942  
4943                                                  // IE 9's matchesSelector returns false on disconnected nodes
4944                                                  if ( ret || !disconnectedMatch ||
4945                                                                  // As well, disconnected nodes are said to be in a document
4946                                                                  // fragment in IE 9, so check for that
4947                                                                  node.document && node.document.nodeType !== 11 ) {
4948                                                          return ret;
4949                                                  }
4950                                          }
4951                                  } catch(e) {}
4952                          }
4953  
4954                          return Sizzle(expr, null, null, [node]).length > 0;
4955                  };
4956          }
4957  })();
4958  
4959  (function(){
4960          var div = document.createElement("div");
4961  
4962          div.innerHTML = "<div class='test e'></div><div class='test'></div>";
4963  
4964          // Opera can't find a second classname (in 9.6)
4965          // Also, make sure that getElementsByClassName actually exists
4966          if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) {
4967                  return;
4968          }
4969  
4970          // Safari caches class attributes, doesn't catch changes (in 3.2)
4971          div.lastChild.className = "e";
4972  
4973          if ( div.getElementsByClassName("e").length === 1 ) {
4974                  return;
4975          }
4976         
4977          Expr.order.splice(1, 0, "CLASS");
4978          Expr.find.CLASS = function( match, context, isXML ) {
4979                  if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
4980                          return context.getElementsByClassName(match[1]);
4981                  }
4982          };
4983  
4984          // release memory in IE
4985          div = null;
4986  })();
4987  
4988  function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
4989          for ( var i = 0, l = checkSet.length; i < l; i++ ) {
4990                  var elem = checkSet[i];
4991  
4992                  if ( elem ) {
4993                          var match = false;
4994  
4995                          elem = elem[dir];
4996  
4997                          while ( elem ) {
4998                                  if ( elem.sizcache === doneName ) {
4999                                          match = checkSet[elem.sizset];
5000                                          break;
5001                                  }
5002  
5003                                  if ( elem.nodeType === 1 && !isXML ){
5004                                          elem.sizcache = doneName;
5005                                          elem.sizset = i;
5006                                  }
5007  
5008                                  if ( elem.nodeName.toLowerCase() === cur ) {
5009                                          match = elem;
5010                                          break;
5011                                  }
5012  
5013                                  elem = elem[dir];
5014                          }
5015  
5016                          checkSet[i] = match;
5017                  }
5018          }
5019  }
5020  
5021  function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
5022          for ( var i = 0, l = checkSet.length; i < l; i++ ) {
5023                  var elem = checkSet[i];
5024  
5025                  if ( elem ) {
5026                          var match = false;
5027                         
5028                          elem = elem[dir];
5029  
5030                          while ( elem ) {
5031                                  if ( elem.sizcache === doneName ) {
5032                                          match = checkSet[elem.sizset];
5033                                          break;
5034                                  }
5035  
5036                                  if ( elem.nodeType === 1 ) {
5037                                          if ( !isXML ) {
5038                                                  elem.sizcache = doneName;
5039                                                  elem.sizset = i;
5040                                          }
5041  
5042                                          if ( typeof cur !== "string" ) {
5043                                                  if ( elem === cur ) {
5044                                                          match = true;
5045                                                          break;
5046                                                  }
5047  
5048                                          } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
5049                                                  match = elem;
5050                                                  break;
5051                                          }
5052                                  }
5053  
5054                                  elem = elem[dir];
5055                          }
5056  
5057                          checkSet[i] = match;
5058                  }
5059          }
5060  }
5061  
5062  if ( document.documentElement.contains ) {
5063          Sizzle.contains = function( a, b ) {
5064                  return a !== b && (a.contains ? a.contains(b) : true);
5065          };
5066  
5067  } else if ( document.documentElement.compareDocumentPosition ) {
5068          Sizzle.contains = function( a, b ) {
5069                  return !!(a.compareDocumentPosition(b) & 16);
5070          };
5071  
5072  } else {
5073          Sizzle.contains = function() {
5074                  return false;
5075          };
5076  }
5077  
5078  Sizzle.isXML = function( elem ) {
5079          // documentElement is verified for cases where it doesn't yet exist
5080          // (such as loading iframes in IE - #4833)
5081          var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
5082  
5083          return documentElement ? documentElement.nodeName !== "HTML" : false;
5084  };
5085  
5086  var posProcess = function( selector, context ) {
5087          var match,
5088                  tmpSet = [],
5089                  later = "",
5090                  root = context.nodeType ? [context] : context;
5091  
5092          // Position selectors must be done after the filter
5093          // And so must :not(positional) so we move all PSEUDOs to the end
5094          while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
5095                  later += match[0];
5096                  selector = selector.replace( Expr.match.PSEUDO, "" );
5097          }
5098  
5099          selector = Expr.relative[selector] ? selector + "*" : selector;
5100  
5101          for ( var i = 0, l = root.length; i < l; i++ ) {
5102                  Sizzle( selector, root[i], tmpSet );
5103          }
5104  
5105          return Sizzle.filter( later, tmpSet );
5106  };
5107  
5108  // EXPOSE
5109  jQuery.find = Sizzle;
5110  jQuery.expr = Sizzle.selectors;
5111  jQuery.expr[":"] = jQuery.expr.filters;
5112  jQuery.unique = Sizzle.uniqueSort;
5113  jQuery.text = Sizzle.getText;
5114  jQuery.isXMLDoc = Sizzle.isXML;
5115  jQuery.contains = Sizzle.contains;
5116  
5117  
5118  })();
5119  
5120  
5121  var runtil = /Until$/,
5122          rparentsprev = /^(?:parents|prevUntil|prevAll)/,
5123          // Note: This RegExp should be improved, or likely pulled from Sizzle
5124          rmultiselector = /,/,
5125          isSimple = /^.[^:#\[\.,]*$/,
5126          slice = Array.prototype.slice,
5127          POS = jQuery.expr.match.POS,
5128          // methods guaranteed to produce a unique set when starting from a unique set
5129          guaranteedUnique = {
5130                  children: true,
5131                  contents: true,
5132                  next: true,
5133                  prev: true
5134          };
5135  
5136  jQuery.fn.extend({
5137          find: function( selector ) {
5138                  var self = this,
5139                          i, l;
5140  
5141                  if ( typeof selector !== "string" ) {
5142                          return jQuery( selector ).filter(function() {
5143                                  for ( i = 0, l = self.length; i < l; i++ ) {
5144                                          if ( jQuery.contains( self[ i ], this ) ) {
5145                                                  return true;
5146                                          }
5147                                  }
5148                          });
5149                  }
5150  
5151                  var ret = this.pushStack( "", "find", selector ),
5152                          length, n, r;
5153  
5154                  for ( i = 0, l = this.length; i < l; i++ ) {
5155                          length = ret.length;
5156                          jQuery.find( selector, this[i], ret );
5157  
5158                          if ( i > 0 ) {
5159                                  // Make sure that the results are unique
5160                                  for ( n = length; n < ret.length; n++ ) {
5161                                          for ( r = 0; r < length; r++ ) {
5162                                                  if ( ret[r] === ret[n] ) {
5163                                                          ret.splice(n--, 1);
5164                                                          break;
5165                                                  }
5166                                          }
5167                                  }
5168                          }
5169                  }
5170  
5171                  return ret;
5172          },
5173  
5174          has: function( target ) {
5175                  var targets = jQuery( target );
5176                  return this.filter(function() {
5177                          for ( var i = 0, l = targets.length; i < l; i++ ) {
5178                                  if ( jQuery.contains( this, targets[i] ) ) {
5179                                          return true;
5180                                  }
5181                          }
5182                  });
5183          },
5184  
5185          not: function( selector ) {
5186                  return this.pushStack( winnow(this, selector, false), "not", selector);
5187          },
5188  
5189          filter: function( selector ) {
5190                  return this.pushStack( winnow(this, selector, true), "filter", selector );
5191          },
5192  
5193          is: function( selector ) {
5194                  return !!selector && ( typeof selector === "string" ?
5195                          jQuery.filter( selector, this ).length > 0 :
5196                          this.filter( selector ).length > 0 );
5197          },
5198  
5199          closest: function( selectors, context ) {
5200                  var ret = [], i, l, cur = this[0];
5201                 
5202                  // Array
5203                  if ( jQuery.isArray( selectors ) ) {
5204                          var match, selector,
5205                                  matches = {},
5206                                  level = 1;
5207  
5208                          if ( cur && selectors.length ) {
5209                                  for ( i = 0, l = selectors.length; i < l; i++ ) {
5210                                          selector = selectors[i];
5211  
5212                                          if ( !matches[ selector ] ) {
5213                                                  matches[ selector ] = POS.test( selector ) ?
5214                                                          jQuery( selector, context || this.context ) :
5215                                                          selector;
5216                                          }
5217                                  }
5218  
5219                                  while ( cur && cur.ownerDocument && cur !== context ) {
5220                                          for ( selector in matches ) {
5221                                                  match = matches[ selector ];
5222  
5223                                                  if ( match.jquery ? match.index( cur ) > -1 : jQuery( cur ).is( match ) ) {
5224                                                          ret.push({ selector: selector, elem: cur, level: level });
5225                                                  }
5226                                          }
5227  
5228                                          cur = cur.parentNode;
5229                                          level++;
5230                                  }
5231                          }
5232  
5233                          return ret;
5234                  }
5235  
5236                  // String
5237                  var pos = POS.test( selectors ) || typeof selectors !== "string" ?
5238                                  jQuery( selectors, context || this.context ) :
5239                                  0;
5240  
5241                  for ( i = 0, l = this.length; i < l; i++ ) {
5242                          cur = this[i];
5243  
5244                          while ( cur ) {
5245                                  if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {
5246                                          ret.push( cur );
5247                                          break;
5248  
5249                                  } else {
5250                                          cur = cur.parentNode;
5251                                          if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) {
5252                                                  break;
5253                                          }
5254                                  }
5255                          }
5256                  }
5257  
5258                  ret = ret.length > 1 ? jQuery.unique( ret ) : ret;
5259  
5260                  return this.pushStack( ret, "closest", selectors );
5261          },
5262  
5263          // Determine the position of an element within
5264          // the matched set of elements
5265          index: function( elem ) {
5266                  if ( !elem || typeof elem === "string" ) {
5267                          return jQuery.inArray( this[0],
5268                                  // If it receives a string, the selector is used
5269                                  // If it receives nothing, the siblings are used
5270                                  elem ? jQuery( elem ) : this.parent().children() );
5271                  }
5272                  // Locate the position of the desired element
5273                  return jQuery.inArray(
5274                          // If it receives a jQuery object, the first element is used
5275                          elem.jquery ? elem[0] : elem, this );
5276          },
5277  
5278          add: function( selector, context ) {
5279                  var set = typeof selector === "string" ?
5280                                  jQuery( selector, context ) :
5281                                  jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ),
5282                          all = jQuery.merge( this.get(), set );
5283  
5284                  return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?
5285                          all :
5286                          jQuery.unique( all ) );
5287          },
5288  
5289          andSelf: function() {
5290                  return this.add( this.prevObject );
5291          }
5292  });
5293  
5294  // A painfully simple check to see if an element is disconnected
5295  // from a document (should be improved, where feasible).
5296  function isDisconnected( node ) {
5297          return !node || !node.parentNode || node.parentNode.nodeType === 11;
5298  }
5299  
5300  jQuery.each({
5301          parent: function( elem ) {
5302                  var parent = elem.parentNode;
5303                  return parent && parent.nodeType !== 11 ? parent : null;
5304          },
5305          parents: function( elem ) {
5306                  return jQuery.dir( elem, "parentNode" );
5307          },
5308          parentsUntil: function( elem, i, until ) {
5309                  return jQuery.dir( elem, "parentNode", until );
5310          },
5311          next: function( elem ) {
5312                  return jQuery.nth( elem, 2, "nextSibling" );
5313          },
5314          prev: function( elem ) {
5315                  return jQuery.nth( elem, 2, "previousSibling" );
5316          },
5317          nextAll: function( elem ) {
5318                  return jQuery.dir( elem, "nextSibling" );
5319          },
5320          prevAll: function( elem ) {
5321                  return jQuery.dir( elem, "previousSibling" );
5322          },
5323          nextUntil: function( elem, i, until ) {
5324                  return jQuery.dir( elem, "nextSibling", until );
5325          },
5326          prevUntil: function( elem, i, until ) {
5327                  return jQuery.dir( elem, "previousSibling", until );
5328          },
5329          siblings: function( elem ) {
5330                  return jQuery.sibling( elem.parentNode.firstChild, elem );
5331          },
5332          children: function( elem ) {
5333                  return jQuery.sibling( elem.firstChild );
5334          },
5335          contents: function( elem ) {
5336                  return jQuery.nodeName( elem, "iframe" ) ?
5337                          elem.contentDocument || elem.contentWindow.document :
5338                          jQuery.makeArray( elem.childNodes );
5339          }
5340  }, function( name, fn ) {
5341          jQuery.fn[ name ] = function( until, selector ) {
5342                  var ret = jQuery.map( this, fn, until ),
5343                          // The variable 'args' was introduced in
5344                          // https://github.com/jquery/jquery/commit/52a0238
5345                          // to work around a bug in Chrome 10 (Dev) and should be removed when the bug is fixed.
5346                          // http://code.google.com/p/v8/issues/detail?id=1050
5347                          args = slice.call(arguments);
5348  
5349                  if ( !runtil.test( name ) ) {
5350                          selector = until;
5351                  }
5352  
5353                  if ( selector && typeof selector === "string" ) {
5354                          ret = jQuery.filter( selector, ret );
5355                  }
5356  
5357                  ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret;
5358  
5359                  if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) {
5360                          ret = ret.reverse();
5361                  }
5362  
5363                  return this.pushStack( ret, name, args.join(",") );
5364          };
5365  });
5366  
5367  jQuery.extend({
5368          filter: function( expr, elems, not ) {
5369                  if ( not ) {
5370                          expr = ":not(" + expr + ")";
5371                  }
5372  
5373                  return elems.length === 1 ?
5374                          jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :
5375                          jQuery.find.matches(expr, elems);
5376          },
5377  
5378          dir: function( elem, dir, until ) {
5379                  var matched = [],
5380                          cur = elem[ dir ];
5381  
5382                  while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
5383                          if ( cur.nodeType === 1 ) {
5384                                  matched.push( cur );
5385                          }
5386                          cur = cur[dir];
5387                  }
5388                  return matched;
5389          },
5390  
5391          nth: function( cur, result, dir, elem ) {
5392                  result = result || 1;
5393                  var num = 0;
5394  
5395                  for ( ; cur; cur = cur[dir] ) {
5396                          if ( cur.nodeType === 1 && ++num === result ) {
5397                                  break;
5398                          }
5399                  }
5400  
5401                  return cur;
5402          },
5403  
5404          sibling: function( n, elem ) {
5405                  var r = [];
5406  
5407                  for ( ; n; n = n.nextSibling ) {
5408                          if ( n.nodeType === 1 && n !== elem ) {
5409                                  r.push( n );
5410                          }
5411                  }
5412  
5413                  return r;
5414          }
5415  });
5416  
5417  // Implement the identical functionality for filter and not
5418  function winnow( elements, qualifier, keep ) {
5419  
5420          // Can't pass null or undefined to indexOf in Firefox 4
5421          // Set to 0 to skip string check
5422          qualifier = qualifier || 0;
5423  
5424          if ( jQuery.isFunction( qualifier ) ) {
5425                  return jQuery.grep(elements, function( elem, i ) {
5426                          var retVal = !!qualifier.call( elem, i, elem );
5427                          return retVal === keep;
5428                  });
5429  
5430          } else if ( qualifier.nodeType ) {
5431                  return jQuery.grep(elements, function( elem, i ) {
5432                          return (elem === qualifier) === keep;
5433                  });
5434  
5435          } else if ( typeof qualifier === "string" ) {
5436                  var filtered = jQuery.grep(elements, function( elem ) {
5437                          return elem.nodeType === 1;
5438                  });
5439  
5440                  if ( isSimple.test( qualifier ) ) {
5441                          return jQuery.filter(qualifier, filtered, !keep);
5442                  } else {
5443                          qualifier = jQuery.filter( qualifier, filtered );
5444                  }
5445          }
5446  
5447          return jQuery.grep(elements, function( elem, i ) {
5448                  return (jQuery.inArray( elem, qualifier ) >= 0) === keep;
5449          });
5450  }
5451  
5452  
5453  
5454  
5455  var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g,
5456          rleadingWhitespace = /^\s+/,
5457          rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,
5458          rtagName = /<([\w:]+)/,
5459          rtbody = /<tbody/i,
5460          rhtml = /<|&#?\w+;/,
5461          rnocache = /<(?:script|object|embed|option|style)/i,
5462          // checked="checked" or checked
5463          rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
5464          rscriptType = /\/(java|ecma)script/i,
5465          rcleanScript = /^\s*<!(?:\[CDATA\[|\-\-)/,
5466          wrapMap = {
5467                  option: [ 1, "<select multiple='multiple'>", "</select>" ],
5468                  legend: [ 1, "<fieldset>", "</fieldset>" ],
5469                  thead: [ 1, "<table>", "</table>" ],
5470                  tr: [ 2, "<table><tbody>", "</tbody></table>" ],
5471                  td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
5472                  col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
5473                  area: [ 1, "<map>", "</map>" ],
5474                  _default: [ 0, "", "" ]
5475          };
5476  
5477  wrapMap.optgroup = wrapMap.option;
5478  wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
5479  wrapMap.th = wrapMap.td;
5480  
5481  // IE can't serialize <link> and <script> tags normally
5482  if ( !jQuery.support.htmlSerialize ) {
5483          wrapMap._default = [ 1, "div<div>", "</div>" ];
5484  }
5485  
5486  jQuery.fn.extend({
5487          text: function( text ) {
5488                  if ( jQuery.isFunction(text) ) {
5489                          return this.each(function(i) {
5490                                  var self = jQuery( this );
5491  
5492                                  self.text( text.call(this, i, self.text()) );
5493                          });
5494                  }
5495  
5496                  if ( typeof text !== "object" && text !== undefined ) {
5497                          return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
5498                  }
5499  
5500                  return jQuery.text( this );
5501          },
5502  
5503          wrapAll: function( html ) {
5504                  if ( jQuery.isFunction( html ) ) {
5505                          return this.each(function(i) {
5506                                  jQuery(this).wrapAll( html.call(this, i) );
5507                          });
5508                  }
5509  
5510                  if ( this[0] ) {
5511                          // The elements to wrap the target around
5512                          var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
5513  
5514                          if ( this[0].parentNode ) {
5515                                  wrap.insertBefore( this[0] );
5516                          }
5517  
5518                          wrap.map(function() {
5519                                  var elem = this;
5520  
5521                                  while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
5522                                          elem = elem.firstChild;
5523                                  }
5524  
5525                                  return elem;
5526                          }).append( this );
5527                  }
5528  
5529                  return this;
5530          },
5531  
5532          wrapInner: function( html ) {
5533                  if ( jQuery.isFunction( html ) ) {
5534                          return this.each(function(i) {
5535                                  jQuery(this).wrapInner( html.call(this, i) );
5536                          });
5537                  }
5538  
5539                  return this.each(function() {
5540                          var self = jQuery( this ),
5541                                  contents = self.contents();
5542  
5543                          if ( contents.length ) {
5544                                  contents.wrapAll( html );
5545  
5546                          } else {
5547                                  self.append( html );
5548                          }
5549                  });
5550          },
5551  
5552          wrap: function( html ) {
5553                  return this.each(function() {
5554                          jQuery( this ).wrapAll( html );
5555                  });
5556          },
5557  
5558          unwrap: function() {
5559                  return this.parent().each(function() {
5560                          if ( !jQuery.nodeName( this, "body" ) ) {
5561                                  jQuery( this ).replaceWith( this.childNodes );
5562                          }
5563                  }).end();
5564          },
5565  
5566          append: function() {
5567                  return this.domManip(arguments, true, function( elem ) {
5568                          if ( this.nodeType === 1 ) {
5569                                  this.appendChild( elem );
5570                          }
5571                  });
5572          },
5573  
5574          prepend: function() {
5575                  return this.domManip(arguments, true, function( elem ) {
5576                          if ( this.nodeType === 1 ) {
5577                                  this.insertBefore( elem, this.firstChild );
5578                          }
5579                  });
5580          },
5581  
5582          before: function() {
5583                  if ( this[0] && this[0].parentNode ) {
5584                          return this.domManip(arguments, false, function( elem ) {
5585                                  this.parentNode.insertBefore( elem, this );
5586                          });
5587                  } else if ( arguments.length ) {
5588                          var set = jQuery(arguments[0]);
5589                          set.push.apply( set, this.toArray() );
5590                          return this.pushStack( set, "before", arguments );
5591                  }
5592          },
5593  
5594          after: function() {
5595                  if ( this[0] && this[0].parentNode ) {
5596                          return this.domManip(arguments, false, function( elem ) {
5597                                  this.parentNode.insertBefore( elem, this.nextSibling );
5598                          });
5599                  } else if ( arguments.length ) {
5600                          var set = this.pushStack( this, "after", arguments );
5601                          set.push.apply( set, jQuery(arguments[0]).toArray() );
5602                          return set;
5603                  }
5604          },
5605  
5606          // keepData is for internal use only--do not document
5607          remove: function( selector, keepData ) {
5608                  for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
5609                          if ( !selector || jQuery.filter( selector, [ elem ] ).length ) {
5610                                  if ( !keepData && elem.nodeType === 1 ) {
5611                                          jQuery.cleanData( elem.getElementsByTagName("*") );
5612                                          jQuery.cleanData( [ elem ] );
5613                                  }
5614  
5615                                  if ( elem.parentNode ) {
5616                                          elem.parentNode.removeChild( elem );
5617                                  }
5618                          }
5619                  }
5620  
5621                  return this;
5622          },
5623  
5624          empty: function() {
5625                  for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
5626                          // Remove element nodes and prevent memory leaks
5627                          if ( elem.nodeType === 1 ) {
5628                                  jQuery.cleanData( elem.getElementsByTagName("*") );
5629                          }
5630  
5631                          // Remove any remaining nodes
5632                          while ( elem.firstChild ) {
5633                                  elem.removeChild( elem.firstChild );
5634                          }
5635                  }
5636  
5637                  return this;
5638          },
5639  
5640          clone: function( dataAndEvents, deepDataAndEvents ) {
5641                  dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
5642                  deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
5643  
5644                  return this.map( function () {
5645                          return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
5646                  });
5647          },
5648  
5649          html: function( value ) {
5650                  if ( value === undefined ) {
5651                          return this[0] && this[0].nodeType === 1 ?
5652                                  this[0].innerHTML.replace(rinlinejQuery, "") :
5653                                  null;
5654  
5655                  // See if we can take a shortcut and just use innerHTML
5656                  } else if ( typeof value === "string" && !rnocache.test( value ) &&
5657                          (jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) &&
5658                          !wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) {
5659  
5660                          value = value.replace(rxhtmlTag, "<$1></$2>");
5661  
5662                          try {
5663                                  for ( var i = 0, l = this.length; i < l; i++ ) {
5664                                          // Remove element nodes and prevent memory leaks
5665                                          if ( this[i].nodeType === 1 ) {
5666                                                  jQuery.cleanData( this[i].getElementsByTagName("*") );
5667                                                  this[i].innerHTML = value;
5668                                          }
5669                                  }
5670  
5671                          // If using innerHTML throws an exception, use the fallback method
5672                          } catch(e) {
5673                                  this.empty().append( value );
5674                          }
5675  
5676                  } else if ( jQuery.isFunction( value ) ) {
5677                          this.each(function(i){
5678                                  var self = jQuery( this );
5679  
5680                                  self.html( value.call(this, i, self.html()) );
5681                          });
5682  
5683                  } else {
5684                          this.empty().append( value );
5685                  }
5686  
5687                  return this;
5688          },
5689  
5690          replaceWith: function( value ) {
5691                  if ( this[0] && this[0].parentNode ) {
5692                          // Make sure that the elements are removed from the DOM before they are inserted
5693                          // this can help fix replacing a parent with child elements
5694                          if ( jQuery.isFunction( value ) ) {
5695                                  return this.each(function(i) {
5696                                          var self = jQuery(this), old = self.html();
5697                                          self.replaceWith( value.call( this, i, old ) );
5698                                  });
5699                          }
5700  
5701                          if ( typeof value !== "string" ) {
5702                                  value = jQuery( value ).detach();
5703                          }
5704  
5705                          return this.each(function() {
5706                                  var next = this.nextSibling,
5707                                          parent = this.parentNode;
5708  
5709                                  jQuery( this ).remove();
5710  
5711                                  if ( next ) {
5712                                          jQuery(next).before( value );
5713                                  } else {
5714                                          jQuery(parent).append( value );
5715                                  }
5716                          });
5717                  } else {
5718                          return this.length ?
5719                                  this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value ) :
5720                                  this;
5721                  }
5722          },
5723  
5724          detach: function( selector ) {
5725                  return this.remove( selector, true );
5726          },
5727  
5728          domManip: function( args, table, callback ) {
5729                  var results, first, fragment, parent,
5730                          value = args[0],
5731                          scripts = [];
5732  
5733                  // We can't cloneNode fragments that contain checked, in WebKit
5734                  if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) {
5735                          return this.each(function() {
5736                                  jQuery(this).domManip( args, table, callback, true );
5737                          });
5738                  }
5739  
5740                  if ( jQuery.isFunction(value) ) {
5741                          return this.each(function(i) {
5742                                  var self = jQuery(this);
5743                                  args[0] = value.call(this, i, table ? self.html() : undefined);
5744                                  self.domManip( args, table, callback );
5745                          });
5746                  }
5747  
5748                  if ( this[0] ) {
5749                          parent = value && value.parentNode;
5750  
5751                          // If we're in a fragment, just use that instead of building a new one
5752                          if ( jQuery.support.parentNode && parent && parent.nodeType === 11 && parent.childNodes.length === this.length ) {
5753                                  results = { fragment: parent };
5754  
5755                          } else {
5756                                  results = jQuery.buildFragment( args, this, scripts );
5757                          }
5758  
5759                          fragment = results.fragment;
5760  
5761                          if ( fragment.childNodes.length === 1 ) {
5762                                  first = fragment = fragment.firstChild;
5763                          } else {
5764                                  first = fragment.firstChild;
5765                          }
5766  
5767                          if ( first ) {
5768                                  table = table && jQuery.nodeName( first, "tr" );
5769  
5770                                  for ( var i = 0, l = this.length, lastIndex = l - 1; i < l; i++ ) {
5771                                          callback.call(
5772                                                  table ?
5773                                                          root(this[i], first) :
5774                                                          this[i],
5775                                                  // Make sure that we do not leak memory by inadvertently discarding
5776                                                  // the original fragment (which might have attached data) instead of
5777                                                  // using it; in addition, use the original fragment object for the last
5778                                                  // item instead of first because it can end up being emptied incorrectly
5779                                                  // in certain situations (Bug #8070).
5780                                                  // Fragments from the fragment cache must always be cloned and never used
5781                                                  // in place.
5782                                                  results.cacheable || (l > 1 && i < lastIndex) ?
5783                                                          jQuery.clone( fragment, true, true ) :
5784                                                          fragment
5785                                          );
5786                                  }
5787                          }
5788  
5789                          if ( scripts.length ) {
5790                                  jQuery.each( scripts, evalScript );
5791                          }
5792                  }
5793  
5794                  return this;
5795          }
5796  });
5797  
5798  function root( elem, cur ) {
5799          return jQuery.nodeName(elem, "table") ?
5800                  (elem.getElementsByTagName("tbody")[0] ||
5801                  elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
5802                  elem;
5803  }
5804  
5805  function cloneCopyEvent( src, dest ) {
5806  
5807          if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {
5808                  return;
5809          }
5810  
5811          var internalKey = jQuery.expando,
5812                  oldData = jQuery.data( src ),
5813                  curData = jQuery.data( dest, oldData );
5814  
5815          // Switch to use the internal data object, if it exists, for the next
5816          // stage of data copying
5817          if ( (oldData = oldData[ internalKey ]) ) {
5818                  var events = oldData.events;
5819                                  curData = curData[ internalKey ] = jQuery.extend({}, oldData);
5820  
5821                  if ( events ) {
5822                          delete curData.handle;
5823                          curData.events = {};
5824  
5825                          for ( var type in events ) {
5826                                  for ( var i = 0, l = events[ type ].length; i < l; i++ ) {
5827                                          jQuery.event.add( dest, type + ( events[ type ][ i ].namespace ? "." : "" ) + events[ type ][ i ].namespace, events[ type ][ i ], events[ type ][ i ].data );
5828                                  }
5829                          }
5830                  }
5831          }
5832  }
5833  
5834  function cloneFixAttributes( src, dest ) {
5835          var nodeName;
5836  
5837          // We do not need to do anything for non-Elements
5838          if ( dest.nodeType !== 1 ) {
5839                  return;
5840          }
5841  
5842          // clearAttributes removes the attributes, which we don't want,
5843          // but also removes the attachEvent events, which we *do* want
5844          if ( dest.clearAttributes ) {
5845                  dest.clearAttributes();
5846          }
5847  
5848          // mergeAttributes, in contrast, only merges back on the
5849          // original attributes, not the events
5850          if ( dest.mergeAttributes ) {
5851                  dest.mergeAttributes( src );
5852          }
5853  
5854          nodeName = dest.nodeName.toLowerCase();
5855  
5856          // IE6-8 fail to clone children inside object elements that use
5857          // the proprietary classid attribute value (rather than the type
5858          // attribute) to identify the type of content to display
5859          if ( nodeName === "object" ) {
5860                  dest.outerHTML = src.outerHTML;
5861  
5862          } else if ( nodeName === "input" && (src.type === "checkbox" || src.type === "radio") ) {
5863                  // IE6-8 fails to persist the checked state of a cloned checkbox
5864                  // or radio button. Worse, IE6-7 fail to give the cloned element
5865                  // a checked appearance if the defaultChecked value isn't also set
5866                  if ( src.checked ) {
5867                          dest.defaultChecked = dest.checked = src.checked;
5868                  }
5869  
5870                  // IE6-7 get confused and end up setting the value of a cloned
5871                  // checkbox/radio button to an empty string instead of "on"
5872                  if ( dest.value !== src.value ) {
5873                          dest.value = src.value;
5874                  }
5875  
5876          // IE6-8 fails to return the selected option to the default selected
5877          // state when cloning options
5878          } else if ( nodeName === "option" ) {
5879                  dest.selected = src.defaultSelected;
5880  
5881          // IE6-8 fails to set the defaultValue to the correct value when
5882          // cloning other types of input fields
5883          } else if ( nodeName === "input" || nodeName === "textarea" ) {
5884                  dest.defaultValue = src.defaultValue;
5885          }
5886  
5887          // Event data gets referenced instead of copied if the expando
5888          // gets copied too
5889          dest.removeAttribute( jQuery.expando );
5890  }
5891  
5892  jQuery.buildFragment = function( args, nodes, scripts ) {
5893          var fragment, cacheable, cacheresults,
5894                  doc = (nodes && nodes[0] ? nodes[0].ownerDocument || nodes[0] : document);
5895  
5896          // Only cache "small" (1/2 KB) HTML strings that are associated with the main document
5897          // Cloning options loses the selected state, so don't cache them
5898          // IE 6 doesn't like it when you put <object> or <embed> elements in a fragment
5899          // Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache
5900          if ( args.length === 1 && typeof args[0] === "string" && args[0].length < 512 && doc === document &&
5901                  args[0].charAt(0) === "<" && !rnocache.test( args[0] ) && (jQuery.support.checkClone || !rchecked.test( args[0] )) ) {
5902  
5903                  cacheable = true;
5904  
5905                  cacheresults = jQuery.fragments[ args[0] ];
5906                  if ( cacheresults && cacheresults !== 1 ) {
5907                          fragment = cacheresults;
5908                  }
5909          }
5910  
5911          if ( !fragment ) {
5912                  fragment = doc.createDocumentFragment();
5913                  jQuery.clean( args, doc, fragment, scripts );
5914          }
5915  
5916          if ( cacheable ) {
5917                  jQuery.fragments[ args[0] ] = cacheresults ? fragment : 1;
5918          }
5919  
5920          return { fragment: fragment, cacheable: cacheable };
5921  };
5922  
5923  jQuery.fragments = {};
5924  
5925  jQuery.each({
5926          appendTo: "append",
5927          prependTo: "prepend",
5928          insertBefore: "before",
5929          insertAfter: "after",
5930          replaceAll: "replaceWith"
5931  }, function( name, original ) {
5932          jQuery.fn[ name ] = function( selector ) {
5933                  var ret = [],
5934                          insert = jQuery( selector ),
5935                          parent = this.length === 1 && this[0].parentNode;
5936  
5937                  if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) {
5938                          insert[ original ]( this[0] );
5939                          return this;
5940  
5941                  } else {
5942                          for ( var i = 0, l = insert.length; i < l; i++ ) {
5943                                  var elems = (i > 0 ? this.clone(true) : this).get();
5944                                  jQuery( insert[i] )[ original ]( elems );
5945                                  ret = ret.concat( elems );
5946                          }
5947  
5948                          return this.pushStack( ret, name, insert.selector );
5949                  }
5950          };
5951  });
5952  
5953  function getAll( elem ) {
5954          if ( "getElementsByTagName" in elem ) {
5955                  return elem.getElementsByTagName( "*" );
5956  
5957          } else if ( "querySelectorAll" in elem ) {
5958                  return elem.querySelectorAll( "*" );
5959  
5960          } else {
5961                  return [];
5962          }
5963  }
5964  
5965  // Used in clean, fixes the defaultChecked property
5966  function fixDefaultChecked( elem ) {
5967          if ( elem.type === "checkbox" || elem.type === "radio" ) {
5968                  elem.defaultChecked = elem.checked;
5969          }
5970  }
5971  // Finds all inputs and passes them to fixDefaultChecked
5972  function findInputs( elem ) {
5973          if ( jQuery.nodeName( elem, "input" ) ) {
5974                  fixDefaultChecked( elem );
5975          } else if ( elem.getElementsByTagName ) {
5976                  jQuery.grep( elem.getElementsByTagName("input"), fixDefaultChecked );
5977          }
5978  }
5979  
5980  jQuery.extend({
5981          clone: function( elem, dataAndEvents, deepDataAndEvents ) {
5982                  var clone = elem.cloneNode(true),
5983                                  srcElements,
5984                                  destElements,
5985                                  i;
5986  
5987                  if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) &&
5988                                  (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {
5989                          // IE copies events bound via attachEvent when using cloneNode.
5990                          // Calling detachEvent on the clone will also remove the events
5991                          // from the original. In order to get around this, we use some
5992                          // proprietary methods to clear the events. Thanks to MooTools
5993                          // guys for this hotness.
5994  
5995                          cloneFixAttributes( elem, clone );
5996  
5997                          // Using Sizzle here is crazy slow, so we use getElementsByTagName
5998                          // instead
5999                          srcElements = getAll( elem );
6000                          destElements = getAll( clone );
6001  
6002                          // Weird iteration because IE will replace the length property
6003                          // with an element if you are cloning the body and one of the
6004                          // elements on the page has a name or id of "length"
6005                          for ( i = 0; srcElements[i]; ++i ) {
6006                                  cloneFixAttributes( srcElements[i], destElements[i] );
6007                          }
6008                  }
6009  
6010                  // Copy the events from the original to the clone
6011                  if ( dataAndEvents ) {
6012                          cloneCopyEvent( elem, clone );
6013  
6014                          if ( deepDataAndEvents ) {
6015                                  srcElements = getAll( elem );
6016                                  destElements = getAll( clone );
6017  
6018                                  for ( i = 0; srcElements[i]; ++i ) {
6019                                          cloneCopyEvent( srcElements[i], destElements[i] );
6020                                  }
6021                          }
6022                  }
6023  
6024                  // Return the cloned set
6025                  return clone;
6026          },
6027  
6028          clean: function( elems, context, fragment, scripts ) {
6029                  var checkScriptType;
6030  
6031                  context = context || document;
6032  
6033                  // !context.createElement fails in IE with an error but returns typeof 'object'
6034                  if ( typeof context.createElement === "undefined" ) {
6035                          context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
6036                  }
6037  
6038                  var ret = [], j;
6039  
6040                  for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
6041                          if ( typeof elem === "number" ) {
6042                                  elem += "";
6043                          }
6044  
6045                          if ( !elem ) {
6046                                  continue;
6047                          }
6048  
6049                          // Convert html string into DOM nodes
6050                          if ( typeof elem === "string" ) {
6051                                  if ( !rhtml.test( elem ) ) {
6052                                          elem = context.createTextNode( elem );
6053                                  } else {
6054                                          // Fix "XHTML"-style tags in all browsers
6055                                          elem = elem.replace(rxhtmlTag, "<$1></$2>");
6056  
6057                                          // Trim whitespace, otherwise indexOf won't work as expected
6058                                          var tag = (rtagName.exec( elem ) || ["", ""])[1].toLowerCase(),
6059                                                  wrap = wrapMap[ tag ] || wrapMap._default,
6060                                                  depth = wrap[0],
6061                                                  div = context.createElement("div");
6062  
6063                                          // Go to html and back, then peel off extra wrappers
6064                                          div.innerHTML = wrap[1] + elem + wrap[2];
6065  
6066                                          // Move to the right depth
6067                                          while ( depth-- ) {
6068                                                  div = div.lastChild;
6069                                          }
6070  
6071                                          // Remove IE's autoinserted <tbody> from table fragments
6072                                          if ( !jQuery.support.tbody ) {
6073  
6074                                                  // String was a <table>, *may* have spurious <tbody>
6075                                                  var hasBody = rtbody.test(elem),
6076                                                          tbody = tag === "table" && !hasBody ?
6077                                                                  div.firstChild && div.firstChild.childNodes :
6078  
6079                                                                  // String was a bare <thead> or <tfoot>
6080                                                                  wrap[1] === "<table>" && !hasBody ?
6081                                                                          div.childNodes :
6082                                                                          [];
6083  
6084                                                  for ( j = tbody.length - 1; j >= 0 ; --j ) {
6085                                                          if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) {
6086                                                                  tbody[ j ].parentNode.removeChild( tbody[ j ] );
6087                                                          }
6088                                                  }
6089                                          }
6090  
6091                                          // IE completely kills leading whitespace when innerHTML is used
6092                                          if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
6093                                                  div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );
6094                                          }
6095  
6096                                          elem = div.childNodes;
6097                                  }
6098                          }
6099  
6100                          // Resets defaultChecked for any radios and checkboxes
6101                          // about to be appended to the DOM in IE 6/7 (#8060)
6102                          var len;
6103                          if ( !jQuery.support.appendChecked ) {
6104                                  if ( elem[0] && typeof (len = elem.length) === "number" ) {
6105                                          for ( j = 0; j < len; j++ ) {
6106                                                  findInputs( elem[j] );
6107                                          }
6108                                  } else {
6109                                          findInputs( elem );
6110                                  }
6111                          }
6112  
6113                          if ( elem.nodeType ) {
6114                                  ret.push( elem );
6115                          } else {
6116                                  ret = jQuery.merge( ret, elem );
6117                          }
6118                  }
6119  
6120                  if ( fragment ) {
6121                          checkScriptType = function( elem ) {
6122                                  return !elem.type || rscriptType.test( elem.type );
6123                          };
6124                          for ( i = 0; ret[i]; i++ ) {
6125                                  if ( scripts && jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
6126                                          scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
6127  
6128                                  } else {
6129                                          if ( ret[i].nodeType === 1 ) {
6130                                                  var jsTags = jQuery.grep( ret[i].getElementsByTagName( "script" ), checkScriptType );
6131  
6132                                                  ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) );
6133                                          }
6134                                          fragment.appendChild( ret[i] );
6135                                  }
6136                          }
6137                  }
6138  
6139                  return ret;
6140          },
6141  
6142          cleanData: function( elems ) {
6143                  var data, id, cache = jQuery.cache, internalKey = jQuery.expando, special = jQuery.event.special,
6144                          deleteExpando = jQuery.support.deleteExpando;
6145  
6146                  for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
6147                          if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
6148                                  continue;
6149                          }
6150  
6151                          id = elem[ jQuery.expando ];
6152  
6153                          if ( id ) {
6154                                  data = cache[ id ] && cache[ id ][ internalKey ];
6155  
6156                                  if ( data && data.events ) {
6157                                          for ( var type in data.events ) {
6158                                                  if ( special[ type ] ) {
6159                                                          jQuery.event.remove( elem, type );
6160  
6161                                                  // This is a shortcut to avoid jQuery.event.remove's overhead
6162                                                  } else {
6163                                                          jQuery.removeEvent( elem, type, data.handle );
6164                                                  }
6165                                          }
6166  
6167                                          // Null the DOM reference to avoid IE6/7/8 leak (#7054)
6168                                          if ( data.handle ) {
6169                                                  data.handle.elem = null;
6170                                          }
6171                                  }
6172  
6173                                  if ( deleteExpando ) {
6174                                          delete elem[ jQuery.expando ];
6175  
6176                                  } else if ( elem.removeAttribute ) {
6177                                          elem.removeAttribute( jQuery.expando );
6178                                  }
6179  
6180                                  delete cache[ id ];
6181                          }
6182                  }
6183          }
6184  });
6185  
6186  function evalScript( i, elem ) {
6187          if ( elem.src ) {
6188                  jQuery.ajax({
6189                          url: elem.src,
6190                          async: false,
6191                          dataType: "script"
6192                  });
6193          } else {
6194                  jQuery.globalEval( ( elem.text || elem.textContent || elem.innerHTML || "" ).replace( rcleanScript, "/*$0*/" ) );
6195          }
6196  
6197          if ( elem.parentNode ) {
6198                  elem.parentNode.removeChild( elem );
6199          }
6200  }
6201  
6202  
6203  
6204  
6205  var ralpha = /alpha\([^)]*\)/i,
6206          ropacity = /opacity=([^)]*)/,
6207          rdashAlpha = /-([a-z])/ig,
6208          // fixed for IE9, see #8346
6209          rupper = /([A-Z]|^ms)/g,
6210          rnumpx = /^-?\d+(?:px)?$/i,
6211          rnum = /^-?\d/,
6212          rrelNum = /^[+\-]=/,
6213          rrelNumFilter = /[^+\-\.\de]+/g,
6214  
6215          cssShow = { position: "absolute", visibility: "hidden", display: "block" },
6216          cssWidth = [ "Left", "Right" ],
6217          cssHeight = [ "Top", "Bottom" ],
6218          curCSS,
6219  
6220          getComputedStyle,
6221          currentStyle,
6222  
6223          fcamelCase = function( all, letter ) {
6224                  return letter.toUpperCase();
6225          };
6226  
6227  jQuery.fn.css = function( name, value ) {
6228          // Setting 'undefined' is a no-op
6229          if ( arguments.length === 2 && value === undefined ) {
6230                  return this;
6231          }
6232  
6233          return jQuery.access( this, name, value, true, function( elem, name, value ) {
6234                  return value !== undefined ?
6235                          jQuery.style( elem, name, value ) :
6236                          jQuery.css( elem, name );
6237          });
6238  };
6239  
6240  jQuery.extend({
6241          // Add in style property hooks for overriding the default
6242          // behavior of getting and setting a style property
6243          cssHooks: {
6244                  opacity: {
6245                          get: function( elem, computed ) {
6246                                  if ( computed ) {
6247                                          // We should always get a number back from opacity
6248                                          var ret = curCSS( elem, "opacity", "opacity" );
6249                                          return ret === "" ? "1" : ret;
6250  
6251                                  } else {
6252                                          return elem.style.opacity;
6253                                  }
6254                          }
6255                  }
6256          },
6257  
6258          // Exclude the following css properties to add px
6259          cssNumber: {
6260                  "zIndex": true,
6261                  "fontWeight": true,
6262                  "opacity": true,
6263                  "zoom": true,
6264                  "lineHeight": true,
6265                  "widows": true,
6266                  "orphans": true
6267          },
6268  
6269          // Add in properties whose names you wish to fix before
6270          // setting or getting the value
6271          cssProps: {
6272                  // normalize float css property
6273                  "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat"
6274          },
6275  
6276          // Get and set the style property on a DOM Node
6277          style: function( elem, name, value, extra ) {
6278                  // Don't set styles on text and comment nodes
6279                  if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
6280                          return;
6281                  }
6282  
6283                  // Make sure that we're working with the right name
6284                  var ret, type, origName = jQuery.camelCase( name ),
6285                          style = elem.style, hooks = jQuery.cssHooks[ origName ];
6286  
6287                  name = jQuery.cssProps[ origName ] || origName;
6288  
6289                  // Check if we're setting a value
6290                  if ( value !== undefined ) {
6291                          type = typeof value;
6292  
6293                          // Make sure that NaN and null values aren't set. See: #7116
6294                          if ( type === "number" && isNaN( value ) || value == null ) {
6295                                  return;
6296                          }
6297  
6298                          // convert relative number strings (+= or -=) to relative numbers. #7345
6299                          if ( type === "string" && rrelNum.test( value ) ) {
6300                                  value = +value.replace( rrelNumFilter, "" ) + parseFloat( jQuery.css( elem, name ) );
6301                          }
6302  
6303                          // If a number was passed in, add 'px' to the (except for certain CSS properties)
6304                          if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
6305                                  value += "px";
6306                          }
6307  
6308                          // If a hook was provided, use that value, otherwise just set the specified value
6309                          if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value )) !== undefined ) {
6310                                  // Wrapped to prevent IE from throwing errors when 'invalid' values are provided
6311                                  // Fixes bug #5509
6312                                  try {
6313                                          style[ name ] = value;
6314                                  } catch(e) {}
6315                          }
6316  
6317                  } else {
6318                          // If a hook was provided get the non-computed value from there
6319                          if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
6320                                  return ret;
6321                          }
6322  
6323                          // Otherwise just get the value from the style object
6324                          return style[ name ];
6325                  }
6326          },
6327  
6328          css: function( elem, name, extra ) {
6329                  var ret, hooks;
6330  
6331                  // Make sure that we're working with the right name
6332                  name = jQuery.camelCase( name );
6333                  hooks = jQuery.cssHooks[ name ];
6334                  name = jQuery.cssProps[ name ] || name;
6335  
6336                  // cssFloat needs a special treatment
6337                  if ( name === "cssFloat" ) {
6338                          name = "float";
6339                  }
6340  
6341                  // If a hook was provided get the computed value from there
6342                  if ( hooks && "get" in hooks && (ret = hooks.get( elem, true, extra )) !== undefined ) {
6343                          return ret;
6344  
6345                  // Otherwise, if a way to get the computed value exists, use that
6346                  } else if ( curCSS ) {
6347                          return curCSS( elem, name );
6348                  }
6349          },
6350  
6351          // A method for quickly swapping in/out CSS properties to get correct calculations
6352          swap: function( elem, options, callback ) {
6353                  var old = {};
6354  
6355                  // Remember the old values, and insert the new ones
6356                  for ( var name in options ) {
6357                          old[ name ] = elem.style[ name ];
6358                          elem.style[ name ] = options[ name ];
6359                  }
6360  
6361                  callback.call( elem );
6362  
6363                  // Revert the old values
6364                  for ( name in options ) {
6365                          elem.style[ name ] = old[ name ];
6366                  }
6367          },
6368  
6369          camelCase: function( string ) {
6370                  return string.replace( rdashAlpha, fcamelCase );
6371          }
6372  });
6373  
6374  // DEPRECATED, Use jQuery.css() instead
6375  jQuery.curCSS = jQuery.css;
6376  
6377  jQuery.each(["height", "width"], function( i, name ) {
6378          jQuery.cssHooks[ name ] = {
6379                  get: function( elem, computed, extra ) {
6380                          var val;
6381  
6382                          if ( computed ) {
6383                                  if ( elem.offsetWidth !== 0 ) {
6384                                          val = getWH( elem, name, extra );
6385  
6386                                  } else {
6387                                          jQuery.swap( elem, cssShow, function() {
6388                                                  val = getWH( elem, name, extra );
6389                                          });
6390                                  }
6391  
6392                                  if ( val <= 0 ) {
6393                                          val = curCSS( elem, name, name );
6394  
6395                                          if ( val === "0px" && currentStyle ) {
6396                                                  val = currentStyle( elem, name, name );
6397                                          }
6398  
6399                                          if ( val != null ) {
6400                                                  // Should return "auto" instead of 0, use 0 for
6401                                                  // temporary backwards-compat
6402                                                  return val === "" || val === "auto" ? "0px" : val;
6403                                          }
6404                                  }
6405  
6406                                  if ( val < 0 || val == null ) {
6407                                          val = elem.style[ name ];
6408  
6409                                          // Should return "auto" instead of 0, use 0 for
6410                                          // temporary backwards-compat
6411                                          return val === "" || val === "auto" ? "0px" : val;
6412                                  }
6413  
6414                                  return typeof val === "string" ? val : val + "px";
6415                          }
6416                  },
6417  
6418                  set: function( elem, value ) {
6419                          if ( rnumpx.test( value ) ) {
6420                                  // ignore negative width and height values #1599
6421                                  value = parseFloat(value);
6422  
6423                                  if ( value >= 0 ) {
6424                                          return value + "px";
6425                                  }
6426  
6427                          } else {
6428                                  return value;
6429                          }
6430                  }
6431          };
6432  });
6433  
6434  if ( !jQuery.support.opacity ) {
6435          jQuery.cssHooks.opacity = {
6436                  get: function( elem, computed ) {
6437                          // IE uses filters for opacity
6438                          return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ?
6439                                  ( parseFloat( RegExp.$1 ) / 100 ) + "" :
6440                                  computed ? "1" : "";
6441                  },
6442  
6443                  set: function( elem, value ) {
6444                          var style = elem.style,
6445                                  currentStyle = elem.currentStyle;
6446  
6447                          // IE has trouble with opacity if it does not have layout
6448                          // Force it by setting the zoom level
6449                          style.zoom = 1;
6450  
6451                          // Set the alpha filter to set the opacity
6452                          var opacity = jQuery.isNaN( value ) ?
6453                                  "" :
6454                                  "alpha(opacity=" + value * 100 + ")",
6455                                  filter = currentStyle && currentStyle.filter || style.filter || "";
6456  
6457                          style.filter = ralpha.test( filter ) ?
6458                                  filter.replace( ralpha, opacity ) :
6459                                  filter + " " + opacity;
6460                  }
6461          };
6462  }
6463  
6464  jQuery(function() {
6465          // This hook cannot be added until DOM ready because the support test
6466          // for it is not run until after DOM ready
6467          if ( !jQuery.support.reliableMarginRight ) {
6468                  jQuery.cssHooks.marginRight = {
6469                          get: function( elem, computed ) {
6470                                  // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
6471                                  // Work around by temporarily setting element display to inline-block
6472                                  var ret;
6473                                  jQuery.swap( elem, { "display": "inline-block" }, function() {
6474                                          if ( computed ) {
6475                                                  ret = curCSS( elem, "margin-right", "marginRight" );
6476                                          } else {
6477                                                  ret = elem.style.marginRight;
6478                                          }
6479                                  });
6480                                  return ret;
6481                          }
6482                  };
6483          }
6484  });
6485  
6486  if ( document.defaultView && document.defaultView.getComputedStyle ) {
6487          getComputedStyle = function( elem, name ) {
6488                  var ret, defaultView, computedStyle;
6489  
6490                  name = name.replace( rupper, "-$1" ).toLowerCase();
6491  
6492                  if ( !(defaultView = elem.ownerDocument.defaultView) ) {
6493                          return undefined;
6494                  }
6495  
6496                  if ( (computedStyle = defaultView.getComputedStyle( elem, null )) ) {
6497                          ret = computedStyle.getPropertyValue( name );
6498                          if ( ret === "" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) {
6499                                  ret = jQuery.style( elem, name );
6500                          }
6501                  }
6502  
6503                  return ret;
6504          };
6505  }
6506  
6507  if ( document.documentElement.currentStyle ) {
6508          currentStyle = function( elem, name ) {
6509                  var left,
6510                          ret = elem.currentStyle && elem.currentStyle[ name ],
6511                          rsLeft = elem.runtimeStyle && elem.runtimeStyle[ name ],
6512                          style = elem.style;
6513  
6514                  // From the awesome hack by Dean Edwards
6515                  // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
6516  
6517                  // If we're not dealing with a regular pixel number
6518                  // but a number that has a weird ending, we need to convert it to pixels
6519                  if ( !rnumpx.test( ret ) && rnum.test( ret ) ) {
6520                          // Remember the original values
6521                          left = style.left;
6522  
6523                          // Put in the new values to get a computed value out
6524                          if ( rsLeft ) {
6525                                  elem.runtimeStyle.left = elem.currentStyle.left;
6526                          }
6527                          style.left = name === "fontSize" ? "1em" : (ret || 0);
6528                          ret = style.pixelLeft + "px";
6529  
6530                          // Revert the changed values
6531                          style.left = left;
6532                          if ( rsLeft ) {
6533                                  elem.runtimeStyle.left = rsLeft;
6534                          }
6535                  }
6536  
6537                  return ret === "" ? "auto" : ret;
6538          };
6539  }
6540  
6541  curCSS = getComputedStyle || currentStyle;
6542  
6543  function getWH( elem, name, extra ) {
6544          var which = name === "width" ? cssWidth : cssHeight,
6545                  val = name === "width" ? elem.offsetWidth : elem.offsetHeight;
6546  
6547          if ( extra === "border" ) {
6548                  return val;
6549          }
6550  
6551          jQuery.each( which, function() {
6552                  if ( !extra ) {
6553                          val -= parseFloat(jQuery.css( elem, "padding" + this )) || 0;
6554                  }
6555  
6556                  if ( extra === "margin" ) {
6557                          val += parseFloat(jQuery.css( elem, "margin" + this )) || 0;
6558  
6559                  } else {
6560                          val -= parseFloat(jQuery.css( elem, "border" + this + "Width" )) || 0;
6561                  }
6562          });
6563  
6564          return val;
6565  }
6566  
6567  if ( jQuery.expr && jQuery.expr.filters ) {
6568          jQuery.expr.filters.hidden = function( elem ) {
6569                  var width = elem.offsetWidth,
6570                          height = elem.offsetHeight;
6571  
6572                  return (width === 0 && height === 0) || (!jQuery.support.reliableHiddenOffsets && (elem.style.display || jQuery.css( elem, "display" )) === "none");
6573          };
6574  
6575          jQuery.expr.filters.visible = function( elem ) {
6576                  return !jQuery.expr.filters.hidden( elem );
6577          };
6578  }
6579  
6580  
6581  
6582  
6583  var r20 = /%20/g,
6584          rbracket = /\[\]$/,
6585          rCRLF = /\r?\n/g,
6586          rhash = /#.*$/,
6587          rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL
6588          rinput = /^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,
6589          // #7653, #8125, #8152: local protocol detection
6590          rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|widget):$/,
6591          rnoContent = /^(?:GET|HEAD)$/,
6592          rprotocol = /^\/\//,
6593          rquery = /\?/,
6594          rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
6595          rselectTextarea = /^(?:select|textarea)/i,
6596          rspacesAjax = /\s+/,
6597          rts = /([?&])_=[^&]*/,
6598          rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,
6599  
6600          // Keep a copy of the old load method
6601          _load = jQuery.fn.load,
6602  
6603          /* Prefilters
6604           * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
6605           * 2) These are called:
6606           *    - BEFORE asking for a transport
6607           *    - AFTER param serialization (s.data is a string if s.processData is true)
6608           * 3) key is the dataType
6609           * 4) the catchall symbol "*" can be used
6610           * 5) execution will start with transport dataType and THEN continue down to "*" if needed
6611           */
6612          prefilters = {},
6613  
6614          /* Transports bindings
6615           * 1) key is the dataType
6616           * 2) the catchall symbol "*" can be used
6617           * 3) selection will start with transport dataType and THEN go to "*" if needed
6618           */
6619          transports = {},
6620  
6621          // Document location
6622          ajaxLocation,
6623  
6624          // Document location segments
6625          ajaxLocParts;
6626  
6627  // #8138, IE may throw an exception when accessing
6628  // a field from window.location if document.domain has been set
6629  try {
6630          ajaxLocation = location.href;
6631  } catch( e ) {
6632          // Use the href attribute of an A element
6633          // since IE will modify it given document.location
6634          ajaxLocation = document.createElement( "a" );
6635          ajaxLocation.href = "";
6636          ajaxLocation = ajaxLocation.href;
6637  }
6638  
6639  // Segment location into parts
6640  ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
6641  
6642  // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
6643  function addToPrefiltersOrTransports( structure ) {
6644  
6645          // dataTypeExpression is optional and defaults to "*"
6646          return function( dataTypeExpression, func ) {
6647  
6648                  if ( typeof dataTypeExpression !== "string" ) {
6649                          func = dataTypeExpression;
6650                          dataTypeExpression = "*";
6651                  }
6652  
6653                  if ( jQuery.isFunction( func ) ) {
6654                          var dataTypes = dataTypeExpression.toLowerCase().split( rspacesAjax ),
6655                                  i = 0,
6656                                  length = dataTypes.length,
6657                                  dataType,
6658                                  list,
6659                                  placeBefore;
6660  
6661                          // For each dataType in the dataTypeExpression
6662                          for(; i < length; i++ ) {
6663                                  dataType = dataTypes[ i ];
6664                                  // We control if we're asked to add before
6665                                  // any existing element
6666                                  placeBefore = /^\+/.test( dataType );
6667                                  if ( placeBefore ) {
6668                                          dataType = dataType.substr( 1 ) || "*";
6669                                  }
6670                                  list = structure[ dataType ] = structure[ dataType ] || [];
6671                                  // then we add to the structure accordingly
6672                                  list[ placeBefore ? "unshift" : "push" ]( func );
6673                          }
6674                  }
6675          };
6676  }
6677  
6678  // Base inspection function for prefilters and transports
6679  function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR,
6680                  dataType /* internal */, inspected /* internal */ ) {
6681  
6682          dataType = dataType || options.dataTypes[ 0 ];
6683          inspected = inspected || {};
6684  
6685          inspected[ dataType ] = true;
6686  
6687          var list = structure[ dataType ],
6688                  i = 0,
6689                  length = list ? list.length : 0,
6690                  executeOnly = ( structure === prefilters ),
6691                  selection;
6692  
6693          for(; i < length && ( executeOnly || !selection ); i++ ) {
6694                  selection = list[ i ]( options, originalOptions, jqXHR );
6695                  // If we got redirected to another dataType
6696                  // we try there if executing only and not done already
6697                  if ( typeof selection === "string" ) {
6698                          if ( !executeOnly || inspected[ selection ] ) {
6699                                  selection = undefined;
6700                          } else {
6701                                  options.dataTypes.unshift( selection );
6702                                  selection = inspectPrefiltersOrTransports(
6703                                                  structure, options, originalOptions, jqXHR, selection, inspected );
6704                          }
6705                  }
6706          }
6707          // If we're only executing or nothing was selected
6708          // we try the catchall dataType if not done already
6709          if ( ( executeOnly || !selection ) && !inspected[ "*" ] ) {
6710                  selection = inspectPrefiltersOrTransports(
6711                                  structure, options, originalOptions, jqXHR, "*", inspected );
6712          }
6713          // unnecessary when only executing (prefilters)
6714          // but it'll be ignored by the caller in that case
6715          return selection;
6716  }
6717  
6718  jQuery.fn.extend({
6719          load: function( url, params, callback ) {
6720                  if ( typeof url !== "string" && _load ) {
6721                          return _load.apply( this, arguments );
6722  
6723                  // Don't do a request if no elements are being requested
6724                  } else if ( !this.length ) {
6725                          return this;
6726                  }
6727  
6728                  var off = url.indexOf( " " );
6729                  if ( off >= 0 ) {
6730                          var selector = url.slice( off, url.length );
6731                          url = url.slice( 0, off );
6732                  }
6733  
6734                  // Default to a GET request
6735                  var type = "GET";
6736  
6737                  // If the second parameter was provided
6738                  if ( params ) {
6739                          // If it's a function
6740                          if ( jQuery.isFunction( params ) ) {
6741                                  // We assume that it's the callback
6742                                  callback = params;
6743                                  params = undefined;
6744  
6745                          // Otherwise, build a param string
6746                          } else if ( typeof params === "object" ) {
6747                                  params = jQuery.param( params, jQuery.ajaxSettings.traditional );
6748                                  type = "POST";
6749                          }
6750                  }
6751  
6752                  var self = this;
6753  
6754                  // Request the remote document
6755                  jQuery.ajax({
6756                          url: url,
6757                          type: type,
6758                          dataType: "html",
6759                          data: params,
6760                          // Complete callback (responseText is used internally)
6761                          complete: function( jqXHR, status, responseText ) {
6762                                  // Store the response as specified by the jqXHR object
6763                                  responseText = jqXHR.responseText;
6764                                  // If successful, inject the HTML into all the matched elements
6765                                  if ( jqXHR.isResolved() ) {
6766                                          // #4825: Get the actual response in case
6767                                          // a dataFilter is present in ajaxSettings
6768                                          jqXHR.done(function( r ) {
6769                                                  responseText = r;
6770                                          });
6771                                          // See if a selector was specified
6772                                          self.html( selector ?
6773                                                  // Create a dummy div to hold the results
6774                                                  jQuery("<div>")
6775                                                          // inject the contents of the document in, removing the scripts
6776                                                          // to avoid any 'Permission Denied' errors in IE
6777                                                          .append(responseText.replace(rscript, ""))
6778  
6779                                                          // Locate the specified elements
6780                                                          .find(selector) :
6781  
6782                                                  // If not, just inject the full result
6783                                                  responseText );
6784                                  }
6785  
6786                                  if ( callback ) {
6787                                          self.each( callback, [ responseText, status, jqXHR ] );
6788                                  }
6789                          }
6790                  });
6791  
6792                  return this;
6793          },
6794  
6795          serialize: function() {
6796                  return jQuery.param( this.serializeArray() );
6797          },
6798  
6799          serializeArray: function() {
6800                  return this.map(function(){
6801                          return this.elements ? jQuery.makeArray( this.elements ) : this;
6802                  })
6803                  .filter(function(){
6804                          return this.name && !this.disabled &&
6805                                  ( this.checked || rselectTextarea.test( this.nodeName ) ||
6806                                          rinput.test( this.type ) );
6807                  })
6808                  .map(function( i, elem ){
6809                          var val = jQuery( this ).val();
6810  
6811                          return val == null ?
6812                                  null :
6813                                  jQuery.isArray( val ) ?
6814                                          jQuery.map( val, function( val, i ){
6815                                                  return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
6816                                          }) :
6817                                          { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
6818                  }).get();
6819          }
6820  });
6821  
6822  // Attach a bunch of functions for handling common AJAX events
6823  jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split( " " ), function( i, o ){
6824          jQuery.fn[ o ] = function( f ){
6825                  return this.bind( o, f );
6826          };
6827  });
6828  
6829  jQuery.each( [ "get", "post" ], function( i, method ) {
6830          jQuery[ method ] = function( url, data, callback, type ) {
6831                  // shift arguments if data argument was omitted
6832                  if ( jQuery.isFunction( data ) ) {
6833                          type = type || callback;
6834                          callback = data;
6835                          data = undefined;
6836                  }
6837  
6838                  return jQuery.ajax({
6839                          type: method,
6840                          url: url,
6841                          data: data,
6842                          success: callback,
6843                          dataType: type
6844                  });
6845          };
6846  });
6847  
6848  jQuery.extend({
6849  
6850          getScript: function( url, callback ) {
6851                  return jQuery.get( url, undefined, callback, "script" );
6852          },
6853  
6854          getJSON: function( url, data, callback ) {
6855                  return jQuery.get( url, data, callback, "json" );
6856          },
6857  
6858          // Creates a full fledged settings object into target
6859          // with both ajaxSettings and settings fields.
6860          // If target is omitted, writes into ajaxSettings.
6861          ajaxSetup: function ( target, settings ) {
6862                  if ( !settings ) {
6863                          // Only one parameter, we extend ajaxSettings
6864                          settings = target;
6865                          target = jQuery.extend( true, jQuery.ajaxSettings, settings );
6866                  } else {
6867                          // target was provided, we extend into it
6868                          jQuery.extend( true, target, jQuery.ajaxSettings, settings );
6869                  }
6870                  // Flatten fields we don't want deep extended
6871                  for( var field in { context: 1, url: 1 } ) {
6872                          if ( field in settings ) {
6873                                  target[ field ] = settings[ field ];
6874                          } else if( field in jQuery.ajaxSettings ) {
6875                                  target[ field ] = jQuery.ajaxSettings[ field ];
6876                          }
6877                  }
6878                  return target;
6879          },
6880  
6881          ajaxSettings: {
6882                  url: ajaxLocation,
6883                  isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
6884                  global: true,
6885                  type: "GET",
6886                  contentType: "application/x-www-form-urlencoded",
6887                  processData: true,
6888                  async: true,
6889                  /*
6890                  timeout: 0,
6891                  data: null,
6892                  dataType: null,
6893                  username: null,
6894                  password: null,
6895                  cache: null,
6896                  traditional: false,
6897                  headers: {},
6898                  */
6899  
6900                  accepts: {
6901                          xml: "application/xml, text/xml",
6902                          html: "text/html",
6903                          text: "text/plain",
6904                          json: "application/json, text/javascript",
6905                          "*": "*/*"
6906                  },
6907  
6908                  contents: {
6909                          xml: /xml/,
6910                          html: /html/,
6911                          json: /json/
6912                  },
6913  
6914                  responseFields: {
6915                          xml: "responseXML",
6916                          text: "responseText"
6917                  },
6918  
6919                  // List of data converters
6920                  // 1) key format is "source_type destination_type" (a single space in-between)
6921                  // 2) the catchall symbol "*" can be used for source_type
6922                  converters: {
6923  
6924                          // Convert anything to text
6925                          "* text": window.String,
6926  
6927                          // Text to html (true = no transformation)
6928                          "text html": true,
6929  
6930                          // Evaluate text as a json expression
6931                          "text json": jQuery.parseJSON,
6932  
6933                          // Parse text as xml
6934                          "text xml": jQuery.parseXML
6935                  }
6936          },
6937  
6938          ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
6939          ajaxTransport: addToPrefiltersOrTransports( transports ),
6940  
6941          // Main method
6942          ajax: function( url, options ) {
6943  
6944                  // If url is an object, simulate pre-1.5 signature
6945                  if ( typeof url === "object" ) {
6946                          options = url;
6947                          url = undefined;
6948                  }
6949  
6950                  // Force options to be an object
6951                  options = options || {};
6952  
6953                  var // Create the final options object
6954                          s = jQuery.ajaxSetup( {}, options ),
6955                          // Callbacks context
6956                          callbackContext = s.context || s,
6957                          // Context for global events
6958                          // It's the callbackContext if one was provided in the options
6959                          // and if it's a DOM node or a jQuery collection
6960                          globalEventContext = callbackContext !== s &&
6961                                  ( callbackContext.nodeType || callbackContext instanceof jQuery ) ?
6962                                                  jQuery( callbackContext ) : jQuery.event,
6963                          // Deferreds
6964                          deferred = jQuery.Deferred(),
6965                          completeDeferred = jQuery._Deferred(),
6966                          // Status-dependent callbacks
6967                          statusCode = s.statusCode || {},
6968                          // ifModified key
6969                          ifModifiedKey,
6970                          // Headers (they are sent all at once)
6971                          requestHeaders = {},
6972                          requestHeadersNames = {},
6973                          // Response headers
6974                          responseHeadersString,
6975                          responseHeaders,
6976                          // transport
6977                          transport,
6978                          // timeout handle
6979                          timeoutTimer,
6980                          // Cross-domain detection vars
6981                          parts,
6982                          // The jqXHR state
6983                          state = 0,
6984                          // To know if global events are to be dispatched
6985                          fireGlobals,
6986                          // Loop variable
6987                          i,
6988                          // Fake xhr
6989                          jqXHR = {
6990  
6991                                  readyState: 0,
6992  
6993                                  // Caches the header
6994                                  setRequestHeader: function( name, value ) {
6995                                          if ( !state ) {
6996                                                  var lname = name.toLowerCase();
6997                                                  name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
6998                                                  requestHeaders[ name ] = value;
6999                                          }
7000                                          return this;
7001                                  },
7002  
7003                                  // Raw string
7004                                  getAllResponseHeaders: function() {
7005                                          return state === 2 ? responseHeadersString : null;
7006                                  },
7007  
7008                                  // Builds headers hashtable if needed
7009                                  getResponseHeader: function( key ) {
7010                                          var match;
7011                                          if ( state === 2 ) {
7012                                                  if ( !responseHeaders ) {
7013                                                          responseHeaders = {};
7014                                                          while( ( match = rheaders.exec( responseHeadersString ) ) ) {
7015                                                                  responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
7016                                                          }
7017                                                  }
7018                                                  match = responseHeaders[ key.toLowerCase() ];
7019                                          }
7020                                          return match === undefined ? null : match;
7021                                  },
7022  
7023                                  // Overrides response content-type header
7024                                  overrideMimeType: function( type ) {
7025                                          if ( !state ) {
7026                                                  s.mimeType = type;
7027                                          }
7028                                          return this;
7029                                  },
7030  
7031                                  // Cancel the request
7032                                  abort: function( statusText ) {
7033                                          statusText = statusText || "abort";
7034                                          if ( transport ) {
7035                                                  transport.abort( statusText );
7036                                          }
7037                                          done( 0, statusText );
7038                                          return this;
7039                                  }
7040                          };
7041  
7042                  // Callback for when everything is done
7043                  // It is defined here because jslint complains if it is declared
7044                  // at the end of the function (which would be more logical and readable)
7045                  function done( status, statusText, responses, headers ) {
7046  
7047                          // Called once
7048                          if ( state === 2 ) {
7049                                  return;
7050                          }
7051  
7052                          // State is "done" now
7053                          state = 2;
7054  
7055                          // Clear timeout if it exists
7056                          if ( timeoutTimer ) {
7057                                  clearTimeout( timeoutTimer );
7058                          }
7059  
7060                          // Dereference transport for early garbage collection
7061                          // (no matter how long the jqXHR object will be used)
7062                          transport = undefined;
7063  
7064                          // Cache response headers
7065                          responseHeadersString = headers || "";
7066  
7067                          // Set readyState
7068                          jqXHR.readyState = status ? 4 : 0;
7069  
7070                          var isSuccess,
7071                                  success,
7072                                  error,
7073                                  response = responses ? ajaxHandleResponses( s, jqXHR, responses ) : undefined,
7074                                  lastModified,
7075                                  etag;
7076  
7077                          // If successful, handle type chaining
7078                          if ( status >= 200 && status < 300 || status === 304 ) {
7079  
7080                                  // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
7081                                  if ( s.ifModified ) {
7082  
7083                                          if ( ( lastModified = jqXHR.getResponseHeader( "Last-Modified" ) ) ) {
7084                                                  jQuery.lastModified[ ifModifiedKey ] = lastModified;
7085                                          }
7086                                          if ( ( etag = jqXHR.getResponseHeader( "Etag" ) ) ) {
7087                                                  jQuery.etag[ ifModifiedKey ] = etag;
7088                                          }
7089                                  }
7090  
7091                                  // If not modified
7092                                  if ( status === 304 ) {
7093  
7094                                          statusText = "notmodified";
7095                                          isSuccess = true;
7096  
7097                                  // If we have data
7098                                  } else {
7099  
7100                                          try {
7101                                                  success = ajaxConvert( s, response );
7102                                                  statusText = "success";
7103                                                  isSuccess = true;
7104                                          } catch(e) {
7105                                                  // We have a parsererror
7106                                                  statusText = "parsererror";
7107                                                  error = e;
7108                                          }
7109                                  }
7110                          } else {
7111                                  // We extract error from statusText
7112                                  // then normalize statusText and status for non-aborts
7113                                  error = statusText;
7114                                  if( !statusText || status ) {
7115                                          statusText = "error";
7116                                          if ( status < 0 ) {
7117                                                  status = 0;
7118                                          }
7119                                  }
7120                          }
7121  
7122                          // Set data for the fake xhr object
7123                          jqXHR.status = status;
7124                          jqXHR.statusText = statusText;
7125  
7126                          // Success/Error
7127                          if ( isSuccess ) {
7128                                  deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
7129                          } else {
7130                                  deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
7131                          }
7132  
7133                          // Status-dependent callbacks
7134                          jqXHR.statusCode( statusCode );
7135                          statusCode = undefined;
7136  
7137                          if ( fireGlobals ) {
7138                                  globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ),
7139                                                  [ jqXHR, s, isSuccess ? success : error ] );
7140                          }
7141  
7142                          // Complete
7143                          completeDeferred.resolveWith( callbackContext, [ jqXHR, statusText ] );
7144  
7145                          if ( fireGlobals ) {
7146                                  globalEventContext.trigger( "ajaxComplete", [ jqXHR, s] );
7147                                  // Handle the global AJAX counter
7148                                  if ( !( --jQuery.active ) ) {
7149                                          jQuery.event.trigger( "ajaxStop" );
7150                                  }
7151                          }
7152                  }
7153  
7154                  // Attach deferreds
7155                  deferred.promise( jqXHR );
7156                  jqXHR.success = jqXHR.done;
7157                  jqXHR.error = jqXHR.fail;
7158                  jqXHR.complete = completeDeferred.done;
7159  
7160                  // Status-dependent callbacks
7161                  jqXHR.statusCode = function( map ) {
7162                          if ( map ) {
7163                                  var tmp;
7164                                  if ( state < 2 ) {
7165                                          for( tmp in map ) {
7166                                                  statusCode[ tmp ] = [ statusCode[tmp], map[tmp] ];
7167                                          }
7168                                  } else {
7169                                          tmp = map[ jqXHR.status ];
7170                                          jqXHR.then( tmp, tmp );
7171                                  }
7172                          }
7173                          return this;
7174                  };
7175  
7176                  // Remove hash character (#7531: and string promotion)
7177                  // Add protocol if not provided (#5866: IE7 issue with protocol-less urls)
7178                  // We also use the url parameter if available
7179                  s.url = ( ( url || s.url ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
7180  
7181                  // Extract dataTypes list
7182                  s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( rspacesAjax );
7183  
7184                  // Determine if a cross-domain request is in order
7185                  if ( s.crossDomain == null ) {
7186                          parts = rurl.exec( s.url.toLowerCase() );
7187                          s.crossDomain = !!( parts &&
7188                                  ( parts[ 1 ] != ajaxLocParts[ 1 ] || parts[ 2 ] != ajaxLocParts[ 2 ] ||
7189                                          ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? 80 : 443 ) ) !=
7190                                                  ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? 80 : 443 ) ) )
7191                          );
7192                  }
7193  
7194                  // Convert data if not already a string
7195                  if ( s.data && s.processData && typeof s.data !== "string" ) {
7196                          s.data = jQuery.param( s.data, s.traditional );
7197                  }
7198  
7199                  // Apply prefilters
7200                  inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
7201  
7202                  // If request was aborted inside a prefiler, stop there
7203                  if ( state === 2 ) {
7204                          return false;
7205                  }
7206  
7207                  // We can fire global events as of now if asked to
7208                  fireGlobals = s.global;
7209  
7210                  // Uppercase the type
7211                  s.type = s.type.toUpperCase();
7212  
7213                  // Determine if request has content
7214                  s.hasContent = !rnoContent.test( s.type );
7215  
7216                  // Watch for a new set of requests
7217                  if ( fireGlobals && jQuery.active++ === 0 ) {
7218                          jQuery.event.trigger( "ajaxStart" );
7219                  }
7220  
7221                  // More options handling for requests with no content
7222                  if ( !s.hasContent ) {
7223  
7224                          // If data is available, append data to url
7225                          if ( s.data ) {
7226                                  s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data;
7227                          }
7228  
7229                          // Get ifModifiedKey before adding the anti-cache parameter
7230                          ifModifiedKey = s.url;
7231  
7232                          // Add anti-cache in url if needed
7233                          if ( s.cache === false ) {
7234  
7235                                  var ts = jQuery.now(),
7236                                          // try replacing _= if it is there
7237                                          ret = s.url.replace( rts, "$1_=" + ts );
7238  
7239                                  // if nothing was replaced, add timestamp to the end
7240                                  s.url = ret + ( (ret === s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : "" );
7241                          }
7242                  }
7243  
7244                  // Set the correct header, if data is being sent
7245                  if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
7246                          jqXHR.setRequestHeader( "Content-Type", s.contentType );
7247                  }
7248  
7249                  // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
7250                  if ( s.ifModified ) {
7251                          ifModifiedKey = ifModifiedKey || s.url;
7252                          if ( jQuery.lastModified[ ifModifiedKey ] ) {
7253                                  jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ ifModifiedKey ] );
7254                          }
7255                          if ( jQuery.etag[ ifModifiedKey ] ) {
7256                                  jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ ifModifiedKey ] );
7257                          }
7258                  }
7259  
7260                  // Set the Accepts header for the server, depending on the dataType
7261                  jqXHR.setRequestHeader(
7262                          "Accept",
7263                          s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?
7264                                  s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", */*; q=0.01" : "" ) :
7265                                  s.accepts[ "*" ]
7266                  );
7267  
7268                  // Check for headers option
7269                  for ( i in s.headers ) {
7270                          jqXHR.setRequestHeader( i, s.headers[ i ] );
7271                  }
7272  
7273                  // Allow custom headers/mimetypes and early abort
7274                  if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
7275                                  // Abort if not done already
7276                                  jqXHR.abort();
7277                                  return false;
7278  
7279                  }
7280  
7281                  // Install callbacks on deferreds
7282                  for ( i in { success: 1, error: 1, complete: 1 } ) {
7283                          jqXHR[ i ]( s[ i ] );
7284                  }
7285  
7286                  // Get transport
7287                  transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
7288  
7289                  // If no transport, we auto-abort
7290                  if ( !transport ) {
7291                          done( -1, "No Transport" );
7292                  } else {
7293                          jqXHR.readyState = 1;
7294                          // Send global event
7295                          if ( fireGlobals ) {
7296                                  globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
7297                          }
7298                          // Timeout
7299                          if ( s.async && s.timeout > 0 ) {
7300                                  timeoutTimer = setTimeout( function(){
7301                                          jqXHR.abort( "timeout" );
7302                                  }, s.timeout );
7303                          }
7304  
7305                          try {
7306                                  state = 1;
7307                                  transport.send( requestHeaders, done );
7308                          } catch (e) {
7309                                  // Propagate exception as error if not done
7310                                  if ( status < 2 ) {
7311                                          done( -1, e );
7312                                  // Simply rethrow otherwise
7313                                  } else {
7314                                          jQuery.error( e );
7315                                  }
7316                          }
7317                  }
7318  
7319                  return jqXHR;
7320          },
7321  
7322          // Serialize an array of form elements or a set of
7323          // key/values into a query string
7324          param: function( a, traditional ) {
7325                  var s = [],
7326                          add = function( key, value ) {
7327                                  // If value is a function, invoke it and return its value
7328                                  value = jQuery.isFunction( value ) ? value() : value;
7329                                  s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
7330                          };
7331  
7332                  // Set traditional to true for jQuery <= 1.3.2 behavior.
7333                  if ( traditional === undefined ) {
7334                          traditional = jQuery.ajaxSettings.traditional;
7335                  }
7336  
7337                  // If an array was passed in, assume that it is an array of form elements.
7338                  if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
7339                          // Serialize the form elements
7340                          jQuery.each( a, function() {
7341                                  add( this.name, this.value );
7342                          });
7343  
7344                  } else {
7345                          // If traditional, encode the "old" way (the way 1.3.2 or older
7346                          // did it), otherwise encode params recursively.
7347                          for ( var prefix in a ) {
7348                                  buildParams( prefix, a[ prefix ], traditional, add );
7349                          }
7350                  }
7351  
7352                  // Return the resulting serialization
7353                  return s.join( "&" ).replace( r20, "+" );
7354          }
7355  });
7356  
7357  function buildParams( prefix, obj, traditional, add ) {
7358          if ( jQuery.isArray( obj ) ) {
7359                  // Serialize array item.
7360                  jQuery.each( obj, function( i, v ) {
7361                          if ( traditional || rbracket.test( prefix ) ) {
7362                                  // Treat each array item as a scalar.
7363                                  add( prefix, v );
7364  
7365                          } else {
7366                                  // If array item is non-scalar (array or object), encode its
7367                                  // numeric index to resolve deserialization ambiguity issues.
7368                                  // Note that rack (as of 1.0.0) can't currently deserialize
7369                                  // nested arrays properly, and attempting to do so may cause
7370                                  // a server error. Possible fixes are to modify rack's
7371                                  // deserialization algorithm or to provide an option or flag
7372                                  // to force array serialization to be shallow.
7373                                  buildParams( prefix + "[" + ( typeof v === "object" || jQuery.isArray(v) ? i : "" ) + "]", v, traditional, add );
7374                          }
7375                  });
7376  
7377          } else if ( !traditional && obj != null && typeof obj === "object" ) {
7378                  // Serialize object item.
7379                  for ( var name in obj ) {
7380                          buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
7381                  }
7382  
7383          } else {
7384                  // Serialize scalar item.
7385                  add( prefix, obj );
7386          }
7387  }
7388  
7389  // This is still on the jQuery object... for now
7390  // Want to move this to jQuery.ajax some day
7391  jQuery.extend({
7392  
7393          // Counter for holding the number of active queries
7394          active: 0,
7395  
7396          // Last-Modified header cache for next request
7397          lastModified: {},
7398          etag: {}
7399  
7400  });
7401  
7402  /* Handles responses to an ajax request:
7403   * - sets all responseXXX fields accordingly
7404   * - finds the right dataType (mediates between content-type and expected dataType)
7405   * - returns the corresponding response
7406   */
7407  function ajaxHandleResponses( s, jqXHR, responses ) {
7408  
7409          var contents = s.contents,
7410                  dataTypes = s.dataTypes,
7411                  responseFields = s.responseFields,
7412                  ct,
7413                  type,
7414                  finalDataType,
7415                  firstDataType;
7416  
7417          // Fill responseXXX fields
7418          for( type in responseFields ) {
7419                  if ( type in responses ) {
7420                          jqXHR[ responseFields[type] ] = responses[ type ];
7421                  }
7422          }
7423  
7424          // Remove auto dataType and get content-type in the process
7425          while( dataTypes[ 0 ] === "*" ) {
7426                  dataTypes.shift();
7427                  if ( ct === undefined ) {
7428                          ct = s.mimeType || jqXHR.getResponseHeader( "content-type" );
7429                  }
7430          }
7431  
7432          // Check if we're dealing with a known content-type
7433          if ( ct ) {
7434                  for ( type in contents ) {
7435                          if ( contents[ type ] && contents[ type ].test( ct ) ) {
7436                                  dataTypes.unshift( type );
7437                                  break;
7438                          }
7439                  }
7440          }
7441  
7442          // Check to see if we have a response for the expected dataType
7443          if ( dataTypes[ 0 ] in responses ) {
7444                  finalDataType = dataTypes[ 0 ];
7445          } else {
7446                  // Try convertible dataTypes
7447                  for ( type in responses ) {
7448                          if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {
7449                                  finalDataType = type;
7450                                  break;
7451                          }
7452                          if ( !firstDataType ) {
7453                                  firstDataType = type;
7454                          }
7455                  }
7456                  // Or just use first one
7457                  finalDataType = finalDataType || firstDataType;
7458          }
7459  
7460          // If we found a dataType
7461          // We add the dataType to the list if needed
7462          // and return the corresponding response
7463          if ( finalDataType ) {
7464                  if ( finalDataType !== dataTypes[ 0 ] ) {
7465                          dataTypes.unshift( finalDataType );
7466                  }
7467                  return responses[ finalDataType ];
7468          }
7469  }
7470  
7471  // Chain conversions given the request and the original response
7472  function ajaxConvert( s, response ) {
7473  
7474          // Apply the dataFilter if provided
7475          if ( s.dataFilter ) {
7476                  response = s.dataFilter( response, s.dataType );
7477          }
7478  
7479          var dataTypes = s.dataTypes,
7480                  converters = {},
7481                  i,
7482                  key,
7483                  length = dataTypes.length,
7484                  tmp,
7485                  // Current and previous dataTypes
7486                  current = dataTypes[ 0 ],
7487                  prev,
7488                  // Conversion expression
7489                  conversion,
7490                  // Conversion function
7491                  conv,
7492                  // Conversion functions (transitive conversion)
7493                  conv1,
7494                  conv2;
7495  
7496          // For each dataType in the chain
7497          for( i = 1; i < length; i++ ) {
7498  
7499                  // Create converters map
7500                  // with lowercased keys
7501                  if ( i === 1 ) {
7502                          for( key in s.converters ) {
7503                                  if( typeof key === "string" ) {
7504                                          converters[ key.toLowerCase() ] = s.converters[ key ];
7505                                  }
7506                          }
7507                  }
7508  
7509                  // Get the dataTypes
7510                  prev = current;
7511                  current = dataTypes[ i ];
7512  
7513                  // If current is auto dataType, update it to prev
7514                  if( current === "*" ) {
7515                          current = prev;
7516                  // If no auto and dataTypes are actually different
7517                  } else if ( prev !== "*" && prev !== current ) {
7518  
7519                          // Get the converter
7520                          conversion = prev + " " + current;
7521                          conv = converters[ conversion ] || converters[ "* " + current ];
7522  
7523                          // If there is no direct converter, search transitively
7524                          if ( !conv ) {
7525                                  conv2 = undefined;
7526                                  for( conv1 in converters ) {
7527                                          tmp = conv1.split( " " );
7528                                          if ( tmp[ 0 ] === prev || tmp[ 0 ] === "*" ) {
7529                                                  conv2 = converters[ tmp[1] + " " + current ];
7530                                                  if ( conv2 ) {
7531                                                          conv1 = converters[ conv1 ];
7532                                                          if ( conv1 === true ) {
7533                                                                  conv = conv2;
7534                                                          } else if ( conv2 === true ) {
7535                                                                  conv = conv1;
7536                                                          }
7537                                                          break;
7538                                                  }
7539                                          }
7540                                  }
7541                          }
7542                          // If we found no converter, dispatch an error
7543                          if ( !( conv || conv2 ) ) {
7544                                  jQuery.error( "No conversion from " + conversion.replace(" "," to ") );
7545                          }
7546                          // If found converter is not an equivalence
7547                          if ( conv !== true ) {
7548                                  // Convert with 1 or 2 converters accordingly
7549                                  response = conv ? conv( response ) : conv2( conv1(response) );
7550                          }
7551                  }
7552          }
7553          return response;
7554  }
7555  
7556  
7557  
7558  
7559  var jsc = jQuery.now(),
7560          jsre = /(\=)\?(&|$)|\?\?/i;
7561  
7562  // Default jsonp settings
7563  jQuery.ajaxSetup({
7564          jsonp: "callback",
7565          jsonpCallback: function() {
7566                  return jQuery.expando + "_" + ( jsc++ );
7567          }
7568  });
7569  
7570  // Detect, normalize options and install callbacks for jsonp requests
7571  jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
7572  
7573          var inspectData = s.contentType === "application/x-www-form-urlencoded" &&
7574                  ( typeof s.data === "string" );
7575  
7576          if ( s.dataTypes[ 0 ] === "jsonp" ||
7577                  s.jsonp !== false && ( jsre.test( s.url ) ||
7578                                  inspectData && jsre.test( s.data ) ) ) {
7579  
7580                  var responseContainer,
7581                          jsonpCallback = s.jsonpCallback =
7582                                  jQuery.isFunction( s.jsonpCallback ) ? s.jsonpCallback() : s.jsonpCallback,
7583                          previous = window[ jsonpCallback ],
7584                          url = s.url,
7585                          data = s.data,
7586                          replace = "$1" + jsonpCallback + "$2";
7587  
7588                  if ( s.jsonp !== false ) {
7589                          url = url.replace( jsre, replace );
7590                          if ( s.url === url ) {
7591                                  if ( inspectData ) {
7592                                          data = data.replace( jsre, replace );
7593                                  }
7594                                  if ( s.data === data ) {
7595                                          // Add callback manually
7596                                          url += (/\?/.test( url ) ? "&" : "?") + s.jsonp + "=" + jsonpCallback;
7597                                  }
7598                          }
7599                  }
7600  
7601                  s.url = url;
7602                  s.data = data;
7603  
7604                  // Install callback
7605                  window[ jsonpCallback ] = function( response ) {
7606                          responseContainer = [ response ];
7607                  };
7608  
7609                  // Clean-up function
7610                  jqXHR.always(function() {
7611                          // Set callback back to previous value
7612                          window[ jsonpCallback ] = previous;
7613                          // Call if it was a function and we have a response
7614                          if ( responseContainer && jQuery.isFunction( previous ) ) {
7615                                  window[ jsonpCallback ]( responseContainer[ 0 ] );
7616                          }
7617                  });
7618  
7619                  // Use data converter to retrieve json after script execution
7620                  s.converters["script json"] = function() {
7621                          if ( !responseContainer ) {
7622                                  jQuery.error( jsonpCallback + " was not called" );
7623                          }
7624                          return responseContainer[ 0 ];
7625                  };
7626  
7627                  // force json dataType
7628                  s.dataTypes[ 0 ] = "json";
7629  
7630                  // Delegate to script
7631                  return "script";
7632          }
7633  });
7634  
7635  
7636  
7637  
7638  // Install script dataType
7639  jQuery.ajaxSetup({
7640          accepts: {
7641                  script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
7642          },
7643          contents: {
7644                  script: /javascript|ecmascript/
7645          },
7646          converters: {
7647                  "text script": function( text ) {
7648                          jQuery.globalEval( text );
7649                          return text;
7650                  }
7651          }
7652  });
7653  
7654  // Handle cache's special case and global
7655  jQuery.ajaxPrefilter( "script", function( s ) {
7656          if ( s.cache === undefined ) {
7657                  s.cache = false;
7658          }
7659          if ( s.crossDomain ) {
7660                  s.type = "GET";
7661                  s.global = false;
7662          }
7663  });
7664  
7665  // Bind script tag hack transport
7666  jQuery.ajaxTransport( "script", function(s) {
7667  
7668          // This transport only deals with cross domain requests
7669          if ( s.crossDomain ) {
7670  
7671                  var script,
7672                          head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement;
7673  
7674                  return {
7675  
7676                          send: function( _, callback ) {
7677  
7678                                  script = document.createElement( "script" );
7679  
7680                                  script.async = "async";
7681  
7682                                  if ( s.scriptCharset ) {
7683                                          script.charset = s.scriptCharset;
7684                                  }
7685  
7686                                  script.src = s.url;
7687  
7688                                  // Attach handlers for all browsers
7689                                  script.onload = script.onreadystatechange = function( _, isAbort ) {
7690  
7691                                          if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {
7692  
7693                                                  // Handle memory leak in IE
7694                                                  script.onload = script.onreadystatechange = null;
7695  
7696                                                  // Remove the script
7697                                                  if ( head && script.parentNode ) {
7698                                                          head.removeChild( script );
7699                                                  }
7700  
7701                                                  // Dereference the script
7702                                                  script = undefined;
7703  
7704                                                  // Callback if not abort
7705                                                  if ( !isAbort ) {
7706                                                          callback( 200, "success" );
7707                                                  }
7708                                          }
7709                                  };
7710                                  // Use insertBefore instead of appendChild  to circumvent an IE6 bug.
7711                                  // This arises when a base node is used (#2709 and #4378).
7712                                  head.insertBefore( script, head.firstChild );
7713                          },
7714  
7715                          abort: function() {
7716                                  if ( script ) {
7717                                          script.onload( 0, 1 );
7718                                  }
7719                          }
7720                  };
7721          }
7722  });
7723  
7724  
7725  
7726  
7727  var // #5280: Internet Explorer will keep connections alive if we don't abort on unload
7728          xhrOnUnloadAbort = window.ActiveXObject ? function() {
7729                  // Abort all pending requests
7730                  for ( var key in xhrCallbacks ) {
7731                          xhrCallbacks[ key ]( 0, 1 );
7732                  }
7733          } : false,
7734          xhrId = 0,
7735          xhrCallbacks;
7736  
7737  // Functions to create xhrs
7738  function createStandardXHR() {
7739          try {
7740                  return new window.XMLHttpRequest();
7741          } catch( e ) {}
7742  }
7743  
7744  function createActiveXHR() {
7745          try {
7746                  return new window.ActiveXObject( "Microsoft.XMLHTTP" );
7747          } catch( e ) {}
7748  }
7749  
7750  // Create the request object
7751  // (This is still attached to ajaxSettings for backward compatibility)
7752  jQuery.ajaxSettings.xhr = window.ActiveXObject ?
7753          /* Microsoft failed to properly
7754           * implement the XMLHttpRequest in IE7 (can't request local files),
7755           * so we use the ActiveXObject when it is available
7756           * Additionally XMLHttpRequest can be disabled in IE7/IE8 so
7757           * we need a fallback.
7758           */
7759          function() {
7760                  return !this.isLocal && createStandardXHR() || createActiveXHR();
7761          } :
7762          // For all other browsers, use the standard XMLHttpRequest object
7763          createStandardXHR;
7764  
7765  // Determine support properties
7766  (function( xhr ) {
7767          jQuery.extend( jQuery.support, {
7768                  ajax: !!xhr,
7769                  cors: !!xhr && ( "withCredentials" in xhr )
7770          });
7771  })( jQuery.ajaxSettings.xhr() );
7772  
7773  // Create transport if the browser can provide an xhr
7774  if ( jQuery.support.ajax ) {
7775  
7776          jQuery.ajaxTransport(function( s ) {
7777                  // Cross domain only allowed if supported through XMLHttpRequest
7778                  if ( !s.crossDomain || jQuery.support.cors ) {
7779  
7780                          var callback;
7781  
7782                          return {
7783                                  send: function( headers, complete ) {
7784  
7785                                          // Get a new xhr
7786                                          var xhr = s.xhr(),
7787                                                  handle,
7788                                                  i;
7789  
7790                                          // Open the socket
7791                                          // Passing null username, generates a login popup on Opera (#2865)
7792                                          if ( s.username ) {
7793                                                  xhr.open( s.type, s.url, s.async, s.username, s.password );
7794                                          } else {
7795                                                  xhr.open( s.type, s.url, s.async );
7796                                          }
7797  
7798                                          // Apply custom fields if provided
7799                                          if ( s.xhrFields ) {
7800                                                  for ( i in s.xhrFields ) {
7801                                                          xhr[ i ] = s.xhrFields[ i ];
7802                                                  }
7803                                          }
7804  
7805                                          // Override mime type if needed
7806                                          if ( s.mimeType && xhr.overrideMimeType ) {
7807                                                  xhr.overrideMimeType( s.mimeType );
7808                                          }
7809  
7810                                          // X-Requested-With header
7811                                          // For cross-domain requests, seeing as conditions for a preflight are
7812                                          // akin to a jigsaw puzzle, we simply never set it to be sure.
7813                                          // (it can always be set on a per-request basis or even using ajaxSetup)
7814                                          // For same-domain requests, won't change header if already provided.
7815                                          if ( !s.crossDomain && !headers["X-Requested-With"] ) {
7816                                                  headers[ "X-Requested-With" ] = "XMLHttpRequest";
7817                                          }
7818  
7819                                          // Need an extra try/catch for cross domain requests in Firefox 3
7820                                          try {
7821                                                  for ( i in headers ) {
7822                                                          xhr.setRequestHeader( i, headers[ i ] );
7823                                                  }
7824                                          } catch( _ ) {}
7825  
7826                                          // Do send the request
7827                                          // This may raise an exception which is actually
7828                                          // handled in jQuery.ajax (so no try/catch here)
7829                                          xhr.send( ( s.hasContent && s.data ) || null );
7830  
7831                                          // Listener
7832                                          callback = function( _, isAbort ) {
7833  
7834                                                  var status,
7835                                                          statusText,
7836                                                          responseHeaders,
7837                                                          responses,
7838                                                          xml;
7839  
7840                                                  // Firefox throws exceptions when accessing properties
7841                                                  // of an xhr when a network error occured
7842                                                  // http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE)
7843                                                  try {
7844  
7845                                                          // Was never called and is aborted or complete
7846                                                          if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
7847  
7848                                                                  // Only called once
7849                                                                  callback = undefined;
7850  
7851                                                                  // Do not keep as active anymore
7852                                                                  if ( handle ) {
7853                                                                          xhr.onreadystatechange = jQuery.noop;
7854                                                                          if ( xhrOnUnloadAbort ) {
7855                                                                                  delete xhrCallbacks[ handle ];
7856                                                                          }
7857                                                                  }
7858  
7859                                                                  // If it's an abort
7860                                                                  if ( isAbort ) {
7861                                                                          // Abort it manually if needed
7862                                                                          if ( xhr.readyState !== 4 ) {
7863                                                                                  xhr.abort();
7864                                                                          }
7865                                                                  } else {
7866                                                                          status = xhr.status;
7867                                                                          responseHeaders = xhr.getAllResponseHeaders();
7868                                                                          responses = {};
7869                                                                          xml = xhr.responseXML;
7870  
7871                                                                          // Construct response list
7872                                                                          if ( xml && xml.documentElement /* #4958 */ ) {
7873                                                                                  responses.xml = xml;
7874                                                                          }
7875                                                                          responses.text = xhr.responseText;
7876  
7877                                                                          // Firefox throws an exception when accessing
7878                                                                          // statusText for faulty cross-domain requests
7879                                                                          try {
7880                                                                                  statusText = xhr.statusText;
7881                                                                          } catch( e ) {
7882                                                                                  // We normalize with Webkit giving an empty statusText
7883                                                                                  statusText = "";
7884                                                                          }
7885  
7886                                                                          // Filter status for non standard behaviors
7887  
7888                                                                          // If the request is local and we have data: assume a success
7889                                                                          // (success with no data won't get notified, that's the best we
7890                                                                          // can do given current implementations)
7891                                                                          if ( !status && s.isLocal && !s.crossDomain ) {
7892                                                                                  status = responses.text ? 200 : 404;
7893                                                                          // IE - #1450: sometimes returns 1223 when it should be 204
7894                                                                          } else if ( status === 1223 ) {
7895                                                                                  status = 204;
7896                                                                          }
7897                                                                  }
7898                                                          }
7899                                                  } catch( firefoxAccessException ) {
7900                                                          if ( !isAbort ) {
7901                                                                  complete( -1, firefoxAccessException );
7902                                                          }
7903                                                  }
7904  
7905                                                  // Call complete if needed
7906                                                  if ( responses ) {
7907                                                          complete( status, statusText, responses, responseHeaders );
7908                                                  }
7909                                          };
7910  
7911                                          // if we're in sync mode or it's in cache
7912                                          // and has been retrieved directly (IE6 & IE7)
7913                                          // we need to manually fire the callback
7914                                          if ( !s.async || xhr.readyState === 4 ) {
7915                                                  callback();
7916                                          } else {
7917                                                  handle = ++xhrId;
7918                                                  if ( xhrOnUnloadAbort ) {
7919                                                          // Create the active xhrs callbacks list if needed
7920                                                          // and attach the unload handler
7921                                                          if ( !xhrCallbacks ) {
7922                                                                  xhrCallbacks = {};
7923                                                                  jQuery( window ).unload( xhrOnUnloadAbort );
7924                                                          }
7925                                                          // Add to list of active xhrs callbacks
7926                                                          xhrCallbacks[ handle ] = callback;
7927                                                  }
7928                                                  xhr.onreadystatechange = callback;
7929                                          }
7930                                  },
7931  
7932                                  abort: function() {
7933                                          if ( callback ) {
7934                                                  callback(0,1);
7935                                          }
7936                                  }
7937                          };
7938                  }
7939          });
7940  }
7941  
7942  
7943  
7944  
7945  var elemdisplay = {},
7946          iframe, iframeDoc,
7947          rfxtypes = /^(?:toggle|show|hide)$/,
7948          rfxnum = /^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,
7949          timerId,
7950          fxAttrs = [
7951                  // height animations
7952                  [ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
7953                  // width animations
7954                  [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
7955                  // opacity animations
7956                  [ "opacity" ]
7957          ],
7958          fxNow,
7959          requestAnimationFrame = window.webkitRequestAnimationFrame ||
7960              window.mozRequestAnimationFrame ||
7961              window.oRequestAnimationFrame;
7962  
7963  jQuery.fn.extend({
7964          show: function( speed, easing, callback ) {
7965                  var elem, display;
7966  
7967                  if ( speed || speed === 0 ) {
7968                          return this.animate( genFx("show", 3), speed, easing, callback);
7969  
7970                  } else {
7971                          for ( var i = 0, j = this.length; i < j; i++ ) {
7972                                  elem = this[i];
7973  
7974                                  if ( elem.style ) {
7975                                          display = elem.style.display;
7976  
7977                                          // Reset the inline display of this element to learn if it is
7978                                          // being hidden by cascaded rules or not
7979                                          if ( !jQuery._data(elem, "olddisplay") && display === "none" ) {
7980                                                  display = elem.style.display = "";
7981                                          }
7982  
7983                                          // Set elements which have been overridden with display: none
7984                                          // in a stylesheet to whatever the default browser style is
7985                                          // for such an element
7986                                          if ( display === "" && jQuery.css( elem, "display" ) === "none" ) {
7987                                                  jQuery._data(elem, "olddisplay", defaultDisplay(elem.nodeName));
7988                                          }
7989                                  }
7990                          }
7991  
7992                          // Set the display of most of the elements in a second loop
7993                          // to avoid the constant reflow
7994                          for ( i = 0; i < j; i++ ) {
7995                                  elem = this[i];
7996  
7997                                  if ( elem.style ) {
7998                                          display = elem.style.display;
7999  
8000                                          if ( display === "" || display === "none" ) {
8001                                                  elem.style.display = jQuery._data(elem, "olddisplay") || "";
8002                                          }
8003                                  }
8004                          }
8005  
8006                          return this;
8007                  }
8008          },
8009  
8010          hide: function( speed, easing, callback ) {
8011                  if ( speed || speed === 0 ) {
8012                          return this.animate( genFx("hide", 3), speed, easing, callback);
8013  
8014                  } else {
8015                          for ( var i = 0, j = this.length; i < j; i++ ) {
8016                                  if ( this[i].style ) {
8017                                          var display = jQuery.css( this[i], "display" );
8018  
8019                                          if ( display !== "none" && !jQuery._data( this[i], "olddisplay" ) ) {
8020                                                  jQuery._data( this[i], "olddisplay", display );
8021                                          }
8022                                  }
8023                          }
8024  
8025                          // Set the display of the elements in a second loop
8026                          // to avoid the constant reflow
8027                          for ( i = 0; i < j; i++ ) {
8028                                  if ( this[i].style ) {
8029                                          this[i].style.display = "none";
8030                                  }
8031                          }
8032  
8033                          return this;
8034                  }
8035          },
8036  
8037          // Save the old toggle function
8038          _toggle: jQuery.fn.toggle,
8039  
8040          toggle: function( fn, fn2, callback ) {
8041                  var bool = typeof fn === "boolean";
8042  
8043                  if ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) {
8044                          this._toggle.apply( this, arguments );
8045  
8046                  } else if ( fn == null || bool ) {
8047                          this.each(function() {
8048                                  var state = bool ? fn : jQuery(this).is(":hidden");
8049                                  jQuery(this)[ state ? "show" : "hide" ]();
8050                          });
8051  
8052                  } else {
8053                          this.animate(genFx("toggle", 3), fn, fn2, callback);
8054                  }
8055  
8056                  return this;
8057          },
8058  
8059          fadeTo: function( speed, to, easing, callback ) {
8060                  return this.filter(":hidden").css("opacity", 0).show().end()
8061                                          .animate({opacity: to}, speed, easing, callback);
8062          },
8063  
8064          animate: function( prop, speed, easing, callback ) {
8065                  var optall = jQuery.speed(speed, easing, callback);
8066  
8067                  if ( jQuery.isEmptyObject( prop ) ) {
8068                          return this.each( optall.complete, [ false ] );
8069                  }
8070  
8071                  // Do not change referenced properties as per-property easing will be lost
8072                  prop = jQuery.extend( {}, prop );
8073  
8074                  return this[ optall.queue === false ? "each" : "queue" ](function() {
8075                          // XXX 'this' does not always have a nodeName when running the
8076                          // test suite
8077  
8078                          if ( optall.queue === false ) {
8079                                  jQuery._mark( this );
8080                          }
8081  
8082                          var opt = jQuery.extend( {}, optall ),
8083                                  isElement = this.nodeType === 1,
8084                                  hidden = isElement && jQuery(this).is(":hidden"),
8085                                  name, val, p,
8086                                  display, e,
8087                                  parts, start, end, unit;
8088  
8089                          // will store per property easing and be used to determine when an animation is complete
8090                          opt.animatedProperties = {};
8091  
8092                          for ( p in prop ) {
8093  
8094                                  // property name normalization
8095                                  name = jQuery.camelCase( p );
8096                                  if ( p !== name ) {
8097                                          prop[ name ] = prop[ p ];
8098                                          delete prop[ p ];
8099                                  }
8100  
8101                                  val = prop[ name ];
8102  
8103                                  // easing resolution: per property > opt.specialEasing > opt.easing > 'swing' (default)
8104                                  if ( jQuery.isArray( val ) ) {
8105                                          opt.animatedProperties[ name ] = val[ 1 ];
8106                                          val = prop[ name ] = val[ 0 ];
8107                                  } else {
8108                                          opt.animatedProperties[ name ] = opt.specialEasing && opt.specialEasing[ name ] || opt.easing || 'swing';
8109                                  }
8110  
8111                                  if ( val === "hide" && hidden || val === "show" && !hidden ) {
8112                                          return opt.complete.call( this );
8113                                  }
8114  
8115                                  if ( isElement && ( name === "height" || name === "width" ) ) {
8116                                          // Make sure that nothing sneaks out
8117                                          // Record all 3 overflow attributes because IE does not
8118                                          // change the overflow attribute when overflowX and
8119                                          // overflowY are set to the same value
8120                                          opt.overflow = [ this.style.overflow, this.style.overflowX, this.style.overflowY ];
8121  
8122                                          // Set display property to inline-block for height/width
8123                                          // animations on inline elements that are having width/height
8124                                          // animated
8125                                          if ( jQuery.css( this, "display" ) === "inline" &&
8126                                                          jQuery.css( this, "float" ) === "none" ) {
8127                                                  if ( !jQuery.support.inlineBlockNeedsLayout ) {
8128                                                          this.style.display = "inline-block";
8129  
8130                                                  } else {
8131                                                          display = defaultDisplay( this.nodeName );
8132  
8133                                                          // inline-level elements accept inline-block;
8134                                                          // block-level elements need to be inline with layout
8135                                                          if ( display === "inline" ) {
8136                                                                  this.style.display = "inline-block";
8137  
8138                                                          } else {
8139                                                                  this.style.display = "inline";
8140                                                                  this.style.zoom = 1;
8141                                                          }
8142                                                  }
8143                                          }
8144                                  }
8145                          }
8146  
8147                          if ( opt.overflow != null ) {
8148                                  this.style.overflow = "hidden";
8149                          }
8150  
8151                          for ( p in prop ) {
8152                                  e = new jQuery.fx( this, opt, p );
8153                                  val = prop[ p ];
8154  
8155                                  if ( rfxtypes.test(val) ) {
8156                                          e[ val === "toggle" ? hidden ? "show" : "hide" : val ]();
8157  
8158                                  } else {
8159                                          parts = rfxnum.exec( val );
8160                                          start = e.cur();
8161  
8162                                          if ( parts ) {
8163                                                  end = parseFloat( parts[2] );
8164                                                  unit = parts[3] || ( jQuery.cssNumber[ p ] ? "" : "px" );
8165  
8166                                                  // We need to compute starting value
8167                                                  if ( unit !== "px" ) {
8168                                                          jQuery.style( this, p, (end || 1) + unit);
8169                                                          start = ((end || 1) / e.cur()) * start;
8170                                                          jQuery.style( this, p, start + unit);
8171                                                  }
8172  
8173                                                  // If a +=/-= token was provided, we're doing a relative animation
8174                                                  if ( parts[1] ) {
8175                                                          end = ( (parts[ 1 ] === "-=" ? -1 : 1) * end ) + start;
8176                                                  }
8177  
8178                                                  e.custom( start, end, unit );
8179  
8180                                          } else {
8181                                                  e.custom( start, val, "" );
8182                                          }
8183                                  }
8184                          }
8185  
8186                          // For JS strict compliance
8187                          return true;
8188                  });
8189          },
8190  
8191          stop: function( clearQueue, gotoEnd ) {
8192                  if ( clearQueue ) {
8193                          this.queue([]);
8194                  }
8195  
8196                  this.each(function() {
8197                          var timers = jQuery.timers,
8198                                  i = timers.length;
8199                          // clear marker counters if we know they won't be
8200                          if ( !gotoEnd ) {
8201                                  jQuery._unmark( true, this );
8202                          }
8203                          while ( i-- ) {
8204                                  if ( timers[i].elem === this ) {
8205                                          if (gotoEnd) {
8206                                                  // force the next step to be the last
8207                                                  timers[i](true);
8208                                          }
8209  
8210                                          timers.splice(i, 1);
8211                                  }
8212                          }
8213                  });
8214  
8215                  // start the next in the queue if the last step wasn't forced
8216                  if ( !gotoEnd ) {
8217                          this.dequeue();
8218                  }
8219  
8220                  return this;
8221          }
8222  
8223  });
8224  
8225  // Animations created synchronously will run synchronously
8226  function createFxNow() {
8227          setTimeout( clearFxNow, 0 );
8228          return ( fxNow = jQuery.now() );
8229  }
8230  
8231  function clearFxNow() {
8232          fxNow = undefined;
8233  }
8234  
8235  // Generate parameters to create a standard animation
8236  function genFx( type, num ) {
8237          var obj = {};
8238  
8239          jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function() {
8240                  obj[ this ] = type;
8241          });
8242  
8243          return obj;
8244  }
8245  
8246  // Generate shortcuts for custom animations
8247  jQuery.each({
8248          slideDown: genFx("show", 1),
8249          slideUp: genFx("hide", 1),
8250          slideToggle: genFx("toggle", 1),
8251          fadeIn: { opacity: "show" },
8252          fadeOut: { opacity: "hide" },
8253          fadeToggle: { opacity: "toggle" }
8254  }, function( name, props ) {
8255          jQuery.fn[ name ] = function( speed, easing, callback ) {
8256                  return this.animate( props, speed, easing, callback );
8257          };
8258  });
8259  
8260  jQuery.extend({
8261          speed: function( speed, easing, fn ) {
8262                  var opt = speed && typeof speed === "object" ? jQuery.extend({}, speed) : {
8263                          complete: fn || !fn && easing ||
8264                                  jQuery.isFunction( speed ) && speed,
8265                          duration: speed,
8266                          easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
8267                  };
8268  
8269                  opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
8270                          opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[opt.duration] : jQuery.fx.speeds._default;
8271  
8272                  // Queueing
8273                  opt.old = opt.complete;
8274                  opt.complete = function( noUnmark ) {
8275                          if ( opt.queue !== false ) {
8276                                  jQuery.dequeue( this );
8277                          } else if ( noUnmark !== false ) {
8278                                  jQuery._unmark( this );
8279                          }
8280  
8281                          if ( jQuery.isFunction( opt.old ) ) {
8282                                  opt.old.call( this );
8283                          }
8284                  };
8285  
8286                  return opt;
8287          },
8288  
8289          easing: {
8290                  linear: function( p, n, firstNum, diff ) {
8291                          return firstNum + diff * p;
8292                  },
8293                  swing: function( p, n, firstNum, diff ) {
8294                          return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
8295                  }
8296          },
8297  
8298          timers: [],
8299  
8300          fx: function( elem, options, prop ) {
8301                  this.options = options;
8302                  this.elem = elem;
8303                  this.prop = prop;
8304  
8305                  options.orig = options.orig || {};
8306          }
8307  
8308  });
8309  
8310  jQuery.fx.prototype = {
8311          // Simple function for setting a style value
8312          update: function() {
8313                  if ( this.options.step ) {
8314                          this.options.step.call( this.elem, this.now, this );
8315                  }
8316  
8317                  (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
8318          },
8319  
8320          // Get the current size
8321          cur: function() {
8322                  if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) ) {
8323                          return this.elem[ this.prop ];
8324                  }
8325  
8326                  var parsed,
8327                          r = jQuery.css( this.elem, this.prop );
8328                  // Empty strings, null, undefined and "auto" are converted to 0,
8329                  // complex values such as "rotate(1rad)" are returned as is,
8330                  // simple values such as "10px" are parsed to Float.
8331                  return isNaN( parsed = parseFloat( r ) ) ? !r || r === "auto" ? 0 : r : parsed;
8332          },
8333  
8334          // Start an animation from one number to another
8335          custom: function( from, to, unit ) {
8336                  var self = this,
8337                          fx = jQuery.fx,
8338                          raf;
8339  
8340                  this.startTime = fxNow || createFxNow();
8341                  this.start = from;
8342                  this.end = to;
8343                  this.unit = unit || this.unit || ( jQuery.cssNumber[ this.prop ] ? "" : "px" );
8344                  this.now = this.start;
8345                  this.pos = this.state = 0;
8346  
8347                  function t( gotoEnd ) {
8348                          return self.step(gotoEnd);
8349                  }
8350  
8351                  t.elem = this.elem;
8352  
8353                  if ( t() && jQuery.timers.push(t) && !timerId ) {
8354                          // Use requestAnimationFrame instead of setInterval if available
8355                          if ( requestAnimationFrame ) {
8356                                  timerId = 1;
8357                                  raf = function() {
8358                                          // When timerId gets set to null at any point, this stops
8359                                          if ( timerId ) {
8360                                                  requestAnimationFrame( raf );
8361                                                  fx.tick();
8362                                          }
8363                                  };
8364                                  requestAnimationFrame( raf );
8365                          } else {
8366                                  timerId = setInterval( fx.tick, fx.interval );
8367                          }
8368                  }
8369          },
8370  
8371          // Simple 'show' function
8372          show: function() {
8373                  // Remember where we started, so that we can go back to it later
8374                  this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
8375                  this.options.show = true;
8376  
8377                  // Begin the animation
8378                  // Make sure that we start at a small width/height to avoid any
8379                  // flash of content
8380                  this.custom(this.prop === "width" || this.prop === "height" ? 1 : 0, this.cur());
8381  
8382                  // Start by showing the element
8383                  jQuery( this.elem ).show();
8384          },
8385  
8386          // Simple 'hide' function
8387          hide: function() {
8388                  // Remember where we started, so that we can go back to it later
8389                  this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
8390                  this.options.hide = true;
8391  
8392                  // Begin the animation
8393                  this.custom(this.cur(), 0);
8394          },
8395  
8396          // Each step of an animation
8397          step: function( gotoEnd ) {
8398                  var t = fxNow || createFxNow(),
8399                          done = true,
8400                          elem = this.elem,
8401                          options = this.options,
8402                          i, n;
8403  
8404                  if ( gotoEnd || t >= options.duration + this.startTime ) {
8405                          this.now = this.end;
8406                          this.pos = this.state = 1;
8407                          this.update();
8408  
8409                          options.animatedProperties[ this.prop ] = true;
8410  
8411                          for ( i in options.animatedProperties ) {
8412                                  if ( options.animatedProperties[i] !== true ) {
8413                                          done = false;
8414                                  }
8415                          }
8416  
8417                          if ( done ) {
8418                                  // Reset the overflow
8419                                  if ( options.overflow != null && !jQuery.support.shrinkWrapBlocks ) {
8420  
8421                                          jQuery.each( [ "", "X", "Y" ], function (index, value) {
8422                                                  elem.style[ "overflow" + value ] = options.overflow[index];
8423                                          });
8424                                  }
8425  
8426                                  // Hide the element if the "hide" operation was done
8427                                  if ( options.hide ) {
8428                                          jQuery(elem).hide();
8429                                  }
8430  
8431                                  // Reset the properties, if the item has been hidden or shown
8432                                  if ( options.hide || options.show ) {
8433                                          for ( var p in options.animatedProperties ) {
8434                                                  jQuery.style( elem, p, options.orig[p] );
8435                                          }
8436                                  }
8437  
8438                                  // Execute the complete function
8439                                  options.complete.call( elem );
8440                          }
8441  
8442                          return false;
8443  
8444                  } else {
8445                          // classical easing cannot be used with an Infinity duration
8446                          if ( options.duration == Infinity ) {
8447                                  this.now = t;
8448                          } else {
8449                                  n = t - this.startTime;
8450                                  this.state = n / options.duration;
8451  
8452                                  // Perform the easing function, defaults to swing
8453                                  this.pos = jQuery.easing[ options.animatedProperties[ this.prop ] ]( this.state, n, 0, 1, options.duration );
8454                                  this.now = this.start + ((this.end - this.start) * this.pos);
8455                          }
8456                          // Perform the next step of the animation
8457                          this.update();
8458                  }
8459  
8460                  return true;
8461          }
8462  };
8463  
8464  jQuery.extend( jQuery.fx, {
8465          tick: function() {
8466                  for ( var timers = jQuery.timers, i = 0 ; i < timers.length ; ++i ) {
8467                          if ( !timers[i]() ) {
8468                                  timers.splice(i--, 1);
8469                          }
8470                  }
8471  
8472                  if ( !timers.length ) {
8473                          jQuery.fx.stop();
8474                  }
8475          },
8476  
8477          interval: 13,
8478  
8479          stop: function() {
8480                  clearInterval( timerId );
8481                  timerId = null;
8482          },
8483  
8484          speeds: {
8485                  slow: 600,
8486                  fast: 200,
8487                  // Default speed
8488                  _default: 400
8489          },
8490  
8491          step: {
8492                  opacity: function( fx ) {
8493                          jQuery.style( fx.elem, "opacity", fx.now );
8494                  },
8495  
8496                  _default: function( fx ) {
8497                          if ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) {
8498                                  fx.elem.style[ fx.prop ] = (fx.prop === "width" || fx.prop === "height" ? Math.max(0, fx.now) : fx.now) + fx.unit;
8499                          } else {
8500                                  fx.elem[ fx.prop ] = fx.now;
8501                          }
8502                  }
8503          }
8504  });
8505  
8506  if ( jQuery.expr && jQuery.expr.filters ) {
8507          jQuery.expr.filters.animated = function( elem ) {
8508                  return jQuery.grep(jQuery.timers, function( fn ) {
8509                          return elem === fn.elem;
8510                  }).length;
8511          };
8512  }
8513  
8514  // Try to restore the default display value of an element
8515  function defaultDisplay( nodeName ) {
8516  
8517          if ( !elemdisplay[ nodeName ] ) {
8518  
8519                  var elem = jQuery( "<" + nodeName + ">" ).appendTo( "body" ),
8520                          display = elem.css( "display" );
8521  
8522                  elem.remove();
8523  
8524                  // If the simple way fails,
8525                  // get element's real default display by attaching it to a temp iframe
8526                  if ( display === "none" || display === "" ) {
8527                          // No iframe to use yet, so create it
8528                          if ( !iframe ) {
8529                                  iframe = document.createElement( "iframe" );
8530                                  iframe.frameBorder = iframe.width = iframe.height = 0;
8531                          }
8532  
8533                          document.body.appendChild( iframe );
8534  
8535                          // Create a cacheable copy of the iframe document on first call.
8536                          // IE and Opera will allow us to reuse the iframeDoc without re-writing the fake html
8537                          // document to it, Webkit & Firefox won't allow reusing the iframe document
8538                          if ( !iframeDoc || !iframe.createElement ) {
8539                                  iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document;
8540                                  iframeDoc.write( "<!doctype><html><body></body></html>" );
8541                          }
8542  
8543                          elem = iframeDoc.createElement( nodeName );
8544  
8545                          iframeDoc.body.appendChild( elem );
8546  
8547                          display = jQuery.css( elem, "display" );
8548  
8549                          document.body.removeChild( iframe );
8550                  }
8551  
8552                  // Store the correct default display
8553                  elemdisplay[ nodeName ] = display;
8554          }
8555  
8556          return elemdisplay[ nodeName ];
8557  }
8558  
8559  
8560  
8561  
8562  var rtable = /^t(?:able|d|h)$/i,
8563          rroot = /^(?:body|html)$/i;
8564  
8565  if ( "getBoundingClientRect" in document.documentElement ) {
8566          jQuery.fn.offset = function( options ) {
8567                  var elem = this[0], box;
8568  
8569                  if ( options ) {
8570                          return this.each(function( i ) {
8571                                  jQuery.offset.setOffset( this, options, i );
8572                          });
8573                  }
8574  
8575                  if ( !elem || !elem.ownerDocument ) {
8576                          return null;
8577                  }
8578  
8579                  if ( elem === elem.ownerDocument.body ) {
8580                          return jQuery.offset.bodyOffset( elem );
8581                  }
8582  
8583                  try {
8584                          box = elem.getBoundingClientRect();
8585                  } catch(e) {}
8586  
8587                  var doc = elem.ownerDocument,
8588                          docElem = doc.documentElement;
8589  
8590                  // Make sure we're not dealing with a disconnected DOM node
8591                  if ( !box || !jQuery.contains( docElem, elem ) ) {
8592                          return box ? { top: box.top, left: box.left } : { top: 0, left: 0 };
8593                  }
8594  
8595                  var body = doc.body,
8596                          win = getWindow(doc),
8597                          clientTop  = docElem.clientTop  || body.clientTop  || 0,
8598                          clientLeft = docElem.clientLeft || body.clientLeft || 0,
8599                          scrollTop  = win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop  || body.scrollTop,
8600                          scrollLeft = win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft,
8601                          top  = box.top  + scrollTop  - clientTop,
8602                          left = box.left + scrollLeft - clientLeft;
8603  
8604                  return { top: top, left: left };
8605          };
8606  
8607  } else {
8608          jQuery.fn.offset = function( options ) {
8609                  var elem = this[0];
8610  
8611                  if ( options ) {
8612                          return this.each(function( i ) {
8613                                  jQuery.offset.setOffset( this, options, i );
8614                          });
8615                  }
8616  
8617                  if ( !elem || !elem.ownerDocument ) {
8618                          return null;
8619                  }
8620  
8621                  if ( elem === elem.ownerDocument.body ) {
8622                          return jQuery.offset.bodyOffset( elem );
8623                  }
8624  
8625                  jQuery.offset.initialize();
8626  
8627                  var computedStyle,
8628                          offsetParent = elem.offsetParent,
8629                          prevOffsetParent = elem,
8630                          doc = elem.ownerDocument,
8631                          docElem = doc.documentElement,
8632                          body = doc.body,
8633                          defaultView = doc.defaultView,
8634                          prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle,
8635                          top = elem.offsetTop,
8636                          left = elem.offsetLeft;
8637  
8638                  while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
8639                          if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
8640                                  break;
8641                          }
8642  
8643                          computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle;
8644                          top  -= elem.scrollTop;
8645                          left -= elem.scrollLeft;
8646  
8647                          if ( elem === offsetParent ) {
8648                                  top  += elem.offsetTop;
8649                                  left += elem.offsetLeft;
8650  
8651                                  if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && rtable.test(elem.nodeName)) ) {
8652                                          top  += parseFloat( computedStyle.borderTopWidth  ) || 0;
8653                                          left += parseFloat( computedStyle.borderLeftWidth ) || 0;
8654                                  }
8655  
8656                                  prevOffsetParent = offsetParent;
8657                                  offsetParent = elem.offsetParent;
8658                          }
8659  
8660                          if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) {
8661                                  top  += parseFloat( computedStyle.borderTopWidth  ) || 0;
8662                                  left += parseFloat( computedStyle.borderLeftWidth ) || 0;
8663                          }
8664  
8665                          prevComputedStyle = computedStyle;
8666                  }
8667  
8668                  if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) {
8669                          top  += body.offsetTop;
8670                          left += body.offsetLeft;
8671                  }
8672  
8673                  if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
8674                          top  += Math.max( docElem.scrollTop, body.scrollTop );
8675                          left += Math.max( docElem.scrollLeft, body.scrollLeft );
8676                  }
8677  
8678                  return { top: top, left: left };
8679          };
8680  }
8681  
8682  jQuery.offset = {
8683          initialize: function() {
8684                  var body = document.body, container = document.createElement("div"), innerDiv, checkDiv, table, td, bodyMarginTop = parseFloat( jQuery.css(body, "marginTop") ) || 0,
8685                          html = "<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";
8686  
8687                  jQuery.extend( container.style, { position: "absolute", top: 0, left: 0, margin: 0, border: 0, width: "1px", height: "1px", visibility: "hidden" } );
8688  
8689                  container.innerHTML = html;
8690                  body.insertBefore( container, body.firstChild );
8691                  innerDiv = container.firstChild;
8692                  checkDiv = innerDiv.firstChild;
8693                  td = innerDiv.nextSibling.firstChild.firstChild;
8694  
8695                  this.doesNotAddBorder = (checkDiv.offsetTop !== 5);
8696                  this.doesAddBorderForTableAndCells = (td.offsetTop === 5);
8697  
8698                  checkDiv.style.position = "fixed";
8699                  checkDiv.style.top = "20px";
8700  
8701                  // safari subtracts parent border width here which is 5px
8702                  this.supportsFixedPosition = (checkDiv.offsetTop === 20 || checkDiv.offsetTop === 15);
8703                  checkDiv.style.position = checkDiv.style.top = "";
8704  
8705                  innerDiv.style.overflow = "hidden";
8706                  innerDiv.style.position = "relative";
8707  
8708                  this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5);
8709  
8710                  this.doesNotIncludeMarginInBodyOffset = (body.offsetTop !== bodyMarginTop);
8711  
8712                  body.removeChild( container );
8713                  jQuery.offset.initialize = jQuery.noop;
8714          },
8715  
8716          bodyOffset: function( body ) {
8717                  var top = body.offsetTop,
8718                          left = body.offsetLeft;
8719  
8720                  jQuery.offset.initialize();
8721  
8722                  if ( jQuery.offset.doesNotIncludeMarginInBodyOffset ) {
8723                          top  += parseFloat( jQuery.css(body, "marginTop") ) || 0;
8724                          left += parseFloat( jQuery.css(body, "marginLeft") ) || 0;
8725                  }
8726  
8727                  return { top: top, left: left };
8728          },
8729  
8730          setOffset: function( elem, options, i ) {
8731                  var position = jQuery.css( elem, "position" );
8732  
8733                  // set position first, in-case top/left are set even on static elem
8734                  if ( position === "static" ) {
8735                          elem.style.position = "relative";
8736                  }
8737  
8738                  var curElem = jQuery( elem ),
8739                          curOffset = curElem.offset(),
8740                          curCSSTop = jQuery.css( elem, "top" ),
8741                          curCSSLeft = jQuery.css( elem, "left" ),
8742                          calculatePosition = (position === "absolute" || position === "fixed") && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1,
8743                          props = {}, curPosition = {}, curTop, curLeft;
8744  
8745                  // need to be able to calculate position if either top or left is auto and position is either absolute or fixed
8746                  if ( calculatePosition ) {
8747                          curPosition = curElem.position();
8748                          curTop = curPosition.top;
8749                          curLeft = curPosition.left;
8750                  } else {
8751                          curTop = parseFloat( curCSSTop ) || 0;
8752                          curLeft = parseFloat( curCSSLeft ) || 0;
8753                  }
8754  
8755                  if ( jQuery.isFunction( options ) ) {
8756                          options = options.call( elem, i, curOffset );
8757                  }
8758  
8759                  if (options.top != null) {
8760                          props.top = (options.top - curOffset.top) + curTop;
8761                  }
8762                  if (options.left != null) {
8763                          props.left = (options.left - curOffset.left) + curLeft;
8764                  }
8765  
8766                  if ( "using" in options ) {
8767                          options.using.call( elem, props );
8768                  } else {
8769                          curElem.css( props );
8770                  }
8771          }
8772  };
8773  
8774  
8775  jQuery.fn.extend({
8776          position: function() {
8777                  if ( !this[0] ) {
8778                          return null;
8779                  }
8780  
8781                  var elem = this[0],
8782  
8783                  // Get *real* offsetParent
8784                  offsetParent = this.offsetParent(),
8785  
8786                  // Get correct offsets
8787                  offset       = this.offset(),
8788                  parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();
8789  
8790                  // Subtract element margins
8791                  // note: when an element has margin: auto the offsetLeft and marginLeft
8792                  // are the same in Safari causing offset.left to incorrectly be 0
8793                  offset.top  -= parseFloat( jQuery.css(elem, "marginTop") ) || 0;
8794                  offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0;
8795  
8796                  // Add offsetParent borders
8797                  parentOffset.top  += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0;
8798                  parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0;
8799  
8800                  // Subtract the two offsets
8801                  return {
8802                          top:  offset.top  - parentOffset.top,
8803                          left: offset.left - parentOffset.left
8804                  };
8805          },
8806  
8807          offsetParent: function() {
8808                  return this.map(function() {
8809                          var offsetParent = this.offsetParent || document.body;
8810                          while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) {
8811                                  offsetParent = offsetParent.offsetParent;
8812                          }
8813                          return offsetParent;
8814                  });
8815          }
8816  });
8817  
8818  
8819  // Create scrollLeft and scrollTop methods
8820  jQuery.each( ["Left", "Top"], function( i, name ) {
8821          var method = "scroll" + name;
8822  
8823          jQuery.fn[ method ] = function( val ) {
8824                  var elem, win;
8825  
8826                  if ( val === undefined ) {
8827                          elem = this[ 0 ];
8828  
8829                          if ( !elem ) {
8830                                  return null;
8831                          }
8832  
8833                          win = getWindow( elem );
8834  
8835                          // Return the scroll offset
8836                          return win ? ("pageXOffset" in win) ? win[ i ? "pageYOffset" : "pageXOffset" ] :
8837                                  jQuery.support.boxModel && win.document.documentElement[ method ] ||
8838                                          win.document.body[ method ] :
8839                                  elem[ method ];
8840                  }
8841  
8842                  // Set the scroll offset
8843                  return this.each(function() {
8844                          win = getWindow( this );
8845  
8846                          if ( win ) {
8847                                  win.scrollTo(
8848                                          !i ? val : jQuery( win ).scrollLeft(),
8849                                           i ? val : jQuery( win ).scrollTop()
8850                                  );
8851  
8852                          } else {
8853                                  this[ method ] = val;
8854                          }
8855                  });
8856          };
8857  });
8858  
8859  function getWindow( elem ) {
8860          return jQuery.isWindow( elem ) ?
8861                  elem :
8862                  elem.nodeType === 9 ?
8863                          elem.defaultView || elem.parentWindow :
8864                          false;
8865  }
8866  
8867  
8868  
8869  
8870  // Create innerHeight, innerWidth, outerHeight and outerWidth methods
8871  jQuery.each([ "Height", "Width" ], function( i, name ) {
8872  
8873          var type = name.toLowerCase();
8874  
8875          // innerHeight and innerWidth
8876          jQuery.fn["inner" + name] = function() {
8877                  return this[0] ?
8878                          parseFloat( jQuery.css( this[0], type, "padding" ) ) :
8879                          null;
8880          };
8881  
8882          // outerHeight and outerWidth
8883          jQuery.fn["outer" + name] = function( margin ) {
8884                  return this[0] ?
8885                          parseFloat( jQuery.css( this[0], type, margin ? "margin" : "border" ) ) :
8886                          null;
8887          };
8888  
8889          jQuery.fn[ type ] = function( size ) {
8890                  // Get window width or height
8891                  var elem = this[0];
8892                  if ( !elem ) {
8893                          return size == null ? null : this;
8894                  }
8895  
8896                  if ( jQuery.isFunction( size ) ) {
8897                          return this.each(function( i ) {
8898                                  var self = jQuery( this );
8899                                  self[ type ]( size.call( this, i, self[ type ]() ) );
8900                          });
8901                  }
8902  
8903                  if ( jQuery.isWindow( elem ) ) {
8904                          // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
8905                          // 3rd condition allows Nokia support, as it supports the docElem prop but not CSS1Compat
8906                          var docElemProp = elem.document.documentElement[ "client" + name ];
8907                          return elem.document.compatMode === "CSS1Compat" && docElemProp ||
8908                                  elem.document.body[ "client" + name ] || docElemProp;
8909  
8910                  // Get document width or height
8911                  } else if ( elem.nodeType === 9 ) {
8912                          // Either scroll[Width/Height] or offset[Width/Height], whichever is greater
8913                          return Math.max(
8914                                  elem.documentElement["client" + name],
8915                                  elem.body["scroll" + name], elem.documentElement["scroll" + name],
8916                                  elem.body["offset" + name], elem.documentElement["offset" + name]
8917                          );
8918  
8919                  // Get or set width or height on the element
8920                  } else if ( size === undefined ) {
8921                          var orig = jQuery.css( elem, type ),
8922                                  ret = parseFloat( orig );
8923  
8924                          return jQuery.isNaN( ret ) ? orig : ret;
8925  
8926                  // Set the width or height on the element (default to pixels if value is unitless)
8927                  } else {
8928                          return this.css( type, typeof size === "string" ? size : size + "px" );
8929                  }
8930          };
8931  
8932  });
8933  
8934  
8935  window.jQuery = window.$ = jQuery;
8936  })(window);
1 /*! 2 * jQuery JavaScript Library v1.6.1 3 * http://jquery.com/ 4 * 5 * Copyright 2011, John Resig 6 * Dual licensed under the MIT or GPL Version 2 licenses. 7 * http://jquery.org/license 8 * 9 * Includes Sizzle.js 10 * http://sizzlejs.com/ 11 * Copyright 2011, The Dojo Foundation 12 * Released under the MIT, BSD, and GPL Licenses. 13 * 14 * Date: Thu May 12 15:04:36 2011 -0400 15 */ 16 (function( window, undefined ) { 17 18 // Use the correct document accordingly with window argument (sandbox) 19 var document = window.document, 20 navigator = window.navigator, 21 location = window.location; 22 var jQuery = (function() { 23 24 // Define a local copy of jQuery 25 var jQuery = function( selector, context ) { 26 // The jQuery object is actually just the init constructor 'enhanced' 27 return new jQuery.fn.init( selector, context, rootjQuery ); 28 }, 29 30 // Map over jQuery in case of overwrite 31 _jQuery = window.jQuery, 32 33 // Map over the $ in case of overwrite 34 _$ = window.$, 35 36 // A central reference to the root jQuery(document) 37 rootjQuery, 38 39 // A simple way to check for HTML strings or ID strings 40 // (both of which we optimize for) 41 quickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/, 42 43 // Check if a string has a non-whitespace character in it 44 rnotwhite = /\S/, 45 46 // Used for trimming whitespace 47 trimLeft = /^\s+/, 48 trimRight = /\s+$/, 49 50 // Check for digits 51 rdigit = /\d/, 52 53 // Match a standalone tag 54 rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/, 55 56 // JSON RegExp 57 rvalidchars = /^[\],:{}\s]*$/, 58 rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, 59 rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, 60 rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, 61 62 // Useragent RegExp 63 rwebkit = /(webkit)[ \/]([\w.]+)/, 64 ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/, 65 rmsie = /(msie) ([\w.]+)/, 66 rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/, 67 68 // Keep a UserAgent string for use with jQuery.browser 69 userAgent = navigator.userAgent, 70 71 // For matching the engine and version of the browser 72 browserMatch, 73 74 // The deferred used on DOM ready 75 readyList, 76 77 // The ready event handler 78 DOMContentLoaded, 79 80 // Save a reference to some core methods 81 toString = Object.prototype.toString, 82 hasOwn = Object.prototype.hasOwnProperty, 83 push = Array.prototype.push, 84 slice = Array.prototype.slice, 85 trim = String.prototype.trim, 86 indexOf = Array.prototype.indexOf, 87 88 // [[Class]] -> type pairs 89 class2type = {}; 90 91 jQuery.fn = jQuery.prototype = { 92 constructor: jQuery, 93 init: function( selector, context, rootjQuery ) { 94 var match, elem, ret, doc; 95 96 // Handle $(""), $(null), or $(undefined) 97 if ( !selector ) { 98 return this; 99 } 100 101 // Handle $(DOMElement) 102 if ( selector.nodeType ) { 103 this.context = this[0] = selector; 104 this.length = 1; 105 return this; 106 } 107 108 // The body element only exists once, optimize finding it 109 if ( selector === "body" && !context && document.body ) { 110 this.context = document; 111 this[0] = document.body; 112 this.selector = selector; 113 this.length = 1; 114 return this; 115 } 116 117 // Handle HTML strings 118 if ( typeof selector === "string" ) { 119 // Are we dealing with HTML string or an ID? 120 if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { 121 // Assume that strings that start and end with <> are HTML and skip the regex check 122 match = [ null, selector, null ]; 123 124 } else { 125 match = quickExpr.exec( selector ); 126 } 127 128 // Verify a match, and that no context was specified for #id 129 if ( match && (match[1] || !context) ) { 130 131 // HANDLE: $(html) -> $(array) 132 if ( match[1] ) { 133 context = context instanceof jQuery ? context[0] : context; 134 doc = (context ? context.ownerDocument || context : document); 135 136 // If a single string is passed in and it's a single tag 137 // just do a createElement and skip the rest 138 ret = rsingleTag.exec( selector ); 139 140 if ( ret ) { 141 if ( jQuery.isPlainObject( context ) ) { 142 selector = [ document.createElement( ret[1] ) ]; 143 jQuery.fn.attr.call( selector, context, true ); 144 145 } else { 146 selector = [ doc.createElement( ret[1] ) ]; 147 } 148 149 } else { 150 ret = jQuery.buildFragment( [ match[1] ], [ doc ] ); 151 selector = (ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment).childNodes; 152 } 153 154 return jQuery.merge( this, selector ); 155 156 // HANDLE: $("#id") 157 } else { 158 elem = document.getElementById( match[2] ); 159 160 // Check parentNode to catch when Blackberry 4.6 returns 161 // nodes that are no longer in the document #6963 162 if ( elem && elem.parentNode ) { 163 // Handle the case where IE and Opera return items 164 // by name instead of ID 165 if ( elem.id !== match[2] ) { 166 return rootjQuery.find( selector ); 167 } 168 169 // Otherwise, we inject the element directly into the jQuery object 170 this.length = 1; 171 this[0] = elem; 172 } 173 174 this.context = document; 175 this.selector = selector; 176 return this; 177 } 178 179 // HANDLE: $(expr, $(...)) 180 } else if ( !context || context.jquery ) { 181 return (context || rootjQuery).find( selector ); 182 183 // HANDLE: $(expr, context) 184 // (which is just equivalent to: $(context).find(expr) 185 } else { 186 return this.constructor( context ).find( selector ); 187 } 188 189 // HANDLE: $(function) 190 // Shortcut for document ready 191 } else if ( jQuery.isFunction( selector ) ) { 192 return rootjQuery.ready( selector ); 193 } 194 195 if (selector.selector !== undefined) { 196 this.selector = selector.selector; 197 this.context = selector.context; 198 } 199 200 return jQuery.makeArray( selector, this ); 201 }, 202 203 // Start with an empty selector 204 selector: "", 205 206 // The current version of jQuery being used 207 jquery: "1.6.1", 208 209 // The default length of a jQuery object is 0 210 length: 0, 211 212 // The number of elements contained in the matched element set 213 size: function() { 214 return this.length; 215 }, 216 217 toArray: function() { 218 return slice.call( this, 0 ); 219 }, 220 221 // Get the Nth element in the matched element set OR 222 // Get the whole matched element set as a clean array 223 get: function( num ) { 224 return num == null ? 225 226 // Return a 'clean' array 227 this.toArray() : 228 229 // Return just the object 230 ( num < 0 ? this[ this.length + num ] : this[ num ] ); 231 }, 232 233 // Take an array of elements and push it onto the stack 234 // (returning the new matched element set) 235 pushStack: function( elems, name, selector ) { 236 // Build a new jQuery matched element set 237 var ret = this.constructor(); 238 239 if ( jQuery.isArray( elems ) ) { 240 push.apply( ret, elems ); 241 242 } else { 243 jQuery.merge( ret, elems ); 244 } 245 246 // Add the old object onto the stack (as a reference) 247 ret.prevObject = this; 248 249 ret.context = this.context; 250 251 if ( name === "find" ) { 252 ret.selector = this.selector + (this.selector ? " " : "") + selector; 253 } else if ( name ) { 254 ret.selector = this.selector + "." + name + "(" + selector + ")"; 255 } 256 257 // Return the newly-formed element set 258 return ret; 259 }, 260 261 // Execute a callback for every element in the matched set. 262 // (You can seed the arguments with an array of args, but this is 263 // only used internally.) 264 each: function( callback, args ) { 265 return jQuery.each( this, callback, args ); 266 }, 267 268 ready: function( fn ) { 269 // Attach the listeners 270 jQuery.bindReady(); 271 272 // Add the callback 273 readyList.done( fn ); 274 275 return this; 276 }, 277 278 eq: function( i ) { 279 return i === -1 ? 280 this.slice( i ) : 281 this.slice( i, +i + 1 ); 282 }, 283 284 first: function() { 285 return this.eq( 0 ); 286 }, 287 288 last: function() { 289 return this.eq( -1 ); 290 }, 291 292 slice: function() { 293 return this.pushStack( slice.apply( this, arguments ), 294 "slice", slice.call(arguments).join(",") ); 295 }, 296 297 map: function( callback ) { 298 return this.pushStack( jQuery.map(this, function( elem, i ) { 299 return callback.call( elem, i, elem ); 300 })); 301 }, 302 303 end: function() { 304 return this.prevObject || this.constructor(null); 305 }, 306 307 // For internal use only. 308 // Behaves like an Array's method, not like a jQuery method. 309 push: push, 310 sort: [].sort, 311 splice: [].splice 312 }; 313 314 // Give the init function the jQuery prototype for later instantiation 315 jQuery.fn.init.prototype = jQuery.fn; 316 317 jQuery.extend = jQuery.fn.extend = function() { 318 var options, name, src, copy, copyIsArray, clone, 319 target = arguments[0] || {}, 320 i = 1, 321 length = arguments.length, 322 deep = false; 323 324 // Handle a deep copy situation 325 if ( typeof target === "boolean" ) { 326 deep = target; 327 target = arguments[1] || {}; 328 // skip the boolean and the target 329 i = 2; 330 } 331 332 // Handle case when target is a string or something (possible in deep copy) 333 if ( typeof target !== "object" && !jQuery.isFunction(target) ) { 334 target = {}; 335 } 336 337 // extend jQuery itself if only one argument is passed 338 if ( length === i ) { 339 target = this; 340 --i; 341 } 342 343 for ( ; i < length; i++ ) { 344 // Only deal with non-null/undefined values 345 if ( (options = arguments[ i ]) != null ) { 346 // Extend the base object 347 for ( name in options ) { 348 src = target[ name ]; 349 copy = options[ name ]; 350 351 // Prevent never-ending loop 352 if ( target === copy ) { 353 continue; 354 } 355 356 // Recurse if we're merging plain objects or arrays 357 if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { 358 if ( copyIsArray ) { 359 copyIsArray = false; 360 clone = src && jQuery.isArray(src) ? src : []; 361 362 } else { 363 clone = src && jQuery.isPlainObject(src) ? src : {}; 364 } 365 366 // Never move original objects, clone them 367 target[ name ] = jQuery.extend( deep, clone, copy ); 368 369 // Don't bring in undefined values 370 } else if ( copy !== undefined ) { 371 target[ name ] = copy; 372 } 373 } 374 } 375 } 376 377 // Return the modified object 378 return target; 379 }; 380 381 jQuery.extend({ 382 noConflict: function( deep ) { 383 if ( window.$ === jQuery ) { 384 window.$ = _$; 385 } 386 387 if ( deep && window.jQuery === jQuery ) { 388 window.jQuery = _jQuery; 389 } 390 391 return jQuery; 392 }, 393 394 // Is the DOM ready to be used? Set to true once it occurs. 395 isReady: false, 396 397 // A counter to track how many items to wait for before 398 // the ready event fires. See #6781 399 readyWait: 1, 400 401 // Hold (or release) the ready event 402 holdReady: function( hold ) { 403 if ( hold ) { 404 jQuery.readyWait++; 405 } else { 406 jQuery.ready( true ); 407 } 408 }, 409 410 // Handle when the DOM is ready 411 ready: function( wait ) { 412 // Either a released hold or an DOMready/load event and not yet ready 413 if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) { 414 // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). 415 if ( !document.body ) { 416 return setTimeout( jQuery.ready, 1 ); 417 } 418 419 // Remember that the DOM is ready 420 jQuery.isReady = true; 421 422 // If a normal DOM Ready event fired, decrement, and wait if need be 423 if ( wait !== true && --jQuery.readyWait > 0 ) { 424 return; 425 } 426 427 // If there are functions bound, to execute 428 readyList.resolveWith( document, [ jQuery ] ); 429 430 // Trigger any bound ready events 431 if ( jQuery.fn.trigger ) { 432 jQuery( document ).trigger( "ready" ).unbind( "ready" ); 433 } 434 } 435 }, 436 437 bindReady: function() { 438 if ( readyList ) { 439 return; 440 } 441 442 readyList = jQuery._Deferred(); 443 444 // Catch cases where $(document).ready() is called after the 445 // browser event has already occurred. 446 if ( document.readyState === "complete" ) { 447 // Handle it asynchronously to allow scripts the opportunity to delay ready 448 return setTimeout( jQuery.ready, 1 ); 449 } 450 451 // Mozilla, Opera and webkit nightlies currently support this event 452 if ( document.addEventListener ) { 453 // Use the handy event callback 454 document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false ); 455 456 // A fallback to window.onload, that will always work 457 window.addEventListener( "load", jQuery.ready, false ); 458 459 // If IE event model is used 460 } else if ( document.attachEvent ) { 461 // ensure firing before onload, 462 // maybe late but safe also for iframes 463 document.attachEvent( "onreadystatechange", DOMContentLoaded ); 464 465 // A fallback to window.onload, that will always work 466 window.attachEvent( "onload", jQuery.ready ); 467 468 // If IE and not a frame 469 // continually check to see if the document is ready 470 var toplevel = false; 471 472 try { 473 toplevel = window.frameElement == null; 474 } catch(e) {} 475 476 if ( document.documentElement.doScroll && toplevel ) { 477 doScrollCheck(); 478 } 479 } 480 }, 481 482 // See test/unit/core.js for details concerning isFunction. 483 // Since version 1.3, DOM methods and functions like alert 484 // aren't supported. They return false on IE (#2968). 485 isFunction: function( obj ) { 486 return jQuery.type(obj) === "function"; 487 }, 488 489 isArray: Array.isArray || function( obj ) { 490 return jQuery.type(obj) === "array"; 491 }, 492 493 // A crude way of determining if an object is a window 494 isWindow: function( obj ) { 495 return obj && typeof obj === "object" && "setInterval" in obj; 496 }, 497 498 isNaN: function( obj ) { 499 return obj == null || !rdigit.test( obj ) || isNaN( obj ); 500 }, 501 502 type: function( obj ) { 503 return obj == null ? 504 String( obj ) : 505 class2type[ toString.call(obj) ] || "object"; 506 }, 507 508 isPlainObject: function( obj ) { 509 // Must be an Object. 510 // Because of IE, we also have to check the presence of the constructor property. 511 // Make sure that DOM nodes and window objects don't pass through, as well 512 if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { 513 return false; 514 } 515 516 // Not own constructor property must be Object 517 if ( obj.constructor && 518 !hasOwn.call(obj, "constructor") && 519 !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { 520 return false; 521 } 522 523 // Own properties are enumerated firstly, so to speed up, 524 // if last one is own, then all properties are own. 525 526 var key; 527 for ( key in obj ) {} 528 529 return key === undefined || hasOwn.call( obj, key ); 530 }, 531 532 isEmptyObject: function( obj ) { 533 for ( var name in obj ) { 534 return false; 535 } 536 return true; 537 }, 538 539 error: function( msg ) { 540 throw msg; 541 }, 542 543 parseJSON: function( data ) { 544 if ( typeof data !== "string" || !data ) { 545 return null; 546 } 547 548 // Make sure leading/trailing whitespace is removed (IE can't handle it) 549 data = jQuery.trim( data ); 550 551 // Attempt to parse using the native JSON parser first 552 if ( window.JSON && window.JSON.parse ) { 553 return window.JSON.parse( data ); 554 } 555 556 // Make sure the incoming data is actual JSON 557 // Logic borrowed from http://json.org/json2.js 558 if ( rvalidchars.test( data.replace( rvalidescape, "@" ) 559 .replace( rvalidtokens, "]" ) 560 .replace( rvalidbraces, "")) ) { 561 562 return (new Function( "return " + data ))(); 563 564 } 565 jQuery.error( "Invalid JSON: " + data ); 566 }, 567 568 // Cross-browser xml parsing 569 // (xml & tmp used internally) 570 parseXML: function( data , xml , tmp ) { 571 572 if ( window.DOMParser ) { // Standard 573 tmp = new DOMParser(); 574 xml = tmp.parseFromString( data , "text/xml" ); 575 } else { // IE 576 xml = new ActiveXObject( "Microsoft.XMLDOM" ); 577 xml.async = "false"; 578 xml.loadXML( data ); 579 } 580 581 tmp = xml.documentElement; 582 583 if ( ! tmp || ! tmp.nodeName || tmp.nodeName === "parsererror" ) { 584 jQuery.error( "Invalid XML: " + data ); 585 } 586 587 return xml; 588 }, 589 590 noop: function() {}, 591 592 // Evaluates a script in a global context 593 // Workarounds based on findings by Jim Driscoll 594 // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context 595 globalEval: function( data ) { 596 if ( data && rnotwhite.test( data ) ) { 597 // We use execScript on Internet Explorer 598 // We use an anonymous function so that context is window 599 // rather than jQuery in Firefox 600 ( window.execScript || function( data ) { 601 window[ "eval" ].call( window, data ); 602 } )( data ); 603 } 604 }, 605 606 nodeName: function( elem, name ) { 607 return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase(); 608 }, 609 610 // args is for internal usage only 611 each: function( object, callback, args ) { 612 var name, i = 0, 613 length = object.length, 614 isObj = length === undefined || jQuery.isFunction( object ); 615 616 if ( args ) { 617 if ( isObj ) { 618 for ( name in object ) { 619 if ( callback.apply( object[ name ], args ) === false ) { 620 break; 621 } 622 } 623 } else { 624 for ( ; i < length; ) { 625 if ( callback.apply( object[ i++ ], args ) === false ) { 626 break; 627 } 628 } 629 } 630 631 // A special, fast, case for the most common use of each 632 } else { 633 if ( isObj ) { 634 for ( name in object ) { 635 if ( callback.call( object[ name ], name, object[ name ] ) === false ) { 636 break; 637 } 638 } 639 } else { 640 for ( ; i < length; ) { 641 if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) { 642 break; 643 } 644 } 645 } 646 } 647 648 return object; 649 }, 650 651 // Use native String.trim function wherever possible 652 trim: trim ? 653 function( text ) { 654 return text == null ? 655 "" : 656 trim.call( text ); 657 } : 658 659 // Otherwise use our own trimming functionality 660 function( text ) { 661 return text == null ? 662 "" : 663 text.toString().replace( trimLeft, "" ).replace( trimRight, "" ); 664 }, 665 666 // results is for internal usage only 667 makeArray: function( array, results ) { 668 var ret = results || []; 669 670 if ( array != null ) { 671 // The window, strings (and functions) also have 'length' 672 // The extra typeof function check is to prevent crashes 673 // in Safari 2 (See: #3039) 674 // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930 675 var type = jQuery.type( array ); 676 677 if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) { 678 push.call( ret, array ); 679 } else { 680 jQuery.merge( ret, array ); 681 } 682 } 683 684 return ret; 685 }, 686 687 inArray: function( elem, array ) { 688 689 if ( indexOf ) { 690 return indexOf.call( array, elem ); 691 } 692 693 for ( var i = 0, length = array.length; i < length; i++ ) { 694 if ( array[ i ] === elem ) { 695 return i; 696 } 697 } 698 699 return -1; 700 }, 701 702 merge: function( first, second ) { 703 var i = first.length, 704 j = 0; 705 706 if ( typeof second.length === "number" ) { 707 for ( var l = second.length; j < l; j++ ) { 708 first[ i++ ] = second[ j ]; 709 } 710 711 } else { 712 while ( second[j] !== undefined ) { 713 first[ i++ ] = second[ j++ ]; 714 } 715 } 716 717 first.length = i; 718 719 return first; 720 }, 721 722 grep: function( elems, callback, inv ) { 723 var ret = [], retVal; 724 inv = !!inv; 725 726 // Go through the array, only saving the items 727 // that pass the validator function 728 for ( var i = 0, length = elems.length; i < length; i++ ) { 729 retVal = !!callback( elems[ i ], i ); 730 if ( inv !== retVal ) { 731 ret.push( elems[ i ] ); 732 } 733 } 734 735 return ret; 736 }, 737 738 // arg is for internal usage only 739 map: function( elems, callback, arg ) { 740 var value, key, ret = [], 741 i = 0, 742 length = elems.length, 743 // jquery objects are treated as arrays 744 isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ; 745 746 // Go through the array, translating each of the items to their 747 if ( isArray ) { 748 for ( ; i < length; i++ ) { 749 value = callback( elems[ i ], i, arg ); 750 751 if ( value != null ) { 752 ret[ ret.length ] = value; 753 } 754 } 755 756 // Go through every key on the object, 757 } else { 758 for ( key in elems ) { 759 value = callback( elems[ key ], key, arg ); 760 761 if ( value != null ) { 762 ret[ ret.length ] = value; 763 } 764 } 765 } 766 767 // Flatten any nested arrays 768 return ret.concat.apply( [], ret ); 769 }, 770 771 // A global GUID counter for objects 772 guid: 1, 773 774 // Bind a function to a context, optionally partially applying any 775 // arguments. 776 proxy: function( fn, context ) { 777 if ( typeof context === "string" ) { 778 var tmp = fn[ context ]; 779 context = fn; 780 fn = tmp; 781 } 782 783 // Quick check to determine if target is callable, in the spec 784 // this throws a TypeError, but we will just return undefined. 785 if ( !jQuery.isFunction( fn ) ) { 786 return undefined; 787 } 788 789 // Simulated bind 790 var args = slice.call( arguments, 2 ), 791 proxy = function() { 792 return fn.apply( context, args.concat( slice.call( arguments ) ) ); 793 }; 794 795 // Set the guid of unique handler to the same of original handler, so it can be removed 796 proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++; 797 798 return proxy; 799 }, 800 801 // Mutifunctional method to get and set values to a collection 802 // The value/s can be optionally by executed if its a function 803 access: function( elems, key, value, exec, fn, pass ) { 804 var length = elems.length; 805 806 // Setting many attributes 807 if ( typeof key === "object" ) { 808 for ( var k in key ) { 809 jQuery.access( elems, k, key[k], exec, fn, value ); 810 } 811 return elems; 812 } 813 814 // Setting one attribute 815 if ( value !== undefined ) { 816 // Optionally, function values get executed if exec is true 817 exec = !pass && exec && jQuery.isFunction(value); 818 819 for ( var i = 0; i < length; i++ ) { 820 fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass ); 821 } 822 823 return elems; 824 } 825 826 // Getting an attribute 827 return length ? fn( elems[0], key ) : undefined; 828 }, 829 830 now: function() { 831 return (new Date()).getTime(); 832 }, 833 834 // Use of jQuery.browser is frowned upon. 835 // More details: http://docs.jquery.com/Utilities/jQuery.browser 836 uaMatch: function( ua ) { 837 ua = ua.toLowerCase(); 838 839 var match = rwebkit.exec( ua ) || 840 ropera.exec( ua ) || 841 rmsie.exec( ua ) || 842 ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) || 843 []; 844 845 return { browser: match[1] || "", version: match[2] || "0" }; 846 }, 847 848 sub: function() { 849 function jQuerySub( selector, context ) { 850 return new jQuerySub.fn.init( selector, context ); 851 } 852 jQuery.extend( true, jQuerySub, this ); 853 jQuerySub.superclass = this; 854 jQuerySub.fn = jQuerySub.prototype = this(); 855 jQuerySub.fn.constructor = jQuerySub; 856 jQuerySub.sub = this.sub; 857 jQuerySub.fn.init = function init( selector, context ) { 858 if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) { 859 context = jQuerySub( context ); 860 } 861 862 return jQuery.fn.init.call( this, selector, context, rootjQuerySub ); 863 }; 864 jQuerySub.fn.init.prototype = jQuerySub.fn; 865 var rootjQuerySub = jQuerySub(document); 866 return jQuerySub; 867 }, 868 869 browser: {} 870 }); 871 872 // Populate the class2type map 873 jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) { 874 class2type[ "[object " + name + "]" ] = name.toLowerCase(); 875 }); 876 877 browserMatch = jQuery.uaMatch( userAgent ); 878 if ( browserMatch.browser ) { 879 jQuery.browser[ browserMatch.browser ] = true; 880 jQuery.browser.version = browserMatch.version; 881 } 882 883 // Deprecated, use jQuery.browser.webkit instead 884 if ( jQuery.browser.webkit ) { 885 jQuery.browser.safari = true; 886 } 887 888 // IE doesn't match non-breaking spaces with \s 889 if ( rnotwhite.test( "\xA0" ) ) { 890 trimLeft = /^[\s\xA0]+/; 891 trimRight = /[\s\xA0]+$/; 892 } 893 894 // All jQuery objects should point back to these 895 rootjQuery = jQuery(document); 896 897 // Cleanup functions for the document ready method 898 if ( document.addEventListener ) { 899 DOMContentLoaded = function() { 900 document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false ); 901 jQuery.ready(); 902 }; 903 904 } else if ( document.attachEvent ) { 905 DOMContentLoaded = function() { 906 // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). 907 if ( document.readyState === "complete" ) { 908 document.detachEvent( "onreadystatechange", DOMContentLoaded ); 909 jQuery.ready(); 910 } 911 }; 912 } 913 914 // The DOM ready check for Internet Explorer 915 function doScrollCheck() { 916 if ( jQuery.isReady ) { 917 return; 918 } 919 920 try { 921 // If IE is used, use the trick by Diego Perini 922 // http://javascript.nwbox.com/IEContentLoaded/ 923 document.documentElement.doScroll("left"); 924 } catch(e) { 925 setTimeout( doScrollCheck, 1 ); 926 return; 927 } 928 929 // and execute any waiting functions 930 jQuery.ready(); 931 } 932 933 // Expose jQuery to the global object 934 return jQuery; 935 936 })(); 937 938 939 var // Promise methods 940 promiseMethods = "done fail isResolved isRejected promise then always pipe".split( " " ), 941 // Static reference to slice 942 sliceDeferred = [].slice; 943 944 jQuery.extend({ 945 // Create a simple deferred (one callbacks list) 946 _Deferred: function() { 947 var // callbacks list 948 callbacks = [], 949 // stored [ context , args ] 950 fired, 951 // to avoid firing when already doing so 952 firing, 953 // flag to know if the deferred has been cancelled 954 cancelled, 955 // the deferred itself 956 deferred = { 957 958 // done( f1, f2, ...) 959 done: function() { 960 if ( !cancelled ) { 961 var args = arguments, 962 i, 963 length, 964 elem, 965 type, 966 _fired; 967 if ( fired ) { 968 _fired = fired; 969 fired = 0; 970 } 971 for ( i = 0, length = args.length; i < length; i++ ) { 972 elem = args[ i ]; 973 type = jQuery.type( elem ); 974 if ( type === "array" ) { 975 deferred.done.apply( deferred, elem ); 976 } else if ( type === "function" ) { 977 callbacks.push( elem ); 978 } 979 } 980 if ( _fired ) { 981 deferred.resolveWith( _fired[ 0 ], _fired[ 1 ] ); 982 } 983 } 984 return this; 985 }, 986 987 // resolve with given context and args 988 resolveWith: function( context, args ) { 989 if ( !cancelled && !fired && !firing ) { 990 // make sure args are available (#8421) 991 args = args || []; 992 firing = 1; 993 try { 994 while( callbacks[ 0 ] ) { 995 callbacks.shift().apply( context, args ); 996 } 997 } 998 finally { 999 fired = [ context, args ]; 1000 firing = 0; 1001 } 1002 } 1003 return this; 1004 }, 1005 1006 // resolve with this as context and given arguments 1007 resolve: function() { 1008 deferred.resolveWith( this, arguments ); 1009 return this; 1010 }, 1011 1012 // Has this deferred been resolved? 1013 isResolved: function() { 1014 return !!( firing || fired ); 1015 }, 1016 1017 // Cancel 1018 cancel: function() { 1019 cancelled = 1; 1020 callbacks = []; 1021 return this; 1022 } 1023 }; 1024 1025 return deferred; 1026 }, 1027 1028 // Full fledged deferred (two callbacks list) 1029 Deferred: function( func ) { 1030 var deferred = jQuery._Deferred(), 1031 failDeferred = jQuery._Deferred(), 1032 promise; 1033 // Add errorDeferred methods, then and promise 1034 jQuery.extend( deferred, { 1035 then: function( doneCallbacks, failCallbacks ) { 1036 deferred.done( doneCallbacks ).fail( failCallbacks ); 1037 return this; 1038 }, 1039 always: function() { 1040 return deferred.done.apply( deferred, arguments ).fail.apply( this, arguments ); 1041 }, 1042 fail: failDeferred.done, 1043 rejectWith: failDeferred.resolveWith, 1044 reject: failDeferred.resolve, 1045 isRejected: failDeferred.isResolved, 1046 pipe: function( fnDone, fnFail ) { 1047 return jQuery.Deferred(function( newDefer ) { 1048 jQuery.each( { 1049 done: [ fnDone, "resolve" ], 1050 fail: [ fnFail, "reject" ] 1051 }, function( handler, data ) { 1052 var fn = data[ 0 ], 1053 action = data[ 1 ], 1054 returned; 1055 if ( jQuery.isFunction( fn ) ) { 1056 deferred[ handler ](function() { 1057 returned = fn.apply( this, arguments ); 1058 if ( returned && jQuery.isFunction( returned.promise ) ) { 1059 returned.promise().then( newDefer.resolve, newDefer.reject ); 1060 } else { 1061 newDefer[ action ]( returned ); 1062 } 1063 }); 1064 } else { 1065 deferred[ handler ]( newDefer[ action ] ); 1066 } 1067 }); 1068 }).promise(); 1069 }, 1070 // Get a promise for this deferred 1071 // If obj is provided, the promise aspect is added to the object 1072 promise: function( obj ) { 1073 if ( obj == null ) { 1074 if ( promise ) { 1075 return promise; 1076 } 1077 promise = obj = {}; 1078 } 1079 var i = promiseMethods.length; 1080 while( i-- ) { 1081 obj[ promiseMethods[i] ] = deferred[ promiseMethods[i] ]; 1082 } 1083 return obj; 1084 } 1085 }); 1086 // Make sure only one callback list will be used 1087 deferred.done( failDeferred.cancel ).fail( deferred.cancel ); 1088 // Unexpose cancel 1089 delete deferred.cancel; 1090 // Call given func if any 1091 if ( func ) { 1092 func.call( deferred, deferred ); 1093 } 1094 return deferred; 1095 }, 1096 1097 // Deferred helper 1098 when: function( firstParam ) { 1099 var args = arguments, 1100 i = 0, 1101 length = args.length, 1102 count = length, 1103 deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ? 1104 firstParam : 1105 jQuery.Deferred(); 1106 function resolveFunc( i ) { 1107 return function( value ) { 1108 args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value; 1109 if ( !( --count ) ) { 1110 // Strange bug in FF4: 1111 // Values changed onto the arguments object sometimes end up as undefined values 1112 // outside the $.when method. Cloning the object into a fresh array solves the issue 1113 deferred.resolveWith( deferred, sliceDeferred.call( args, 0 ) ); 1114 } 1115 }; 1116 } 1117 if ( length > 1 ) { 1118 for( ; i < length; i++ ) { 1119 if ( args[ i ] && jQuery.isFunction( args[ i ].promise ) ) { 1120 args[ i ].promise().then( resolveFunc(i), deferred.reject ); 1121 } else { 1122 --count; 1123 } 1124 } 1125 if ( !count ) { 1126 deferred.resolveWith( deferred, args ); 1127 } 1128 } else if ( deferred !== firstParam ) { 1129 deferred.resolveWith( deferred, length ? [ firstParam ] : [] ); 1130 } 1131 return deferred.promise(); 1132 } 1133 }); 1134 1135 1136 1137 jQuery.support = (function() { 1138 1139 var div = document.createElement( "div" ), 1140 documentElement = document.documentElement, 1141 all, 1142 a, 1143 select, 1144 opt, 1145 input, 1146 marginDiv, 1147 support, 1148 fragment, 1149 body, 1150 bodyStyle, 1151 tds, 1152 events, 1153 eventName, 1154 i, 1155 isSupported; 1156 1157 // Preliminary tests 1158 div.setAttribute("className", "t"); 1159 div.innerHTML = " <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>"; 1160 1161 all = div.getElementsByTagName( "*" ); 1162 a = div.getElementsByTagName( "a" )[ 0 ]; 1163 1164 // Can't get basic test support 1165 if ( !all || !all.length || !a ) { 1166 return {}; 1167 } 1168 1169 // First batch of supports tests 1170 select = document.createElement( "select" ); 1171 opt = select.appendChild( document.createElement("option") ); 1172 input = div.getElementsByTagName( "input" )[ 0 ]; 1173 1174 support = { 1175 // IE strips leading whitespace when .innerHTML is used 1176 leadingWhitespace: ( div.firstChild.nodeType === 3 ), 1177 1178 // Make sure that tbody elements aren't automatically inserted 1179 // IE will insert them into empty tables 1180 tbody: !div.getElementsByTagName( "tbody" ).length, 1181 1182 // Make sure that link elements get serialized correctly by innerHTML 1183 // This requires a wrapper element in IE 1184 htmlSerialize: !!div.getElementsByTagName( "link" ).length, 1185 1186 // Get the style information from getAttribute 1187 // (IE uses .cssText instead) 1188 style: /top/.test( a.getAttribute("style") ), 1189 1190 // Make sure that URLs aren't manipulated 1191 // (IE normalizes it by default) 1192 hrefNormalized: ( a.getAttribute( "href" ) === "/a" ), 1193 1194 // Make sure that element opacity exists 1195 // (IE uses filter instead) 1196 // Use a regex to work around a WebKit issue. See #5145 1197 opacity: /^0.55$/.test( a.style.opacity ), 1198 1199 // Verify style float existence 1200 // (IE uses styleFloat instead of cssFloat) 1201 cssFloat: !!a.style.cssFloat, 1202 1203 // Make sure that if no value is specified for a checkbox 1204 // that it defaults to "on". 1205 // (WebKit defaults to "" instead) 1206 checkOn: ( input.value === "on" ), 1207 1208 // Make sure that a selected-by-default option has a working selected property. 1209 // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) 1210 optSelected: opt.selected, 1211 1212 // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7) 1213 getSetAttribute: div.className !== "t", 1214 1215 // Will be defined later 1216 submitBubbles: true, 1217 changeBubbles: true, 1218 focusinBubbles: false, 1219 deleteExpando: true, 1220 noCloneEvent: true, 1221 inlineBlockNeedsLayout: false, 1222 shrinkWrapBlocks: false, 1223 reliableMarginRight: true 1224 }; 1225 1226 // Make sure checked status is properly cloned 1227 input.checked = true; 1228 support.noCloneChecked = input.cloneNode( true ).checked; 1229 1230 // Make sure that the options inside disabled selects aren't marked as disabled 1231 // (WebKit marks them as disabled) 1232 select.disabled = true; 1233 support.optDisabled = !opt.disabled; 1234 1235 // Test to see if it's possible to delete an expando from an element 1236 // Fails in Internet Explorer 1237 try { 1238 delete div.test; 1239 } catch( e ) { 1240 support.deleteExpando = false; 1241 } 1242 1243 if ( !div.addEventListener && div.attachEvent && div.fireEvent ) { 1244 div.attachEvent( "onclick", function click() { 1245 // Cloning a node shouldn't copy over any 1246 // bound event handlers (IE does this) 1247 support.noCloneEvent = false; 1248 div.detachEvent( "onclick", click ); 1249 }); 1250 div.cloneNode( true ).fireEvent( "onclick" ); 1251 } 1252 1253 // Check if a radio maintains it's value 1254 // after being appended to the DOM 1255 input = document.createElement("input"); 1256 input.value = "t"; 1257 input.setAttribute("type", "radio"); 1258 support.radioValue = input.value === "t"; 1259 1260 input.setAttribute("checked", "checked"); 1261 div.appendChild( input ); 1262 fragment = document.createDocumentFragment(); 1263 fragment.appendChild( div.firstChild ); 1264 1265 // WebKit doesn't clone checked state correctly in fragments 1266 support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked; 1267 1268 div.innerHTML = ""; 1269 1270 // Figure out if the W3C box model works as expected 1271 div.style.width = div.style.paddingLeft = "1px"; 1272 1273 // We use our own, invisible, body 1274 body = document.createElement( "body" ); 1275 bodyStyle = { 1276 visibility: "hidden", 1277 width: 0, 1278 height: 0, 1279 border: 0, 1280 margin: 0, 1281 // Set background to avoid IE crashes when removing (#9028) 1282 background: "none" 1283 }; 1284 for ( i in bodyStyle ) { 1285 body.style[ i ] = bodyStyle[ i ]; 1286 } 1287 body.appendChild( div ); 1288 documentElement.insertBefore( body, documentElement.firstChild ); 1289 1290 // Check if a disconnected checkbox will retain its checked 1291 // value of true after appended to the DOM (IE6/7) 1292 support.appendChecked = input.checked; 1293 1294 support.boxModel = div.offsetWidth === 2; 1295 1296 if ( "zoom" in div.style ) { 1297 // Check if natively block-level elements act like inline-block 1298 // elements when setting their display to 'inline' and giving 1299 // them layout 1300 // (IE < 8 does this) 1301 div.style.display = "inline"; 1302 div.style.zoom = 1; 1303 support.inlineBlockNeedsLayout = ( div.offsetWidth === 2 ); 1304 1305 // Check if elements with layout shrink-wrap their children 1306 // (IE 6 does this) 1307 div.style.display = ""; 1308 div.innerHTML = "<div style='width:4px;'></div>"; 1309 support.shrinkWrapBlocks = ( div.offsetWidth !== 2 ); 1310 } 1311 1312 div.innerHTML = "<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>"; 1313 tds = div.getElementsByTagName( "td" ); 1314 1315 // Check if table cells still have offsetWidth/Height when they are set 1316 // to display:none and there are still other visible table cells in a 1317 // table row; if so, offsetWidth/Height are not reliable for use when 1318 // determining if an element has been hidden directly using 1319 // display:none (it is still safe to use offsets if a parent element is 1320 // hidden; don safety goggles and see bug #4512 for more information). 1321 // (only IE 8 fails this test) 1322 isSupported = ( tds[ 0 ].offsetHeight === 0 ); 1323 1324 tds[ 0 ].style.display = ""; 1325 tds[ 1 ].style.display = "none"; 1326 1327 // Check if empty table cells still have offsetWidth/Height 1328 // (IE < 8 fail this test) 1329 support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 ); 1330 div.innerHTML = ""; 1331 1332 // Check if div with explicit width and no margin-right incorrectly 1333 // gets computed margin-right based on width of container. For more 1334 // info see bug #3333 1335 // Fails in WebKit before Feb 2011 nightlies 1336 // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right 1337 if ( document.defaultView && document.defaultView.getComputedStyle ) { 1338 marginDiv = document.createElement( "div" ); 1339 marginDiv.style.width = "0"; 1340 marginDiv.style.marginRight = "0"; 1341 div.appendChild( marginDiv ); 1342 support.reliableMarginRight = 1343 ( parseInt( ( document.defaultView.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0; 1344 } 1345 1346 // Remove the body element we added 1347 body.innerHTML = ""; 1348 documentElement.removeChild( body ); 1349 1350 // Technique from Juriy Zaytsev 1351 // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/ 1352 // We only care about the case where non-standard event systems 1353 // are used, namely in IE. Short-circuiting here helps us to 1354 // avoid an eval call (in setAttribute) which can cause CSP 1355 // to go haywire. See: https://developer.mozilla.org/en/Security/CSP 1356 if ( div.attachEvent ) { 1357 for( i in { 1358 submit: 1, 1359 change: 1, 1360 focusin: 1 1361 } ) { 1362 eventName = "on" + i; 1363 isSupported = ( eventName in div ); 1364 if ( !isSupported ) { 1365 div.setAttribute( eventName, "return;" ); 1366 isSupported = ( typeof div[ eventName ] === "function" ); 1367 } 1368 support[ i + "Bubbles" ] = isSupported; 1369 } 1370 } 1371 1372 return support; 1373 })(); 1374 1375 // Keep track of boxModel 1376 jQuery.boxModel = jQuery.support.boxModel; 1377 1378 1379 1380 1381 var rbrace = /^(?:\{.*\}|\[.*\])$/, 1382 rmultiDash = /([a-z])([A-Z])/g; 1383 1384 jQuery.extend({ 1385 cache: {}, 1386 1387 // Please use with caution 1388 uuid: 0, 1389 1390 // Unique for each copy of jQuery on the page 1391 // Non-digits removed to match rinlinejQuery 1392 expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ), 1393 1394 // The following elements throw uncatchable exceptions if you 1395 // attempt to add expando properties to them. 1396 noData: { 1397 "embed": true, 1398 // Ban all objects except for Flash (which handle expandos) 1399 "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000", 1400 "applet": true 1401 }, 1402 1403 hasData: function( elem ) { 1404 elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; 1405 1406 return !!elem && !isEmptyDataObject( elem ); 1407 }, 1408 1409 data: function( elem, name, data, pvt /* Internal Use Only */ ) { 1410 if ( !jQuery.acceptData( elem ) ) { 1411 return; 1412 } 1413 1414 var internalKey = jQuery.expando, getByName = typeof name === "string", thisCache, 1415 1416 // We have to handle DOM nodes and JS objects differently because IE6-7 1417 // can't GC object references properly across the DOM-JS boundary 1418 isNode = elem.nodeType, 1419 1420 // Only DOM nodes need the global jQuery cache; JS object data is 1421 // attached directly to the object so GC can occur automatically 1422 cache = isNode ? jQuery.cache : elem, 1423 1424 // Only defining an ID for JS objects if its cache already exists allows 1425 // the code to shortcut on the same path as a DOM node with no cache 1426 id = isNode ? elem[ jQuery.expando ] : elem[ jQuery.expando ] && jQuery.expando; 1427 1428 // Avoid doing any more work than we need to when trying to get data on an 1429 // object that has no data at all 1430 if ( (!id || (pvt && id && !cache[ id ][ internalKey ])) && getByName && data === undefined ) { 1431 return; 1432 } 1433 1434 if ( !id ) { 1435 // Only DOM nodes need a new unique ID for each element since their data 1436 // ends up in the global cache 1437 if ( isNode ) { 1438 elem[ jQuery.expando ] = id = ++jQuery.uuid; 1439 } else { 1440 id = jQuery.expando; 1441 } 1442 } 1443 1444 if ( !cache[ id ] ) { 1445 cache[ id ] = {}; 1446 1447 // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery 1448 // metadata on plain JS objects when the object is serialized using 1449 // JSON.stringify 1450 if ( !isNode ) { 1451 cache[ id ].toJSON = jQuery.noop; 1452 } 1453 } 1454 1455 // An object can be passed to jQuery.data instead of a key/value pair; this gets 1456 // shallow copied over onto the existing cache 1457 if ( typeof name === "object" || typeof name === "function" ) { 1458 if ( pvt ) { 1459 cache[ id ][ internalKey ] = jQuery.extend(cache[ id ][ internalKey ], name); 1460 } else { 1461 cache[ id ] = jQuery.extend(cache[ id ], name); 1462 } 1463 } 1464 1465 thisCache = cache[ id ]; 1466 1467 // Internal jQuery data is stored in a separate object inside the object's data 1468 // cache in order to avoid key collisions between internal data and user-defined 1469 // data 1470 if ( pvt ) { 1471 if ( !thisCache[ internalKey ] ) { 1472 thisCache[ internalKey ] = {}; 1473 } 1474 1475 thisCache = thisCache[ internalKey ]; 1476 } 1477 1478 if ( data !== undefined ) { 1479 thisCache[ jQuery.camelCase( name ) ] = data; 1480 } 1481 1482 // TODO: This is a hack for 1.5 ONLY. It will be removed in 1.6. Users should 1483 // not attempt to inspect the internal events object using jQuery.data, as this 1484 // internal data object is undocumented and subject to change. 1485 if ( name === "events" && !thisCache[name] ) { 1486 return thisCache[ internalKey ] && thisCache[ internalKey ].events; 1487 } 1488 1489 return getByName ? thisCache[ jQuery.camelCase( name ) ] : thisCache; 1490 }, 1491 1492 removeData: function( elem, name, pvt /* Internal Use Only */ ) { 1493 if ( !jQuery.acceptData( elem ) ) { 1494 return; 1495 } 1496 1497 var internalKey = jQuery.expando, isNode = elem.nodeType, 1498 1499 // See jQuery.data for more information 1500 cache = isNode ? jQuery.cache : elem, 1501 1502 // See jQuery.data for more information 1503 id = isNode ? elem[ jQuery.expando ] : jQuery.expando; 1504 1505 // If there is already no cache entry for this object, there is no 1506 // purpose in continuing 1507 if ( !cache[ id ] ) { 1508 return; 1509 } 1510 1511 if ( name ) { 1512 var thisCache = pvt ? cache[ id ][ internalKey ] : cache[ id ]; 1513 1514 if ( thisCache ) { 1515 delete thisCache[ name ]; 1516 1517 // If there is no data left in the cache, we want to continue 1518 // and let the cache object itself get destroyed 1519 if ( !isEmptyDataObject(thisCache) ) { 1520 return; 1521 } 1522 } 1523 } 1524 1525 // See jQuery.data for more information 1526 if ( pvt ) { 1527 delete cache[ id ][ internalKey ]; 1528 1529 // Don't destroy the parent cache unless the internal data object 1530 // had been the only thing left in it 1531 if ( !isEmptyDataObject(cache[ id ]) ) { 1532 return; 1533 } 1534 } 1535 1536 var internalCache = cache[ id ][ internalKey ]; 1537 1538 // Browsers that fail expando deletion also refuse to delete expandos on 1539 // the window, but it will allow it on all other JS objects; other browsers 1540 // don't care 1541 if ( jQuery.support.deleteExpando || cache != window ) { 1542 delete cache[ id ]; 1543 } else { 1544 cache[ id ] = null; 1545 } 1546 1547 // We destroyed the entire user cache at once because it's faster than 1548 // iterating through each key, but we need to continue to persist internal 1549 // data if it existed 1550 if ( internalCache ) { 1551 cache[ id ] = {}; 1552 // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery 1553 // metadata on plain JS objects when the object is serialized using 1554 // JSON.stringify 1555 if ( !isNode ) { 1556 cache[ id ].toJSON = jQuery.noop; 1557 } 1558 1559 cache[ id ][ internalKey ] = internalCache; 1560 1561 // Otherwise, we need to eliminate the expando on the node to avoid 1562 // false lookups in the cache for entries that no longer exist 1563 } else if ( isNode ) { 1564 // IE does not allow us to delete expando properties from nodes, 1565 // nor does it have a removeAttribute function on Document nodes; 1566 // we must handle all of these cases 1567 if ( jQuery.support.deleteExpando ) { 1568 delete elem[ jQuery.expando ]; 1569 } else if ( elem.removeAttribute ) { 1570 elem.removeAttribute( jQuery.expando ); 1571 } else { 1572 elem[ jQuery.expando ] = null; 1573 } 1574 } 1575 }, 1576 1577 // For internal use only. 1578 _data: function( elem, name, data ) { 1579 return jQuery.data( elem, name, data, true ); 1580 }, 1581 1582 // A method for determining if a DOM node can handle the data expando 1583 acceptData: function( elem ) { 1584 if ( elem.nodeName ) { 1585 var match = jQuery.noData[ elem.nodeName.toLowerCase() ]; 1586 1587 if ( match ) { 1588 return !(match === true || elem.getAttribute("classid") !== match); 1589 } 1590 } 1591 1592 return true; 1593 } 1594 }); 1595 1596 jQuery.fn.extend({ 1597 data: function( key, value ) { 1598 var data = null; 1599 1600 if ( typeof key === "undefined" ) { 1601 if ( this.length ) { 1602 data = jQuery.data( this[0] ); 1603 1604 if ( this[0].nodeType === 1 ) { 1605 var attr = this[0].attributes, name; 1606 for ( var i = 0, l = attr.length; i < l; i++ ) { 1607 name = attr[i].name; 1608 1609 if ( name.indexOf( "data-" ) === 0 ) { 1610 name = jQuery.camelCase( name.substring(5) ); 1611 1612 dataAttr( this[0], name, data[ name ] ); 1613 } 1614 } 1615 } 1616 } 1617 1618 return data; 1619 1620 } else if ( typeof key === "object" ) { 1621 return this.each(function() { 1622 jQuery.data( this, key ); 1623 }); 1624 } 1625 1626 var parts = key.split("."); 1627 parts[1] = parts[1] ? "." + parts[1] : ""; 1628 1629 if ( value === undefined ) { 1630 data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]); 1631 1632 // Try to fetch any internally stored data first 1633 if ( data === undefined && this.length ) { 1634 data = jQuery.data( this[0], key ); 1635 data = dataAttr( this[0], key, data ); 1636 } 1637 1638 return data === undefined && parts[1] ? 1639 this.data( parts[0] ) : 1640 data; 1641 1642 } else { 1643 return this.each(function() { 1644 var $this = jQuery( this ), 1645 args = [ parts[0], value ]; 1646 1647 $this.triggerHandler( "setData" + parts[1] + "!", args ); 1648 jQuery.data( this, key, value ); 1649 $this.triggerHandler( "changeData" + parts[1] + "!", args ); 1650 }); 1651 } 1652 }, 1653 1654 removeData: function( key ) { 1655 return this.each(function() { 1656 jQuery.removeData( this, key ); 1657 }); 1658 } 1659 }); 1660 1661 function dataAttr( elem, key, data ) { 1662 // If nothing was found internally, try to fetch any 1663 // data from the HTML5 data-* attribute 1664 if ( data === undefined && elem.nodeType === 1 ) { 1665 var name = "data-" + key.replace( rmultiDash, "$1-$2" ).toLowerCase(); 1666 1667 data = elem.getAttribute( name ); 1668 1669 if ( typeof data === "string" ) { 1670 try { 1671 data = data === "true" ? true : 1672 data === "false" ? false : 1673 data === "null" ? null : 1674 !jQuery.isNaN( data ) ? parseFloat( data ) : 1675 rbrace.test( data ) ? jQuery.parseJSON( data ) : 1676 data; 1677 } catch( e ) {} 1678 1679 // Make sure we set the data so it isn't changed later 1680 jQuery.data( elem, key, data ); 1681 1682 } else { 1683 data = undefined; 1684 } 1685 } 1686 1687 return data; 1688 } 1689 1690 // TODO: This is a hack for 1.5 ONLY to allow objects with a single toJSON 1691 // property to be considered empty objects; this property always exists in 1692 // order to make sure JSON.stringify does not expose internal metadata 1693 function isEmptyDataObject( obj ) { 1694 for ( var name in obj ) { 1695 if ( name !== "toJSON" ) { 1696 return false; 1697 } 1698 } 1699 1700 return true; 1701 } 1702 1703 1704 1705 1706 function handleQueueMarkDefer( elem, type, src ) { 1707 var deferDataKey = type + "defer", 1708 queueDataKey = type + "queue", 1709 markDataKey = type + "mark", 1710 defer = jQuery.data( elem, deferDataKey, undefined, true ); 1711 if ( defer && 1712 ( src === "queue" || !jQuery.data( elem, queueDataKey, undefined, true ) ) && 1713 ( src === "mark" || !jQuery.data( elem, markDataKey, undefined, true ) ) ) { 1714 // Give room for hard-coded callbacks to fire first 1715 // and eventually mark/queue something else on the element 1716 setTimeout( function() { 1717 if ( !jQuery.data( elem, queueDataKey, undefined, true ) && 1718 !jQuery.data( elem, markDataKey, undefined, true ) ) { 1719 jQuery.removeData( elem, deferDataKey, true ); 1720 defer.resolve(); 1721 } 1722 }, 0 ); 1723 } 1724 } 1725 1726 jQuery.extend({ 1727 1728 _mark: function( elem, type ) { 1729 if ( elem ) { 1730 type = (type || "fx") + "mark"; 1731 jQuery.data( elem, type, (jQuery.data(elem,type,undefined,true) || 0) + 1, true ); 1732 } 1733 }, 1734 1735 _unmark: function( force, elem, type ) { 1736 if ( force !== true ) { 1737 type = elem; 1738 elem = force; 1739 force = false; 1740 } 1741 if ( elem ) { 1742 type = type || "fx"; 1743 var key = type + "mark", 1744 count = force ? 0 : ( (jQuery.data( elem, key, undefined, true) || 1 ) - 1 ); 1745 if ( count ) { 1746 jQuery.data( elem, key, count, true ); 1747 } else { 1748 jQuery.removeData( elem, key, true ); 1749 handleQueueMarkDefer( elem, type, "mark" ); 1750 } 1751 } 1752 }, 1753 1754 queue: function( elem, type, data ) { 1755 if ( elem ) { 1756 type = (type || "fx") + "queue"; 1757 var q = jQuery.data( elem, type, undefined, true ); 1758 // Speed up dequeue by getting out quickly if this is just a lookup 1759 if ( data ) { 1760 if ( !q || jQuery.isArray(data) ) { 1761 q = jQuery.data( elem, type, jQuery.makeArray(data), true ); 1762 } else { 1763 q.push( data ); 1764 } 1765 } 1766 return q || []; 1767 } 1768 }, 1769 1770 dequeue: function( elem, type ) { 1771 type = type || "fx"; 1772 1773 var queue = jQuery.queue( elem, type ), 1774 fn = queue.shift(), 1775 defer; 1776 1777 // If the fx queue is dequeued, always remove the progress sentinel 1778 if ( fn === "inprogress" ) { 1779 fn = queue.shift(); 1780 } 1781 1782 if ( fn ) { 1783 // Add a progress sentinel to prevent the fx queue from being 1784 // automatically dequeued 1785 if ( type === "fx" ) { 1786 queue.unshift("inprogress"); 1787 } 1788 1789 fn.call(elem, function() { 1790 jQuery.dequeue(elem, type); 1791 }); 1792 } 1793 1794 if ( !queue.length ) { 1795 jQuery.removeData( elem, type + "queue", true ); 1796 handleQueueMarkDefer( elem, type, "queue" ); 1797 } 1798 } 1799 }); 1800 1801 jQuery.fn.extend({ 1802 queue: function( type, data ) { 1803 if ( typeof type !== "string" ) { 1804 data = type; 1805 type = "fx"; 1806 } 1807 1808 if ( data === undefined ) { 1809 return jQuery.queue( this[0], type ); 1810 } 1811 return this.each(function() { 1812 var queue = jQuery.queue( this, type, data ); 1813 1814 if ( type === "fx" && queue[0] !== "inprogress" ) { 1815 jQuery.dequeue( this, type ); 1816 } 1817 }); 1818 }, 1819 dequeue: function( type ) { 1820 return this.each(function() { 1821 jQuery.dequeue( this, type ); 1822 }); 1823 }, 1824 // Based off of the plugin by Clint Helfers, with permission. 1825 // http://blindsignals.com/index.php/2009/07/jquery-delay/ 1826 delay: function( time, type ) { 1827 time = jQuery.fx ? jQuery.fx.speeds[time] || time : time; 1828 type = type || "fx"; 1829 1830 return this.queue( type, function() { 1831 var elem = this; 1832 setTimeout(function() { 1833 jQuery.dequeue( elem, type ); 1834 }, time ); 1835 }); 1836 }, 1837 clearQueue: function( type ) { 1838 return this.queue( type || "fx", [] ); 1839 }, 1840 // Get a promise resolved when queues of a certain type 1841 // are emptied (fx is the type by default) 1842 promise: function( type, object ) { 1843 if ( typeof type !== "string" ) { 1844 object = type; 1845 type = undefined; 1846 } 1847 type = type || "fx"; 1848 var defer = jQuery.Deferred(), 1849 elements = this, 1850 i = elements.length, 1851 count = 1, 1852 deferDataKey = type + "defer", 1853 queueDataKey = type + "queue", 1854 markDataKey = type + "mark", 1855 tmp; 1856 function resolve() { 1857 if ( !( --count ) ) { 1858 defer.resolveWith( elements, [ elements ] ); 1859 } 1860 } 1861 while( i-- ) { 1862 if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) || 1863 ( jQuery.data( elements[ i ], queueDataKey, undefined, true ) || 1864 jQuery.data( elements[ i ], markDataKey, undefined, true ) ) && 1865 jQuery.data( elements[ i ], deferDataKey, jQuery._Deferred(), true ) )) { 1866 count++; 1867 tmp.done( resolve ); 1868 } 1869 } 1870 resolve(); 1871 return defer.promise(); 1872 } 1873 }); 1874 1875 1876 1877 1878 var rclass = /[\n\t\r]/g, 1879 rspace = /\s+/, 1880 rreturn = /\r/g, 1881 rtype = /^(?:button|input)$/i, 1882 rfocusable = /^(?:button|input|object|select|textarea)$/i, 1883 rclickable = /^a(?:rea)?$/i, 1884 rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i, 1885 rinvalidChar = /\:/, 1886 formHook, boolHook; 1887 1888 jQuery.fn.extend({ 1889 attr: function( name, value ) { 1890 return jQuery.access( this, name, value, true, jQuery.attr ); 1891 }, 1892 1893 removeAttr: function( name ) { 1894 return this.each(function() { 1895 jQuery.removeAttr( this, name ); 1896 }); 1897 }, 1898 1899 prop: function( name, value ) { 1900 return jQuery.access( this, name, value, true, jQuery.prop ); 1901 }, 1902 1903 removeProp: function( name ) { 1904 name = jQuery.propFix[ name ] || name; 1905 return this.each(function() { 1906 // try/catch handles cases where IE balks (such as removing a property on window) 1907 try { 1908 this[ name ] = undefined; 1909 delete this[ name ]; 1910 } catch( e ) {} 1911 }); 1912 }, 1913 1914 addClass: function( value ) { 1915 if ( jQuery.isFunction( value ) ) { 1916 return this.each(function(i) { 1917 var self = jQuery(this); 1918 self.addClass( value.call(this, i, self.attr("class") || "") ); 1919 }); 1920 } 1921 1922 if ( value && typeof value === "string" ) { 1923 var classNames = (value || "").split( rspace ); 1924 1925 for ( var i = 0, l = this.length; i < l; i++ ) { 1926 var elem = this[i]; 1927 1928 if ( elem.nodeType === 1 ) { 1929 if ( !elem.className ) { 1930 elem.className = value; 1931 1932 } else { 1933 var className = " " + elem.className + " ", 1934 setClass = elem.className; 1935 1936 for ( var c = 0, cl = classNames.length; c < cl; c++ ) { 1937 if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) { 1938 setClass += " " + classNames[c]; 1939 } 1940 } 1941 elem.className = jQuery.trim( setClass ); 1942 } 1943 } 1944 } 1945 } 1946 1947 return this; 1948 }, 1949 1950 removeClass: function( value ) { 1951 if ( jQuery.isFunction(value) ) { 1952 return this.each(function(i) { 1953 var self = jQuery(this); 1954 self.removeClass( value.call(this, i, self.attr("class")) ); 1955 }); 1956 } 1957 1958 if ( (value && typeof value === "string") || value === undefined ) { 1959 var classNames = (value || "").split( rspace ); 1960 1961 for ( var i = 0, l = this.length; i < l; i++ ) { 1962 var elem = this[i]; 1963 1964 if ( elem.nodeType === 1 && elem.className ) { 1965 if ( value ) { 1966 var className = (" " + elem.className + " ").replace(rclass, " "); 1967 for ( var c = 0, cl = classNames.length; c < cl; c++ ) { 1968 className = className.replace(" " + classNames[c] + " ", " "); 1969 } 1970 elem.className = jQuery.trim( className ); 1971 1972 } else { 1973 elem.className = ""; 1974 } 1975 } 1976 } 1977 } 1978 1979 return this; 1980 }, 1981 1982 toggleClass: function( value, stateVal ) { 1983 var type = typeof value, 1984 isBool = typeof stateVal === "boolean"; 1985 1986 if ( jQuery.isFunction( value ) ) { 1987 return this.each(function(i) { 1988 var self = jQuery(this); 1989 self.toggleClass( value.call(this, i, self.attr("class"), stateVal), stateVal ); 1990 }); 1991 } 1992 1993 return this.each(function() { 1994 if ( type === "string" ) { 1995 // toggle individual class names 1996 var className, 1997 i = 0, 1998 self = jQuery( this ), 1999 state = stateVal, 2000 classNames = value.split( rspace ); 2001 2002 while ( (className = classNames[ i++ ]) ) { 2003 // check each className given, space seperated list 2004 state = isBool ? state : !self.hasClass( className ); 2005 self[ state ? "addClass" : "removeClass" ]( className ); 2006 } 2007 2008 } else if ( type === "undefined" || type === "boolean" ) { 2009 if ( this.className ) { 2010 // store className if set 2011 jQuery._data( this, "__className__", this.className ); 2012 } 2013 2014 // toggle whole className 2015 this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || ""; 2016 } 2017 }); 2018 }, 2019 2020 hasClass: function( selector ) { 2021 var className = " " + selector + " "; 2022 for ( var i = 0, l = this.length; i < l; i++ ) { 2023 if ( (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) { 2024 return true; 2025 } 2026 } 2027 2028 return false; 2029 }, 2030 2031 val: function( value ) { 2032 var hooks, ret, 2033 elem = this[0]; 2034 2035 if ( !arguments.length ) { 2036 if ( elem ) { 2037 hooks = jQuery.valHooks[ elem.nodeName.toLowerCase() ] || jQuery.valHooks[ elem.type ]; 2038 2039 if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) { 2040 return ret; 2041 } 2042 2043 return (elem.value || "").replace(rreturn, ""); 2044 } 2045 2046 return undefined; 2047 } 2048 2049 var isFunction = jQuery.isFunction( value ); 2050 2051 return this.each(function( i ) { 2052 var self = jQuery(this), val; 2053 2054 if ( this.nodeType !== 1 ) { 2055 return; 2056 } 2057 2058 if ( isFunction ) { 2059 val = value.call( this, i, self.val() ); 2060 } else { 2061 val = value; 2062 } 2063 2064 // Treat null/undefined as ""; convert numbers to string 2065 if ( val == null ) { 2066 val = ""; 2067 } else if ( typeof val === "number" ) { 2068 val += ""; 2069 } else if ( jQuery.isArray( val ) ) { 2070 val = jQuery.map(val, function ( value ) { 2071 return value == null ? "" : value + ""; 2072 }); 2073 } 2074 2075 hooks = jQuery.valHooks[ this.nodeName.toLowerCase() ] || jQuery.valHooks[ this.type ]; 2076 2077 // If set returns undefined, fall back to normal setting 2078 if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) { 2079 this.value = val; 2080 } 2081 }); 2082 } 2083 }); 2084 2085 jQuery.extend({ 2086 valHooks: { 2087 option: { 2088 get: function( elem ) { 2089 // attributes.value is undefined in Blackberry 4.7 but 2090 // uses .value. See #6932 2091 var val = elem.attributes.value; 2092 return !val || val.specified ? elem.value : elem.text; 2093 } 2094 }, 2095 select: { 2096 get: function( elem ) { 2097 var value, 2098 index = elem.selectedIndex, 2099 values = [], 2100 options = elem.options, 2101 one = elem.type === "select-one"; 2102 2103 // Nothing was selected 2104 if ( index < 0 ) { 2105 return null; 2106 } 2107 2108 // Loop through all the selected options 2109 for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) { 2110 var option = options[ i ]; 2111 2112 // Don't return options that are disabled or in a disabled optgroup 2113 if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) && 2114 (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) { 2115 2116 // Get the specific value for the option 2117 value = jQuery( option ).val(); 2118 2119 // We don't need an array for one selects 2120 if ( one ) { 2121 return value; 2122 } 2123 2124 // Multi-Selects return an array 2125 values.push( value ); 2126 } 2127 } 2128 2129 // Fixes Bug #2551 -- select.val() broken in IE after form.reset() 2130 if ( one && !values.length && options.length ) { 2131 return jQuery( options[ index ] ).val(); 2132 } 2133 2134 return values; 2135 }, 2136 2137 set: function( elem, value ) { 2138 var values = jQuery.makeArray( value ); 2139 2140 jQuery(elem).find("option").each(function() { 2141 this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0; 2142 }); 2143 2144 if ( !values.length ) { 2145 elem.selectedIndex = -1; 2146 } 2147 return values; 2148 } 2149 } 2150 }, 2151 2152 attrFn: { 2153 val: true, 2154 css: true, 2155 html: true, 2156 text: true, 2157 data: true, 2158 width: true, 2159 height: true, 2160 offset: true 2161 }, 2162 2163 attrFix: { 2164 // Always normalize to ensure hook usage 2165 tabindex: "tabIndex" 2166 }, 2167 2168 attr: function( elem, name, value, pass ) { 2169 var nType = elem.nodeType; 2170 2171 // don't get/set attributes on text, comment and attribute nodes 2172 if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { 2173 return undefined; 2174 } 2175 2176 if ( pass && name in jQuery.attrFn ) { 2177 return jQuery( elem )[ name ]( value ); 2178 } 2179 2180 // Fallback to prop when attributes are not supported 2181 if ( !("getAttribute" in elem) ) { 2182 return jQuery.prop( elem, name, value ); 2183 } 2184 2185 var ret, hooks, 2186 notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); 2187 2188 // Normalize the name if needed 2189 name = notxml && jQuery.attrFix[ name ] || name; 2190 2191 hooks = jQuery.attrHooks[ name ]; 2192 2193 if ( !hooks ) { 2194 // Use boolHook for boolean attributes 2195 if ( rboolean.test( name ) && 2196 (typeof value === "boolean" || value === undefined || value.toLowerCase() === name.toLowerCase()) ) { 2197 2198 hooks = boolHook; 2199 2200 // Use formHook for forms and if the name contains certain characters 2201 } else if ( formHook && (jQuery.nodeName( elem, "form" ) || rinvalidChar.test( name )) ) { 2202 hooks = formHook; 2203 } 2204 } 2205 2206 if ( value !== undefined ) { 2207 2208 if ( value === null ) { 2209 jQuery.removeAttr( elem, name ); 2210 return undefined; 2211 2212 } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) { 2213 return ret; 2214 2215 } else { 2216 elem.setAttribute( name, "" + value ); 2217 return value; 2218 } 2219 2220 } else if ( hooks && "get" in hooks && notxml ) { 2221 return hooks.get( elem, name ); 2222 2223 } else { 2224 2225 ret = elem.getAttribute( name ); 2226 2227 // Non-existent attributes return null, we normalize to undefined 2228 return ret === null ? 2229 undefined : 2230 ret; 2231 } 2232 }, 2233 2234 removeAttr: function( elem, name ) { 2235 var propName; 2236 if ( elem.nodeType === 1 ) { 2237 name = jQuery.attrFix[ name ] || name; 2238 2239 if ( jQuery.support.getSetAttribute ) { 2240 // Use removeAttribute in browsers that support it 2241 elem.removeAttribute( name ); 2242 } else { 2243 jQuery.attr( elem, name, "" ); 2244 elem.removeAttributeNode( elem.getAttributeNode( name ) ); 2245 } 2246 2247 // Set corresponding property to false for boolean attributes 2248 if ( rboolean.test( name ) && (propName = jQuery.propFix[ name ] || name) in elem ) { 2249 elem[ propName ] = false; 2250 } 2251 } 2252 }, 2253 2254 attrHooks: { 2255 type: { 2256 set: function( elem, value ) { 2257 // We can't allow the type property to be changed (since it causes problems in IE) 2258 if ( rtype.test( elem.nodeName ) && elem.parentNode ) { 2259 jQuery.error( "type property can't be changed" ); 2260 } else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) { 2261 // Setting the type on a radio button after the value resets the value in IE6-9 2262 // Reset value to it's default in case type is set after value 2263 // This is for element creation 2264 var val = elem.value; 2265 elem.setAttribute( "type", value ); 2266 if ( val ) { 2267 elem.value = val; 2268 } 2269 return value; 2270 } 2271 } 2272 }, 2273 tabIndex: { 2274 get: function( elem ) { 2275 // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set 2276 // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ 2277 var attributeNode = elem.getAttributeNode("tabIndex"); 2278 2279 return attributeNode && attributeNode.specified ? 2280 parseInt( attributeNode.value, 10 ) : 2281 rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? 2282 0 : 2283 undefined; 2284 } 2285 } 2286 }, 2287 2288 propFix: { 2289 tabindex: "tabIndex", 2290 readonly: "readOnly", 2291 "for": "htmlFor", 2292 "class": "className", 2293 maxlength: "maxLength", 2294 cellspacing: "cellSpacing", 2295 cellpadding: "cellPadding", 2296 rowspan: "rowSpan", 2297 colspan: "colSpan", 2298 usemap: "useMap", 2299 frameborder: "frameBorder", 2300 contenteditable: "contentEditable" 2301 }, 2302 2303 prop: function( elem, name, value ) { 2304 var nType = elem.nodeType; 2305 2306 // don't get/set properties on text, comment and attribute nodes 2307 if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { 2308 return undefined; 2309 } 2310 2311 var ret, hooks, 2312 notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); 2313 2314 // Try to normalize/fix the name 2315 name = notxml && jQuery.propFix[ name ] || name; 2316 2317 hooks = jQuery.propHooks[ name ]; 2318 2319 if ( value !== undefined ) { 2320 if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { 2321 return ret; 2322 2323 } else { 2324 return (elem[ name ] = value); 2325 } 2326 2327 } else { 2328 if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== undefined ) { 2329 return ret; 2330 2331 } else { 2332 return elem[ name ]; 2333 } 2334 } 2335 }, 2336 2337 propHooks: {} 2338 }); 2339 2340 // Hook for boolean attributes 2341 boolHook = { 2342 get: function( elem, name ) { 2343 // Align boolean attributes with corresponding properties 2344 return elem[ jQuery.propFix[ name ] || name ] ? 2345 name.toLowerCase() : 2346 undefined; 2347 }, 2348 set: function( elem, value, name ) { 2349 var propName; 2350 if ( value === false ) { 2351 // Remove boolean attributes when set to false 2352 jQuery.removeAttr( elem, name ); 2353 } else { 2354 // value is true since we know at this point it's type boolean and not false 2355 // Set boolean attributes to the same name and set the DOM property 2356 propName = jQuery.propFix[ name ] || name; 2357 if ( propName in elem ) { 2358 // Only set the IDL specifically if it already exists on the element 2359 elem[ propName ] = value; 2360 } 2361 2362 elem.setAttribute( name, name.toLowerCase() ); 2363 } 2364 return name; 2365 } 2366 }; 2367 2368 // Use the value property for back compat 2369 // Use the formHook for button elements in IE6/7 (#1954) 2370 jQuery.attrHooks.value = { 2371 get: function( elem, name ) { 2372 if ( formHook && jQuery.nodeName( elem, "button" ) ) { 2373 return formHook.get( elem, name ); 2374 } 2375 return elem.value; 2376 }, 2377 set: function( elem, value, name ) { 2378 if ( formHook && jQuery.nodeName( elem, "button" ) ) { 2379 return formHook.set( elem, value, name ); 2380 } 2381 // Does not return so that setAttribute is also used 2382 elem.value = value; 2383 } 2384 }; 2385 2386 // IE6/7 do not support getting/setting some attributes with get/setAttribute 2387 if ( !jQuery.support.getSetAttribute ) { 2388 2389 // propFix is more comprehensive and contains all fixes 2390 jQuery.attrFix = jQuery.propFix; 2391 2392 // Use this for any attribute on a form in IE6/7 2393 formHook = jQuery.attrHooks.name = jQuery.valHooks.button = { 2394 get: function( elem, name ) { 2395 var ret; 2396 ret = elem.getAttributeNode( name ); 2397 // Return undefined if nodeValue is empty string 2398 return ret && ret.nodeValue !== "" ? 2399 ret.nodeValue : 2400 undefined; 2401 }, 2402 set: function( elem, value, name ) { 2403 // Check form objects in IE (multiple bugs related) 2404 // Only use nodeValue if the attribute node exists on the form 2405 var ret = elem.getAttributeNode( name ); 2406 if ( ret ) { 2407 ret.nodeValue = value; 2408 return value; 2409 } 2410 } 2411 }; 2412 2413 // Set width and height to auto instead of 0 on empty string( Bug #8150 ) 2414 // This is for removals 2415 jQuery.each([ "width", "height" ], function( i, name ) { 2416 jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { 2417 set: function( elem, value ) { 2418 if ( value === "" ) { 2419 elem.setAttribute( name, "auto" ); 2420 return value; 2421 } 2422 } 2423 }); 2424 }); 2425 } 2426 2427 2428 // Some attributes require a special call on IE 2429 if ( !jQuery.support.hrefNormalized ) { 2430 jQuery.each([ "href", "src", "width", "height" ], function( i, name ) { 2431 jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { 2432 get: function( elem ) { 2433 var ret = elem.getAttribute( name, 2 ); 2434 return ret === null ? undefined : ret; 2435 } 2436 }); 2437 }); 2438 } 2439 2440 if ( !jQuery.support.style ) { 2441 jQuery.attrHooks.style = { 2442 get: function( elem ) { 2443 // Return undefined in the case of empty string 2444 // Normalize to lowercase since IE uppercases css property names 2445 return elem.style.cssText.toLowerCase() || undefined; 2446 }, 2447 set: function( elem, value ) { 2448 return (elem.style.cssText = "" + value); 2449 } 2450 }; 2451 } 2452 2453 // Safari mis-reports the default selected property of an option 2454 // Accessing the parent's selectedIndex property fixes it 2455 if ( !jQuery.support.optSelected ) { 2456 jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, { 2457 get: function( elem ) { 2458 var parent = elem.parentNode; 2459 2460 if ( parent ) { 2461 parent.selectedIndex; 2462 2463 // Make sure that it also works with optgroups, see #5701 2464 if ( parent.parentNode ) { 2465 parent.parentNode.selectedIndex; 2466 } 2467 } 2468 } 2469 }); 2470 } 2471 2472 // Radios and checkboxes getter/setter 2473 if ( !jQuery.support.checkOn ) { 2474 jQuery.each([ "radio", "checkbox" ], function() { 2475 jQuery.valHooks[ this ] = { 2476 get: function( elem ) { 2477 // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified 2478 return elem.getAttribute("value") === null ? "on" : elem.value; 2479 } 2480 }; 2481 }); 2482 } 2483 jQuery.each([ "radio", "checkbox" ], function() { 2484 jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], { 2485 set: function( elem, value ) { 2486 if ( jQuery.isArray( value ) ) { 2487 return (elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0); 2488 } 2489 } 2490 }); 2491 }); 2492 2493 2494 2495 2496 var hasOwn = Object.prototype.hasOwnProperty, 2497 rnamespaces = /\.(.*)$/, 2498 rformElems = /^(?:textarea|input|select)$/i, 2499 rperiod = /\./g, 2500 rspaces = / /g, 2501 rescape = /[^\w\s.|`]/g, 2502 fcleanup = function( nm ) { 2503 return nm.replace(rescape, "\\$&"); 2504 }; 2505 2506 /* 2507 * A number of helper functions used for managing events. 2508 * Many of the ideas behind this code originated from 2509 * Dean Edwards' addEvent library. 2510 */ 2511 jQuery.event = { 2512 2513 // Bind an event to an element 2514 // Original by Dean Edwards 2515 add: function( elem, types, handler, data ) { 2516 if ( elem.nodeType === 3 || elem.nodeType === 8 ) { 2517 return; 2518 } 2519 2520 if ( handler === false ) { 2521 handler = returnFalse; 2522 } else if ( !handler ) { 2523 // Fixes bug #7229. Fix recommended by jdalton 2524 return; 2525 } 2526 2527 var handleObjIn, handleObj; 2528 2529 if ( handler.handler ) { 2530 handleObjIn = handler; 2531 handler = handleObjIn.handler; 2532 } 2533 2534 // Make sure that the function being executed has a unique ID 2535 if ( !handler.guid ) { 2536 handler.guid = jQuery.guid++; 2537 } 2538 2539 // Init the element's event structure 2540 var elemData = jQuery._data( elem ); 2541 2542 // If no elemData is found then we must be trying to bind to one of the 2543 // banned noData elements 2544 if ( !elemData ) { 2545 return; 2546 } 2547 2548 var events = elemData.events, 2549 eventHandle = elemData.handle; 2550 2551 if ( !events ) { 2552 elemData.events = events = {}; 2553 } 2554 2555 if ( !eventHandle ) { 2556 elemData.handle = eventHandle = function( e ) { 2557 // Discard the second event of a jQuery.event.trigger() and 2558 // when an event is called after a page has unloaded 2559 return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ? 2560 jQuery.event.handle.apply( eventHandle.elem, arguments ) : 2561 undefined; 2562 }; 2563 } 2564 2565 // Add elem as a property of the handle function 2566 // This is to prevent a memory leak with non-native events in IE. 2567 eventHandle.elem = elem; 2568 2569 // Handle multiple events separated by a space 2570 // jQuery(...).bind("mouseover mouseout", fn); 2571 types = types.split(" "); 2572 2573 var type, i = 0, namespaces; 2574 2575 while ( (type = types[ i++ ]) ) { 2576 handleObj = handleObjIn ? 2577 jQuery.extend({}, handleObjIn) : 2578 { handler: handler, data: data }; 2579 2580 // Namespaced event handlers 2581 if ( type.indexOf(".") > -1 ) { 2582 namespaces = type.split("."); 2583 type = namespaces.shift(); 2584 handleObj.namespace = namespaces.slice(0).sort().join("."); 2585 2586 } else { 2587 namespaces = []; 2588 handleObj.namespace = ""; 2589 } 2590 2591 handleObj.type = type; 2592 if ( !handleObj.guid ) { 2593 handleObj.guid = handler.guid; 2594 } 2595 2596 // Get the current list of functions bound to this event 2597 var handlers = events[ type ], 2598 special = jQuery.event.special[ type ] || {}; 2599 2600 // Init the event handler queue 2601 if ( !handlers ) { 2602 handlers = events[ type ] = []; 2603 2604 // Check for a special event handler 2605 // Only use addEventListener/attachEvent if the special 2606 // events handler returns false 2607 if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { 2608 // Bind the global event handler to the element 2609 if ( elem.addEventListener ) { 2610 elem.addEventListener( type, eventHandle, false ); 2611 2612 } else if ( elem.attachEvent ) { 2613 elem.attachEvent( "on" + type, eventHandle ); 2614 } 2615 } 2616 } 2617 2618 if ( special.add ) { 2619 special.add.call( elem, handleObj ); 2620 2621 if ( !handleObj.handler.guid ) { 2622 handleObj.handler.guid = handler.guid; 2623 } 2624 } 2625 2626 // Add the function to the element's handler list 2627 handlers.push( handleObj ); 2628 2629 // Keep track of which events have been used, for event optimization 2630 jQuery.event.global[ type ] = true; 2631 } 2632 2633 // Nullify elem to prevent memory leaks in IE 2634 elem = null; 2635 }, 2636 2637 global: {}, 2638 2639 // Detach an event or set of events from an element 2640 remove: function( elem, types, handler, pos ) { 2641 // don't do events on text and comment nodes 2642 if ( elem.nodeType === 3 || elem.nodeType === 8 ) { 2643 return; 2644 } 2645 2646 if ( handler === false ) { 2647 handler = returnFalse; 2648 } 2649 2650 var ret, type, fn, j, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType, 2651 elemData = jQuery.hasData( elem ) && jQuery._data( elem ), 2652 events = elemData && elemData.events; 2653 2654 if ( !elemData || !events ) { 2655 return; 2656 } 2657 2658 // types is actually an event object here 2659 if ( types && types.type ) { 2660 handler = types.handler; 2661 types = types.type; 2662 } 2663 2664 // Unbind all events for the element 2665 if ( !types || typeof types === "string" && types.charAt(0) === "." ) { 2666 types = types || ""; 2667 2668 for ( type in events ) { 2669 jQuery.event.remove( elem, type + types ); 2670 } 2671 2672 return; 2673 } 2674 2675 // Handle multiple events separated by a space 2676 // jQuery(...).unbind("mouseover mouseout", fn); 2677 types = types.split(" "); 2678 2679 while ( (type = types[ i++ ]) ) { 2680 origType = type; 2681 handleObj = null; 2682 all = type.indexOf(".") < 0; 2683 namespaces = []; 2684 2685 if ( !all ) { 2686 // Namespaced event handlers 2687 namespaces = type.split("."); 2688 type = namespaces.shift(); 2689 2690 namespace = new RegExp("(^|\\.)" + 2691 jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)"); 2692 } 2693 2694 eventType = events[ type ]; 2695 2696 if ( !eventType ) { 2697 continue; 2698 } 2699 2700 if ( !handler ) { 2701 for ( j = 0; j < eventType.length; j++ ) { 2702 handleObj = eventType[ j ]; 2703 2704 if ( all || namespace.test( handleObj.namespace ) ) { 2705 jQuery.event.remove( elem, origType, handleObj.handler, j ); 2706 eventType.splice( j--, 1 ); 2707 } 2708 } 2709 2710 continue; 2711 } 2712 2713 special = jQuery.event.special[ type ] || {}; 2714 2715 for ( j = pos || 0; j < eventType.length; j++ ) { 2716 handleObj = eventType[ j ]; 2717 2718 if ( handler.guid === handleObj.guid ) { 2719 // remove the given handler for the given type 2720 if ( all || namespace.test( handleObj.namespace ) ) { 2721 if ( pos == null ) { 2722 eventType.splice( j--, 1 ); 2723 } 2724 2725 if ( special.remove ) { 2726 special.remove.call( elem, handleObj ); 2727 } 2728 } 2729 2730 if ( pos != null ) { 2731 break; 2732 } 2733 } 2734 } 2735 2736 // remove generic event handler if no more handlers exist 2737 if ( eventType.length === 0 || pos != null && eventType.length === 1 ) { 2738 if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) { 2739 jQuery.removeEvent( elem, type, elemData.handle ); 2740 } 2741 2742 ret = null; 2743 delete events[ type ]; 2744 } 2745 } 2746 2747 // Remove the expando if it's no longer used 2748 if ( jQuery.isEmptyObject( events ) ) { 2749 var handle = elemData.handle; 2750 if ( handle ) { 2751 handle.elem = null; 2752 } 2753 2754 delete elemData.events; 2755 delete elemData.handle; 2756 2757 if ( jQuery.isEmptyObject( elemData ) ) { 2758 jQuery.removeData( elem, undefined, true ); 2759 } 2760 } 2761 }, 2762 2763 // Events that are safe to short-circuit if no handlers are attached. 2764 // Native DOM events should not be added, they may have inline handlers. 2765 customEvent: { 2766 "getData": true, 2767 "setData": true, 2768 "changeData": true 2769 }, 2770 2771 trigger: function( event, data, elem, onlyHandlers ) { 2772 // Event object or event type 2773 var type = event.type || event, 2774 namespaces = [], 2775 exclusive; 2776 2777 if ( type.indexOf("!") >= 0 ) { 2778 // Exclusive events trigger only for the exact event (no namespaces) 2779 type = type.slice(0, -1); 2780 exclusive = true; 2781 } 2782 2783 if ( type.indexOf(".") >= 0 ) { 2784 // Namespaced trigger; create a regexp to match event type in handle() 2785 namespaces = type.split("."); 2786 type = namespaces.shift(); 2787 namespaces.sort(); 2788 } 2789 2790 if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) { 2791 // No jQuery handlers for this event type, and it can't have inline handlers 2792 return; 2793 } 2794 2795 // Caller can pass in an Event, Object, or just an event type string 2796 event = typeof event === "object" ? 2797 // jQuery.Event object 2798 event[ jQuery.expando ] ? event : 2799 // Object literal 2800 new jQuery.Event( type, event ) : 2801 // Just the event type (string) 2802 new jQuery.Event( type ); 2803 2804 event.type = type; 2805 event.exclusive = exclusive; 2806 event.namespace = namespaces.join("."); 2807 event.namespace_re = new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)"); 2808 2809 // triggerHandler() and global events don't bubble or run the default action 2810 if ( onlyHandlers || !elem ) { 2811 event.preventDefault(); 2812 event.stopPropagation(); 2813 } 2814 2815 // Handle a global trigger 2816 if ( !elem ) { 2817 // TODO: Stop taunting the data cache; remove global events and always attach to document 2818 jQuery.each( jQuery.cache, function() { 2819 // internalKey variable is just used to make it easier to find 2820 // and potentially change this stuff later; currently it just 2821 // points to jQuery.expando 2822 var internalKey = jQuery.expando, 2823 internalCache = this[ internalKey ]; 2824 if ( internalCache && internalCache.events && internalCache.events[ type ] ) { 2825 jQuery.event.trigger( event, data, internalCache.handle.elem ); 2826 } 2827 }); 2828 return; 2829 } 2830 2831 // Don't do events on text and comment nodes 2832 if ( elem.nodeType === 3 || elem.nodeType === 8 ) { 2833 return; 2834 } 2835 2836 // Clean up the event in case it is being reused 2837 event.result = undefined; 2838 event.target = elem; 2839 2840 // Clone any incoming data and prepend the event, creating the handler arg list 2841 data = data ? jQuery.makeArray( data ) : []; 2842 data.unshift( event ); 2843 2844 var cur = elem, 2845 // IE doesn't like method names with a colon (#3533, #8272) 2846 ontype = type.indexOf(":") < 0 ? "on" + type : ""; 2847 2848 // Fire event on the current element, then bubble up the DOM tree 2849 do { 2850 var handle = jQuery._data( cur, "handle" ); 2851 2852 event.currentTarget = cur; 2853 if ( handle ) { 2854 handle.apply( cur, data ); 2855 } 2856 2857 // Trigger an inline bound script 2858 if ( ontype && jQuery.acceptData( cur ) && cur[ ontype ] && cur[ ontype ].apply( cur, data ) === false ) { 2859 event.result = false; 2860 event.preventDefault(); 2861 } 2862 2863 // Bubble up to document, then to window 2864 cur = cur.parentNode || cur.ownerDocument || cur === event.target.ownerDocument && window; 2865 } while ( cur && !event.isPropagationStopped() ); 2866 2867 // If nobody prevented the default action, do it now 2868 if ( !event.isDefaultPrevented() ) { 2869 var old, 2870 special = jQuery.event.special[ type ] || {}; 2871 2872 if ( (!special._default || special._default.call( elem.ownerDocument, event ) === false) && 2873 !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) { 2874 2875 // Call a native DOM method on the target with the same name name as the event. 2876 // Can't use an .isFunction)() check here because IE6/7 fails that test. 2877 // IE<9 dies on focus to hidden element (#1486), may want to revisit a try/catch. 2878 try { 2879 if ( ontype && elem[ type ] ) { 2880 // Don't re-trigger an onFOO event when we call its FOO() method 2881 old = elem[ ontype ]; 2882 2883 if ( old ) { 2884 elem[ ontype ] = null; 2885 } 2886 2887 jQuery.event.triggered = type; 2888 elem[ type ](); 2889 } 2890 } catch ( ieError ) {} 2891 2892 if ( old ) { 2893 elem[ ontype ] = old; 2894 } 2895 2896 jQuery.event.triggered = undefined; 2897 } 2898 } 2899 2900 return event.result; 2901 }, 2902 2903 handle: function( event ) { 2904 event = jQuery.event.fix( event || window.event ); 2905 // Snapshot the handlers list since a called handler may add/remove events. 2906 var handlers = ((jQuery._data( this, "events" ) || {})[ event.type ] || []).slice(0), 2907 run_all = !event.exclusive && !event.namespace, 2908 args = Array.prototype.slice.call( arguments, 0 ); 2909 2910 // Use the fix-ed Event rather than the (read-only) native event 2911 args[0] = event; 2912 event.currentTarget = this; 2913 2914 for ( var j = 0, l = handlers.length; j < l; j++ ) { 2915 var handleObj = handlers[ j ]; 2916 2917 // Triggered event must 1) be non-exclusive and have no namespace, or 2918 // 2) have namespace(s) a subset or equal to those in the bound event. 2919 if ( run_all || event.namespace_re.test( handleObj.namespace ) ) { 2920 // Pass in a reference to the handler function itself 2921 // So that we can later remove it 2922 event.handler = handleObj.handler; 2923 event.data = handleObj.data; 2924 event.handleObj = handleObj; 2925 2926 var ret = handleObj.handler.apply( this, args ); 2927 2928 if ( ret !== undefined ) { 2929 event.result = ret; 2930 if ( ret === false ) { 2931 event.preventDefault(); 2932 event.stopPropagation(); 2933 } 2934 } 2935 2936 if ( event.isImmediatePropagationStopped() ) { 2937 break; 2938 } 2939 } 2940 } 2941 return event.result; 2942 }, 2943 2944 props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "), 2945 2946 fix: function( event ) { 2947 if ( event[ jQuery.expando ] ) { 2948 return event; 2949 } 2950 2951 // store a copy of the original event object 2952 // and "clone" to set read-only properties 2953 var originalEvent = event; 2954 event = jQuery.Event( originalEvent ); 2955 2956 for ( var i = this.props.length, prop; i; ) { 2957 prop = this.props[ --i ]; 2958 event[ prop ] = originalEvent[ prop ]; 2959 } 2960 2961 // Fix target property, if necessary 2962 if ( !event.target ) { 2963 // Fixes #1925 where srcElement might not be defined either 2964 event.target = event.srcElement || document; 2965 } 2966 2967 // check if target is a textnode (safari) 2968 if ( event.target.nodeType === 3 ) { 2969 event.target = event.target.parentNode; 2970 } 2971 2972 // Add relatedTarget, if necessary 2973 if ( !event.relatedTarget && event.fromElement ) { 2974 event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement; 2975 } 2976 2977 // Calculate pageX/Y if missing and clientX/Y available 2978 if ( event.pageX == null && event.clientX != null ) { 2979 var eventDocument = event.target.ownerDocument || document, 2980 doc = eventDocument.documentElement, 2981 body = eventDocument.body; 2982 2983 event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0); 2984 event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0); 2985 } 2986 2987 // Add which for key events 2988 if ( event.which == null && (event.charCode != null || event.keyCode != null) ) { 2989 event.which = event.charCode != null ? event.charCode : event.keyCode; 2990 } 2991 2992 // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs) 2993 if ( !event.metaKey && event.ctrlKey ) { 2994 event.metaKey = event.ctrlKey; 2995 } 2996 2997 // Add which for click: 1 === left; 2 === middle; 3 === right 2998 // Note: button is not normalized, so don't use it 2999 if ( !event.which && event.button !== undefined ) { 3000 event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) )); 3001 } 3002 3003 return event; 3004 }, 3005 3006 // Deprecated, use jQuery.guid instead 3007 guid: 1E8, 3008 3009 // Deprecated, use jQuery.proxy instead 3010 proxy: jQuery.proxy, 3011 3012 special: { 3013 ready: { 3014 // Make sure the ready event is setup 3015 setup: jQuery.bindReady, 3016 teardown: jQuery.noop 3017 }, 3018 3019 live: { 3020 add: function( handleObj ) { 3021 jQuery.event.add( this, 3022 liveConvert( handleObj.origType, handleObj.selector ), 3023 jQuery.extend({}, handleObj, {handler: liveHandler, guid: handleObj.handler.guid}) ); 3024 }, 3025 3026 remove: function( handleObj ) { 3027 jQuery.event.remove( this, liveConvert( handleObj.origType, handleObj.selector ), handleObj ); 3028 } 3029 }, 3030 3031 beforeunload: { 3032 setup: function( data, namespaces, eventHandle ) { 3033 // We only want to do this special case on windows 3034 if ( jQuery.isWindow( this ) ) { 3035 this.onbeforeunload = eventHandle; 3036 } 3037 }, 3038 3039 teardown: function( namespaces, eventHandle ) { 3040 if ( this.onbeforeunload === eventHandle ) { 3041 this.onbeforeunload = null; 3042 } 3043 } 3044 } 3045 } 3046 }; 3047 3048 jQuery.removeEvent = document.removeEventListener ? 3049 function( elem, type, handle ) { 3050 if ( elem.removeEventListener ) { 3051 elem.removeEventListener( type, handle, false ); 3052 } 3053 } : 3054 function( elem, type, handle ) { 3055 if ( elem.detachEvent ) { 3056 elem.detachEvent( "on" + type, handle ); 3057 } 3058 }; 3059 3060 jQuery.Event = function( src, props ) { 3061 // Allow instantiation without the 'new' keyword 3062 if ( !this.preventDefault ) { 3063 return new jQuery.Event( src, props ); 3064 } 3065 3066 // Event object 3067 if ( src && src.type ) { 3068 this.originalEvent = src; 3069 this.type = src.type; 3070 3071 // Events bubbling up the document may have been marked as prevented 3072 // by a handler lower down the tree; reflect the correct value. 3073 this.isDefaultPrevented = (src.defaultPrevented || src.returnValue === false || 3074 src.getPreventDefault && src.getPreventDefault()) ? returnTrue : returnFalse; 3075 3076 // Event type 3077 } else { 3078 this.type = src; 3079 } 3080 3081 // Put explicitly provided properties onto the event object 3082 if ( props ) { 3083 jQuery.extend( this, props ); 3084 } 3085 3086 // timeStamp is buggy for some events on Firefox(#3843) 3087 // So we won't rely on the native value 3088 this.timeStamp = jQuery.now(); 3089 3090 // Mark it as fixed 3091 this[ jQuery.expando ] = true; 3092 }; 3093 3094 function returnFalse() { 3095 return false; 3096 } 3097 function returnTrue() { 3098 return true; 3099 } 3100 3101 // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding 3102 // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html 3103 jQuery.Event.prototype = { 3104 preventDefault: function() { 3105 this.isDefaultPrevented = returnTrue; 3106 3107 var e = this.originalEvent; 3108 if ( !e ) { 3109 return; 3110 } 3111 3112 // if preventDefault exists run it on the original event 3113 if ( e.preventDefault ) { 3114 e.preventDefault(); 3115 3116 // otherwise set the returnValue property of the original event to false (IE) 3117 } else { 3118 e.returnValue = false; 3119 } 3120 }, 3121 stopPropagation: function() { 3122 this.isPropagationStopped = returnTrue; 3123 3124 var e = this.originalEvent; 3125 if ( !e ) { 3126 return; 3127 } 3128 // if stopPropagation exists run it on the original event 3129 if ( e.stopPropagation ) { 3130 e.stopPropagation(); 3131 } 3132 // otherwise set the cancelBubble property of the original event to true (IE) 3133 e.cancelBubble = true; 3134 }, 3135 stopImmediatePropagation: function() { 3136 this.isImmediatePropagationStopped = returnTrue; 3137 this.stopPropagation(); 3138 }, 3139 isDefaultPrevented: returnFalse, 3140 isPropagationStopped: returnFalse, 3141 isImmediatePropagationStopped: returnFalse 3142 }; 3143 3144 // Checks if an event happened on an element within another element 3145 // Used in jQuery.event.special.mouseenter and mouseleave handlers 3146 var withinElement = function( event ) { 3147 // Check if mouse(over|out) are still within the same parent element 3148 var parent = event.relatedTarget; 3149 3150 // set the correct event type 3151 event.type = event.data; 3152 3153 // Firefox sometimes assigns relatedTarget a XUL element 3154 // which we cannot access the parentNode property of 3155 try { 3156 3157 // Chrome does something similar, the parentNode property 3158 // can be accessed but is null. 3159 if ( parent && parent !== document && !parent.parentNode ) { 3160 return; 3161 } 3162 3163 // Traverse up the tree 3164 while ( parent && parent !== this ) { 3165 parent = parent.parentNode; 3166 } 3167 3168 if ( parent !== this ) { 3169 // handle event if we actually just moused on to a non sub-element 3170 jQuery.event.handle.apply( this, arguments ); 3171 } 3172 3173 // assuming we've left the element since we most likely mousedover a xul element 3174 } catch(e) { } 3175 }, 3176 3177 // In case of event delegation, we only need to rename the event.type, 3178 // liveHandler will take care of the rest. 3179 delegate = function( event ) { 3180 event.type = event.data; 3181 jQuery.event.handle.apply( this, arguments ); 3182 }; 3183 3184 // Create mouseenter and mouseleave events 3185 jQuery.each({ 3186 mouseenter: "mouseover", 3187 mouseleave: "mouseout" 3188 }, function( orig, fix ) { 3189 jQuery.event.special[ orig ] = { 3190 setup: function( data ) { 3191 jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig ); 3192 }, 3193 teardown: function( data ) { 3194 jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement ); 3195 } 3196 }; 3197 }); 3198 3199 // submit delegation 3200 if ( !jQuery.support.submitBubbles ) { 3201 3202 jQuery.event.special.submit = { 3203 setup: function( data, namespaces ) { 3204 if ( !jQuery.nodeName( this, "form" ) ) { 3205 jQuery.event.add(this, "click.specialSubmit", function( e ) { 3206 var elem = e.target, 3207 type = elem.type; 3208 3209 if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) { 3210 trigger( "submit", this, arguments ); 3211 } 3212 }); 3213 3214 jQuery.event.add(this, "keypress.specialSubmit", function( e ) { 3215 var elem = e.target, 3216 type = elem.type; 3217 3218 if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) { 3219 trigger( "submit", this, arguments ); 3220 } 3221 }); 3222 3223 } else { 3224 return false; 3225 } 3226 }, 3227 3228 teardown: function( namespaces ) { 3229 jQuery.event.remove( this, ".specialSubmit" ); 3230 } 3231 }; 3232 3233 } 3234 3235 // change delegation, happens here so we have bind. 3236 if ( !jQuery.support.changeBubbles ) { 3237 3238 var changeFilters, 3239 3240 getVal = function( elem ) { 3241 var type = elem.type, val = elem.value; 3242 3243 if ( type === "radio" || type === "checkbox" ) { 3244 val = elem.checked; 3245 3246 } else if ( type === "select-multiple" ) { 3247 val = elem.selectedIndex > -1 ? 3248 jQuery.map( elem.options, function( elem ) { 3249 return elem.selected; 3250 }).join("-") : 3251 ""; 3252 3253 } else if ( jQuery.nodeName( elem, "select" ) ) { 3254 val = elem.selectedIndex; 3255 } 3256 3257 return val; 3258 }, 3259 3260 testChange = function testChange( e ) { 3261 var elem = e.target, data, val; 3262 3263 if ( !rformElems.test( elem.nodeName ) || elem.readOnly ) { 3264 return; 3265 } 3266 3267 data = jQuery._data( elem, "_change_data" ); 3268 val = getVal(elem); 3269 3270 // the current data will be also retrieved by beforeactivate 3271 if ( e.type !== "focusout" || elem.type !== "radio" ) { 3272 jQuery._data( elem, "_change_data", val ); 3273 } 3274 3275 if ( data === undefined || val === data ) { 3276 return; 3277 } 3278 3279 if ( data != null || val ) { 3280 e.type = "change"; 3281 e.liveFired = undefined; 3282 jQuery.event.trigger( e, arguments[1], elem ); 3283 } 3284 }; 3285 3286 jQuery.event.special.change = { 3287 filters: { 3288 focusout: testChange, 3289 3290 beforedeactivate: testChange, 3291 3292 click: function( e ) { 3293 var elem = e.target, type = jQuery.nodeName( elem, "input" ) ? elem.type : ""; 3294 3295 if ( type === "radio" || type === "checkbox" || jQuery.nodeName( elem, "select" ) ) { 3296 testChange.call( this, e ); 3297 } 3298 }, 3299 3300 // Change has to be called before submit 3301 // Keydown will be called before keypress, which is used in submit-event delegation 3302 keydown: function( e ) { 3303 var elem = e.target, type = jQuery.nodeName( elem, "input" ) ? elem.type : ""; 3304 3305 if ( (e.keyCode === 13 && !jQuery.nodeName( elem, "textarea" ) ) || 3306 (e.keyCode === 32 && (type === "checkbox" || type === "radio")) || 3307 type === "select-multiple" ) { 3308 testChange.call( this, e ); 3309 } 3310 }, 3311 3312 // Beforeactivate happens also before the previous element is blurred 3313 // with this event you can't trigger a change event, but you can store 3314 // information 3315 beforeactivate: function( e ) { 3316 var elem = e.target; 3317 jQuery._data( elem, "_change_data", getVal(elem) ); 3318 } 3319 }, 3320 3321 setup: function( data, namespaces ) { 3322 if ( this.type === "file" ) { 3323 return false; 3324 } 3325 3326 for ( var type in changeFilters ) { 3327 jQuery.event.add( this, type + ".specialChange", changeFilters[type] ); 3328 } 3329 3330 return rformElems.test( this.nodeName ); 3331 }, 3332 3333 teardown: function( namespaces ) { 3334 jQuery.event.remove( this, ".specialChange" ); 3335 3336 return rformElems.test( this.nodeName ); 3337 } 3338 }; 3339 3340 changeFilters = jQuery.event.special.change.filters; 3341 3342 // Handle when the input is .focus()'d 3343 changeFilters.focus = changeFilters.beforeactivate; 3344 } 3345 3346 function trigger( type, elem, args ) { 3347 // Piggyback on a donor event to simulate a different one. 3348 // Fake originalEvent to avoid donor's stopPropagation, but if the 3349 // simulated event prevents default then we do the same on the donor. 3350 // Don't pass args or remember liveFired; they apply to the donor event. 3351 var event = jQuery.extend( {}, args[ 0 ] ); 3352 event.type = type; 3353 event.originalEvent = {}; 3354 event.liveFired = undefined; 3355 jQuery.event.handle.call( elem, event ); 3356 if ( event.isDefaultPrevented() ) { 3357 args[ 0 ].preventDefault(); 3358 } 3359 } 3360 3361 // Create "bubbling" focus and blur events 3362 if ( !jQuery.support.focusinBubbles ) { 3363 jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { 3364 3365 // Attach a single capturing handler while someone wants focusin/focusout 3366 var attaches = 0; 3367 3368 jQuery.event.special[ fix ] = { 3369 setup: function() { 3370 if ( attaches++ === 0 ) { 3371 document.addEventListener( orig, handler, true ); 3372 } 3373 }, 3374 teardown: function() { 3375 if ( --attaches === 0 ) { 3376 document.removeEventListener( orig, handler, true ); 3377 } 3378 } 3379 }; 3380 3381 function handler( donor ) { 3382 // Donor event is always a native one; fix it and switch its type. 3383 // Let focusin/out handler cancel the donor focus/blur event. 3384 var e = jQuery.event.fix( donor ); 3385 e.type = fix; 3386 e.originalEvent = {}; 3387 jQuery.event.trigger( e, null, e.target ); 3388 if ( e.isDefaultPrevented() ) { 3389 donor.preventDefault(); 3390 } 3391 } 3392 }); 3393 } 3394 3395 jQuery.each(["bind", "one"], function( i, name ) { 3396 jQuery.fn[ name ] = function( type, data, fn ) { 3397 var handler; 3398 3399 // Handle object literals 3400 if ( typeof type === "object" ) { 3401 for ( var key in type ) { 3402 this[ name ](key, data, type[key], fn); 3403 } 3404 return this; 3405 } 3406 3407 if ( arguments.length === 2 || data === false ) { 3408 fn = data; 3409 data = undefined; 3410 } 3411 3412 if ( name === "one" ) { 3413 handler = function( event ) { 3414 jQuery( this ).unbind( event, handler ); 3415 return fn.apply( this, arguments ); 3416 }; 3417 handler.guid = fn.guid || jQuery.guid++; 3418 } else { 3419 handler = fn; 3420 } 3421 3422 if ( type === "unload" && name !== "one" ) { 3423 this.one( type, data, fn ); 3424 3425 } else { 3426 for ( var i = 0, l = this.length; i < l; i++ ) { 3427 jQuery.event.add( this[i], type, handler, data ); 3428 } 3429 } 3430 3431 return this; 3432 }; 3433 }); 3434 3435 jQuery.fn.extend({ 3436 unbind: function( type, fn ) { 3437 // Handle object literals 3438 if ( typeof type === "object" && !type.preventDefault ) { 3439 for ( var key in type ) { 3440 this.unbind(key, type[key]); 3441 } 3442 3443 } else { 3444 for ( var i = 0, l = this.length; i < l; i++ ) { 3445 jQuery.event.remove( this[i], type, fn ); 3446 } 3447 } 3448 3449 return this; 3450 }, 3451 3452 delegate: function( selector, types, data, fn ) { 3453 return this.live( types, data, fn, selector ); 3454 }, 3455 3456 undelegate: function( selector, types, fn ) { 3457 if ( arguments.length === 0 ) { 3458 return this.unbind( "live" ); 3459 3460 } else { 3461 return this.die( types, null, fn, selector ); 3462 } 3463 }, 3464 3465 trigger: function( type, data ) { 3466 return this.each(function() { 3467 jQuery.event.trigger( type, data, this ); 3468 }); 3469 }, 3470 3471 triggerHandler: function( type, data ) { 3472 if ( this[0] ) { 3473 return jQuery.event.trigger( type, data, this[0], true ); 3474 } 3475 }, 3476 3477 toggle: function( fn ) { 3478 // Save reference to arguments for access in closure 3479 var args = arguments, 3480 guid = fn.guid || jQuery.guid++, 3481 i = 0, 3482 toggler = function( event ) { 3483 // Figure out which function to execute 3484 var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i; 3485 jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 ); 3486 3487 // Make sure that clicks stop 3488 event.preventDefault(); 3489 3490 // and execute the function 3491 return args[ lastToggle ].apply( this, arguments ) || false; 3492 }; 3493 3494 // link all the functions, so any of them can unbind this click handler 3495 toggler.guid = guid; 3496 while ( i < args.length ) { 3497 args[ i++ ].guid = guid; 3498 } 3499 3500 return this.click( toggler ); 3501 }, 3502 3503 hover: function( fnOver, fnOut ) { 3504 return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); 3505 } 3506 }); 3507 3508 var liveMap = { 3509 focus: "focusin", 3510 blur: "focusout", 3511 mouseenter: "mouseover", 3512 mouseleave: "mouseout" 3513 }; 3514 3515 jQuery.each(["live", "die"], function( i, name ) { 3516 jQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) { 3517 var type, i = 0, match, namespaces, preType, 3518 selector = origSelector || this.selector, 3519 context = origSelector ? this : jQuery( this.context ); 3520 3521 if ( typeof types === "object" && !types.preventDefault ) { 3522 for ( var key in types ) { 3523 context[ name ]( key, data, types[key], selector ); 3524 } 3525 3526 return this; 3527 } 3528 3529 if ( name === "die" && !types && 3530 origSelector && origSelector.charAt(0) === "." ) { 3531 3532 context.unbind( origSelector ); 3533 3534 return this; 3535 } 3536 3537 if ( data === false || jQuery.isFunction( data ) ) { 3538 fn = data || returnFalse; 3539 data = undefined; 3540 } 3541 3542 types = (types || "").split(" "); 3543 3544 while ( (type = types[ i++ ]) != null ) { 3545 match = rnamespaces.exec( type ); 3546 namespaces = ""; 3547 3548 if ( match ) { 3549 namespaces = match[0]; 3550 type = type.replace( rnamespaces, "" ); 3551 } 3552 3553 if ( type === "hover" ) { 3554 types.push( "mouseenter" + namespaces, "mouseleave" + namespaces ); 3555 continue; 3556 } 3557 3558 preType = type; 3559 3560 if ( liveMap[ type ] ) { 3561 types.push( liveMap[ type ] + namespaces ); 3562 type = type + namespaces; 3563 3564 } else { 3565 type = (liveMap[ type ] || type) + namespaces; 3566 } 3567 3568 if ( name === "live" ) { 3569 // bind live handler 3570 for ( var j = 0, l = context.length; j < l; j++ ) { 3571 jQuery.event.add( context[j], "live." + liveConvert( type, selector ), 3572 { data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } ); 3573 } 3574 3575 } else { 3576 // unbind live handler 3577 context.unbind( "live." + liveConvert( type, selector ), fn ); 3578 } 3579 } 3580 3581 return this; 3582 }; 3583 }); 3584 3585 function liveHandler( event ) { 3586 var stop, maxLevel, related, match, handleObj, elem, j, i, l, data, close, namespace, ret, 3587 elems = [], 3588 selectors = [], 3589 events = jQuery._data( this, "events" ); 3590 3591 // Make sure we avoid non-left-click bubbling in Firefox (#3861) and disabled elements in IE (#6911) 3592 if ( event.liveFired === this || !events || !events.live || event.target.disabled || event.button && event.type === "click" ) { 3593 return; 3594 } 3595 3596 if ( event.namespace ) { 3597 namespace = new RegExp("(^|\\.)" + event.namespace.split(".").join("\\.(?:.*\\.)?") + "(\\.|$)"); 3598 } 3599 3600 event.liveFired = this; 3601 3602 var live = events.live.slice(0); 3603 3604 for ( j = 0; j < live.length; j++ ) { 3605 handleObj = live[j]; 3606 3607 if ( handleObj.origType.replace( rnamespaces, "" ) === event.type ) { 3608 selectors.push( handleObj.selector ); 3609 3610 } else { 3611 live.splice( j--, 1 ); 3612 } 3613 } 3614 3615 match = jQuery( event.target ).closest( selectors, event.currentTarget ); 3616 3617 for ( i = 0, l = match.length; i < l; i++ ) { 3618 close = match[i]; 3619 3620 for ( j = 0; j < live.length; j++ ) { 3621 handleObj = live[j]; 3622 3623 if ( close.selector === handleObj.selector && (!namespace || namespace.test( handleObj.namespace )) && !close.elem.disabled ) { 3624 elem = close.elem; 3625 related = null; 3626 3627 // Those two events require additional checking 3628 if ( handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave" ) { 3629 event.type = handleObj.preType; 3630 related = jQuery( event.relatedTarget ).closest( handleObj.selector )[0]; 3631 3632 // Make sure not to accidentally match a child element with the same selector 3633 if ( related && jQuery.contains( elem, related ) ) { 3634 related = elem; 3635 } 3636 } 3637 3638 if ( !related || related !== elem ) { 3639 elems.push({ elem: elem, handleObj: handleObj, level: close.level }); 3640 } 3641 } 3642 } 3643 } 3644 3645 for ( i = 0, l = elems.length; i < l; i++ ) { 3646 match = elems[i]; 3647 3648 if ( maxLevel && match.level > maxLevel ) { 3649 break; 3650 } 3651 3652 event.currentTarget = match.elem; 3653 event.data = match.handleObj.data; 3654 event.handleObj = match.handleObj; 3655 3656 ret = match.handleObj.origHandler.apply( match.elem, arguments ); 3657 3658 if ( ret === false || event.isPropagationStopped() ) { 3659 maxLevel = match.level; 3660 3661 if ( ret === false ) { 3662 stop = false; 3663 } 3664 if ( event.isImmediatePropagationStopped() ) { 3665 break; 3666 } 3667 } 3668 } 3669 3670 return stop; 3671 } 3672 3673 function liveConvert( type, selector ) { 3674 return (type && type !== "*" ? type + "." : "") + selector.replace(rperiod, "`").replace(rspaces, "&"); 3675 } 3676 3677 jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " + 3678 "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + 3679 "change select submit keydown keypress keyup error").split(" "), function( i, name ) { 3680 3681 // Handle event binding 3682 jQuery.fn[ name ] = function( data, fn ) { 3683 if ( fn == null ) { 3684 fn = data; 3685 data = null; 3686 } 3687 3688 return arguments.length > 0 ? 3689 this.bind( name, data, fn ) : 3690 this.trigger( name ); 3691 }; 3692 3693 if ( jQuery.attrFn ) { 3694 jQuery.attrFn[ name ] = true; 3695 } 3696 }); 3697 3698 3699 3700 /*! 3701 * Sizzle CSS Selector Engine 3702 * Copyright 2011, The Dojo Foundation 3703 * Released under the MIT, BSD, and GPL Licenses. 3704 * More information: http://sizzlejs.com/ 3705 */ 3706 (function(){ 3707 3708 var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, 3709 done = 0, 3710 toString = Object.prototype.toString, 3711 hasDuplicate = false, 3712 baseHasDuplicate = true, 3713 rBackslash = /\\/g, 3714 rNonWord = /\W/; 3715 3716 // Here we check if the JavaScript engine is using some sort of 3717 // optimization where it does not always call our comparision 3718 // function. If that is the case, discard the hasDuplicate value. 3719 // Thus far that includes Google Chrome. 3720 [0, 0].sort(function() { 3721 baseHasDuplicate = false; 3722 return 0; 3723 }); 3724 3725 var Sizzle = function( selector, context, results, seed ) { 3726 results = results || []; 3727 context = context || document; 3728 3729 var origContext = context; 3730 3731 if ( context.nodeType !== 1 && context.nodeType !== 9 ) { 3732 return []; 3733 } 3734 3735 if ( !selector || typeof selector !== "string" ) { 3736 return results; 3737 } 3738 3739 var m, set, checkSet, extra, ret, cur, pop, i, 3740 prune = true, 3741 contextXML = Sizzle.isXML( context ), 3742 parts = [], 3743 soFar = selector; 3744 3745 // Reset the position of the chunker regexp (start from head) 3746 do { 3747 chunker.exec( "" ); 3748 m = chunker.exec( soFar ); 3749 3750 if ( m ) { 3751 soFar = m[3]; 3752 3753 parts.push( m[1] ); 3754 3755 if ( m[2] ) { 3756 extra = m[3]; 3757 break; 3758 } 3759 } 3760 } while ( m ); 3761 3762 if ( parts.length > 1 && origPOS.exec( selector ) ) { 3763 3764 if ( parts.length === 2 && Expr.relative[ parts[0] ] ) { 3765 set = posProcess( parts[0] + parts[1], context ); 3766 3767 } else { 3768 set = Expr.relative[ parts[0] ] ? 3769 [ context ] : 3770 Sizzle( parts.shift(), context ); 3771 3772 while ( parts.length ) { 3773 selector = parts.shift(); 3774 3775 if ( Expr.relative[ selector ] ) { 3776 selector += parts.shift(); 3777 } 3778 3779 set = posProcess( selector, set ); 3780 } 3781 } 3782 3783 } else { 3784 // Take a shortcut and set the context if the root selector is an ID 3785 // (but not if it'll be faster if the inner selector is an ID) 3786 if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML && 3787 Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) { 3788 3789 ret = Sizzle.find( parts.shift(), context, contextXML ); 3790 context = ret.expr ? 3791 Sizzle.filter( ret.expr, ret.set )[0] : 3792 ret.set[0]; 3793 } 3794 3795 if ( context ) { 3796 ret = seed ? 3797 { expr: parts.pop(), set: makeArray(seed) } : 3798 Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML ); 3799 3800 set = ret.expr ? 3801 Sizzle.filter( ret.expr, ret.set ) : 3802 ret.set; 3803 3804 if ( parts.length > 0 ) { 3805 checkSet = makeArray( set ); 3806 3807 } else { 3808 prune = false; 3809 } 3810 3811 while ( parts.length ) { 3812 cur = parts.pop(); 3813 pop = cur; 3814 3815 if ( !Expr.relative[ cur ] ) { 3816 cur = ""; 3817 } else { 3818 pop = parts.pop(); 3819 } 3820 3821 if ( pop == null ) { 3822 pop = context; 3823 } 3824 3825 Expr.relative[ cur ]( checkSet, pop, contextXML ); 3826 } 3827 3828 } else { 3829 checkSet = parts = []; 3830 } 3831 } 3832 3833 if ( !checkSet ) { 3834 checkSet = set; 3835 } 3836 3837 if ( !checkSet ) { 3838 Sizzle.error( cur || selector ); 3839 } 3840 3841 if ( toString.call(checkSet) === "[object Array]" ) { 3842 if ( !prune ) { 3843 results.push.apply( results, checkSet ); 3844 3845 } else if ( context && context.nodeType === 1 ) { 3846 for ( i = 0; checkSet[i] != null; i++ ) { 3847 if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) { 3848 results.push( set[i] ); 3849 } 3850 } 3851 3852 } else { 3853 for ( i = 0; checkSet[i] != null; i++ ) { 3854 if ( checkSet[i] && checkSet[i].nodeType === 1 ) { 3855 results.push( set[i] ); 3856 } 3857 } 3858 } 3859 3860 } else { 3861 makeArray( checkSet, results ); 3862 } 3863 3864 if ( extra ) { 3865 Sizzle( extra, origContext, results, seed ); 3866 Sizzle.uniqueSort( results ); 3867 } 3868 3869 return results; 3870 }; 3871 3872 Sizzle.uniqueSort = function( results ) { 3873 if ( sortOrder ) { 3874 hasDuplicate = baseHasDuplicate; 3875 results.sort( sortOrder ); 3876 3877 if ( hasDuplicate ) { 3878 for ( var i = 1; i < results.length; i++ ) { 3879 if ( results[i] === results[ i - 1 ] ) { 3880 results.splice( i--, 1 ); 3881 } 3882 } 3883 } 3884 } 3885 3886 return results; 3887 }; 3888 3889 Sizzle.matches = function( expr, set ) { 3890 return Sizzle( expr, null, null, set ); 3891 }; 3892 3893 Sizzle.matchesSelector = function( node, expr ) { 3894 return Sizzle( expr, null, null, [node] ).length > 0; 3895 }; 3896 3897 Sizzle.find = function( expr, context, isXML ) { 3898 var set; 3899 3900 if ( !expr ) { 3901 return []; 3902 } 3903 3904 for ( var i = 0, l = Expr.order.length; i < l; i++ ) { 3905 var match, 3906 type = Expr.order[i]; 3907 3908 if ( (match = Expr.leftMatch[ type ].exec( expr )) ) { 3909 var left = match[1]; 3910 match.splice( 1, 1 ); 3911 3912 if ( left.substr( left.length - 1 ) !== "\\" ) { 3913 match[1] = (match[1] || "").replace( rBackslash, "" ); 3914 set = Expr.find[ type ]( match, context, isXML ); 3915 3916 if ( set != null ) { 3917 expr = expr.replace( Expr.match[ type ], "" ); 3918 break; 3919 } 3920 } 3921 } 3922 } 3923 3924 if ( !set ) { 3925 set = typeof context.getElementsByTagName !== "undefined" ? 3926 context.getElementsByTagName( "*" ) : 3927 []; 3928 } 3929 3930 return { set: set, expr: expr }; 3931 }; 3932 3933 Sizzle.filter = function( expr, set, inplace, not ) { 3934 var match, anyFound, 3935 old = expr, 3936 result = [], 3937 curLoop = set, 3938 isXMLFilter = set && set[0] && Sizzle.isXML( set[0] ); 3939 3940 while ( expr && set.length ) { 3941 for ( var type in Expr.filter ) { 3942 if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) { 3943 var found, item, 3944 filter = Expr.filter[ type ], 3945 left = match[1]; 3946 3947 anyFound = false; 3948 3949 match.splice(1,1); 3950 3951 if ( left.substr( left.length - 1 ) === "\\" ) { 3952 continue; 3953 } 3954 3955 if ( curLoop === result ) { 3956 result = []; 3957 } 3958 3959 if ( Expr.preFilter[ type ] ) { 3960 match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter ); 3961 3962 if ( !match ) { 3963 anyFound = found = true; 3964 3965 } else if ( match === true ) { 3966 continue; 3967 } 3968 } 3969 3970 if ( match ) { 3971 for ( var i = 0; (item = curLoop[i]) != null; i++ ) { 3972 if ( item ) { 3973 found = filter( item, match, i, curLoop ); 3974 var pass = not ^ !!found; 3975 3976 if ( inplace && found != null ) { 3977 if ( pass ) { 3978 anyFound = true; 3979 3980 } else { 3981 curLoop[i] = false; 3982 } 3983 3984 } else if ( pass ) { 3985 result.push( item ); 3986 anyFound = true; 3987 } 3988 } 3989 } 3990 } 3991 3992 if ( found !== undefined ) { 3993 if ( !inplace ) { 3994 curLoop = result; 3995 } 3996 3997 expr = expr.replace( Expr.match[ type ], "" ); 3998 3999 if ( !anyFound ) { 4000 return []; 4001 } 4002 4003 break; 4004 } 4005 } 4006 } 4007 4008 // Improper expression 4009 if ( expr === old ) { 4010 if ( anyFound == null ) { 4011 Sizzle.error( expr ); 4012 4013 } else { 4014 break; 4015 } 4016 } 4017 4018 old = expr; 4019 } 4020 4021 return curLoop; 4022 }; 4023 4024 Sizzle.error = function( msg ) { 4025 throw "Syntax error, unrecognized expression: " + msg; 4026 }; 4027 4028 var Expr = Sizzle.selectors = { 4029 order: [ "ID", "NAME", "TAG" ], 4030 4031 match: { 4032 ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, 4033 CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, 4034 NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/, 4035 ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/, 4036 TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/, 4037 CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/, 4038 POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/, 4039 PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/ 4040 }, 4041 4042 leftMatch: {}, 4043 4044 attrMap: { 4045 "class": "className", 4046 "for": "htmlFor" 4047 }, 4048 4049 attrHandle: { 4050 href: function( elem ) { 4051 return elem.getAttribute( "href" ); 4052 }, 4053 type: function( elem ) { 4054 return elem.getAttribute( "type" ); 4055 } 4056 }, 4057 4058 relative: { 4059 "+": function(checkSet, part){ 4060 var isPartStr = typeof part === "string", 4061 isTag = isPartStr && !rNonWord.test( part ), 4062 isPartStrNotTag = isPartStr && !isTag; 4063 4064 if ( isTag ) { 4065 part = part.toLowerCase(); 4066 } 4067 4068 for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) { 4069 if ( (elem = checkSet[i]) ) { 4070 while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {} 4071 4072 checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ? 4073 elem || false : 4074 elem === part; 4075 } 4076 } 4077 4078 if ( isPartStrNotTag ) { 4079 Sizzle.filter( part, checkSet, true ); 4080 } 4081 }, 4082 4083 ">": function( checkSet, part ) { 4084 var elem, 4085 isPartStr = typeof part === "string", 4086 i = 0, 4087 l = checkSet.length; 4088 4089 if ( isPartStr && !rNonWord.test( part ) ) { 4090 part = part.toLowerCase(); 4091 4092 for ( ; i < l; i++ ) { 4093 elem = checkSet[i]; 4094 4095 if ( elem ) { 4096 var parent = elem.parentNode; 4097 checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false; 4098 } 4099 } 4100 4101 } else { 4102 for ( ; i < l; i++ ) { 4103 elem = checkSet[i]; 4104 4105 if ( elem ) { 4106 checkSet[i] = isPartStr ? 4107 elem.parentNode : 4108 elem.parentNode === part; 4109 } 4110 } 4111 4112 if ( isPartStr ) { 4113 Sizzle.filter( part, checkSet, true ); 4114 } 4115 } 4116 }, 4117 4118 "": function(checkSet, part, isXML){ 4119 var nodeCheck, 4120 doneName = done++, 4121 checkFn = dirCheck; 4122 4123 if ( typeof part === "string" && !rNonWord.test( part ) ) { 4124 part = part.toLowerCase(); 4125 nodeCheck = part; 4126 checkFn = dirNodeCheck; 4127 } 4128 4129 checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML ); 4130 }, 4131 4132 "~": function( checkSet, part, isXML ) { 4133 var nodeCheck, 4134 doneName = done++, 4135 checkFn = dirCheck; 4136 4137 if ( typeof part === "string" && !rNonWord.test( part ) ) { 4138 part = part.toLowerCase(); 4139 nodeCheck = part; 4140 checkFn = dirNodeCheck; 4141 } 4142 4143 checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML ); 4144 } 4145 }, 4146 4147 find: { 4148 ID: function( match, context, isXML ) { 4149 if ( typeof context.getElementById !== "undefined" && !isXML ) { 4150 var m = context.getElementById(match[1]); 4151 // Check parentNode to catch when Blackberry 4.6 returns 4152 // nodes that are no longer in the document #6963 4153 return m && m.parentNode ? [m] : []; 4154 } 4155 }, 4156 4157 NAME: function( match, context ) { 4158 if ( typeof context.getElementsByName !== "undefined" ) { 4159 var ret = [], 4160 results = context.getElementsByName( match[1] ); 4161 4162 for ( var i = 0, l = results.length; i < l; i++ ) { 4163 if ( results[i].getAttribute("name") === match[1] ) { 4164 ret.push( results[i] ); 4165 } 4166 } 4167 4168 return ret.length === 0 ? null : ret; 4169 } 4170 }, 4171 4172 TAG: function( match, context ) { 4173 if ( typeof context.getElementsByTagName !== "undefined" ) { 4174 return context.getElementsByTagName( match[1] ); 4175 } 4176 } 4177 }, 4178 preFilter: { 4179 CLASS: function( match, curLoop, inplace, result, not, isXML ) { 4180 match = " " + match[1].replace( rBackslash, "" ) + " "; 4181 4182 if ( isXML ) { 4183 return match; 4184 } 4185 4186 for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) { 4187 if ( elem ) { 4188 if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) { 4189 if ( !inplace ) { 4190 result.push( elem ); 4191 } 4192 4193 } else if ( inplace ) { 4194 curLoop[i] = false; 4195 } 4196 } 4197 } 4198 4199 return false; 4200 }, 4201 4202 ID: function( match ) { 4203 return match[1].replace( rBackslash, "" ); 4204 }, 4205 4206 TAG: function( match, curLoop ) { 4207 return match[1].replace( rBackslash, "" ).toLowerCase(); 4208 }, 4209 4210 CHILD: function( match ) { 4211 if ( match[1] === "nth" ) { 4212 if ( !match[2] ) { 4213 Sizzle.error( match[0] ); 4214 } 4215 4216 match[2] = match[2].replace(/^\+|\s*/g, ''); 4217 4218 // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6' 4219 var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec( 4220 match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" || 4221 !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]); 4222 4223 // calculate the numbers (first)n+(last) including if they are negative 4224 match[2] = (test[1] + (test[2] || 1)) - 0; 4225 match[3] = test[3] - 0; 4226 } 4227 else if ( match[2] ) { 4228 Sizzle.error( match[0] ); 4229 } 4230 4231 // TODO: Move to normal caching system 4232 match[0] = done++; 4233 4234 return match; 4235 }, 4236 4237 ATTR: function( match, curLoop, inplace, result, not, isXML ) { 4238 var name = match[1] = match[1].replace( rBackslash, "" ); 4239 4240 if ( !isXML && Expr.attrMap[name] ) { 4241 match[1] = Expr.attrMap[name]; 4242 } 4243 4244 // Handle if an un-quoted value was used 4245 match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" ); 4246 4247 if ( match[2] === "~=" ) { 4248 match[4] = " " + match[4] + " "; 4249 } 4250 4251 return match; 4252 }, 4253 4254 PSEUDO: function( match, curLoop, inplace, result, not ) { 4255 if ( match[1] === "not" ) { 4256 // If we're dealing with a complex expression, or a simple one 4257 if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) { 4258 match[3] = Sizzle(match[3], null, null, curLoop); 4259 4260 } else { 4261 var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not); 4262 4263 if ( !inplace ) { 4264 result.push.apply( result, ret ); 4265 } 4266 4267 return false; 4268 } 4269 4270 } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) { 4271 return true; 4272 } 4273 4274 return match; 4275 }, 4276 4277 POS: function( match ) { 4278 match.unshift( true ); 4279 4280 return match; 4281 } 4282 }, 4283 4284 filters: { 4285 enabled: function( elem ) { 4286 return elem.disabled === false && elem.type !== "hidden"; 4287 }, 4288 4289 disabled: function( elem ) { 4290 return elem.disabled === true; 4291 }, 4292 4293 checked: function( elem ) { 4294 return elem.checked === true; 4295 }, 4296 4297 selected: function( elem ) { 4298 // Accessing this property makes selected-by-default 4299 // options in Safari work properly 4300 if ( elem.parentNode ) { 4301 elem.parentNode.selectedIndex; 4302 } 4303 4304 return elem.selected === true; 4305 }, 4306 4307 parent: function( elem ) { 4308 return !!elem.firstChild; 4309 }, 4310 4311 empty: function( elem ) { 4312 return !elem.firstChild; 4313 }, 4314 4315 has: function( elem, i, match ) { 4316 return !!Sizzle( match[3], elem ).length; 4317 }, 4318 4319 header: function( elem ) { 4320 return (/h\d/i).test( elem.nodeName ); 4321 }, 4322 4323 text: function( elem ) { 4324 var attr = elem.getAttribute( "type" ), type = elem.type; 4325 // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) 4326 // use getAttribute instead to test this case 4327 return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null ); 4328 }, 4329 4330 radio: function( elem ) { 4331 return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type; 4332 }, 4333 4334 checkbox: function( elem ) { 4335 return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type; 4336 }, 4337 4338 file: function( elem ) { 4339 return elem.nodeName.toLowerCase() === "input" && "file" === elem.type; 4340 }, 4341 4342 password: function( elem ) { 4343 return elem.nodeName.toLowerCase() === "input" && "password" === elem.type; 4344 }, 4345 4346 submit: function( elem ) { 4347 var name = elem.nodeName.toLowerCase(); 4348 return (name === "input" || name === "button") && "submit" === elem.type; 4349 }, 4350 4351 image: function( elem ) { 4352 return elem.nodeName.toLowerCase() === "input" && "image" === elem.type; 4353 }, 4354 4355 reset: function( elem ) { 4356 var name = elem.nodeName.toLowerCase(); 4357 return (name === "input" || name === "button") && "reset" === elem.type; 4358 }, 4359 4360 button: function( elem ) { 4361 var name = elem.nodeName.toLowerCase(); 4362 return name === "input" && "button" === elem.type || name === "button"; 4363 }, 4364 4365 input: function( elem ) { 4366 return (/input|select|textarea|button/i).test( elem.nodeName ); 4367 }, 4368 4369 focus: function( elem ) { 4370 return elem === elem.ownerDocument.activeElement; 4371 } 4372 }, 4373 setFilters: { 4374 first: function( elem, i ) { 4375 return i === 0; 4376 }, 4377 4378 last: function( elem, i, match, array ) { 4379 return i === array.length - 1; 4380 }, 4381 4382 even: function( elem, i ) { 4383 return i % 2 === 0; 4384 }, 4385 4386 odd: function( elem, i ) { 4387 return i % 2 === 1; 4388 }, 4389 4390 lt: function( elem, i, match ) { 4391 return i < match[3] - 0; 4392 }, 4393 4394 gt: function( elem, i, match ) { 4395 return i > match[3] - 0; 4396 }, 4397 4398 nth: function( elem, i, match ) { 4399 return match[3] - 0 === i; 4400 }, 4401 4402 eq: function( elem, i, match ) { 4403 return match[3] - 0 === i; 4404 } 4405 }, 4406 filter: { 4407 PSEUDO: function( elem, match, i, array ) { 4408 var name = match[1], 4409 filter = Expr.filters[ name ]; 4410 4411 if ( filter ) { 4412 return filter( elem, i, match, array ); 4413 4414 } else if ( name === "contains" ) { 4415 return (elem.textContent || elem.innerText || Sizzle.getText([ elem ]) || "").indexOf(match[3]) >= 0; 4416 4417 } else if ( name === "not" ) { 4418 var not = match[3]; 4419 4420 for ( var j = 0, l = not.length; j < l; j++ ) { 4421 if ( not[j] === elem ) { 4422 return false; 4423 } 4424 } 4425 4426 return true; 4427 4428 } else { 4429 Sizzle.error( name ); 4430 } 4431 }, 4432 4433 CHILD: function( elem, match ) { 4434 var type = match[1], 4435 node = elem; 4436 4437 switch ( type ) { 4438 case "only": 4439 case "first": 4440 while ( (node = node.previousSibling) ) { 4441 if ( node.nodeType === 1 ) { 4442 return false; 4443 } 4444 } 4445 4446 if ( type === "first" ) { 4447 return true; 4448 } 4449 4450 node = elem; 4451 4452 case "last": 4453 while ( (node = node.nextSibling) ) { 4454 if ( node.nodeType === 1 ) { 4455 return false; 4456 } 4457 } 4458 4459 return true; 4460 4461 case "nth": 4462 var first = match[2], 4463 last = match[3]; 4464 4465 if ( first === 1 && last === 0 ) { 4466 return true; 4467 } 4468 4469 var doneName = match[0], 4470 parent = elem.parentNode; 4471 4472 if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) { 4473 var count = 0; 4474 4475 for ( node = parent.firstChild; node; node = node.nextSibling ) { 4476 if ( node.nodeType === 1 ) { 4477 node.nodeIndex = ++count; 4478 } 4479 } 4480 4481 parent.sizcache = doneName; 4482 } 4483 4484 var diff = elem.nodeIndex - last; 4485 4486 if ( first === 0 ) { 4487 return diff === 0; 4488 4489 } else { 4490 return ( diff % first === 0 && diff / first >= 0 ); 4491 } 4492 } 4493 }, 4494 4495 ID: function( elem, match ) { 4496 return elem.nodeType === 1 && elem.getAttribute("id") === match; 4497 }, 4498 4499 TAG: function( elem, match ) { 4500 return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match; 4501 }, 4502 4503 CLASS: function( elem, match ) { 4504 return (" " + (elem.className || elem.getAttribute("class")) + " ") 4505 .indexOf( match ) > -1; 4506 }, 4507 4508 ATTR: function( elem, match ) { 4509 var name = match[1], 4510 result = Expr.attrHandle[ name ] ? 4511 Expr.attrHandle[ name ]( elem ) : 4512 elem[ name ] != null ? 4513 elem[ name ] : 4514 elem.getAttribute( name ), 4515 value = result + "", 4516 type = match[2], 4517 check = match[4]; 4518 4519 return result == null ? 4520 type === "!=" : 4521 type === "=" ? 4522 value === check : 4523 type === "*=" ? 4524 value.indexOf(check) >= 0 : 4525 type === "~=" ? 4526 (" " + value + " ").indexOf(check) >= 0 : 4527 !check ? 4528 value && result !== false : 4529 type === "!=" ? 4530 value !== check : 4531 type === "^=" ? 4532 value.indexOf(check) === 0 : 4533 type === "$=" ? 4534 value.substr(value.length - check.length) === check : 4535 type === "|=" ? 4536 value === check || value.substr(0, check.length + 1) === check + "-" : 4537 false; 4538 }, 4539 4540 POS: function( elem, match, i, array ) { 4541 var name = match[2], 4542 filter = Expr.setFilters[ name ]; 4543 4544 if ( filter ) { 4545 return filter( elem, i, match, array ); 4546 } 4547 } 4548 } 4549 }; 4550 4551 var origPOS = Expr.match.POS, 4552 fescape = function(all, num){ 4553 return "\\" + (num - 0 + 1); 4554 }; 4555 4556 for ( var type in Expr.match ) { 4557 Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) ); 4558 Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) ); 4559 } 4560 4561 var makeArray = function( array, results ) { 4562 array = Array.prototype.slice.call( array, 0 ); 4563 4564 if ( results ) { 4565 results.push.apply( results, array ); 4566 return results; 4567 } 4568 4569 return array; 4570 }; 4571 4572 // Perform a simple check to determine if the browser is capable of 4573 // converting a NodeList to an array using builtin methods. 4574 // Also verifies that the returned array holds DOM nodes 4575 // (which is not the case in the Blackberry browser) 4576 try { 4577 Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType; 4578 4579 // Provide a fallback method if it does not work 4580 } catch( e ) { 4581 makeArray = function( array, results ) { 4582 var i = 0, 4583 ret = results || []; 4584 4585 if ( toString.call(array) === "[object Array]" ) { 4586 Array.prototype.push.apply( ret, array ); 4587 4588 } else { 4589 if ( typeof array.length === "number" ) { 4590 for ( var l = array.length; i < l; i++ ) { 4591 ret.push( array[i] ); 4592 } 4593 4594 } else { 4595 for ( ; array[i]; i++ ) { 4596 ret.push( array[i] ); 4597 } 4598 } 4599 } 4600 4601 return ret; 4602 }; 4603 } 4604 4605 var sortOrder, siblingCheck; 4606 4607 if ( document.documentElement.compareDocumentPosition ) { 4608 sortOrder = function( a, b ) { 4609 if ( a === b ) { 4610 hasDuplicate = true; 4611 return 0; 4612 } 4613 4614 if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) { 4615 return a.compareDocumentPosition ? -1 : 1; 4616 } 4617 4618 return a.compareDocumentPosition(b) & 4 ? -1 : 1; 4619 }; 4620 4621 } else { 4622 sortOrder = function( a, b ) { 4623 // The nodes are identical, we can exit early 4624 if ( a === b ) { 4625 hasDuplicate = true; 4626 return 0; 4627 4628 // Fallback to using sourceIndex (in IE) if it's available on both nodes 4629 } else if ( a.sourceIndex && b.sourceIndex ) { 4630 return a.sourceIndex - b.sourceIndex; 4631 } 4632 4633 var al, bl, 4634 ap = [], 4635 bp = [], 4636 aup = a.parentNode, 4637 bup = b.parentNode, 4638 cur = aup; 4639 4640 // If the nodes are siblings (or identical) we can do a quick check 4641 if ( aup === bup ) { 4642 return siblingCheck( a, b ); 4643 4644 // If no parents were found then the nodes are disconnected 4645 } else if ( !aup ) { 4646 return -1; 4647 4648 } else if ( !bup ) { 4649 return 1; 4650 } 4651 4652 // Otherwise they're somewhere else in the tree so we need 4653 // to build up a full list of the parentNodes for comparison 4654 while ( cur ) { 4655 ap.unshift( cur ); 4656 cur = cur.parentNode; 4657 } 4658 4659 cur = bup; 4660 4661 while ( cur ) { 4662 bp.unshift( cur ); 4663 cur = cur.parentNode; 4664 } 4665 4666 al = ap.length; 4667 bl = bp.length; 4668 4669 // Start walking down the tree looking for a discrepancy 4670 for ( var i = 0; i < al && i < bl; i++ ) { 4671 if ( ap[i] !== bp[i] ) { 4672 return siblingCheck( ap[i], bp[i] ); 4673 } 4674 } 4675 4676 // We ended someplace up the tree so do a sibling check 4677 return i === al ? 4678 siblingCheck( a, bp[i], -1 ) : 4679 siblingCheck( ap[i], b, 1 ); 4680 }; 4681 4682 siblingCheck = function( a, b, ret ) { 4683 if ( a === b ) { 4684 return ret; 4685 } 4686 4687 var cur = a.nextSibling; 4688 4689 while ( cur ) { 4690 if ( cur === b ) { 4691 return -1; 4692 } 4693 4694 cur = cur.nextSibling; 4695 } 4696 4697 return 1; 4698 }; 4699 } 4700 4701 // Utility function for retreiving the text value of an array of DOM nodes 4702 Sizzle.getText = function( elems ) { 4703 var ret = "", elem; 4704 4705 for ( var i = 0; elems[i]; i++ ) { 4706 elem = elems[i]; 4707 4708 // Get the text from text nodes and CDATA nodes 4709 if ( elem.nodeType === 3 || elem.nodeType === 4 ) { 4710 ret += elem.nodeValue; 4711 4712 // Traverse everything else, except comment nodes 4713 } else if ( elem.nodeType !== 8 ) { 4714 ret += Sizzle.getText( elem.childNodes ); 4715 } 4716 } 4717 4718 return ret; 4719 }; 4720 4721 // Check to see if the browser returns elements by name when 4722 // querying by getElementById (and provide a workaround) 4723 (function(){ 4724 // We're going to inject a fake input element with a specified name 4725 var form = document.createElement("div"), 4726 id = "script" + (new Date()).getTime(), 4727 root = document.documentElement; 4728 4729 form.innerHTML = "<a name='" + id + "'/>"; 4730 4731 // Inject it into the root element, check its status, and remove it quickly 4732 root.insertBefore( form, root.firstChild ); 4733 4734 // The workaround has to do additional checks after a getElementById 4735 // Which slows things down for other browsers (hence the branching) 4736 if ( document.getElementById( id ) ) { 4737 Expr.find.ID = function( match, context, isXML ) { 4738 if ( typeof context.getElementById !== "undefined" && !isXML ) { 4739 var m = context.getElementById(match[1]); 4740 4741 return m ? 4742 m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? 4743 [m] : 4744 undefined : 4745 []; 4746 } 4747 }; 4748 4749 Expr.filter.ID = function( elem, match ) { 4750 var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); 4751 4752 return elem.nodeType === 1 && node && node.nodeValue === match; 4753 }; 4754 } 4755 4756 root.removeChild( form ); 4757 4758 // release memory in IE 4759 root = form = null; 4760 })(); 4761 4762 (function(){ 4763 // Check to see if the browser returns only elements 4764 // when doing getElementsByTagName("*") 4765 4766 // Create a fake element 4767 var div = document.createElement("div"); 4768 div.appendChild( document.createComment("") ); 4769 4770 // Make sure no comments are found 4771 if ( div.getElementsByTagName("*").length > 0 ) { 4772 Expr.find.TAG = function( match, context ) { 4773 var results = context.getElementsByTagName( match[1] ); 4774 4775 // Filter out possible comments 4776 if ( match[1] === "*" ) { 4777 var tmp = []; 4778 4779 for ( var i = 0; results[i]; i++ ) { 4780 if ( results[i].nodeType === 1 ) { 4781 tmp.push( results[i] ); 4782 } 4783 } 4784 4785 results = tmp; 4786 } 4787 4788 return results; 4789 }; 4790 } 4791 4792 // Check to see if an attribute returns normalized href attributes 4793 div.innerHTML = "<a href='#'></a>"; 4794 4795 if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" && 4796 div.firstChild.getAttribute("href") !== "#" ) { 4797 4798 Expr.attrHandle.href = function( elem ) { 4799 return elem.getAttribute( "href", 2 ); 4800 }; 4801 } 4802 4803 // release memory in IE 4804 div = null; 4805 })(); 4806 4807 if ( document.querySelectorAll ) { 4808 (function(){ 4809 var oldSizzle = Sizzle, 4810 div = document.createElement("div"), 4811 id = "__sizzle__"; 4812 4813 div.innerHTML = "<p class='TEST'></p>"; 4814 4815 // Safari can't handle uppercase or unicode characters when 4816 // in quirks mode. 4817 if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) { 4818 return; 4819 } 4820 4821 Sizzle = function( query, context, extra, seed ) { 4822 context = context || document; 4823 4824 // Only use querySelectorAll on non-XML documents 4825 // (ID selectors don't work in non-HTML documents) 4826 if ( !seed && !Sizzle.isXML(context) ) { 4827 // See if we find a selector to speed up 4828 var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query ); 4829 4830 if ( match && (context.nodeType === 1 || context.nodeType === 9) ) { 4831 // Speed-up: Sizzle("TAG") 4832 if ( match[1] ) { 4833 return makeArray( context.getElementsByTagName( query ), extra ); 4834 4835 // Speed-up: Sizzle(".CLASS") 4836 } else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) { 4837 return makeArray( context.getElementsByClassName( match[2] ), extra ); 4838 } 4839 } 4840 4841 if ( context.nodeType === 9 ) { 4842 // Speed-up: Sizzle("body") 4843 // The body element only exists once, optimize finding it 4844 if ( query === "body" && context.body ) { 4845 return makeArray( [ context.body ], extra ); 4846 4847 // Speed-up: Sizzle("#ID") 4848 } else if ( match && match[3] ) { 4849 var elem = context.getElementById( match[3] ); 4850 4851 // Check parentNode to catch when Blackberry 4.6 returns 4852 // nodes that are no longer in the document #6963 4853 if ( elem && elem.parentNode ) { 4854 // Handle the case where IE and Opera return items 4855 // by name instead of ID 4856 if ( elem.id === match[3] ) { 4857 return makeArray( [ elem ], extra ); 4858 } 4859 4860 } else { 4861 return makeArray( [], extra ); 4862 } 4863 } 4864 4865 try { 4866 return makeArray( context.querySelectorAll(query), extra ); 4867 } catch(qsaError) {} 4868 4869 // qSA works strangely on Element-rooted queries 4870 // We can work around this by specifying an extra ID on the root 4871 // and working up from there (Thanks to Andrew Dupont for the technique) 4872 // IE 8 doesn't work on object elements 4873 } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { 4874 var oldContext = context, 4875 old = context.getAttribute( "id" ), 4876 nid = old || id, 4877 hasParent = context.parentNode, 4878 relativeHierarchySelector = /^\s*[+~]/.test( query ); 4879 4880 if ( !old ) { 4881 context.setAttribute( "id", nid ); 4882 } else { 4883 nid = nid.replace( /'/g, "\\$&" ); 4884 } 4885 if ( relativeHierarchySelector && hasParent ) { 4886 context = context.parentNode; 4887 } 4888 4889 try { 4890 if ( !relativeHierarchySelector || hasParent ) { 4891 return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra ); 4892 } 4893 4894 } catch(pseudoError) { 4895 } finally { 4896 if ( !old ) { 4897 oldContext.removeAttribute( "id" ); 4898 } 4899 } 4900 } 4901 } 4902 4903 return oldSizzle(query, context, extra, seed); 4904 }; 4905 4906 for ( var prop in oldSizzle ) { 4907 Sizzle[ prop ] = oldSizzle[ prop ]; 4908 } 4909 4910 // release memory in IE 4911 div = null; 4912 })(); 4913 } 4914 4915 (function(){ 4916 var html = document.documentElement, 4917 matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector; 4918 4919 if ( matches ) { 4920 // Check to see if it's possible to do matchesSelector 4921 // on a disconnected node (IE 9 fails this) 4922 var disconnectedMatch = !matches.call( document.createElement( "div" ), "div" ), 4923 pseudoWorks = false; 4924 4925 try { 4926 // This should fail with an exception 4927 // Gecko does not error, returns false instead 4928 matches.call( document.documentElement, "[test!='']:sizzle" ); 4929 4930 } catch( pseudoError ) { 4931 pseudoWorks = true; 4932 } 4933 4934 Sizzle.matchesSelector = function( node, expr ) { 4935 // Make sure that attribute selectors are quoted 4936 expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']"); 4937 4938 if ( !Sizzle.isXML( node ) ) { 4939 try { 4940 if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) { 4941 var ret = matches.call( node, expr ); 4942 4943 // IE 9's matchesSelector returns false on disconnected nodes 4944 if ( ret || !disconnectedMatch || 4945 // As well, disconnected nodes are said to be in a document 4946 // fragment in IE 9, so check for that 4947 node.document && node.document.nodeType !== 11 ) { 4948 return ret; 4949 } 4950 } 4951 } catch(e) {} 4952 } 4953 4954 return Sizzle(expr, null, null, [node]).length > 0; 4955 }; 4956 } 4957 })(); 4958 4959 (function(){ 4960 var div = document.createElement("div"); 4961 4962 div.innerHTML = "<div class='test e'></div><div class='test'></div>"; 4963 4964 // Opera can't find a second classname (in 9.6) 4965 // Also, make sure that getElementsByClassName actually exists 4966 if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) { 4967 return; 4968 } 4969 4970 // Safari caches class attributes, doesn't catch changes (in 3.2) 4971 div.lastChild.className = "e"; 4972 4973 if ( div.getElementsByClassName("e").length === 1 ) { 4974 return; 4975 } 4976 4977 Expr.order.splice(1, 0, "CLASS"); 4978 Expr.find.CLASS = function( match, context, isXML ) { 4979 if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) { 4980 return context.getElementsByClassName(match[1]); 4981 } 4982 }; 4983 4984 // release memory in IE 4985 div = null; 4986 })(); 4987 4988 function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { 4989 for ( var i = 0, l = checkSet.length; i < l; i++ ) { 4990 var elem = checkSet[i]; 4991 4992 if ( elem ) { 4993 var match = false; 4994 4995 elem = elem[dir]; 4996 4997 while ( elem ) { 4998 if ( elem.sizcache === doneName ) { 4999 match = checkSet[elem.sizset]; 5000 break; 5001 } 5002 5003 if ( elem.nodeType === 1 && !isXML ){ 5004 elem.sizcache = doneName; 5005 elem.sizset = i; 5006 } 5007 5008 if ( elem.nodeName.toLowerCase() === cur ) { 5009 match = elem; 5010 break; 5011 } 5012 5013 elem = elem[dir]; 5014 } 5015 5016 checkSet[i] = match; 5017 } 5018 } 5019 } 5020 5021 function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { 5022 for ( var i = 0, l = checkSet.length; i < l; i++ ) { 5023 var elem = checkSet[i]; 5024 5025 if ( elem ) { 5026 var match = false; 5027 5028 elem = elem[dir]; 5029 5030 while ( elem ) { 5031 if ( elem.sizcache === doneName ) { 5032 match = checkSet[elem.sizset]; 5033 break; 5034 } 5035 5036 if ( elem.nodeType === 1 ) { 5037 if ( !isXML ) { 5038 elem.sizcache = doneName; 5039 elem.sizset = i; 5040 } 5041 5042 if ( typeof cur !== "string" ) { 5043 if ( elem === cur ) { 5044 match = true; 5045 break; 5046 } 5047 5048 } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) { 5049 match = elem; 5050 break; 5051 } 5052 } 5053 5054 elem = elem[dir]; 5055 } 5056 5057 checkSet[i] = match; 5058 } 5059 } 5060 } 5061 5062 if ( document.documentElement.contains ) { 5063 Sizzle.contains = function( a, b ) { 5064 return a !== b && (a.contains ? a.contains(b) : true); 5065 }; 5066 5067 } else if ( document.documentElement.compareDocumentPosition ) { 5068 Sizzle.contains = function( a, b ) { 5069 return !!(a.compareDocumentPosition(b) & 16); 5070 }; 5071 5072 } else { 5073 Sizzle.contains = function() { 5074 return false; 5075 }; 5076 } 5077 5078 Sizzle.isXML = function( elem ) { 5079 // documentElement is verified for cases where it doesn't yet exist 5080 // (such as loading iframes in IE - #4833) 5081 var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement; 5082 5083 return documentElement ? documentElement.nodeName !== "HTML" : false; 5084 }; 5085 5086 var posProcess = function( selector, context ) { 5087 var match, 5088 tmpSet = [], 5089 later = "", 5090 root = context.nodeType ? [context] : context; 5091 5092 // Position selectors must be done after the filter 5093 // And so must :not(positional) so we move all PSEUDOs to the end 5094 while ( (match = Expr.match.PSEUDO.exec( selector )) ) { 5095 later += match[0]; 5096 selector = selector.replace( Expr.match.PSEUDO, "" ); 5097 } 5098 5099 selector = Expr.relative[selector] ? selector + "*" : selector; 5100 5101 for ( var i = 0, l = root.length; i < l; i++ ) { 5102 Sizzle( selector, root[i], tmpSet ); 5103 } 5104 5105 return Sizzle.filter( later, tmpSet ); 5106 }; 5107 5108 // EXPOSE 5109 jQuery.find = Sizzle; 5110 jQuery.expr = Sizzle.selectors; 5111 jQuery.expr[":"] = jQuery.expr.filters; 5112 jQuery.unique = Sizzle.uniqueSort; 5113 jQuery.text = Sizzle.getText; 5114 jQuery.isXMLDoc = Sizzle.isXML; 5115 jQuery.contains = Sizzle.contains; 5116 5117 5118 })(); 5119 5120 5121 var runtil = /Until$/, 5122 rparentsprev = /^(?:parents|prevUntil|prevAll)/, 5123 // Note: This RegExp should be improved, or likely pulled from Sizzle 5124 rmultiselector = /,/, 5125 isSimple = /^.[^:#\[\.,]*$/, 5126 slice = Array.prototype.slice, 5127 POS = jQuery.expr.match.POS, 5128 // methods guaranteed to produce a unique set when starting from a unique set 5129 guaranteedUnique = { 5130 children: true, 5131 contents: true, 5132 next: true, 5133 prev: true 5134 }; 5135 5136 jQuery.fn.extend({ 5137 find: function( selector ) { 5138 var self = this, 5139 i, l; 5140 5141 if ( typeof selector !== "string" ) { 5142 return jQuery( selector ).filter(function() { 5143 for ( i = 0, l = self.length; i < l; i++ ) { 5144 if ( jQuery.contains( self[ i ], this ) ) { 5145 return true; 5146 } 5147 } 5148 }); 5149 } 5150 5151 var ret = this.pushStack( "", "find", selector ), 5152 length, n, r; 5153 5154 for ( i = 0, l = this.length; i < l; i++ ) { 5155 length = ret.length; 5156 jQuery.find( selector, this[i], ret ); 5157 5158 if ( i > 0 ) { 5159 // Make sure that the results are unique 5160 for ( n = length; n < ret.length; n++ ) { 5161 for ( r = 0; r < length; r++ ) { 5162 if ( ret[r] === ret[n] ) { 5163 ret.splice(n--, 1); 5164 break; 5165 } 5166 } 5167 } 5168 } 5169 } 5170 5171 return ret; 5172 }, 5173 5174 has: function( target ) { 5175 var targets = jQuery( target ); 5176 return this.filter(function() { 5177 for ( var i = 0, l = targets.length; i < l; i++ ) { 5178 if ( jQuery.contains( this, targets[i] ) ) { 5179 return true; 5180 } 5181 } 5182 }); 5183 }, 5184 5185 not: function( selector ) { 5186 return this.pushStack( winnow(this, selector, false), "not", selector); 5187 }, 5188 5189 filter: function( selector ) { 5190 return this.pushStack( winnow(this, selector, true), "filter", selector ); 5191 }, 5192 5193 is: function( selector ) { 5194 return !!selector && ( typeof selector === "string" ? 5195 jQuery.filter( selector, this ).length > 0 : 5196 this.filter( selector ).length > 0 ); 5197 }, 5198 5199 closest: function( selectors, context ) { 5200 var ret = [], i, l, cur = this[0]; 5201 5202 // Array 5203 if ( jQuery.isArray( selectors ) ) { 5204 var match, selector, 5205 matches = {}, 5206 level = 1; 5207 5208 if ( cur && selectors.length ) { 5209 for ( i = 0, l = selectors.length; i < l; i++ ) { 5210 selector = selectors[i]; 5211 5212 if ( !matches[ selector ] ) { 5213 matches[ selector ] = POS.test( selector ) ? 5214 jQuery( selector, context || this.context ) : 5215 selector; 5216 } 5217 } 5218 5219 while ( cur && cur.ownerDocument && cur !== context ) { 5220 for ( selector in matches ) { 5221 match = matches[ selector ]; 5222 5223 if ( match.jquery ? match.index( cur ) > -1 : jQuery( cur ).is( match ) ) { 5224 ret.push({ selector: selector, elem: cur, level: level }); 5225 } 5226 } 5227 5228 cur = cur.parentNode; 5229 level++; 5230 } 5231 } 5232 5233 return ret; 5234 } 5235 5236 // String 5237 var pos = POS.test( selectors ) || typeof selectors !== "string" ? 5238 jQuery( selectors, context || this.context ) : 5239 0; 5240 5241 for ( i = 0, l = this.length; i < l; i++ ) { 5242 cur = this[i]; 5243 5244 while ( cur ) { 5245 if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) { 5246 ret.push( cur ); 5247 break; 5248 5249 } else { 5250 cur = cur.parentNode; 5251 if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) { 5252 break; 5253 } 5254 } 5255 } 5256 } 5257 5258 ret = ret.length > 1 ? jQuery.unique( ret ) : ret; 5259 5260 return this.pushStack( ret, "closest", selectors ); 5261 }, 5262 5263 // Determine the position of an element within 5264 // the matched set of elements 5265 index: function( elem ) { 5266 if ( !elem || typeof elem === "string" ) { 5267 return jQuery.inArray( this[0], 5268 // If it receives a string, the selector is used 5269 // If it receives nothing, the siblings are used 5270 elem ? jQuery( elem ) : this.parent().children() ); 5271 } 5272 // Locate the position of the desired element 5273 return jQuery.inArray( 5274 // If it receives a jQuery object, the first element is used 5275 elem.jquery ? elem[0] : elem, this ); 5276 }, 5277 5278 add: function( selector, context ) { 5279 var set = typeof selector === "string" ? 5280 jQuery( selector, context ) : 5281 jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ), 5282 all = jQuery.merge( this.get(), set ); 5283 5284 return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ? 5285 all : 5286 jQuery.unique( all ) ); 5287 }, 5288 5289 andSelf: function() { 5290 return this.add( this.prevObject ); 5291 } 5292 }); 5293 5294 // A painfully simple check to see if an element is disconnected 5295 // from a document (should be improved, where feasible). 5296 function isDisconnected( node ) { 5297 return !node || !node.parentNode || node.parentNode.nodeType === 11; 5298 } 5299 5300 jQuery.each({ 5301 parent: function( elem ) { 5302 var parent = elem.parentNode; 5303 return parent && parent.nodeType !== 11 ? parent : null; 5304 }, 5305 parents: function( elem ) { 5306 return jQuery.dir( elem, "parentNode" ); 5307 }, 5308 parentsUntil: function( elem, i, until ) { 5309 return jQuery.dir( elem, "parentNode", until ); 5310 }, 5311 next: function( elem ) { 5312 return jQuery.nth( elem, 2, "nextSibling" ); 5313 }, 5314 prev: function( elem ) { 5315 return jQuery.nth( elem, 2, "previousSibling" ); 5316 }, 5317 nextAll: function( elem ) { 5318 return jQuery.dir( elem, "nextSibling" ); 5319 }, 5320 prevAll: function( elem ) { 5321 return jQuery.dir( elem, "previousSibling" ); 5322 }, 5323 nextUntil: function( elem, i, until ) { 5324 return jQuery.dir( elem, "nextSibling", until ); 5325 }, 5326 prevUntil: function( elem, i, until ) { 5327 return jQuery.dir( elem, "previousSibling", until ); 5328 }, 5329 siblings: function( elem ) { 5330 return jQuery.sibling( elem.parentNode.firstChild, elem ); 5331 }, 5332 children: function( elem ) { 5333 return jQuery.sibling( elem.firstChild ); 5334 }, 5335 contents: function( elem ) { 5336 return jQuery.nodeName( elem, "iframe" ) ? 5337 elem.contentDocument || elem.contentWindow.document : 5338 jQuery.makeArray( elem.childNodes ); 5339 } 5340 }, function( name, fn ) { 5341 jQuery.fn[ name ] = function( until, selector ) { 5342 var ret = jQuery.map( this, fn, until ), 5343 // The variable 'args' was introduced in 5344 // https://github.com/jquery/jquery/commit/52a0238 5345 // to work around a bug in Chrome 10 (Dev) and should be removed when the bug is fixed. 5346 // http://code.google.com/p/v8/issues/detail?id=1050 5347 args = slice.call(arguments); 5348 5349 if ( !runtil.test( name ) ) { 5350 selector = until; 5351 } 5352 5353 if ( selector && typeof selector === "string" ) { 5354 ret = jQuery.filter( selector, ret ); 5355 } 5356 5357 ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret; 5358 5359 if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) { 5360 ret = ret.reverse(); 5361 } 5362 5363 return this.pushStack( ret, name, args.join(",") ); 5364 }; 5365 }); 5366 5367 jQuery.extend({ 5368 filter: function( expr, elems, not ) { 5369 if ( not ) { 5370 expr = ":not(" + expr + ")"; 5371 } 5372 5373 return elems.length === 1 ? 5374 jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] : 5375 jQuery.find.matches(expr, elems); 5376 }, 5377 5378 dir: function( elem, dir, until ) { 5379 var matched = [], 5380 cur = elem[ dir ]; 5381 5382 while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { 5383 if ( cur.nodeType === 1 ) { 5384 matched.push( cur ); 5385 } 5386 cur = cur[dir]; 5387 } 5388 return matched; 5389 }, 5390 5391 nth: function( cur, result, dir, elem ) { 5392 result = result || 1; 5393 var num = 0; 5394 5395 for ( ; cur; cur = cur[dir] ) { 5396 if ( cur.nodeType === 1 && ++num === result ) { 5397 break; 5398 } 5399 } 5400 5401 return cur; 5402 }, 5403 5404 sibling: function( n, elem ) { 5405 var r = []; 5406 5407 for ( ; n; n = n.nextSibling ) { 5408 if ( n.nodeType === 1 && n !== elem ) { 5409 r.push( n ); 5410 } 5411 } 5412 5413 return r; 5414 } 5415 }); 5416 5417 // Implement the identical functionality for filter and not 5418 function winnow( elements, qualifier, keep ) { 5419 5420 // Can't pass null or undefined to indexOf in Firefox 4 5421 // Set to 0 to skip string check 5422 qualifier = qualifier || 0; 5423 5424 if ( jQuery.isFunction( qualifier ) ) { 5425 return jQuery.grep(elements, function( elem, i ) { 5426 var retVal = !!qualifier.call( elem, i, elem ); 5427 return retVal === keep; 5428 }); 5429 5430 } else if ( qualifier.nodeType ) { 5431 return jQuery.grep(elements, function( elem, i ) { 5432 return (elem === qualifier) === keep; 5433 }); 5434 5435 } else if ( typeof qualifier === "string" ) { 5436 var filtered = jQuery.grep(elements, function( elem ) { 5437 return elem.nodeType === 1; 5438 }); 5439 5440 if ( isSimple.test( qualifier ) ) { 5441 return jQuery.filter(qualifier, filtered, !keep); 5442 } else { 5443 qualifier = jQuery.filter( qualifier, filtered ); 5444 } 5445 } 5446 5447 return jQuery.grep(elements, function( elem, i ) { 5448 return (jQuery.inArray( elem, qualifier ) >= 0) === keep; 5449 }); 5450 } 5451 5452 5453 5454 5455 var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g, 5456 rleadingWhitespace = /^\s+/, 5457 rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig, 5458 rtagName = /<([\w:]+)/, 5459 rtbody = /<tbody/i, 5460 rhtml = /<|&#?\w+;/, 5461 rnocache = /<(?:script|object|embed|option|style)/i, 5462 // checked="checked" or checked 5463 rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, 5464 rscriptType = /\/(java|ecma)script/i, 5465 rcleanScript = /^\s*<!(?:\[CDATA\[|\-\-)/, 5466 wrapMap = { 5467 option: [ 1, "<select multiple='multiple'>", "</select>" ], 5468 legend: [ 1, "<fieldset>", "</fieldset>" ], 5469 thead: [ 1, "<table>", "</table>" ], 5470 tr: [ 2, "<table><tbody>", "</tbody></table>" ], 5471 td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ], 5472 col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ], 5473 area: [ 1, "<map>", "</map>" ], 5474 _default: [ 0, "", "" ] 5475 }; 5476 5477 wrapMap.optgroup = wrapMap.option; 5478 wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; 5479 wrapMap.th = wrapMap.td; 5480 5481 // IE can't serialize <link> and <script> tags normally 5482 if ( !jQuery.support.htmlSerialize ) { 5483 wrapMap._default = [ 1, "div<div>", "</div>" ]; 5484 } 5485 5486 jQuery.fn.extend({ 5487 text: function( text ) { 5488 if ( jQuery.isFunction(text) ) { 5489 return this.each(function(i) { 5490 var self = jQuery( this ); 5491 5492 self.text( text.call(this, i, self.text()) ); 5493 }); 5494 } 5495 5496 if ( typeof text !== "object" && text !== undefined ) { 5497 return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) ); 5498 } 5499 5500 return jQuery.text( this ); 5501 }, 5502 5503 wrapAll: function( html ) { 5504 if ( jQuery.isFunction( html ) ) { 5505 return this.each(function(i) { 5506 jQuery(this).wrapAll( html.call(this, i) ); 5507 }); 5508 } 5509 5510 if ( this[0] ) { 5511 // The elements to wrap the target around 5512 var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true); 5513 5514 if ( this[0].parentNode ) { 5515 wrap.insertBefore( this[0] ); 5516 } 5517 5518 wrap.map(function() { 5519 var elem = this; 5520 5521 while ( elem.firstChild && elem.firstChild.nodeType === 1 ) { 5522 elem = elem.firstChild; 5523 } 5524 5525 return elem; 5526 }).append( this ); 5527 } 5528 5529 return this; 5530 }, 5531 5532 wrapInner: function( html ) { 5533 if ( jQuery.isFunction( html ) ) { 5534 return this.each(function(i) { 5535 jQuery(this).wrapInner( html.call(this, i) ); 5536 }); 5537 } 5538 5539 return this.each(function() { 5540 var self = jQuery( this ), 5541 contents = self.contents(); 5542 5543 if ( contents.length ) { 5544 contents.wrapAll( html ); 5545 5546 } else { 5547 self.append( html ); 5548 } 5549 }); 5550 }, 5551 5552 wrap: function( html ) { 5553 return this.each(function() { 5554 jQuery( this ).wrapAll( html ); 5555 }); 5556 }, 5557 5558 unwrap: function() { 5559 return this.parent().each(function() { 5560 if ( !jQuery.nodeName( this, "body" ) ) { 5561 jQuery( this ).replaceWith( this.childNodes ); 5562 } 5563 }).end(); 5564 }, 5565 5566 append: function() { 5567 return this.domManip(arguments, true, function( elem ) { 5568 if ( this.nodeType === 1 ) { 5569 this.appendChild( elem ); 5570 } 5571 }); 5572 }, 5573 5574 prepend: function() { 5575 return this.domManip(arguments, true, function( elem ) { 5576 if ( this.nodeType === 1 ) { 5577 this.insertBefore( elem, this.firstChild ); 5578 } 5579 }); 5580 }, 5581 5582 before: function() { 5583 if ( this[0] && this[0].parentNode ) { 5584 return this.domManip(arguments, false, function( elem ) { 5585 this.parentNode.insertBefore( elem, this ); 5586 }); 5587 } else if ( arguments.length ) { 5588 var set = jQuery(arguments[0]); 5589 set.push.apply( set, this.toArray() ); 5590 return this.pushStack( set, "before", arguments ); 5591 } 5592 }, 5593 5594 after: function() { 5595 if ( this[0] && this[0].parentNode ) { 5596 return this.domManip(arguments, false, function( elem ) { 5597 this.parentNode.insertBefore( elem, this.nextSibling ); 5598 }); 5599 } else if ( arguments.length ) { 5600 var set = this.pushStack( this, "after", arguments ); 5601 set.push.apply( set, jQuery(arguments[0]).toArray() ); 5602 return set; 5603 } 5604 }, 5605 5606 // keepData is for internal use only--do not document 5607 remove: function( selector, keepData ) { 5608 for ( var i = 0, elem; (elem = this[i]) != null; i++ ) { 5609 if ( !selector || jQuery.filter( selector, [ elem ] ).length ) { 5610 if ( !keepData && elem.nodeType === 1 ) { 5611 jQuery.cleanData( elem.getElementsByTagName("*") ); 5612 jQuery.cleanData( [ elem ] ); 5613 } 5614 5615 if ( elem.parentNode ) { 5616 elem.parentNode.removeChild( elem ); 5617 } 5618 } 5619 } 5620 5621 return this; 5622 }, 5623 5624 empty: function() { 5625 for ( var i = 0, elem; (elem = this[i]) != null; i++ ) { 5626 // Remove element nodes and prevent memory leaks 5627 if ( elem.nodeType === 1 ) { 5628 jQuery.cleanData( elem.getElementsByTagName("*") ); 5629 } 5630 5631 // Remove any remaining nodes 5632 while ( elem.firstChild ) { 5633 elem.removeChild( elem.firstChild ); 5634 } 5635 } 5636 5637 return this; 5638 }, 5639 5640 clone: function( dataAndEvents, deepDataAndEvents ) { 5641 dataAndEvents = dataAndEvents == null ? false : dataAndEvents; 5642 deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; 5643 5644 return this.map( function () { 5645 return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); 5646 }); 5647 }, 5648 5649 html: function( value ) { 5650 if ( value === undefined ) { 5651 return this[0] && this[0].nodeType === 1 ? 5652 this[0].innerHTML.replace(rinlinejQuery, "") : 5653 null; 5654 5655 // See if we can take a shortcut and just use innerHTML 5656 } else if ( typeof value === "string" && !rnocache.test( value ) && 5657 (jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) && 5658 !wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) { 5659 5660 value = value.replace(rxhtmlTag, "<$1></$2>"); 5661 5662 try { 5663 for ( var i = 0, l = this.length; i < l; i++ ) { 5664 // Remove element nodes and prevent memory leaks 5665 if ( this[i].nodeType === 1 ) { 5666 jQuery.cleanData( this[i].getElementsByTagName("*") ); 5667 this[i].innerHTML = value; 5668 } 5669 } 5670 5671 // If using innerHTML throws an exception, use the fallback method 5672 } catch(e) { 5673 this.empty().append( value ); 5674 } 5675 5676 } else if ( jQuery.isFunction( value ) ) { 5677 this.each(function(i){ 5678 var self = jQuery( this ); 5679 5680 self.html( value.call(this, i, self.html()) ); 5681 }); 5682 5683 } else { 5684 this.empty().append( value ); 5685 } 5686 5687 return this; 5688 }, 5689 5690 replaceWith: function( value ) { 5691 if ( this[0] && this[0].parentNode ) { 5692 // Make sure that the elements are removed from the DOM before they are inserted 5693 // this can help fix replacing a parent with child elements 5694 if ( jQuery.isFunction( value ) ) { 5695 return this.each(function(i) { 5696 var self = jQuery(this), old = self.html(); 5697 self.replaceWith( value.call( this, i, old ) ); 5698 }); 5699 } 5700 5701 if ( typeof value !== "string" ) { 5702 value = jQuery( value ).detach(); 5703 } 5704 5705 return this.each(function() { 5706 var next = this.nextSibling, 5707 parent = this.parentNode; 5708 5709 jQuery( this ).remove(); 5710 5711 if ( next ) { 5712 jQuery(next).before( value ); 5713 } else { 5714 jQuery(parent).append( value ); 5715 } 5716 }); 5717 } else { 5718 return this.length ? 5719 this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value ) : 5720 this; 5721 } 5722 }, 5723 5724 detach: function( selector ) { 5725 return this.remove( selector, true ); 5726 }, 5727 5728 domManip: function( args, table, callback ) { 5729 var results, first, fragment, parent, 5730 value = args[0], 5731 scripts = []; 5732 5733 // We can't cloneNode fragments that contain checked, in WebKit 5734 if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) { 5735 return this.each(function() { 5736 jQuery(this).domManip( args, table, callback, true ); 5737 }); 5738 } 5739 5740 if ( jQuery.isFunction(value) ) { 5741 return this.each(function(i) { 5742 var self = jQuery(this); 5743 args[0] = value.call(this, i, table ? self.html() : undefined); 5744 self.domManip( args, table, callback ); 5745 }); 5746 } 5747 5748 if ( this[0] ) { 5749 parent = value && value.parentNode; 5750 5751 // If we're in a fragment, just use that instead of building a new one 5752 if ( jQuery.support.parentNode && parent && parent.nodeType === 11 && parent.childNodes.length === this.length ) { 5753 results = { fragment: parent }; 5754 5755 } else { 5756 results = jQuery.buildFragment( args, this, scripts ); 5757 } 5758 5759 fragment = results.fragment; 5760 5761 if ( fragment.childNodes.length === 1 ) { 5762 first = fragment = fragment.firstChild; 5763 } else { 5764 first = fragment.firstChild; 5765 } 5766 5767 if ( first ) { 5768 table = table && jQuery.nodeName( first, "tr" ); 5769 5770 for ( var i = 0, l = this.length, lastIndex = l - 1; i < l; i++ ) { 5771 callback.call( 5772 table ? 5773 root(this[i], first) : 5774 this[i], 5775 // Make sure that we do not leak memory by inadvertently discarding 5776 // the original fragment (which might have attached data) instead of 5777 // using it; in addition, use the original fragment object for the last 5778 // item instead of first because it can end up being emptied incorrectly 5779 // in certain situations (Bug #8070). 5780 // Fragments from the fragment cache must always be cloned and never used 5781 // in place. 5782 results.cacheable || (l > 1 && i < lastIndex) ? 5783 jQuery.clone( fragment, true, true ) : 5784 fragment 5785 ); 5786 } 5787 } 5788 5789 if ( scripts.length ) { 5790 jQuery.each( scripts, evalScript ); 5791 } 5792 } 5793 5794 return this; 5795 } 5796 }); 5797 5798 function root( elem, cur ) { 5799 return jQuery.nodeName(elem, "table") ? 5800 (elem.getElementsByTagName("tbody")[0] || 5801 elem.appendChild(elem.ownerDocument.createElement("tbody"))) : 5802 elem; 5803 } 5804 5805 function cloneCopyEvent( src, dest ) { 5806 5807 if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) { 5808 return; 5809 } 5810 5811 var internalKey = jQuery.expando, 5812 oldData = jQuery.data( src ), 5813 curData = jQuery.data( dest, oldData ); 5814 5815 // Switch to use the internal data object, if it exists, for the next 5816 // stage of data copying 5817 if ( (oldData = oldData[ internalKey ]) ) { 5818 var events = oldData.events; 5819 curData = curData[ internalKey ] = jQuery.extend({}, oldData); 5820 5821 if ( events ) { 5822 delete curData.handle; 5823 curData.events = {}; 5824 5825 for ( var type in events ) { 5826 for ( var i = 0, l = events[ type ].length; i < l; i++ ) { 5827 jQuery.event.add( dest, type + ( events[ type ][ i ].namespace ? "." : "" ) + events[ type ][ i ].namespace, events[ type ][ i ], events[ type ][ i ].data ); 5828 } 5829 } 5830 } 5831 } 5832 } 5833 5834 function cloneFixAttributes( src, dest ) { 5835 var nodeName; 5836 5837 // We do not need to do anything for non-Elements 5838 if ( dest.nodeType !== 1 ) { 5839 return; 5840 } 5841 5842 // clearAttributes removes the attributes, which we don't want, 5843 // but also removes the attachEvent events, which we *do* want 5844 if ( dest.clearAttributes ) { 5845 dest.clearAttributes(); 5846 } 5847 5848 // mergeAttributes, in contrast, only merges back on the 5849 // original attributes, not the events 5850 if ( dest.mergeAttributes ) { 5851 dest.mergeAttributes( src ); 5852 } 5853 5854 nodeName = dest.nodeName.toLowerCase(); 5855 5856 // IE6-8 fail to clone children inside object elements that use 5857 // the proprietary classid attribute value (rather than the type 5858 // attribute) to identify the type of content to display 5859 if ( nodeName === "object" ) { 5860 dest.outerHTML = src.outerHTML; 5861 5862 } else if ( nodeName === "input" && (src.type === "checkbox" || src.type === "radio") ) { 5863 // IE6-8 fails to persist the checked state of a cloned checkbox 5864 // or radio button. Worse, IE6-7 fail to give the cloned element 5865 // a checked appearance if the defaultChecked value isn't also set 5866 if ( src.checked ) { 5867 dest.defaultChecked = dest.checked = src.checked; 5868 } 5869 5870 // IE6-7 get confused and end up setting the value of a cloned 5871 // checkbox/radio button to an empty string instead of "on" 5872 if ( dest.value !== src.value ) { 5873 dest.value = src.value; 5874 } 5875 5876 // IE6-8 fails to return the selected option to the default selected 5877 // state when cloning options 5878 } else if ( nodeName === "option" ) { 5879 dest.selected = src.defaultSelected; 5880 5881 // IE6-8 fails to set the defaultValue to the correct value when 5882 // cloning other types of input fields 5883 } else if ( nodeName === "input" || nodeName === "textarea" ) { 5884 dest.defaultValue = src.defaultValue; 5885 } 5886 5887 // Event data gets referenced instead of copied if the expando 5888 // gets copied too 5889 dest.removeAttribute( jQuery.expando ); 5890 } 5891 5892 jQuery.buildFragment = function( args, nodes, scripts ) { 5893 var fragment, cacheable, cacheresults, 5894 doc = (nodes && nodes[0] ? nodes[0].ownerDocument || nodes[0] : document); 5895 5896 // Only cache "small" (1/2 KB) HTML strings that are associated with the main document 5897 // Cloning options loses the selected state, so don't cache them 5898 // IE 6 doesn't like it when you put <object> or <embed> elements in a fragment 5899 // Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache 5900 if ( args.length === 1 && typeof args[0] === "string" && args[0].length < 512 && doc === document && 5901 args[0].charAt(0) === "<" && !rnocache.test( args[0] ) && (jQuery.support.checkClone || !rchecked.test( args[0] )) ) { 5902 5903 cacheable = true; 5904 5905 cacheresults = jQuery.fragments[ args[0] ]; 5906 if ( cacheresults && cacheresults !== 1 ) { 5907 fragment = cacheresults; 5908 } 5909 } 5910 5911 if ( !fragment ) { 5912 fragment = doc.createDocumentFragment(); 5913 jQuery.clean( args, doc, fragment, scripts ); 5914 } 5915 5916 if ( cacheable ) { 5917 jQuery.fragments[ args[0] ] = cacheresults ? fragment : 1; 5918 } 5919 5920 return { fragment: fragment, cacheable: cacheable }; 5921 }; 5922 5923 jQuery.fragments = {}; 5924 5925 jQuery.each({ 5926 appendTo: "append", 5927 prependTo: "prepend", 5928 insertBefore: "before", 5929 insertAfter: "after", 5930 replaceAll: "replaceWith" 5931 }, function( name, original ) { 5932 jQuery.fn[ name ] = function( selector ) { 5933 var ret = [], 5934 insert = jQuery( selector ), 5935 parent = this.length === 1 && this[0].parentNode; 5936 5937 if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) { 5938 insert[ original ]( this[0] ); 5939 return this; 5940 5941 } else { 5942 for ( var i = 0, l = insert.length; i < l; i++ ) { 5943 var elems = (i > 0 ? this.clone(true) : this).get(); 5944 jQuery( insert[i] )[ original ]( elems ); 5945 ret = ret.concat( elems ); 5946 } 5947 5948 return this.pushStack( ret, name, insert.selector ); 5949 } 5950 }; 5951 }); 5952 5953 function getAll( elem ) { 5954 if ( "getElementsByTagName" in elem ) { 5955 return elem.getElementsByTagName( "*" ); 5956 5957 } else if ( "querySelectorAll" in elem ) { 5958 return elem.querySelectorAll( "*" ); 5959 5960 } else { 5961 return []; 5962 } 5963 } 5964 5965 // Used in clean, fixes the defaultChecked property 5966 function fixDefaultChecked( elem ) { 5967 if ( elem.type === "checkbox" || elem.type === "radio" ) { 5968 elem.defaultChecked = elem.checked; 5969 } 5970 } 5971 // Finds all inputs and passes them to fixDefaultChecked 5972 function findInputs( elem ) { 5973 if ( jQuery.nodeName( elem, "input" ) ) { 5974 fixDefaultChecked( elem ); 5975 } else if ( elem.getElementsByTagName ) { 5976 jQuery.grep( elem.getElementsByTagName("input"), fixDefaultChecked ); 5977 } 5978 } 5979 5980 jQuery.extend({ 5981 clone: function( elem, dataAndEvents, deepDataAndEvents ) { 5982 var clone = elem.cloneNode(true), 5983 srcElements, 5984 destElements, 5985 i; 5986 5987 if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) && 5988 (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) { 5989 // IE copies events bound via attachEvent when using cloneNode. 5990 // Calling detachEvent on the clone will also remove the events 5991 // from the original. In order to get around this, we use some 5992 // proprietary methods to clear the events. Thanks to MooTools 5993 // guys for this hotness. 5994 5995 cloneFixAttributes( elem, clone ); 5996 5997 // Using Sizzle here is crazy slow, so we use getElementsByTagName 5998 // instead 5999 srcElements = getAll( elem ); 6000 destElements = getAll( clone ); 6001 6002 // Weird iteration because IE will replace the length property 6003 // with an element if you are cloning the body and one of the 6004 // elements on the page has a name or id of "length" 6005 for ( i = 0; srcElements[i]; ++i ) { 6006 cloneFixAttributes( srcElements[i], destElements[i] ); 6007 } 6008 } 6009 6010 // Copy the events from the original to the clone 6011 if ( dataAndEvents ) { 6012 cloneCopyEvent( elem, clone ); 6013 6014 if ( deepDataAndEvents ) { 6015 srcElements = getAll( elem ); 6016 destElements = getAll( clone ); 6017 6018 for ( i = 0; srcElements[i]; ++i ) { 6019 cloneCopyEvent( srcElements[i], destElements[i] ); 6020 } 6021 } 6022 } 6023 6024 // Return the cloned set 6025 return clone; 6026 }, 6027 6028 clean: function( elems, context, fragment, scripts ) { 6029 var checkScriptType; 6030 6031 context = context || document; 6032 6033 // !context.createElement fails in IE with an error but returns typeof 'object' 6034 if ( typeof context.createElement === "undefined" ) { 6035 context = context.ownerDocument || context[0] && context[0].ownerDocument || document; 6036 } 6037 6038 var ret = [], j; 6039 6040 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { 6041 if ( typeof elem === "number" ) { 6042 elem += ""; 6043 } 6044 6045 if ( !elem ) { 6046 continue; 6047 } 6048 6049 // Convert html string into DOM nodes 6050 if ( typeof elem === "string" ) { 6051 if ( !rhtml.test( elem ) ) { 6052 elem = context.createTextNode( elem ); 6053 } else { 6054 // Fix "XHTML"-style tags in all browsers 6055 elem = elem.replace(rxhtmlTag, "<$1></$2>"); 6056 6057 // Trim whitespace, otherwise indexOf won't work as expected 6058 var tag = (rtagName.exec( elem ) || ["", ""])[1].toLowerCase(), 6059 wrap = wrapMap[ tag ] || wrapMap._default, 6060 depth = wrap[0], 6061 div = context.createElement("div"); 6062 6063 // Go to html and back, then peel off extra wrappers 6064 div.innerHTML = wrap[1] + elem + wrap[2]; 6065 6066 // Move to the right depth 6067 while ( depth-- ) { 6068 div = div.lastChild; 6069 } 6070 6071 // Remove IE's autoinserted <tbody> from table fragments 6072 if ( !jQuery.support.tbody ) { 6073 6074 // String was a <table>, *may* have spurious <tbody> 6075 var hasBody = rtbody.test(elem), 6076 tbody = tag === "table" && !hasBody ? 6077 div.firstChild && div.firstChild.childNodes : 6078 6079 // String was a bare <thead> or <tfoot> 6080 wrap[1] === "<table>" && !hasBody ? 6081 div.childNodes : 6082 []; 6083 6084 for ( j = tbody.length - 1; j >= 0 ; --j ) { 6085 if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) { 6086 tbody[ j ].parentNode.removeChild( tbody[ j ] ); 6087 } 6088 } 6089 } 6090 6091 // IE completely kills leading whitespace when innerHTML is used 6092 if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) { 6093 div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild ); 6094 } 6095 6096 elem = div.childNodes; 6097 } 6098 } 6099 6100 // Resets defaultChecked for any radios and checkboxes 6101 // about to be appended to the DOM in IE 6/7 (#8060) 6102 var len; 6103 if ( !jQuery.support.appendChecked ) { 6104 if ( elem[0] && typeof (len = elem.length) === "number" ) { 6105 for ( j = 0; j < len; j++ ) { 6106 findInputs( elem[j] ); 6107 } 6108 } else { 6109 findInputs( elem ); 6110 } 6111 } 6112 6113 if ( elem.nodeType ) { 6114 ret.push( elem ); 6115 } else { 6116 ret = jQuery.merge( ret, elem ); 6117 } 6118 } 6119 6120 if ( fragment ) { 6121 checkScriptType = function( elem ) { 6122 return !elem.type || rscriptType.test( elem.type ); 6123 }; 6124 for ( i = 0; ret[i]; i++ ) { 6125 if ( scripts && jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) { 6126 scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] ); 6127 6128 } else { 6129 if ( ret[i].nodeType === 1 ) { 6130 var jsTags = jQuery.grep( ret[i].getElementsByTagName( "script" ), checkScriptType ); 6131 6132 ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) ); 6133 } 6134 fragment.appendChild( ret[i] ); 6135 } 6136 } 6137 } 6138 6139 return ret; 6140 }, 6141 6142 cleanData: function( elems ) { 6143 var data, id, cache = jQuery.cache, internalKey = jQuery.expando, special = jQuery.event.special, 6144 deleteExpando = jQuery.support.deleteExpando; 6145 6146 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { 6147 if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) { 6148 continue; 6149 } 6150 6151 id = elem[ jQuery.expando ]; 6152 6153 if ( id ) { 6154 data = cache[ id ] && cache[ id ][ internalKey ]; 6155 6156 if ( data && data.events ) { 6157 for ( var type in data.events ) { 6158 if ( special[ type ] ) { 6159 jQuery.event.remove( elem, type ); 6160 6161 // This is a shortcut to avoid jQuery.event.remove's overhead 6162 } else { 6163 jQuery.removeEvent( elem, type, data.handle ); 6164 } 6165 } 6166 6167 // Null the DOM reference to avoid IE6/7/8 leak (#7054) 6168 if ( data.handle ) { 6169 data.handle.elem = null; 6170 } 6171 } 6172 6173 if ( deleteExpando ) { 6174 delete elem[ jQuery.expando ]; 6175 6176 } else if ( elem.removeAttribute ) { 6177 elem.removeAttribute( jQuery.expando ); 6178 } 6179 6180 delete cache[ id ]; 6181 } 6182 } 6183 } 6184 }); 6185 6186 function evalScript( i, elem ) { 6187 if ( elem.src ) { 6188 jQuery.ajax({ 6189 url: elem.src, 6190 async: false, 6191 dataType: "script" 6192 }); 6193 } else { 6194 jQuery.globalEval( ( elem.text || elem.textContent || elem.innerHTML || "" ).replace( rcleanScript, "/*$0*/" ) ); 6195 } 6196 6197 if ( elem.parentNode ) { 6198 elem.parentNode.removeChild( elem ); 6199 } 6200 } 6201 6202 6203 6204 6205 var ralpha = /alpha\([^)]*\)/i, 6206 ropacity = /opacity=([^)]*)/, 6207 rdashAlpha = /-([a-z])/ig, 6208 // fixed for IE9, see #8346 6209 rupper = /([A-Z]|^ms)/g, 6210 rnumpx = /^-?\d+(?:px)?$/i, 6211 rnum = /^-?\d/, 6212 rrelNum = /^[+\-]=/, 6213 rrelNumFilter = /[^+\-\.\de]+/g, 6214 6215 cssShow = { position: "absolute", visibility: "hidden", display: "block" }, 6216 cssWidth = [ "Left", "Right" ], 6217 cssHeight = [ "Top", "Bottom" ], 6218 curCSS, 6219 6220 getComputedStyle, 6221 currentStyle, 6222 6223 fcamelCase = function( all, letter ) { 6224 return letter.toUpperCase(); 6225 }; 6226 6227 jQuery.fn.css = function( name, value ) { 6228 // Setting 'undefined' is a no-op 6229 if ( arguments.length === 2 && value === undefined ) { 6230 return this; 6231 } 6232 6233 return jQuery.access( this, name, value, true, function( elem, name, value ) { 6234 return value !== undefined ? 6235 jQuery.style( elem, name, value ) : 6236 jQuery.css( elem, name ); 6237 }); 6238 }; 6239 6240 jQuery.extend({ 6241 // Add in style property hooks for overriding the default 6242 // behavior of getting and setting a style property 6243 cssHooks: { 6244 opacity: { 6245 get: function( elem, computed ) { 6246 if ( computed ) { 6247 // We should always get a number back from opacity 6248 var ret = curCSS( elem, "opacity", "opacity" ); 6249 return ret === "" ? "1" : ret; 6250 6251 } else { 6252 return elem.style.opacity; 6253 } 6254 } 6255 } 6256 }, 6257 6258 // Exclude the following css properties to add px 6259 cssNumber: { 6260 "zIndex": true, 6261 "fontWeight": true, 6262 "opacity": true, 6263 "zoom": true, 6264 "lineHeight": true, 6265 "widows": true, 6266 "orphans": true 6267 }, 6268 6269 // Add in properties whose names you wish to fix before 6270 // setting or getting the value 6271 cssProps: { 6272 // normalize float css property 6273 "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat" 6274 }, 6275 6276 // Get and set the style property on a DOM Node 6277 style: function( elem, name, value, extra ) { 6278 // Don't set styles on text and comment nodes 6279 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { 6280 return; 6281 } 6282 6283 // Make sure that we're working with the right name 6284 var ret, type, origName = jQuery.camelCase( name ), 6285 style = elem.style, hooks = jQuery.cssHooks[ origName ]; 6286 6287 name = jQuery.cssProps[ origName ] || origName; 6288 6289 // Check if we're setting a value 6290 if ( value !== undefined ) { 6291 type = typeof value; 6292 6293 // Make sure that NaN and null values aren't set. See: #7116 6294 if ( type === "number" && isNaN( value ) || value == null ) { 6295 return; 6296 } 6297 6298 // convert relative number strings (+= or -=) to relative numbers. #7345 6299 if ( type === "string" && rrelNum.test( value ) ) { 6300 value = +value.replace( rrelNumFilter, "" ) + parseFloat( jQuery.css( elem, name ) ); 6301 } 6302 6303 // If a number was passed in, add 'px' to the (except for certain CSS properties) 6304 if ( type === "number" && !jQuery.cssNumber[ origName ] ) { 6305 value += "px"; 6306 } 6307 6308 // If a hook was provided, use that value, otherwise just set the specified value 6309 if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value )) !== undefined ) { 6310 // Wrapped to prevent IE from throwing errors when 'invalid' values are provided 6311 // Fixes bug #5509 6312 try { 6313 style[ name ] = value; 6314 } catch(e) {} 6315 } 6316 6317 } else { 6318 // If a hook was provided get the non-computed value from there 6319 if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) { 6320 return ret; 6321 } 6322 6323 // Otherwise just get the value from the style object 6324 return style[ name ]; 6325 } 6326 }, 6327 6328 css: function( elem, name, extra ) { 6329 var ret, hooks; 6330 6331 // Make sure that we're working with the right name 6332 name = jQuery.camelCase( name ); 6333 hooks = jQuery.cssHooks[ name ]; 6334 name = jQuery.cssProps[ name ] || name; 6335 6336 // cssFloat needs a special treatment 6337 if ( name === "cssFloat" ) { 6338 name = "float"; 6339 } 6340 6341 // If a hook was provided get the computed value from there 6342 if ( hooks && "get" in hooks && (ret = hooks.get( elem, true, extra )) !== undefined ) { 6343 return ret; 6344 6345 // Otherwise, if a way to get the computed value exists, use that 6346 } else if ( curCSS ) { 6347 return curCSS( elem, name ); 6348 } 6349 }, 6350 6351 // A method for quickly swapping in/out CSS properties to get correct calculations 6352 swap: function( elem, options, callback ) { 6353 var old = {}; 6354 6355 // Remember the old values, and insert the new ones 6356 for ( var name in options ) { 6357 old[ name ] = elem.style[ name ]; 6358 elem.style[ name ] = options[ name ]; 6359 } 6360 6361 callback.call( elem ); 6362 6363 // Revert the old values 6364 for ( name in options ) { 6365 elem.style[ name ] = old[ name ]; 6366 } 6367 }, 6368 6369 camelCase: function( string ) { 6370 return string.replace( rdashAlpha, fcamelCase ); 6371 } 6372 }); 6373 6374 // DEPRECATED, Use jQuery.css() instead 6375 jQuery.curCSS = jQuery.css; 6376 6377 jQuery.each(["height", "width"], function( i, name ) { 6378 jQuery.cssHooks[ name ] = { 6379 get: function( elem, computed, extra ) { 6380 var val; 6381 6382 if ( computed ) { 6383 if ( elem.offsetWidth !== 0 ) { 6384 val = getWH( elem, name, extra ); 6385 6386 } else { 6387 jQuery.swap( elem, cssShow, function() { 6388 val = getWH( elem, name, extra ); 6389 }); 6390 } 6391 6392 if ( val <= 0 ) { 6393 val = curCSS( elem, name, name ); 6394 6395 if ( val === "0px" && currentStyle ) { 6396 val = currentStyle( elem, name, name ); 6397 } 6398 6399 if ( val != null ) { 6400 // Should return "auto" instead of 0, use 0 for 6401 // temporary backwards-compat 6402 return val === "" || val === "auto" ? "0px" : val; 6403 } 6404 } 6405 6406 if ( val < 0 || val == null ) { 6407 val = elem.style[ name ]; 6408 6409 // Should return "auto" instead of 0, use 0 for 6410 // temporary backwards-compat 6411 return val === "" || val === "auto" ? "0px" : val; 6412 } 6413 6414 return typeof val === "string" ? val : val + "px"; 6415 } 6416 }, 6417 6418 set: function( elem, value ) { 6419 if ( rnumpx.test( value ) ) { 6420 // ignore negative width and height values #1599 6421 value = parseFloat(value); 6422 6423 if ( value >= 0 ) { 6424 return value + "px"; 6425 } 6426 6427 } else { 6428 return value; 6429 } 6430 } 6431 }; 6432 }); 6433 6434 if ( !jQuery.support.opacity ) { 6435 jQuery.cssHooks.opacity = { 6436 get: function( elem, computed ) { 6437 // IE uses filters for opacity 6438 return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ? 6439 ( parseFloat( RegExp.$1 ) / 100 ) + "" : 6440 computed ? "1" : ""; 6441 }, 6442 6443 set: function( elem, value ) { 6444 var style = elem.style, 6445 currentStyle = elem.currentStyle; 6446 6447 // IE has trouble with opacity if it does not have layout 6448 // Force it by setting the zoom level 6449 style.zoom = 1; 6450 6451 // Set the alpha filter to set the opacity 6452 var opacity = jQuery.isNaN( value ) ? 6453 "" : 6454 "alpha(opacity=" + value * 100 + ")", 6455 filter = currentStyle && currentStyle.filter || style.filter || ""; 6456 6457 style.filter = ralpha.test( filter ) ? 6458 filter.replace( ralpha, opacity ) : 6459 filter + " " + opacity; 6460 } 6461 }; 6462 } 6463 6464 jQuery(function() { 6465 // This hook cannot be added until DOM ready because the support test 6466 // for it is not run until after DOM ready 6467 if ( !jQuery.support.reliableMarginRight ) { 6468 jQuery.cssHooks.marginRight = { 6469 get: function( elem, computed ) { 6470 // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right 6471 // Work around by temporarily setting element display to inline-block 6472 var ret; 6473 jQuery.swap( elem, { "display": "inline-block" }, function() { 6474 if ( computed ) { 6475 ret = curCSS( elem, "margin-right", "marginRight" ); 6476 } else { 6477 ret = elem.style.marginRight; 6478 } 6479 }); 6480 return ret; 6481 } 6482 }; 6483 } 6484 }); 6485 6486 if ( document.defaultView && document.defaultView.getComputedStyle ) { 6487 getComputedStyle = function( elem, name ) { 6488 var ret, defaultView, computedStyle; 6489 6490 name = name.replace( rupper, "-$1" ).toLowerCase(); 6491 6492 if ( !(defaultView = elem.ownerDocument.defaultView) ) { 6493 return undefined; 6494 } 6495 6496 if ( (computedStyle = defaultView.getComputedStyle( elem, null )) ) { 6497 ret = computedStyle.getPropertyValue( name ); 6498 if ( ret === "" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) { 6499 ret = jQuery.style( elem, name ); 6500 } 6501 } 6502 6503 return ret; 6504 }; 6505 } 6506 6507 if ( document.documentElement.currentStyle ) { 6508 currentStyle = function( elem, name ) { 6509 var left, 6510 ret = elem.currentStyle && elem.currentStyle[ name ], 6511 rsLeft = elem.runtimeStyle && elem.runtimeStyle[ name ], 6512 style = elem.style; 6513 6514 // From the awesome hack by Dean Edwards 6515 // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 6516 6517 // If we're not dealing with a regular pixel number 6518 // but a number that has a weird ending, we need to convert it to pixels 6519 if ( !rnumpx.test( ret ) && rnum.test( ret ) ) { 6520 // Remember the original values 6521 left = style.left; 6522 6523 // Put in the new values to get a computed value out 6524 if ( rsLeft ) { 6525 elem.runtimeStyle.left = elem.currentStyle.left; 6526 } 6527 style.left = name === "fontSize" ? "1em" : (ret || 0); 6528 ret = style.pixelLeft + "px"; 6529 6530 // Revert the changed values 6531 style.left = left; 6532 if ( rsLeft ) { 6533 elem.runtimeStyle.left = rsLeft; 6534 } 6535 } 6536 6537 return ret === "" ? "auto" : ret; 6538 }; 6539 } 6540 6541 curCSS = getComputedStyle || currentStyle; 6542 6543 function getWH( elem, name, extra ) { 6544 var which = name === "width" ? cssWidth : cssHeight, 6545 val = name === "width" ? elem.offsetWidth : elem.offsetHeight; 6546 6547 if ( extra === "border" ) { 6548 return val; 6549 } 6550 6551 jQuery.each( which, function() { 6552 if ( !extra ) { 6553 val -= parseFloat(jQuery.css( elem, "padding" + this )) || 0; 6554 } 6555 6556 if ( extra === "margin" ) { 6557 val += parseFloat(jQuery.css( elem, "margin" + this )) || 0; 6558 6559 } else { 6560 val -= parseFloat(jQuery.css( elem, "border" + this + "Width" )) || 0; 6561 } 6562 }); 6563 6564 return val; 6565 } 6566 6567 if ( jQuery.expr && jQuery.expr.filters ) { 6568 jQuery.expr.filters.hidden = function( elem ) { 6569 var width = elem.offsetWidth, 6570 height = elem.offsetHeight; 6571 6572 return (width === 0 && height === 0) || (!jQuery.support.reliableHiddenOffsets && (elem.style.display || jQuery.css( elem, "display" )) === "none"); 6573 }; 6574 6575 jQuery.expr.filters.visible = function( elem ) { 6576 return !jQuery.expr.filters.hidden( elem ); 6577 }; 6578 } 6579 6580 6581 6582 6583 var r20 = /%20/g, 6584 rbracket = /\[\]$/, 6585 rCRLF = /\r?\n/g, 6586 rhash = /#.*$/, 6587 rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL 6588 rinput = /^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i, 6589 // #7653, #8125, #8152: local protocol detection 6590 rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|widget):$/, 6591 rnoContent = /^(?:GET|HEAD)$/, 6592 rprotocol = /^\/\//, 6593 rquery = /\?/, 6594 rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, 6595 rselectTextarea = /^(?:select|textarea)/i, 6596 rspacesAjax = /\s+/, 6597 rts = /([?&])_=[^&]*/, 6598 rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/, 6599 6600 // Keep a copy of the old load method 6601 _load = jQuery.fn.load, 6602 6603 /* Prefilters 6604 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) 6605 * 2) These are called: 6606 * - BEFORE asking for a transport 6607 * - AFTER param serialization (s.data is a string if s.processData is true) 6608 * 3) key is the dataType 6609 * 4) the catchall symbol "*" can be used 6610 * 5) execution will start with transport dataType and THEN continue down to "*" if needed 6611 */ 6612 prefilters = {}, 6613 6614 /* Transports bindings 6615 * 1) key is the dataType 6616 * 2) the catchall symbol "*" can be used 6617 * 3) selection will start with transport dataType and THEN go to "*" if needed 6618 */ 6619 transports = {}, 6620 6621 // Document location 6622 ajaxLocation, 6623 6624 // Document location segments 6625 ajaxLocParts; 6626 6627 // #8138, IE may throw an exception when accessing 6628 // a field from window.location if document.domain has been set 6629 try { 6630 ajaxLocation = location.href; 6631 } catch( e ) { 6632 // Use the href attribute of an A element 6633 // since IE will modify it given document.location 6634 ajaxLocation = document.createElement( "a" ); 6635 ajaxLocation.href = ""; 6636 ajaxLocation = ajaxLocation.href; 6637 } 6638 6639 // Segment location into parts 6640 ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || []; 6641 6642 // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport 6643 function addToPrefiltersOrTransports( structure ) { 6644 6645 // dataTypeExpression is optional and defaults to "*" 6646 return function( dataTypeExpression, func ) { 6647 6648 if ( typeof dataTypeExpression !== "string" ) { 6649 func = dataTypeExpression; 6650 dataTypeExpression = "*"; 6651 } 6652 6653 if ( jQuery.isFunction( func ) ) { 6654 var dataTypes = dataTypeExpression.toLowerCase().split( rspacesAjax ), 6655 i = 0, 6656 length = dataTypes.length, 6657 dataType, 6658 list, 6659 placeBefore; 6660 6661 // For each dataType in the dataTypeExpression 6662 for(; i < length; i++ ) { 6663 dataType = dataTypes[ i ]; 6664 // We control if we're asked to add before 6665 // any existing element 6666 placeBefore = /^\+/.test( dataType ); 6667 if ( placeBefore ) { 6668 dataType = dataType.substr( 1 ) || "*"; 6669 } 6670 list = structure[ dataType ] = structure[ dataType ] || []; 6671 // then we add to the structure accordingly 6672 list[ placeBefore ? "unshift" : "push" ]( func ); 6673 } 6674 } 6675 }; 6676 } 6677 6678 // Base inspection function for prefilters and transports 6679 function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR, 6680 dataType /* internal */, inspected /* internal */ ) { 6681 6682 dataType = dataType || options.dataTypes[ 0 ]; 6683 inspected = inspected || {}; 6684 6685 inspected[ dataType ] = true; 6686 6687 var list = structure[ dataType ], 6688 i = 0, 6689 length = list ? list.length : 0, 6690 executeOnly = ( structure === prefilters ), 6691 selection; 6692 6693 for(; i < length && ( executeOnly || !selection ); i++ ) { 6694 selection = list[ i ]( options, originalOptions, jqXHR ); 6695 // If we got redirected to another dataType 6696 // we try there if executing only and not done already 6697 if ( typeof selection === "string" ) { 6698 if ( !executeOnly || inspected[ selection ] ) { 6699 selection = undefined; 6700 } else { 6701 options.dataTypes.unshift( selection ); 6702 selection = inspectPrefiltersOrTransports( 6703 structure, options, originalOptions, jqXHR, selection, inspected ); 6704 } 6705 } 6706 } 6707 // If we're only executing or nothing was selected 6708 // we try the catchall dataType if not done already 6709 if ( ( executeOnly || !selection ) && !inspected[ "*" ] ) { 6710 selection = inspectPrefiltersOrTransports( 6711 structure, options, originalOptions, jqXHR, "*", inspected ); 6712 } 6713 // unnecessary when only executing (prefilters) 6714 // but it'll be ignored by the caller in that case 6715 return selection; 6716 } 6717 6718 jQuery.fn.extend({ 6719 load: function( url, params, callback ) { 6720 if ( typeof url !== "string" && _load ) { 6721 return _load.apply( this, arguments ); 6722 6723 // Don't do a request if no elements are being requested 6724 } else if ( !this.length ) { 6725 return this; 6726 } 6727 6728 var off = url.indexOf( " " ); 6729 if ( off >= 0 ) { 6730 var selector = url.slice( off, url.length ); 6731 url = url.slice( 0, off ); 6732 } 6733 6734 // Default to a GET request 6735 var type = "GET"; 6736 6737 // If the second parameter was provided 6738 if ( params ) { 6739 // If it's a function 6740 if ( jQuery.isFunction( params ) ) { 6741 // We assume that it's the callback 6742 callback = params; 6743 params = undefined; 6744 6745 // Otherwise, build a param string 6746 } else if ( typeof params === "object" ) { 6747 params = jQuery.param( params, jQuery.ajaxSettings.traditional ); 6748 type = "POST"; 6749 } 6750 } 6751 6752 var self = this; 6753 6754 // Request the remote document 6755 jQuery.ajax({ 6756 url: url, 6757 type: type, 6758 dataType: "html", 6759 data: params, 6760 // Complete callback (responseText is used internally) 6761 complete: function( jqXHR, status, responseText ) { 6762 // Store the response as specified by the jqXHR object 6763 responseText = jqXHR.responseText; 6764 // If successful, inject the HTML into all the matched elements 6765 if ( jqXHR.isResolved() ) { 6766 // #4825: Get the actual response in case 6767 // a dataFilter is present in ajaxSettings 6768 jqXHR.done(function( r ) { 6769 responseText = r; 6770 }); 6771 // See if a selector was specified 6772 self.html( selector ? 6773 // Create a dummy div to hold the results 6774 jQuery("<div>") 6775 // inject the contents of the document in, removing the scripts 6776 // to avoid any 'Permission Denied' errors in IE 6777 .append(responseText.replace(rscript, "")) 6778 6779 // Locate the specified elements 6780 .find(selector) : 6781 6782 // If not, just inject the full result 6783 responseText ); 6784 } 6785 6786 if ( callback ) { 6787 self.each( callback, [ responseText, status, jqXHR ] ); 6788 } 6789 } 6790 }); 6791 6792 return this; 6793 }, 6794 6795 serialize: function() { 6796 return jQuery.param( this.serializeArray() ); 6797 }, 6798 6799 serializeArray: function() { 6800 return this.map(function(){ 6801 return this.elements ? jQuery.makeArray( this.elements ) : this; 6802 }) 6803 .filter(function(){ 6804 return this.name && !this.disabled && 6805 ( this.checked || rselectTextarea.test( this.nodeName ) || 6806 rinput.test( this.type ) ); 6807 }) 6808 .map(function( i, elem ){ 6809 var val = jQuery( this ).val(); 6810 6811 return val == null ? 6812 null : 6813 jQuery.isArray( val ) ? 6814 jQuery.map( val, function( val, i ){ 6815 return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; 6816 }) : 6817 { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; 6818 }).get(); 6819 } 6820 }); 6821 6822 // Attach a bunch of functions for handling common AJAX events 6823 jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split( " " ), function( i, o ){ 6824 jQuery.fn[ o ] = function( f ){ 6825 return this.bind( o, f ); 6826 }; 6827 }); 6828 6829 jQuery.each( [ "get", "post" ], function( i, method ) { 6830 jQuery[ method ] = function( url, data, callback, type ) { 6831 // shift arguments if data argument was omitted 6832 if ( jQuery.isFunction( data ) ) { 6833 type = type || callback; 6834 callback = data; 6835 data = undefined; 6836 } 6837 6838 return jQuery.ajax({ 6839 type: method, 6840 url: url, 6841 data: data, 6842 success: callback, 6843 dataType: type 6844 }); 6845 }; 6846 }); 6847 6848 jQuery.extend({ 6849 6850 getScript: function( url, callback ) { 6851 return jQuery.get( url, undefined, callback, "script" ); 6852 }, 6853 6854 getJSON: function( url, data, callback ) { 6855 return jQuery.get( url, data, callback, "json" ); 6856 }, 6857 6858 // Creates a full fledged settings object into target 6859 // with both ajaxSettings and settings fields. 6860 // If target is omitted, writes into ajaxSettings. 6861 ajaxSetup: function ( target, settings ) { 6862 if ( !settings ) { 6863 // Only one parameter, we extend ajaxSettings 6864 settings = target; 6865 target = jQuery.extend( true, jQuery.ajaxSettings, settings ); 6866 } else { 6867 // target was provided, we extend into it 6868 jQuery.extend( true, target, jQuery.ajaxSettings, settings ); 6869 } 6870 // Flatten fields we don't want deep extended 6871 for( var field in { context: 1, url: 1 } ) { 6872 if ( field in settings ) { 6873 target[ field ] = settings[ field ]; 6874 } else if( field in jQuery.ajaxSettings ) { 6875 target[ field ] = jQuery.ajaxSettings[ field ]; 6876 } 6877 } 6878 return target; 6879 }, 6880 6881 ajaxSettings: { 6882 url: ajaxLocation, 6883 isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ), 6884 global: true, 6885 type: "GET", 6886 contentType: "application/x-www-form-urlencoded", 6887 processData: true, 6888 async: true, 6889 /* 6890 timeout: 0, 6891 data: null, 6892 dataType: null, 6893 username: null, 6894 password: null, 6895 cache: null, 6896 traditional: false, 6897 headers: {}, 6898 */ 6899 6900 accepts: { 6901 xml: "application/xml, text/xml", 6902 html: "text/html", 6903 text: "text/plain", 6904 json: "application/json, text/javascript", 6905 "*": "*/*" 6906 }, 6907 6908 contents: { 6909 xml: /xml/, 6910 html: /html/, 6911 json: /json/ 6912 }, 6913 6914 responseFields: { 6915 xml: "responseXML", 6916 text: "responseText" 6917 }, 6918 6919 // List of data converters 6920 // 1) key format is "source_type destination_type" (a single space in-between) 6921 // 2) the catchall symbol "*" can be used for source_type 6922 converters: { 6923 6924 // Convert anything to text 6925 "* text": window.String, 6926 6927 // Text to html (true = no transformation) 6928 "text html": true, 6929 6930 // Evaluate text as a json expression 6931 "text json": jQuery.parseJSON, 6932 6933 // Parse text as xml 6934 "text xml": jQuery.parseXML 6935 } 6936 }, 6937 6938 ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), 6939 ajaxTransport: addToPrefiltersOrTransports( transports ), 6940 6941 // Main method 6942 ajax: function( url, options ) { 6943 6944 // If url is an object, simulate pre-1.5 signature 6945 if ( typeof url === "object" ) { 6946 options = url; 6947 url = undefined; 6948 } 6949 6950 // Force options to be an object 6951 options = options || {}; 6952 6953 var // Create the final options object 6954 s = jQuery.ajaxSetup( {}, options ), 6955 // Callbacks context 6956 callbackContext = s.context || s, 6957 // Context for global events 6958 // It's the callbackContext if one was provided in the options 6959 // and if it's a DOM node or a jQuery collection 6960 globalEventContext = callbackContext !== s && 6961 ( callbackContext.nodeType || callbackContext instanceof jQuery ) ? 6962 jQuery( callbackContext ) : jQuery.event, 6963 // Deferreds 6964 deferred = jQuery.Deferred(), 6965 completeDeferred = jQuery._Deferred(), 6966 // Status-dependent callbacks 6967 statusCode = s.statusCode || {}, 6968 // ifModified key 6969 ifModifiedKey, 6970 // Headers (they are sent all at once) 6971 requestHeaders = {}, 6972 requestHeadersNames = {}, 6973 // Response headers 6974 responseHeadersString, 6975 responseHeaders, 6976 // transport 6977 transport, 6978 // timeout handle 6979 timeoutTimer, 6980 // Cross-domain detection vars 6981 parts, 6982 // The jqXHR state 6983 state = 0, 6984 // To know if global events are to be dispatched 6985 fireGlobals, 6986 // Loop variable 6987 i, 6988 // Fake xhr 6989 jqXHR = { 6990 6991 readyState: 0, 6992 6993 // Caches the header 6994 setRequestHeader: function( name, value ) { 6995 if ( !state ) { 6996 var lname = name.toLowerCase(); 6997 name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name; 6998 requestHeaders[ name ] = value; 6999 } 7000 return this; 7001 }, 7002 7003 // Raw string 7004 getAllResponseHeaders: function() { 7005 return state === 2 ? responseHeadersString : null; 7006 }, 7007 7008 // Builds headers hashtable if needed 7009 getResponseHeader: function( key ) { 7010 var match; 7011 if ( state === 2 ) { 7012 if ( !responseHeaders ) { 7013 responseHeaders = {}; 7014 while( ( match = rheaders.exec( responseHeadersString ) ) ) { 7015 responseHeaders[ match[1].toLowerCase() ] = match[ 2 ]; 7016 } 7017 } 7018 match = responseHeaders[ key.toLowerCase() ]; 7019 } 7020 return match === undefined ? null : match; 7021 }, 7022 7023 // Overrides response content-type header 7024 overrideMimeType: function( type ) { 7025 if ( !state ) { 7026 s.mimeType = type; 7027 } 7028 return this; 7029 }, 7030 7031 // Cancel the request 7032 abort: function( statusText ) { 7033 statusText = statusText || "abort"; 7034 if ( transport ) { 7035 transport.abort( statusText ); 7036 } 7037 done( 0, statusText ); 7038 return this; 7039 } 7040 }; 7041 7042 // Callback for when everything is done 7043 // It is defined here because jslint complains if it is declared 7044 // at the end of the function (which would be more logical and readable) 7045 function done( status, statusText, responses, headers ) { 7046 7047 // Called once 7048 if ( state === 2 ) { 7049 return; 7050 } 7051 7052 // State is "done" now 7053 state = 2; 7054 7055 // Clear timeout if it exists 7056 if ( timeoutTimer ) { 7057 clearTimeout( timeoutTimer ); 7058 } 7059 7060 // Dereference transport for early garbage collection 7061 // (no matter how long the jqXHR object will be used) 7062 transport = undefined; 7063 7064 // Cache response headers 7065 responseHeadersString = headers || ""; 7066 7067 // Set readyState 7068 jqXHR.readyState = status ? 4 : 0; 7069 7070 var isSuccess, 7071 success, 7072 error, 7073 response = responses ? ajaxHandleResponses( s, jqXHR, responses ) : undefined, 7074 lastModified, 7075 etag; 7076 7077 // If successful, handle type chaining 7078 if ( status >= 200 && status < 300 || status === 304 ) { 7079 7080 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. 7081 if ( s.ifModified ) { 7082 7083 if ( ( lastModified = jqXHR.getResponseHeader( "Last-Modified" ) ) ) { 7084 jQuery.lastModified[ ifModifiedKey ] = lastModified; 7085 } 7086 if ( ( etag = jqXHR.getResponseHeader( "Etag" ) ) ) { 7087 jQuery.etag[ ifModifiedKey ] = etag; 7088 } 7089 } 7090 7091 // If not modified 7092 if ( status === 304 ) { 7093 7094 statusText = "notmodified"; 7095 isSuccess = true; 7096 7097 // If we have data 7098 } else { 7099 7100 try { 7101 success = ajaxConvert( s, response ); 7102 statusText = "success"; 7103 isSuccess = true; 7104 } catch(e) { 7105 // We have a parsererror 7106 statusText = "parsererror"; 7107 error = e; 7108 } 7109 } 7110 } else { 7111 // We extract error from statusText 7112 // then normalize statusText and status for non-aborts 7113 error = statusText; 7114 if( !statusText || status ) { 7115 statusText = "error"; 7116 if ( status < 0 ) { 7117 status = 0; 7118 } 7119 } 7120 } 7121 7122 // Set data for the fake xhr object 7123 jqXHR.status = status; 7124 jqXHR.statusText = statusText; 7125 7126 // Success/Error 7127 if ( isSuccess ) { 7128 deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); 7129 } else { 7130 deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); 7131 } 7132 7133 // Status-dependent callbacks 7134 jqXHR.statusCode( statusCode ); 7135 statusCode = undefined; 7136 7137 if ( fireGlobals ) { 7138 globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ), 7139 [ jqXHR, s, isSuccess ? success : error ] ); 7140 } 7141 7142 // Complete 7143 completeDeferred.resolveWith( callbackContext, [ jqXHR, statusText ] ); 7144 7145 if ( fireGlobals ) { 7146 globalEventContext.trigger( "ajaxComplete", [ jqXHR, s] ); 7147 // Handle the global AJAX counter 7148 if ( !( --jQuery.active ) ) { 7149 jQuery.event.trigger( "ajaxStop" ); 7150 } 7151 } 7152 } 7153 7154 // Attach deferreds 7155 deferred.promise( jqXHR ); 7156 jqXHR.success = jqXHR.done; 7157 jqXHR.error = jqXHR.fail; 7158 jqXHR.complete = completeDeferred.done; 7159 7160 // Status-dependent callbacks 7161 jqXHR.statusCode = function( map ) { 7162 if ( map ) { 7163 var tmp; 7164 if ( state < 2 ) { 7165 for( tmp in map ) { 7166 statusCode[ tmp ] = [ statusCode[tmp], map[tmp] ]; 7167 } 7168 } else { 7169 tmp = map[ jqXHR.status ]; 7170 jqXHR.then( tmp, tmp ); 7171 } 7172 } 7173 return this; 7174 }; 7175 7176 // Remove hash character (#7531: and string promotion) 7177 // Add protocol if not provided (#5866: IE7 issue with protocol-less urls) 7178 // We also use the url parameter if available 7179 s.url = ( ( url || s.url ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" ); 7180 7181 // Extract dataTypes list 7182 s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( rspacesAjax ); 7183 7184 // Determine if a cross-domain request is in order 7185 if ( s.crossDomain == null ) { 7186 parts = rurl.exec( s.url.toLowerCase() ); 7187 s.crossDomain = !!( parts && 7188 ( parts[ 1 ] != ajaxLocParts[ 1 ] || parts[ 2 ] != ajaxLocParts[ 2 ] || 7189 ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? 80 : 443 ) ) != 7190 ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? 80 : 443 ) ) ) 7191 ); 7192 } 7193 7194 // Convert data if not already a string 7195 if ( s.data && s.processData && typeof s.data !== "string" ) { 7196 s.data = jQuery.param( s.data, s.traditional ); 7197 } 7198 7199 // Apply prefilters 7200 inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); 7201 7202 // If request was aborted inside a prefiler, stop there 7203 if ( state === 2 ) { 7204 return false; 7205 } 7206 7207 // We can fire global events as of now if asked to 7208 fireGlobals = s.global; 7209 7210 // Uppercase the type 7211 s.type = s.type.toUpperCase(); 7212 7213 // Determine if request has content 7214 s.hasContent = !rnoContent.test( s.type ); 7215 7216 // Watch for a new set of requests 7217 if ( fireGlobals && jQuery.active++ === 0 ) { 7218 jQuery.event.trigger( "ajaxStart" ); 7219 } 7220 7221 // More options handling for requests with no content 7222 if ( !s.hasContent ) { 7223 7224 // If data is available, append data to url 7225 if ( s.data ) { 7226 s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data; 7227 } 7228 7229 // Get ifModifiedKey before adding the anti-cache parameter 7230 ifModifiedKey = s.url; 7231 7232 // Add anti-cache in url if needed 7233 if ( s.cache === false ) { 7234 7235 var ts = jQuery.now(), 7236 // try replacing _= if it is there 7237 ret = s.url.replace( rts, "$1_=" + ts ); 7238 7239 // if nothing was replaced, add timestamp to the end 7240 s.url = ret + ( (ret === s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : "" ); 7241 } 7242 } 7243 7244 // Set the correct header, if data is being sent 7245 if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { 7246 jqXHR.setRequestHeader( "Content-Type", s.contentType ); 7247 } 7248 7249 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. 7250 if ( s.ifModified ) { 7251 ifModifiedKey = ifModifiedKey || s.url; 7252 if ( jQuery.lastModified[ ifModifiedKey ] ) { 7253 jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ ifModifiedKey ] ); 7254 } 7255 if ( jQuery.etag[ ifModifiedKey ] ) { 7256 jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ ifModifiedKey ] ); 7257 } 7258 } 7259 7260 // Set the Accepts header for the server, depending on the dataType 7261 jqXHR.setRequestHeader( 7262 "Accept", 7263 s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ? 7264 s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", */*; q=0.01" : "" ) : 7265 s.accepts[ "*" ] 7266 ); 7267 7268 // Check for headers option 7269 for ( i in s.headers ) { 7270 jqXHR.setRequestHeader( i, s.headers[ i ] ); 7271 } 7272 7273 // Allow custom headers/mimetypes and early abort 7274 if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) { 7275 // Abort if not done already 7276 jqXHR.abort(); 7277 return false; 7278 7279 } 7280 7281 // Install callbacks on deferreds 7282 for ( i in { success: 1, error: 1, complete: 1 } ) { 7283 jqXHR[ i ]( s[ i ] ); 7284 } 7285 7286 // Get transport 7287 transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); 7288 7289 // If no transport, we auto-abort 7290 if ( !transport ) { 7291 done( -1, "No Transport" ); 7292 } else { 7293 jqXHR.readyState = 1; 7294 // Send global event 7295 if ( fireGlobals ) { 7296 globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); 7297 } 7298 // Timeout 7299 if ( s.async && s.timeout > 0 ) { 7300 timeoutTimer = setTimeout( function(){ 7301 jqXHR.abort( "timeout" ); 7302 }, s.timeout ); 7303 } 7304 7305 try { 7306 state = 1; 7307 transport.send( requestHeaders, done ); 7308 } catch (e) { 7309 // Propagate exception as error if not done 7310 if ( status < 2 ) { 7311 done( -1, e ); 7312 // Simply rethrow otherwise 7313 } else { 7314 jQuery.error( e ); 7315 } 7316 } 7317 } 7318 7319 return jqXHR; 7320 }, 7321 7322 // Serialize an array of form elements or a set of 7323 // key/values into a query string 7324 param: function( a, traditional ) { 7325 var s = [], 7326 add = function( key, value ) { 7327 // If value is a function, invoke it and return its value 7328 value = jQuery.isFunction( value ) ? value() : value; 7329 s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value ); 7330 }; 7331 7332 // Set traditional to true for jQuery <= 1.3.2 behavior. 7333 if ( traditional === undefined ) { 7334 traditional = jQuery.ajaxSettings.traditional; 7335 } 7336 7337 // If an array was passed in, assume that it is an array of form elements. 7338 if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { 7339 // Serialize the form elements 7340 jQuery.each( a, function() { 7341 add( this.name, this.value ); 7342 }); 7343 7344 } else { 7345 // If traditional, encode the "old" way (the way 1.3.2 or older 7346 // did it), otherwise encode params recursively. 7347 for ( var prefix in a ) { 7348 buildParams( prefix, a[ prefix ], traditional, add ); 7349 } 7350 } 7351 7352 // Return the resulting serialization 7353 return s.join( "&" ).replace( r20, "+" ); 7354 } 7355 }); 7356 7357 function buildParams( prefix, obj, traditional, add ) { 7358 if ( jQuery.isArray( obj ) ) { 7359 // Serialize array item. 7360 jQuery.each( obj, function( i, v ) { 7361 if ( traditional || rbracket.test( prefix ) ) { 7362 // Treat each array item as a scalar. 7363 add( prefix, v ); 7364 7365 } else { 7366 // If array item is non-scalar (array or object), encode its 7367 // numeric index to resolve deserialization ambiguity issues. 7368 // Note that rack (as of 1.0.0) can't currently deserialize 7369 // nested arrays properly, and attempting to do so may cause 7370 // a server error. Possible fixes are to modify rack's 7371 // deserialization algorithm or to provide an option or flag 7372 // to force array serialization to be shallow. 7373 buildParams( prefix + "[" + ( typeof v === "object" || jQuery.isArray(v) ? i : "" ) + "]", v, traditional, add ); 7374 } 7375 }); 7376 7377 } else if ( !traditional && obj != null && typeof obj === "object" ) { 7378 // Serialize object item. 7379 for ( var name in obj ) { 7380 buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); 7381 } 7382 7383 } else { 7384 // Serialize scalar item. 7385 add( prefix, obj ); 7386 } 7387 } 7388 7389 // This is still on the jQuery object... for now 7390 // Want to move this to jQuery.ajax some day 7391 jQuery.extend({ 7392 7393 // Counter for holding the number of active queries 7394 active: 0, 7395 7396 // Last-Modified header cache for next request 7397 lastModified: {}, 7398 etag: {} 7399 7400 }); 7401 7402 /* Handles responses to an ajax request: 7403 * - sets all responseXXX fields accordingly 7404 * - finds the right dataType (mediates between content-type and expected dataType) 7405 * - returns the corresponding response 7406 */ 7407 function ajaxHandleResponses( s, jqXHR, responses ) { 7408 7409 var contents = s.contents, 7410 dataTypes = s.dataTypes, 7411 responseFields = s.responseFields, 7412 ct, 7413 type, 7414 finalDataType, 7415 firstDataType; 7416 7417 // Fill responseXXX fields 7418 for( type in responseFields ) { 7419 if ( type in responses ) { 7420 jqXHR[ responseFields[type] ] = responses[ type ]; 7421 } 7422 } 7423 7424 // Remove auto dataType and get content-type in the process 7425 while( dataTypes[ 0 ] === "*" ) { 7426 dataTypes.shift(); 7427 if ( ct === undefined ) { 7428 ct = s.mimeType || jqXHR.getResponseHeader( "content-type" ); 7429 } 7430 } 7431 7432 // Check if we're dealing with a known content-type 7433 if ( ct ) { 7434 for ( type in contents ) { 7435 if ( contents[ type ] && contents[ type ].test( ct ) ) { 7436 dataTypes.unshift( type ); 7437 break; 7438 } 7439 } 7440 } 7441 7442 // Check to see if we have a response for the expected dataType 7443 if ( dataTypes[ 0 ] in responses ) { 7444 finalDataType = dataTypes[ 0 ]; 7445 } else { 7446 // Try convertible dataTypes 7447 for ( type in responses ) { 7448 if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) { 7449 finalDataType = type; 7450 break; 7451 } 7452 if ( !firstDataType ) { 7453 firstDataType = type; 7454 } 7455 } 7456 // Or just use first one 7457 finalDataType = finalDataType || firstDataType; 7458 } 7459 7460 // If we found a dataType 7461 // We add the dataType to the list if needed 7462 // and return the corresponding response 7463 if ( finalDataType ) { 7464 if ( finalDataType !== dataTypes[ 0 ] ) { 7465 dataTypes.unshift( finalDataType ); 7466 } 7467 return responses[ finalDataType ]; 7468 } 7469 } 7470 7471 // Chain conversions given the request and the original response 7472 function ajaxConvert( s, response ) { 7473 7474 // Apply the dataFilter if provided 7475 if ( s.dataFilter ) { 7476 response = s.dataFilter( response, s.dataType ); 7477 } 7478 7479 var dataTypes = s.dataTypes, 7480 converters = {}, 7481 i, 7482 key, 7483 length = dataTypes.length, 7484 tmp, 7485 // Current and previous dataTypes 7486 current = dataTypes[ 0 ], 7487 prev, 7488 // Conversion expression 7489 conversion, 7490 // Conversion function 7491 conv, 7492 // Conversion functions (transitive conversion) 7493 conv1, 7494 conv2; 7495 7496 // For each dataType in the chain 7497 for( i = 1; i < length; i++ ) { 7498 7499 // Create converters map 7500 // with lowercased keys 7501 if ( i === 1 ) { 7502 for( key in s.converters ) { 7503 if( typeof key === "string" ) { 7504 converters[ key.toLowerCase() ] = s.converters[ key ]; 7505 } 7506 } 7507 } 7508 7509 // Get the dataTypes 7510 prev = current; 7511 current = dataTypes[ i ]; 7512 7513 // If current is auto dataType, update it to prev 7514 if( current === "*" ) { 7515 current = prev; 7516 // If no auto and dataTypes are actually different 7517 } else if ( prev !== "*" && prev !== current ) { 7518 7519 // Get the converter 7520 conversion = prev + " " + current; 7521 conv = converters[ conversion ] || converters[ "* " + current ]; 7522 7523 // If there is no direct converter, search transitively 7524 if ( !conv ) { 7525 conv2 = undefined; 7526 for( conv1 in converters ) { 7527 tmp = conv1.split( " " ); 7528 if ( tmp[ 0 ] === prev || tmp[ 0 ] === "*" ) { 7529 conv2 = converters[ tmp[1] + " " + current ]; 7530 if ( conv2 ) { 7531 conv1 = converters[ conv1 ]; 7532 if ( conv1 === true ) { 7533 conv = conv2; 7534 } else if ( conv2 === true ) { 7535 conv = conv1; 7536 } 7537 break; 7538 } 7539 } 7540 } 7541 } 7542 // If we found no converter, dispatch an error 7543 if ( !( conv || conv2 ) ) { 7544 jQuery.error( "No conversion from " + conversion.replace(" "," to ") ); 7545 } 7546 // If found converter is not an equivalence 7547 if ( conv !== true ) { 7548 // Convert with 1 or 2 converters accordingly 7549 response = conv ? conv( response ) : conv2( conv1(response) ); 7550 } 7551 } 7552 } 7553 return response; 7554 } 7555 7556 7557 7558 7559 var jsc = jQuery.now(), 7560 jsre = /(\=)\?(&|$)|\?\?/i; 7561 7562 // Default jsonp settings 7563 jQuery.ajaxSetup({ 7564 jsonp: "callback", 7565 jsonpCallback: function() { 7566 return jQuery.expando + "_" + ( jsc++ ); 7567 } 7568 }); 7569 7570 // Detect, normalize options and install callbacks for jsonp requests 7571 jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { 7572 7573 var inspectData = s.contentType === "application/x-www-form-urlencoded" && 7574 ( typeof s.data === "string" ); 7575 7576 if ( s.dataTypes[ 0 ] === "jsonp" || 7577 s.jsonp !== false && ( jsre.test( s.url ) || 7578 inspectData && jsre.test( s.data ) ) ) { 7579 7580 var responseContainer, 7581 jsonpCallback = s.jsonpCallback = 7582 jQuery.isFunction( s.jsonpCallback ) ? s.jsonpCallback() : s.jsonpCallback, 7583 previous = window[ jsonpCallback ], 7584 url = s.url, 7585 data = s.data, 7586 replace = "$1" + jsonpCallback + "$2"; 7587 7588 if ( s.jsonp !== false ) { 7589 url = url.replace( jsre, replace ); 7590 if ( s.url === url ) { 7591 if ( inspectData ) { 7592 data = data.replace( jsre, replace ); 7593 } 7594 if ( s.data === data ) { 7595 // Add callback manually 7596 url += (/\?/.test( url ) ? "&" : "?") + s.jsonp + "=" + jsonpCallback; 7597 } 7598 } 7599 } 7600 7601 s.url = url; 7602 s.data = data; 7603 7604 // Install callback 7605 window[ jsonpCallback ] = function( response ) { 7606 responseContainer = [ response ]; 7607 }; 7608 7609 // Clean-up function 7610 jqXHR.always(function() { 7611 // Set callback back to previous value 7612 window[ jsonpCallback ] = previous; 7613 // Call if it was a function and we have a response 7614 if ( responseContainer && jQuery.isFunction( previous ) ) { 7615 window[ jsonpCallback ]( responseContainer[ 0 ] ); 7616 } 7617 }); 7618 7619 // Use data converter to retrieve json after script execution 7620 s.converters["script json"] = function() { 7621 if ( !responseContainer ) { 7622 jQuery.error( jsonpCallback + " was not called" ); 7623 } 7624 return responseContainer[ 0 ]; 7625 }; 7626 7627 // force json dataType 7628 s.dataTypes[ 0 ] = "json"; 7629 7630 // Delegate to script 7631 return "script"; 7632 } 7633 }); 7634 7635 7636 7637 7638 // Install script dataType 7639 jQuery.ajaxSetup({ 7640 accepts: { 7641 script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript" 7642 }, 7643 contents: { 7644 script: /javascript|ecmascript/ 7645 }, 7646 converters: { 7647 "text script": function( text ) { 7648 jQuery.globalEval( text ); 7649 return text; 7650 } 7651 } 7652 }); 7653 7654 // Handle cache's special case and global 7655 jQuery.ajaxPrefilter( "script", function( s ) { 7656 if ( s.cache === undefined ) { 7657 s.cache = false; 7658 } 7659 if ( s.crossDomain ) { 7660 s.type = "GET"; 7661 s.global = false; 7662 } 7663 }); 7664 7665 // Bind script tag hack transport 7666 jQuery.ajaxTransport( "script", function(s) { 7667 7668 // This transport only deals with cross domain requests 7669 if ( s.crossDomain ) { 7670 7671 var script, 7672 head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement; 7673 7674 return { 7675 7676 send: function( _, callback ) { 7677 7678 script = document.createElement( "script" ); 7679 7680 script.async = "async"; 7681 7682 if ( s.scriptCharset ) { 7683 script.charset = s.scriptCharset; 7684 } 7685 7686 script.src = s.url; 7687 7688 // Attach handlers for all browsers 7689 script.onload = script.onreadystatechange = function( _, isAbort ) { 7690 7691 if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) { 7692 7693 // Handle memory leak in IE 7694 script.onload = script.onreadystatechange = null; 7695 7696 // Remove the script 7697 if ( head && script.parentNode ) { 7698 head.removeChild( script ); 7699 } 7700 7701 // Dereference the script 7702 script = undefined; 7703 7704 // Callback if not abort 7705 if ( !isAbort ) { 7706 callback( 200, "success" ); 7707 } 7708 } 7709 }; 7710 // Use insertBefore instead of appendChild to circumvent an IE6 bug. 7711 // This arises when a base node is used (#2709 and #4378). 7712 head.insertBefore( script, head.firstChild ); 7713 }, 7714 7715 abort: function() { 7716 if ( script ) { 7717 script.onload( 0, 1 ); 7718 } 7719 } 7720 }; 7721 } 7722 }); 7723 7724 7725 7726 7727 var // #5280: Internet Explorer will keep connections alive if we don't abort on unload 7728 xhrOnUnloadAbort = window.ActiveXObject ? function() { 7729 // Abort all pending requests 7730 for ( var key in xhrCallbacks ) { 7731 xhrCallbacks[ key ]( 0, 1 ); 7732 } 7733 } : false, 7734 xhrId = 0, 7735 xhrCallbacks; 7736 7737 // Functions to create xhrs 7738 function createStandardXHR() { 7739 try { 7740 return new window.XMLHttpRequest(); 7741 } catch( e ) {} 7742 } 7743 7744 function createActiveXHR() { 7745 try { 7746 return new window.ActiveXObject( "Microsoft.XMLHTTP" ); 7747 } catch( e ) {} 7748 } 7749 7750 // Create the request object 7751 // (This is still attached to ajaxSettings for backward compatibility) 7752 jQuery.ajaxSettings.xhr = window.ActiveXObject ? 7753 /* Microsoft failed to properly 7754 * implement the XMLHttpRequest in IE7 (can't request local files), 7755 * so we use the ActiveXObject when it is available 7756 * Additionally XMLHttpRequest can be disabled in IE7/IE8 so 7757 * we need a fallback. 7758 */ 7759 function() { 7760 return !this.isLocal && createStandardXHR() || createActiveXHR(); 7761 } : 7762 // For all other browsers, use the standard XMLHttpRequest object 7763 createStandardXHR; 7764 7765 // Determine support properties 7766 (function( xhr ) { 7767 jQuery.extend( jQuery.support, { 7768 ajax: !!xhr, 7769 cors: !!xhr && ( "withCredentials" in xhr ) 7770 }); 7771 })( jQuery.ajaxSettings.xhr() ); 7772 7773 // Create transport if the browser can provide an xhr 7774 if ( jQuery.support.ajax ) { 7775 7776 jQuery.ajaxTransport(function( s ) { 7777 // Cross domain only allowed if supported through XMLHttpRequest 7778 if ( !s.crossDomain || jQuery.support.cors ) { 7779 7780 var callback; 7781 7782 return { 7783 send: function( headers, complete ) { 7784 7785 // Get a new xhr 7786 var xhr = s.xhr(), 7787 handle, 7788 i; 7789 7790 // Open the socket 7791 // Passing null username, generates a login popup on Opera (#2865) 7792 if ( s.username ) { 7793 xhr.open( s.type, s.url, s.async, s.username, s.password ); 7794 } else { 7795 xhr.open( s.type, s.url, s.async ); 7796 } 7797 7798 // Apply custom fields if provided 7799 if ( s.xhrFields ) { 7800 for ( i in s.xhrFields ) { 7801 xhr[ i ] = s.xhrFields[ i ]; 7802 } 7803 } 7804 7805 // Override mime type if needed 7806 if ( s.mimeType && xhr.overrideMimeType ) { 7807 xhr.overrideMimeType( s.mimeType ); 7808 } 7809 7810 // X-Requested-With header 7811 // For cross-domain requests, seeing as conditions for a preflight are 7812 // akin to a jigsaw puzzle, we simply never set it to be sure. 7813 // (it can always be set on a per-request basis or even using ajaxSetup) 7814 // For same-domain requests, won't change header if already provided. 7815 if ( !s.crossDomain && !headers["X-Requested-With"] ) { 7816 headers[ "X-Requested-With" ] = "XMLHttpRequest"; 7817 } 7818 7819 // Need an extra try/catch for cross domain requests in Firefox 3 7820 try { 7821 for ( i in headers ) { 7822 xhr.setRequestHeader( i, headers[ i ] ); 7823 } 7824 } catch( _ ) {} 7825 7826 // Do send the request 7827 // This may raise an exception which is actually 7828 // handled in jQuery.ajax (so no try/catch here) 7829 xhr.send( ( s.hasContent && s.data ) || null ); 7830 7831 // Listener 7832 callback = function( _, isAbort ) { 7833 7834 var status, 7835 statusText, 7836 responseHeaders, 7837 responses, 7838 xml; 7839 7840 // Firefox throws exceptions when accessing properties 7841 // of an xhr when a network error occured 7842 // http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE) 7843 try { 7844 7845 // Was never called and is aborted or complete 7846 if ( callback && ( isAbort || xhr.readyState === 4 ) ) { 7847 7848 // Only called once 7849 callback = undefined; 7850 7851 // Do not keep as active anymore 7852 if ( handle ) { 7853 xhr.onreadystatechange = jQuery.noop; 7854 if ( xhrOnUnloadAbort ) { 7855 delete xhrCallbacks[ handle ]; 7856 } 7857 } 7858 7859 // If it's an abort 7860 if ( isAbort ) { 7861 // Abort it manually if needed 7862 if ( xhr.readyState !== 4 ) { 7863 xhr.abort(); 7864 } 7865 } else { 7866 status = xhr.status; 7867 responseHeaders = xhr.getAllResponseHeaders(); 7868 responses = {}; 7869 xml = xhr.responseXML; 7870 7871 // Construct response list 7872 if ( xml && xml.documentElement /* #4958 */ ) { 7873 responses.xml = xml; 7874 } 7875 responses.text = xhr.responseText; 7876 7877 // Firefox throws an exception when accessing 7878 // statusText for faulty cross-domain requests 7879 try { 7880 statusText = xhr.statusText; 7881 } catch( e ) { 7882 // We normalize with Webkit giving an empty statusText 7883 statusText = ""; 7884 } 7885 7886 // Filter status for non standard behaviors 7887 7888 // If the request is local and we have data: assume a success 7889 // (success with no data won't get notified, that's the best we 7890 // can do given current implementations) 7891 if ( !status && s.isLocal && !s.crossDomain ) { 7892 status = responses.text ? 200 : 404; 7893 // IE - #1450: sometimes returns 1223 when it should be 204 7894 } else if ( status === 1223 ) { 7895 status = 204; 7896 } 7897 } 7898 } 7899 } catch( firefoxAccessException ) { 7900 if ( !isAbort ) { 7901 complete( -1, firefoxAccessException ); 7902 } 7903 } 7904 7905 // Call complete if needed 7906 if ( responses ) { 7907 complete( status, statusText, responses, responseHeaders ); 7908 } 7909 }; 7910 7911 // if we're in sync mode or it's in cache 7912 // and has been retrieved directly (IE6 & IE7) 7913 // we need to manually fire the callback 7914 if ( !s.async || xhr.readyState === 4 ) { 7915 callback(); 7916 } else { 7917 handle = ++xhrId; 7918 if ( xhrOnUnloadAbort ) { 7919 // Create the active xhrs callbacks list if needed 7920 // and attach the unload handler 7921 if ( !xhrCallbacks ) { 7922 xhrCallbacks = {}; 7923 jQuery( window ).unload( xhrOnUnloadAbort ); 7924 } 7925 // Add to list of active xhrs callbacks 7926 xhrCallbacks[ handle ] = callback; 7927 } 7928 xhr.onreadystatechange = callback; 7929 } 7930 }, 7931 7932 abort: function() { 7933 if ( callback ) { 7934 callback(0,1); 7935 } 7936 } 7937 }; 7938 } 7939 }); 7940 } 7941 7942 7943 7944 7945 var elemdisplay = {}, 7946 iframe, iframeDoc, 7947 rfxtypes = /^(?:toggle|show|hide)$/, 7948 rfxnum = /^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i, 7949 timerId, 7950 fxAttrs = [ 7951 // height animations 7952 [ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ], 7953 // width animations 7954 [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ], 7955 // opacity animations 7956 [ "opacity" ] 7957 ], 7958 fxNow, 7959 requestAnimationFrame = window.webkitRequestAnimationFrame || 7960 window.mozRequestAnimationFrame || 7961 window.oRequestAnimationFrame; 7962 7963 jQuery.fn.extend({ 7964 show: function( speed, easing, callback ) { 7965 var elem, display; 7966 7967 if ( speed || speed === 0 ) { 7968 return this.animate( genFx("show", 3), speed, easing, callback); 7969 7970 } else { 7971 for ( var i = 0, j = this.length; i < j; i++ ) { 7972 elem = this[i]; 7973 7974 if ( elem.style ) { 7975 display = elem.style.display; 7976 7977 // Reset the inline display of this element to learn if it is 7978 // being hidden by cascaded rules or not 7979 if ( !jQuery._data(elem, "olddisplay") && display === "none" ) { 7980 display = elem.style.display = ""; 7981 } 7982 7983 // Set elements which have been overridden with display: none 7984 // in a stylesheet to whatever the default browser style is 7985 // for such an element 7986 if ( display === "" && jQuery.css( elem, "display" ) === "none" ) { 7987 jQuery._data(elem, "olddisplay", defaultDisplay(elem.nodeName)); 7988 } 7989 } 7990 } 7991 7992 // Set the display of most of the elements in a second loop 7993 // to avoid the constant reflow 7994 for ( i = 0; i < j; i++ ) { 7995 elem = this[i]; 7996 7997 if ( elem.style ) { 7998 display = elem.style.display; 7999 8000 if ( display === "" || display === "none" ) { 8001 elem.style.display = jQuery._data(elem, "olddisplay") || ""; 8002 } 8003 } 8004 } 8005 8006 return this; 8007 } 8008 }, 8009 8010 hide: function( speed, easing, callback ) { 8011 if ( speed || speed === 0 ) { 8012 return this.animate( genFx("hide", 3), speed, easing, callback); 8013 8014 } else { 8015 for ( var i = 0, j = this.length; i < j; i++ ) { 8016 if ( this[i].style ) { 8017 var display = jQuery.css( this[i], "display" ); 8018 8019 if ( display !== "none" && !jQuery._data( this[i], "olddisplay" ) ) { 8020 jQuery._data( this[i], "olddisplay", display ); 8021 } 8022 } 8023 } 8024 8025 // Set the display of the elements in a second loop 8026 // to avoid the constant reflow 8027 for ( i = 0; i < j; i++ ) { 8028 if ( this[i].style ) { 8029 this[i].style.display = "none"; 8030 } 8031 } 8032 8033 return this; 8034 } 8035 }, 8036 8037 // Save the old toggle function 8038 _toggle: jQuery.fn.toggle, 8039 8040 toggle: function( fn, fn2, callback ) { 8041 var bool = typeof fn === "boolean"; 8042 8043 if ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) { 8044 this._toggle.apply( this, arguments ); 8045 8046 } else if ( fn == null || bool ) { 8047 this.each(function() { 8048 var state = bool ? fn : jQuery(this).is(":hidden"); 8049 jQuery(this)[ state ? "show" : "hide" ](); 8050 }); 8051 8052 } else { 8053 this.animate(genFx("toggle", 3), fn, fn2, callback); 8054 } 8055 8056 return this; 8057 }, 8058 8059 fadeTo: function( speed, to, easing, callback ) { 8060 return this.filter(":hidden").css("opacity", 0).show().end() 8061 .animate({opacity: to}, speed, easing, callback); 8062 }, 8063 8064 animate: function( prop, speed, easing, callback ) { 8065 var optall = jQuery.speed(speed, easing, callback); 8066 8067 if ( jQuery.isEmptyObject( prop ) ) { 8068 return this.each( optall.complete, [ false ] ); 8069 } 8070 8071 // Do not change referenced properties as per-property easing will be lost 8072 prop = jQuery.extend( {}, prop ); 8073 8074 return this[ optall.queue === false ? "each" : "queue" ](function() { 8075 // XXX 'this' does not always have a nodeName when running the 8076 // test suite 8077 8078 if ( optall.queue === false ) { 8079 jQuery._mark( this ); 8080 } 8081 8082 var opt = jQuery.extend( {}, optall ), 8083 isElement = this.nodeType === 1, 8084 hidden = isElement && jQuery(this).is(":hidden"), 8085 name, val, p, 8086 display, e, 8087 parts, start, end, unit; 8088 8089 // will store per property easing and be used to determine when an animation is complete 8090 opt.animatedProperties = {}; 8091 8092 for ( p in prop ) { 8093 8094 // property name normalization 8095 name = jQuery.camelCase( p ); 8096 if ( p !== name ) { 8097 prop[ name ] = prop[ p ]; 8098 delete prop[ p ]; 8099 } 8100 8101 val = prop[ name ]; 8102 8103 // easing resolution: per property > opt.specialEasing > opt.easing > 'swing' (default) 8104 if ( jQuery.isArray( val ) ) { 8105 opt.animatedProperties[ name ] = val[ 1 ]; 8106 val = prop[ name ] = val[ 0 ]; 8107 } else { 8108 opt.animatedProperties[ name ] = opt.specialEasing && opt.specialEasing[ name ] || opt.easing || 'swing'; 8109 } 8110 8111 if ( val === "hide" && hidden || val === "show" && !hidden ) { 8112 return opt.complete.call( this ); 8113 } 8114 8115 if ( isElement && ( name === "height" || name === "width" ) ) { 8116 // Make sure that nothing sneaks out 8117 // Record all 3 overflow attributes because IE does not 8118 // change the overflow attribute when overflowX and 8119 // overflowY are set to the same value 8120 opt.overflow = [ this.style.overflow, this.style.overflowX, this.style.overflowY ]; 8121 8122 // Set display property to inline-block for height/width 8123 // animations on inline elements that are having width/height 8124 // animated 8125 if ( jQuery.css( this, "display" ) === "inline" && 8126 jQuery.css( this, "float" ) === "none" ) { 8127 if ( !jQuery.support.inlineBlockNeedsLayout ) { 8128 this.style.display = "inline-block"; 8129 8130 } else { 8131 display = defaultDisplay( this.nodeName ); 8132 8133 // inline-level elements accept inline-block; 8134 // block-level elements need to be inline with layout 8135 if ( display === "inline" ) { 8136 this.style.display = "inline-block"; 8137 8138 } else { 8139 this.style.display = "inline"; 8140 this.style.zoom = 1; 8141 } 8142 } 8143 } 8144 } 8145 } 8146 8147 if ( opt.overflow != null ) { 8148 this.style.overflow = "hidden"; 8149 } 8150 8151 for ( p in prop ) { 8152 e = new jQuery.fx( this, opt, p ); 8153 val = prop[ p ]; 8154 8155 if ( rfxtypes.test(val) ) { 8156 e[ val === "toggle" ? hidden ? "show" : "hide" : val ](); 8157 8158 } else { 8159 parts = rfxnum.exec( val ); 8160 start = e.cur(); 8161 8162 if ( parts ) { 8163 end = parseFloat( parts[2] ); 8164 unit = parts[3] || ( jQuery.cssNumber[ p ] ? "" : "px" ); 8165 8166 // We need to compute starting value 8167 if ( unit !== "px" ) { 8168 jQuery.style( this, p, (end || 1) + unit); 8169 start = ((end || 1) / e.cur()) * start; 8170 jQuery.style( this, p, start + unit); 8171 } 8172 8173 // If a +=/-= token was provided, we're doing a relative animation 8174 if ( parts[1] ) { 8175 end = ( (parts[ 1 ] === "-=" ? -1 : 1) * end ) + start; 8176 } 8177 8178 e.custom( start, end, unit ); 8179 8180 } else { 8181 e.custom( start, val, "" ); 8182 } 8183 } 8184 } 8185 8186 // For JS strict compliance 8187 return true; 8188 }); 8189 }, 8190 8191 stop: function( clearQueue, gotoEnd ) { 8192 if ( clearQueue ) { 8193 this.queue([]); 8194 } 8195 8196 this.each(function() { 8197 var timers = jQuery.timers, 8198 i = timers.length; 8199 // clear marker counters if we know they won't be 8200 if ( !gotoEnd ) { 8201 jQuery._unmark( true, this ); 8202 } 8203 while ( i-- ) { 8204 if ( timers[i].elem === this ) { 8205 if (gotoEnd) { 8206 // force the next step to be the last 8207 timers[i](true); 8208 } 8209 8210 timers.splice(i, 1); 8211 } 8212 } 8213 }); 8214 8215 // start the next in the queue if the last step wasn't forced 8216 if ( !gotoEnd ) { 8217 this.dequeue(); 8218 } 8219 8220 return this; 8221 } 8222 8223 }); 8224 8225 // Animations created synchronously will run synchronously 8226 function createFxNow() { 8227 setTimeout( clearFxNow, 0 ); 8228 return ( fxNow = jQuery.now() ); 8229 } 8230 8231 function clearFxNow() { 8232 fxNow = undefined; 8233 } 8234 8235 // Generate parameters to create a standard animation 8236 function genFx( type, num ) { 8237 var obj = {}; 8238 8239 jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function() { 8240 obj[ this ] = type; 8241 }); 8242 8243 return obj; 8244 } 8245 8246 // Generate shortcuts for custom animations 8247 jQuery.each({ 8248 slideDown: genFx("show", 1), 8249 slideUp: genFx("hide", 1), 8250 slideToggle: genFx("toggle", 1), 8251 fadeIn: { opacity: "show" }, 8252 fadeOut: { opacity: "hide" }, 8253 fadeToggle: { opacity: "toggle" } 8254 }, function( name, props ) { 8255 jQuery.fn[ name ] = function( speed, easing, callback ) { 8256 return this.animate( props, speed, easing, callback ); 8257 }; 8258 }); 8259 8260 jQuery.extend({ 8261 speed: function( speed, easing, fn ) { 8262 var opt = speed && typeof speed === "object" ? jQuery.extend({}, speed) : { 8263 complete: fn || !fn && easing || 8264 jQuery.isFunction( speed ) && speed, 8265 duration: speed, 8266 easing: fn && easing || easing && !jQuery.isFunction(easing) && easing 8267 }; 8268 8269 opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration : 8270 opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[opt.duration] : jQuery.fx.speeds._default; 8271 8272 // Queueing 8273 opt.old = opt.complete; 8274 opt.complete = function( noUnmark ) { 8275 if ( opt.queue !== false ) { 8276 jQuery.dequeue( this ); 8277 } else if ( noUnmark !== false ) { 8278 jQuery._unmark( this ); 8279 } 8280 8281 if ( jQuery.isFunction( opt.old ) ) { 8282 opt.old.call( this ); 8283 } 8284 }; 8285 8286 return opt; 8287 }, 8288 8289 easing: { 8290 linear: function( p, n, firstNum, diff ) { 8291 return firstNum + diff * p; 8292 }, 8293 swing: function( p, n, firstNum, diff ) { 8294 return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum; 8295 } 8296 }, 8297 8298 timers: [], 8299 8300 fx: function( elem, options, prop ) { 8301 this.options = options; 8302 this.elem = elem; 8303 this.prop = prop; 8304 8305 options.orig = options.orig || {}; 8306 } 8307 8308 }); 8309 8310 jQuery.fx.prototype = { 8311 // Simple function for setting a style value 8312 update: function() { 8313 if ( this.options.step ) { 8314 this.options.step.call( this.elem, this.now, this ); 8315 } 8316 8317 (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this ); 8318 }, 8319 8320 // Get the current size 8321 cur: function() { 8322 if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) ) { 8323 return this.elem[ this.prop ]; 8324 } 8325 8326 var parsed, 8327 r = jQuery.css( this.elem, this.prop ); 8328 // Empty strings, null, undefined and "auto" are converted to 0, 8329 // complex values such as "rotate(1rad)" are returned as is, 8330 // simple values such as "10px" are parsed to Float. 8331 return isNaN( parsed = parseFloat( r ) ) ? !r || r === "auto" ? 0 : r : parsed; 8332 }, 8333 8334 // Start an animation from one number to another 8335 custom: function( from, to, unit ) { 8336 var self = this, 8337 fx = jQuery.fx, 8338 raf; 8339 8340 this.startTime = fxNow || createFxNow(); 8341 this.start = from; 8342 this.end = to; 8343 this.unit = unit || this.unit || ( jQuery.cssNumber[ this.prop ] ? "" : "px" ); 8344 this.now = this.start; 8345 this.pos = this.state = 0; 8346 8347 function t( gotoEnd ) { 8348 return self.step(gotoEnd); 8349 } 8350 8351 t.elem = this.elem; 8352 8353 if ( t() && jQuery.timers.push(t) && !timerId ) { 8354 // Use requestAnimationFrame instead of setInterval if available 8355 if ( requestAnimationFrame ) { 8356 timerId = 1; 8357 raf = function() { 8358 // When timerId gets set to null at any point, this stops 8359 if ( timerId ) { 8360 requestAnimationFrame( raf ); 8361 fx.tick(); 8362 } 8363 }; 8364 requestAnimationFrame( raf ); 8365 } else { 8366 timerId = setInterval( fx.tick, fx.interval ); 8367 } 8368 } 8369 }, 8370 8371 // Simple 'show' function 8372 show: function() { 8373 // Remember where we started, so that we can go back to it later 8374 this.options.orig[this.prop] = jQuery.style( this.elem, this.prop ); 8375 this.options.show = true; 8376 8377 // Begin the animation 8378 // Make sure that we start at a small width/height to avoid any 8379 // flash of content 8380 this.custom(this.prop === "width" || this.prop === "height" ? 1 : 0, this.cur()); 8381 8382 // Start by showing the element 8383 jQuery( this.elem ).show(); 8384 }, 8385 8386 // Simple 'hide' function 8387 hide: function() { 8388 // Remember where we started, so that we can go back to it later 8389 this.options.orig[this.prop] = jQuery.style( this.elem, this.prop ); 8390 this.options.hide = true; 8391 8392 // Begin the animation 8393 this.custom(this.cur(), 0); 8394 }, 8395 8396 // Each step of an animation 8397 step: function( gotoEnd ) { 8398 var t = fxNow || createFxNow(), 8399 done = true, 8400 elem = this.elem, 8401 options = this.options, 8402 i, n; 8403 8404 if ( gotoEnd || t >= options.duration + this.startTime ) { 8405 this.now = this.end; 8406 this.pos = this.state = 1; 8407 this.update(); 8408 8409 options.animatedProperties[ this.prop ] = true; 8410 8411 for ( i in options.animatedProperties ) { 8412 if ( options.animatedProperties[i] !== true ) { 8413 done = false; 8414 } 8415 } 8416 8417 if ( done ) { 8418 // Reset the overflow 8419 if ( options.overflow != null && !jQuery.support.shrinkWrapBlocks ) { 8420 8421 jQuery.each( [ "", "X", "Y" ], function (index, value) { 8422 elem.style[ "overflow" + value ] = options.overflow[index]; 8423 }); 8424 } 8425 8426 // Hide the element if the "hide" operation was done 8427 if ( options.hide ) { 8428 jQuery(elem).hide(); 8429 } 8430 8431 // Reset the properties, if the item has been hidden or shown 8432 if ( options.hide || options.show ) { 8433 for ( var p in options.animatedProperties ) { 8434 jQuery.style( elem, p, options.orig[p] ); 8435 } 8436 } 8437 8438 // Execute the complete function 8439 options.complete.call( elem ); 8440 } 8441 8442 return false; 8443 8444 } else { 8445 // classical easing cannot be used with an Infinity duration 8446 if ( options.duration == Infinity ) { 8447 this.now = t; 8448 } else { 8449 n = t - this.startTime; 8450 this.state = n / options.duration; 8451 8452 // Perform the easing function, defaults to swing 8453 this.pos = jQuery.easing[ options.animatedProperties[ this.prop ] ]( this.state, n, 0, 1, options.duration ); 8454 this.now = this.start + ((this.end - this.start) * this.pos); 8455 } 8456 // Perform the next step of the animation 8457 this.update(); 8458 } 8459 8460 return true; 8461 } 8462 }; 8463 8464 jQuery.extend( jQuery.fx, { 8465 tick: function() { 8466 for ( var timers = jQuery.timers, i = 0 ; i < timers.length ; ++i ) { 8467 if ( !timers[i]() ) { 8468 timers.splice(i--, 1); 8469 } 8470 } 8471 8472 if ( !timers.length ) { 8473 jQuery.fx.stop(); 8474 } 8475 }, 8476 8477 interval: 13, 8478 8479 stop: function() { 8480 clearInterval( timerId ); 8481 timerId = null; 8482 }, 8483 8484 speeds: { 8485 slow: 600, 8486 fast: 200, 8487 // Default speed 8488 _default: 400 8489 }, 8490 8491 step: { 8492 opacity: function( fx ) { 8493 jQuery.style( fx.elem, "opacity", fx.now ); 8494 }, 8495 8496 _default: function( fx ) { 8497 if ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) { 8498 fx.elem.style[ fx.prop ] = (fx.prop === "width" || fx.prop === "height" ? Math.max(0, fx.now) : fx.now) + fx.unit; 8499 } else { 8500 fx.elem[ fx.prop ] = fx.now; 8501 } 8502 } 8503 } 8504 }); 8505 8506 if ( jQuery.expr && jQuery.expr.filters ) { 8507 jQuery.expr.filters.animated = function( elem ) { 8508 return jQuery.grep(jQuery.timers, function( fn ) { 8509 return elem === fn.elem; 8510 }).length; 8511 }; 8512 } 8513 8514 // Try to restore the default display value of an element 8515 function defaultDisplay( nodeName ) { 8516 8517 if ( !elemdisplay[ nodeName ] ) { 8518 8519 var elem = jQuery( "<" + nodeName + ">" ).appendTo( "body" ), 8520 display = elem.css( "display" ); 8521 8522 elem.remove(); 8523 8524 // If the simple way fails, 8525 // get element's real default display by attaching it to a temp iframe 8526 if ( display === "none" || display === "" ) { 8527 // No iframe to use yet, so create it 8528 if ( !iframe ) { 8529 iframe = document.createElement( "iframe" ); 8530 iframe.frameBorder = iframe.width = iframe.height = 0; 8531 } 8532 8533 document.body.appendChild( iframe ); 8534 8535 // Create a cacheable copy of the iframe document on first call. 8536 // IE and Opera will allow us to reuse the iframeDoc without re-writing the fake html 8537 // document to it, Webkit & Firefox won't allow reusing the iframe document 8538 if ( !iframeDoc || !iframe.createElement ) { 8539 iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document; 8540 iframeDoc.write( "<!doctype><html><body></body></html>" ); 8541 } 8542 8543 elem = iframeDoc.createElement( nodeName ); 8544 8545 iframeDoc.body.appendChild( elem ); 8546 8547 display = jQuery.css( elem, "display" ); 8548 8549 document.body.removeChild( iframe ); 8550 } 8551 8552 // Store the correct default display 8553 elemdisplay[ nodeName ] = display; 8554 } 8555 8556 return elemdisplay[ nodeName ]; 8557 } 8558 8559 8560 8561 8562 var rtable = /^t(?:able|d|h)$/i, 8563 rroot = /^(?:body|html)$/i; 8564 8565 if ( "getBoundingClientRect" in document.documentElement ) { 8566 jQuery.fn.offset = function( options ) { 8567 var elem = this[0], box; 8568 8569 if ( options ) { 8570 return this.each(function( i ) { 8571 jQuery.offset.setOffset( this, options, i ); 8572 }); 8573 } 8574 8575 if ( !elem || !elem.ownerDocument ) { 8576 return null; 8577 } 8578 8579 if ( elem === elem.ownerDocument.body ) { 8580 return jQuery.offset.bodyOffset( elem ); 8581 } 8582 8583 try { 8584 box = elem.getBoundingClientRect(); 8585 } catch(e) {} 8586 8587 var doc = elem.ownerDocument, 8588 docElem = doc.documentElement; 8589 8590 // Make sure we're not dealing with a disconnected DOM node 8591 if ( !box || !jQuery.contains( docElem, elem ) ) { 8592 return box ? { top: box.top, left: box.left } : { top: 0, left: 0 }; 8593 } 8594 8595 var body = doc.body, 8596 win = getWindow(doc), 8597 clientTop = docElem.clientTop || body.clientTop || 0, 8598 clientLeft = docElem.clientLeft || body.clientLeft || 0, 8599 scrollTop = win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop || body.scrollTop, 8600 scrollLeft = win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft, 8601 top = box.top + scrollTop - clientTop, 8602 left = box.left + scrollLeft - clientLeft; 8603 8604 return { top: top, left: left }; 8605 }; 8606 8607 } else { 8608 jQuery.fn.offset = function( options ) { 8609 var elem = this[0]; 8610 8611 if ( options ) { 8612 return this.each(function( i ) { 8613 jQuery.offset.setOffset( this, options, i ); 8614 }); 8615 } 8616 8617 if ( !elem || !elem.ownerDocument ) { 8618 return null; 8619 } 8620 8621 if ( elem === elem.ownerDocument.body ) { 8622 return jQuery.offset.bodyOffset( elem ); 8623 } 8624 8625 jQuery.offset.initialize(); 8626 8627 var computedStyle, 8628 offsetParent = elem.offsetParent, 8629 prevOffsetParent = elem, 8630 doc = elem.ownerDocument, 8631 docElem = doc.documentElement, 8632 body = doc.body, 8633 defaultView = doc.defaultView, 8634 prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle, 8635 top = elem.offsetTop, 8636 left = elem.offsetLeft; 8637 8638 while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) { 8639 if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) { 8640 break; 8641 } 8642 8643 computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle; 8644 top -= elem.scrollTop; 8645 left -= elem.scrollLeft; 8646 8647 if ( elem === offsetParent ) { 8648 top += elem.offsetTop; 8649 left += elem.offsetLeft; 8650 8651 if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && rtable.test(elem.nodeName)) ) { 8652 top += parseFloat( computedStyle.borderTopWidth ) || 0; 8653 left += parseFloat( computedStyle.borderLeftWidth ) || 0; 8654 } 8655 8656 prevOffsetParent = offsetParent; 8657 offsetParent = elem.offsetParent; 8658 } 8659 8660 if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) { 8661 top += parseFloat( computedStyle.borderTopWidth ) || 0; 8662 left += parseFloat( computedStyle.borderLeftWidth ) || 0; 8663 } 8664 8665 prevComputedStyle = computedStyle; 8666 } 8667 8668 if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) { 8669 top += body.offsetTop; 8670 left += body.offsetLeft; 8671 } 8672 8673 if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) { 8674 top += Math.max( docElem.scrollTop, body.scrollTop ); 8675 left += Math.max( docElem.scrollLeft, body.scrollLeft ); 8676 } 8677 8678 return { top: top, left: left }; 8679 }; 8680 } 8681 8682 jQuery.offset = { 8683 initialize: function() { 8684 var body = document.body, container = document.createElement("div"), innerDiv, checkDiv, table, td, bodyMarginTop = parseFloat( jQuery.css(body, "marginTop") ) || 0, 8685 html = "<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>"; 8686 8687 jQuery.extend( container.style, { position: "absolute", top: 0, left: 0, margin: 0, border: 0, width: "1px", height: "1px", visibility: "hidden" } ); 8688 8689 container.innerHTML = html; 8690 body.insertBefore( container, body.firstChild ); 8691 innerDiv = container.firstChild; 8692 checkDiv = innerDiv.firstChild; 8693 td = innerDiv.nextSibling.firstChild.firstChild; 8694 8695 this.doesNotAddBorder = (checkDiv.offsetTop !== 5); 8696 this.doesAddBorderForTableAndCells = (td.offsetTop === 5); 8697 8698 checkDiv.style.position = "fixed"; 8699 checkDiv.style.top = "20px"; 8700 8701 // safari subtracts parent border width here which is 5px 8702 this.supportsFixedPosition = (checkDiv.offsetTop === 20 || checkDiv.offsetTop === 15); 8703 checkDiv.style.position = checkDiv.style.top = ""; 8704 8705 innerDiv.style.overflow = "hidden"; 8706 innerDiv.style.position = "relative"; 8707 8708 this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5); 8709 8710 this.doesNotIncludeMarginInBodyOffset = (body.offsetTop !== bodyMarginTop); 8711 8712 body.removeChild( container ); 8713 jQuery.offset.initialize = jQuery.noop; 8714 }, 8715 8716 bodyOffset: function( body ) { 8717 var top = body.offsetTop, 8718 left = body.offsetLeft; 8719 8720 jQuery.offset.initialize(); 8721 8722 if ( jQuery.offset.doesNotIncludeMarginInBodyOffset ) { 8723 top += parseFloat( jQuery.css(body, "marginTop") ) || 0; 8724 left += parseFloat( jQuery.css(body, "marginLeft") ) || 0; 8725 } 8726 8727 return { top: top, left: left }; 8728 }, 8729 8730 setOffset: function( elem, options, i ) { 8731 var position = jQuery.css( elem, "position" ); 8732 8733 // set position first, in-case top/left are set even on static elem 8734 if ( position === "static" ) { 8735 elem.style.position = "relative"; 8736 } 8737 8738 var curElem = jQuery( elem ), 8739 curOffset = curElem.offset(), 8740 curCSSTop = jQuery.css( elem, "top" ), 8741 curCSSLeft = jQuery.css( elem, "left" ), 8742 calculatePosition = (position === "absolute" || position === "fixed") && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1, 8743 props = {}, curPosition = {}, curTop, curLeft; 8744 8745 // need to be able to calculate position if either top or left is auto and position is either absolute or fixed 8746 if ( calculatePosition ) { 8747 curPosition = curElem.position(); 8748 curTop = curPosition.top; 8749 curLeft = curPosition.left; 8750 } else { 8751 curTop = parseFloat( curCSSTop ) || 0; 8752 curLeft = parseFloat( curCSSLeft ) || 0; 8753 } 8754 8755 if ( jQuery.isFunction( options ) ) { 8756 options = options.call( elem, i, curOffset ); 8757 } 8758 8759 if (options.top != null) { 8760 props.top = (options.top - curOffset.top) + curTop; 8761 } 8762 if (options.left != null) { 8763 props.left = (options.left - curOffset.left) + curLeft; 8764 } 8765 8766 if ( "using" in options ) { 8767 options.using.call( elem, props ); 8768 } else { 8769 curElem.css( props ); 8770 } 8771 } 8772 }; 8773 8774 8775 jQuery.fn.extend({ 8776 position: function() { 8777 if ( !this[0] ) { 8778 return null; 8779 } 8780 8781 var elem = this[0], 8782 8783 // Get *real* offsetParent 8784 offsetParent = this.offsetParent(), 8785 8786 // Get correct offsets 8787 offset = this.offset(), 8788 parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset(); 8789 8790 // Subtract element margins 8791 // note: when an element has margin: auto the offsetLeft and marginLeft 8792 // are the same in Safari causing offset.left to incorrectly be 0 8793 offset.top -= parseFloat( jQuery.css(elem, "marginTop") ) || 0; 8794 offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0; 8795 8796 // Add offsetParent borders 8797 parentOffset.top += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0; 8798 parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0; 8799 8800 // Subtract the two offsets 8801 return { 8802 top: offset.top - parentOffset.top, 8803 left: offset.left - parentOffset.left 8804 }; 8805 }, 8806 8807 offsetParent: function() { 8808 return this.map(function() { 8809 var offsetParent = this.offsetParent || document.body; 8810 while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) { 8811 offsetParent = offsetParent.offsetParent; 8812 } 8813 return offsetParent; 8814 }); 8815 } 8816 }); 8817 8818 8819 // Create scrollLeft and scrollTop methods 8820 jQuery.each( ["Left", "Top"], function( i, name ) { 8821 var method = "scroll" + name; 8822 8823 jQuery.fn[ method ] = function( val ) { 8824 var elem, win; 8825 8826 if ( val === undefined ) { 8827 elem = this[ 0 ]; 8828 8829 if ( !elem ) { 8830 return null; 8831 } 8832 8833 win = getWindow( elem ); 8834 8835 // Return the scroll offset 8836 return win ? ("pageXOffset" in win) ? win[ i ? "pageYOffset" : "pageXOffset" ] : 8837 jQuery.support.boxModel && win.document.documentElement[ method ] || 8838 win.document.body[ method ] : 8839 elem[ method ]; 8840 } 8841 8842 // Set the scroll offset 8843 return this.each(function() { 8844 win = getWindow( this ); 8845 8846 if ( win ) { 8847 win.scrollTo( 8848 !i ? val : jQuery( win ).scrollLeft(), 8849 i ? val : jQuery( win ).scrollTop() 8850 ); 8851 8852 } else { 8853 this[ method ] = val; 8854 } 8855 }); 8856 }; 8857 }); 8858 8859 function getWindow( elem ) { 8860 return jQuery.isWindow( elem ) ? 8861 elem : 8862 elem.nodeType === 9 ? 8863 elem.defaultView || elem.parentWindow : 8864 false; 8865 } 8866 8867 8868 8869 8870 // Create innerHeight, innerWidth, outerHeight and outerWidth methods 8871 jQuery.each([ "Height", "Width" ], function( i, name ) { 8872 8873 var type = name.toLowerCase(); 8874 8875 // innerHeight and innerWidth 8876 jQuery.fn["inner" + name] = function() { 8877 return this[0] ? 8878 parseFloat( jQuery.css( this[0], type, "padding" ) ) : 8879 null; 8880 }; 8881 8882 // outerHeight and outerWidth 8883 jQuery.fn["outer" + name] = function( margin ) { 8884 return this[0] ? 8885 parseFloat( jQuery.css( this[0], type, margin ? "margin" : "border" ) ) : 8886 null; 8887 }; 8888 8889 jQuery.fn[ type ] = function( size ) { 8890 // Get window width or height 8891 var elem = this[0]; 8892 if ( !elem ) { 8893 return size == null ? null : this; 8894 } 8895 8896 if ( jQuery.isFunction( size ) ) { 8897 return this.each(function( i ) { 8898 var self = jQuery( this ); 8899 self[ type ]( size.call( this, i, self[ type ]() ) ); 8900 }); 8901 } 8902 8903 if ( jQuery.isWindow( elem ) ) { 8904 // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode 8905 // 3rd condition allows Nokia support, as it supports the docElem prop but not CSS1Compat 8906 var docElemProp = elem.document.documentElement[ "client" + name ]; 8907 return elem.document.compatMode === "CSS1Compat" && docElemProp || 8908 elem.document.body[ "client" + name ] || docElemProp; 8909 8910 // Get document width or height 8911 } else if ( elem.nodeType === 9 ) { 8912 // Either scroll[Width/Height] or offset[Width/Height], whichever is greater 8913 return Math.max( 8914 elem.documentElement["client" + name], 8915 elem.body["scroll" + name], elem.documentElement["scroll" + name], 8916 elem.body["offset" + name], elem.documentElement["offset" + name] 8917 ); 8918 8919 // Get or set width or height on the element 8920 } else if ( size === undefined ) { 8921 var orig = jQuery.css( elem, type ), 8922 ret = parseFloat( orig ); 8923 8924 return jQuery.isNaN( ret ) ? orig : ret; 8925 8926 // Set the width or height on the element (default to pixels if value is unitless) 8927 } else { 8928 return this.css( type, typeof size === "string" ? size : size + "px" ); 8929 } 8930 }; 8931 8932 }); 8933 8934 8935 window.jQuery = window.$ = jQuery; 8936 })(window);

Contact Us
Can't read the article? Contact us for free answers! Free help for personal, small business sites!
Tel: 020-2206-9892
QQ咨询:1025174874
(iii) E-mail: info@361sale.com
Working hours: Monday to Friday, 9:30-18:30, holidays off
© Reprint statement
This article was written by Harry
THE END
If you like it, support it.
kudos0 share (joys, benefits, privileges etc) with others
commentaries sofa-buying

Please log in to post a comment

    No comments