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