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