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