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