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