PageRenderTime 317ms CodeModel.GetById 28ms app.highlight 244ms RepoModel.GetById 2ms app.codeStats 1ms

/src/MM.Web/Scripts/jquery-1.4.1.js

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