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