dom/tests/mochitest/ajax/jquery/dist/jquery.js

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     1 (function(){
     2 /*
     3  * jQuery 1.2.6 - New Wave Javascript
     4  *
     5  * Copyright (c) 2008 John Resig (jquery.com)
     6  * Dual licensed under the MIT (MIT-LICENSE.txt)
     7  * and GPL (GPL-LICENSE.txt) licenses.
     8  *
     9  * $Date: 2008-05-24 11:09:21 -0700 (Sat, 24 May 2008) $
    10  * $Rev: 5683 $
    11  */
    13 // Map over jQuery in case of overwrite
    14 var _jQuery = window.jQuery,
    15 // Map over the $ in case of overwrite
    16 	_$ = window.$;
    18 var jQuery = window.jQuery = window.$ = function( selector, context ) {
    19 	// The jQuery object is actually just the init constructor 'enhanced'
    20 	return new jQuery.fn.init( selector, context );
    21 };
    23 // A simple way to check for HTML strings or ID strings
    24 // (both of which we optimize for)
    25 var quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/,
    27 // Is it a simple selector
    28 	isSimple = /^.[^:#\[\.]*$/,
    30 // Will speed up references to undefined, and allows munging its name.
    31 	undefined;
    33 jQuery.fn = jQuery.prototype = {
    34 	init: function( selector, context ) {
    35 		// Make sure that a selection was provided
    36 		selector = selector || document;
    38 		// Handle $(DOMElement)
    39 		if ( selector.nodeType ) {
    40 			this[0] = selector;
    41 			this.length = 1;
    42 			return this;
    43 		}
    44 		// Handle HTML strings
    45 		if ( typeof selector == "string" ) {
    46 			// Are we dealing with HTML string or an ID?
    47 			var match = quickExpr.exec( selector );
    49 			// Verify a match, and that no context was specified for #id
    50 			if ( match && (match[1] || !context) ) {
    52 				// HANDLE: $(html) -> $(array)
    53 				if ( match[1] )
    54 					selector = jQuery.clean( [ match[1] ], context );
    56 				// HANDLE: $("#id")
    57 				else {
    58 					var elem = document.getElementById( match[3] );
    60 					// Make sure an element was located
    61 					if ( elem ){
    62 						// Handle the case where IE and Opera return items
    63 						// by name instead of ID
    64 						if ( elem.id != match[3] )
    65 							return jQuery().find( selector );
    67 						// Otherwise, we inject the element directly into the jQuery object
    68 						return jQuery( elem );
    69 					}
    70 					selector = [];
    71 				}
    73 			// HANDLE: $(expr, [context])
    74 			// (which is just equivalent to: $(content).find(expr)
    75 			} else
    76 				return jQuery( context ).find( selector );
    78 		// HANDLE: $(function)
    79 		// Shortcut for document ready
    80 		} else if ( jQuery.isFunction( selector ) )
    81 			return jQuery( document )[ jQuery.fn.ready ? "ready" : "load" ]( selector );
    83 		return this.setArray(jQuery.makeArray(selector));
    84 	},
    86 	// The current version of jQuery being used
    87 	jquery: "1.2.6",
    89 	// The number of elements contained in the matched element set
    90 	size: function() {
    91 		return this.length;
    92 	},
    94 	// The number of elements contained in the matched element set
    95 	length: 0,
    97 	// Get the Nth element in the matched element set OR
    98 	// Get the whole matched element set as a clean array
    99 	get: function( num ) {
   100 		return num == undefined ?
   102 			// Return a 'clean' array
   103 			jQuery.makeArray( this ) :
   105 			// Return just the object
   106 			this[ num ];
   107 	},
   109 	// Take an array of elements and push it onto the stack
   110 	// (returning the new matched element set)
   111 	pushStack: function( elems ) {
   112 		// Build a new jQuery matched element set
   113 		var ret = jQuery( elems );
   115 		// Add the old object onto the stack (as a reference)
   116 		ret.prevObject = this;
   118 		// Return the newly-formed element set
   119 		return ret;
   120 	},
   122 	// Force the current matched set of elements to become
   123 	// the specified array of elements (destroying the stack in the process)
   124 	// You should use pushStack() in order to do this, but maintain the stack
   125 	setArray: function( elems ) {
   126 		// Resetting the length to 0, then using the native Array push
   127 		// is a super-fast way to populate an object with array-like properties
   128 		this.length = 0;
   129 		Array.prototype.push.apply( this, elems );
   131 		return this;
   132 	},
   134 	// Execute a callback for every element in the matched set.
   135 	// (You can seed the arguments with an array of args, but this is
   136 	// only used internally.)
   137 	each: function( callback, args ) {
   138 		return jQuery.each( this, callback, args );
   139 	},
   141 	// Determine the position of an element within
   142 	// the matched set of elements
   143 	index: function( elem ) {
   144 		var ret = -1;
   146 		// Locate the position of the desired element
   147 		return jQuery.inArray(
   148 			// If it receives a jQuery object, the first element is used
   149 			elem && elem.jquery ? elem[0] : elem
   150 		, this );
   151 	},
   153 	attr: function( name, value, type ) {
   154 		var options = name;
   156 		// Look for the case where we're accessing a style value
   157 		if ( name.constructor == String )
   158 			if ( value === undefined )
   159 				return this[0] && jQuery[ type || "attr" ]( this[0], name );
   161 			else {
   162 				options = {};
   163 				options[ name ] = value;
   164 			}
   166 		// Check to see if we're setting style values
   167 		return this.each(function(i){
   168 			// Set all the styles
   169 			for ( name in options )
   170 				jQuery.attr(
   171 					type ?
   172 						this.style :
   173 						this,
   174 					name, jQuery.prop( this, options[ name ], type, i, name )
   175 				);
   176 		});
   177 	},
   179 	css: function( key, value ) {
   180 		// ignore negative width and height values
   181 		if ( (key == 'width' || key == 'height') && parseFloat(value) < 0 )
   182 			value = undefined;
   183 		return this.attr( key, value, "curCSS" );
   184 	},
   186 	text: function( text ) {
   187 		if ( typeof text != "object" && text != null )
   188 			return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
   190 		var ret = "";
   192 		jQuery.each( text || this, function(){
   193 			jQuery.each( this.childNodes, function(){
   194 				if ( this.nodeType != 8 )
   195 					ret += this.nodeType != 1 ?
   196 						this.nodeValue :
   197 						jQuery.fn.text( [ this ] );
   198 			});
   199 		});
   201 		return ret;
   202 	},
   204 	wrapAll: function( html ) {
   205 		if ( this[0] )
   206 			// The elements to wrap the target around
   207 			jQuery( html, this[0].ownerDocument )
   208 				.clone()
   209 				.insertBefore( this[0] )
   210 				.map(function(){
   211 					var elem = this;
   213 					while ( elem.firstChild )
   214 						elem = elem.firstChild;
   216 					return elem;
   217 				})
   218 				.append(this);
   220 		return this;
   221 	},
   223 	wrapInner: function( html ) {
   224 		return this.each(function(){
   225 			jQuery( this ).contents().wrapAll( html );
   226 		});
   227 	},
   229 	wrap: function( html ) {
   230 		return this.each(function(){
   231 			jQuery( this ).wrapAll( html );
   232 		});
   233 	},
   235 	append: function() {
   236 		return this.domManip(arguments, true, false, function(elem){
   237 			if (this.nodeType == 1)
   238 				this.appendChild( elem );
   239 		});
   240 	},
   242 	prepend: function() {
   243 		return this.domManip(arguments, true, true, function(elem){
   244 			if (this.nodeType == 1)
   245 				this.insertBefore( elem, this.firstChild );
   246 		});
   247 	},
   249 	before: function() {
   250 		return this.domManip(arguments, false, false, function(elem){
   251 			this.parentNode.insertBefore( elem, this );
   252 		});
   253 	},
   255 	after: function() {
   256 		return this.domManip(arguments, false, true, function(elem){
   257 			this.parentNode.insertBefore( elem, this.nextSibling );
   258 		});
   259 	},
   261 	end: function() {
   262 		return this.prevObject || jQuery( [] );
   263 	},
   265 	find: function( selector ) {
   266 		var elems = jQuery.map(this, function(elem){
   267 			return jQuery.find( selector, elem );
   268 		});
   270 		return this.pushStack( /[^+>] [^+>]/.test( selector ) || selector.indexOf("..") > -1 ?
   271 			jQuery.unique( elems ) :
   272 			elems );
   273 	},
   275 	clone: function( events ) {
   276 		// Do the clone
   277 		var ret = this.map(function(){
   278 			if ( jQuery.browser.msie && !jQuery.isXMLDoc(this) ) {
   279 				// IE copies events bound via attachEvent when
   280 				// using cloneNode. Calling detachEvent on the
   281 				// clone will also remove the events from the orignal
   282 				// In order to get around this, we use innerHTML.
   283 				// Unfortunately, this means some modifications to
   284 				// attributes in IE that are actually only stored
   285 				// as properties will not be copied (such as the
   286 				// the name attribute on an input).
   287 				var clone = this.cloneNode(true),
   288 					container = document.createElement("div");
   289 				container.appendChild(clone);
   290 				return jQuery.clean([container.innerHTML])[0];
   291 			} else
   292 				return this.cloneNode(true);
   293 		});
   295 		// Need to set the expando to null on the cloned set if it exists
   296 		// removeData doesn't work here, IE removes it from the original as well
   297 		// this is primarily for IE but the data expando shouldn't be copied over in any browser
   298 		var clone = ret.find("*").andSelf().each(function(){
   299 			if ( this[ expando ] != undefined )
   300 				this[ expando ] = null;
   301 		});
   303 		// Copy the events from the original to the clone
   304 		if ( events === true )
   305 			this.find("*").andSelf().each(function(i){
   306 				if (this.nodeType == 3)
   307 					return;
   308 				var events = jQuery.data( this, "events" );
   310 				for ( var type in events )
   311 					for ( var handler in events[ type ] )
   312 						jQuery.event.add( clone[ i ], type, events[ type ][ handler ], events[ type ][ handler ].data );
   313 			});
   315 		// Return the cloned set
   316 		return ret;
   317 	},
   319 	filter: function( selector ) {
   320 		return this.pushStack(
   321 			jQuery.isFunction( selector ) &&
   322 			jQuery.grep(this, function(elem, i){
   323 				return selector.call( elem, i );
   324 			}) ||
   326 			jQuery.multiFilter( selector, this ) );
   327 	},
   329 	not: function( selector ) {
   330 		if ( selector.constructor == String )
   331 			// test special case where just one selector is passed in
   332 			if ( isSimple.test( selector ) )
   333 				return this.pushStack( jQuery.multiFilter( selector, this, true ) );
   334 			else
   335 				selector = jQuery.multiFilter( selector, this );
   337 		var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType;
   338 		return this.filter(function() {
   339 			return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector;
   340 		});
   341 	},
   343 	add: function( selector ) {
   344 		return this.pushStack( jQuery.unique( jQuery.merge(
   345 			this.get(),
   346 			typeof selector == 'string' ?
   347 				jQuery( selector ) :
   348 				jQuery.makeArray( selector )
   349 		)));
   350 	},
   352 	is: function( selector ) {
   353 		return !!selector && jQuery.multiFilter( selector, this ).length > 0;
   354 	},
   356 	hasClass: function( selector ) {
   357 		return this.is( "." + selector );
   358 	},
   360 	val: function( value ) {
   361 		if ( value == undefined ) {
   363 			if ( this.length ) {
   364 				var elem = this[0];
   366 				// We need to handle select boxes special
   367 				if ( jQuery.nodeName( elem, "select" ) ) {
   368 					var index = elem.selectedIndex,
   369 						values = [],
   370 						options = elem.options,
   371 						one = elem.type == "select-one";
   373 					// Nothing was selected
   374 					if ( index < 0 )
   375 						return null;
   377 					// Loop through all the selected options
   378 					for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
   379 						var option = options[ i ];
   381 						if ( option.selected ) {
   382 							// Get the specifc value for the option
   383 							value = jQuery.browser.msie && !option.attributes.value.specified ? option.text : option.value;
   385 							// We don't need an array for one selects
   386 							if ( one )
   387 								return value;
   389 							// Multi-Selects return an array
   390 							values.push( value );
   391 						}
   392 					}
   394 					return values;
   396 				// Everything else, we just grab the value
   397 				} else
   398 					return (this[0].value || "").replace(/\r/g, "");
   400 			}
   402 			return undefined;
   403 		}
   405 		if( value.constructor == Number )
   406 			value += '';
   408 		return this.each(function(){
   409 			if ( this.nodeType != 1 )
   410 				return;
   412 			if ( value.constructor == Array && /radio|checkbox/.test( this.type ) )
   413 				this.checked = (jQuery.inArray(this.value, value) >= 0 ||
   414 					jQuery.inArray(this.name, value) >= 0);
   416 			else if ( jQuery.nodeName( this, "select" ) ) {
   417 				var values = jQuery.makeArray(value);
   419 				jQuery( "option", this ).each(function(){
   420 					this.selected = (jQuery.inArray( this.value, values ) >= 0 ||
   421 						jQuery.inArray( this.text, values ) >= 0);
   422 				});
   424 				if ( !values.length )
   425 					this.selectedIndex = -1;
   427 			} else
   428 				this.value = value;
   429 		});
   430 	},
   432 	html: function( value ) {
   433 		return value == undefined ?
   434 			(this[0] ?
   435 				this[0].innerHTML :
   436 				null) :
   437 			this.empty().append( value );
   438 	},
   440 	replaceWith: function( value ) {
   441 		return this.after( value ).remove();
   442 	},
   444 	eq: function( i ) {
   445 		return this.slice( i, i + 1 );
   446 	},
   448 	slice: function() {
   449 		return this.pushStack( Array.prototype.slice.apply( this, arguments ) );
   450 	},
   452 	map: function( callback ) {
   453 		return this.pushStack( jQuery.map(this, function(elem, i){
   454 			return callback.call( elem, i, elem );
   455 		}));
   456 	},
   458 	andSelf: function() {
   459 		return this.add( this.prevObject );
   460 	},
   462 	data: function( key, value ){
   463 		var parts = key.split(".");
   464 		parts[1] = parts[1] ? "." + parts[1] : "";
   466 		if ( value === undefined ) {
   467 			var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
   469 			if ( data === undefined && this.length )
   470 				data = jQuery.data( this[0], key );
   472 			return data === undefined && parts[1] ?
   473 				this.data( parts[0] ) :
   474 				data;
   475 		} else
   476 			return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function(){
   477 				jQuery.data( this, key, value );
   478 			});
   479 	},
   481 	removeData: function( key ){
   482 		return this.each(function(){
   483 			jQuery.removeData( this, key );
   484 		});
   485 	},
   487 	domManip: function( args, table, reverse, callback ) {
   488 		var clone = this.length > 1, elems;
   490 		return this.each(function(){
   491 			if ( !elems ) {
   492 				elems = jQuery.clean( args, this.ownerDocument );
   494 				if ( reverse )
   495 					elems.reverse();
   496 			}
   498 			var obj = this;
   500 			if ( table && jQuery.nodeName( this, "table" ) && jQuery.nodeName( elems[0], "tr" ) )
   501 				obj = this.getElementsByTagName("tbody")[0] || this.appendChild( this.ownerDocument.createElement("tbody") );
   503 			var scripts = jQuery( [] );
   505 			jQuery.each(elems, function(){
   506 				var elem = clone ?
   507 					jQuery( this ).clone( true )[0] :
   508 					this;
   510 				// execute all scripts after the elements have been injected
   511 				if ( jQuery.nodeName( elem, "script" ) )
   512 					scripts = scripts.add( elem );
   513 				else {
   514 					// Remove any inner scripts for later evaluation
   515 					if ( elem.nodeType == 1 )
   516 						scripts = scripts.add( jQuery( "script", elem ).remove() );
   518 					// Inject the elements into the document
   519 					callback.call( obj, elem );
   520 				}
   521 			});
   523 			scripts.each( evalScript );
   524 		});
   525 	}
   526 };
   528 // Give the init function the jQuery prototype for later instantiation
   529 jQuery.fn.init.prototype = jQuery.fn;
   531 function evalScript( i, elem ) {
   532 	if ( elem.src )
   533 		jQuery.ajax({
   534 			url: elem.src,
   535 			async: false,
   536 			dataType: "script"
   537 		});
   539 	else
   540 		jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
   542 	if ( elem.parentNode )
   543 		elem.parentNode.removeChild( elem );
   544 }
   546 function now(){
   547 	return +new Date;
   548 }
   550 jQuery.extend = jQuery.fn.extend = function() {
   551 	// copy reference to target object
   552 	var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options;
   554 	// Handle a deep copy situation
   555 	if ( target.constructor == Boolean ) {
   556 		deep = target;
   557 		target = arguments[1] || {};
   558 		// skip the boolean and the target
   559 		i = 2;
   560 	}
   562 	// Handle case when target is a string or something (possible in deep copy)
   563 	if ( typeof target != "object" && typeof target != "function" )
   564 		target = {};
   566 	// extend jQuery itself if only one argument is passed
   567 	if ( length == i ) {
   568 		target = this;
   569 		--i;
   570 	}
   572 	for ( ; i < length; i++ )
   573 		// Only deal with non-null/undefined values
   574 		if ( (options = arguments[ i ]) != null )
   575 			// Extend the base object
   576 			for ( var name in options ) {
   577 				var src = target[ name ], copy = options[ name ];
   579 				// Prevent never-ending loop
   580 				if ( target === copy )
   581 					continue;
   583 				// Recurse if we're merging object values
   584 				if ( deep && copy && typeof copy == "object" && !copy.nodeType )
   585 					target[ name ] = jQuery.extend( deep, 
   586 						// Never move original objects, clone them
   587 						src || ( copy.length != null ? [ ] : { } )
   588 					, copy );
   590 				// Don't bring in undefined values
   591 				else if ( copy !== undefined )
   592 					target[ name ] = copy;
   594 			}
   596 	// Return the modified object
   597 	return target;
   598 };
   600 var expando = "jQuery" + now(), uuid = 0, windowData = {},
   601 	// exclude the following css properties to add px
   602 	exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i,
   603 	// cache defaultView
   604 	defaultView = document.defaultView || {};
   606 jQuery.extend({
   607 	noConflict: function( deep ) {
   608 		window.$ = _$;
   610 		if ( deep )
   611 			window.jQuery = _jQuery;
   613 		return jQuery;
   614 	},
   616 	// See test/unit/core.js for details concerning this function.
   617 	isFunction: function( fn ) {
   618 		return !!fn && typeof fn != "string" && !fn.nodeName &&
   619 			fn.constructor != Array && /^[\s[]?function/.test( fn + "" );
   620 	},
   622 	// check if an element is in a (or is an) XML document
   623 	isXMLDoc: function( elem ) {
   624 		return elem.documentElement && !elem.body ||
   625 			elem.tagName && elem.ownerDocument && !elem.ownerDocument.body;
   626 	},
   628 	// Evalulates a script in a global context
   629 	globalEval: function( data ) {
   630 		data = jQuery.trim( data );
   632 		if ( data ) {
   633 			// Inspired by code by Andrea Giammarchi
   634 			// http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
   635 			var head = document.getElementsByTagName("head")[0] || document.documentElement,
   636 				script = document.createElement("script");
   638 			script.type = "text/javascript";
   639 			if ( jQuery.browser.msie )
   640 				script.text = data;
   641 			else
   642 				script.appendChild( document.createTextNode( data ) );
   644 			// Use insertBefore instead of appendChild  to circumvent an IE6 bug.
   645 			// This arises when a base node is used (#2709).
   646 			head.insertBefore( script, head.firstChild );
   647 			head.removeChild( script );
   648 		}
   649 	},
   651 	nodeName: function( elem, name ) {
   652 		return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase();
   653 	},
   655 	cache: {},
   657 	data: function( elem, name, data ) {
   658 		elem = elem == window ?
   659 			windowData :
   660 			elem;
   662 		var id = elem[ expando ];
   664 		// Compute a unique ID for the element
   665 		if ( !id )
   666 			id = elem[ expando ] = ++uuid;
   668 		// Only generate the data cache if we're
   669 		// trying to access or manipulate it
   670 		if ( name && !jQuery.cache[ id ] )
   671 			jQuery.cache[ id ] = {};
   673 		// Prevent overriding the named cache with undefined values
   674 		if ( data !== undefined )
   675 			jQuery.cache[ id ][ name ] = data;
   677 		// Return the named cache data, or the ID for the element
   678 		return name ?
   679 			jQuery.cache[ id ][ name ] :
   680 			id;
   681 	},
   683 	removeData: function( elem, name ) {
   684 		elem = elem == window ?
   685 			windowData :
   686 			elem;
   688 		var id = elem[ expando ];
   690 		// If we want to remove a specific section of the element's data
   691 		if ( name ) {
   692 			if ( jQuery.cache[ id ] ) {
   693 				// Remove the section of cache data
   694 				delete jQuery.cache[ id ][ name ];
   696 				// If we've removed all the data, remove the element's cache
   697 				name = "";
   699 				for ( name in jQuery.cache[ id ] )
   700 					break;
   702 				if ( !name )
   703 					jQuery.removeData( elem );
   704 			}
   706 		// Otherwise, we want to remove all of the element's data
   707 		} else {
   708 			// Clean up the element expando
   709 			try {
   710 				delete elem[ expando ];
   711 			} catch(e){
   712 				// IE has trouble directly removing the expando
   713 				// but it's ok with using removeAttribute
   714 				if ( elem.removeAttribute )
   715 					elem.removeAttribute( expando );
   716 			}
   718 			// Completely remove the data cache
   719 			delete jQuery.cache[ id ];
   720 		}
   721 	},
   723 	// args is for internal usage only
   724 	each: function( object, callback, args ) {
   725 		var name, i = 0, length = object.length;
   727 		if ( args ) {
   728 			if ( length == undefined ) {
   729 				for ( name in object )
   730 					if ( callback.apply( object[ name ], args ) === false )
   731 						break;
   732 			} else
   733 				for ( ; i < length; )
   734 					if ( callback.apply( object[ i++ ], args ) === false )
   735 						break;
   737 		// A special, fast, case for the most common use of each
   738 		} else {
   739 			if ( length == undefined ) {
   740 				for ( name in object )
   741 					if ( callback.call( object[ name ], name, object[ name ] ) === false )
   742 						break;
   743 			} else
   744 				for ( var value = object[0];
   745 					i < length && callback.call( value, i, value ) !== false; value = object[++i] ){}
   746 		}
   748 		return object;
   749 	},
   751 	prop: function( elem, value, type, i, name ) {
   752 		// Handle executable functions
   753 		if ( jQuery.isFunction( value ) )
   754 			value = value.call( elem, i );
   756 		// Handle passing in a number to a CSS property
   757 		return value && value.constructor == Number && type == "curCSS" && !exclude.test( name ) ?
   758 			value + "px" :
   759 			value;
   760 	},
   762 	className: {
   763 		// internal only, use addClass("class")
   764 		add: function( elem, classNames ) {
   765 			jQuery.each((classNames || "").split(/\s+/), function(i, className){
   766 				if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) )
   767 					elem.className += (elem.className ? " " : "") + className;
   768 			});
   769 		},
   771 		// internal only, use removeClass("class")
   772 		remove: function( elem, classNames ) {
   773 			if (elem.nodeType == 1)
   774 				elem.className = classNames != undefined ?
   775 					jQuery.grep(elem.className.split(/\s+/), function(className){
   776 						return !jQuery.className.has( classNames, className );
   777 					}).join(" ") :
   778 					"";
   779 		},
   781 		// internal only, use hasClass("class")
   782 		has: function( elem, className ) {
   783 			return jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1;
   784 		}
   785 	},
   787 	// A method for quickly swapping in/out CSS properties to get correct calculations
   788 	swap: function( elem, options, callback ) {
   789 		var old = {};
   790 		// Remember the old values, and insert the new ones
   791 		for ( var name in options ) {
   792 			old[ name ] = elem.style[ name ];
   793 			elem.style[ name ] = options[ name ];
   794 		}
   796 		callback.call( elem );
   798 		// Revert the old values
   799 		for ( var name in options )
   800 			elem.style[ name ] = old[ name ];
   801 	},
   803 	css: function( elem, name, force ) {
   804 		if ( name == "width" || name == "height" ) {
   805 			var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ];
   807 			function getWH() {
   808 				val = name == "width" ? elem.offsetWidth : elem.offsetHeight;
   809 				var padding = 0, border = 0;
   810 				jQuery.each( which, function() {
   811 					padding += parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0;
   812 					border += parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0;
   813 				});
   814 				val -= Math.round(padding + border);
   815 			}
   817 			if ( jQuery(elem).is(":visible") )
   818 				getWH();
   819 			else
   820 				jQuery.swap( elem, props, getWH );
   822 			return Math.max(0, val);
   823 		}
   825 		return jQuery.curCSS( elem, name, force );
   826 	},
   828 	curCSS: function( elem, name, force ) {
   829 		var ret, style = elem.style;
   831 		// A helper method for determining if an element's values are broken
   832 		function color( elem ) {
   833 			if ( !jQuery.browser.safari )
   834 				return false;
   836 			// defaultView is cached
   837 			var ret = defaultView.getComputedStyle( elem, null );
   838 			return !ret || ret.getPropertyValue("color") == "";
   839 		}
   841 		// We need to handle opacity special in IE
   842 		if ( name == "opacity" && jQuery.browser.msie ) {
   843 			ret = jQuery.attr( style, "opacity" );
   845 			return ret == "" ?
   846 				"1" :
   847 				ret;
   848 		}
   849 		// Opera sometimes will give the wrong display answer, this fixes it, see #2037
   850 		if ( jQuery.browser.opera && name == "display" ) {
   851 			var save = style.outline;
   852 			style.outline = "0 solid black";
   853 			style.outline = save;
   854 		}
   856 		// Make sure we're using the right name for getting the float value
   857 		if ( name.match( /float/i ) )
   858 			name = styleFloat;
   860 		if ( !force && style && style[ name ] )
   861 			ret = style[ name ];
   863 		else if ( defaultView.getComputedStyle ) {
   865 			// Only "float" is needed here
   866 			if ( name.match( /float/i ) )
   867 				name = "float";
   869 			name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase();
   871 			var computedStyle = defaultView.getComputedStyle( elem, null );
   873 			if ( computedStyle && !color( elem ) )
   874 				ret = computedStyle.getPropertyValue( name );
   876 			// If the element isn't reporting its values properly in Safari
   877 			// then some display: none elements are involved
   878 			else {
   879 				var swap = [], stack = [], a = elem, i = 0;
   881 				// Locate all of the parent display: none elements
   882 				for ( ; a && color(a); a = a.parentNode )
   883 					stack.unshift(a);
   885 				// Go through and make them visible, but in reverse
   886 				// (It would be better if we knew the exact display type that they had)
   887 				for ( ; i < stack.length; i++ )
   888 					if ( color( stack[ i ] ) ) {
   889 						swap[ i ] = stack[ i ].style.display;
   890 						stack[ i ].style.display = "block";
   891 					}
   893 				// Since we flip the display style, we have to handle that
   894 				// one special, otherwise get the value
   895 				ret = name == "display" && swap[ stack.length - 1 ] != null ?
   896 					"none" :
   897 					( computedStyle && computedStyle.getPropertyValue( name ) ) || "";
   899 				// Finally, revert the display styles back
   900 				for ( i = 0; i < swap.length; i++ )
   901 					if ( swap[ i ] != null )
   902 						stack[ i ].style.display = swap[ i ];
   903 			}
   905 			// We should always get a number back from opacity
   906 			if ( name == "opacity" && ret == "" )
   907 				ret = "1";
   909 		} else if ( elem.currentStyle ) {
   910 			var camelCase = name.replace(/\-(\w)/g, function(all, letter){
   911 				return letter.toUpperCase();
   912 			});
   914 			ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ];
   916 			// From the awesome hack by Dean Edwards
   917 			// http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
   919 			// If we're not dealing with a regular pixel number
   920 			// but a number that has a weird ending, we need to convert it to pixels
   921 			if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) {
   922 				// Remember the original values
   923 				var left = style.left, rsLeft = elem.runtimeStyle.left;
   925 				// Put in the new values to get a computed value out
   926 				elem.runtimeStyle.left = elem.currentStyle.left;
   927 				style.left = ret || 0;
   928 				ret = style.pixelLeft + "px";
   930 				// Revert the changed values
   931 				style.left = left;
   932 				elem.runtimeStyle.left = rsLeft;
   933 			}
   934 		}
   936 		return ret;
   937 	},
   939 	clean: function( elems, context ) {
   940 		var ret = [];
   941 		context = context || document;
   942 		// !context.createElement fails in IE with an error but returns typeof 'object'
   943 		if (typeof context.createElement == 'undefined')
   944 			context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
   946 		jQuery.each(elems, function(i, elem){
   947 			if ( !elem )
   948 				return;
   950 			if ( elem.constructor == Number )
   951 				elem += '';
   953 			// Convert html string into DOM nodes
   954 			if ( typeof elem == "string" ) {
   955 				// Fix "XHTML"-style tags in all browsers
   956 				elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){
   957 					return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ?
   958 						all :
   959 						front + "></" + tag + ">";
   960 				});
   962 				// Trim whitespace, otherwise indexOf won't work as expected
   963 				var tags = jQuery.trim( elem ).toLowerCase(), div = context.createElement("div");
   965 				var wrap =
   966 					// option or optgroup
   967 					!tags.indexOf("<opt") &&
   968 					[ 1, "<select multiple='multiple'>", "</select>" ] ||
   970 					!tags.indexOf("<leg") &&
   971 					[ 1, "<fieldset>", "</fieldset>" ] ||
   973 					tags.match(/^<(thead|tbody|tfoot|colg|cap)/) &&
   974 					[ 1, "<table>", "</table>" ] ||
   976 					!tags.indexOf("<tr") &&
   977 					[ 2, "<table><tbody>", "</tbody></table>" ] ||
   979 				 	// <thead> matched above
   980 					(!tags.indexOf("<td") || !tags.indexOf("<th")) &&
   981 					[ 3, "<table><tbody><tr>", "</tr></tbody></table>" ] ||
   983 					!tags.indexOf("<col") &&
   984 					[ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ] ||
   986 					// IE can't serialize <link> and <script> tags normally
   987 					jQuery.browser.msie &&
   988 					[ 1, "div<div>", "</div>" ] ||
   990 					[ 0, "", "" ];
   992 				// Go to html and back, then peel off extra wrappers
   993 				div.innerHTML = wrap[1] + elem + wrap[2];
   995 				// Move to the right depth
   996 				while ( wrap[0]-- )
   997 					div = div.lastChild;
   999 				// Remove IE's autoinserted <tbody> from table fragments
  1000 				if ( jQuery.browser.msie ) {
  1002 					// String was a <table>, *may* have spurious <tbody>
  1003 					var tbody = !tags.indexOf("<table") && tags.indexOf("<tbody") < 0 ?
  1004 						div.firstChild && div.firstChild.childNodes :
  1006 						// String was a bare <thead> or <tfoot>
  1007 						wrap[1] == "<table>" && tags.indexOf("<tbody") < 0 ?
  1008 							div.childNodes :
  1009 							[];
  1011 					for ( var j = tbody.length - 1; j >= 0 ; --j )
  1012 						if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length )
  1013 							tbody[ j ].parentNode.removeChild( tbody[ j ] );
  1015 					// IE completely kills leading whitespace when innerHTML is used
  1016 					if ( /^\s/.test( elem ) )
  1017 						div.insertBefore( context.createTextNode( elem.match(/^\s*/)[0] ), div.firstChild );
  1021 				elem = jQuery.makeArray( div.childNodes );
  1024 			if ( elem.length === 0 && (!jQuery.nodeName( elem, "form" ) && !jQuery.nodeName( elem, "select" )) )
  1025 				return;
  1027 			if ( elem[0] == undefined || jQuery.nodeName( elem, "form" ) || elem.options )
  1028 				ret.push( elem );
  1030 			else
  1031 				ret = jQuery.merge( ret, elem );
  1033 		});
  1035 		return ret;
  1036 	},
  1038 	attr: function( elem, name, value ) {
  1039 		// don't set attributes on text and comment nodes
  1040 		if (!elem || elem.nodeType == 3 || elem.nodeType == 8)
  1041 			return undefined;
  1043 		var notxml = !jQuery.isXMLDoc( elem ),
  1044 			// Whether we are setting (or getting)
  1045 			set = value !== undefined,
  1046 			msie = jQuery.browser.msie;
  1048 		// Try to normalize/fix the name
  1049 		name = notxml && jQuery.props[ name ] || name;
  1051 		// Only do all the following if this is a node (faster for style)
  1052 		// IE elem.getAttribute passes even for style
  1053 		if ( elem.tagName ) {
  1055 			// These attributes require special treatment
  1056 			var special = /href|src|style/.test( name );
  1058 			// Safari mis-reports the default selected property of a hidden option
  1059 			// Accessing the parent's selectedIndex property fixes it
  1060 			if ( name == "selected" && jQuery.browser.safari )
  1061 				elem.parentNode.selectedIndex;
  1063 			// If applicable, access the attribute via the DOM 0 way
  1064 			if ( name in elem && notxml && !special ) {
  1065 				if ( set ){
  1066 					// We can't allow the type property to be changed (since it causes problems in IE)
  1067 					if ( name == "type" && jQuery.nodeName( elem, "input" ) && elem.parentNode )
  1068 						throw "type property can't be changed";
  1070 					elem[ name ] = value;
  1073 				// browsers index elements by id/name on forms, give priority to attributes.
  1074 				if( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) )
  1075 					return elem.getAttributeNode( name ).nodeValue;
  1077 				return elem[ name ];
  1080 			if ( msie && notxml &&  name == "style" )
  1081 				return jQuery.attr( elem.style, "cssText", value );
  1083 			if ( set )
  1084 				// convert the value to a string (all browsers do this but IE) see #1070
  1085 				elem.setAttribute( name, "" + value );
  1087 			var attr = msie && notxml && special
  1088 					// Some attributes require a special call on IE
  1089 					? elem.getAttribute( name, 2 )
  1090 					: elem.getAttribute( name );
  1092 			// Non-existent attributes return null, we normalize to undefined
  1093 			return attr === null ? undefined : attr;
  1096 		// elem is actually elem.style ... set the style
  1098 		// IE uses filters for opacity
  1099 		if ( msie && name == "opacity" ) {
  1100 			if ( set ) {
  1101 				// IE has trouble with opacity if it does not have layout
  1102 				// Force it by setting the zoom level
  1103 				elem.zoom = 1;
  1105 				// Set the alpha filter to set the opacity
  1106 				elem.filter = (elem.filter || "").replace( /alpha\([^)]*\)/, "" ) +
  1107 					(parseInt( value ) + '' == "NaN" ? "" : "alpha(opacity=" + value * 100 + ")");
  1110 			return elem.filter && elem.filter.indexOf("opacity=") >= 0 ?
  1111 				(parseFloat( elem.filter.match(/opacity=([^)]*)/)[1] ) / 100) + '':
  1112 				"";
  1115 		name = name.replace(/-([a-z])/ig, function(all, letter){
  1116 			return letter.toUpperCase();
  1117 		});
  1119 		if ( set )
  1120 			elem[ name ] = value;
  1122 		return elem[ name ];
  1123 	},
  1125 	trim: function( text ) {
  1126 		return (text || "").replace( /^\s+|\s+$/g, "" );
  1127 	},
  1129 	makeArray: function( array ) {
  1130 		var ret = [];
  1132 		if( array != null ){
  1133 			var i = array.length;
  1134 			//the window, strings and functions also have 'length'
  1135 			if( i == null || array.split || array.setInterval || array.call )
  1136 				ret[0] = array;
  1137 			else
  1138 				while( i )
  1139 					ret[--i] = array[i];
  1142 		return ret;
  1143 	},
  1145 	inArray: function( elem, array ) {
  1146 		for ( var i = 0, length = array.length; i < length; i++ )
  1147 		// Use === because on IE, window == document
  1148 			if ( array[ i ] === elem )
  1149 				return i;
  1151 		return -1;
  1152 	},
  1154 	merge: function( first, second ) {
  1155 		// We have to loop this way because IE & Opera overwrite the length
  1156 		// expando of getElementsByTagName
  1157 		var i = 0, elem, pos = first.length;
  1158 		// Also, we need to make sure that the correct elements are being returned
  1159 		// (IE returns comment nodes in a '*' query)
  1160 		if ( jQuery.browser.msie ) {
  1161 			while ( elem = second[ i++ ] )
  1162 				if ( elem.nodeType != 8 )
  1163 					first[ pos++ ] = elem;
  1165 		} else
  1166 			while ( elem = second[ i++ ] )
  1167 				first[ pos++ ] = elem;
  1169 		return first;
  1170 	},
  1172 	unique: function( array ) {
  1173 		var ret = [], done = {};
  1175 		try {
  1177 			for ( var i = 0, length = array.length; i < length; i++ ) {
  1178 				var id = jQuery.data( array[ i ] );
  1180 				if ( !done[ id ] ) {
  1181 					done[ id ] = true;
  1182 					ret.push( array[ i ] );
  1186 		} catch( e ) {
  1187 			ret = array;
  1190 		return ret;
  1191 	},
  1193 	grep: function( elems, callback, inv ) {
  1194 		var ret = [];
  1196 		// Go through the array, only saving the items
  1197 		// that pass the validator function
  1198 		for ( var i = 0, length = elems.length; i < length; i++ )
  1199 			if ( !inv != !callback( elems[ i ], i ) )
  1200 				ret.push( elems[ i ] );
  1202 		return ret;
  1203 	},
  1205 	map: function( elems, callback ) {
  1206 		var ret = [];
  1208 		// Go through the array, translating each of the items to their
  1209 		// new value (or values).
  1210 		for ( var i = 0, length = elems.length; i < length; i++ ) {
  1211 			var value = callback( elems[ i ], i );
  1213 			if ( value != null )
  1214 				ret[ ret.length ] = value;
  1217 		return ret.concat.apply( [], ret );
  1219 });
  1221 var userAgent = navigator.userAgent.toLowerCase();
  1223 // Figure out what browser is being used
  1224 jQuery.browser = {
  1225 	version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [])[1],
  1226 	safari: /webkit/.test( userAgent ),
  1227 	opera: /opera/.test( userAgent ),
  1228 	msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ),
  1229 	mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent )
  1230 };
  1232 var styleFloat = jQuery.browser.msie ?
  1233 	"styleFloat" :
  1234 	"cssFloat";
  1236 jQuery.extend({
  1237 	// Check to see if the W3C box model is being used
  1238 	boxModel: !jQuery.browser.msie || document.compatMode == "CSS1Compat",
  1240 	props: {
  1241 		"for": "htmlFor",
  1242 		"class": "className",
  1243 		"float": styleFloat,
  1244 		cssFloat: styleFloat,
  1245 		styleFloat: styleFloat,
  1246 		readonly: "readOnly",
  1247 		maxlength: "maxLength",
  1248 		cellspacing: "cellSpacing"
  1250 });
  1252 jQuery.each({
  1253 	parent: function(elem){return elem.parentNode;},
  1254 	parents: function(elem){return jQuery.dir(elem,"parentNode");},
  1255 	next: function(elem){return jQuery.nth(elem,2,"nextSibling");},
  1256 	prev: function(elem){return jQuery.nth(elem,2,"previousSibling");},
  1257 	nextAll: function(elem){return jQuery.dir(elem,"nextSibling");},
  1258 	prevAll: function(elem){return jQuery.dir(elem,"previousSibling");},
  1259 	siblings: function(elem){return jQuery.sibling(elem.parentNode.firstChild,elem);},
  1260 	children: function(elem){return jQuery.sibling(elem.firstChild);},
  1261 	contents: function(elem){return jQuery.nodeName(elem,"iframe")?elem.contentDocument||elem.contentWindow.document:jQuery.makeArray(elem.childNodes);}
  1262 }, function(name, fn){
  1263 	jQuery.fn[ name ] = function( selector ) {
  1264 		var ret = jQuery.map( this, fn );
  1266 		if ( selector && typeof selector == "string" )
  1267 			ret = jQuery.multiFilter( selector, ret );
  1269 		return this.pushStack( jQuery.unique( ret ) );
  1270 	};
  1271 });
  1273 jQuery.each({
  1274 	appendTo: "append",
  1275 	prependTo: "prepend",
  1276 	insertBefore: "before",
  1277 	insertAfter: "after",
  1278 	replaceAll: "replaceWith"
  1279 }, function(name, original){
  1280 	jQuery.fn[ name ] = function() {
  1281 		var args = arguments;
  1283 		return this.each(function(){
  1284 			for ( var i = 0, length = args.length; i < length; i++ )
  1285 				jQuery( args[ i ] )[ original ]( this );
  1286 		});
  1287 	};
  1288 });
  1290 jQuery.each({
  1291 	removeAttr: function( name ) {
  1292 		jQuery.attr( this, name, "" );
  1293 		if (this.nodeType == 1)
  1294 			this.removeAttribute( name );
  1295 	},
  1297 	addClass: function( classNames ) {
  1298 		jQuery.className.add( this, classNames );
  1299 	},
  1301 	removeClass: function( classNames ) {
  1302 		jQuery.className.remove( this, classNames );
  1303 	},
  1305 	toggleClass: function( classNames ) {
  1306 		jQuery.className[ jQuery.className.has( this, classNames ) ? "remove" : "add" ]( this, classNames );
  1307 	},
  1309 	remove: function( selector ) {
  1310 		if ( !selector || jQuery.filter( selector, [ this ] ).r.length ) {
  1311 			// Prevent memory leaks
  1312 			jQuery( "*", this ).add(this).each(function(){
  1313 				jQuery.event.remove(this);
  1314 				jQuery.removeData(this);
  1315 			});
  1316 			if (this.parentNode)
  1317 				this.parentNode.removeChild( this );
  1319 	},
  1321 	empty: function() {
  1322 		// Remove element nodes and prevent memory leaks
  1323 		jQuery( ">*", this ).remove();
  1325 		// Remove any remaining nodes
  1326 		while ( this.firstChild )
  1327 			this.removeChild( this.firstChild );
  1329 }, function(name, fn){
  1330 	jQuery.fn[ name ] = function(){
  1331 		return this.each( fn, arguments );
  1332 	};
  1333 });
  1335 jQuery.each([ "Height", "Width" ], function(i, name){
  1336 	var type = name.toLowerCase();
  1338 	jQuery.fn[ type ] = function( size ) {
  1339 		// Get window width or height
  1340 		return this[0] == window ?
  1341 			// Opera reports document.body.client[Width/Height] properly in both quirks and standards
  1342 			jQuery.browser.opera && document.body[ "client" + name ] ||
  1344 			// Safari reports inner[Width/Height] just fine (Mozilla and Opera include scroll bar widths)
  1345 			jQuery.browser.safari && window[ "inner" + name ] ||
  1347 			// Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
  1348 			document.compatMode == "CSS1Compat" && document.documentElement[ "client" + name ] || document.body[ "client" + name ] :
  1350 			// Get document width or height
  1351 			this[0] == document ?
  1352 				// Either scroll[Width/Height] or offset[Width/Height], whichever is greater
  1353 				Math.max(
  1354 					Math.max(document.body["scroll" + name], document.documentElement["scroll" + name]),
  1355 					Math.max(document.body["offset" + name], document.documentElement["offset" + name])
  1356 				) :
  1358 				// Get or set width or height on the element
  1359 				size == undefined ?
  1360 					// Get width or height on the element
  1361 					(this.length ? jQuery.css( this[0], type ) : null) :
  1363 					// Set the width or height on the element (default to pixels if value is unitless)
  1364 					this.css( type, size.constructor == String ? size : size + "px" );
  1365 	};
  1366 });
  1368 // Helper function used by the dimensions and offset modules
  1369 function num(elem, prop) {
  1370 	return elem[0] && parseInt( jQuery.curCSS(elem[0], prop, true), 10 ) || 0;
  1371 }var chars = jQuery.browser.safari && parseInt(jQuery.browser.version) < 417 ?
  1372 		"(?:[\\w*_-]|\\\\.)" :
  1373 		"(?:[\\w\u0128-\uFFFF*_-]|\\\\.)",
  1374 	quickChild = new RegExp("^>\\s*(" + chars + "+)"),
  1375 	quickID = new RegExp("^(" + chars + "+)(#)(" + chars + "+)"),
  1376 	quickClass = new RegExp("^([#.]?)(" + chars + "*)");
  1378 jQuery.extend({
  1379 	expr: {
  1380 		"": function(a,i,m){return m[2]=="*"||jQuery.nodeName(a,m[2]);},
  1381 		"#": function(a,i,m){return a.getAttribute("id")==m[2];},
  1382 		":": {
  1383 			// Position Checks
  1384 			lt: function(a,i,m){return i<m[3]-0;},
  1385 			gt: function(a,i,m){return i>m[3]-0;},
  1386 			nth: function(a,i,m){return m[3]-0==i;},
  1387 			eq: function(a,i,m){return m[3]-0==i;},
  1388 			first: function(a,i){return i==0;},
  1389 			last: function(a,i,m,r){return i==r.length-1;},
  1390 			even: function(a,i){return i%2==0;},
  1391 			odd: function(a,i){return i%2;},
  1393 			// Child Checks
  1394 			"first-child": function(a){return a.parentNode.getElementsByTagName("*")[0]==a;},
  1395 			"last-child": function(a){return jQuery.nth(a.parentNode.lastChild,1,"previousSibling")==a;},
  1396 			"only-child": function(a){return !jQuery.nth(a.parentNode.lastChild,2,"previousSibling");},
  1398 			// Parent Checks
  1399 			parent: function(a){return a.firstChild;},
  1400 			empty: function(a){return !a.firstChild;},
  1402 			// Text Check
  1403 			contains: function(a,i,m){return (a.textContent||a.innerText||jQuery(a).text()||"").indexOf(m[3])>=0;},
  1405 			// Visibility
  1406 			visible: function(a){return "hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden";},
  1407 			hidden: function(a){return "hidden"==a.type||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden";},
  1409 			// Form attributes
  1410 			enabled: function(a){return !a.disabled;},
  1411 			disabled: function(a){return a.disabled;},
  1412 			checked: function(a){return a.checked;},
  1413 			selected: function(a){return a.selected||jQuery.attr(a,"selected");},
  1415 			// Form elements
  1416 			text: function(a){return "text"==a.type;},
  1417 			radio: function(a){return "radio"==a.type;},
  1418 			checkbox: function(a){return "checkbox"==a.type;},
  1419 			file: function(a){return "file"==a.type;},
  1420 			password: function(a){return "password"==a.type;},
  1421 			submit: function(a){return "submit"==a.type;},
  1422 			image: function(a){return "image"==a.type;},
  1423 			reset: function(a){return "reset"==a.type;},
  1424 			button: function(a){return "button"==a.type||jQuery.nodeName(a,"button");},
  1425 			input: function(a){return /input|select|textarea|button/i.test(a.nodeName);},
  1427 			// :has()
  1428 			has: function(a,i,m){return jQuery.find(m[3],a).length;},
  1430 			// :header
  1431 			header: function(a){return /h\d/i.test(a.nodeName);},
  1433 			// :animated
  1434 			animated: function(a){return jQuery.grep(jQuery.timers,function(fn){return a==fn.elem;}).length;}
  1436 	},
  1438 	// The regular expressions that power the parsing engine
  1439 	parse: [
  1440 		// Match: [@value='test'], [@foo]
  1441 		/^(\[) *@?([\w-]+) *([!*$^~=]*) *('?"?)(.*?)\4 *\]/,
  1443 		// Match: :contains('foo')
  1444 		/^(:)([\w-]+)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/,
  1446 		// Match: :even, :last-child, #id, .class
  1447 		new RegExp("^([:.#]*)(" + chars + "+)")
  1448 	],
  1450 	multiFilter: function( expr, elems, not ) {
  1451 		var old, cur = [];
  1453 		while ( expr && expr != old ) {
  1454 			old = expr;
  1455 			var f = jQuery.filter( expr, elems, not );
  1456 			expr = f.t.replace(/^\s*,\s*/, "" );
  1457 			cur = not ? elems = f.r : jQuery.merge( cur, f.r );
  1460 		return cur;
  1461 	},
  1463 	find: function( t, context ) {
  1464 		// Quickly handle non-string expressions
  1465 		if ( typeof t != "string" )
  1466 			return [ t ];
  1468 		// check to make sure context is a DOM element or a document
  1469 		if ( context && context.nodeType != 1 && context.nodeType != 9)
  1470 			return [ ];
  1472 		// Set the correct context (if none is provided)
  1473 		context = context || document;
  1475 		// Initialize the search
  1476 		var ret = [context], done = [], last, nodeName;
  1478 		// Continue while a selector expression exists, and while
  1479 		// we're no longer looping upon ourselves
  1480 		while ( t && last != t ) {
  1481 			var r = [];
  1482 			last = t;
  1484 			t = jQuery.trim(t);
  1486 			var foundToken = false,
  1488 			// An attempt at speeding up child selectors that
  1489 			// point to a specific element tag
  1490 				re = quickChild,
  1492 				m = re.exec(t);
  1494 			if ( m ) {
  1495 				nodeName = m[1].toUpperCase();
  1497 				// Perform our own iteration and filter
  1498 				for ( var i = 0; ret[i]; i++ )
  1499 					for ( var c = ret[i].firstChild; c; c = c.nextSibling )
  1500 						if ( c.nodeType == 1 && (nodeName == "*" || c.nodeName.toUpperCase() == nodeName) )
  1501 							r.push( c );
  1503 				ret = r;
  1504 				t = t.replace( re, "" );
  1505 				if ( t.indexOf(" ") == 0 ) continue;
  1506 				foundToken = true;
  1507 			} else {
  1508 				re = /^([>+~])\s*(\w*)/i;
  1510 				if ( (m = re.exec(t)) != null ) {
  1511 					r = [];
  1513 					var merge = {};
  1514 					nodeName = m[2].toUpperCase();
  1515 					m = m[1];
  1517 					for ( var j = 0, rl = ret.length; j < rl; j++ ) {
  1518 						var n = m == "~" || m == "+" ? ret[j].nextSibling : ret[j].firstChild;
  1519 						for ( ; n; n = n.nextSibling )
  1520 							if ( n.nodeType == 1 ) {
  1521 								var id = jQuery.data(n);
  1523 								if ( m == "~" && merge[id] ) break;
  1525 								if (!nodeName || n.nodeName.toUpperCase() == nodeName ) {
  1526 									if ( m == "~" ) merge[id] = true;
  1527 									r.push( n );
  1530 								if ( m == "+" ) break;
  1534 					ret = r;
  1536 					// And remove the token
  1537 					t = jQuery.trim( t.replace( re, "" ) );
  1538 					foundToken = true;
  1542 			// See if there's still an expression, and that we haven't already
  1543 			// matched a token
  1544 			if ( t && !foundToken ) {
  1545 				// Handle multiple expressions
  1546 				if ( !t.indexOf(",") ) {
  1547 					// Clean the result set
  1548 					if ( context == ret[0] ) ret.shift();
  1550 					// Merge the result sets
  1551 					done = jQuery.merge( done, ret );
  1553 					// Reset the context
  1554 					r = ret = [context];
  1556 					// Touch up the selector string
  1557 					t = " " + t.substr(1,t.length);
  1559 				} else {
  1560 					// Optimize for the case nodeName#idName
  1561 					var re2 = quickID;
  1562 					var m = re2.exec(t);
  1564 					// Re-organize the results, so that they're consistent
  1565 					if ( m ) {
  1566 						m = [ 0, m[2], m[3], m[1] ];
  1568 					} else {
  1569 						// Otherwise, do a traditional filter check for
  1570 						// ID, class, and element selectors
  1571 						re2 = quickClass;
  1572 						m = re2.exec(t);
  1575 					m[2] = m[2].replace(/\\/g, "");
  1577 					var elem = ret[ret.length-1];
  1579 					// Try to do a global search by ID, where we can
  1580 					if ( m[1] == "#" && elem && elem.getElementById && !jQuery.isXMLDoc(elem) ) {
  1581 						// Optimization for HTML document case
  1582 						var oid = elem.getElementById(m[2]);
  1584 						// Do a quick check for the existence of the actual ID attribute
  1585 						// to avoid selecting by the name attribute in IE
  1586 						// also check to insure id is a string to avoid selecting an element with the name of 'id' inside a form
  1587 						if ( (jQuery.browser.msie||jQuery.browser.opera) && oid && typeof oid.id == "string" && oid.id != m[2] )
  1588 							oid = jQuery('[@id="'+m[2]+'"]', elem)[0];
  1590 						// Do a quick check for node name (where applicable) so
  1591 						// that div#foo searches will be really fast
  1592 						ret = r = oid && (!m[3] || jQuery.nodeName(oid, m[3])) ? [oid] : [];
  1593 					} else {
  1594 						// We need to find all descendant elements
  1595 						for ( var i = 0; ret[i]; i++ ) {
  1596 							// Grab the tag name being searched for
  1597 							var tag = m[1] == "#" && m[3] ? m[3] : m[1] != "" || m[0] == "" ? "*" : m[2];
  1599 							// Handle IE7 being really dumb about <object>s
  1600 							if ( tag == "*" && ret[i].nodeName.toLowerCase() == "object" )
  1601 								tag = "param";
  1603 							r = jQuery.merge( r, ret[i].getElementsByTagName( tag ));
  1606 						// It's faster to filter by class and be done with it
  1607 						if ( m[1] == "." )
  1608 							r = jQuery.classFilter( r, m[2] );
  1610 						// Same with ID filtering
  1611 						if ( m[1] == "#" ) {
  1612 							var tmp = [];
  1614 							// Try to find the element with the ID
  1615 							for ( var i = 0; r[i]; i++ )
  1616 								if ( r[i].getAttribute("id") == m[2] ) {
  1617 									tmp = [ r[i] ];
  1618 									break;
  1621 							r = tmp;
  1624 						ret = r;
  1627 					t = t.replace( re2, "" );
  1632 			// If a selector string still exists
  1633 			if ( t ) {
  1634 				// Attempt to filter it
  1635 				var val = jQuery.filter(t,r);
  1636 				ret = r = val.r;
  1637 				t = jQuery.trim(val.t);
  1641 		// An error occurred with the selector;
  1642 		// just return an empty set instead
  1643 		if ( t )
  1644 			ret = [];
  1646 		// Remove the root context
  1647 		if ( ret && context == ret[0] )
  1648 			ret.shift();
  1650 		// And combine the results
  1651 		done = jQuery.merge( done, ret );
  1653 		return done;
  1654 	},
  1656 	classFilter: function(r,m,not){
  1657 		m = " " + m + " ";
  1658 		var tmp = [];
  1659 		for ( var i = 0; r[i]; i++ ) {
  1660 			var pass = (" " + r[i].className + " ").indexOf( m ) >= 0;
  1661 			if ( !not && pass || not && !pass )
  1662 				tmp.push( r[i] );
  1664 		return tmp;
  1665 	},
  1667 	filter: function(t,r,not) {
  1668 		var last;
  1670 		// Look for common filter expressions
  1671 		while ( t && t != last ) {
  1672 			last = t;
  1674 			var p = jQuery.parse, m;
  1676 			for ( var i = 0; p[i]; i++ ) {
  1677 				m = p[i].exec( t );
  1679 				if ( m ) {
  1680 					// Remove what we just matched
  1681 					t = t.substring( m[0].length );
  1683 					m[2] = m[2].replace(/\\/g, "");
  1684 					break;
  1688 			if ( !m )
  1689 				break;
  1691 			// :not() is a special case that can be optimized by
  1692 			// keeping it out of the expression list
  1693 			if ( m[1] == ":" && m[2] == "not" )
  1694 				// optimize if only one selector found (most common case)
  1695 				r = isSimple.test( m[3] ) ?
  1696 					jQuery.filter(m[3], r, true).r :
  1697 					jQuery( r ).not( m[3] );
  1699 			// We can get a big speed boost by filtering by class here
  1700 			else if ( m[1] == "." )
  1701 				r = jQuery.classFilter(r, m[2], not);
  1703 			else if ( m[1] == "[" ) {
  1704 				var tmp = [], type = m[3];
  1706 				for ( var i = 0, rl = r.length; i < rl; i++ ) {
  1707 					var a = r[i], z = a[ jQuery.props[m[2]] || m[2] ];
  1709 					if ( z == null || /href|src|selected/.test(m[2]) )
  1710 						z = jQuery.attr(a,m[2]) || '';
  1712 					if ( (type == "" && !!z ||
  1713 						 type == "=" && z == m[5] ||
  1714 						 type == "!=" && z != m[5] ||
  1715 						 type == "^=" && z && !z.indexOf(m[5]) ||
  1716 						 type == "$=" && z.substr(z.length - m[5].length) == m[5] ||
  1717 						 (type == "*=" || type == "~=") && z.indexOf(m[5]) >= 0) ^ not )
  1718 							tmp.push( a );
  1721 				r = tmp;
  1723 			// We can get a speed boost by handling nth-child here
  1724 			} else if ( m[1] == ":" && m[2] == "nth-child" ) {
  1725 				var merge = {}, tmp = [],
  1726 					// parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
  1727 					test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
  1728 						m[3] == "even" && "2n" || m[3] == "odd" && "2n+1" ||
  1729 						!/\D/.test(m[3]) && "0n+" + m[3] || m[3]),
  1730 					// calculate the numbers (first)n+(last) including if they are negative
  1731 					first = (test[1] + (test[2] || 1)) - 0, last = test[3] - 0;
  1733 				// loop through all the elements left in the jQuery object
  1734 				for ( var i = 0, rl = r.length; i < rl; i++ ) {
  1735 					var node = r[i], parentNode = node.parentNode, id = jQuery.data(parentNode);
  1737 					if ( !merge[id] ) {
  1738 						var c = 1;
  1740 						for ( var n = parentNode.firstChild; n; n = n.nextSibling )
  1741 							if ( n.nodeType == 1 )
  1742 								n.nodeIndex = c++;
  1744 						merge[id] = true;
  1747 					var add = false;
  1749 					if ( first == 0 ) {
  1750 						if ( node.nodeIndex == last )
  1751 							add = true;
  1752 					} else if ( (node.nodeIndex - last) % first == 0 && (node.nodeIndex - last) / first >= 0 )
  1753 						add = true;
  1755 					if ( add ^ not )
  1756 						tmp.push( node );
  1759 				r = tmp;
  1761 			// Otherwise, find the expression to execute
  1762 			} else {
  1763 				var fn = jQuery.expr[ m[1] ];
  1764 				if ( typeof fn == "object" )
  1765 					fn = fn[ m[2] ];
  1767 				if ( typeof fn == "string" )
  1768 					fn = eval("false||function(a,i){return " + fn + ";}");
  1770 				// Execute it against the current filter
  1771 				r = jQuery.grep( r, function(elem, i){
  1772 					return fn(elem, i, m, r);
  1773 				}, not );
  1777 		// Return an array of filtered elements (r)
  1778 		// and the modified expression string (t)
  1779 		return { r: r, t: t };
  1780 	},
  1782 	dir: function( elem, dir ){
  1783 		var matched = [],
  1784 			cur = elem[dir];
  1785 		while ( cur && cur != document ) {
  1786 			if ( cur.nodeType == 1 )
  1787 				matched.push( cur );
  1788 			cur = cur[dir];
  1790 		return matched;
  1791 	},
  1793 	nth: function(cur,result,dir,elem){
  1794 		result = result || 1;
  1795 		var num = 0;
  1797 		for ( ; cur; cur = cur[dir] )
  1798 			if ( cur.nodeType == 1 && ++num == result )
  1799 				break;
  1801 		return cur;
  1802 	},
  1804 	sibling: function( n, elem ) {
  1805 		var r = [];
  1807 		for ( ; n; n = n.nextSibling ) {
  1808 			if ( n.nodeType == 1 && n != elem )
  1809 				r.push( n );
  1812 		return r;
  1814 });
  1815 /*
  1816  * A number of helper functions used for managing events.
  1817  * Many of the ideas behind this code orignated from
  1818  * Dean Edwards' addEvent library.
  1819  */
  1820 jQuery.event = {
  1822 	// Bind an event to an element
  1823 	// Original by Dean Edwards
  1824 	add: function(elem, types, handler, data) {
  1825 		if ( elem.nodeType == 3 || elem.nodeType == 8 )
  1826 			return;
  1828 		// For whatever reason, IE has trouble passing the window object
  1829 		// around, causing it to be cloned in the process
  1830 		if ( jQuery.browser.msie && elem.setInterval )
  1831 			elem = window;
  1833 		// Make sure that the function being executed has a unique ID
  1834 		if ( !handler.guid )
  1835 			handler.guid = this.guid++;
  1837 		// if data is passed, bind to handler
  1838 		if( data != undefined ) {
  1839 			// Create temporary function pointer to original handler
  1840 			var fn = handler;
  1842 			// Create unique handler function, wrapped around original handler
  1843 			handler = this.proxy( fn, function() {
  1844 				// Pass arguments and context to original handler
  1845 				return fn.apply(this, arguments);
  1846 			});
  1848 			// Store data in unique handler
  1849 			handler.data = data;
  1852 		// Init the element's event structure
  1853 		var events = jQuery.data(elem, "events") || jQuery.data(elem, "events", {}),
  1854 			handle = jQuery.data(elem, "handle") || jQuery.data(elem, "handle", function(){
  1855 				// Handle the second event of a trigger and when
  1856 				// an event is called after a page has unloaded
  1857 				if ( typeof jQuery != "undefined" && !jQuery.event.triggered )
  1858 					return jQuery.event.handle.apply(arguments.callee.elem, arguments);
  1859 			});
  1860 		// Add elem as a property of the handle function
  1861 		// This is to prevent a memory leak with non-native
  1862 		// event in IE.
  1863 		handle.elem = elem;
  1865 		// Handle multiple events separated by a space
  1866 		// jQuery(...).bind("mouseover mouseout", fn);
  1867 		jQuery.each(types.split(/\s+/), function(index, type) {
  1868 			// Namespaced event handlers
  1869 			var parts = type.split(".");
  1870 			type = parts[0];
  1871 			handler.type = parts[1];
  1873 			// Get the current list of functions bound to this event
  1874 			var handlers = events[type];
  1876 			// Init the event handler queue
  1877 			if (!handlers) {
  1878 				handlers = events[type] = {};
  1880 				// Check for a special event handler
  1881 				// Only use addEventListener/attachEvent if the special
  1882 				// events handler returns false
  1883 				if ( !jQuery.event.special[type] || jQuery.event.special[type].setup.call(elem) === false ) {
  1884 					// Bind the global event handler to the element
  1885 					if (elem.addEventListener)
  1886 						elem.addEventListener(type, handle, false);
  1887 					else if (elem.attachEvent)
  1888 						elem.attachEvent("on" + type, handle);
  1892 			// Add the function to the element's handler list
  1893 			handlers[handler.guid] = handler;
  1895 			// Keep track of which events have been used, for global triggering
  1896 			jQuery.event.global[type] = true;
  1897 		});
  1899 		// Nullify elem to prevent memory leaks in IE
  1900 		elem = null;
  1901 	},
  1903 	guid: 1,
  1904 	global: {},
  1906 	// Detach an event or set of events from an element
  1907 	remove: function(elem, types, handler) {
  1908 		// don't do events on text and comment nodes
  1909 		if ( elem.nodeType == 3 || elem.nodeType == 8 )
  1910 			return;
  1912 		var events = jQuery.data(elem, "events"), ret, index;
  1914 		if ( events ) {
  1915 			// Unbind all events for the element
  1916 			if ( types == undefined || (typeof types == "string" && types.charAt(0) == ".") )
  1917 				for ( var type in events )
  1918 					this.remove( elem, type + (types || "") );
  1919 			else {
  1920 				// types is actually an event object here
  1921 				if ( types.type ) {
  1922 					handler = types.handler;
  1923 					types = types.type;
  1926 				// Handle multiple events seperated by a space
  1927 				// jQuery(...).unbind("mouseover mouseout", fn);
  1928 				jQuery.each(types.split(/\s+/), function(index, type){
  1929 					// Namespaced event handlers
  1930 					var parts = type.split(".");
  1931 					type = parts[0];
  1933 					if ( events[type] ) {
  1934 						// remove the given handler for the given type
  1935 						if ( handler )
  1936 							delete events[type][handler.guid];
  1938 						// remove all handlers for the given type
  1939 						else
  1940 							for ( handler in events[type] )
  1941 								// Handle the removal of namespaced events
  1942 								if ( !parts[1] || events[type][handler].type == parts[1] )
  1943 									delete events[type][handler];
  1945 						// remove generic event handler if no more handlers exist
  1946 						for ( ret in events[type] ) break;
  1947 						if ( !ret ) {
  1948 							if ( !jQuery.event.special[type] || jQuery.event.special[type].teardown.call(elem) === false ) {
  1949 								if (elem.removeEventListener)
  1950 									elem.removeEventListener(type, jQuery.data(elem, "handle"), false);
  1951 								else if (elem.detachEvent)
  1952 									elem.detachEvent("on" + type, jQuery.data(elem, "handle"));
  1954 							ret = null;
  1955 							delete events[type];
  1958 				});
  1961 			// Remove the expando if it's no longer used
  1962 			for ( ret in events ) break;
  1963 			if ( !ret ) {
  1964 				var handle = jQuery.data( elem, "handle" );
  1965 				if ( handle ) handle.elem = null;
  1966 				jQuery.removeData( elem, "events" );
  1967 				jQuery.removeData( elem, "handle" );
  1970 	},
  1972 	trigger: function(type, data, elem, donative, extra) {
  1973 		// Clone the incoming data, if any
  1974 		data = jQuery.makeArray(data);
  1976 		if ( type.indexOf("!") >= 0 ) {
  1977 			type = type.slice(0, -1);
  1978 			var exclusive = true;
  1981 		// Handle a global trigger
  1982 		if ( !elem ) {
  1983 			// Only trigger if we've ever bound an event for it
  1984 			if ( this.global[type] )
  1985 				jQuery("*").add([window, document]).trigger(type, data);
  1987 		// Handle triggering a single element
  1988 		} else {
  1989 			// don't do events on text and comment nodes
  1990 			if ( elem.nodeType == 3 || elem.nodeType == 8 )
  1991 				return undefined;
  1993 			var val, ret, fn = jQuery.isFunction( elem[ type ] || null ),
  1994 				// Check to see if we need to provide a fake event, or not
  1995 				event = !data[0] || !data[0].preventDefault;
  1997 			// Pass along a fake event
  1998 			if ( event ) {
  1999 				data.unshift({
  2000 					type: type,
  2001 					target: elem,
  2002 					preventDefault: function(){},
  2003 					stopPropagation: function(){},
  2004 					timeStamp: now()
  2005 				});
  2006 				data[0][expando] = true; // no need to fix fake event
  2009 			// Enforce the right trigger type
  2010 			data[0].type = type;
  2011 			if ( exclusive )
  2012 				data[0].exclusive = true;
  2014 			// Trigger the event, it is assumed that "handle" is a function
  2015 			var handle = jQuery.data(elem, "handle");
  2016 			if ( handle )
  2017 				val = handle.apply( elem, data );
  2019 			// Handle triggering native .onfoo handlers (and on links since we don't call .click() for links)
  2020 			if ( (!fn || (jQuery.nodeName(elem, 'a') && type == "click")) && elem["on"+type] && elem["on"+type].apply( elem, data ) === false )
  2021 				val = false;
  2023 			// Extra functions don't get the custom event object
  2024 			if ( event )
  2025 				data.shift();
  2027 			// Handle triggering of extra function
  2028 			if ( extra && jQuery.isFunction( extra ) ) {
  2029 				// call the extra function and tack the current return value on the end for possible inspection
  2030 				ret = extra.apply( elem, val == null ? data : data.concat( val ) );
  2031 				// if anything is returned, give it precedence and have it overwrite the previous value
  2032 				if (ret !== undefined)
  2033 					val = ret;
  2036 			// Trigger the native events (except for clicks on links)
  2037 			if ( fn && donative !== false && val !== false && !(jQuery.nodeName(elem, 'a') && type == "click") ) {
  2038 				this.triggered = true;
  2039 				try {
  2040 					elem[ type ]();
  2041 				// prevent IE from throwing an error for some hidden elements
  2042 				} catch (e) {}
  2045 			this.triggered = false;
  2048 		return val;
  2049 	},
  2051 	handle: function(event) {
  2052 		// returned undefined or false
  2053 		var val, ret, namespace, all, handlers;
  2055 		event = arguments[0] = jQuery.event.fix( event || window.event );
  2057 		// Namespaced event handlers
  2058 		namespace = event.type.split(".");
  2059 		event.type = namespace[0];
  2060 		namespace = namespace[1];
  2061 		// Cache this now, all = true means, any handler
  2062 		all = !namespace && !event.exclusive;
  2064 		handlers = ( jQuery.data(this, "events") || {} )[event.type];
  2066 		for ( var j in handlers ) {
  2067 			var handler = handlers[j];
  2069 			// Filter the functions by class
  2070 			if ( all || handler.type == namespace ) {
  2071 				// Pass in a reference to the handler function itself
  2072 				// So that we can later remove it
  2073 				event.handler = handler;
  2074 				event.data = handler.data;
  2076 				ret = handler.apply( this, arguments );
  2078 				if ( val !== false )
  2079 					val = ret;
  2081 				if ( ret === false ) {
  2082 					event.preventDefault();
  2083 					event.stopPropagation();
  2088 		return val;
  2089 	},
  2091 	fix: function(event) {
  2092 		if ( event[expando] == true )
  2093 			return event;
  2095 		// store a copy of the original event object
  2096 		// and "clone" to set read-only properties
  2097 		var originalEvent = event;
  2098 		event = { originalEvent: originalEvent };
  2099 		var props = "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target timeStamp toElement type view wheelDelta which".split(" ");
  2100 		for ( var i=props.length; i; i-- )
  2101 			event[ props[i] ] = originalEvent[ props[i] ];
  2103 		// Mark it as fixed
  2104 		event[expando] = true;
  2106 		// add preventDefault and stopPropagation since
  2107 		// they will not work on the clone
  2108 		event.preventDefault = function() {
  2109 			// if preventDefault exists run it on the original event
  2110 			if (originalEvent.preventDefault)
  2111 				originalEvent.preventDefault();
  2112 			// otherwise set the returnValue property of the original event to false (IE)
  2113 			originalEvent.returnValue = false;
  2114 		};
  2115 		event.stopPropagation = function() {
  2116 			// if stopPropagation exists run it on the original event
  2117 			if (originalEvent.stopPropagation)
  2118 				originalEvent.stopPropagation();
  2119 			// otherwise set the cancelBubble property of the original event to true (IE)
  2120 			originalEvent.cancelBubble = true;
  2121 		};
  2123 		// Fix timeStamp
  2124 		event.timeStamp = event.timeStamp || now();
  2126 		// Fix target property, if necessary
  2127 		if ( !event.target )
  2128 			event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either
  2130 		// check if target is a textnode (safari)
  2131 		if ( event.target.nodeType == 3 )
  2132 			event.target = event.target.parentNode;
  2134 		// Add relatedTarget, if necessary
  2135 		if ( !event.relatedTarget && event.fromElement )
  2136 			event.relatedTarget = event.fromElement == event.target ? event.toElement : event.fromElement;
  2138 		// Calculate pageX/Y if missing and clientX/Y available
  2139 		if ( event.pageX == null && event.clientX != null ) {
  2140 			var doc = document.documentElement, body = document.body;
  2141 			event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc.clientLeft || 0);
  2142 			event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc.clientTop || 0);
  2145 		// Add which for key events
  2146 		if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) )
  2147 			event.which = event.charCode || event.keyCode;
  2149 		// Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
  2150 		if ( !event.metaKey && event.ctrlKey )
  2151 			event.metaKey = event.ctrlKey;
  2153 		// Add which for click: 1 == left; 2 == middle; 3 == right
  2154 		// Note: button is not normalized, so don't use it
  2155 		if ( !event.which && event.button )
  2156 			event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
  2158 		return event;
  2159 	},
  2161 	proxy: function( fn, proxy ){
  2162 		// Set the guid of unique handler to the same of original handler, so it can be removed
  2163 		proxy.guid = fn.guid = fn.guid || proxy.guid || this.guid++;
  2164 		// So proxy can be declared as an argument
  2165 		return proxy;
  2166 	},
  2168 	special: {
  2169 		ready: {
  2170 			setup: function() {
  2171 				// Make sure the ready event is setup
  2172 				bindReady();
  2173 				return;
  2174 			},
  2176 			teardown: function() { return; }
  2177 		},
  2179 		mouseenter: {
  2180 			setup: function() {
  2181 				if ( jQuery.browser.msie ) return false;
  2182 				jQuery(this).bind("mouseover", jQuery.event.special.mouseenter.handler);
  2183 				return true;
  2184 			},
  2186 			teardown: function() {
  2187 				if ( jQuery.browser.msie ) return false;
  2188 				jQuery(this).unbind("mouseover", jQuery.event.special.mouseenter.handler);
  2189 				return true;
  2190 			},
  2192 			handler: function(event) {
  2193 				// If we actually just moused on to a sub-element, ignore it
  2194 				if ( withinElement(event, this) ) return true;
  2195 				// Execute the right handlers by setting the event type to mouseenter
  2196 				event.type = "mouseenter";
  2197 				return jQuery.event.handle.apply(this, arguments);
  2199 		},
  2201 		mouseleave: {
  2202 			setup: function() {
  2203 				if ( jQuery.browser.msie ) return false;
  2204 				jQuery(this).bind("mouseout", jQuery.event.special.mouseleave.handler);
  2205 				return true;
  2206 			},
  2208 			teardown: function() {
  2209 				if ( jQuery.browser.msie ) return false;
  2210 				jQuery(this).unbind("mouseout", jQuery.event.special.mouseleave.handler);
  2211 				return true;
  2212 			},
  2214 			handler: function(event) {
  2215 				// If we actually just moused on to a sub-element, ignore it
  2216 				if ( withinElement(event, this) ) return true;
  2217 				// Execute the right handlers by setting the event type to mouseleave
  2218 				event.type = "mouseleave";
  2219 				return jQuery.event.handle.apply(this, arguments);
  2223 };
  2225 jQuery.fn.extend({
  2226 	bind: function( type, data, fn ) {
  2227 		return type == "unload" ? this.one(type, data, fn) : this.each(function(){
  2228 			jQuery.event.add( this, type, fn || data, fn && data );
  2229 		});
  2230 	},
  2232 	one: function( type, data, fn ) {
  2233 		var one = jQuery.event.proxy( fn || data, function(event) {
  2234 			jQuery(this).unbind(event, one);
  2235 			return (fn || data).apply( this, arguments );
  2236 		});
  2237 		return this.each(function(){
  2238 			jQuery.event.add( this, type, one, fn && data);
  2239 		});
  2240 	},
  2242 	unbind: function( type, fn ) {
  2243 		return this.each(function(){
  2244 			jQuery.event.remove( this, type, fn );
  2245 		});
  2246 	},
  2248 	trigger: function( type, data, fn ) {
  2249 		return this.each(function(){
  2250 			jQuery.event.trigger( type, data, this, true, fn );
  2251 		});
  2252 	},
  2254 	triggerHandler: function( type, data, fn ) {
  2255 		return this[0] && jQuery.event.trigger( type, data, this[0], false, fn );
  2256 	},
  2258 	toggle: function( fn ) {
  2259 		// Save reference to arguments for access in closure
  2260 		var args = arguments, i = 1;
  2262 		// link all the functions, so any of them can unbind this click handler
  2263 		while( i < args.length )
  2264 			jQuery.event.proxy( fn, args[i++] );
  2266 		return this.click( jQuery.event.proxy( fn, function(event) {
  2267 			// Figure out which function to execute
  2268 			this.lastToggle = ( this.lastToggle || 0 ) % i;
  2270 			// Make sure that clicks stop
  2271 			event.preventDefault();
  2273 			// and execute the function
  2274 			return args[ this.lastToggle++ ].apply( this, arguments ) || false;
  2275 		}));
  2276 	},
  2278 	hover: function(fnOver, fnOut) {
  2279 		return this.bind('mouseenter', fnOver).bind('mouseleave', fnOut);
  2280 	},
  2282 	ready: function(fn) {
  2283 		// Attach the listeners
  2284 		bindReady();
  2286 		// If the DOM is already ready
  2287 		if ( jQuery.isReady )
  2288 			// Execute the function immediately
  2289 			fn.call( document, jQuery );
  2291 		// Otherwise, remember the function for later
  2292 		else
  2293 			// Add the function to the wait list
  2294 			jQuery.readyList.push( function() { return fn.call(this, jQuery); } );
  2296 		return this;
  2298 });
  2300 jQuery.extend({
  2301 	isReady: false,
  2302 	readyList: [],
  2303 	// Handle when the DOM is ready
  2304 	ready: function() {
  2305 		// Make sure that the DOM is not already loaded
  2306 		if ( !jQuery.isReady ) {
  2307 			// Remember that the DOM is ready
  2308 			jQuery.isReady = true;
  2310 			// If there are functions bound, to execute
  2311 			if ( jQuery.readyList ) {
  2312 				// Execute all of them
  2313 				jQuery.each( jQuery.readyList, function(){
  2314 					this.call( document );
  2315 				});
  2317 				// Reset the list of functions
  2318 				jQuery.readyList = null;
  2321 			// Trigger any bound ready events
  2322 			jQuery(document).triggerHandler("ready");
  2325 });
  2327 var readyBound = false;
  2329 function bindReady(){
  2330 	if ( readyBound ) return;
  2331 	readyBound = true;
  2333 	// Mozilla, Opera (see further below for it) and webkit nightlies currently support this event
  2334 	if ( document.addEventListener && !jQuery.browser.opera)
  2335 		// Use the handy event callback
  2336 		document.addEventListener( "DOMContentLoaded", jQuery.ready, false );
  2338 	// If IE is used and is not in a frame
  2339 	// Continually check to see if the document is ready
  2340 	if ( jQuery.browser.msie && window == top ) (function(){
  2341 		if (jQuery.isReady) return;
  2342 		try {
  2343 			// If IE is used, use the trick by Diego Perini
  2344 			// http://javascript.nwbox.com/IEContentLoaded/
  2345 			document.documentElement.doScroll("left");
  2346 		} catch( error ) {
  2347 			setTimeout( arguments.callee, 0 );
  2348 			return;
  2350 		// and execute any waiting functions
  2351 		jQuery.ready();
  2352 	})();
  2354 	if ( jQuery.browser.opera )
  2355 		document.addEventListener( "DOMContentLoaded", function () {
  2356 			if (jQuery.isReady) return;
  2357 			for (var i = 0; i < document.styleSheets.length; i++)
  2358 				if (document.styleSheets[i].disabled) {
  2359 					setTimeout( arguments.callee, 0 );
  2360 					return;
  2362 			// and execute any waiting functions
  2363 			jQuery.ready();
  2364 		}, false);
  2366 	if ( jQuery.browser.safari ) {
  2367 		var numStyles;
  2368 		(function(){
  2369 			if (jQuery.isReady) return;
  2370 			if ( document.readyState != "loaded" && document.readyState != "complete" ) {
  2371 				setTimeout( arguments.callee, 0 );
  2372 				return;
  2374 			if ( numStyles === undefined )
  2375 				numStyles = jQuery("style, link[rel=stylesheet]").length;
  2376 			if ( document.styleSheets.length != numStyles ) {
  2377 				setTimeout( arguments.callee, 0 );
  2378 				return;
  2380 			// and execute any waiting functions
  2381 			jQuery.ready();
  2382 		})();
  2385 	// A fallback to window.onload, that will always work
  2386 	jQuery.event.add( window, "load", jQuery.ready );
  2389 jQuery.each( ("blur,focus,load,resize,scroll,unload,click,dblclick," +
  2390 	"mousedown,mouseup,mousemove,mouseover,mouseout,change,select," +
  2391 	"submit,keydown,keypress,keyup,error").split(","), function(i, name){
  2393 	// Handle event binding
  2394 	jQuery.fn[name] = function(fn){
  2395 		return fn ? this.bind(name, fn) : this.trigger(name);
  2396 	};
  2397 });
  2399 // Checks if an event happened on an element within another element
  2400 // Used in jQuery.event.special.mouseenter and mouseleave handlers
  2401 var withinElement = function(event, elem) {
  2402 	// Check if mouse(over|out) are still within the same parent element
  2403 	var parent = event.relatedTarget;
  2404 	// Traverse up the tree
  2405 	while ( parent && parent != elem ) try { parent = parent.parentNode; } catch(error) { parent = elem; }
  2406 	// Return true if we actually just moused on to a sub-element
  2407 	return parent == elem;
  2408 };
  2410 // Prevent memory leaks in IE
  2411 // And prevent errors on refresh with events like mouseover in other browsers
  2412 // Window isn't included so as not to unbind existing unload events
  2413 jQuery(window).bind("unload", function() {
  2414 	jQuery("*").add(document).unbind();
  2415 });
  2416 jQuery.fn.extend({
  2417 	// Keep a copy of the old load
  2418 	_load: jQuery.fn.load,
  2420 	load: function( url, params, callback ) {
  2421 		if ( typeof url != 'string' )
  2422 			return this._load( url );
  2424 		var off = url.indexOf(" ");
  2425 		if ( off >= 0 ) {
  2426 			var selector = url.slice(off, url.length);
  2427 			url = url.slice(0, off);
  2430 		callback = callback || function(){};
  2432 		// Default to a GET request
  2433 		var type = "GET";
  2435 		// If the second parameter was provided
  2436 		if ( params )
  2437 			// If it's a function
  2438 			if ( jQuery.isFunction( params ) ) {
  2439 				// We assume that it's the callback
  2440 				callback = params;
  2441 				params = null;
  2443 			// Otherwise, build a param string
  2444 			} else {
  2445 				params = jQuery.param( params );
  2446 				type = "POST";
  2449 		var self = this;
  2451 		// Request the remote document
  2452 		jQuery.ajax({
  2453 			url: url,
  2454 			type: type,
  2455 			dataType: "html",
  2456 			data: params,
  2457 			complete: function(res, status){
  2458 				// If successful, inject the HTML into all the matched elements
  2459 				if ( status == "success" || status == "notmodified" )
  2460 					// See if a selector was specified
  2461 					self.html( selector ?
  2462 						// Create a dummy div to hold the results
  2463 						jQuery("<div/>")
  2464 							// inject the contents of the document in, removing the scripts
  2465 							// to avoid any 'Permission Denied' errors in IE
  2466 							.append(res.responseText.replace(/<script(.|\s)*?\/script>/g, ""))
  2468 							// Locate the specified elements
  2469 							.find(selector) :
  2471 						// If not, just inject the full result
  2472 						res.responseText );
  2474 				self.each( callback, [res.responseText, status, res] );
  2476 		});
  2477 		return this;
  2478 	},
  2480 	serialize: function() {
  2481 		return jQuery.param(this.serializeArray());
  2482 	},
  2483 	serializeArray: function() {
  2484 		return this.map(function(){
  2485 			return jQuery.nodeName(this, "form") ?
  2486 				jQuery.makeArray(this.elements) : this;
  2487 		})
  2488 		.filter(function(){
  2489 			return this.name && !this.disabled &&
  2490 				(this.checked || /select|textarea/i.test(this.nodeName) ||
  2491 					/text|hidden|password/i.test(this.type));
  2492 		})
  2493 		.map(function(i, elem){
  2494 			var val = jQuery(this).val();
  2495 			return val == null ? null :
  2496 				val.constructor == Array ?
  2497 					jQuery.map( val, function(val, i){
  2498 						return {name: elem.name, value: val};
  2499 					}) :
  2500 					{name: elem.name, value: val};
  2501 		}).get();
  2503 });
  2505 // Attach a bunch of functions for handling common AJAX events
  2506 jQuery.each( "ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","), function(i,o){
  2507 	jQuery.fn[o] = function(f){
  2508 		return this.bind(o, f);
  2509 	};
  2510 });
  2512 var jsc = now();
  2514 jQuery.extend({
  2515 	get: function( url, data, callback, type ) {
  2516 		// shift arguments if data argument was ommited
  2517 		if ( jQuery.isFunction( data ) ) {
  2518 			callback = data;
  2519 			data = null;
  2522 		return jQuery.ajax({
  2523 			type: "GET",
  2524 			url: url,
  2525 			data: data,
  2526 			success: callback,
  2527 			dataType: type
  2528 		});
  2529 	},
  2531 	getScript: function( url, callback ) {
  2532 		return jQuery.get(url, null, callback, "script");
  2533 	},
  2535 	getJSON: function( url, data, callback ) {
  2536 		return jQuery.get(url, data, callback, "json");
  2537 	},
  2539 	post: function( url, data, callback, type ) {
  2540 		if ( jQuery.isFunction( data ) ) {
  2541 			callback = data;
  2542 			data = {};
  2545 		return jQuery.ajax({
  2546 			type: "POST",
  2547 			url: url,
  2548 			data: data,
  2549 			success: callback,
  2550 			dataType: type
  2551 		});
  2552 	},
  2554 	ajaxSetup: function( settings ) {
  2555 		jQuery.extend( jQuery.ajaxSettings, settings );
  2556 	},
  2558 	ajaxSettings: {
  2559 		url: location.href,
  2560 		global: true,
  2561 		type: "GET",
  2562 		timeout: 0,
  2563 		contentType: "application/x-www-form-urlencoded",
  2564 		processData: true,
  2565 		async: true,
  2566 		data: null,
  2567 		username: null,
  2568 		password: null,
  2569 		accepts: {
  2570 			xml: "application/xml, text/xml",
  2571 			html: "text/html",
  2572 			script: "text/javascript, application/javascript",
  2573 			json: "application/json, text/javascript",
  2574 			text: "text/plain",
  2575 			_default: "*/*"
  2577 	},
  2579 	// Last-Modified header cache for next request
  2580 	lastModified: {},
  2582 	ajax: function( s ) {
  2583 		// Extend the settings, but re-extend 's' so that it can be
  2584 		// checked again later (in the test suite, specifically)
  2585 		s = jQuery.extend(true, s, jQuery.extend(true, {}, jQuery.ajaxSettings, s));
  2587 		var jsonp, jsre = /=\?(&|$)/g, status, data,
  2588 			type = s.type.toUpperCase();
  2590 		// convert data if not already a string
  2591 		if ( s.data && s.processData && typeof s.data != "string" )
  2592 			s.data = jQuery.param(s.data);
  2594 		// Handle JSONP Parameter Callbacks
  2595 		if ( s.dataType == "jsonp" ) {
  2596 			if ( type == "GET" ) {
  2597 				if ( !s.url.match(jsre) )
  2598 					s.url += (s.url.match(/\?/) ? "&" : "?") + (s.jsonp || "callback") + "=?";
  2599 			} else if ( !s.data || !s.data.match(jsre) )
  2600 				s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";
  2601 			s.dataType = "json";
  2604 		// Build temporary JSONP function
  2605 		if ( s.dataType == "json" && (s.data && s.data.match(jsre) || s.url.match(jsre)) ) {
  2606 			jsonp = "jsonp" + jsc++;
  2608 			// Replace the =? sequence both in the query string and the data
  2609 			if ( s.data )
  2610 				s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");
  2611 			s.url = s.url.replace(jsre, "=" + jsonp + "$1");
  2613 			// We need to make sure
  2614 			// that a JSONP style response is executed properly
  2615 			s.dataType = "script";
  2617 			// Handle JSONP-style loading
  2618 			window[ jsonp ] = function(tmp){
  2619 				data = tmp;
  2620 				success();
  2621 				complete();
  2622 				// Garbage collect
  2623 				window[ jsonp ] = undefined;
  2624 				try{ delete window[ jsonp ]; } catch(e){}
  2625 				if ( head )
  2626 					head.removeChild( script );
  2627 			};
  2630 		if ( s.dataType == "script" && s.cache == null )
  2631 			s.cache = false;
  2633 		if ( s.cache === false && type == "GET" ) {
  2634 			var ts = now();
  2635 			// try replacing _= if it is there
  2636 			var ret = s.url.replace(/(\?|&)_=.*?(&|$)/, "$1_=" + ts + "$2");
  2637 			// if nothing was replaced, add timestamp to the end
  2638 			s.url = ret + ((ret == s.url) ? (s.url.match(/\?/) ? "&" : "?") + "_=" + ts : "");
  2641 		// If data is available, append data to url for get requests
  2642 		if ( s.data && type == "GET" ) {
  2643 			s.url += (s.url.match(/\?/) ? "&" : "?") + s.data;
  2645 			// IE likes to send both get and post data, prevent this
  2646 			s.data = null;
  2649 		// Watch for a new set of requests
  2650 		if ( s.global && ! jQuery.active++ )
  2651 			jQuery.event.trigger( "ajaxStart" );
  2653 		// Matches an absolute URL, and saves the domain
  2654 		var remote = /^(?:\w+:)?\/\/([^\/?#]+)/;
  2656 		// If we're requesting a remote document
  2657 		// and trying to load JSON or Script with a GET
  2658 		if ( s.dataType == "script" && type == "GET"
  2659 				&& remote.test(s.url) && remote.exec(s.url)[1] != location.host ){
  2660 			var head = document.getElementsByTagName("head")[0];
  2661 			var script = document.createElement("script");
  2662 			script.src = s.url;
  2663 			if (s.scriptCharset)
  2664 				script.charset = s.scriptCharset;
  2666 			// Handle Script loading
  2667 			if ( !jsonp ) {
  2668 				var done = false;
  2670 				// Attach handlers for all browsers
  2671 				script.onload = script.onreadystatechange = function(){
  2672 					if ( !done && (!this.readyState ||
  2673 							this.readyState == "loaded" || this.readyState == "complete") ) {
  2674 						done = true;
  2675 						success();
  2676 						complete();
  2677 						head.removeChild( script );
  2679 				};
  2682 			head.appendChild(script);
  2684 			// We handle everything using the script element injection
  2685 			return undefined;
  2688 		var requestDone = false;
  2690 		// Create the request object; Microsoft failed to properly
  2691 		// implement the XMLHttpRequest in IE7, so we use the ActiveXObject when it is available
  2692 		var xhr = window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
  2694 		// Open the socket
  2695 		// Passing null username, generates a login popup on Opera (#2865)
  2696 		if( s.username )
  2697 			xhr.open(type, s.url, s.async, s.username, s.password);
  2698 		else
  2699 			xhr.open(type, s.url, s.async);
  2701 		// Need an extra try/catch for cross domain requests in Firefox 3
  2702 		try {
  2703 			// Set the correct header, if data is being sent
  2704 			if ( s.data )
  2705 				xhr.setRequestHeader("Content-Type", s.contentType);
  2707 			// Set the If-Modified-Since header, if ifModified mode.
  2708 			if ( s.ifModified )
  2709 				xhr.setRequestHeader("If-Modified-Since",
  2710 					jQuery.lastModified[s.url] || "Thu, 01 Jan 1970 00:00:00 GMT" );
  2712 			// Set header so the called script knows that it's an XMLHttpRequest
  2713 			xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
  2715 			// Set the Accepts header for the server, depending on the dataType
  2716 			xhr.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ?
  2717 				s.accepts[ s.dataType ] + ", */*" :
  2718 				s.accepts._default );
  2719 		} catch(e){}
  2721 		// Allow custom headers/mimetypes
  2722 		if ( s.beforeSend && s.beforeSend(xhr, s) === false ) {
  2723 			// cleanup active request counter
  2724 			s.global && jQuery.active--;
  2725 			// close opended socket
  2726 			xhr.abort();
  2727 			return false;
  2730 		if ( s.global )
  2731 			jQuery.event.trigger("ajaxSend", [xhr, s]);
  2733 		// Wait for a response to come back
  2734 		var onreadystatechange = function(isTimeout){
  2735 			// The transfer is complete and the data is available, or the request timed out
  2736 			if ( !requestDone && xhr && (xhr.readyState == 4 || isTimeout == "timeout") ) {
  2737 				requestDone = true;
  2739 				// clear poll interval
  2740 				if (ival) {
  2741 					clearInterval(ival);
  2742 					ival = null;
  2745 				status = isTimeout == "timeout" && "timeout" ||
  2746 					!jQuery.httpSuccess( xhr ) && "error" ||
  2747 					s.ifModified && jQuery.httpNotModified( xhr, s.url ) && "notmodified" ||
  2748 					"success";
  2750 				if ( status == "success" ) {
  2751 					// Watch for, and catch, XML document parse errors
  2752 					try {
  2753 						// process the data (runs the xml through httpData regardless of callback)
  2754 						data = jQuery.httpData( xhr, s.dataType, s.dataFilter );
  2755 					} catch(e) {
  2756 						status = "parsererror";
  2760 				// Make sure that the request was successful or notmodified
  2761 				if ( status == "success" ) {
  2762 					// Cache Last-Modified header, if ifModified mode.
  2763 					var modRes;
  2764 					try {
  2765 						modRes = xhr.getResponseHeader("Last-Modified");
  2766 					} catch(e) {} // swallow exception thrown by FF if header is not available
  2768 					if ( s.ifModified && modRes )
  2769 						jQuery.lastModified[s.url] = modRes;
  2771 					// JSONP handles its own success callback
  2772 					if ( !jsonp )
  2773 						success();
  2774 				} else
  2775 					jQuery.handleError(s, xhr, status);
  2777 				// Fire the complete handlers
  2778 				complete();
  2780 				// Stop memory leaks
  2781 				if ( s.async )
  2782 					xhr = null;
  2784 		};
  2786 		if ( s.async ) {
  2787 			// don't attach the handler to the request, just poll it instead
  2788 			var ival = setInterval(onreadystatechange, 13);
  2790 			// Timeout checker
  2791 			if ( s.timeout > 0 )
  2792 				setTimeout(function(){
  2793 					// Check to see if the request is still happening
  2794 					if ( xhr ) {
  2795 						// Cancel the request
  2796 						xhr.abort();
  2798 						if( !requestDone )
  2799 							onreadystatechange( "timeout" );
  2801 				}, s.timeout);
  2804 		// Send the data
  2805 		try {
  2806 			xhr.send(s.data);
  2807 		} catch(e) {
  2808 			jQuery.handleError(s, xhr, null, e);
  2811 		// firefox 1.5 doesn't fire statechange for sync requests
  2812 		if ( !s.async )
  2813 			onreadystatechange();
  2815 		function success(){
  2816 			// If a local callback was specified, fire it and pass it the data
  2817 			if ( s.success )
  2818 				s.success( data, status );
  2820 			// Fire the global callback
  2821 			if ( s.global )
  2822 				jQuery.event.trigger( "ajaxSuccess", [xhr, s] );
  2825 		function complete(){
  2826 			// Process result
  2827 			if ( s.complete )
  2828 				s.complete(xhr, status);
  2830 			// The request was completed
  2831 			if ( s.global )
  2832 				jQuery.event.trigger( "ajaxComplete", [xhr, s] );
  2834 			// Handle the global AJAX counter
  2835 			if ( s.global && ! --jQuery.active )
  2836 				jQuery.event.trigger( "ajaxStop" );
  2839 		// return XMLHttpRequest to allow aborting the request etc.
  2840 		return xhr;
  2841 	},
  2843 	handleError: function( s, xhr, status, e ) {
  2844 		// If a local callback was specified, fire it
  2845 		if ( s.error ) s.error( xhr, status, e );
  2847 		// Fire the global callback
  2848 		if ( s.global )
  2849 			jQuery.event.trigger( "ajaxError", [xhr, s, e] );
  2850 	},
  2852 	// Counter for holding the number of active queries
  2853 	active: 0,
  2855 	// Determines if an XMLHttpRequest was successful or not
  2856 	httpSuccess: function( xhr ) {
  2857 		try {
  2858 			// IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450
  2859 			return !xhr.status && location.protocol == "file:" ||
  2860 				( xhr.status >= 200 && xhr.status < 300 ) || xhr.status == 304 || xhr.status == 1223 ||
  2861 				jQuery.browser.safari && xhr.status == undefined;
  2862 		} catch(e){}
  2863 		return false;
  2864 	},
  2866 	// Determines if an XMLHttpRequest returns NotModified
  2867 	httpNotModified: function( xhr, url ) {
  2868 		try {
  2869 			var xhrRes = xhr.getResponseHeader("Last-Modified");
  2871 			// Firefox always returns 200. check Last-Modified date
  2872 			return xhr.status == 304 || xhrRes == jQuery.lastModified[url] ||
  2873 				jQuery.browser.safari && xhr.status == undefined;
  2874 		} catch(e){}
  2875 		return false;
  2876 	},
  2878 	httpData: function( xhr, type, filter ) {
  2879 		var ct = xhr.getResponseHeader("content-type"),
  2880 			xml = type == "xml" || !type && ct && ct.indexOf("xml") >= 0,
  2881 			data = xml ? xhr.responseXML : xhr.responseText;
  2883 		if ( xml && data.documentElement.tagName == "parsererror" )
  2884 			throw "parsererror";
  2886 		// Allow a pre-filtering function to sanitize the response
  2887 		if( filter )
  2888 			data = filter( data, type );
  2890 		// If the type is "script", eval it in global context
  2891 		if ( type == "script" )
  2892 			jQuery.globalEval( data );
  2894 		// Get the JavaScript object, if JSON is used.
  2895 		if ( type == "json" )
  2896 			data = eval("(" + data + ")");
  2898 		return data;
  2899 	},
  2901 	// Serialize an array of form elements or a set of
  2902 	// key/values into a query string
  2903 	param: function( a ) {
  2904 		var s = [];
  2906 		// If an array was passed in, assume that it is an array
  2907 		// of form elements
  2908 		if ( a.constructor == Array || a.jquery )
  2909 			// Serialize the form elements
  2910 			jQuery.each( a, function(){
  2911 				s.push( encodeURIComponent(this.name) + "=" + encodeURIComponent( this.value ) );
  2912 			});
  2914 		// Otherwise, assume that it's an object of key/value pairs
  2915 		else
  2916 			// Serialize the key/values
  2917 			for ( var j in a )
  2918 				// If the value is an array then the key names need to be repeated
  2919 				if ( a[j] && a[j].constructor == Array )
  2920 					jQuery.each( a[j], function(){
  2921 						s.push( encodeURIComponent(j) + "=" + encodeURIComponent( this ) );
  2922 					});
  2923 				else
  2924 					s.push( encodeURIComponent(j) + "=" + encodeURIComponent( jQuery.isFunction(a[j]) ? a[j]() : a[j] ) );
  2926 		// Return the resulting serialization
  2927 		return s.join("&").replace(/%20/g, "+");
  2930 });
  2931 jQuery.fn.extend({
  2932 	show: function(speed,callback){
  2933 		return speed ?
  2934 			this.animate({
  2935 				height: "show", width: "show", opacity: "show"
  2936 			}, speed, callback) :
  2938 			this.filter(":hidden").each(function(){
  2939 				this.style.display = this.oldblock || "";
  2940 				if ( jQuery.css(this,"display") == "none" ) {
  2941 					var elem = jQuery("<" + this.tagName + " />").appendTo("body");
  2942 					this.style.display = elem.css("display");
  2943 					// handle an edge condition where css is - div { display:none; } or similar
  2944 					if (this.style.display == "none")
  2945 						this.style.display = "block";
  2946 					elem.remove();
  2948 			}).end();
  2949 	},
  2951 	hide: function(speed,callback){
  2952 		return speed ?
  2953 			this.animate({
  2954 				height: "hide", width: "hide", opacity: "hide"
  2955 			}, speed, callback) :
  2957 			this.filter(":visible").each(function(){
  2958 				this.oldblock = this.oldblock || jQuery.css(this,"display");
  2959 				this.style.display = "none";
  2960 			}).end();
  2961 	},
  2963 	// Save the old toggle function
  2964 	_toggle: jQuery.fn.toggle,
  2966 	toggle: function( fn, fn2 ){
  2967 		return jQuery.isFunction(fn) && jQuery.isFunction(fn2) ?
  2968 			this._toggle.apply( this, arguments ) :
  2969 			fn ?
  2970 				this.animate({
  2971 					height: "toggle", width: "toggle", opacity: "toggle"
  2972 				}, fn, fn2) :
  2973 				this.each(function(){
  2974 					jQuery(this)[ jQuery(this).is(":hidden") ? "show" : "hide" ]();
  2975 				});
  2976 	},
  2978 	slideDown: function(speed,callback){
  2979 		return this.animate({height: "show"}, speed, callback);
  2980 	},
  2982 	slideUp: function(speed,callback){
  2983 		return this.animate({height: "hide"}, speed, callback);
  2984 	},
  2986 	slideToggle: function(speed, callback){
  2987 		return this.animate({height: "toggle"}, speed, callback);
  2988 	},
  2990 	fadeIn: function(speed, callback){
  2991 		return this.animate({opacity: "show"}, speed, callback);
  2992 	},
  2994 	fadeOut: function(speed, callback){
  2995 		return this.animate({opacity: "hide"}, speed, callback);
  2996 	},
  2998 	fadeTo: function(speed,to,callback){
  2999 		return this.animate({opacity: to}, speed, callback);
  3000 	},
  3002 	animate: function( prop, speed, easing, callback ) {
  3003 		var optall = jQuery.speed(speed, easing, callback);
  3005 		return this[ optall.queue === false ? "each" : "queue" ](function(){
  3006 			if ( this.nodeType != 1)
  3007 				return false;
  3009 			var opt = jQuery.extend({}, optall), p,
  3010 				hidden = jQuery(this).is(":hidden"), self = this;
  3012 			for ( p in prop ) {
  3013 				if ( prop[p] == "hide" && hidden || prop[p] == "show" && !hidden )
  3014 					return opt.complete.call(this);
  3016 				if ( p == "height" || p == "width" ) {
  3017 					// Store display property
  3018 					opt.display = jQuery.css(this, "display");
  3020 					// Make sure that nothing sneaks out
  3021 					opt.overflow = this.style.overflow;
  3025 			if ( opt.overflow != null )
  3026 				this.style.overflow = "hidden";
  3028 			opt.curAnim = jQuery.extend({}, prop);
  3030 			jQuery.each( prop, function(name, val){
  3031 				var e = new jQuery.fx( self, opt, name );
  3033 				if ( /toggle|show|hide/.test(val) )
  3034 					e[ val == "toggle" ? hidden ? "show" : "hide" : val ]( prop );
  3035 				else {
  3036 					var parts = val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),
  3037 						start = e.cur(true) || 0;
  3039 					if ( parts ) {
  3040 						var end = parseFloat(parts[2]),
  3041 							unit = parts[3] || "px";
  3043 						// We need to compute starting value
  3044 						if ( unit != "px" ) {
  3045 							self.style[ name ] = (end || 1) + unit;
  3046 							start = ((end || 1) / e.cur(true)) * start;
  3047 							self.style[ name ] = start + unit;
  3050 						// If a +=/-= token was provided, we're doing a relative animation
  3051 						if ( parts[1] )
  3052 							end = ((parts[1] == "-=" ? -1 : 1) * end) + start;
  3054 						e.custom( start, end, unit );
  3055 					} else
  3056 						e.custom( start, val, "" );
  3058 			});
  3060 			// For JS strict compliance
  3061 			return true;
  3062 		});
  3063 	},
  3065 	queue: function(type, fn){
  3066 		if ( jQuery.isFunction(type) || ( type && type.constructor == Array )) {
  3067 			fn = type;
  3068 			type = "fx";
  3071 		if ( !type || (typeof type == "string" && !fn) )
  3072 			return queue( this[0], type );
  3074 		return this.each(function(){
  3075 			if ( fn.constructor == Array )
  3076 				queue(this, type, fn);
  3077 			else {
  3078 				queue(this, type).push( fn );
  3080 				if ( queue(this, type).length == 1 )
  3081 					fn.call(this);
  3083 		});
  3084 	},
  3086 	stop: function(clearQueue, gotoEnd){
  3087 		var timers = jQuery.timers;
  3089 		if (clearQueue)
  3090 			this.queue([]);
  3092 		this.each(function(){
  3093 			// go in reverse order so anything added to the queue during the loop is ignored
  3094 			for ( var i = timers.length - 1; i >= 0; i-- )
  3095 				if ( timers[i].elem == this ) {
  3096 					if (gotoEnd)
  3097 						// force the next step to be the last
  3098 						timers[i](true);
  3099 					timers.splice(i, 1);
  3101 		});
  3103 		// start the next in the queue if the last step wasn't forced
  3104 		if (!gotoEnd)
  3105 			this.dequeue();
  3107 		return this;
  3110 });
  3112 var queue = function( elem, type, array ) {
  3113 	if ( elem ){
  3115 		type = type || "fx";
  3117 		var q = jQuery.data( elem, type + "queue" );
  3119 		if ( !q || array )
  3120 			q = jQuery.data( elem, type + "queue", jQuery.makeArray(array) );
  3123 	return q;
  3124 };
  3126 jQuery.fn.dequeue = function(type){
  3127 	type = type || "fx";
  3129 	return this.each(function(){
  3130 		var q = queue(this, type);
  3132 		q.shift();
  3134 		if ( q.length )
  3135 			q[0].call( this );
  3136 	});
  3137 };
  3139 jQuery.extend({
  3141 	speed: function(speed, easing, fn) {
  3142 		var opt = speed && speed.constructor == Object ? speed : {
  3143 			complete: fn || !fn && easing ||
  3144 				jQuery.isFunction( speed ) && speed,
  3145 			duration: speed,
  3146 			easing: fn && easing || easing && easing.constructor != Function && easing
  3147 		};
  3149 		opt.duration = (opt.duration && opt.duration.constructor == Number ?
  3150 			opt.duration :
  3151 			jQuery.fx.speeds[opt.duration]) || jQuery.fx.speeds.def;
  3153 		// Queueing
  3154 		opt.old = opt.complete;
  3155 		opt.complete = function(){
  3156 			if ( opt.queue !== false )
  3157 				jQuery(this).dequeue();
  3158 			if ( jQuery.isFunction( opt.old ) )
  3159 				opt.old.call( this );
  3160 		};
  3162 		return opt;
  3163 	},
  3165 	easing: {
  3166 		linear: function( p, n, firstNum, diff ) {
  3167 			return firstNum + diff * p;
  3168 		},
  3169 		swing: function( p, n, firstNum, diff ) {
  3170 			return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
  3172 	},
  3174 	timers: [],
  3175 	timerId: null,
  3177 	fx: function( elem, options, prop ){
  3178 		this.options = options;
  3179 		this.elem = elem;
  3180 		this.prop = prop;
  3182 		if ( !options.orig )
  3183 			options.orig = {};
  3186 });
  3188 jQuery.fx.prototype = {
  3190 	// Simple function for setting a style value
  3191 	update: function(){
  3192 		if ( this.options.step )
  3193 			this.options.step.call( this.elem, this.now, this );
  3195 		(jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
  3197 		// Set display property to block for height/width animations
  3198 		if ( this.prop == "height" || this.prop == "width" )
  3199 			this.elem.style.display = "block";
  3200 	},
  3202 	// Get the current size
  3203 	cur: function(force){
  3204 		if ( this.elem[this.prop] != null && this.elem.style[this.prop] == null )
  3205 			return this.elem[ this.prop ];
  3207 		var r = parseFloat(jQuery.css(this.elem, this.prop, force));
  3208 		return r && r > -10000 ? r : parseFloat(jQuery.curCSS(this.elem, this.prop)) || 0;
  3209 	},
  3211 	// Start an animation from one number to another
  3212 	custom: function(from, to, unit){
  3213 		this.startTime = now();
  3214 		this.start = from;
  3215 		this.end = to;
  3216 		this.unit = unit || this.unit || "px";
  3217 		this.now = this.start;
  3218 		this.pos = this.state = 0;
  3219 		this.update();
  3221 		var self = this;
  3222 		function t(gotoEnd){
  3223 			return self.step(gotoEnd);
  3226 		t.elem = this.elem;
  3228 		jQuery.timers.push(t);
  3230 		if ( jQuery.timerId == null ) {
  3231 			jQuery.timerId = setInterval(function(){
  3232 				var timers = jQuery.timers;
  3234 				for ( var i = 0; i < timers.length; i++ )
  3235 					if ( !timers[i]() )
  3236 						timers.splice(i--, 1);
  3238 				if ( !timers.length ) {
  3239 					clearInterval( jQuery.timerId );
  3240 					jQuery.timerId = null;
  3242 			}, 13);
  3244 	},
  3246 	// Simple 'show' function
  3247 	show: function(){
  3248 		// Remember where we started, so that we can go back to it later
  3249 		this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );
  3250 		this.options.show = true;
  3252 		// Begin the animation
  3253 		this.custom(0, this.cur());
  3255 		// Make sure that we start at a small width/height to avoid any
  3256 		// flash of content
  3257 		if ( this.prop == "width" || this.prop == "height" )
  3258 			this.elem.style[this.prop] = "1px";
  3260 		// Start by showing the element
  3261 		jQuery(this.elem).show();
  3262 	},
  3264 	// Simple 'hide' function
  3265 	hide: function(){
  3266 		// Remember where we started, so that we can go back to it later
  3267 		this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );
  3268 		this.options.hide = true;
  3270 		// Begin the animation
  3271 		this.custom(this.cur(), 0);
  3272 	},
  3274 	// Each step of an animation
  3275 	step: function(gotoEnd){
  3276 		var t = now();
  3278 		if ( gotoEnd || t > this.options.duration + this.startTime ) {
  3279 			this.now = this.end;
  3280 			this.pos = this.state = 1;
  3281 			this.update();
  3283 			this.options.curAnim[ this.prop ] = true;
  3285 			var done = true;
  3286 			for ( var i in this.options.curAnim )
  3287 				if ( this.options.curAnim[i] !== true )
  3288 					done = false;
  3290 			if ( done ) {
  3291 				if ( this.options.display != null ) {
  3292 					// Reset the overflow
  3293 					this.elem.style.overflow = this.options.overflow;
  3295 					// Reset the display
  3296 					this.elem.style.display = this.options.display;
  3297 					if ( jQuery.css(this.elem, "display") == "none" )
  3298 						this.elem.style.display = "block";
  3301 				// Hide the element if the "hide" operation was done
  3302 				if ( this.options.hide )
  3303 					this.elem.style.display = "none";
  3305 				// Reset the properties, if the item has been hidden or shown
  3306 				if ( this.options.hide || this.options.show )
  3307 					for ( var p in this.options.curAnim )
  3308 						jQuery.attr(this.elem.style, p, this.options.orig[p]);
  3311 			if ( done )
  3312 				// Execute the complete function
  3313 				this.options.complete.call( this.elem );
  3315 			return false;
  3316 		} else {
  3317 			var n = t - this.startTime;
  3318 			this.state = n / this.options.duration;
  3320 			// Perform the easing function, defaults to swing
  3321 			this.pos = jQuery.easing[this.options.easing || (jQuery.easing.swing ? "swing" : "linear")](this.state, n, 0, 1, this.options.duration);
  3322 			this.now = this.start + ((this.end - this.start) * this.pos);
  3324 			// Perform the next step of the animation
  3325 			this.update();
  3328 		return true;
  3331 };
  3333 jQuery.extend( jQuery.fx, {
  3334 	speeds:{
  3335 		slow: 600,
  3336  		fast: 200,
  3337  		// Default speed
  3338  		def: 400
  3339 	},
  3340 	step: {
  3341 		scrollLeft: function(fx){
  3342 			fx.elem.scrollLeft = fx.now;
  3343 		},
  3345 		scrollTop: function(fx){
  3346 			fx.elem.scrollTop = fx.now;
  3347 		},
  3349 		opacity: function(fx){
  3350 			jQuery.attr(fx.elem.style, "opacity", fx.now);
  3351 		},
  3353 		_default: function(fx){
  3354 			fx.elem.style[ fx.prop ] = fx.now + fx.unit;
  3357 });
  3358 // The Offset Method
  3359 // Originally By Brandon Aaron, part of the Dimension Plugin
  3360 // http://jquery.com/plugins/project/dimensions
  3361 jQuery.fn.offset = function() {
  3362 	var left = 0, top = 0, elem = this[0], results;
  3364 	if ( elem ) with ( jQuery.browser ) {
  3365 		var parent       = elem.parentNode,
  3366 		    offsetChild  = elem,
  3367 		    offsetParent = elem.offsetParent,
  3368 		    doc          = elem.ownerDocument,
  3369 		    safari2      = safari && parseInt(version) < 522 && !/adobeair/i.test(userAgent),
  3370 		    css          = jQuery.curCSS,
  3371 		    fixed        = css(elem, "position") == "fixed";
  3373 		// Use getBoundingClientRect if available
  3374 		if ( elem.getBoundingClientRect ) {
  3375 			var box = elem.getBoundingClientRect();
  3377 			// Add the document scroll offsets
  3378 			add(box.left + Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft),
  3379 				box.top  + Math.max(doc.documentElement.scrollTop,  doc.body.scrollTop));
  3381 			// IE adds the HTML element's border, by default it is medium which is 2px
  3382 			// IE 6 and 7 quirks mode the border width is overwritable by the following css html { border: 0; }
  3383 			// IE 7 standards mode, the border is always 2px
  3384 			// This border/offset is typically represented by the clientLeft and clientTop properties
  3385 			// However, in IE6 and 7 quirks mode the clientLeft and clientTop properties are not updated when overwriting it via CSS
  3386 			// Therefore this method will be off by 2px in IE while in quirksmode
  3387 			add( -doc.documentElement.clientLeft, -doc.documentElement.clientTop );
  3389 		// Otherwise loop through the offsetParents and parentNodes
  3390 		} else {
  3392 			// Initial element offsets
  3393 			add( elem.offsetLeft, elem.offsetTop );
  3395 			// Get parent offsets
  3396 			while ( offsetParent ) {
  3397 				// Add offsetParent offsets
  3398 				add( offsetParent.offsetLeft, offsetParent.offsetTop );
  3400 				// Mozilla and Safari > 2 does not include the border on offset parents
  3401 				// However Mozilla adds the border for table or table cells
  3402 				if ( mozilla && !/^t(able|d|h)$/i.test(offsetParent.tagName) || safari && !safari2 )
  3403 					border( offsetParent );
  3405 				// Add the document scroll offsets if position is fixed on any offsetParent
  3406 				if ( !fixed && css(offsetParent, "position") == "fixed" )
  3407 					fixed = true;
  3409 				// Set offsetChild to previous offsetParent unless it is the body element
  3410 				offsetChild  = /^body$/i.test(offsetParent.tagName) ? offsetChild : offsetParent;
  3411 				// Get next offsetParent
  3412 				offsetParent = offsetParent.offsetParent;
  3415 			// Get parent scroll offsets
  3416 			while ( parent && parent.tagName && !/^body|html$/i.test(parent.tagName) ) {
  3417 				// Remove parent scroll UNLESS that parent is inline or a table to work around Opera inline/table scrollLeft/Top bug
  3418 				if ( !/^inline|table.*$/i.test(css(parent, "display")) )
  3419 					// Subtract parent scroll offsets
  3420 					add( -parent.scrollLeft, -parent.scrollTop );
  3422 				// Mozilla does not add the border for a parent that has overflow != visible
  3423 				if ( mozilla && css(parent, "overflow") != "visible" )
  3424 					border( parent );
  3426 				// Get next parent
  3427 				parent = parent.parentNode;
  3430 			// Safari <= 2 doubles body offsets with a fixed position element/offsetParent or absolutely positioned offsetChild
  3431 			// Mozilla doubles body offsets with a non-absolutely positioned offsetChild
  3432 			if ( (safari2 && (fixed || css(offsetChild, "position") == "absolute")) ||
  3433 				(mozilla && css(offsetChild, "position") != "absolute") )
  3434 					add( -doc.body.offsetLeft, -doc.body.offsetTop );
  3436 			// Add the document scroll offsets if position is fixed
  3437 			if ( fixed )
  3438 				add(Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft),
  3439 					Math.max(doc.documentElement.scrollTop,  doc.body.scrollTop));
  3442 		// Return an object with top and left properties
  3443 		results = { top: top, left: left };
  3446 	function border(elem) {
  3447 		add( jQuery.curCSS(elem, "borderLeftWidth", true), jQuery.curCSS(elem, "borderTopWidth", true) );
  3450 	function add(l, t) {
  3451 		left += parseInt(l, 10) || 0;
  3452 		top += parseInt(t, 10) || 0;
  3455 	return results;
  3456 };
  3459 jQuery.fn.extend({
  3460 	position: function() {
  3461 		var left = 0, top = 0, results;
  3463 		if ( this[0] ) {
  3464 			// Get *real* offsetParent
  3465 			var offsetParent = this.offsetParent(),
  3467 			// Get correct offsets
  3468 			offset       = this.offset(),
  3469 			parentOffset = /^body|html$/i.test(offsetParent[0].tagName) ? { top: 0, left: 0 } : offsetParent.offset();
  3471 			// Subtract element margins
  3472 			// note: when an element has margin: auto the offsetLeft and marginLeft 
  3473 			// are the same in Safari causing offset.left to incorrectly be 0
  3474 			offset.top  -= num( this, 'marginTop' );
  3475 			offset.left -= num( this, 'marginLeft' );
  3477 			// Add offsetParent borders
  3478 			parentOffset.top  += num( offsetParent, 'borderTopWidth' );
  3479 			parentOffset.left += num( offsetParent, 'borderLeftWidth' );
  3481 			// Subtract the two offsets
  3482 			results = {
  3483 				top:  offset.top  - parentOffset.top,
  3484 				left: offset.left - parentOffset.left
  3485 			};
  3488 		return results;
  3489 	},
  3491 	offsetParent: function() {
  3492 		var offsetParent = this[0].offsetParent;
  3493 		while ( offsetParent && (!/^body|html$/i.test(offsetParent.tagName) && jQuery.css(offsetParent, 'position') == 'static') )
  3494 			offsetParent = offsetParent.offsetParent;
  3495 		return jQuery(offsetParent);
  3497 });
  3500 // Create scrollLeft and scrollTop methods
  3501 jQuery.each( ['Left', 'Top'], function(i, name) {
  3502 	var method = 'scroll' + name;
  3504 	jQuery.fn[ method ] = function(val) {
  3505 		if (!this[0]) return;
  3507 		return val != undefined ?
  3509 			// Set the scroll offset
  3510 			this.each(function() {
  3511 				this == window || this == document ?
  3512 					window.scrollTo(
  3513 						!i ? val : jQuery(window).scrollLeft(),
  3514 						 i ? val : jQuery(window).scrollTop()
  3515 					) :
  3516 					this[ method ] = val;
  3517 			}) :
  3519 			// Return the scroll offset
  3520 			this[0] == window || this[0] == document ?
  3521 				self[ i ? 'pageYOffset' : 'pageXOffset' ] ||
  3522 					jQuery.boxModel && document.documentElement[ method ] ||
  3523 					document.body[ method ] :
  3524 				this[0][ method ];
  3525 	};
  3526 });
  3527 // Create innerHeight, innerWidth, outerHeight and outerWidth methods
  3528 jQuery.each([ "Height", "Width" ], function(i, name){
  3530 	var tl = i ? "Left"  : "Top",  // top or left
  3531 		br = i ? "Right" : "Bottom"; // bottom or right
  3533 	// innerHeight and innerWidth
  3534 	jQuery.fn["inner" + name] = function(){
  3535 		return this[ name.toLowerCase() ]() +
  3536 			num(this, "padding" + tl) +
  3537 			num(this, "padding" + br);
  3538 	};
  3540 	// outerHeight and outerWidth
  3541 	jQuery.fn["outer" + name] = function(margin) {
  3542 		return this["inner" + name]() +
  3543 			num(this, "border" + tl + "Width") +
  3544 			num(this, "border" + br + "Width") +
  3545 			(margin ?
  3546 				num(this, "margin" + tl) + num(this, "margin" + br) : 0);
  3547 	};
  3549 });})();

mercurial