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