fhiiqm/js/jquery/jquery.js
changeset 1 6288d5685bff
equal deleted inserted replaced
0:ef68113ff309 1:6288d5685bff
       
     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-27 21:17:26 +0200 (Di, 27 Mai 2008) $
       
    10  * $Rev: 5700 $
       
    11  */
       
    12 
       
    13 // Map over jQuery in case of overwrite
       
    14 var _jQuery = window.jQuery,
       
    15 // Map over the $ in case of overwrite
       
    16 	_$ = window.$;
       
    17 
       
    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 };
       
    22 
       
    23 // A simple way to check for HTML strings or ID strings
       
    24 // (both of which we optimize for)
       
    25 var quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/,
       
    26 
       
    27 // Is it a simple selector
       
    28 	isSimple = /^.[^:#\[\.]*$/,
       
    29 
       
    30 // Will speed up references to undefined, and allows munging its name.
       
    31 	undefined;
       
    32 
       
    33 jQuery.fn = jQuery.prototype = {
       
    34 	init: function( selector, context ) {
       
    35 		// Make sure that a selection was provided
       
    36 		selector = selector || document;
       
    37 
       
    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 );
       
    48 
       
    49 			// Verify a match, and that no context was specified for #id
       
    50 			if ( match && (match[1] || !context) ) {
       
    51 
       
    52 				// HANDLE: $(html) -> $(array)
       
    53 				if ( match[1] )
       
    54 					selector = jQuery.clean( [ match[1] ], context );
       
    55 
       
    56 				// HANDLE: $("#id")
       
    57 				else {
       
    58 					var elem = document.getElementById( match[3] );
       
    59 
       
    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 );
       
    66 
       
    67 						// Otherwise, we inject the element directly into the jQuery object
       
    68 						return jQuery( elem );
       
    69 					}
       
    70 					selector = [];
       
    71 				}
       
    72 
       
    73 			// HANDLE: $(expr, [context])
       
    74 			// (which is just equivalent to: $(content).find(expr)
       
    75 			} else
       
    76 				return jQuery( context ).find( selector );
       
    77 
       
    78 		// HANDLE: $(function)
       
    79 		// Shortcut for document ready
       
    80 		} else if ( jQuery.isFunction( selector ) )
       
    81 			return jQuery( document )[ jQuery.fn.ready ? "ready" : "load" ]( selector );
       
    82 
       
    83 		return this.setArray(jQuery.makeArray(selector));
       
    84 	},
       
    85 
       
    86 	// The current version of jQuery being used
       
    87 	jquery: "1.2.6",
       
    88 
       
    89 	// The number of elements contained in the matched element set
       
    90 	size: function() {
       
    91 		return this.length;
       
    92 	},
       
    93 
       
    94 	// The number of elements contained in the matched element set
       
    95 	length: 0,
       
    96 
       
    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 ?
       
   101 
       
   102 			// Return a 'clean' array
       
   103 			jQuery.makeArray( this ) :
       
   104 
       
   105 			// Return just the object
       
   106 			this[ num ];
       
   107 	},
       
   108 
       
   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 );
       
   114 
       
   115 		// Add the old object onto the stack (as a reference)
       
   116 		ret.prevObject = this;
       
   117 
       
   118 		// Return the newly-formed element set
       
   119 		return ret;
       
   120 	},
       
   121 
       
   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 );
       
   130 
       
   131 		return this;
       
   132 	},
       
   133 
       
   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 	},
       
   140 
       
   141 	// Determine the position of an element within
       
   142 	// the matched set of elements
       
   143 	index: function( elem ) {
       
   144 		var ret = -1;
       
   145 
       
   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 	},
       
   152 
       
   153 	attr: function( name, value, type ) {
       
   154 		var options = name;
       
   155 
       
   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 );
       
   160 
       
   161 			else {
       
   162 				options = {};
       
   163 				options[ name ] = value;
       
   164 			}
       
   165 
       
   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 	},
       
   178 
       
   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 	},
       
   185 
       
   186 	text: function( text ) {
       
   187 		if ( typeof text != "object" && text != null )
       
   188 			return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
       
   189 
       
   190 		var ret = "";
       
   191 
       
   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 		});
       
   200 
       
   201 		return ret;
       
   202 	},
       
   203 
       
   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;
       
   212 
       
   213 					while ( elem.firstChild )
       
   214 						elem = elem.firstChild;
       
   215 
       
   216 					return elem;
       
   217 				})
       
   218 				.append(this);
       
   219 
       
   220 		return this;
       
   221 	},
       
   222 
       
   223 	wrapInner: function( html ) {
       
   224 		return this.each(function(){
       
   225 			jQuery( this ).contents().wrapAll( html );
       
   226 		});
       
   227 	},
       
   228 
       
   229 	wrap: function( html ) {
       
   230 		return this.each(function(){
       
   231 			jQuery( this ).wrapAll( html );
       
   232 		});
       
   233 	},
       
   234 
       
   235 	append: function() {
       
   236 		return this.domManip(arguments, true, false, function(elem){
       
   237 			if (this.nodeType == 1)
       
   238 				this.appendChild( elem );
       
   239 		});
       
   240 	},
       
   241 
       
   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 	},
       
   248 
       
   249 	before: function() {
       
   250 		return this.domManip(arguments, false, false, function(elem){
       
   251 			this.parentNode.insertBefore( elem, this );
       
   252 		});
       
   253 	},
       
   254 
       
   255 	after: function() {
       
   256 		return this.domManip(arguments, false, true, function(elem){
       
   257 			this.parentNode.insertBefore( elem, this.nextSibling );
       
   258 		});
       
   259 	},
       
   260 
       
   261 	end: function() {
       
   262 		return this.prevObject || jQuery( [] );
       
   263 	},
       
   264 
       
   265 	find: function( selector ) {
       
   266 		var elems = jQuery.map(this, function(elem){
       
   267 			return jQuery.find( selector, elem );
       
   268 		});
       
   269 
       
   270 		return this.pushStack( /[^+>] [^+>]/.test( selector ) || selector.indexOf("..") > -1 ?
       
   271 			jQuery.unique( elems ) :
       
   272 			elems );
       
   273 	},
       
   274 
       
   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 		});
       
   294 
       
   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 		});
       
   302 
       
   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" );
       
   309 
       
   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 			});
       
   314 
       
   315 		// Return the cloned set
       
   316 		return ret;
       
   317 	},
       
   318 
       
   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 			}) ||
       
   325 
       
   326 			jQuery.multiFilter( selector, this ) );
       
   327 	},
       
   328 
       
   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 );
       
   336 
       
   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 	},
       
   342 
       
   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 	},
       
   351 
       
   352 	is: function( selector ) {
       
   353 		return !!selector && jQuery.multiFilter( selector, this ).length > 0;
       
   354 	},
       
   355 
       
   356 	hasClass: function( selector ) {
       
   357 		return this.is( "." + selector );
       
   358 	},
       
   359 
       
   360 	val: function( value ) {
       
   361 		if ( value == undefined ) {
       
   362 
       
   363 			if ( this.length ) {
       
   364 				var elem = this[0];
       
   365 
       
   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";
       
   372 
       
   373 					// Nothing was selected
       
   374 					if ( index < 0 )
       
   375 						return null;
       
   376 
       
   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 ];
       
   380 
       
   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;
       
   384 
       
   385 							// We don't need an array for one selects
       
   386 							if ( one )
       
   387 								return value;
       
   388 
       
   389 							// Multi-Selects return an array
       
   390 							values.push( value );
       
   391 						}
       
   392 					}
       
   393 
       
   394 					return values;
       
   395 
       
   396 				// Everything else, we just grab the value
       
   397 				} else
       
   398 					return (this[0].value || "").replace(/\r/g, "");
       
   399 
       
   400 			}
       
   401 
       
   402 			return undefined;
       
   403 		}
       
   404 
       
   405 		if( value.constructor == Number )
       
   406 			value += '';
       
   407 
       
   408 		return this.each(function(){
       
   409 			if ( this.nodeType != 1 )
       
   410 				return;
       
   411 
       
   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);
       
   415 
       
   416 			else if ( jQuery.nodeName( this, "select" ) ) {
       
   417 				var values = jQuery.makeArray(value);
       
   418 
       
   419 				jQuery( "option", this ).each(function(){
       
   420 					this.selected = (jQuery.inArray( this.value, values ) >= 0 ||
       
   421 						jQuery.inArray( this.text, values ) >= 0);
       
   422 				});
       
   423 
       
   424 				if ( !values.length )
       
   425 					this.selectedIndex = -1;
       
   426 
       
   427 			} else
       
   428 				this.value = value;
       
   429 		});
       
   430 	},
       
   431 
       
   432 	html: function( value ) {
       
   433 		return value == undefined ?
       
   434 			(this[0] ?
       
   435 				this[0].innerHTML :
       
   436 				null) :
       
   437 			this.empty().append( value );
       
   438 	},
       
   439 
       
   440 	replaceWith: function( value ) {
       
   441 		return this.after( value ).remove();
       
   442 	},
       
   443 
       
   444 	eq: function( i ) {
       
   445 		return this.slice( i, i + 1 );
       
   446 	},
       
   447 
       
   448 	slice: function() {
       
   449 		return this.pushStack( Array.prototype.slice.apply( this, arguments ) );
       
   450 	},
       
   451 
       
   452 	map: function( callback ) {
       
   453 		return this.pushStack( jQuery.map(this, function(elem, i){
       
   454 			return callback.call( elem, i, elem );
       
   455 		}));
       
   456 	},
       
   457 
       
   458 	andSelf: function() {
       
   459 		return this.add( this.prevObject );
       
   460 	},
       
   461 
       
   462 	data: function( key, value ){
       
   463 		var parts = key.split(".");
       
   464 		parts[1] = parts[1] ? "." + parts[1] : "";
       
   465 
       
   466 		if ( value === undefined ) {
       
   467 			var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
       
   468 
       
   469 			if ( data === undefined && this.length )
       
   470 				data = jQuery.data( this[0], key );
       
   471 
       
   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 	},
       
   480 
       
   481 	removeData: function( key ){
       
   482 		return this.each(function(){
       
   483 			jQuery.removeData( this, key );
       
   484 		});
       
   485 	},
       
   486 
       
   487 	domManip: function( args, table, reverse, callback ) {
       
   488 		var clone = this.length > 1, elems;
       
   489 
       
   490 		return this.each(function(){
       
   491 			if ( !elems ) {
       
   492 				elems = jQuery.clean( args, this.ownerDocument );
       
   493 
       
   494 				if ( reverse )
       
   495 					elems.reverse();
       
   496 			}
       
   497 
       
   498 			var obj = this;
       
   499 
       
   500 			if ( table && jQuery.nodeName( this, "table" ) && jQuery.nodeName( elems[0], "tr" ) )
       
   501 				obj = this.getElementsByTagName("tbody")[0] || this.appendChild( this.ownerDocument.createElement("tbody") );
       
   502 
       
   503 			var scripts = jQuery( [] );
       
   504 
       
   505 			jQuery.each(elems, function(){
       
   506 				var elem = clone ?
       
   507 					jQuery( this ).clone( true )[0] :
       
   508 					this;
       
   509 
       
   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() );
       
   517 
       
   518 					// Inject the elements into the document
       
   519 					callback.call( obj, elem );
       
   520 				}
       
   521 			});
       
   522 
       
   523 			scripts.each( evalScript );
       
   524 		});
       
   525 	}
       
   526 };
       
   527 
       
   528 // Give the init function the jQuery prototype for later instantiation
       
   529 jQuery.fn.init.prototype = jQuery.fn;
       
   530 
       
   531 function evalScript( i, elem ) {
       
   532 	if ( elem.src )
       
   533 		jQuery.ajax({
       
   534 			url: elem.src,
       
   535 			async: false,
       
   536 			dataType: "script"
       
   537 		});
       
   538 
       
   539 	else
       
   540 		jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
       
   541 
       
   542 	if ( elem.parentNode )
       
   543 		elem.parentNode.removeChild( elem );
       
   544 }
       
   545 
       
   546 function now(){
       
   547 	return +new Date;
       
   548 }
       
   549 
       
   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;
       
   553 
       
   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 	}
       
   561 
       
   562 	// Handle case when target is a string or something (possible in deep copy)
       
   563 	if ( typeof target != "object" && typeof target != "function" )
       
   564 		target = {};
       
   565 
       
   566 	// extend jQuery itself if only one argument is passed
       
   567 	if ( length == i ) {
       
   568 		target = this;
       
   569 		--i;
       
   570 	}
       
   571 
       
   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 ];
       
   578 
       
   579 				// Prevent never-ending loop
       
   580 				if ( target === copy )
       
   581 					continue;
       
   582 
       
   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 );
       
   589 
       
   590 				// Don't bring in undefined values
       
   591 				else if ( copy !== undefined )
       
   592 					target[ name ] = copy;
       
   593 
       
   594 			}
       
   595 
       
   596 	// Return the modified object
       
   597 	return target;
       
   598 };
       
   599 
       
   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 || {};
       
   605 
       
   606 jQuery.extend({
       
   607 	noConflict: function( deep ) {
       
   608 		window.$ = _$;
       
   609 
       
   610 		if ( deep )
       
   611 			window.jQuery = _jQuery;
       
   612 
       
   613 		return jQuery;
       
   614 	},
       
   615 
       
   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 	},
       
   621 
       
   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 	},
       
   627 
       
   628 	// Evalulates a script in a global context
       
   629 	globalEval: function( data ) {
       
   630 		data = jQuery.trim( data );
       
   631 
       
   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");
       
   637 
       
   638 			script.type = "text/javascript";
       
   639 			if ( jQuery.browser.msie )
       
   640 				script.text = data;
       
   641 			else
       
   642 				script.appendChild( document.createTextNode( data ) );
       
   643 
       
   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 	},
       
   650 
       
   651 	nodeName: function( elem, name ) {
       
   652 		return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase();
       
   653 	},
       
   654 
       
   655 	cache: {},
       
   656 
       
   657 	data: function( elem, name, data ) {
       
   658 		elem = elem == window ?
       
   659 			windowData :
       
   660 			elem;
       
   661 
       
   662 		var id = elem[ expando ];
       
   663 
       
   664 		// Compute a unique ID for the element
       
   665 		if ( !id )
       
   666 			id = elem[ expando ] = ++uuid;
       
   667 
       
   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 ] = {};
       
   672 
       
   673 		// Prevent overriding the named cache with undefined values
       
   674 		if ( data !== undefined )
       
   675 			jQuery.cache[ id ][ name ] = data;
       
   676 
       
   677 		// Return the named cache data, or the ID for the element
       
   678 		return name ?
       
   679 			jQuery.cache[ id ][ name ] :
       
   680 			id;
       
   681 	},
       
   682 
       
   683 	removeData: function( elem, name ) {
       
   684 		elem = elem == window ?
       
   685 			windowData :
       
   686 			elem;
       
   687 
       
   688 		var id = elem[ expando ];
       
   689 
       
   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 ];
       
   695 
       
   696 				// If we've removed all the data, remove the element's cache
       
   697 				name = "";
       
   698 
       
   699 				for ( name in jQuery.cache[ id ] )
       
   700 					break;
       
   701 
       
   702 				if ( !name )
       
   703 					jQuery.removeData( elem );
       
   704 			}
       
   705 
       
   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 			}
       
   717 
       
   718 			// Completely remove the data cache
       
   719 			delete jQuery.cache[ id ];
       
   720 		}
       
   721 	},
       
   722 
       
   723 	// args is for internal usage only
       
   724 	each: function( object, callback, args ) {
       
   725 		var name, i = 0, length = object.length;
       
   726 
       
   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;
       
   736 
       
   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 		}
       
   747 
       
   748 		return object;
       
   749 	},
       
   750 
       
   751 	prop: function( elem, value, type, i, name ) {
       
   752 		// Handle executable functions
       
   753 		if ( jQuery.isFunction( value ) )
       
   754 			value = value.call( elem, i );
       
   755 
       
   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 	},
       
   761 
       
   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 		},
       
   770 
       
   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 		},
       
   780 
       
   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 	},
       
   786 
       
   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 		}
       
   795 
       
   796 		callback.call( elem );
       
   797 
       
   798 		// Revert the old values
       
   799 		for ( var name in options )
       
   800 			elem.style[ name ] = old[ name ];
       
   801 	},
       
   802 
       
   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" ];
       
   806 
       
   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 			}
       
   816 
       
   817 			if ( jQuery(elem).is(":visible") )
       
   818 				getWH();
       
   819 			else
       
   820 				jQuery.swap( elem, props, getWH );
       
   821 
       
   822 			return Math.max(0, val);
       
   823 		}
       
   824 
       
   825 		return jQuery.curCSS( elem, name, force );
       
   826 	},
       
   827 
       
   828 	curCSS: function( elem, name, force ) {
       
   829 		var ret, style = elem.style;
       
   830 
       
   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;
       
   835 
       
   836 			// defaultView is cached
       
   837 			var ret = defaultView.getComputedStyle( elem, null );
       
   838 			return !ret || ret.getPropertyValue("color") == "";
       
   839 		}
       
   840 
       
   841 		// We need to handle opacity special in IE
       
   842 		if ( name == "opacity" && jQuery.browser.msie ) {
       
   843 			ret = jQuery.attr( style, "opacity" );
       
   844 
       
   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 		}
       
   855 
       
   856 		// Make sure we're using the right name for getting the float value
       
   857 		if ( name.match( /float/i ) )
       
   858 			name = styleFloat;
       
   859 
       
   860 		if ( !force && style && style[ name ] )
       
   861 			ret = style[ name ];
       
   862 
       
   863 		else if ( defaultView.getComputedStyle ) {
       
   864 
       
   865 			// Only "float" is needed here
       
   866 			if ( name.match( /float/i ) )
       
   867 				name = "float";
       
   868 
       
   869 			name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase();
       
   870 
       
   871 			var computedStyle = defaultView.getComputedStyle( elem, null );
       
   872 
       
   873 			if ( computedStyle && !color( elem ) )
       
   874 				ret = computedStyle.getPropertyValue( name );
       
   875 
       
   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;
       
   880 
       
   881 				// Locate all of the parent display: none elements
       
   882 				for ( ; a && color(a); a = a.parentNode )
       
   883 					stack.unshift(a);
       
   884 
       
   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 					}
       
   892 
       
   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 ) ) || "";
       
   898 
       
   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 			}
       
   904 
       
   905 			// We should always get a number back from opacity
       
   906 			if ( name == "opacity" && ret == "" )
       
   907 				ret = "1";
       
   908 
       
   909 		} else if ( elem.currentStyle ) {
       
   910 			var camelCase = name.replace(/\-(\w)/g, function(all, letter){
       
   911 				return letter.toUpperCase();
       
   912 			});
       
   913 
       
   914 			ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ];
       
   915 
       
   916 			// From the awesome hack by Dean Edwards
       
   917 			// http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
       
   918 
       
   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;
       
   924 
       
   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";
       
   929 
       
   930 				// Revert the changed values
       
   931 				style.left = left;
       
   932 				elem.runtimeStyle.left = rsLeft;
       
   933 			}
       
   934 		}
       
   935 
       
   936 		return ret;
       
   937 	},
       
   938 
       
   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;
       
   945 
       
   946 		jQuery.each(elems, function(i, elem){
       
   947 			if ( !elem )
       
   948 				return;
       
   949 
       
   950 			if ( elem.constructor == Number )
       
   951 				elem += '';
       
   952 
       
   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 				});
       
   961 
       
   962 				// Trim whitespace, otherwise indexOf won't work as expected
       
   963 				var tags = jQuery.trim( elem ).toLowerCase(), div = context.createElement("div");
       
   964 
       
   965 				var wrap =
       
   966 					// option or optgroup
       
   967 					!tags.indexOf("<opt") &&
       
   968 					[ 1, "<select multiple='multiple'>", "</select>" ] ||
       
   969 
       
   970 					!tags.indexOf("<leg") &&
       
   971 					[ 1, "<fieldset>", "</fieldset>" ] ||
       
   972 
       
   973 					tags.match(/^<(thead|tbody|tfoot|colg|cap)/) &&
       
   974 					[ 1, "<table>", "</table>" ] ||
       
   975 
       
   976 					!tags.indexOf("<tr") &&
       
   977 					[ 2, "<table><tbody>", "</tbody></table>" ] ||
       
   978 
       
   979 				 	// <thead> matched above
       
   980 					(!tags.indexOf("<td") || !tags.indexOf("<th")) &&
       
   981 					[ 3, "<table><tbody><tr>", "</tr></tbody></table>" ] ||
       
   982 
       
   983 					!tags.indexOf("<col") &&
       
   984 					[ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ] ||
       
   985 
       
   986 					// IE can't serialize <link> and <script> tags normally
       
   987 					jQuery.browser.msie &&
       
   988 					[ 1, "div<div>", "</div>" ] ||
       
   989 
       
   990 					[ 0, "", "" ];
       
   991 
       
   992 				// Go to html and back, then peel off extra wrappers
       
   993 				div.innerHTML = wrap[1] + elem + wrap[2];
       
   994 
       
   995 				// Move to the right depth
       
   996 				while ( wrap[0]-- )
       
   997 					div = div.lastChild;
       
   998 
       
   999 				// Remove IE's autoinserted <tbody> from table fragments
       
  1000 				if ( jQuery.browser.msie ) {
       
  1001 
       
  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 :
       
  1005 
       
  1006 						// String was a bare <thead> or <tfoot>
       
  1007 						wrap[1] == "<table>" && tags.indexOf("<tbody") < 0 ?
       
  1008 							div.childNodes :
       
  1009 							[];
       
  1010 
       
  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 ] );
       
  1014 
       
  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 );
       
  1018 
       
  1019 				}
       
  1020 
       
  1021 				elem = jQuery.makeArray( div.childNodes );
       
  1022 			}
       
  1023 
       
  1024 			if ( elem.length === 0 && (!jQuery.nodeName( elem, "form" ) && !jQuery.nodeName( elem, "select" )) )
       
  1025 				return;
       
  1026 
       
  1027 			if ( elem[0] == undefined || jQuery.nodeName( elem, "form" ) || elem.options )
       
  1028 				ret.push( elem );
       
  1029 
       
  1030 			else
       
  1031 				ret = jQuery.merge( ret, elem );
       
  1032 
       
  1033 		});
       
  1034 
       
  1035 		return ret;
       
  1036 	},
       
  1037 
       
  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;
       
  1042 
       
  1043 		var notxml = !jQuery.isXMLDoc( elem ),
       
  1044 			// Whether we are setting (or getting)
       
  1045 			set = value !== undefined,
       
  1046 			msie = jQuery.browser.msie;
       
  1047 
       
  1048 		// Try to normalize/fix the name
       
  1049 		name = notxml && jQuery.props[ name ] || name;
       
  1050 
       
  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 ) {
       
  1054 
       
  1055 			// These attributes require special treatment
       
  1056 			var special = /href|src|style/.test( name );
       
  1057 
       
  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;
       
  1062 
       
  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";
       
  1069 
       
  1070 					elem[ name ] = value;
       
  1071 				}
       
  1072 
       
  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;
       
  1076 
       
  1077 				return elem[ name ];
       
  1078 			}
       
  1079 
       
  1080 			if ( msie && notxml &&  name == "style" )
       
  1081 				return jQuery.attr( elem.style, "cssText", value );
       
  1082 
       
  1083 			if ( set )
       
  1084 				// convert the value to a string (all browsers do this but IE) see #1070
       
  1085 				elem.setAttribute( name, "" + value );
       
  1086 
       
  1087 			var attr = msie && notxml && special
       
  1088 					// Some attributes require a special call on IE
       
  1089 					? elem.getAttribute( name, 2 )
       
  1090 					: elem.getAttribute( name );
       
  1091 
       
  1092 			// Non-existent attributes return null, we normalize to undefined
       
  1093 			return attr === null ? undefined : attr;
       
  1094 		}
       
  1095 
       
  1096 		// elem is actually elem.style ... set the style
       
  1097 
       
  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;
       
  1104 
       
  1105 				// Set the alpha filter to set the opacity
       
  1106 				elem.filter = (elem.filter || "").replace( /alpha\([^)]*\)/, "" ) +
       
  1107 					(parseInt( value ) + '' == "NaN" ? "" : "alpha(opacity=" + value * 100 + ")");
       
  1108 			}
       
  1109 
       
  1110 			return elem.filter && elem.filter.indexOf("opacity=") >= 0 ?
       
  1111 				(parseFloat( elem.filter.match(/opacity=([^)]*)/)[1] ) / 100) + '':
       
  1112 				"";
       
  1113 		}
       
  1114 
       
  1115 		name = name.replace(/-([a-z])/ig, function(all, letter){
       
  1116 			return letter.toUpperCase();
       
  1117 		});
       
  1118 
       
  1119 		if ( set )
       
  1120 			elem[ name ] = value;
       
  1121 
       
  1122 		return elem[ name ];
       
  1123 	},
       
  1124 
       
  1125 	trim: function( text ) {
       
  1126 		return (text || "").replace( /^\s+|\s+$/g, "" );
       
  1127 	},
       
  1128 
       
  1129 	makeArray: function( array ) {
       
  1130 		var ret = [];
       
  1131 
       
  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];
       
  1140 		}
       
  1141 
       
  1142 		return ret;
       
  1143 	},
       
  1144 
       
  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;
       
  1150 
       
  1151 		return -1;
       
  1152 	},
       
  1153 
       
  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;
       
  1164 
       
  1165 		} else
       
  1166 			while ( elem = second[ i++ ] )
       
  1167 				first[ pos++ ] = elem;
       
  1168 
       
  1169 		return first;
       
  1170 	},
       
  1171 
       
  1172 	unique: function( array ) {
       
  1173 		var ret = [], done = {};
       
  1174 
       
  1175 		try {
       
  1176 
       
  1177 			for ( var i = 0, length = array.length; i < length; i++ ) {
       
  1178 				var id = jQuery.data( array[ i ] );
       
  1179 
       
  1180 				if ( !done[ id ] ) {
       
  1181 					done[ id ] = true;
       
  1182 					ret.push( array[ i ] );
       
  1183 				}
       
  1184 			}
       
  1185 
       
  1186 		} catch( e ) {
       
  1187 			ret = array;
       
  1188 		}
       
  1189 
       
  1190 		return ret;
       
  1191 	},
       
  1192 
       
  1193 	grep: function( elems, callback, inv ) {
       
  1194 		var ret = [];
       
  1195 
       
  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 ] );
       
  1201 
       
  1202 		return ret;
       
  1203 	},
       
  1204 
       
  1205 	map: function( elems, callback ) {
       
  1206 		var ret = [];
       
  1207 
       
  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 );
       
  1212 
       
  1213 			if ( value != null )
       
  1214 				ret[ ret.length ] = value;
       
  1215 		}
       
  1216 
       
  1217 		return ret.concat.apply( [], ret );
       
  1218 	}
       
  1219 });
       
  1220 
       
  1221 var userAgent = navigator.userAgent.toLowerCase();
       
  1222 
       
  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 };
       
  1231 
       
  1232 var styleFloat = jQuery.browser.msie ?
       
  1233 	"styleFloat" :
       
  1234 	"cssFloat";
       
  1235 
       
  1236 jQuery.extend({
       
  1237 	// Check to see if the W3C box model is being used
       
  1238 	boxModel: !jQuery.browser.msie || document.compatMode == "CSS1Compat",
       
  1239 
       
  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",
       
  1249 		rowspan: "rowSpan"
       
  1250 	}
       
  1251 });
       
  1252 
       
  1253 jQuery.each({
       
  1254 	parent: function(elem){return elem.parentNode;},
       
  1255 	parents: function(elem){return jQuery.dir(elem,"parentNode");},
       
  1256 	next: function(elem){return jQuery.nth(elem,2,"nextSibling");},
       
  1257 	prev: function(elem){return jQuery.nth(elem,2,"previousSibling");},
       
  1258 	nextAll: function(elem){return jQuery.dir(elem,"nextSibling");},
       
  1259 	prevAll: function(elem){return jQuery.dir(elem,"previousSibling");},
       
  1260 	siblings: function(elem){return jQuery.sibling(elem.parentNode.firstChild,elem);},
       
  1261 	children: function(elem){return jQuery.sibling(elem.firstChild);},
       
  1262 	contents: function(elem){return jQuery.nodeName(elem,"iframe")?elem.contentDocument||elem.contentWindow.document:jQuery.makeArray(elem.childNodes);}
       
  1263 }, function(name, fn){
       
  1264 	jQuery.fn[ name ] = function( selector ) {
       
  1265 		var ret = jQuery.map( this, fn );
       
  1266 
       
  1267 		if ( selector && typeof selector == "string" )
       
  1268 			ret = jQuery.multiFilter( selector, ret );
       
  1269 
       
  1270 		return this.pushStack( jQuery.unique( ret ) );
       
  1271 	};
       
  1272 });
       
  1273 
       
  1274 jQuery.each({
       
  1275 	appendTo: "append",
       
  1276 	prependTo: "prepend",
       
  1277 	insertBefore: "before",
       
  1278 	insertAfter: "after",
       
  1279 	replaceAll: "replaceWith"
       
  1280 }, function(name, original){
       
  1281 	jQuery.fn[ name ] = function() {
       
  1282 		var args = arguments;
       
  1283 
       
  1284 		return this.each(function(){
       
  1285 			for ( var i = 0, length = args.length; i < length; i++ )
       
  1286 				jQuery( args[ i ] )[ original ]( this );
       
  1287 		});
       
  1288 	};
       
  1289 });
       
  1290 
       
  1291 jQuery.each({
       
  1292 	removeAttr: function( name ) {
       
  1293 		jQuery.attr( this, name, "" );
       
  1294 		if (this.nodeType == 1)
       
  1295 			this.removeAttribute( name );
       
  1296 	},
       
  1297 
       
  1298 	addClass: function( classNames ) {
       
  1299 		jQuery.className.add( this, classNames );
       
  1300 	},
       
  1301 
       
  1302 	removeClass: function( classNames ) {
       
  1303 		jQuery.className.remove( this, classNames );
       
  1304 	},
       
  1305 
       
  1306 	toggleClass: function( classNames ) {
       
  1307 		jQuery.className[ jQuery.className.has( this, classNames ) ? "remove" : "add" ]( this, classNames );
       
  1308 	},
       
  1309 
       
  1310 	remove: function( selector ) {
       
  1311 		if ( !selector || jQuery.filter( selector, [ this ] ).r.length ) {
       
  1312 			// Prevent memory leaks
       
  1313 			jQuery( "*", this ).add(this).each(function(){
       
  1314 				jQuery.event.remove(this);
       
  1315 				jQuery.removeData(this);
       
  1316 			});
       
  1317 			if (this.parentNode)
       
  1318 				this.parentNode.removeChild( this );
       
  1319 		}
       
  1320 	},
       
  1321 
       
  1322 	empty: function() {
       
  1323 		// Remove element nodes and prevent memory leaks
       
  1324 		jQuery( ">*", this ).remove();
       
  1325 
       
  1326 		// Remove any remaining nodes
       
  1327 		while ( this.firstChild )
       
  1328 			this.removeChild( this.firstChild );
       
  1329 	}
       
  1330 }, function(name, fn){
       
  1331 	jQuery.fn[ name ] = function(){
       
  1332 		return this.each( fn, arguments );
       
  1333 	};
       
  1334 });
       
  1335 
       
  1336 jQuery.each([ "Height", "Width" ], function(i, name){
       
  1337 	var type = name.toLowerCase();
       
  1338 
       
  1339 	jQuery.fn[ type ] = function( size ) {
       
  1340 		// Get window width or height
       
  1341 		return this[0] == window ?
       
  1342 			// Opera reports document.body.client[Width/Height] properly in both quirks and standards
       
  1343 			jQuery.browser.opera && document.body[ "client" + name ] ||
       
  1344 
       
  1345 			// Safari reports inner[Width/Height] just fine (Mozilla and Opera include scroll bar widths)
       
  1346 			jQuery.browser.safari && window[ "inner" + name ] ||
       
  1347 
       
  1348 			// Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
       
  1349 			document.compatMode == "CSS1Compat" && document.documentElement[ "client" + name ] || document.body[ "client" + name ] :
       
  1350 
       
  1351 			// Get document width or height
       
  1352 			this[0] == document ?
       
  1353 				// Either scroll[Width/Height] or offset[Width/Height], whichever is greater
       
  1354 				Math.max(
       
  1355 					Math.max(document.body["scroll" + name], document.documentElement["scroll" + name]),
       
  1356 					Math.max(document.body["offset" + name], document.documentElement["offset" + name])
       
  1357 				) :
       
  1358 
       
  1359 				// Get or set width or height on the element
       
  1360 				size == undefined ?
       
  1361 					// Get width or height on the element
       
  1362 					(this.length ? jQuery.css( this[0], type ) : null) :
       
  1363 
       
  1364 					// Set the width or height on the element (default to pixels if value is unitless)
       
  1365 					this.css( type, size.constructor == String ? size : size + "px" );
       
  1366 	};
       
  1367 });
       
  1368 
       
  1369 // Helper function used by the dimensions and offset modules
       
  1370 function num(elem, prop) {
       
  1371 	return elem[0] && parseInt( jQuery.curCSS(elem[0], prop, true), 10 ) || 0;
       
  1372 }var chars = jQuery.browser.safari && parseInt(jQuery.browser.version) < 417 ?
       
  1373 		"(?:[\\w*_-]|\\\\.)" :
       
  1374 		"(?:[\\w\u0128-\uFFFF*_-]|\\\\.)",
       
  1375 	quickChild = new RegExp("^>\\s*(" + chars + "+)"),
       
  1376 	quickID = new RegExp("^(" + chars + "+)(#)(" + chars + "+)"),
       
  1377 	quickClass = new RegExp("^([#.]?)(" + chars + "*)");
       
  1378 
       
  1379 jQuery.extend({
       
  1380 	expr: {
       
  1381 		"": function(a,i,m){return m[2]=="*"||jQuery.nodeName(a,m[2]);},
       
  1382 		"#": function(a,i,m){return a.getAttribute("id")==m[2];},
       
  1383 		":": {
       
  1384 			// Position Checks
       
  1385 			lt: function(a,i,m){return i<m[3]-0;},
       
  1386 			gt: function(a,i,m){return i>m[3]-0;},
       
  1387 			nth: function(a,i,m){return m[3]-0==i;},
       
  1388 			eq: function(a,i,m){return m[3]-0==i;},
       
  1389 			first: function(a,i){return i==0;},
       
  1390 			last: function(a,i,m,r){return i==r.length-1;},
       
  1391 			even: function(a,i){return i%2==0;},
       
  1392 			odd: function(a,i){return i%2;},
       
  1393 
       
  1394 			// Child Checks
       
  1395 			"first-child": function(a){return a.parentNode.getElementsByTagName("*")[0]==a;},
       
  1396 			"last-child": function(a){return jQuery.nth(a.parentNode.lastChild,1,"previousSibling")==a;},
       
  1397 			"only-child": function(a){return !jQuery.nth(a.parentNode.lastChild,2,"previousSibling");},
       
  1398 
       
  1399 			// Parent Checks
       
  1400 			parent: function(a){return a.firstChild;},
       
  1401 			empty: function(a){return !a.firstChild;},
       
  1402 
       
  1403 			// Text Check
       
  1404 			contains: function(a,i,m){return (a.textContent||a.innerText||jQuery(a).text()||"").indexOf(m[3])>=0;},
       
  1405 
       
  1406 			// Visibility
       
  1407 			visible: function(a){return "hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden";},
       
  1408 			hidden: function(a){return "hidden"==a.type||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden";},
       
  1409 
       
  1410 			// Form attributes
       
  1411 			enabled: function(a){return !a.disabled;},
       
  1412 			disabled: function(a){return a.disabled;},
       
  1413 			checked: function(a){return a.checked;},
       
  1414 			selected: function(a){return a.selected||jQuery.attr(a,"selected");},
       
  1415 
       
  1416 			// Form elements
       
  1417 			text: function(a){return "text"==a.type;},
       
  1418 			radio: function(a){return "radio"==a.type;},
       
  1419 			checkbox: function(a){return "checkbox"==a.type;},
       
  1420 			file: function(a){return "file"==a.type;},
       
  1421 			password: function(a){return "password"==a.type;},
       
  1422 			submit: function(a){return "submit"==a.type;},
       
  1423 			image: function(a){return "image"==a.type;},
       
  1424 			reset: function(a){return "reset"==a.type;},
       
  1425 			button: function(a){return "button"==a.type||jQuery.nodeName(a,"button");},
       
  1426 			input: function(a){return /input|select|textarea|button/i.test(a.nodeName);},
       
  1427 
       
  1428 			// :has()
       
  1429 			has: function(a,i,m){return jQuery.find(m[3],a).length;},
       
  1430 
       
  1431 			// :header
       
  1432 			header: function(a){return /h\d/i.test(a.nodeName);},
       
  1433 
       
  1434 			// :animated
       
  1435 			animated: function(a){return jQuery.grep(jQuery.timers,function(fn){return a==fn.elem;}).length;}
       
  1436 		}
       
  1437 	},
       
  1438 
       
  1439 	// The regular expressions that power the parsing engine
       
  1440 	parse: [
       
  1441 		// Match: [@value='test'], [@foo]
       
  1442 		/^(\[) *@?([\w-]+) *([!*$^~=]*) *('?"?)(.*?)\4 *\]/,
       
  1443 
       
  1444 		// Match: :contains('foo')
       
  1445 		/^(:)([\w-]+)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/,
       
  1446 
       
  1447 		// Match: :even, :last-child, #id, .class
       
  1448 		new RegExp("^([:.#]*)(" + chars + "+)")
       
  1449 	],
       
  1450 
       
  1451 	multiFilter: function( expr, elems, not ) {
       
  1452 		var old, cur = [];
       
  1453 
       
  1454 		while ( expr && expr != old ) {
       
  1455 			old = expr;
       
  1456 			var f = jQuery.filter( expr, elems, not );
       
  1457 			expr = f.t.replace(/^\s*,\s*/, "" );
       
  1458 			cur = not ? elems = f.r : jQuery.merge( cur, f.r );
       
  1459 		}
       
  1460 
       
  1461 		return cur;
       
  1462 	},
       
  1463 
       
  1464 	find: function( t, context ) {
       
  1465 		// Quickly handle non-string expressions
       
  1466 		if ( typeof t != "string" )
       
  1467 			return [ t ];
       
  1468 
       
  1469 		// check to make sure context is a DOM element or a document
       
  1470 		if ( context && context.nodeType != 1 && context.nodeType != 9)
       
  1471 			return [ ];
       
  1472 
       
  1473 		// Set the correct context (if none is provided)
       
  1474 		context = context || document;
       
  1475 
       
  1476 		// Initialize the search
       
  1477 		var ret = [context], done = [], last, nodeName;
       
  1478 
       
  1479 		// Continue while a selector expression exists, and while
       
  1480 		// we're no longer looping upon ourselves
       
  1481 		while ( t && last != t ) {
       
  1482 			var r = [];
       
  1483 			last = t;
       
  1484 
       
  1485 			t = jQuery.trim(t);
       
  1486 
       
  1487 			var foundToken = false,
       
  1488 
       
  1489 			// An attempt at speeding up child selectors that
       
  1490 			// point to a specific element tag
       
  1491 				re = quickChild,
       
  1492 
       
  1493 				m = re.exec(t);
       
  1494 
       
  1495 			if ( m ) {
       
  1496 				nodeName = m[1].toUpperCase();
       
  1497 
       
  1498 				// Perform our own iteration and filter
       
  1499 				for ( var i = 0; ret[i]; i++ )
       
  1500 					for ( var c = ret[i].firstChild; c; c = c.nextSibling )
       
  1501 						if ( c.nodeType == 1 && (nodeName == "*" || c.nodeName.toUpperCase() == nodeName) )
       
  1502 							r.push( c );
       
  1503 
       
  1504 				ret = r;
       
  1505 				t = t.replace( re, "" );
       
  1506 				if ( t.indexOf(" ") == 0 ) continue;
       
  1507 				foundToken = true;
       
  1508 			} else {
       
  1509 				re = /^([>+~])\s*(\w*)/i;
       
  1510 
       
  1511 				if ( (m = re.exec(t)) != null ) {
       
  1512 					r = [];
       
  1513 
       
  1514 					var merge = {};
       
  1515 					nodeName = m[2].toUpperCase();
       
  1516 					m = m[1];
       
  1517 
       
  1518 					for ( var j = 0, rl = ret.length; j < rl; j++ ) {
       
  1519 						var n = m == "~" || m == "+" ? ret[j].nextSibling : ret[j].firstChild;
       
  1520 						for ( ; n; n = n.nextSibling )
       
  1521 							if ( n.nodeType == 1 ) {
       
  1522 								var id = jQuery.data(n);
       
  1523 
       
  1524 								if ( m == "~" && merge[id] ) break;
       
  1525 
       
  1526 								if (!nodeName || n.nodeName.toUpperCase() == nodeName ) {
       
  1527 									if ( m == "~" ) merge[id] = true;
       
  1528 									r.push( n );
       
  1529 								}
       
  1530 
       
  1531 								if ( m == "+" ) break;
       
  1532 							}
       
  1533 					}
       
  1534 
       
  1535 					ret = r;
       
  1536 
       
  1537 					// And remove the token
       
  1538 					t = jQuery.trim( t.replace( re, "" ) );
       
  1539 					foundToken = true;
       
  1540 				}
       
  1541 			}
       
  1542 
       
  1543 			// See if there's still an expression, and that we haven't already
       
  1544 			// matched a token
       
  1545 			if ( t && !foundToken ) {
       
  1546 				// Handle multiple expressions
       
  1547 				if ( !t.indexOf(",") ) {
       
  1548 					// Clean the result set
       
  1549 					if ( context == ret[0] ) ret.shift();
       
  1550 
       
  1551 					// Merge the result sets
       
  1552 					done = jQuery.merge( done, ret );
       
  1553 
       
  1554 					// Reset the context
       
  1555 					r = ret = [context];
       
  1556 
       
  1557 					// Touch up the selector string
       
  1558 					t = " " + t.substr(1,t.length);
       
  1559 
       
  1560 				} else {
       
  1561 					// Optimize for the case nodeName#idName
       
  1562 					var re2 = quickID;
       
  1563 					var m = re2.exec(t);
       
  1564 
       
  1565 					// Re-organize the results, so that they're consistent
       
  1566 					if ( m ) {
       
  1567 						m = [ 0, m[2], m[3], m[1] ];
       
  1568 
       
  1569 					} else {
       
  1570 						// Otherwise, do a traditional filter check for
       
  1571 						// ID, class, and element selectors
       
  1572 						re2 = quickClass;
       
  1573 						m = re2.exec(t);
       
  1574 					}
       
  1575 
       
  1576 					m[2] = m[2].replace(/\\/g, "");
       
  1577 
       
  1578 					var elem = ret[ret.length-1];
       
  1579 
       
  1580 					// Try to do a global search by ID, where we can
       
  1581 					if ( m[1] == "#" && elem && elem.getElementById && !jQuery.isXMLDoc(elem) ) {
       
  1582 						// Optimization for HTML document case
       
  1583 						var oid = elem.getElementById(m[2]);
       
  1584 
       
  1585 						// Do a quick check for the existence of the actual ID attribute
       
  1586 						// to avoid selecting by the name attribute in IE
       
  1587 						// also check to insure id is a string to avoid selecting an element with the name of 'id' inside a form
       
  1588 						if ( (jQuery.browser.msie||jQuery.browser.opera) && oid && typeof oid.id == "string" && oid.id != m[2] )
       
  1589 							oid = jQuery('[@id="'+m[2]+'"]', elem)[0];
       
  1590 
       
  1591 						// Do a quick check for node name (where applicable) so
       
  1592 						// that div#foo searches will be really fast
       
  1593 						ret = r = oid && (!m[3] || jQuery.nodeName(oid, m[3])) ? [oid] : [];
       
  1594 					} else {
       
  1595 						// We need to find all descendant elements
       
  1596 						for ( var i = 0; ret[i]; i++ ) {
       
  1597 							// Grab the tag name being searched for
       
  1598 							var tag = m[1] == "#" && m[3] ? m[3] : m[1] != "" || m[0] == "" ? "*" : m[2];
       
  1599 
       
  1600 							// Handle IE7 being really dumb about <object>s
       
  1601 							if ( tag == "*" && ret[i].nodeName.toLowerCase() == "object" )
       
  1602 								tag = "param";
       
  1603 
       
  1604 							r = jQuery.merge( r, ret[i].getElementsByTagName( tag ));
       
  1605 						}
       
  1606 
       
  1607 						// It's faster to filter by class and be done with it
       
  1608 						if ( m[1] == "." )
       
  1609 							r = jQuery.classFilter( r, m[2] );
       
  1610 
       
  1611 						// Same with ID filtering
       
  1612 						if ( m[1] == "#" ) {
       
  1613 							var tmp = [];
       
  1614 
       
  1615 							// Try to find the element with the ID
       
  1616 							for ( var i = 0; r[i]; i++ )
       
  1617 								if ( r[i].getAttribute("id") == m[2] ) {
       
  1618 									tmp = [ r[i] ];
       
  1619 									break;
       
  1620 								}
       
  1621 
       
  1622 							r = tmp;
       
  1623 						}
       
  1624 
       
  1625 						ret = r;
       
  1626 					}
       
  1627 
       
  1628 					t = t.replace( re2, "" );
       
  1629 				}
       
  1630 
       
  1631 			}
       
  1632 
       
  1633 			// If a selector string still exists
       
  1634 			if ( t ) {
       
  1635 				// Attempt to filter it
       
  1636 				var val = jQuery.filter(t,r);
       
  1637 				ret = r = val.r;
       
  1638 				t = jQuery.trim(val.t);
       
  1639 			}
       
  1640 		}
       
  1641 
       
  1642 		// An error occurred with the selector;
       
  1643 		// just return an empty set instead
       
  1644 		if ( t )
       
  1645 			ret = [];
       
  1646 
       
  1647 		// Remove the root context
       
  1648 		if ( ret && context == ret[0] )
       
  1649 			ret.shift();
       
  1650 
       
  1651 		// And combine the results
       
  1652 		done = jQuery.merge( done, ret );
       
  1653 
       
  1654 		return done;
       
  1655 	},
       
  1656 
       
  1657 	classFilter: function(r,m,not){
       
  1658 		m = " " + m + " ";
       
  1659 		var tmp = [];
       
  1660 		for ( var i = 0; r[i]; i++ ) {
       
  1661 			var pass = (" " + r[i].className + " ").indexOf( m ) >= 0;
       
  1662 			if ( !not && pass || not && !pass )
       
  1663 				tmp.push( r[i] );
       
  1664 		}
       
  1665 		return tmp;
       
  1666 	},
       
  1667 
       
  1668 	filter: function(t,r,not) {
       
  1669 		var last;
       
  1670 
       
  1671 		// Look for common filter expressions
       
  1672 		while ( t && t != last ) {
       
  1673 			last = t;
       
  1674 
       
  1675 			var p = jQuery.parse, m;
       
  1676 
       
  1677 			for ( var i = 0; p[i]; i++ ) {
       
  1678 				m = p[i].exec( t );
       
  1679 
       
  1680 				if ( m ) {
       
  1681 					// Remove what we just matched
       
  1682 					t = t.substring( m[0].length );
       
  1683 
       
  1684 					m[2] = m[2].replace(/\\/g, "");
       
  1685 					break;
       
  1686 				}
       
  1687 			}
       
  1688 
       
  1689 			if ( !m )
       
  1690 				break;
       
  1691 
       
  1692 			// :not() is a special case that can be optimized by
       
  1693 			// keeping it out of the expression list
       
  1694 			if ( m[1] == ":" && m[2] == "not" )
       
  1695 				// optimize if only one selector found (most common case)
       
  1696 				r = isSimple.test( m[3] ) ?
       
  1697 					jQuery.filter(m[3], r, true).r :
       
  1698 					jQuery( r ).not( m[3] );
       
  1699 
       
  1700 			// We can get a big speed boost by filtering by class here
       
  1701 			else if ( m[1] == "." )
       
  1702 				r = jQuery.classFilter(r, m[2], not);
       
  1703 
       
  1704 			else if ( m[1] == "[" ) {
       
  1705 				var tmp = [], type = m[3];
       
  1706 
       
  1707 				for ( var i = 0, rl = r.length; i < rl; i++ ) {
       
  1708 					var a = r[i], z = a[ jQuery.props[m[2]] || m[2] ];
       
  1709 
       
  1710 					if ( z == null || /href|src|selected/.test(m[2]) )
       
  1711 						z = jQuery.attr(a,m[2]) || '';
       
  1712 
       
  1713 					if ( (type == "" && !!z ||
       
  1714 						 type == "=" && z == m[5] ||
       
  1715 						 type == "!=" && z != m[5] ||
       
  1716 						 type == "^=" && z && !z.indexOf(m[5]) ||
       
  1717 						 type == "$=" && z.substr(z.length - m[5].length) == m[5] ||
       
  1718 						 (type == "*=" || type == "~=") && z.indexOf(m[5]) >= 0) ^ not )
       
  1719 							tmp.push( a );
       
  1720 				}
       
  1721 
       
  1722 				r = tmp;
       
  1723 
       
  1724 			// We can get a speed boost by handling nth-child here
       
  1725 			} else if ( m[1] == ":" && m[2] == "nth-child" ) {
       
  1726 				var merge = {}, tmp = [],
       
  1727 					// parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
       
  1728 					test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
       
  1729 						m[3] == "even" && "2n" || m[3] == "odd" && "2n+1" ||
       
  1730 						!/\D/.test(m[3]) && "0n+" + m[3] || m[3]),
       
  1731 					// calculate the numbers (first)n+(last) including if they are negative
       
  1732 					first = (test[1] + (test[2] || 1)) - 0, last = test[3] - 0;
       
  1733 
       
  1734 				// loop through all the elements left in the jQuery object
       
  1735 				for ( var i = 0, rl = r.length; i < rl; i++ ) {
       
  1736 					var node = r[i], parentNode = node.parentNode, id = jQuery.data(parentNode);
       
  1737 
       
  1738 					if ( !merge[id] ) {
       
  1739 						var c = 1;
       
  1740 
       
  1741 						for ( var n = parentNode.firstChild; n; n = n.nextSibling )
       
  1742 							if ( n.nodeType == 1 )
       
  1743 								n.nodeIndex = c++;
       
  1744 
       
  1745 						merge[id] = true;
       
  1746 					}
       
  1747 
       
  1748 					var add = false;
       
  1749 
       
  1750 					if ( first == 0 ) {
       
  1751 						if ( node.nodeIndex == last )
       
  1752 							add = true;
       
  1753 					} else if ( (node.nodeIndex - last) % first == 0 && (node.nodeIndex - last) / first >= 0 )
       
  1754 						add = true;
       
  1755 
       
  1756 					if ( add ^ not )
       
  1757 						tmp.push( node );
       
  1758 				}
       
  1759 
       
  1760 				r = tmp;
       
  1761 
       
  1762 			// Otherwise, find the expression to execute
       
  1763 			} else {
       
  1764 				var fn = jQuery.expr[ m[1] ];
       
  1765 				if ( typeof fn == "object" )
       
  1766 					fn = fn[ m[2] ];
       
  1767 
       
  1768 				if ( typeof fn == "string" )
       
  1769 					fn = eval("false||function(a,i){return " + fn + ";}");
       
  1770 
       
  1771 				// Execute it against the current filter
       
  1772 				r = jQuery.grep( r, function(elem, i){
       
  1773 					return fn(elem, i, m, r);
       
  1774 				}, not );
       
  1775 			}
       
  1776 		}
       
  1777 
       
  1778 		// Return an array of filtered elements (r)
       
  1779 		// and the modified expression string (t)
       
  1780 		return { r: r, t: t };
       
  1781 	},
       
  1782 
       
  1783 	dir: function( elem, dir ){
       
  1784 		var matched = [],
       
  1785 			cur = elem[dir];
       
  1786 		while ( cur && cur != document ) {
       
  1787 			if ( cur.nodeType == 1 )
       
  1788 				matched.push( cur );
       
  1789 			cur = cur[dir];
       
  1790 		}
       
  1791 		return matched;
       
  1792 	},
       
  1793 
       
  1794 	nth: function(cur,result,dir,elem){
       
  1795 		result = result || 1;
       
  1796 		var num = 0;
       
  1797 
       
  1798 		for ( ; cur; cur = cur[dir] )
       
  1799 			if ( cur.nodeType == 1 && ++num == result )
       
  1800 				break;
       
  1801 
       
  1802 		return cur;
       
  1803 	},
       
  1804 
       
  1805 	sibling: function( n, elem ) {
       
  1806 		var r = [];
       
  1807 
       
  1808 		for ( ; n; n = n.nextSibling ) {
       
  1809 			if ( n.nodeType == 1 && n != elem )
       
  1810 				r.push( n );
       
  1811 		}
       
  1812 
       
  1813 		return r;
       
  1814 	}
       
  1815 });
       
  1816 /*
       
  1817  * A number of helper functions used for managing events.
       
  1818  * Many of the ideas behind this code orignated from
       
  1819  * Dean Edwards' addEvent library.
       
  1820  */
       
  1821 jQuery.event = {
       
  1822 
       
  1823 	// Bind an event to an element
       
  1824 	// Original by Dean Edwards
       
  1825 	add: function(elem, types, handler, data) {
       
  1826 		if ( elem.nodeType == 3 || elem.nodeType == 8 )
       
  1827 			return;
       
  1828 
       
  1829 		// For whatever reason, IE has trouble passing the window object
       
  1830 		// around, causing it to be cloned in the process
       
  1831 		if ( jQuery.browser.msie && elem.setInterval )
       
  1832 			elem = window;
       
  1833 
       
  1834 		// Make sure that the function being executed has a unique ID
       
  1835 		if ( !handler.guid )
       
  1836 			handler.guid = this.guid++;
       
  1837 
       
  1838 		// if data is passed, bind to handler
       
  1839 		if( data != undefined ) {
       
  1840 			// Create temporary function pointer to original handler
       
  1841 			var fn = handler;
       
  1842 
       
  1843 			// Create unique handler function, wrapped around original handler
       
  1844 			handler = this.proxy( fn, function() {
       
  1845 				// Pass arguments and context to original handler
       
  1846 				return fn.apply(this, arguments);
       
  1847 			});
       
  1848 
       
  1849 			// Store data in unique handler
       
  1850 			handler.data = data;
       
  1851 		}
       
  1852 
       
  1853 		// Init the element's event structure
       
  1854 		var events = jQuery.data(elem, "events") || jQuery.data(elem, "events", {}),
       
  1855 			handle = jQuery.data(elem, "handle") || jQuery.data(elem, "handle", function(){
       
  1856 				// Handle the second event of a trigger and when
       
  1857 				// an event is called after a page has unloaded
       
  1858 				if ( typeof jQuery != "undefined" && !jQuery.event.triggered )
       
  1859 					return jQuery.event.handle.apply(arguments.callee.elem, arguments);
       
  1860 			});
       
  1861 		// Add elem as a property of the handle function
       
  1862 		// This is to prevent a memory leak with non-native
       
  1863 		// event in IE.
       
  1864 		handle.elem = elem;
       
  1865 
       
  1866 		// Handle multiple events separated by a space
       
  1867 		// jQuery(...).bind("mouseover mouseout", fn);
       
  1868 		jQuery.each(types.split(/\s+/), function(index, type) {
       
  1869 			// Namespaced event handlers
       
  1870 			var parts = type.split(".");
       
  1871 			type = parts[0];
       
  1872 			handler.type = parts[1];
       
  1873 
       
  1874 			// Get the current list of functions bound to this event
       
  1875 			var handlers = events[type];
       
  1876 
       
  1877 			// Init the event handler queue
       
  1878 			if (!handlers) {
       
  1879 				handlers = events[type] = {};
       
  1880 
       
  1881 				// Check for a special event handler
       
  1882 				// Only use addEventListener/attachEvent if the special
       
  1883 				// events handler returns false
       
  1884 				if ( !jQuery.event.special[type] || jQuery.event.special[type].setup.call(elem) === false ) {
       
  1885 					// Bind the global event handler to the element
       
  1886 					if (elem.addEventListener)
       
  1887 						elem.addEventListener(type, handle, false);
       
  1888 					else if (elem.attachEvent)
       
  1889 						elem.attachEvent("on" + type, handle);
       
  1890 				}
       
  1891 			}
       
  1892 
       
  1893 			// Add the function to the element's handler list
       
  1894 			handlers[handler.guid] = handler;
       
  1895 
       
  1896 			// Keep track of which events have been used, for global triggering
       
  1897 			jQuery.event.global[type] = true;
       
  1898 		});
       
  1899 
       
  1900 		// Nullify elem to prevent memory leaks in IE
       
  1901 		elem = null;
       
  1902 	},
       
  1903 
       
  1904 	guid: 1,
       
  1905 	global: {},
       
  1906 
       
  1907 	// Detach an event or set of events from an element
       
  1908 	remove: function(elem, types, handler) {
       
  1909 		// don't do events on text and comment nodes
       
  1910 		if ( elem.nodeType == 3 || elem.nodeType == 8 )
       
  1911 			return;
       
  1912 
       
  1913 		var events = jQuery.data(elem, "events"), ret, index;
       
  1914 
       
  1915 		if ( events ) {
       
  1916 			// Unbind all events for the element
       
  1917 			if ( types == undefined || (typeof types == "string" && types.charAt(0) == ".") )
       
  1918 				for ( var type in events )
       
  1919 					this.remove( elem, type + (types || "") );
       
  1920 			else {
       
  1921 				// types is actually an event object here
       
  1922 				if ( types.type ) {
       
  1923 					handler = types.handler;
       
  1924 					types = types.type;
       
  1925 				}
       
  1926 
       
  1927 				// Handle multiple events seperated by a space
       
  1928 				// jQuery(...).unbind("mouseover mouseout", fn);
       
  1929 				jQuery.each(types.split(/\s+/), function(index, type){
       
  1930 					// Namespaced event handlers
       
  1931 					var parts = type.split(".");
       
  1932 					type = parts[0];
       
  1933 
       
  1934 					if ( events[type] ) {
       
  1935 						// remove the given handler for the given type
       
  1936 						if ( handler )
       
  1937 							delete events[type][handler.guid];
       
  1938 
       
  1939 						// remove all handlers for the given type
       
  1940 						else
       
  1941 							for ( handler in events[type] )
       
  1942 								// Handle the removal of namespaced events
       
  1943 								if ( !parts[1] || events[type][handler].type == parts[1] )
       
  1944 									delete events[type][handler];
       
  1945 
       
  1946 						// remove generic event handler if no more handlers exist
       
  1947 						for ( ret in events[type] ) break;
       
  1948 						if ( !ret ) {
       
  1949 							if ( !jQuery.event.special[type] || jQuery.event.special[type].teardown.call(elem) === false ) {
       
  1950 								if (elem.removeEventListener)
       
  1951 									elem.removeEventListener(type, jQuery.data(elem, "handle"), false);
       
  1952 								else if (elem.detachEvent)
       
  1953 									elem.detachEvent("on" + type, jQuery.data(elem, "handle"));
       
  1954 							}
       
  1955 							ret = null;
       
  1956 							delete events[type];
       
  1957 						}
       
  1958 					}
       
  1959 				});
       
  1960 			}
       
  1961 
       
  1962 			// Remove the expando if it's no longer used
       
  1963 			for ( ret in events ) break;
       
  1964 			if ( !ret ) {
       
  1965 				var handle = jQuery.data( elem, "handle" );
       
  1966 				if ( handle ) handle.elem = null;
       
  1967 				jQuery.removeData( elem, "events" );
       
  1968 				jQuery.removeData( elem, "handle" );
       
  1969 			}
       
  1970 		}
       
  1971 	},
       
  1972 
       
  1973 	trigger: function(type, data, elem, donative, extra) {
       
  1974 		// Clone the incoming data, if any
       
  1975 		data = jQuery.makeArray(data);
       
  1976 
       
  1977 		if ( type.indexOf("!") >= 0 ) {
       
  1978 			type = type.slice(0, -1);
       
  1979 			var exclusive = true;
       
  1980 		}
       
  1981 
       
  1982 		// Handle a global trigger
       
  1983 		if ( !elem ) {
       
  1984 			// Only trigger if we've ever bound an event for it
       
  1985 			if ( this.global[type] )
       
  1986 				jQuery("*").add([window, document]).trigger(type, data);
       
  1987 
       
  1988 		// Handle triggering a single element
       
  1989 		} else {
       
  1990 			// don't do events on text and comment nodes
       
  1991 			if ( elem.nodeType == 3 || elem.nodeType == 8 )
       
  1992 				return undefined;
       
  1993 
       
  1994 			var val, ret, fn = jQuery.isFunction( elem[ type ] || null ),
       
  1995 				// Check to see if we need to provide a fake event, or not
       
  1996 				event = !data[0] || !data[0].preventDefault;
       
  1997 
       
  1998 			// Pass along a fake event
       
  1999 			if ( event ) {
       
  2000 				data.unshift({
       
  2001 					type: type,
       
  2002 					target: elem,
       
  2003 					preventDefault: function(){},
       
  2004 					stopPropagation: function(){},
       
  2005 					timeStamp: now()
       
  2006 				});
       
  2007 				data[0][expando] = true; // no need to fix fake event
       
  2008 			}
       
  2009 
       
  2010 			// Enforce the right trigger type
       
  2011 			data[0].type = type;
       
  2012 			if ( exclusive )
       
  2013 				data[0].exclusive = true;
       
  2014 
       
  2015 			// Trigger the event, it is assumed that "handle" is a function
       
  2016 			var handle = jQuery.data(elem, "handle");
       
  2017 			if ( handle )
       
  2018 				val = handle.apply( elem, data );
       
  2019 
       
  2020 			// Handle triggering native .onfoo handlers (and on links since we don't call .click() for links)
       
  2021 			if ( (!fn || (jQuery.nodeName(elem, 'a') && type == "click")) && elem["on"+type] && elem["on"+type].apply( elem, data ) === false )
       
  2022 				val = false;
       
  2023 
       
  2024 			// Extra functions don't get the custom event object
       
  2025 			if ( event )
       
  2026 				data.shift();
       
  2027 
       
  2028 			// Handle triggering of extra function
       
  2029 			if ( extra && jQuery.isFunction( extra ) ) {
       
  2030 				// call the extra function and tack the current return value on the end for possible inspection
       
  2031 				ret = extra.apply( elem, val == null ? data : data.concat( val ) );
       
  2032 				// if anything is returned, give it precedence and have it overwrite the previous value
       
  2033 				if (ret !== undefined)
       
  2034 					val = ret;
       
  2035 			}
       
  2036 
       
  2037 			// Trigger the native events (except for clicks on links)
       
  2038 			if ( fn && donative !== false && val !== false && !(jQuery.nodeName(elem, 'a') && type == "click") ) {
       
  2039 				this.triggered = true;
       
  2040 				try {
       
  2041 					elem[ type ]();
       
  2042 				// prevent IE from throwing an error for some hidden elements
       
  2043 				} catch (e) {}
       
  2044 			}
       
  2045 
       
  2046 			this.triggered = false;
       
  2047 		}
       
  2048 
       
  2049 		return val;
       
  2050 	},
       
  2051 
       
  2052 	handle: function(event) {
       
  2053 		// returned undefined or false
       
  2054 		var val, ret, namespace, all, handlers;
       
  2055 
       
  2056 		event = arguments[0] = jQuery.event.fix( event || window.event );
       
  2057 
       
  2058 		// Namespaced event handlers
       
  2059 		namespace = event.type.split(".");
       
  2060 		event.type = namespace[0];
       
  2061 		namespace = namespace[1];
       
  2062 		// Cache this now, all = true means, any handler
       
  2063 		all = !namespace && !event.exclusive;
       
  2064 
       
  2065 		handlers = ( jQuery.data(this, "events") || {} )[event.type];
       
  2066 
       
  2067 		for ( var j in handlers ) {
       
  2068 			var handler = handlers[j];
       
  2069 
       
  2070 			// Filter the functions by class
       
  2071 			if ( all || handler.type == namespace ) {
       
  2072 				// Pass in a reference to the handler function itself
       
  2073 				// So that we can later remove it
       
  2074 				event.handler = handler;
       
  2075 				event.data = handler.data;
       
  2076 
       
  2077 				ret = handler.apply( this, arguments );
       
  2078 
       
  2079 				if ( val !== false )
       
  2080 					val = ret;
       
  2081 
       
  2082 				if ( ret === false ) {
       
  2083 					event.preventDefault();
       
  2084 					event.stopPropagation();
       
  2085 				}
       
  2086 			}
       
  2087 		}
       
  2088 
       
  2089 		return val;
       
  2090 	},
       
  2091 
       
  2092 	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(" "),
       
  2093 
       
  2094 	fix: function(event) {
       
  2095 		if ( event[expando] == true )
       
  2096 			return event;
       
  2097 
       
  2098 		// store a copy of the original event object
       
  2099 		// and "clone" to set read-only properties
       
  2100 		var originalEvent = event;
       
  2101 		event = { originalEvent: originalEvent };
       
  2102 
       
  2103 		for ( var i = this.props.length, prop; i; ){
       
  2104 			prop = this.props[ --i ];
       
  2105 			event[ prop ] = originalEvent[ prop ];
       
  2106 		}
       
  2107 
       
  2108 		// Mark it as fixed
       
  2109 		event[expando] = true;
       
  2110 
       
  2111 		// add preventDefault and stopPropagation since
       
  2112 		// they will not work on the clone
       
  2113 		event.preventDefault = function() {
       
  2114 			// if preventDefault exists run it on the original event
       
  2115 			if (originalEvent.preventDefault)
       
  2116 				originalEvent.preventDefault();
       
  2117 			// otherwise set the returnValue property of the original event to false (IE)
       
  2118 			originalEvent.returnValue = false;
       
  2119 		};
       
  2120 		event.stopPropagation = function() {
       
  2121 			// if stopPropagation exists run it on the original event
       
  2122 			if (originalEvent.stopPropagation)
       
  2123 				originalEvent.stopPropagation();
       
  2124 			// otherwise set the cancelBubble property of the original event to true (IE)
       
  2125 			originalEvent.cancelBubble = true;
       
  2126 		};
       
  2127 
       
  2128 		// Fix timeStamp
       
  2129 		event.timeStamp = event.timeStamp || now();
       
  2130 
       
  2131 		// Fix target property, if necessary
       
  2132 		if ( !event.target )
       
  2133 			event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either
       
  2134 
       
  2135 		// check if target is a textnode (safari)
       
  2136 		if ( event.target.nodeType == 3 )
       
  2137 			event.target = event.target.parentNode;
       
  2138 
       
  2139 		// Add relatedTarget, if necessary
       
  2140 		if ( !event.relatedTarget && event.fromElement )
       
  2141 			event.relatedTarget = event.fromElement == event.target ? event.toElement : event.fromElement;
       
  2142 
       
  2143 		// Calculate pageX/Y if missing and clientX/Y available
       
  2144 		if ( event.pageX == null && event.clientX != null ) {
       
  2145 			var doc = document.documentElement, body = document.body;
       
  2146 			event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc.clientLeft || 0);
       
  2147 			event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc.clientTop || 0);
       
  2148 		}
       
  2149 
       
  2150 		// Add which for key events
       
  2151 		if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) )
       
  2152 			event.which = event.charCode || event.keyCode;
       
  2153 
       
  2154 		// Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
       
  2155 		if ( !event.metaKey && event.ctrlKey )
       
  2156 			event.metaKey = event.ctrlKey;
       
  2157 
       
  2158 		// Add which for click: 1 == left; 2 == middle; 3 == right
       
  2159 		// Note: button is not normalized, so don't use it
       
  2160 		if ( !event.which && event.button )
       
  2161 			event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
       
  2162 
       
  2163 		return event;
       
  2164 	},
       
  2165 
       
  2166 	proxy: function( fn, proxy ){
       
  2167 		// Set the guid of unique handler to the same of original handler, so it can be removed
       
  2168 		proxy.guid = fn.guid = fn.guid || proxy.guid || this.guid++;
       
  2169 		// So proxy can be declared as an argument
       
  2170 		return proxy;
       
  2171 	},
       
  2172 
       
  2173 	special: {
       
  2174 		ready: {
       
  2175 			setup: function() {
       
  2176 				// Make sure the ready event is setup
       
  2177 				bindReady();
       
  2178 				return;
       
  2179 			},
       
  2180 
       
  2181 			teardown: function() { return; }
       
  2182 		},
       
  2183 
       
  2184 		mouseenter: {
       
  2185 			setup: function() {
       
  2186 				if ( jQuery.browser.msie ) return false;
       
  2187 				jQuery(this).bind("mouseover", jQuery.event.special.mouseenter.handler);
       
  2188 				return true;
       
  2189 			},
       
  2190 
       
  2191 			teardown: function() {
       
  2192 				if ( jQuery.browser.msie ) return false;
       
  2193 				jQuery(this).unbind("mouseover", jQuery.event.special.mouseenter.handler);
       
  2194 				return true;
       
  2195 			},
       
  2196 
       
  2197 			handler: function(event) {
       
  2198 				// If we actually just moused on to a sub-element, ignore it
       
  2199 				if ( withinElement(event, this) ) return true;
       
  2200 				// Execute the right handlers by setting the event type to mouseenter
       
  2201 				event.type = "mouseenter";
       
  2202 				return jQuery.event.handle.apply(this, arguments);
       
  2203 			}
       
  2204 		},
       
  2205 
       
  2206 		mouseleave: {
       
  2207 			setup: function() {
       
  2208 				if ( jQuery.browser.msie ) return false;
       
  2209 				jQuery(this).bind("mouseout", jQuery.event.special.mouseleave.handler);
       
  2210 				return true;
       
  2211 			},
       
  2212 
       
  2213 			teardown: function() {
       
  2214 				if ( jQuery.browser.msie ) return false;
       
  2215 				jQuery(this).unbind("mouseout", jQuery.event.special.mouseleave.handler);
       
  2216 				return true;
       
  2217 			},
       
  2218 
       
  2219 			handler: function(event) {
       
  2220 				// If we actually just moused on to a sub-element, ignore it
       
  2221 				if ( withinElement(event, this) ) return true;
       
  2222 				// Execute the right handlers by setting the event type to mouseleave
       
  2223 				event.type = "mouseleave";
       
  2224 				return jQuery.event.handle.apply(this, arguments);
       
  2225 			}
       
  2226 		}
       
  2227 	}
       
  2228 };
       
  2229 
       
  2230 jQuery.fn.extend({
       
  2231 	bind: function( type, data, fn ) {
       
  2232 		return type == "unload" ? this.one(type, data, fn) : this.each(function(){
       
  2233 			jQuery.event.add( this, type, fn || data, fn && data );
       
  2234 		});
       
  2235 	},
       
  2236 
       
  2237 	one: function( type, data, fn ) {
       
  2238 		var one = jQuery.event.proxy( fn || data, function(event) {
       
  2239 			jQuery(this).unbind(event, one);
       
  2240 			return (fn || data).apply( this, arguments );
       
  2241 		});
       
  2242 		return this.each(function(){
       
  2243 			jQuery.event.add( this, type, one, fn && data);
       
  2244 		});
       
  2245 	},
       
  2246 
       
  2247 	unbind: function( type, fn ) {
       
  2248 		return this.each(function(){
       
  2249 			jQuery.event.remove( this, type, fn );
       
  2250 		});
       
  2251 	},
       
  2252 
       
  2253 	trigger: function( type, data, fn ) {
       
  2254 		return this.each(function(){
       
  2255 			jQuery.event.trigger( type, data, this, true, fn );
       
  2256 		});
       
  2257 	},
       
  2258 
       
  2259 	triggerHandler: function( type, data, fn ) {
       
  2260 		return this[0] && jQuery.event.trigger( type, data, this[0], false, fn );
       
  2261 	},
       
  2262 
       
  2263 	toggle: function( fn ) {
       
  2264 		// Save reference to arguments for access in closure
       
  2265 		var args = arguments, i = 1;
       
  2266 
       
  2267 		// link all the functions, so any of them can unbind this click handler
       
  2268 		while( i < args.length )
       
  2269 			jQuery.event.proxy( fn, args[i++] );
       
  2270 
       
  2271 		return this.click( jQuery.event.proxy( fn, function(event) {
       
  2272 			// Figure out which function to execute
       
  2273 			this.lastToggle = ( this.lastToggle || 0 ) % i;
       
  2274 
       
  2275 			// Make sure that clicks stop
       
  2276 			event.preventDefault();
       
  2277 
       
  2278 			// and execute the function
       
  2279 			return args[ this.lastToggle++ ].apply( this, arguments ) || false;
       
  2280 		}));
       
  2281 	},
       
  2282 
       
  2283 	hover: function(fnOver, fnOut) {
       
  2284 		return this.bind('mouseenter', fnOver).bind('mouseleave', fnOut);
       
  2285 	},
       
  2286 
       
  2287 	ready: function(fn) {
       
  2288 		// Attach the listeners
       
  2289 		bindReady();
       
  2290 
       
  2291 		// If the DOM is already ready
       
  2292 		if ( jQuery.isReady )
       
  2293 			// Execute the function immediately
       
  2294 			fn.call( document, jQuery );
       
  2295 
       
  2296 		// Otherwise, remember the function for later
       
  2297 		else
       
  2298 			// Add the function to the wait list
       
  2299 			jQuery.readyList.push( function() { return fn.call(this, jQuery); } );
       
  2300 
       
  2301 		return this;
       
  2302 	}
       
  2303 });
       
  2304 
       
  2305 jQuery.extend({
       
  2306 	isReady: false,
       
  2307 	readyList: [],
       
  2308 	// Handle when the DOM is ready
       
  2309 	ready: function() {
       
  2310 		// Make sure that the DOM is not already loaded
       
  2311 		if ( !jQuery.isReady ) {
       
  2312 			// Remember that the DOM is ready
       
  2313 			jQuery.isReady = true;
       
  2314 
       
  2315 			// If there are functions bound, to execute
       
  2316 			if ( jQuery.readyList ) {
       
  2317 				// Execute all of them
       
  2318 				jQuery.each( jQuery.readyList, function(){
       
  2319 					this.call( document );
       
  2320 				});
       
  2321 
       
  2322 				// Reset the list of functions
       
  2323 				jQuery.readyList = null;
       
  2324 			}
       
  2325 
       
  2326 			// Trigger any bound ready events
       
  2327 			jQuery(document).triggerHandler("ready");
       
  2328 		}
       
  2329 	}
       
  2330 });
       
  2331 
       
  2332 var readyBound = false;
       
  2333 
       
  2334 function bindReady(){
       
  2335 	if ( readyBound ) return;
       
  2336 	readyBound = true;
       
  2337 
       
  2338 	// Mozilla, Opera (see further below for it) and webkit nightlies currently support this event
       
  2339 	if ( document.addEventListener && !jQuery.browser.opera)
       
  2340 		// Use the handy event callback
       
  2341 		document.addEventListener( "DOMContentLoaded", jQuery.ready, false );
       
  2342 
       
  2343 	// If IE is used and is not in a frame
       
  2344 	// Continually check to see if the document is ready
       
  2345 	if ( jQuery.browser.msie && window == top ) (function(){
       
  2346 		if (jQuery.isReady) return;
       
  2347 		try {
       
  2348 			// If IE is used, use the trick by Diego Perini
       
  2349 			// http://javascript.nwbox.com/IEContentLoaded/
       
  2350 			document.documentElement.doScroll("left");
       
  2351 		} catch( error ) {
       
  2352 			setTimeout( arguments.callee, 0 );
       
  2353 			return;
       
  2354 		}
       
  2355 		// and execute any waiting functions
       
  2356 		jQuery.ready();
       
  2357 	})();
       
  2358 
       
  2359 	if ( jQuery.browser.opera )
       
  2360 		document.addEventListener( "DOMContentLoaded", function () {
       
  2361 			if (jQuery.isReady) return;
       
  2362 			for (var i = 0; i < document.styleSheets.length; i++)
       
  2363 				if (document.styleSheets[i].disabled) {
       
  2364 					setTimeout( arguments.callee, 0 );
       
  2365 					return;
       
  2366 				}
       
  2367 			// and execute any waiting functions
       
  2368 			jQuery.ready();
       
  2369 		}, false);
       
  2370 
       
  2371 	if ( jQuery.browser.safari ) {
       
  2372 		var numStyles;
       
  2373 		(function(){
       
  2374 			if (jQuery.isReady) return;
       
  2375 			if ( document.readyState != "loaded" && document.readyState != "complete" ) {
       
  2376 				setTimeout( arguments.callee, 0 );
       
  2377 				return;
       
  2378 			}
       
  2379 			if ( numStyles === undefined )
       
  2380 				numStyles = jQuery("style, link[rel=stylesheet]").length;
       
  2381 			if ( document.styleSheets.length != numStyles ) {
       
  2382 				setTimeout( arguments.callee, 0 );
       
  2383 				return;
       
  2384 			}
       
  2385 			// and execute any waiting functions
       
  2386 			jQuery.ready();
       
  2387 		})();
       
  2388 	}
       
  2389 
       
  2390 	// A fallback to window.onload, that will always work
       
  2391 	jQuery.event.add( window, "load", jQuery.ready );
       
  2392 }
       
  2393 
       
  2394 jQuery.each( ("blur,focus,load,resize,scroll,unload,click,dblclick," +
       
  2395 	"mousedown,mouseup,mousemove,mouseover,mouseout,change,select," +
       
  2396 	"submit,keydown,keypress,keyup,error").split(","), function(i, name){
       
  2397 
       
  2398 	// Handle event binding
       
  2399 	jQuery.fn[name] = function(fn){
       
  2400 		return fn ? this.bind(name, fn) : this.trigger(name);
       
  2401 	};
       
  2402 });
       
  2403 
       
  2404 // Checks if an event happened on an element within another element
       
  2405 // Used in jQuery.event.special.mouseenter and mouseleave handlers
       
  2406 var withinElement = function(event, elem) {
       
  2407 	// Check if mouse(over|out) are still within the same parent element
       
  2408 	var parent = event.relatedTarget;
       
  2409 	// Traverse up the tree
       
  2410 	while ( parent && parent != elem ) try { parent = parent.parentNode; } catch(error) { parent = elem; }
       
  2411 	// Return true if we actually just moused on to a sub-element
       
  2412 	return parent == elem;
       
  2413 };
       
  2414 
       
  2415 // Prevent memory leaks in IE
       
  2416 // And prevent errors on refresh with events like mouseover in other browsers
       
  2417 // Window isn't included so as not to unbind existing unload events
       
  2418 jQuery(window).bind("unload", function() {
       
  2419 	jQuery("*").add(document).unbind();
       
  2420 });
       
  2421 jQuery.fn.extend({
       
  2422 	// Keep a copy of the old load
       
  2423 	_load: jQuery.fn.load,
       
  2424 
       
  2425 	load: function( url, params, callback ) {
       
  2426 		if ( typeof url != 'string' )
       
  2427 			return this._load( url );
       
  2428 
       
  2429 		var off = url.indexOf(" ");
       
  2430 		if ( off >= 0 ) {
       
  2431 			var selector = url.slice(off, url.length);
       
  2432 			url = url.slice(0, off);
       
  2433 		}
       
  2434 
       
  2435 		callback = callback || function(){};
       
  2436 
       
  2437 		// Default to a GET request
       
  2438 		var type = "GET";
       
  2439 
       
  2440 		// If the second parameter was provided
       
  2441 		if ( params )
       
  2442 			// If it's a function
       
  2443 			if ( jQuery.isFunction( params ) ) {
       
  2444 				// We assume that it's the callback
       
  2445 				callback = params;
       
  2446 				params = null;
       
  2447 
       
  2448 			// Otherwise, build a param string
       
  2449 			} else if( typeof params == 'object' ) {
       
  2450 				params = jQuery.param( params );
       
  2451 				type = "POST";
       
  2452 			}
       
  2453 
       
  2454 		var self = this;
       
  2455 
       
  2456 		// Request the remote document
       
  2457 		jQuery.ajax({
       
  2458 			url: url,
       
  2459 			type: type,
       
  2460 			dataType: "html",
       
  2461 			data: params,
       
  2462 			complete: function(res, status){
       
  2463 				// If successful, inject the HTML into all the matched elements
       
  2464 				if ( status == "success" || status == "notmodified" )
       
  2465 					// See if a selector was specified
       
  2466 					self.html( selector ?
       
  2467 						// Create a dummy div to hold the results
       
  2468 						jQuery("<div/>")
       
  2469 							// inject the contents of the document in, removing the scripts
       
  2470 							// to avoid any 'Permission Denied' errors in IE
       
  2471 							.append(res.responseText.replace(/<script(.|\s)*?\/script>/g, ""))
       
  2472 
       
  2473 							// Locate the specified elements
       
  2474 							.find(selector) :
       
  2475 
       
  2476 						// If not, just inject the full result
       
  2477 						res.responseText );
       
  2478 
       
  2479 				self.each( callback, [res.responseText, status, res] );
       
  2480 			}
       
  2481 		});
       
  2482 		return this;
       
  2483 	},
       
  2484 
       
  2485 	serialize: function() {
       
  2486 		return jQuery.param(this.serializeArray());
       
  2487 	},
       
  2488 	serializeArray: function() {
       
  2489 		return this.map(function(){
       
  2490 			return jQuery.nodeName(this, "form") ?
       
  2491 				jQuery.makeArray(this.elements) : this;
       
  2492 		})
       
  2493 		.filter(function(){
       
  2494 			return this.name && !this.disabled &&
       
  2495 				(this.checked || /select|textarea/i.test(this.nodeName) ||
       
  2496 					/text|hidden|password/i.test(this.type));
       
  2497 		})
       
  2498 		.map(function(i, elem){
       
  2499 			var val = jQuery(this).val();
       
  2500 			return val == null ? null :
       
  2501 				val.constructor == Array ?
       
  2502 					jQuery.map( val, function(val, i){
       
  2503 						return {name: elem.name, value: val};
       
  2504 					}) :
       
  2505 					{name: elem.name, value: val};
       
  2506 		}).get();
       
  2507 	}
       
  2508 });
       
  2509 
       
  2510 // Attach a bunch of functions for handling common AJAX events
       
  2511 jQuery.each( "ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","), function(i,o){
       
  2512 	jQuery.fn[o] = function(f){
       
  2513 		return this.bind(o, f);
       
  2514 	};
       
  2515 });
       
  2516 
       
  2517 var jsc = now();
       
  2518 
       
  2519 jQuery.extend({
       
  2520 	get: function( url, data, callback, type ) {
       
  2521 		// shift arguments if data argument was ommited
       
  2522 		if ( jQuery.isFunction( data ) ) {
       
  2523 			callback = data;
       
  2524 			data = null;
       
  2525 		}
       
  2526 
       
  2527 		return jQuery.ajax({
       
  2528 			type: "GET",
       
  2529 			url: url,
       
  2530 			data: data,
       
  2531 			success: callback,
       
  2532 			dataType: type
       
  2533 		});
       
  2534 	},
       
  2535 
       
  2536 	getScript: function( url, callback ) {
       
  2537 		return jQuery.get(url, null, callback, "script");
       
  2538 	},
       
  2539 
       
  2540 	getJSON: function( url, data, callback ) {
       
  2541 		return jQuery.get(url, data, callback, "json");
       
  2542 	},
       
  2543 
       
  2544 	post: function( url, data, callback, type ) {
       
  2545 		if ( jQuery.isFunction( data ) ) {
       
  2546 			callback = data;
       
  2547 			data = {};
       
  2548 		}
       
  2549 
       
  2550 		return jQuery.ajax({
       
  2551 			type: "POST",
       
  2552 			url: url,
       
  2553 			data: data,
       
  2554 			success: callback,
       
  2555 			dataType: type
       
  2556 		});
       
  2557 	},
       
  2558 
       
  2559 	ajaxSetup: function( settings ) {
       
  2560 		jQuery.extend( jQuery.ajaxSettings, settings );
       
  2561 	},
       
  2562 
       
  2563 	ajaxSettings: {
       
  2564 		url: location.href,
       
  2565 		global: true,
       
  2566 		type: "GET",
       
  2567 		timeout: 0,
       
  2568 		contentType: "application/x-www-form-urlencoded",
       
  2569 		processData: true,
       
  2570 		async: true,
       
  2571 		data: null,
       
  2572 		username: null,
       
  2573 		password: null,
       
  2574 		accepts: {
       
  2575 			xml: "application/xml, text/xml",
       
  2576 			html: "text/html",
       
  2577 			script: "text/javascript, application/javascript",
       
  2578 			json: "application/json, text/javascript",
       
  2579 			text: "text/plain",
       
  2580 			_default: "*/*"
       
  2581 		}
       
  2582 	},
       
  2583 
       
  2584 	// Last-Modified header cache for next request
       
  2585 	lastModified: {},
       
  2586 
       
  2587 	ajax: function( s ) {
       
  2588 		// Extend the settings, but re-extend 's' so that it can be
       
  2589 		// checked again later (in the test suite, specifically)
       
  2590 		s = jQuery.extend(true, s, jQuery.extend(true, {}, jQuery.ajaxSettings, s));
       
  2591 
       
  2592 		var jsonp, jsre = /=\?(&|$)/g, status, data,
       
  2593 			type = s.type.toUpperCase();
       
  2594 
       
  2595 		// convert data if not already a string
       
  2596 		if ( s.data && s.processData && typeof s.data != "string" )
       
  2597 			s.data = jQuery.param(s.data);
       
  2598 
       
  2599 		// Handle JSONP Parameter Callbacks
       
  2600 		if ( s.dataType == "jsonp" ) {
       
  2601 			if ( type == "GET" ) {
       
  2602 				if ( !s.url.match(jsre) )
       
  2603 					s.url += (s.url.match(/\?/) ? "&" : "?") + (s.jsonp || "callback") + "=?";
       
  2604 			} else if ( !s.data || !s.data.match(jsre) )
       
  2605 				s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";
       
  2606 			s.dataType = "json";
       
  2607 		}
       
  2608 
       
  2609 		// Build temporary JSONP function
       
  2610 		if ( s.dataType == "json" && (s.data && s.data.match(jsre) || s.url.match(jsre)) ) {
       
  2611 			jsonp = "jsonp" + jsc++;
       
  2612 
       
  2613 			// Replace the =? sequence both in the query string and the data
       
  2614 			if ( s.data )
       
  2615 				s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");
       
  2616 			s.url = s.url.replace(jsre, "=" + jsonp + "$1");
       
  2617 
       
  2618 			// We need to make sure
       
  2619 			// that a JSONP style response is executed properly
       
  2620 			s.dataType = "script";
       
  2621 
       
  2622 			// Handle JSONP-style loading
       
  2623 			window[ jsonp ] = function(tmp){
       
  2624 				data = tmp;
       
  2625 				success();
       
  2626 				complete();
       
  2627 				// Garbage collect
       
  2628 				window[ jsonp ] = undefined;
       
  2629 				try{ delete window[ jsonp ]; } catch(e){}
       
  2630 				if ( head )
       
  2631 					head.removeChild( script );
       
  2632 			};
       
  2633 		}
       
  2634 
       
  2635 		if ( s.dataType == "script" && s.cache == null )
       
  2636 			s.cache = false;
       
  2637 
       
  2638 		if ( s.cache === false && type == "GET" ) {
       
  2639 			var ts = now();
       
  2640 			// try replacing _= if it is there
       
  2641 			var ret = s.url.replace(/(\?|&)_=.*?(&|$)/, "$1_=" + ts + "$2");
       
  2642 			// if nothing was replaced, add timestamp to the end
       
  2643 			s.url = ret + ((ret == s.url) ? (s.url.match(/\?/) ? "&" : "?") + "_=" + ts : "");
       
  2644 		}
       
  2645 
       
  2646 		// If data is available, append data to url for get requests
       
  2647 		if ( s.data && type == "GET" ) {
       
  2648 			s.url += (s.url.match(/\?/) ? "&" : "?") + s.data;
       
  2649 
       
  2650 			// IE likes to send both get and post data, prevent this
       
  2651 			s.data = null;
       
  2652 		}
       
  2653 
       
  2654 		// Watch for a new set of requests
       
  2655 		if ( s.global && ! jQuery.active++ )
       
  2656 			jQuery.event.trigger( "ajaxStart" );
       
  2657 
       
  2658 		// Matches an absolute URL, and saves the domain
       
  2659 		var remote = /^(?:\w+:)?\/\/([^\/?#]+)/;
       
  2660 
       
  2661 		// If we're requesting a remote document
       
  2662 		// and trying to load JSON or Script with a GET
       
  2663 		if ( s.dataType == "script" && type == "GET"
       
  2664 				&& remote.test(s.url) && remote.exec(s.url)[1] != location.host ){
       
  2665 			var head = document.getElementsByTagName("head")[0];
       
  2666 			var script = document.createElement("script");
       
  2667 			script.src = s.url;
       
  2668 			if (s.scriptCharset)
       
  2669 				script.charset = s.scriptCharset;
       
  2670 
       
  2671 			// Handle Script loading
       
  2672 			if ( !jsonp ) {
       
  2673 				var done = false;
       
  2674 
       
  2675 				// Attach handlers for all browsers
       
  2676 				script.onload = script.onreadystatechange = function(){
       
  2677 					if ( !done && (!this.readyState ||
       
  2678 							this.readyState == "loaded" || this.readyState == "complete") ) {
       
  2679 						done = true;
       
  2680 						success();
       
  2681 						complete();
       
  2682 						head.removeChild( script );
       
  2683 					}
       
  2684 				};
       
  2685 			}
       
  2686 
       
  2687 			head.appendChild(script);
       
  2688 
       
  2689 			// We handle everything using the script element injection
       
  2690 			return undefined;
       
  2691 		}
       
  2692 
       
  2693 		var requestDone = false;
       
  2694 
       
  2695 		// Create the request object; Microsoft failed to properly
       
  2696 		// implement the XMLHttpRequest in IE7, so we use the ActiveXObject when it is available
       
  2697 		var xhr = window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
       
  2698 
       
  2699 		// Open the socket
       
  2700 		// Passing null username, generates a login popup on Opera (#2865)
       
  2701 		if( s.username )
       
  2702 			xhr.open(type, s.url, s.async, s.username, s.password);
       
  2703 		else
       
  2704 			xhr.open(type, s.url, s.async);
       
  2705 
       
  2706 		// Need an extra try/catch for cross domain requests in Firefox 3
       
  2707 		try {
       
  2708 			// Set the correct header, if data is being sent
       
  2709 			if ( s.data )
       
  2710 				xhr.setRequestHeader("Content-Type", s.contentType);
       
  2711 
       
  2712 			// Set the If-Modified-Since header, if ifModified mode.
       
  2713 			if ( s.ifModified )
       
  2714 				xhr.setRequestHeader("If-Modified-Since",
       
  2715 					jQuery.lastModified[s.url] || "Thu, 01 Jan 1970 00:00:00 GMT" );
       
  2716 
       
  2717 			// Set header so the called script knows that it's an XMLHttpRequest
       
  2718 			xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
       
  2719 
       
  2720 			// Set the Accepts header for the server, depending on the dataType
       
  2721 			xhr.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ?
       
  2722 				s.accepts[ s.dataType ] + ", */*" :
       
  2723 				s.accepts._default );
       
  2724 		} catch(e){}
       
  2725 
       
  2726 		// Allow custom headers/mimetypes
       
  2727 		if ( s.beforeSend && s.beforeSend(xhr, s) === false ) {
       
  2728 			// cleanup active request counter
       
  2729 			s.global && jQuery.active--;
       
  2730 			// close opended socket
       
  2731 			xhr.abort();
       
  2732 			return false;
       
  2733 		}
       
  2734 
       
  2735 		if ( s.global )
       
  2736 			jQuery.event.trigger("ajaxSend", [xhr, s]);
       
  2737 
       
  2738 		// Wait for a response to come back
       
  2739 		var onreadystatechange = function(isTimeout){
       
  2740 			// The transfer is complete and the data is available, or the request timed out
       
  2741 			if ( !requestDone && xhr && (xhr.readyState == 4 || isTimeout == "timeout") ) {
       
  2742 				requestDone = true;
       
  2743 
       
  2744 				// clear poll interval
       
  2745 				if (ival) {
       
  2746 					clearInterval(ival);
       
  2747 					ival = null;
       
  2748 				}
       
  2749 
       
  2750 				status = isTimeout == "timeout" ? "timeout" :
       
  2751 					!jQuery.httpSuccess( xhr ) ? "error" :
       
  2752 					s.ifModified && jQuery.httpNotModified( xhr, s.url ) ? "notmodified" :
       
  2753 					"success";
       
  2754 
       
  2755 				if ( status == "success" ) {
       
  2756 					// Watch for, and catch, XML document parse errors
       
  2757 					try {
       
  2758 						// process the data (runs the xml through httpData regardless of callback)
       
  2759 						data = jQuery.httpData( xhr, s.dataType, s.dataFilter );
       
  2760 					} catch(e) {
       
  2761 						status = "parsererror";
       
  2762 					}
       
  2763 				}
       
  2764 
       
  2765 				// Make sure that the request was successful or notmodified
       
  2766 				if ( status == "success" ) {
       
  2767 					// Cache Last-Modified header, if ifModified mode.
       
  2768 					var modRes;
       
  2769 					try {
       
  2770 						modRes = xhr.getResponseHeader("Last-Modified");
       
  2771 					} catch(e) {} // swallow exception thrown by FF if header is not available
       
  2772 
       
  2773 					if ( s.ifModified && modRes )
       
  2774 						jQuery.lastModified[s.url] = modRes;
       
  2775 
       
  2776 					// JSONP handles its own success callback
       
  2777 					if ( !jsonp )
       
  2778 						success();
       
  2779 				} else
       
  2780 					jQuery.handleError(s, xhr, status);
       
  2781 
       
  2782 				// Fire the complete handlers
       
  2783 				complete();
       
  2784 
       
  2785 				// Stop memory leaks
       
  2786 				if ( s.async )
       
  2787 					xhr = null;
       
  2788 			}
       
  2789 		};
       
  2790 
       
  2791 		if ( s.async ) {
       
  2792 			// don't attach the handler to the request, just poll it instead
       
  2793 			var ival = setInterval(onreadystatechange, 13);
       
  2794 
       
  2795 			// Timeout checker
       
  2796 			if ( s.timeout > 0 )
       
  2797 				setTimeout(function(){
       
  2798 					// Check to see if the request is still happening
       
  2799 					if ( xhr ) {
       
  2800 						// Cancel the request
       
  2801 						xhr.abort();
       
  2802 
       
  2803 						if( !requestDone )
       
  2804 							onreadystatechange( "timeout" );
       
  2805 					}
       
  2806 				}, s.timeout);
       
  2807 		}
       
  2808 
       
  2809 		// Send the data
       
  2810 		try {
       
  2811 			xhr.send(s.data);
       
  2812 		} catch(e) {
       
  2813 			jQuery.handleError(s, xhr, null, e);
       
  2814 		}
       
  2815 
       
  2816 		// firefox 1.5 doesn't fire statechange for sync requests
       
  2817 		if ( !s.async )
       
  2818 			onreadystatechange();
       
  2819 
       
  2820 		function success(){
       
  2821 			// If a local callback was specified, fire it and pass it the data
       
  2822 			if ( s.success )
       
  2823 				s.success( data, status );
       
  2824 
       
  2825 			// Fire the global callback
       
  2826 			if ( s.global )
       
  2827 				jQuery.event.trigger( "ajaxSuccess", [xhr, s] );
       
  2828 		}
       
  2829 
       
  2830 		function complete(){
       
  2831 			// Process result
       
  2832 			if ( s.complete )
       
  2833 				s.complete(xhr, status);
       
  2834 
       
  2835 			// The request was completed
       
  2836 			if ( s.global )
       
  2837 				jQuery.event.trigger( "ajaxComplete", [xhr, s] );
       
  2838 
       
  2839 			// Handle the global AJAX counter
       
  2840 			if ( s.global && ! --jQuery.active )
       
  2841 				jQuery.event.trigger( "ajaxStop" );
       
  2842 		}
       
  2843 
       
  2844 		// return XMLHttpRequest to allow aborting the request etc.
       
  2845 		return xhr;
       
  2846 	},
       
  2847 
       
  2848 	handleError: function( s, xhr, status, e ) {
       
  2849 		// If a local callback was specified, fire it
       
  2850 		if ( s.error ) s.error( xhr, status, e );
       
  2851 
       
  2852 		// Fire the global callback
       
  2853 		if ( s.global )
       
  2854 			jQuery.event.trigger( "ajaxError", [xhr, s, e] );
       
  2855 	},
       
  2856 
       
  2857 	// Counter for holding the number of active queries
       
  2858 	active: 0,
       
  2859 
       
  2860 	// Determines if an XMLHttpRequest was successful or not
       
  2861 	httpSuccess: function( xhr ) {
       
  2862 		try {
       
  2863 			// IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450
       
  2864 			return !xhr.status && location.protocol == "file:" ||
       
  2865 				( xhr.status >= 200 && xhr.status < 300 ) || xhr.status == 304 || xhr.status == 1223 ||
       
  2866 				jQuery.browser.safari && xhr.status == undefined;
       
  2867 		} catch(e){}
       
  2868 		return false;
       
  2869 	},
       
  2870 
       
  2871 	// Determines if an XMLHttpRequest returns NotModified
       
  2872 	httpNotModified: function( xhr, url ) {
       
  2873 		try {
       
  2874 			var xhrRes = xhr.getResponseHeader("Last-Modified");
       
  2875 
       
  2876 			// Firefox always returns 200. check Last-Modified date
       
  2877 			return xhr.status == 304 || xhrRes == jQuery.lastModified[url] ||
       
  2878 				jQuery.browser.safari && xhr.status == undefined;
       
  2879 		} catch(e){}
       
  2880 		return false;
       
  2881 	},
       
  2882 
       
  2883 	httpData: function( xhr, type, filter ) {
       
  2884 		var ct = xhr.getResponseHeader("content-type"),
       
  2885 			xml = type == "xml" || !type && ct && ct.indexOf("xml") >= 0,
       
  2886 			data = xml ? xhr.responseXML : xhr.responseText;
       
  2887 
       
  2888 		if ( xml && data.documentElement.tagName == "parsererror" )
       
  2889 			throw "parsererror";
       
  2890 			
       
  2891 		// Allow a pre-filtering function to sanitize the response
       
  2892 		if( filter )
       
  2893 			data = filter( data, type );
       
  2894 
       
  2895 		// If the type is "script", eval it in global context
       
  2896 		if ( type == "script" )
       
  2897 			jQuery.globalEval( data );
       
  2898 
       
  2899 		// Get the JavaScript object, if JSON is used.
       
  2900 		if ( type == "json" )
       
  2901 			data = eval("(" + data + ")");
       
  2902 
       
  2903 		return data;
       
  2904 	},
       
  2905 
       
  2906 	// Serialize an array of form elements or a set of
       
  2907 	// key/values into a query string
       
  2908 	param: function( a ) {
       
  2909 		var s = [ ];
       
  2910 
       
  2911 		function add( key, value ){
       
  2912 			s[ s.length ] = encodeURIComponent(key) + '=' + encodeURIComponent(value);
       
  2913 		};
       
  2914 
       
  2915 		// If an array was passed in, assume that it is an array
       
  2916 		// of form elements
       
  2917 		if ( a.constructor == Array || a.jquery )
       
  2918 			// Serialize the form elements
       
  2919 			jQuery.each( a, function(){
       
  2920 				add( this.name, this.value );
       
  2921 			});
       
  2922 
       
  2923 		// Otherwise, assume that it's an object of key/value pairs
       
  2924 		else
       
  2925 			// Serialize the key/values
       
  2926 			for ( var j in a )
       
  2927 				// If the value is an array then the key names need to be repeated
       
  2928 				if ( a[j] && a[j].constructor == Array )
       
  2929 					jQuery.each( a[j], function(){
       
  2930 						add( j, this );
       
  2931 					});
       
  2932 				else
       
  2933 					add( j, jQuery.isFunction(a[j]) ? a[j]() : a[j] );
       
  2934 
       
  2935 		// Return the resulting serialization
       
  2936 		return s.join("&").replace(/%20/g, "+");
       
  2937 	}
       
  2938 
       
  2939 });
       
  2940 jQuery.fn.extend({
       
  2941 	show: function(speed,callback){
       
  2942 		return speed ?
       
  2943 			this.animate({
       
  2944 				height: "show", width: "show", opacity: "show"
       
  2945 			}, speed, callback) :
       
  2946 
       
  2947 			this.filter(":hidden").each(function(){
       
  2948 				this.style.display = this.oldblock || "";
       
  2949 				if ( jQuery.css(this,"display") == "none" ) {
       
  2950 					var elem = jQuery("<" + this.tagName + " />").appendTo("body");
       
  2951 					this.style.display = elem.css("display");
       
  2952 					// handle an edge condition where css is - div { display:none; } or similar
       
  2953 					if (this.style.display == "none")
       
  2954 						this.style.display = "block";
       
  2955 					elem.remove();
       
  2956 				}
       
  2957 			}).end();
       
  2958 	},
       
  2959 
       
  2960 	hide: function(speed,callback){
       
  2961 		return speed ?
       
  2962 			this.animate({
       
  2963 				height: "hide", width: "hide", opacity: "hide"
       
  2964 			}, speed, callback) :
       
  2965 
       
  2966 			this.filter(":visible").each(function(){
       
  2967 				this.oldblock = this.oldblock || jQuery.css(this,"display");
       
  2968 				this.style.display = "none";
       
  2969 			}).end();
       
  2970 	},
       
  2971 
       
  2972 	// Save the old toggle function
       
  2973 	_toggle: jQuery.fn.toggle,
       
  2974 
       
  2975 	toggle: function( fn, fn2 ){
       
  2976 		return jQuery.isFunction(fn) && jQuery.isFunction(fn2) ?
       
  2977 			this._toggle.apply( this, arguments ) :
       
  2978 			fn ?
       
  2979 				this.animate({
       
  2980 					height: "toggle", width: "toggle", opacity: "toggle"
       
  2981 				}, fn, fn2) :
       
  2982 				this.each(function(){
       
  2983 					jQuery(this)[ jQuery(this).is(":hidden") ? "show" : "hide" ]();
       
  2984 				});
       
  2985 	},
       
  2986 
       
  2987 	slideDown: function(speed,callback){
       
  2988 		return this.animate({height: "show"}, speed, callback);
       
  2989 	},
       
  2990 
       
  2991 	slideUp: function(speed,callback){
       
  2992 		return this.animate({height: "hide"}, speed, callback);
       
  2993 	},
       
  2994 
       
  2995 	slideToggle: function(speed, callback){
       
  2996 		return this.animate({height: "toggle"}, speed, callback);
       
  2997 	},
       
  2998 
       
  2999 	fadeIn: function(speed, callback){
       
  3000 		return this.animate({opacity: "show"}, speed, callback);
       
  3001 	},
       
  3002 
       
  3003 	fadeOut: function(speed, callback){
       
  3004 		return this.animate({opacity: "hide"}, speed, callback);
       
  3005 	},
       
  3006 
       
  3007 	fadeTo: function(speed,to,callback){
       
  3008 		return this.animate({opacity: to}, speed, callback);
       
  3009 	},
       
  3010 
       
  3011 	animate: function( prop, speed, easing, callback ) {
       
  3012 		var optall = jQuery.speed(speed, easing, callback);
       
  3013 
       
  3014 		return this[ optall.queue === false ? "each" : "queue" ](function(){
       
  3015 			if ( this.nodeType != 1)
       
  3016 				return false;
       
  3017 
       
  3018 			var opt = jQuery.extend({}, optall), p,
       
  3019 				hidden = jQuery(this).is(":hidden"), self = this;
       
  3020 
       
  3021 			for ( p in prop ) {
       
  3022 				if ( prop[p] == "hide" && hidden || prop[p] == "show" && !hidden )
       
  3023 					return opt.complete.call(this);
       
  3024 
       
  3025 				if ( p == "height" || p == "width" ) {
       
  3026 					// Store display property
       
  3027 					opt.display = jQuery.css(this, "display");
       
  3028 
       
  3029 					// Make sure that nothing sneaks out
       
  3030 					opt.overflow = this.style.overflow;
       
  3031 				}
       
  3032 			}
       
  3033 
       
  3034 			if ( opt.overflow != null )
       
  3035 				this.style.overflow = "hidden";
       
  3036 
       
  3037 			opt.curAnim = jQuery.extend({}, prop);
       
  3038 
       
  3039 			jQuery.each( prop, function(name, val){
       
  3040 				var e = new jQuery.fx( self, opt, name );
       
  3041 
       
  3042 				if ( /toggle|show|hide/.test(val) )
       
  3043 					e[ val == "toggle" ? hidden ? "show" : "hide" : val ]( prop );
       
  3044 				else {
       
  3045 					var parts = val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),
       
  3046 						start = e.cur(true) || 0;
       
  3047 
       
  3048 					if ( parts ) {
       
  3049 						var end = parseFloat(parts[2]),
       
  3050 							unit = parts[3] || "px";
       
  3051 
       
  3052 						// We need to compute starting value
       
  3053 						if ( unit != "px" ) {
       
  3054 							self.style[ name ] = (end || 1) + unit;
       
  3055 							start = ((end || 1) / e.cur(true)) * start;
       
  3056 							self.style[ name ] = start + unit;
       
  3057 						}
       
  3058 
       
  3059 						// If a +=/-= token was provided, we're doing a relative animation
       
  3060 						if ( parts[1] )
       
  3061 							end = ((parts[1] == "-=" ? -1 : 1) * end) + start;
       
  3062 
       
  3063 						e.custom( start, end, unit );
       
  3064 					} else
       
  3065 						e.custom( start, val, "" );
       
  3066 				}
       
  3067 			});
       
  3068 
       
  3069 			// For JS strict compliance
       
  3070 			return true;
       
  3071 		});
       
  3072 	},
       
  3073 
       
  3074 	queue: function(type, fn){
       
  3075 		if ( jQuery.isFunction(type) || ( type && type.constructor == Array )) {
       
  3076 			fn = type;
       
  3077 			type = "fx";
       
  3078 		}
       
  3079 
       
  3080 		if ( !type || (typeof type == "string" && !fn) )
       
  3081 			return queue( this[0], type );
       
  3082 
       
  3083 		return this.each(function(){
       
  3084 			if ( fn.constructor == Array )
       
  3085 				queue(this, type, fn);
       
  3086 			else {
       
  3087 				queue(this, type).push( fn );
       
  3088 
       
  3089 				if ( queue(this, type).length == 1 )
       
  3090 					fn.call(this);
       
  3091 			}
       
  3092 		});
       
  3093 	},
       
  3094 
       
  3095 	stop: function(clearQueue, gotoEnd){
       
  3096 		var timers = jQuery.timers;
       
  3097 
       
  3098 		if (clearQueue)
       
  3099 			this.queue([]);
       
  3100 
       
  3101 		this.each(function(){
       
  3102 			// go in reverse order so anything added to the queue during the loop is ignored
       
  3103 			for ( var i = timers.length - 1; i >= 0; i-- )
       
  3104 				if ( timers[i].elem == this ) {
       
  3105 					if (gotoEnd)
       
  3106 						// force the next step to be the last
       
  3107 						timers[i](true);
       
  3108 					timers.splice(i, 1);
       
  3109 				}
       
  3110 		});
       
  3111 
       
  3112 		// start the next in the queue if the last step wasn't forced
       
  3113 		if (!gotoEnd)
       
  3114 			this.dequeue();
       
  3115 
       
  3116 		return this;
       
  3117 	}
       
  3118 
       
  3119 });
       
  3120 
       
  3121 var queue = function( elem, type, array ) {
       
  3122 	if ( elem ){
       
  3123 
       
  3124 		type = type || "fx";
       
  3125 
       
  3126 		var q = jQuery.data( elem, type + "queue" );
       
  3127 
       
  3128 		if ( !q || array )
       
  3129 			q = jQuery.data( elem, type + "queue", jQuery.makeArray(array) );
       
  3130 
       
  3131 	}
       
  3132 	return q;
       
  3133 };
       
  3134 
       
  3135 jQuery.fn.dequeue = function(type){
       
  3136 	type = type || "fx";
       
  3137 
       
  3138 	return this.each(function(){
       
  3139 		var q = queue(this, type);
       
  3140 
       
  3141 		q.shift();
       
  3142 
       
  3143 		if ( q.length )
       
  3144 			q[0].call( this );
       
  3145 	});
       
  3146 };
       
  3147 
       
  3148 jQuery.extend({
       
  3149 
       
  3150 	speed: function(speed, easing, fn) {
       
  3151 		var opt = speed && speed.constructor == Object ? speed : {
       
  3152 			complete: fn || !fn && easing ||
       
  3153 				jQuery.isFunction( speed ) && speed,
       
  3154 			duration: speed,
       
  3155 			easing: fn && easing || easing && easing.constructor != Function && easing
       
  3156 		};
       
  3157 
       
  3158 		opt.duration = (opt.duration && opt.duration.constructor == Number ?
       
  3159 			opt.duration :
       
  3160 			jQuery.fx.speeds[opt.duration]) || jQuery.fx.speeds.def;
       
  3161 
       
  3162 		// Queueing
       
  3163 		opt.old = opt.complete;
       
  3164 		opt.complete = function(){
       
  3165 			if ( opt.queue !== false )
       
  3166 				jQuery(this).dequeue();
       
  3167 			if ( jQuery.isFunction( opt.old ) )
       
  3168 				opt.old.call( this );
       
  3169 		};
       
  3170 
       
  3171 		return opt;
       
  3172 	},
       
  3173 
       
  3174 	easing: {
       
  3175 		linear: function( p, n, firstNum, diff ) {
       
  3176 			return firstNum + diff * p;
       
  3177 		},
       
  3178 		swing: function( p, n, firstNum, diff ) {
       
  3179 			return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
       
  3180 		}
       
  3181 	},
       
  3182 
       
  3183 	timers: [],
       
  3184 	timerId: null,
       
  3185 
       
  3186 	fx: function( elem, options, prop ){
       
  3187 		this.options = options;
       
  3188 		this.elem = elem;
       
  3189 		this.prop = prop;
       
  3190 
       
  3191 		if ( !options.orig )
       
  3192 			options.orig = {};
       
  3193 	}
       
  3194 
       
  3195 });
       
  3196 
       
  3197 jQuery.fx.prototype = {
       
  3198 
       
  3199 	// Simple function for setting a style value
       
  3200 	update: function(){
       
  3201 		if ( this.options.step )
       
  3202 			this.options.step.call( this.elem, this.now, this );
       
  3203 
       
  3204 		(jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
       
  3205 
       
  3206 		// Set display property to block for height/width animations
       
  3207 		if ( this.prop == "height" || this.prop == "width" )
       
  3208 			this.elem.style.display = "block";
       
  3209 	},
       
  3210 
       
  3211 	// Get the current size
       
  3212 	cur: function(force){
       
  3213 		if ( this.elem[this.prop] != null && this.elem.style[this.prop] == null )
       
  3214 			return this.elem[ this.prop ];
       
  3215 
       
  3216 		var r = parseFloat(jQuery.css(this.elem, this.prop, force));
       
  3217 		return r && r > -10000 ? r : parseFloat(jQuery.curCSS(this.elem, this.prop)) || 0;
       
  3218 	},
       
  3219 
       
  3220 	// Start an animation from one number to another
       
  3221 	custom: function(from, to, unit){
       
  3222 		this.startTime = now();
       
  3223 		this.start = from;
       
  3224 		this.end = to;
       
  3225 		this.unit = unit || this.unit || "px";
       
  3226 		this.now = this.start;
       
  3227 		this.pos = this.state = 0;
       
  3228 		this.update();
       
  3229 
       
  3230 		var self = this;
       
  3231 		function t(gotoEnd){
       
  3232 			return self.step(gotoEnd);
       
  3233 		}
       
  3234 
       
  3235 		t.elem = this.elem;
       
  3236 
       
  3237 		jQuery.timers.push(t);
       
  3238 
       
  3239 		if ( jQuery.timerId == null ) {
       
  3240 			jQuery.timerId = setInterval(function(){
       
  3241 				var timers = jQuery.timers;
       
  3242 
       
  3243 				for ( var i = 0; i < timers.length; i++ )
       
  3244 					if ( !timers[i]() )
       
  3245 						timers.splice(i--, 1);
       
  3246 
       
  3247 				if ( !timers.length ) {
       
  3248 					clearInterval( jQuery.timerId );
       
  3249 					jQuery.timerId = null;
       
  3250 				}
       
  3251 			}, 13);
       
  3252 		}
       
  3253 	},
       
  3254 
       
  3255 	// Simple 'show' function
       
  3256 	show: function(){
       
  3257 		// Remember where we started, so that we can go back to it later
       
  3258 		this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );
       
  3259 		this.options.show = true;
       
  3260 
       
  3261 		// Begin the animation
       
  3262 		this.custom(0, this.cur());
       
  3263 
       
  3264 		// Make sure that we start at a small width/height to avoid any
       
  3265 		// flash of content
       
  3266 		if ( this.prop == "width" || this.prop == "height" )
       
  3267 			this.elem.style[this.prop] = "1px";
       
  3268 
       
  3269 		// Start by showing the element
       
  3270 		jQuery(this.elem).show();
       
  3271 	},
       
  3272 
       
  3273 	// Simple 'hide' function
       
  3274 	hide: function(){
       
  3275 		// Remember where we started, so that we can go back to it later
       
  3276 		this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );
       
  3277 		this.options.hide = true;
       
  3278 
       
  3279 		// Begin the animation
       
  3280 		this.custom(this.cur(), 0);
       
  3281 	},
       
  3282 
       
  3283 	// Each step of an animation
       
  3284 	step: function(gotoEnd){
       
  3285 		var t = now();
       
  3286 
       
  3287 		if ( gotoEnd || t > this.options.duration + this.startTime ) {
       
  3288 			this.now = this.end;
       
  3289 			this.pos = this.state = 1;
       
  3290 			this.update();
       
  3291 
       
  3292 			this.options.curAnim[ this.prop ] = true;
       
  3293 
       
  3294 			var done = true;
       
  3295 			for ( var i in this.options.curAnim )
       
  3296 				if ( this.options.curAnim[i] !== true )
       
  3297 					done = false;
       
  3298 
       
  3299 			if ( done ) {
       
  3300 				if ( this.options.display != null ) {
       
  3301 					// Reset the overflow
       
  3302 					this.elem.style.overflow = this.options.overflow;
       
  3303 
       
  3304 					// Reset the display
       
  3305 					this.elem.style.display = this.options.display;
       
  3306 					if ( jQuery.css(this.elem, "display") == "none" )
       
  3307 						this.elem.style.display = "block";
       
  3308 				}
       
  3309 
       
  3310 				// Hide the element if the "hide" operation was done
       
  3311 				if ( this.options.hide )
       
  3312 					this.elem.style.display = "none";
       
  3313 
       
  3314 				// Reset the properties, if the item has been hidden or shown
       
  3315 				if ( this.options.hide || this.options.show )
       
  3316 					for ( var p in this.options.curAnim )
       
  3317 						jQuery.attr(this.elem.style, p, this.options.orig[p]);
       
  3318 			}
       
  3319 
       
  3320 			if ( done )
       
  3321 				// Execute the complete function
       
  3322 				this.options.complete.call( this.elem );
       
  3323 
       
  3324 			return false;
       
  3325 		} else {
       
  3326 			var n = t - this.startTime;
       
  3327 			this.state = n / this.options.duration;
       
  3328 
       
  3329 			// Perform the easing function, defaults to swing
       
  3330 			this.pos = jQuery.easing[this.options.easing || (jQuery.easing.swing ? "swing" : "linear")](this.state, n, 0, 1, this.options.duration);
       
  3331 			this.now = this.start + ((this.end - this.start) * this.pos);
       
  3332 
       
  3333 			// Perform the next step of the animation
       
  3334 			this.update();
       
  3335 		}
       
  3336 
       
  3337 		return true;
       
  3338 	}
       
  3339 
       
  3340 };
       
  3341 
       
  3342 jQuery.extend( jQuery.fx, {
       
  3343 	speeds:{
       
  3344 		slow: 600,
       
  3345  		fast: 200,
       
  3346  		// Default speed
       
  3347  		def: 400
       
  3348 	},
       
  3349 	step: {
       
  3350 		scrollLeft: function(fx){
       
  3351 			fx.elem.scrollLeft = fx.now;
       
  3352 		},
       
  3353 
       
  3354 		scrollTop: function(fx){
       
  3355 			fx.elem.scrollTop = fx.now;
       
  3356 		},
       
  3357 
       
  3358 		opacity: function(fx){
       
  3359 			jQuery.attr(fx.elem.style, "opacity", fx.now);
       
  3360 		},
       
  3361 
       
  3362 		_default: function(fx){
       
  3363 			fx.elem.style[ fx.prop ] = fx.now + fx.unit;
       
  3364 		}
       
  3365 	}
       
  3366 });
       
  3367 // The Offset Method
       
  3368 // Originally By Brandon Aaron, part of the Dimension Plugin
       
  3369 // http://jquery.com/plugins/project/dimensions
       
  3370 jQuery.fn.offset = function() {
       
  3371 	var left = 0, top = 0, elem = this[0], results;
       
  3372 
       
  3373 	if ( elem ) with ( jQuery.browser ) {
       
  3374 		var parent       = elem.parentNode,
       
  3375 		    offsetChild  = elem,
       
  3376 		    offsetParent = elem.offsetParent,
       
  3377 		    doc          = elem.ownerDocument,
       
  3378 		    safari2      = safari && parseInt(version) < 522 && !/adobeair/i.test(userAgent),
       
  3379 		    css          = jQuery.curCSS,
       
  3380 		    fixed        = css(elem, "position") == "fixed";
       
  3381 
       
  3382 		// Use getBoundingClientRect if available
       
  3383 		if ( !(mozilla && elem == document.body) && elem.getBoundingClientRect ) {
       
  3384 			var box = elem.getBoundingClientRect();
       
  3385 
       
  3386 			// Add the document scroll offsets
       
  3387 			add(box.left + Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft),
       
  3388 				box.top  + Math.max(doc.documentElement.scrollTop,  doc.body.scrollTop));
       
  3389 
       
  3390 			// IE adds the HTML element's border, by default it is medium which is 2px
       
  3391 			// IE 6 and 7 quirks mode the border width is overwritable by the following css html { border: 0; }
       
  3392 			// IE 7 standards mode, the border is always 2px
       
  3393 			// This border/offset is typically represented by the clientLeft and clientTop properties
       
  3394 			// However, in IE6 and 7 quirks mode the clientLeft and clientTop properties are not updated when overwriting it via CSS
       
  3395 			// Therefore this method will be off by 2px in IE while in quirksmode
       
  3396 			add( -doc.documentElement.clientLeft, -doc.documentElement.clientTop );
       
  3397 
       
  3398 		// Otherwise loop through the offsetParents and parentNodes
       
  3399 		} else {
       
  3400 
       
  3401 			// Initial element offsets
       
  3402 			add( elem.offsetLeft, elem.offsetTop );
       
  3403 
       
  3404 			// Get parent offsets
       
  3405 			while ( offsetParent ) {
       
  3406 				// Add offsetParent offsets
       
  3407 				add( offsetParent.offsetLeft, offsetParent.offsetTop );
       
  3408 
       
  3409 				// Mozilla and Safari > 2 does not include the border on offset parents
       
  3410 				// However Mozilla adds the border for table or table cells
       
  3411 				if ( mozilla && !/^t(able|d|h)$/i.test(offsetParent.tagName) || safari && !safari2 )
       
  3412 					border( offsetParent );
       
  3413 
       
  3414 				// Add the document scroll offsets if position is fixed on any offsetParent
       
  3415 				if ( !fixed && css(offsetParent, "position") == "fixed" )
       
  3416 					fixed = true;
       
  3417 
       
  3418 				// Set offsetChild to previous offsetParent unless it is the body element
       
  3419 				offsetChild  = /^body$/i.test(offsetParent.tagName) ? offsetChild : offsetParent;
       
  3420 				// Get next offsetParent
       
  3421 				offsetParent = offsetParent.offsetParent;
       
  3422 			}
       
  3423 
       
  3424 			// Get parent scroll offsets
       
  3425 			while ( parent && parent.tagName && !/^body|html$/i.test(parent.tagName) ) {
       
  3426 				// Remove parent scroll UNLESS that parent is inline or a table to work around Opera inline/table scrollLeft/Top bug
       
  3427 				if ( !/^inline|table.*$/i.test(css(parent, "display")) )
       
  3428 					// Subtract parent scroll offsets
       
  3429 					add( -parent.scrollLeft, -parent.scrollTop );
       
  3430 
       
  3431 				// Mozilla does not add the border for a parent that has overflow != visible
       
  3432 				if ( mozilla && css(parent, "overflow") != "visible" )
       
  3433 					border( parent );
       
  3434 
       
  3435 				// Get next parent
       
  3436 				parent = parent.parentNode;
       
  3437 			}
       
  3438 
       
  3439 			// Safari <= 2 doubles body offsets with a fixed position element/offsetParent or absolutely positioned offsetChild
       
  3440 			// Mozilla doubles body offsets with a non-absolutely positioned offsetChild
       
  3441 			if ( (safari2 && (fixed || css(offsetChild, "position") == "absolute")) ||
       
  3442 				(mozilla && css(offsetChild, "position") != "absolute") )
       
  3443 					add( -doc.body.offsetLeft, -doc.body.offsetTop );
       
  3444 
       
  3445 			// Add the document scroll offsets if position is fixed
       
  3446 			if ( fixed )
       
  3447 				add(Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft),
       
  3448 					Math.max(doc.documentElement.scrollTop,  doc.body.scrollTop));
       
  3449 		}
       
  3450 
       
  3451 		// Return an object with top and left properties
       
  3452 		results = { top: top, left: left };
       
  3453 	}
       
  3454 
       
  3455 	function border(elem) {
       
  3456 		add( jQuery.curCSS(elem, "borderLeftWidth", true), jQuery.curCSS(elem, "borderTopWidth", true) );
       
  3457 	}
       
  3458 
       
  3459 	function add(l, t) {
       
  3460 		left += parseInt(l, 10) || 0;
       
  3461 		top += parseInt(t, 10) || 0;
       
  3462 	}
       
  3463 
       
  3464 	return results;
       
  3465 };
       
  3466 
       
  3467 
       
  3468 jQuery.fn.extend({
       
  3469 	position: function() {
       
  3470 		var left = 0, top = 0, results;
       
  3471 
       
  3472 		if ( this[0] ) {
       
  3473 			// Get *real* offsetParent
       
  3474 			var offsetParent = this.offsetParent(),
       
  3475 
       
  3476 			// Get correct offsets
       
  3477 			offset       = this.offset(),
       
  3478 			parentOffset = /^body|html$/i.test(offsetParent[0].tagName) ? { top: 0, left: 0 } : offsetParent.offset();
       
  3479 
       
  3480 			// Subtract element margins
       
  3481 			// note: when an element has margin: auto the offsetLeft and marginLeft 
       
  3482 			// are the same in Safari causing offset.left to incorrectly be 0
       
  3483 			offset.top  -= num( this, 'marginTop' );
       
  3484 			offset.left -= num( this, 'marginLeft' );
       
  3485 
       
  3486 			// Add offsetParent borders
       
  3487 			parentOffset.top  += num( offsetParent, 'borderTopWidth' );
       
  3488 			parentOffset.left += num( offsetParent, 'borderLeftWidth' );
       
  3489 
       
  3490 			// Subtract the two offsets
       
  3491 			results = {
       
  3492 				top:  offset.top  - parentOffset.top,
       
  3493 				left: offset.left - parentOffset.left
       
  3494 			};
       
  3495 		}
       
  3496 
       
  3497 		return results;
       
  3498 	},
       
  3499 
       
  3500 	offsetParent: function() {
       
  3501 		var offsetParent = this[0].offsetParent;
       
  3502 		while ( offsetParent && (!/^body|html$/i.test(offsetParent.tagName) && jQuery.css(offsetParent, 'position') == 'static') )
       
  3503 			offsetParent = offsetParent.offsetParent;
       
  3504 		return jQuery(offsetParent);
       
  3505 	}
       
  3506 });
       
  3507 
       
  3508 
       
  3509 // Create scrollLeft and scrollTop methods
       
  3510 jQuery.each( ['Left', 'Top'], function(i, name) {
       
  3511 	var method = 'scroll' + name;
       
  3512 	
       
  3513 	jQuery.fn[ method ] = function(val) {
       
  3514 		if (!this[0]) return;
       
  3515 
       
  3516 		return val != undefined ?
       
  3517 
       
  3518 			// Set the scroll offset
       
  3519 			this.each(function() {
       
  3520 				this == window || this == document ?
       
  3521 					window.scrollTo(
       
  3522 						!i ? val : jQuery(window).scrollLeft(),
       
  3523 						 i ? val : jQuery(window).scrollTop()
       
  3524 					) :
       
  3525 					this[ method ] = val;
       
  3526 			}) :
       
  3527 
       
  3528 			// Return the scroll offset
       
  3529 			this[0] == window || this[0] == document ?
       
  3530 				self[ i ? 'pageYOffset' : 'pageXOffset' ] ||
       
  3531 					jQuery.boxModel && document.documentElement[ method ] ||
       
  3532 					document.body[ method ] :
       
  3533 				this[0][ method ];
       
  3534 	};
       
  3535 });
       
  3536 // Create innerHeight, innerWidth, outerHeight and outerWidth methods
       
  3537 jQuery.each([ "Height", "Width" ], function(i, name){
       
  3538 
       
  3539 	var tl = i ? "Left"  : "Top",  // top or left
       
  3540 		br = i ? "Right" : "Bottom"; // bottom or right
       
  3541 
       
  3542 	// innerHeight and innerWidth
       
  3543 	jQuery.fn["inner" + name] = function(){
       
  3544 		return this[ name.toLowerCase() ]() +
       
  3545 			num(this, "padding" + tl) +
       
  3546 			num(this, "padding" + br);
       
  3547 	};
       
  3548 
       
  3549 	// outerHeight and outerWidth
       
  3550 	jQuery.fn["outer" + name] = function(margin) {
       
  3551 		return this["inner" + name]() +
       
  3552 			num(this, "border" + tl + "Width") +
       
  3553 			num(this, "border" + br + "Width") +
       
  3554 			(margin ?
       
  3555 				num(this, "margin" + tl) + num(this, "margin" + br) : 0);
       
  3556 	};
       
  3557 
       
  3558 });})();