/[projects]/misc/horsensspejder-web/jquery/jquery-ui-1.10.3/tests/jquery-1.6.3.js
ViewVC logotype

Annotation of /misc/horsensspejder-web/jquery/jquery-ui-1.10.3/tests/jquery-1.6.3.js

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.20