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