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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.20