PageRenderTime 24ms CodeModel.GetById 68ms app.highlight 307ms RepoModel.GetById 1ms app.codeStats 2ms

/js/lib/jquery-1.5.1.js

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