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