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