www

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

jquery-1.4.2.js (163855B)


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