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