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