org.symbian.tools.wrttools.previewer/preview/script/jquery-ui/js/jquery-1.2.6.min.js
changeset 391 62472296236e
parent 390 41fb932132ea
child 392 942398ff3ab7
child 393 5b968742b729
equal deleted inserted replaced
390:41fb932132ea 391:62472296236e
     1 (function(){
       
     2 /*
       
     3  * jQuery 1.2.6 - New Wave Javascript
       
     4  *
       
     5  * Copyright (c) 2008 John Resig (jquery.com)
       
     6  * Dual licensed under the MIT (MIT-LICENSE.txt)
       
     7  * and GPL (GPL-LICENSE.txt) licenses.
       
     8  *
       
     9  * $Date: 2008-05-24 14:22:17 -0400 (Sat, 24 May 2008) $
       
    10  * $Rev: 5685 $
       
    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 	}
       
  1250 });
       
  1251 
       
  1252 jQuery.each({
       
  1253 	parent: function(elem){return elem.parentNode;},
       
  1254 	parents: function(elem){return jQuery.dir(elem,"parentNode");},
       
  1255 	next: function(elem){return jQuery.nth(elem,2,"nextSibling");},
       
  1256 	prev: function(elem){return jQuery.nth(elem,2,"previousSibling");},
       
  1257 	nextAll: function(elem){return jQuery.dir(elem,"nextSibling");},
       
  1258 	prevAll: function(elem){return jQuery.dir(elem,"previousSibling");},
       
  1259 	siblings: function(elem){return jQuery.sibling(elem.parentNode.firstChild,elem);},
       
  1260 	children: function(elem){return jQuery.sibling(elem.firstChild);},
       
  1261 	contents: function(elem){return jQuery.nodeName(elem,"iframe")?elem.contentDocument||elem.contentWindow.document:jQuery.makeArray(elem.childNodes);}
       
  1262 }, function(name, fn){
       
  1263 	jQuery.fn[ name ] = function( selector ) {
       
  1264 		var ret = jQuery.map( this, fn );
       
  1265 
       
  1266 		if ( selector && typeof selector == "string" )
       
  1267 			ret = jQuery.multiFilter( selector, ret );
       
  1268 
       
  1269 		return this.pushStack( jQuery.unique( ret ) );
       
  1270 	};
       
  1271 });
       
  1272 
       
  1273 jQuery.each({
       
  1274 	appendTo: "append",
       
  1275 	prependTo: "prepend",
       
  1276 	insertBefore: "before",
       
  1277 	insertAfter: "after",
       
  1278 	replaceAll: "replaceWith"
       
  1279 }, function(name, original){
       
  1280 	jQuery.fn[ name ] = function() {
       
  1281 		var args = arguments;
       
  1282 
       
  1283 		return this.each(function(){
       
  1284 			for ( var i = 0, length = args.length; i < length; i++ )
       
  1285 				jQuery( args[ i ] )[ original ]( this );
       
  1286 		});
       
  1287 	};
       
  1288 });
       
  1289 
       
  1290 jQuery.each({
       
  1291 	removeAttr: function( name ) {
       
  1292 		jQuery.attr( this, name, "" );
       
  1293 		if (this.nodeType == 1)
       
  1294 			this.removeAttribute( name );
       
  1295 	},
       
  1296 
       
  1297 	addClass: function( classNames ) {
       
  1298 		jQuery.className.add( this, classNames );
       
  1299 	},
       
  1300 
       
  1301 	removeClass: function( classNames ) {
       
  1302 		jQuery.className.remove( this, classNames );
       
  1303 	},
       
  1304 
       
  1305 	toggleClass: function( classNames ) {
       
  1306 		jQuery.className[ jQuery.className.has( this, classNames ) ? "remove" : "add" ]( this, classNames );
       
  1307 	},
       
  1308 
       
  1309 	remove: function( selector ) {
       
  1310 		if ( !selector || jQuery.filter( selector, [ this ] ).r.length ) {
       
  1311 			// Prevent memory leaks
       
  1312 			jQuery( "*", this ).add(this).each(function(){
       
  1313 				jQuery.event.remove(this);
       
  1314 				jQuery.removeData(this);
       
  1315 			});
       
  1316 			if (this.parentNode)
       
  1317 				this.parentNode.removeChild( this );
       
  1318 		}
       
  1319 	},
       
  1320 
       
  1321 	empty: function() {
       
  1322 		// Remove element nodes and prevent memory leaks
       
  1323 		jQuery( ">*", this ).remove();
       
  1324 
       
  1325 		// Remove any remaining nodes
       
  1326 		while ( this.firstChild )
       
  1327 			this.removeChild( this.firstChild );
       
  1328 	}
       
  1329 }, function(name, fn){
       
  1330 	jQuery.fn[ name ] = function(){
       
  1331 		return this.each( fn, arguments );
       
  1332 	};
       
  1333 });
       
  1334 
       
  1335 jQuery.each([ "Height", "Width" ], function(i, name){
       
  1336 	var type = name.toLowerCase();
       
  1337 
       
  1338 	jQuery.fn[ type ] = function( size ) {
       
  1339 		// Get window width or height
       
  1340 		return this[0] == window ?
       
  1341 			// Opera reports document.body.client[Width/Height] properly in both quirks and standards
       
  1342 			jQuery.browser.opera && document.body[ "client" + name ] ||
       
  1343 
       
  1344 			// Safari reports inner[Width/Height] just fine (Mozilla and Opera include scroll bar widths)
       
  1345 			jQuery.browser.safari && window[ "inner" + name ] ||
       
  1346 
       
  1347 			// Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
       
  1348 			document.compatMode == "CSS1Compat" && document.documentElement[ "client" + name ] || document.body[ "client" + name ] :
       
  1349 
       
  1350 			// Get document width or height
       
  1351 			this[0] == document ?
       
  1352 				// Either scroll[Width/Height] or offset[Width/Height], whichever is greater
       
  1353 				Math.max(
       
  1354 					Math.max(document.body["scroll" + name], document.documentElement["scroll" + name]),
       
  1355 					Math.max(document.body["offset" + name], document.documentElement["offset" + name])
       
  1356 				) :
       
  1357 
       
  1358 				// Get or set width or height on the element
       
  1359 				size == undefined ?
       
  1360 					// Get width or height on the element
       
  1361 					(this.length ? jQuery.css( this[0], type ) : null) :
       
  1362 
       
  1363 					// Set the width or height on the element (default to pixels if value is unitless)
       
  1364 					this.css( type, size.constructor == String ? size : size + "px" );
       
  1365 	};
       
  1366 });
       
  1367 
       
  1368 // Helper function used by the dimensions and offset modules
       
  1369 function num(elem, prop) {
       
  1370 	return elem[0] && parseInt( jQuery.curCSS(elem[0], prop, true), 10 ) || 0;
       
  1371 }var chars = jQuery.browser.safari && parseInt(jQuery.browser.version) < 417 ?
       
  1372 		"(?:[\\w*_-]|\\\\.)" :
       
  1373 		"(?:[\\w\u0128-\uFFFF*_-]|\\\\.)",
       
  1374 	quickChild = new RegExp("^>\\s*(" + chars + "+)"),
       
  1375 	quickID = new RegExp("^(" + chars + "+)(#)(" + chars + "+)"),
       
  1376 	quickClass = new RegExp("^([#.]?)(" + chars + "*)");
       
  1377 
       
  1378 jQuery.extend({
       
  1379 	expr: {
       
  1380 		"": function(a,i,m){return m[2]=="*"||jQuery.nodeName(a,m[2]);},
       
  1381 		"#": function(a,i,m){return a.getAttribute("id")==m[2];},
       
  1382 		":": {
       
  1383 			// Position Checks
       
  1384 			lt: function(a,i,m){return i<m[3]-0;},
       
  1385 			gt: function(a,i,m){return i>m[3]-0;},
       
  1386 			nth: function(a,i,m){return m[3]-0==i;},
       
  1387 			eq: function(a,i,m){return m[3]-0==i;},
       
  1388 			first: function(a,i){return i==0;},
       
  1389 			last: function(a,i,m,r){return i==r.length-1;},
       
  1390 			even: function(a,i){return i%2==0;},
       
  1391 			odd: function(a,i){return i%2;},
       
  1392 
       
  1393 			// Child Checks
       
  1394 			"first-child": function(a){return a.parentNode.getElementsByTagName("*")[0]==a;},
       
  1395 			"last-child": function(a){return jQuery.nth(a.parentNode.lastChild,1,"previousSibling")==a;},
       
  1396 			"only-child": function(a){return !jQuery.nth(a.parentNode.lastChild,2,"previousSibling");},
       
  1397 
       
  1398 			// Parent Checks
       
  1399 			parent: function(a){return a.firstChild;},
       
  1400 			empty: function(a){return !a.firstChild;},
       
  1401 
       
  1402 			// Text Check
       
  1403 			contains: function(a,i,m){return (a.textContent||a.innerText||jQuery(a).text()||"").indexOf(m[3])>=0;},
       
  1404 
       
  1405 			// Visibility
       
  1406 			visible: function(a){return "hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden";},
       
  1407 			hidden: function(a){return "hidden"==a.type||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden";},
       
  1408 
       
  1409 			// Form attributes
       
  1410 			enabled: function(a){return !a.disabled;},
       
  1411 			disabled: function(a){return a.disabled;},
       
  1412 			checked: function(a){return a.checked;},
       
  1413 			selected: function(a){return a.selected||jQuery.attr(a,"selected");},
       
  1414 
       
  1415 			// Form elements
       
  1416 			text: function(a){return "text"==a.type;},
       
  1417 			radio: function(a){return "radio"==a.type;},
       
  1418 			checkbox: function(a){return "checkbox"==a.type;},
       
  1419 			file: function(a){return "file"==a.type;},
       
  1420 			password: function(a){return "password"==a.type;},
       
  1421 			submit: function(a){return "submit"==a.type;},
       
  1422 			image: function(a){return "image"==a.type;},
       
  1423 			reset: function(a){return "reset"==a.type;},
       
  1424 			button: function(a){return "button"==a.type||jQuery.nodeName(a,"button");},
       
  1425 			input: function(a){return /input|select|textarea|button/i.test(a.nodeName);},
       
  1426 
       
  1427 			// :has()
       
  1428 			has: function(a,i,m){return jQuery.find(m[3],a).length;},
       
  1429 
       
  1430 			// :header
       
  1431 			header: function(a){return /h\d/i.test(a.nodeName);},
       
  1432 
       
  1433 			// :animated
       
  1434 			animated: function(a){return jQuery.grep(jQuery.timers,function(fn){return a==fn.elem;}).length;}
       
  1435 		}
       
  1436 	},
       
  1437 
       
  1438 	// The regular expressions that power the parsing engine
       
  1439 	parse: [
       
  1440 		// Match: [@value='test'], [@foo]
       
  1441 		/^(\[) *@?([\w-]+) *([!*$^~=]*) *('?"?)(.*?)\4 *\]/,
       
  1442 
       
  1443 		// Match: :contains('foo')
       
  1444 		/^(:)([\w-]+)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/,
       
  1445 
       
  1446 		// Match: :even, :last-child, #id, .class
       
  1447 		new RegExp("^([:.#]*)(" + chars + "+)")
       
  1448 	],
       
  1449 
       
  1450 	multiFilter: function( expr, elems, not ) {
       
  1451 		var old, cur = [];
       
  1452 
       
  1453 		while ( expr && expr != old ) {
       
  1454 			old = expr;
       
  1455 			var f = jQuery.filter( expr, elems, not );
       
  1456 			expr = f.t.replace(/^\s*,\s*/, "" );
       
  1457 			cur = not ? elems = f.r : jQuery.merge( cur, f.r );
       
  1458 		}
       
  1459 
       
  1460 		return cur;
       
  1461 	},
       
  1462 
       
  1463 	find: function( t, context ) {
       
  1464 		// Quickly handle non-string expressions
       
  1465 		if ( typeof t != "string" )
       
  1466 			return [ t ];
       
  1467 
       
  1468 		// check to make sure context is a DOM element or a document
       
  1469 		if ( context && context.nodeType != 1 && context.nodeType != 9)
       
  1470 			return [ ];
       
  1471 
       
  1472 		// Set the correct context (if none is provided)
       
  1473 		context = context || document;
       
  1474 
       
  1475 		// Initialize the search
       
  1476 		var ret = [context], done = [], last, nodeName;
       
  1477 
       
  1478 		// Continue while a selector expression exists, and while
       
  1479 		// we're no longer looping upon ourselves
       
  1480 		while ( t && last != t ) {
       
  1481 			var r = [];
       
  1482 			last = t;
       
  1483 
       
  1484 			t = jQuery.trim(t);
       
  1485 
       
  1486 			var foundToken = false,
       
  1487 
       
  1488 			// An attempt at speeding up child selectors that
       
  1489 			// point to a specific element tag
       
  1490 				re = quickChild,
       
  1491 
       
  1492 				m = re.exec(t);
       
  1493 
       
  1494 			if ( m ) {
       
  1495 				nodeName = m[1].toUpperCase();
       
  1496 
       
  1497 				// Perform our own iteration and filter
       
  1498 				for ( var i = 0; ret[i]; i++ )
       
  1499 					for ( var c = ret[i].firstChild; c; c = c.nextSibling )
       
  1500 						if ( c.nodeType == 1 && (nodeName == "*" || c.nodeName.toUpperCase() == nodeName) )
       
  1501 							r.push( c );
       
  1502 
       
  1503 				ret = r;
       
  1504 				t = t.replace( re, "" );
       
  1505 				if ( t.indexOf(" ") == 0 ) continue;
       
  1506 				foundToken = true;
       
  1507 			} else {
       
  1508 				re = /^([>+~])\s*(\w*)/i;
       
  1509 
       
  1510 				if ( (m = re.exec(t)) != null ) {
       
  1511 					r = [];
       
  1512 
       
  1513 					var merge = {};
       
  1514 					nodeName = m[2].toUpperCase();
       
  1515 					m = m[1];
       
  1516 
       
  1517 					for ( var j = 0, rl = ret.length; j < rl; j++ ) {
       
  1518 						var n = m == "~" || m == "+" ? ret[j].nextSibling : ret[j].firstChild;
       
  1519 						for ( ; n; n = n.nextSibling )
       
  1520 							if ( n.nodeType == 1 ) {
       
  1521 								var id = jQuery.data(n);
       
  1522 
       
  1523 								if ( m == "~" && merge[id] ) break;
       
  1524 
       
  1525 								if (!nodeName || n.nodeName.toUpperCase() == nodeName ) {
       
  1526 									if ( m == "~" ) merge[id] = true;
       
  1527 									r.push( n );
       
  1528 								}
       
  1529 
       
  1530 								if ( m == "+" ) break;
       
  1531 							}
       
  1532 					}
       
  1533 
       
  1534 					ret = r;
       
  1535 
       
  1536 					// And remove the token
       
  1537 					t = jQuery.trim( t.replace( re, "" ) );
       
  1538 					foundToken = true;
       
  1539 				}
       
  1540 			}
       
  1541 
       
  1542 			// See if there's still an expression, and that we haven't already
       
  1543 			// matched a token
       
  1544 			if ( t && !foundToken ) {
       
  1545 				// Handle multiple expressions
       
  1546 				if ( !t.indexOf(",") ) {
       
  1547 					// Clean the result set
       
  1548 					if ( context == ret[0] ) ret.shift();
       
  1549 
       
  1550 					// Merge the result sets
       
  1551 					done = jQuery.merge( done, ret );
       
  1552 
       
  1553 					// Reset the context
       
  1554 					r = ret = [context];
       
  1555 
       
  1556 					// Touch up the selector string
       
  1557 					t = " " + t.substr(1,t.length);
       
  1558 
       
  1559 				} else {
       
  1560 					// Optimize for the case nodeName#idName
       
  1561 					var re2 = quickID;
       
  1562 					var m = re2.exec(t);
       
  1563 
       
  1564 					// Re-organize the results, so that they're consistent
       
  1565 					if ( m ) {
       
  1566 						m = [ 0, m[2], m[3], m[1] ];
       
  1567 
       
  1568 					} else {
       
  1569 						// Otherwise, do a traditional filter check for
       
  1570 						// ID, class, and element selectors
       
  1571 						re2 = quickClass;
       
  1572 						m = re2.exec(t);
       
  1573 					}
       
  1574 
       
  1575 					m[2] = m[2].replace(/\\/g, "");
       
  1576 
       
  1577 					var elem = ret[ret.length-1];
       
  1578 
       
  1579 					// Try to do a global search by ID, where we can
       
  1580 					if ( m[1] == "#" && elem && elem.getElementById && !jQuery.isXMLDoc(elem) ) {
       
  1581 						// Optimization for HTML document case
       
  1582 						var oid = elem.getElementById(m[2]);
       
  1583 
       
  1584 						// Do a quick check for the existence of the actual ID attribute
       
  1585 						// to avoid selecting by the name attribute in IE
       
  1586 						// also check to insure id is a string to avoid selecting an element with the name of 'id' inside a form
       
  1587 						if ( (jQuery.browser.msie||jQuery.browser.opera) && oid && typeof oid.id == "string" && oid.id != m[2] )
       
  1588 							oid = jQuery('[@id="'+m[2]+'"]', elem)[0];
       
  1589 
       
  1590 						// Do a quick check for node name (where applicable) so
       
  1591 						// that div#foo searches will be really fast
       
  1592 						ret = r = oid && (!m[3] || jQuery.nodeName(oid, m[3])) ? [oid] : [];
       
  1593 					} else {
       
  1594 						// We need to find all descendant elements
       
  1595 						for ( var i = 0; ret[i]; i++ ) {
       
  1596 							// Grab the tag name being searched for
       
  1597 							var tag = m[1] == "#" && m[3] ? m[3] : m[1] != "" || m[0] == "" ? "*" : m[2];
       
  1598 
       
  1599 							// Handle IE7 being really dumb about <object>s
       
  1600 							if ( tag == "*" && ret[i].nodeName.toLowerCase() == "object" )
       
  1601 								tag = "param";
       
  1602 
       
  1603 							r = jQuery.merge( r, ret[i].getElementsByTagName( tag ));
       
  1604 						}
       
  1605 
       
  1606 						// It's faster to filter by class and be done with it
       
  1607 						if ( m[1] == "." )
       
  1608 							r = jQuery.classFilter( r, m[2] );
       
  1609 
       
  1610 						// Same with ID filtering
       
  1611 						if ( m[1] == "#" ) {
       
  1612 							var tmp = [];
       
  1613 
       
  1614 							// Try to find the element with the ID
       
  1615 							for ( var i = 0; r[i]; i++ )
       
  1616 								if ( r[i].getAttribute("id") == m[2] ) {
       
  1617 									tmp = [ r[i] ];
       
  1618 									break;
       
  1619 								}
       
  1620 
       
  1621 							r = tmp;
       
  1622 						}
       
  1623 
       
  1624 						ret = r;
       
  1625 					}
       
  1626 
       
  1627 					t = t.replace( re2, "" );
       
  1628 				}
       
  1629 
       
  1630 			}
       
  1631 
       
  1632 			// If a selector string still exists
       
  1633 			if ( t ) {
       
  1634 				// Attempt to filter it
       
  1635 				var val = jQuery.filter(t,r);
       
  1636 				ret = r = val.r;
       
  1637 				t = jQuery.trim(val.t);
       
  1638 			}
       
  1639 		}
       
  1640 
       
  1641 		// An error occurred with the selector;
       
  1642 		// just return an empty set instead
       
  1643 		if ( t )
       
  1644 			ret = [];
       
  1645 
       
  1646 		// Remove the root context
       
  1647 		if ( ret && context == ret[0] )
       
  1648 			ret.shift();
       
  1649 
       
  1650 		// And combine the results
       
  1651 		done = jQuery.merge( done, ret );
       
  1652 
       
  1653 		return done;
       
  1654 	},
       
  1655 
       
  1656 	classFilter: function(r,m,not){
       
  1657 		m = " " + m + " ";
       
  1658 		var tmp = [];
       
  1659 		for ( var i = 0; r[i]; i++ ) {
       
  1660 			var pass = (" " + r[i].className + " ").indexOf( m ) >= 0;
       
  1661 			if ( !not && pass || not && !pass )
       
  1662 				tmp.push( r[i] );
       
  1663 		}
       
  1664 		return tmp;
       
  1665 	},
       
  1666 
       
  1667 	filter: function(t,r,not) {
       
  1668 		var last;
       
  1669 
       
  1670 		// Look for common filter expressions
       
  1671 		while ( t && t != last ) {
       
  1672 			last = t;
       
  1673 
       
  1674 			var p = jQuery.parse, m;
       
  1675 
       
  1676 			for ( var i = 0; p[i]; i++ ) {
       
  1677 				m = p[i].exec( t );
       
  1678 
       
  1679 				if ( m ) {
       
  1680 					// Remove what we just matched
       
  1681 					t = t.substring( m[0].length );
       
  1682 
       
  1683 					m[2] = m[2].replace(/\\/g, "");
       
  1684 					break;
       
  1685 				}
       
  1686 			}
       
  1687 
       
  1688 			if ( !m )
       
  1689 				break;
       
  1690 
       
  1691 			// :not() is a special case that can be optimized by
       
  1692 			// keeping it out of the expression list
       
  1693 			if ( m[1] == ":" && m[2] == "not" )
       
  1694 				// optimize if only one selector found (most common case)
       
  1695 				r = isSimple.test( m[3] ) ?
       
  1696 					jQuery.filter(m[3], r, true).r :
       
  1697 					jQuery( r ).not( m[3] );
       
  1698 
       
  1699 			// We can get a big speed boost by filtering by class here
       
  1700 			else if ( m[1] == "." )
       
  1701 				r = jQuery.classFilter(r, m[2], not);
       
  1702 
       
  1703 			else if ( m[1] == "[" ) {
       
  1704 				var tmp = [], type = m[3];
       
  1705 
       
  1706 				for ( var i = 0, rl = r.length; i < rl; i++ ) {
       
  1707 					var a = r[i], z = a[ jQuery.props[m[2]] || m[2] ];
       
  1708 
       
  1709 					if ( z == null || /href|src|selected/.test(m[2]) )
       
  1710 						z = jQuery.attr(a,m[2]) || '';
       
  1711 
       
  1712 					if ( (type == "" && !!z ||
       
  1713 						 type == "=" && z == m[5] ||
       
  1714 						 type == "!=" && z != m[5] ||
       
  1715 						 type == "^=" && z && !z.indexOf(m[5]) ||
       
  1716 						 type == "$=" && z.substr(z.length - m[5].length) == m[5] ||
       
  1717 						 (type == "*=" || type == "~=") && z.indexOf(m[5]) >= 0) ^ not )
       
  1718 							tmp.push( a );
       
  1719 				}
       
  1720 
       
  1721 				r = tmp;
       
  1722 
       
  1723 			// We can get a speed boost by handling nth-child here
       
  1724 			} else if ( m[1] == ":" && m[2] == "nth-child" ) {
       
  1725 				var merge = {}, tmp = [],
       
  1726 					// parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
       
  1727 					test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
       
  1728 						m[3] == "even" && "2n" || m[3] == "odd" && "2n+1" ||
       
  1729 						!/\D/.test(m[3]) && "0n+" + m[3] || m[3]),
       
  1730 					// calculate the numbers (first)n+(last) including if they are negative
       
  1731 					first = (test[1] + (test[2] || 1)) - 0, last = test[3] - 0;
       
  1732 
       
  1733 				// loop through all the elements left in the jQuery object
       
  1734 				for ( var i = 0, rl = r.length; i < rl; i++ ) {
       
  1735 					var node = r[i], parentNode = node.parentNode, id = jQuery.data(parentNode);
       
  1736 
       
  1737 					if ( !merge[id] ) {
       
  1738 						var c = 1;
       
  1739 
       
  1740 						for ( var n = parentNode.firstChild; n; n = n.nextSibling )
       
  1741 							if ( n.nodeType == 1 )
       
  1742 								n.nodeIndex = c++;
       
  1743 
       
  1744 						merge[id] = true;
       
  1745 					}
       
  1746 
       
  1747 					var add = false;
       
  1748 
       
  1749 					if ( first == 0 ) {
       
  1750 						if ( node.nodeIndex == last )
       
  1751 							add = true;
       
  1752 					} else if ( (node.nodeIndex - last) % first == 0 && (node.nodeIndex - last) / first >= 0 )
       
  1753 						add = true;
       
  1754 
       
  1755 					if ( add ^ not )
       
  1756 						tmp.push( node );
       
  1757 				}
       
  1758 
       
  1759 				r = tmp;
       
  1760 
       
  1761 			// Otherwise, find the expression to execute
       
  1762 			} else {
       
  1763 				var fn = jQuery.expr[ m[1] ];
       
  1764 				if ( typeof fn == "object" )
       
  1765 					fn = fn[ m[2] ];
       
  1766 
       
  1767 				if ( typeof fn == "string" )
       
  1768 					fn = eval("false||function(a,i){return " + fn + ";}");
       
  1769 
       
  1770 				// Execute it against the current filter
       
  1771 				r = jQuery.grep( r, function(elem, i){
       
  1772 					return fn(elem, i, m, r);
       
  1773 				}, not );
       
  1774 			}
       
  1775 		}
       
  1776 
       
  1777 		// Return an array of filtered elements (r)
       
  1778 		// and the modified expression string (t)
       
  1779 		return { r: r, t: t };
       
  1780 	},
       
  1781 
       
  1782 	dir: function( elem, dir ){
       
  1783 		var matched = [],
       
  1784 			cur = elem[dir];
       
  1785 		while ( cur && cur != document ) {
       
  1786 			if ( cur.nodeType == 1 )
       
  1787 				matched.push( cur );
       
  1788 			cur = cur[dir];
       
  1789 		}
       
  1790 		return matched;
       
  1791 	},
       
  1792 
       
  1793 	nth: function(cur,result,dir,elem){
       
  1794 		result = result || 1;
       
  1795 		var num = 0;
       
  1796 
       
  1797 		for ( ; cur; cur = cur[dir] )
       
  1798 			if ( cur.nodeType == 1 && ++num == result )
       
  1799 				break;
       
  1800 
       
  1801 		return cur;
       
  1802 	},
       
  1803 
       
  1804 	sibling: function( n, elem ) {
       
  1805 		var r = [];
       
  1806 
       
  1807 		for ( ; n; n = n.nextSibling ) {
       
  1808 			if ( n.nodeType == 1 && n != elem )
       
  1809 				r.push( n );
       
  1810 		}
       
  1811 
       
  1812 		return r;
       
  1813 	}
       
  1814 });
       
  1815 /*
       
  1816  * A number of helper functions used for managing events.
       
  1817  * Many of the ideas behind this code orignated from
       
  1818  * Dean Edwards' addEvent library.
       
  1819  */
       
  1820 jQuery.event = {
       
  1821 
       
  1822 	// Bind an event to an element
       
  1823 	// Original by Dean Edwards
       
  1824 	add: function(elem, types, handler, data) {
       
  1825 		if ( elem.nodeType == 3 || elem.nodeType == 8 )
       
  1826 			return;
       
  1827 
       
  1828 		// For whatever reason, IE has trouble passing the window object
       
  1829 		// around, causing it to be cloned in the process
       
  1830 		if ( jQuery.browser.msie && elem.setInterval )
       
  1831 			elem = window;
       
  1832 
       
  1833 		// Make sure that the function being executed has a unique ID
       
  1834 		if ( !handler.guid )
       
  1835 			handler.guid = this.guid++;
       
  1836 
       
  1837 		// if data is passed, bind to handler
       
  1838 		if( data != undefined ) {
       
  1839 			// Create temporary function pointer to original handler
       
  1840 			var fn = handler;
       
  1841 
       
  1842 			// Create unique handler function, wrapped around original handler
       
  1843 			handler = this.proxy( fn, function() {
       
  1844 				// Pass arguments and context to original handler
       
  1845 				return fn.apply(this, arguments);
       
  1846 			});
       
  1847 
       
  1848 			// Store data in unique handler
       
  1849 			handler.data = data;
       
  1850 		}
       
  1851 
       
  1852 		// Init the element's event structure
       
  1853 		var events = jQuery.data(elem, "events") || jQuery.data(elem, "events", {}),
       
  1854 			handle = jQuery.data(elem, "handle") || jQuery.data(elem, "handle", function(){
       
  1855 				// Handle the second event of a trigger and when
       
  1856 				// an event is called after a page has unloaded
       
  1857 				if ( typeof jQuery != "undefined" && !jQuery.event.triggered )
       
  1858 					return jQuery.event.handle.apply(arguments.callee.elem, arguments);
       
  1859 			});
       
  1860 		// Add elem as a property of the handle function
       
  1861 		// This is to prevent a memory leak with non-native
       
  1862 		// event in IE.
       
  1863 		handle.elem = elem;
       
  1864 
       
  1865 		// Handle multiple events separated by a space
       
  1866 		// jQuery(...).bind("mouseover mouseout", fn);
       
  1867 		jQuery.each(types.split(/\s+/), function(index, type) {
       
  1868 			// Namespaced event handlers
       
  1869 			var parts = type.split(".");
       
  1870 			type = parts[0];
       
  1871 			handler.type = parts[1];
       
  1872 
       
  1873 			// Get the current list of functions bound to this event
       
  1874 			var handlers = events[type];
       
  1875 
       
  1876 			// Init the event handler queue
       
  1877 			if (!handlers) {
       
  1878 				handlers = events[type] = {};
       
  1879 
       
  1880 				// Check for a special event handler
       
  1881 				// Only use addEventListener/attachEvent if the special
       
  1882 				// events handler returns false
       
  1883 				if ( !jQuery.event.special[type] || jQuery.event.special[type].setup.call(elem) === false ) {
       
  1884 					// Bind the global event handler to the element
       
  1885 					if (elem.addEventListener)
       
  1886 						elem.addEventListener(type, handle, false);
       
  1887 					else if (elem.attachEvent)
       
  1888 						elem.attachEvent("on" + type, handle);
       
  1889 				}
       
  1890 			}
       
  1891 
       
  1892 			// Add the function to the element's handler list
       
  1893 			handlers[handler.guid] = handler;
       
  1894 
       
  1895 			// Keep track of which events have been used, for global triggering
       
  1896 			jQuery.event.global[type] = true;
       
  1897 		});
       
  1898 
       
  1899 		// Nullify elem to prevent memory leaks in IE
       
  1900 		elem = null;
       
  1901 	},
       
  1902 
       
  1903 	guid: 1,
       
  1904 	global: {},
       
  1905 
       
  1906 	// Detach an event or set of events from an element
       
  1907 	remove: function(elem, types, handler) {
       
  1908 		// don't do events on text and comment nodes
       
  1909 		if ( elem.nodeType == 3 || elem.nodeType == 8 )
       
  1910 			return;
       
  1911 
       
  1912 		var events = jQuery.data(elem, "events"), ret, index;
       
  1913 
       
  1914 		if ( events ) {
       
  1915 			// Unbind all events for the element
       
  1916 			if ( types == undefined || (typeof types == "string" && types.charAt(0) == ".") )
       
  1917 				for ( var type in events )
       
  1918 					this.remove( elem, type + (types || "") );
       
  1919 			else {
       
  1920 				// types is actually an event object here
       
  1921 				if ( types.type ) {
       
  1922 					handler = types.handler;
       
  1923 					types = types.type;
       
  1924 				}
       
  1925 
       
  1926 				// Handle multiple events seperated by a space
       
  1927 				// jQuery(...).unbind("mouseover mouseout", fn);
       
  1928 				jQuery.each(types.split(/\s+/), function(index, type){
       
  1929 					// Namespaced event handlers
       
  1930 					var parts = type.split(".");
       
  1931 					type = parts[0];
       
  1932 
       
  1933 					if ( events[type] ) {
       
  1934 						// remove the given handler for the given type
       
  1935 						if ( handler )
       
  1936 							delete events[type][handler.guid];
       
  1937 
       
  1938 						// remove all handlers for the given type
       
  1939 						else
       
  1940 							for ( handler in events[type] )
       
  1941 								// Handle the removal of namespaced events
       
  1942 								if ( !parts[1] || events[type][handler].type == parts[1] )
       
  1943 									delete events[type][handler];
       
  1944 
       
  1945 						// remove generic event handler if no more handlers exist
       
  1946 						for ( ret in events[type] ) break;
       
  1947 						if ( !ret ) {
       
  1948 							if ( !jQuery.event.special[type] || jQuery.event.special[type].teardown.call(elem) === false ) {
       
  1949 								if (elem.removeEventListener)
       
  1950 									elem.removeEventListener(type, jQuery.data(elem, "handle"), false);
       
  1951 								else if (elem.detachEvent)
       
  1952 									elem.detachEvent("on" + type, jQuery.data(elem, "handle"));
       
  1953 							}
       
  1954 							ret = null;
       
  1955 							delete events[type];
       
  1956 						}
       
  1957 					}
       
  1958 				});
       
  1959 			}
       
  1960 
       
  1961 			// Remove the expando if it's no longer used
       
  1962 			for ( ret in events ) break;
       
  1963 			if ( !ret ) {
       
  1964 				var handle = jQuery.data( elem, "handle" );
       
  1965 				if ( handle ) handle.elem = null;
       
  1966 				jQuery.removeData( elem, "events" );
       
  1967 				jQuery.removeData( elem, "handle" );
       
  1968 			}
       
  1969 		}
       
  1970 	},
       
  1971 
       
  1972 	trigger: function(type, data, elem, donative, extra) {
       
  1973 		// Clone the incoming data, if any
       
  1974 		data = jQuery.makeArray(data);
       
  1975 
       
  1976 		if ( type.indexOf("!") >= 0 ) {
       
  1977 			type = type.slice(0, -1);
       
  1978 			var exclusive = true;
       
  1979 		}
       
  1980 
       
  1981 		// Handle a global trigger
       
  1982 		if ( !elem ) {
       
  1983 			// Only trigger if we've ever bound an event for it
       
  1984 			if ( this.global[type] )
       
  1985 				jQuery("*").add([window, document]).trigger(type, data);
       
  1986 
       
  1987 		// Handle triggering a single element
       
  1988 		} else {
       
  1989 			// don't do events on text and comment nodes
       
  1990 			if ( elem.nodeType == 3 || elem.nodeType == 8 )
       
  1991 				return undefined;
       
  1992 
       
  1993 			var val, ret, fn = jQuery.isFunction( elem[ type ] || null ),
       
  1994 				// Check to see if we need to provide a fake event, or not
       
  1995 				event = !data[0] || !data[0].preventDefault;
       
  1996 
       
  1997 			// Pass along a fake event
       
  1998 			if ( event ) {
       
  1999 				data.unshift({
       
  2000 					type: type,
       
  2001 					target: elem,
       
  2002 					preventDefault: function(){},
       
  2003 					stopPropagation: function(){},
       
  2004 					timeStamp: now()
       
  2005 				});
       
  2006 				data[0][expando] = true; // no need to fix fake event
       
  2007 			}
       
  2008 
       
  2009 			// Enforce the right trigger type
       
  2010 			data[0].type = type;
       
  2011 			if ( exclusive )
       
  2012 				data[0].exclusive = true;
       
  2013 
       
  2014 			// Trigger the event, it is assumed that "handle" is a function
       
  2015 			var handle = jQuery.data(elem, "handle");
       
  2016 			if ( handle )
       
  2017 				val = handle.apply( elem, data );
       
  2018 
       
  2019 			// Handle triggering native .onfoo handlers (and on links since we don't call .click() for links)
       
  2020 			if ( (!fn || (jQuery.nodeName(elem, 'a') && type == "click")) && elem["on"+type] && elem["on"+type].apply( elem, data ) === false )
       
  2021 				val = false;
       
  2022 
       
  2023 			// Extra functions don't get the custom event object
       
  2024 			if ( event )
       
  2025 				data.shift();
       
  2026 
       
  2027 			// Handle triggering of extra function
       
  2028 			if ( extra && jQuery.isFunction( extra ) ) {
       
  2029 				// call the extra function and tack the current return value on the end for possible inspection
       
  2030 				ret = extra.apply( elem, val == null ? data : data.concat( val ) );
       
  2031 				// if anything is returned, give it precedence and have it overwrite the previous value
       
  2032 				if (ret !== undefined)
       
  2033 					val = ret;
       
  2034 			}
       
  2035 
       
  2036 			// Trigger the native events (except for clicks on links)
       
  2037 			if ( fn && donative !== false && val !== false && !(jQuery.nodeName(elem, 'a') && type == "click") ) {
       
  2038 				this.triggered = true;
       
  2039 				try {
       
  2040 					elem[ type ]();
       
  2041 				// prevent IE from throwing an error for some hidden elements
       
  2042 				} catch (e) {}
       
  2043 			}
       
  2044 
       
  2045 			this.triggered = false;
       
  2046 		}
       
  2047 
       
  2048 		return val;
       
  2049 	},
       
  2050 
       
  2051 	handle: function(event) {
       
  2052 		// returned undefined or false
       
  2053 		var val, ret, namespace, all, handlers;
       
  2054 
       
  2055 		event = arguments[0] = jQuery.event.fix( event || window.event );
       
  2056 
       
  2057 		// Namespaced event handlers
       
  2058 		namespace = event.type.split(".");
       
  2059 		event.type = namespace[0];
       
  2060 		namespace = namespace[1];
       
  2061 		// Cache this now, all = true means, any handler
       
  2062 		all = !namespace && !event.exclusive;
       
  2063 
       
  2064 		handlers = ( jQuery.data(this, "events") || {} )[event.type];
       
  2065 
       
  2066 		for ( var j in handlers ) {
       
  2067 			var handler = handlers[j];
       
  2068 
       
  2069 			// Filter the functions by class
       
  2070 			if ( all || handler.type == namespace ) {
       
  2071 				// Pass in a reference to the handler function itself
       
  2072 				// So that we can later remove it
       
  2073 				event.handler = handler;
       
  2074 				event.data = handler.data;
       
  2075 
       
  2076 				ret = handler.apply( this, arguments );
       
  2077 
       
  2078 				if ( val !== false )
       
  2079 					val = ret;
       
  2080 
       
  2081 				if ( ret === false ) {
       
  2082 					event.preventDefault();
       
  2083 					event.stopPropagation();
       
  2084 				}
       
  2085 			}
       
  2086 		}
       
  2087 
       
  2088 		return val;
       
  2089 	},
       
  2090 
       
  2091 	fix: function(event) {
       
  2092 		if ( event[expando] == true )
       
  2093 			return event;
       
  2094 
       
  2095 		// store a copy of the original event object
       
  2096 		// and "clone" to set read-only properties
       
  2097 		var originalEvent = event;
       
  2098 		event = { originalEvent: originalEvent };
       
  2099 		var props = "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target timeStamp toElement type view wheelDelta which".split(" ");
       
  2100 		for ( var i=props.length; i; i-- )
       
  2101 			event[ props[i] ] = originalEvent[ props[i] ];
       
  2102 
       
  2103 		// Mark it as fixed
       
  2104 		event[expando] = true;
       
  2105 
       
  2106 		// add preventDefault and stopPropagation since
       
  2107 		// they will not work on the clone
       
  2108 		event.preventDefault = function() {
       
  2109 			// if preventDefault exists run it on the original event
       
  2110 			if (originalEvent.preventDefault)
       
  2111 				originalEvent.preventDefault();
       
  2112 			// otherwise set the returnValue property of the original event to false (IE)
       
  2113 			originalEvent.returnValue = false;
       
  2114 		};
       
  2115 		event.stopPropagation = function() {
       
  2116 			// if stopPropagation exists run it on the original event
       
  2117 			if (originalEvent.stopPropagation)
       
  2118 				originalEvent.stopPropagation();
       
  2119 			// otherwise set the cancelBubble property of the original event to true (IE)
       
  2120 			originalEvent.cancelBubble = true;
       
  2121 		};
       
  2122 
       
  2123 		// Fix timeStamp
       
  2124 		event.timeStamp = event.timeStamp || now();
       
  2125 
       
  2126 		// Fix target property, if necessary
       
  2127 		if ( !event.target )
       
  2128 			event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either
       
  2129 
       
  2130 		// check if target is a textnode (safari)
       
  2131 		if ( event.target.nodeType == 3 )
       
  2132 			event.target = event.target.parentNode;
       
  2133 
       
  2134 		// Add relatedTarget, if necessary
       
  2135 		if ( !event.relatedTarget && event.fromElement )
       
  2136 			event.relatedTarget = event.fromElement == event.target ? event.toElement : event.fromElement;
       
  2137 
       
  2138 		// Calculate pageX/Y if missing and clientX/Y available
       
  2139 		if ( event.pageX == null && event.clientX != null ) {
       
  2140 			var doc = document.documentElement, body = document.body;
       
  2141 			event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc.clientLeft || 0);
       
  2142 			event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc.clientTop || 0);
       
  2143 		}
       
  2144 
       
  2145 		// Add which for key events
       
  2146 		if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) )
       
  2147 			event.which = event.charCode || event.keyCode;
       
  2148 
       
  2149 		// Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
       
  2150 		if ( !event.metaKey && event.ctrlKey )
       
  2151 			event.metaKey = event.ctrlKey;
       
  2152 
       
  2153 		// Add which for click: 1 == left; 2 == middle; 3 == right
       
  2154 		// Note: button is not normalized, so don't use it
       
  2155 		if ( !event.which && event.button )
       
  2156 			event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
       
  2157 
       
  2158 		return event;
       
  2159 	},
       
  2160 
       
  2161 	proxy: function( fn, proxy ){
       
  2162 		// Set the guid of unique handler to the same of original handler, so it can be removed
       
  2163 		proxy.guid = fn.guid = fn.guid || proxy.guid || this.guid++;
       
  2164 		// So proxy can be declared as an argument
       
  2165 		return proxy;
       
  2166 	},
       
  2167 
       
  2168 	special: {
       
  2169 		ready: {
       
  2170 			setup: function() {
       
  2171 				// Make sure the ready event is setup
       
  2172 				bindReady();
       
  2173 				return;
       
  2174 			},
       
  2175 
       
  2176 			teardown: function() { return; }
       
  2177 		},
       
  2178 
       
  2179 		mouseenter: {
       
  2180 			setup: function() {
       
  2181 				if ( jQuery.browser.msie ) return false;
       
  2182 				jQuery(this).bind("mouseover", jQuery.event.special.mouseenter.handler);
       
  2183 				return true;
       
  2184 			},
       
  2185 
       
  2186 			teardown: function() {
       
  2187 				if ( jQuery.browser.msie ) return false;
       
  2188 				jQuery(this).unbind("mouseover", jQuery.event.special.mouseenter.handler);
       
  2189 				return true;
       
  2190 			},
       
  2191 
       
  2192 			handler: function(event) {
       
  2193 				// If we actually just moused on to a sub-element, ignore it
       
  2194 				if ( withinElement(event, this) ) return true;
       
  2195 				// Execute the right handlers by setting the event type to mouseenter
       
  2196 				event.type = "mouseenter";
       
  2197 				return jQuery.event.handle.apply(this, arguments);
       
  2198 			}
       
  2199 		},
       
  2200 
       
  2201 		mouseleave: {
       
  2202 			setup: function() {
       
  2203 				if ( jQuery.browser.msie ) return false;
       
  2204 				jQuery(this).bind("mouseout", jQuery.event.special.mouseleave.handler);
       
  2205 				return true;
       
  2206 			},
       
  2207 
       
  2208 			teardown: function() {
       
  2209 				if ( jQuery.browser.msie ) return false;
       
  2210 				jQuery(this).unbind("mouseout", jQuery.event.special.mouseleave.handler);
       
  2211 				return true;
       
  2212 			},
       
  2213 
       
  2214 			handler: function(event) {
       
  2215 				// If we actually just moused on to a sub-element, ignore it
       
  2216 				if ( withinElement(event, this) ) return true;
       
  2217 				// Execute the right handlers by setting the event type to mouseleave
       
  2218 				event.type = "mouseleave";
       
  2219 				return jQuery.event.handle.apply(this, arguments);
       
  2220 			}
       
  2221 		}
       
  2222 	}
       
  2223 };
       
  2224 
       
  2225 jQuery.fn.extend({
       
  2226 	bind: function( type, data, fn ) {
       
  2227 		return type == "unload" ? this.one(type, data, fn) : this.each(function(){
       
  2228 			jQuery.event.add( this, type, fn || data, fn && data );
       
  2229 		});
       
  2230 	},
       
  2231 
       
  2232 	one: function( type, data, fn ) {
       
  2233 		var one = jQuery.event.proxy( fn || data, function(event) {
       
  2234 			jQuery(this).unbind(event, one);
       
  2235 			return (fn || data).apply( this, arguments );
       
  2236 		});
       
  2237 		return this.each(function(){
       
  2238 			jQuery.event.add( this, type, one, fn && data);
       
  2239 		});
       
  2240 	},
       
  2241 
       
  2242 	unbind: function( type, fn ) {
       
  2243 		return this.each(function(){
       
  2244 			jQuery.event.remove( this, type, fn );
       
  2245 		});
       
  2246 	},
       
  2247 
       
  2248 	trigger: function( type, data, fn ) {
       
  2249 		return this.each(function(){
       
  2250 			jQuery.event.trigger( type, data, this, true, fn );
       
  2251 		});
       
  2252 	},
       
  2253 
       
  2254 	triggerHandler: function( type, data, fn ) {
       
  2255 		return this[0] && jQuery.event.trigger( type, data, this[0], false, fn );
       
  2256 	},
       
  2257 
       
  2258 	toggle: function( fn ) {
       
  2259 		// Save reference to arguments for access in closure
       
  2260 		var args = arguments, i = 1;
       
  2261 
       
  2262 		// link all the functions, so any of them can unbind this click handler
       
  2263 		while( i < args.length )
       
  2264 			jQuery.event.proxy( fn, args[i++] );
       
  2265 
       
  2266 		return this.click( jQuery.event.proxy( fn, function(event) {
       
  2267 			// Figure out which function to execute
       
  2268 			this.lastToggle = ( this.lastToggle || 0 ) % i;
       
  2269 
       
  2270 			// Make sure that clicks stop
       
  2271 			event.preventDefault();
       
  2272 
       
  2273 			// and execute the function
       
  2274 			return args[ this.lastToggle++ ].apply( this, arguments ) || false;
       
  2275 		}));
       
  2276 	},
       
  2277 
       
  2278 	hover: function(fnOver, fnOut) {
       
  2279 		return this.bind('mouseenter', fnOver).bind('mouseleave', fnOut);
       
  2280 	},
       
  2281 
       
  2282 	ready: function(fn) {
       
  2283 		// Attach the listeners
       
  2284 		bindReady();
       
  2285 
       
  2286 		// If the DOM is already ready
       
  2287 		if ( jQuery.isReady )
       
  2288 			// Execute the function immediately
       
  2289 			fn.call( document, jQuery );
       
  2290 
       
  2291 		// Otherwise, remember the function for later
       
  2292 		else
       
  2293 			// Add the function to the wait list
       
  2294 			jQuery.readyList.push( function() { return fn.call(this, jQuery); } );
       
  2295 
       
  2296 		return this;
       
  2297 	}
       
  2298 });
       
  2299 
       
  2300 jQuery.extend({
       
  2301 	isReady: false,
       
  2302 	readyList: [],
       
  2303 	// Handle when the DOM is ready
       
  2304 	ready: function() {
       
  2305 		// Make sure that the DOM is not already loaded
       
  2306 		if ( !jQuery.isReady ) {
       
  2307 			// Remember that the DOM is ready
       
  2308 			jQuery.isReady = true;
       
  2309 
       
  2310 			// If there are functions bound, to execute
       
  2311 			if ( jQuery.readyList ) {
       
  2312 				// Execute all of them
       
  2313 				jQuery.each( jQuery.readyList, function(){
       
  2314 					this.call( document );
       
  2315 				});
       
  2316 
       
  2317 				// Reset the list of functions
       
  2318 				jQuery.readyList = null;
       
  2319 			}
       
  2320 
       
  2321 			// Trigger any bound ready events
       
  2322 			jQuery(document).triggerHandler("ready");
       
  2323 		}
       
  2324 	}
       
  2325 });
       
  2326 
       
  2327 var readyBound = false;
       
  2328 
       
  2329 function bindReady(){
       
  2330 	if ( readyBound ) return;
       
  2331 	readyBound = true;
       
  2332 
       
  2333 	// Mozilla, Opera (see further below for it) and webkit nightlies currently support this event
       
  2334 	if ( document.addEventListener && !jQuery.browser.opera)
       
  2335 		// Use the handy event callback
       
  2336 		document.addEventListener( "DOMContentLoaded", jQuery.ready, false );
       
  2337 
       
  2338 	// If IE is used and is not in a frame
       
  2339 	// Continually check to see if the document is ready
       
  2340 	if ( jQuery.browser.msie && window == top ) (function(){
       
  2341 		if (jQuery.isReady) return;
       
  2342 		try {
       
  2343 			// If IE is used, use the trick by Diego Perini
       
  2344 			// http://javascript.nwbox.com/IEContentLoaded/
       
  2345 			document.documentElement.doScroll("left");
       
  2346 		} catch( error ) {
       
  2347 			setTimeout( arguments.callee, 0 );
       
  2348 			return;
       
  2349 		}
       
  2350 		// and execute any waiting functions
       
  2351 		jQuery.ready();
       
  2352 	})();
       
  2353 
       
  2354 	if ( jQuery.browser.opera )
       
  2355 		document.addEventListener( "DOMContentLoaded", function () {
       
  2356 			if (jQuery.isReady) return;
       
  2357 			for (var i = 0; i < document.styleSheets.length; i++)
       
  2358 				if (document.styleSheets[i].disabled) {
       
  2359 					setTimeout( arguments.callee, 0 );
       
  2360 					return;
       
  2361 				}
       
  2362 			// and execute any waiting functions
       
  2363 			jQuery.ready();
       
  2364 		}, false);
       
  2365 
       
  2366 	if ( jQuery.browser.safari ) {
       
  2367 		var numStyles;
       
  2368 		(function(){
       
  2369 			if (jQuery.isReady) return;
       
  2370 			if ( document.readyState != "loaded" && document.readyState != "complete" ) {
       
  2371 				setTimeout( arguments.callee, 0 );
       
  2372 				return;
       
  2373 			}
       
  2374 			if ( numStyles === undefined )
       
  2375 				numStyles = jQuery("style, link[rel=stylesheet]").length;
       
  2376 			if ( document.styleSheets.length != numStyles ) {
       
  2377 				setTimeout( arguments.callee, 0 );
       
  2378 				return;
       
  2379 			}
       
  2380 			// and execute any waiting functions
       
  2381 			jQuery.ready();
       
  2382 		})();
       
  2383 	}
       
  2384 
       
  2385 	// A fallback to window.onload, that will always work
       
  2386 	jQuery.event.add( window, "load", jQuery.ready );
       
  2387 }
       
  2388 
       
  2389 jQuery.each( ("blur,focus,load,resize,scroll,unload,click,dblclick," +
       
  2390 	"mousedown,mouseup,mousemove,mouseover,mouseout,change,select," +
       
  2391 	"submit,keydown,keypress,keyup,error").split(","), function(i, name){
       
  2392 
       
  2393 	// Handle event binding
       
  2394 	jQuery.fn[name] = function(fn){
       
  2395 		return fn ? this.bind(name, fn) : this.trigger(name);
       
  2396 	};
       
  2397 });
       
  2398 
       
  2399 // Checks if an event happened on an element within another element
       
  2400 // Used in jQuery.event.special.mouseenter and mouseleave handlers
       
  2401 var withinElement = function(event, elem) {
       
  2402 	// Check if mouse(over|out) are still within the same parent element
       
  2403 	var parent = event.relatedTarget;
       
  2404 	// Traverse up the tree
       
  2405 	while ( parent && parent != elem ) try { parent = parent.parentNode; } catch(error) { parent = elem; }
       
  2406 	// Return true if we actually just moused on to a sub-element
       
  2407 	return parent == elem;
       
  2408 };
       
  2409 
       
  2410 // Prevent memory leaks in IE
       
  2411 // And prevent errors on refresh with events like mouseover in other browsers
       
  2412 // Window isn't included so as not to unbind existing unload events
       
  2413 jQuery(window).bind("unload", function() {
       
  2414 	jQuery("*").add(document).unbind();
       
  2415 });
       
  2416 jQuery.fn.extend({
       
  2417 	// Keep a copy of the old load
       
  2418 	_load: jQuery.fn.load,
       
  2419 
       
  2420 	load: function( url, params, callback ) {
       
  2421 		if ( typeof url != 'string' )
       
  2422 			return this._load( url );
       
  2423 
       
  2424 		var off = url.indexOf(" ");
       
  2425 		if ( off >= 0 ) {
       
  2426 			var selector = url.slice(off, url.length);
       
  2427 			url = url.slice(0, off);
       
  2428 		}
       
  2429 
       
  2430 		callback = callback || function(){};
       
  2431 
       
  2432 		// Default to a GET request
       
  2433 		var type = "GET";
       
  2434 
       
  2435 		// If the second parameter was provided
       
  2436 		if ( params )
       
  2437 			// If it's a function
       
  2438 			if ( jQuery.isFunction( params ) ) {
       
  2439 				// We assume that it's the callback
       
  2440 				callback = params;
       
  2441 				params = null;
       
  2442 
       
  2443 			// Otherwise, build a param string
       
  2444 			} else {
       
  2445 				params = jQuery.param( params );
       
  2446 				type = "POST";
       
  2447 			}
       
  2448 
       
  2449 		var self = this;
       
  2450 
       
  2451 		// Request the remote document
       
  2452 		jQuery.ajax({
       
  2453 			url: url,
       
  2454 			type: type,
       
  2455 			dataType: "html",
       
  2456 			data: params,
       
  2457 			complete: function(res, status){
       
  2458 				// If successful, inject the HTML into all the matched elements
       
  2459 				if ( status == "success" || status == "notmodified" )
       
  2460 					// See if a selector was specified
       
  2461 					self.html( selector ?
       
  2462 						// Create a dummy div to hold the results
       
  2463 						jQuery("<div/>")
       
  2464 							// inject the contents of the document in, removing the scripts
       
  2465 							// to avoid any 'Permission Denied' errors in IE
       
  2466 							.append(res.responseText.replace(/<script(.|\s)*?\/script>/g, ""))
       
  2467 
       
  2468 							// Locate the specified elements
       
  2469 							.find(selector) :
       
  2470 
       
  2471 						// If not, just inject the full result
       
  2472 						res.responseText );
       
  2473 
       
  2474 				self.each( callback, [res.responseText, status, res] );
       
  2475 			}
       
  2476 		});
       
  2477 		return this;
       
  2478 	},
       
  2479 
       
  2480 	serialize: function() {
       
  2481 		return jQuery.param(this.serializeArray());
       
  2482 	},
       
  2483 	serializeArray: function() {
       
  2484 		return this.map(function(){
       
  2485 			return jQuery.nodeName(this, "form") ?
       
  2486 				jQuery.makeArray(this.elements) : this;
       
  2487 		})
       
  2488 		.filter(function(){
       
  2489 			return this.name && !this.disabled &&
       
  2490 				(this.checked || /select|textarea/i.test(this.nodeName) ||
       
  2491 					/text|hidden|password/i.test(this.type));
       
  2492 		})
       
  2493 		.map(function(i, elem){
       
  2494 			var val = jQuery(this).val();
       
  2495 			return val == null ? null :
       
  2496 				val.constructor == Array ?
       
  2497 					jQuery.map( val, function(val, i){
       
  2498 						return {name: elem.name, value: val};
       
  2499 					}) :
       
  2500 					{name: elem.name, value: val};
       
  2501 		}).get();
       
  2502 	}
       
  2503 });
       
  2504 
       
  2505 // Attach a bunch of functions for handling common AJAX events
       
  2506 jQuery.each( "ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","), function(i,o){
       
  2507 	jQuery.fn[o] = function(f){
       
  2508 		return this.bind(o, f);
       
  2509 	};
       
  2510 });
       
  2511 
       
  2512 var jsc = now();
       
  2513 
       
  2514 jQuery.extend({
       
  2515 	get: function( url, data, callback, type ) {
       
  2516 		// shift arguments if data argument was ommited
       
  2517 		if ( jQuery.isFunction( data ) ) {
       
  2518 			callback = data;
       
  2519 			data = null;
       
  2520 		}
       
  2521 
       
  2522 		return jQuery.ajax({
       
  2523 			type: "GET",
       
  2524 			url: url,
       
  2525 			data: data,
       
  2526 			success: callback,
       
  2527 			dataType: type
       
  2528 		});
       
  2529 	},
       
  2530 
       
  2531 	getScript: function( url, callback ) {
       
  2532 		return jQuery.get(url, null, callback, "script");
       
  2533 	},
       
  2534 
       
  2535 	getJSON: function( url, data, callback ) {
       
  2536 		return jQuery.get(url, data, callback, "json");
       
  2537 	},
       
  2538 
       
  2539 	post: function( url, data, callback, type ) {
       
  2540 		if ( jQuery.isFunction( data ) ) {
       
  2541 			callback = data;
       
  2542 			data = {};
       
  2543 		}
       
  2544 
       
  2545 		return jQuery.ajax({
       
  2546 			type: "POST",
       
  2547 			url: url,
       
  2548 			data: data,
       
  2549 			success: callback,
       
  2550 			dataType: type
       
  2551 		});
       
  2552 	},
       
  2553 
       
  2554 	ajaxSetup: function( settings ) {
       
  2555 		jQuery.extend( jQuery.ajaxSettings, settings );
       
  2556 	},
       
  2557 
       
  2558 	ajaxSettings: {
       
  2559 		url: location.href,
       
  2560 		global: true,
       
  2561 		type: "GET",
       
  2562 		timeout: 0,
       
  2563 		contentType: "application/x-www-form-urlencoded",
       
  2564 		processData: true,
       
  2565 		async: true,
       
  2566 		data: null,
       
  2567 		username: null,
       
  2568 		password: null,
       
  2569 		accepts: {
       
  2570 			xml: "application/xml, text/xml",
       
  2571 			html: "text/html",
       
  2572 			script: "text/javascript, application/javascript",
       
  2573 			json: "application/json, text/javascript",
       
  2574 			text: "text/plain",
       
  2575 			_default: "*/*"
       
  2576 		}
       
  2577 	},
       
  2578 
       
  2579 	// Last-Modified header cache for next request
       
  2580 	lastModified: {},
       
  2581 
       
  2582 	ajax: function( s ) {
       
  2583 		// Extend the settings, but re-extend 's' so that it can be
       
  2584 		// checked again later (in the test suite, specifically)
       
  2585 		s = jQuery.extend(true, s, jQuery.extend(true, {}, jQuery.ajaxSettings, s));
       
  2586 
       
  2587 		var jsonp, jsre = /=\?(&|$)/g, status, data,
       
  2588 			type = s.type.toUpperCase();
       
  2589 
       
  2590 		// convert data if not already a string
       
  2591 		if ( s.data && s.processData && typeof s.data != "string" )
       
  2592 			s.data = jQuery.param(s.data);
       
  2593 
       
  2594 		// Handle JSONP Parameter Callbacks
       
  2595 		if ( s.dataType == "jsonp" ) {
       
  2596 			if ( type == "GET" ) {
       
  2597 				if ( !s.url.match(jsre) )
       
  2598 					s.url += (s.url.match(/\?/) ? "&" : "?") + (s.jsonp || "callback") + "=?";
       
  2599 			} else if ( !s.data || !s.data.match(jsre) )
       
  2600 				s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";
       
  2601 			s.dataType = "json";
       
  2602 		}
       
  2603 
       
  2604 		// Build temporary JSONP function
       
  2605 		if ( s.dataType == "json" && (s.data && s.data.match(jsre) || s.url.match(jsre)) ) {
       
  2606 			jsonp = "jsonp" + jsc++;
       
  2607 
       
  2608 			// Replace the =? sequence both in the query string and the data
       
  2609 			if ( s.data )
       
  2610 				s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");
       
  2611 			s.url = s.url.replace(jsre, "=" + jsonp + "$1");
       
  2612 
       
  2613 			// We need to make sure
       
  2614 			// that a JSONP style response is executed properly
       
  2615 			s.dataType = "script";
       
  2616 
       
  2617 			// Handle JSONP-style loading
       
  2618 			window[ jsonp ] = function(tmp){
       
  2619 				data = tmp;
       
  2620 				success();
       
  2621 				complete();
       
  2622 				// Garbage collect
       
  2623 				window[ jsonp ] = undefined;
       
  2624 				try{ delete window[ jsonp ]; } catch(e){}
       
  2625 				if ( head )
       
  2626 					head.removeChild( script );
       
  2627 			};
       
  2628 		}
       
  2629 
       
  2630 		if ( s.dataType == "script" && s.cache == null )
       
  2631 			s.cache = false;
       
  2632 
       
  2633 		if ( s.cache === false && type == "GET" ) {
       
  2634 			var ts = now();
       
  2635 			// try replacing _= if it is there
       
  2636 			var ret = s.url.replace(/(\?|&)_=.*?(&|$)/, "$1_=" + ts + "$2");
       
  2637 			// if nothing was replaced, add timestamp to the end
       
  2638 			s.url = ret + ((ret == s.url) ? (s.url.match(/\?/) ? "&" : "?") + "_=" + ts : "");
       
  2639 		}
       
  2640 
       
  2641 		// If data is available, append data to url for get requests
       
  2642 		if ( s.data && type == "GET" ) {
       
  2643 			s.url += (s.url.match(/\?/) ? "&" : "?") + s.data;
       
  2644 
       
  2645 			// IE likes to send both get and post data, prevent this
       
  2646 			s.data = null;
       
  2647 		}
       
  2648 
       
  2649 		// Watch for a new set of requests
       
  2650 		if ( s.global && ! jQuery.active++ )
       
  2651 			jQuery.event.trigger( "ajaxStart" );
       
  2652 
       
  2653 		// Matches an absolute URL, and saves the domain
       
  2654 		var remote = /^(?:\w+:)?\/\/([^\/?#]+)/;
       
  2655 
       
  2656 		// If we're requesting a remote document
       
  2657 		// and trying to load JSON or Script with a GET
       
  2658 		if ( s.dataType == "script" && type == "GET"
       
  2659 				&& remote.test(s.url) && remote.exec(s.url)[1] != location.host ){
       
  2660 			var head = document.getElementsByTagName("head")[0];
       
  2661 			var script = document.createElement("script");
       
  2662 			script.src = s.url;
       
  2663 			if (s.scriptCharset)
       
  2664 				script.charset = s.scriptCharset;
       
  2665 
       
  2666 			// Handle Script loading
       
  2667 			if ( !jsonp ) {
       
  2668 				var done = false;
       
  2669 
       
  2670 				// Attach handlers for all browsers
       
  2671 				script.onload = script.onreadystatechange = function(){
       
  2672 					if ( !done && (!this.readyState ||
       
  2673 							this.readyState == "loaded" || this.readyState == "complete") ) {
       
  2674 						done = true;
       
  2675 						success();
       
  2676 						complete();
       
  2677 						head.removeChild( script );
       
  2678 					}
       
  2679 				};
       
  2680 			}
       
  2681 
       
  2682 			head.appendChild(script);
       
  2683 
       
  2684 			// We handle everything using the script element injection
       
  2685 			return undefined;
       
  2686 		}
       
  2687 
       
  2688 		var requestDone = false;
       
  2689 
       
  2690 		// Create the request object; Microsoft failed to properly
       
  2691 		// implement the XMLHttpRequest in IE7, so we use the ActiveXObject when it is available
       
  2692 		var xhr = window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
       
  2693 
       
  2694 		// Open the socket
       
  2695 		// Passing null username, generates a login popup on Opera (#2865)
       
  2696 		if( s.username )
       
  2697 			xhr.open(type, s.url, s.async, s.username, s.password);
       
  2698 		else
       
  2699 			xhr.open(type, s.url, s.async);
       
  2700 
       
  2701 		// Need an extra try/catch for cross domain requests in Firefox 3
       
  2702 		try {
       
  2703 			// Set the correct header, if data is being sent
       
  2704 			if ( s.data )
       
  2705 				xhr.setRequestHeader("Content-Type", s.contentType);
       
  2706 
       
  2707 			// Set the If-Modified-Since header, if ifModified mode.
       
  2708 			if ( s.ifModified )
       
  2709 				xhr.setRequestHeader("If-Modified-Since",
       
  2710 					jQuery.lastModified[s.url] || "Thu, 01 Jan 1970 00:00:00 GMT" );
       
  2711 
       
  2712 			// Set header so the called script knows that it's an XMLHttpRequest
       
  2713 			xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
       
  2714 
       
  2715 			// Set the Accepts header for the server, depending on the dataType
       
  2716 			xhr.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ?
       
  2717 				s.accepts[ s.dataType ] + ", */*" :
       
  2718 				s.accepts._default );
       
  2719 		} catch(e){}
       
  2720 
       
  2721 		// Allow custom headers/mimetypes
       
  2722 		if ( s.beforeSend && s.beforeSend(xhr, s) === false ) {
       
  2723 			// cleanup active request counter
       
  2724 			s.global && jQuery.active--;
       
  2725 			// close opended socket
       
  2726 			xhr.abort();
       
  2727 			return false;
       
  2728 		}
       
  2729 
       
  2730 		if ( s.global )
       
  2731 			jQuery.event.trigger("ajaxSend", [xhr, s]);
       
  2732 
       
  2733 		// Wait for a response to come back
       
  2734 		var onreadystatechange = function(isTimeout){
       
  2735 			// The transfer is complete and the data is available, or the request timed out
       
  2736 			if ( !requestDone && xhr && (xhr.readyState == 4 || isTimeout == "timeout") ) {
       
  2737 				requestDone = true;
       
  2738 
       
  2739 				// clear poll interval
       
  2740 				if (ival) {
       
  2741 					clearInterval(ival);
       
  2742 					ival = null;
       
  2743 				}
       
  2744 
       
  2745 				status = isTimeout == "timeout" && "timeout" ||
       
  2746 					!jQuery.httpSuccess( xhr ) && "error" ||
       
  2747 					s.ifModified && jQuery.httpNotModified( xhr, s.url ) && "notmodified" ||
       
  2748 					"success";
       
  2749 
       
  2750 				if ( status == "success" ) {
       
  2751 					// Watch for, and catch, XML document parse errors
       
  2752 					try {
       
  2753 						// process the data (runs the xml through httpData regardless of callback)
       
  2754 						data = jQuery.httpData( xhr, s.dataType, s.dataFilter );
       
  2755 					} catch(e) {
       
  2756 						status = "parsererror";
       
  2757 					}
       
  2758 				}
       
  2759 
       
  2760 				// Make sure that the request was successful or notmodified
       
  2761 				if ( status == "success" ) {
       
  2762 					// Cache Last-Modified header, if ifModified mode.
       
  2763 					var modRes;
       
  2764 					try {
       
  2765 						modRes = xhr.getResponseHeader("Last-Modified");
       
  2766 					} catch(e) {} // swallow exception thrown by FF if header is not available
       
  2767 
       
  2768 					if ( s.ifModified && modRes )
       
  2769 						jQuery.lastModified[s.url] = modRes;
       
  2770 
       
  2771 					// JSONP handles its own success callback
       
  2772 					if ( !jsonp )
       
  2773 						success();
       
  2774 				} else
       
  2775 					jQuery.handleError(s, xhr, status);
       
  2776 
       
  2777 				// Fire the complete handlers
       
  2778 				complete();
       
  2779 
       
  2780 				// Stop memory leaks
       
  2781 				if ( s.async )
       
  2782 					xhr = null;
       
  2783 			}
       
  2784 		};
       
  2785 
       
  2786 		if ( s.async ) {
       
  2787 			// don't attach the handler to the request, just poll it instead
       
  2788 			var ival = setInterval(onreadystatechange, 13);
       
  2789 
       
  2790 			// Timeout checker
       
  2791 			if ( s.timeout > 0 )
       
  2792 				setTimeout(function(){
       
  2793 					// Check to see if the request is still happening
       
  2794 					if ( xhr ) {
       
  2795 						// Cancel the request
       
  2796 						xhr.abort();
       
  2797 
       
  2798 						if( !requestDone )
       
  2799 							onreadystatechange( "timeout" );
       
  2800 					}
       
  2801 				}, s.timeout);
       
  2802 		}
       
  2803 
       
  2804 		// Send the data
       
  2805 		try {
       
  2806 			xhr.send(s.data);
       
  2807 		} catch(e) {
       
  2808 			jQuery.handleError(s, xhr, null, e);
       
  2809 		}
       
  2810 
       
  2811 		// firefox 1.5 doesn't fire statechange for sync requests
       
  2812 		if ( !s.async )
       
  2813 			onreadystatechange();
       
  2814 
       
  2815 		function success(){
       
  2816 			// If a local callback was specified, fire it and pass it the data
       
  2817 			if ( s.success )
       
  2818 				s.success( data, status );
       
  2819 
       
  2820 			// Fire the global callback
       
  2821 			if ( s.global )
       
  2822 				jQuery.event.trigger( "ajaxSuccess", [xhr, s] );
       
  2823 		}
       
  2824 
       
  2825 		function complete(){
       
  2826 			// Process result
       
  2827 			if ( s.complete )
       
  2828 				s.complete(xhr, status);
       
  2829 
       
  2830 			// The request was completed
       
  2831 			if ( s.global )
       
  2832 				jQuery.event.trigger( "ajaxComplete", [xhr, s] );
       
  2833 
       
  2834 			// Handle the global AJAX counter
       
  2835 			if ( s.global && ! --jQuery.active )
       
  2836 				jQuery.event.trigger( "ajaxStop" );
       
  2837 		}
       
  2838 
       
  2839 		// return XMLHttpRequest to allow aborting the request etc.
       
  2840 		return xhr;
       
  2841 	},
       
  2842 
       
  2843 	handleError: function( s, xhr, status, e ) {
       
  2844 		// If a local callback was specified, fire it
       
  2845 		if ( s.error ) s.error( xhr, status, e );
       
  2846 
       
  2847 		// Fire the global callback
       
  2848 		if ( s.global )
       
  2849 			jQuery.event.trigger( "ajaxError", [xhr, s, e] );
       
  2850 	},
       
  2851 
       
  2852 	// Counter for holding the number of active queries
       
  2853 	active: 0,
       
  2854 
       
  2855 	// Determines if an XMLHttpRequest was successful or not
       
  2856 	httpSuccess: function( xhr ) {
       
  2857 		try {
       
  2858 			// IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450
       
  2859 			return !xhr.status && location.protocol == "file:" ||
       
  2860 				( xhr.status >= 200 && xhr.status < 300 ) || xhr.status == 304 || xhr.status == 1223 ||
       
  2861 				jQuery.browser.safari && xhr.status == undefined;
       
  2862 		} catch(e){}
       
  2863 		return false;
       
  2864 	},
       
  2865 
       
  2866 	// Determines if an XMLHttpRequest returns NotModified
       
  2867 	httpNotModified: function( xhr, url ) {
       
  2868 		try {
       
  2869 			var xhrRes = xhr.getResponseHeader("Last-Modified");
       
  2870 
       
  2871 			// Firefox always returns 200. check Last-Modified date
       
  2872 			return xhr.status == 304 || xhrRes == jQuery.lastModified[url] ||
       
  2873 				jQuery.browser.safari && xhr.status == undefined;
       
  2874 		} catch(e){}
       
  2875 		return false;
       
  2876 	},
       
  2877 
       
  2878 	httpData: function( xhr, type, filter ) {
       
  2879 		var ct = xhr.getResponseHeader("content-type"),
       
  2880 			xml = type == "xml" || !type && ct && ct.indexOf("xml") >= 0,
       
  2881 			data = xml ? xhr.responseXML : xhr.responseText;
       
  2882 
       
  2883 		if ( xml && data.documentElement.tagName == "parsererror" )
       
  2884 			throw "parsererror";
       
  2885 			
       
  2886 		// Allow a pre-filtering function to sanitize the response
       
  2887 		if( filter )
       
  2888 			data = filter( data, type );
       
  2889 
       
  2890 		// If the type is "script", eval it in global context
       
  2891 		if ( type == "script" )
       
  2892 			jQuery.globalEval( data );
       
  2893 
       
  2894 		// Get the JavaScript object, if JSON is used.
       
  2895 		if ( type == "json" )
       
  2896 			data = eval("(" + data + ")");
       
  2897 
       
  2898 		return data;
       
  2899 	},
       
  2900 
       
  2901 	// Serialize an array of form elements or a set of
       
  2902 	// key/values into a query string
       
  2903 	param: function( a ) {
       
  2904 		var s = [];
       
  2905 
       
  2906 		// If an array was passed in, assume that it is an array
       
  2907 		// of form elements
       
  2908 		if ( a.constructor == Array || a.jquery )
       
  2909 			// Serialize the form elements
       
  2910 			jQuery.each( a, function(){
       
  2911 				s.push( encodeURIComponent(this.name) + "=" + encodeURIComponent( this.value ) );
       
  2912 			});
       
  2913 
       
  2914 		// Otherwise, assume that it's an object of key/value pairs
       
  2915 		else
       
  2916 			// Serialize the key/values
       
  2917 			for ( var j in a )
       
  2918 				// If the value is an array then the key names need to be repeated
       
  2919 				if ( a[j] && a[j].constructor == Array )
       
  2920 					jQuery.each( a[j], function(){
       
  2921 						s.push( encodeURIComponent(j) + "=" + encodeURIComponent( this ) );
       
  2922 					});
       
  2923 				else
       
  2924 					s.push( encodeURIComponent(j) + "=" + encodeURIComponent( jQuery.isFunction(a[j]) ? a[j]() : a[j] ) );
       
  2925 
       
  2926 		// Return the resulting serialization
       
  2927 		return s.join("&").replace(/%20/g, "+");
       
  2928 	}
       
  2929 
       
  2930 });
       
  2931 jQuery.fn.extend({
       
  2932 	show: function(speed,callback){
       
  2933 		return speed ?
       
  2934 			this.animate({
       
  2935 				height: "show", width: "show", opacity: "show"
       
  2936 			}, speed, callback) :
       
  2937 
       
  2938 			this.filter(":hidden").each(function(){
       
  2939 				this.style.display = this.oldblock || "";
       
  2940 				if ( jQuery.css(this,"display") == "none" ) {
       
  2941 					var elem = jQuery("<" + this.tagName + " />").appendTo("body");
       
  2942 					this.style.display = elem.css("display");
       
  2943 					// handle an edge condition where css is - div { display:none; } or similar
       
  2944 					if (this.style.display == "none")
       
  2945 						this.style.display = "block";
       
  2946 					elem.remove();
       
  2947 				}
       
  2948 			}).end();
       
  2949 	},
       
  2950 
       
  2951 	hide: function(speed,callback){
       
  2952 		return speed ?
       
  2953 			this.animate({
       
  2954 				height: "hide", width: "hide", opacity: "hide"
       
  2955 			}, speed, callback) :
       
  2956 
       
  2957 			this.filter(":visible").each(function(){
       
  2958 				this.oldblock = this.oldblock || jQuery.css(this,"display");
       
  2959 				this.style.display = "none";
       
  2960 			}).end();
       
  2961 	},
       
  2962 
       
  2963 	// Save the old toggle function
       
  2964 	_toggle: jQuery.fn.toggle,
       
  2965 
       
  2966 	toggle: function( fn, fn2 ){
       
  2967 		return jQuery.isFunction(fn) && jQuery.isFunction(fn2) ?
       
  2968 			this._toggle.apply( this, arguments ) :
       
  2969 			fn ?
       
  2970 				this.animate({
       
  2971 					height: "toggle", width: "toggle", opacity: "toggle"
       
  2972 				}, fn, fn2) :
       
  2973 				this.each(function(){
       
  2974 					jQuery(this)[ jQuery(this).is(":hidden") ? "show" : "hide" ]();
       
  2975 				});
       
  2976 	},
       
  2977 
       
  2978 	slideDown: function(speed,callback){
       
  2979 		return this.animate({height: "show"}, speed, callback);
       
  2980 	},
       
  2981 
       
  2982 	slideUp: function(speed,callback){
       
  2983 		return this.animate({height: "hide"}, speed, callback);
       
  2984 	},
       
  2985 
       
  2986 	slideToggle: function(speed, callback){
       
  2987 		return this.animate({height: "toggle"}, speed, callback);
       
  2988 	},
       
  2989 
       
  2990 	fadeIn: function(speed, callback){
       
  2991 		return this.animate({opacity: "show"}, speed, callback);
       
  2992 	},
       
  2993 
       
  2994 	fadeOut: function(speed, callback){
       
  2995 		return this.animate({opacity: "hide"}, speed, callback);
       
  2996 	},
       
  2997 
       
  2998 	fadeTo: function(speed,to,callback){
       
  2999 		return this.animate({opacity: to}, speed, callback);
       
  3000 	},
       
  3001 
       
  3002 	animate: function( prop, speed, easing, callback ) {
       
  3003 		var optall = jQuery.speed(speed, easing, callback);
       
  3004 
       
  3005 		return this[ optall.queue === false ? "each" : "queue" ](function(){
       
  3006 			if ( this.nodeType != 1)
       
  3007 				return false;
       
  3008 
       
  3009 			var opt = jQuery.extend({}, optall), p,
       
  3010 				hidden = jQuery(this).is(":hidden"), self = this;
       
  3011 
       
  3012 			for ( p in prop ) {
       
  3013 				if ( prop[p] == "hide" && hidden || prop[p] == "show" && !hidden )
       
  3014 					return opt.complete.call(this);
       
  3015 
       
  3016 				if ( p == "height" || p == "width" ) {
       
  3017 					// Store display property
       
  3018 					opt.display = jQuery.css(this, "display");
       
  3019 
       
  3020 					// Make sure that nothing sneaks out
       
  3021 					opt.overflow = this.style.overflow;
       
  3022 				}
       
  3023 			}
       
  3024 
       
  3025 			if ( opt.overflow != null )
       
  3026 				this.style.overflow = "hidden";
       
  3027 
       
  3028 			opt.curAnim = jQuery.extend({}, prop);
       
  3029 
       
  3030 			jQuery.each( prop, function(name, val){
       
  3031 				var e = new jQuery.fx( self, opt, name );
       
  3032 
       
  3033 				if ( /toggle|show|hide/.test(val) )
       
  3034 					e[ val == "toggle" ? hidden ? "show" : "hide" : val ]( prop );
       
  3035 				else {
       
  3036 					var parts = val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),
       
  3037 						start = e.cur(true) || 0;
       
  3038 
       
  3039 					if ( parts ) {
       
  3040 						var end = parseFloat(parts[2]),
       
  3041 							unit = parts[3] || "px";
       
  3042 
       
  3043 						// We need to compute starting value
       
  3044 						if ( unit != "px" ) {
       
  3045 							self.style[ name ] = (end || 1) + unit;
       
  3046 							start = ((end || 1) / e.cur(true)) * start;
       
  3047 							self.style[ name ] = start + unit;
       
  3048 						}
       
  3049 
       
  3050 						// If a +=/-= token was provided, we're doing a relative animation
       
  3051 						if ( parts[1] )
       
  3052 							end = ((parts[1] == "-=" ? -1 : 1) * end) + start;
       
  3053 
       
  3054 						e.custom( start, end, unit );
       
  3055 					} else
       
  3056 						e.custom( start, val, "" );
       
  3057 				}
       
  3058 			});
       
  3059 
       
  3060 			// For JS strict compliance
       
  3061 			return true;
       
  3062 		});
       
  3063 	},
       
  3064 
       
  3065 	queue: function(type, fn){
       
  3066 		if ( jQuery.isFunction(type) || ( type && type.constructor == Array )) {
       
  3067 			fn = type;
       
  3068 			type = "fx";
       
  3069 		}
       
  3070 
       
  3071 		if ( !type || (typeof type == "string" && !fn) )
       
  3072 			return queue( this[0], type );
       
  3073 
       
  3074 		return this.each(function(){
       
  3075 			if ( fn.constructor == Array )
       
  3076 				queue(this, type, fn);
       
  3077 			else {
       
  3078 				queue(this, type).push( fn );
       
  3079 
       
  3080 				if ( queue(this, type).length == 1 )
       
  3081 					fn.call(this);
       
  3082 			}
       
  3083 		});
       
  3084 	},
       
  3085 
       
  3086 	stop: function(clearQueue, gotoEnd){
       
  3087 		var timers = jQuery.timers;
       
  3088 
       
  3089 		if (clearQueue)
       
  3090 			this.queue([]);
       
  3091 
       
  3092 		this.each(function(){
       
  3093 			// go in reverse order so anything added to the queue during the loop is ignored
       
  3094 			for ( var i = timers.length - 1; i >= 0; i-- )
       
  3095 				if ( timers[i].elem == this ) {
       
  3096 					if (gotoEnd)
       
  3097 						// force the next step to be the last
       
  3098 						timers[i](true);
       
  3099 					timers.splice(i, 1);
       
  3100 				}
       
  3101 		});
       
  3102 
       
  3103 		// start the next in the queue if the last step wasn't forced
       
  3104 		if (!gotoEnd)
       
  3105 			this.dequeue();
       
  3106 
       
  3107 		return this;
       
  3108 	}
       
  3109 
       
  3110 });
       
  3111 
       
  3112 var queue = function( elem, type, array ) {
       
  3113 	if ( elem ){
       
  3114 
       
  3115 		type = type || "fx";
       
  3116 
       
  3117 		var q = jQuery.data( elem, type + "queue" );
       
  3118 
       
  3119 		if ( !q || array )
       
  3120 			q = jQuery.data( elem, type + "queue", jQuery.makeArray(array) );
       
  3121 
       
  3122 	}
       
  3123 	return q;
       
  3124 };
       
  3125 
       
  3126 jQuery.fn.dequeue = function(type){
       
  3127 	type = type || "fx";
       
  3128 
       
  3129 	return this.each(function(){
       
  3130 		var q = queue(this, type);
       
  3131 
       
  3132 		q.shift();
       
  3133 
       
  3134 		if ( q.length )
       
  3135 			q[0].call( this );
       
  3136 	});
       
  3137 };
       
  3138 
       
  3139 jQuery.extend({
       
  3140 
       
  3141 	speed: function(speed, easing, fn) {
       
  3142 		var opt = speed && speed.constructor == Object ? speed : {
       
  3143 			complete: fn || !fn && easing ||
       
  3144 				jQuery.isFunction( speed ) && speed,
       
  3145 			duration: speed,
       
  3146 			easing: fn && easing || easing && easing.constructor != Function && easing
       
  3147 		};
       
  3148 
       
  3149 		opt.duration = (opt.duration && opt.duration.constructor == Number ?
       
  3150 			opt.duration :
       
  3151 			jQuery.fx.speeds[opt.duration]) || jQuery.fx.speeds.def;
       
  3152 
       
  3153 		// Queueing
       
  3154 		opt.old = opt.complete;
       
  3155 		opt.complete = function(){
       
  3156 			if ( opt.queue !== false )
       
  3157 				jQuery(this).dequeue();
       
  3158 			if ( jQuery.isFunction( opt.old ) )
       
  3159 				opt.old.call( this );
       
  3160 		};
       
  3161 
       
  3162 		return opt;
       
  3163 	},
       
  3164 
       
  3165 	easing: {
       
  3166 		linear: function( p, n, firstNum, diff ) {
       
  3167 			return firstNum + diff * p;
       
  3168 		},
       
  3169 		swing: function( p, n, firstNum, diff ) {
       
  3170 			return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
       
  3171 		}
       
  3172 	},
       
  3173 
       
  3174 	timers: [],
       
  3175 	timerId: null,
       
  3176 
       
  3177 	fx: function( elem, options, prop ){
       
  3178 		this.options = options;
       
  3179 		this.elem = elem;
       
  3180 		this.prop = prop;
       
  3181 
       
  3182 		if ( !options.orig )
       
  3183 			options.orig = {};
       
  3184 	}
       
  3185 
       
  3186 });
       
  3187 
       
  3188 jQuery.fx.prototype = {
       
  3189 
       
  3190 	// Simple function for setting a style value
       
  3191 	update: function(){
       
  3192 		if ( this.options.step )
       
  3193 			this.options.step.call( this.elem, this.now, this );
       
  3194 
       
  3195 		(jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
       
  3196 
       
  3197 		// Set display property to block for height/width animations
       
  3198 		if ( this.prop == "height" || this.prop == "width" )
       
  3199 			this.elem.style.display = "block";
       
  3200 	},
       
  3201 
       
  3202 	// Get the current size
       
  3203 	cur: function(force){
       
  3204 		if ( this.elem[this.prop] != null && this.elem.style[this.prop] == null )
       
  3205 			return this.elem[ this.prop ];
       
  3206 
       
  3207 		var r = parseFloat(jQuery.css(this.elem, this.prop, force));
       
  3208 		return r && r > -10000 ? r : parseFloat(jQuery.curCSS(this.elem, this.prop)) || 0;
       
  3209 	},
       
  3210 
       
  3211 	// Start an animation from one number to another
       
  3212 	custom: function(from, to, unit){
       
  3213 		this.startTime = now();
       
  3214 		this.start = from;
       
  3215 		this.end = to;
       
  3216 		this.unit = unit || this.unit || "px";
       
  3217 		this.now = this.start;
       
  3218 		this.pos = this.state = 0;
       
  3219 		this.update();
       
  3220 
       
  3221 		var self = this;
       
  3222 		function t(gotoEnd){
       
  3223 			return self.step(gotoEnd);
       
  3224 		}
       
  3225 
       
  3226 		t.elem = this.elem;
       
  3227 
       
  3228 		jQuery.timers.push(t);
       
  3229 
       
  3230 		if ( jQuery.timerId == null ) {
       
  3231 			jQuery.timerId = setInterval(function(){
       
  3232 				var timers = jQuery.timers;
       
  3233 
       
  3234 				for ( var i = 0; i < timers.length; i++ )
       
  3235 					if ( !timers[i]() )
       
  3236 						timers.splice(i--, 1);
       
  3237 
       
  3238 				if ( !timers.length ) {
       
  3239 					clearInterval( jQuery.timerId );
       
  3240 					jQuery.timerId = null;
       
  3241 				}
       
  3242 			}, 13);
       
  3243 		}
       
  3244 	},
       
  3245 
       
  3246 	// Simple 'show' function
       
  3247 	show: function(){
       
  3248 		// Remember where we started, so that we can go back to it later
       
  3249 		this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );
       
  3250 		this.options.show = true;
       
  3251 
       
  3252 		// Begin the animation
       
  3253 		this.custom(0, this.cur());
       
  3254 
       
  3255 		// Make sure that we start at a small width/height to avoid any
       
  3256 		// flash of content
       
  3257 		if ( this.prop == "width" || this.prop == "height" )
       
  3258 			this.elem.style[this.prop] = "1px";
       
  3259 
       
  3260 		// Start by showing the element
       
  3261 		jQuery(this.elem).show();
       
  3262 	},
       
  3263 
       
  3264 	// Simple 'hide' function
       
  3265 	hide: function(){
       
  3266 		// Remember where we started, so that we can go back to it later
       
  3267 		this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );
       
  3268 		this.options.hide = true;
       
  3269 
       
  3270 		// Begin the animation
       
  3271 		this.custom(this.cur(), 0);
       
  3272 	},
       
  3273 
       
  3274 	// Each step of an animation
       
  3275 	step: function(gotoEnd){
       
  3276 		var t = now();
       
  3277 
       
  3278 		if ( gotoEnd || t > this.options.duration + this.startTime ) {
       
  3279 			this.now = this.end;
       
  3280 			this.pos = this.state = 1;
       
  3281 			this.update();
       
  3282 
       
  3283 			this.options.curAnim[ this.prop ] = true;
       
  3284 
       
  3285 			var done = true;
       
  3286 			for ( var i in this.options.curAnim )
       
  3287 				if ( this.options.curAnim[i] !== true )
       
  3288 					done = false;
       
  3289 
       
  3290 			if ( done ) {
       
  3291 				if ( this.options.display != null ) {
       
  3292 					// Reset the overflow
       
  3293 					this.elem.style.overflow = this.options.overflow;
       
  3294 
       
  3295 					// Reset the display
       
  3296 					this.elem.style.display = this.options.display;
       
  3297 					if ( jQuery.css(this.elem, "display") == "none" )
       
  3298 						this.elem.style.display = "block";
       
  3299 				}
       
  3300 
       
  3301 				// Hide the element if the "hide" operation was done
       
  3302 				if ( this.options.hide )
       
  3303 					this.elem.style.display = "none";
       
  3304 
       
  3305 				// Reset the properties, if the item has been hidden or shown
       
  3306 				if ( this.options.hide || this.options.show )
       
  3307 					for ( var p in this.options.curAnim )
       
  3308 						jQuery.attr(this.elem.style, p, this.options.orig[p]);
       
  3309 			}
       
  3310 
       
  3311 			if ( done )
       
  3312 				// Execute the complete function
       
  3313 				this.options.complete.call( this.elem );
       
  3314 
       
  3315 			return false;
       
  3316 		} else {
       
  3317 			var n = t - this.startTime;
       
  3318 			this.state = n / this.options.duration;
       
  3319 
       
  3320 			// Perform the easing function, defaults to swing
       
  3321 			this.pos = jQuery.easing[this.options.easing || (jQuery.easing.swing ? "swing" : "linear")](this.state, n, 0, 1, this.options.duration);
       
  3322 			this.now = this.start + ((this.end - this.start) * this.pos);
       
  3323 
       
  3324 			// Perform the next step of the animation
       
  3325 			this.update();
       
  3326 		}
       
  3327 
       
  3328 		return true;
       
  3329 	}
       
  3330 
       
  3331 };
       
  3332 
       
  3333 jQuery.extend( jQuery.fx, {
       
  3334 	speeds:{
       
  3335 		slow: 600,
       
  3336  		fast: 200,
       
  3337  		// Default speed
       
  3338  		def: 400
       
  3339 	},
       
  3340 	step: {
       
  3341 		scrollLeft: function(fx){
       
  3342 			fx.elem.scrollLeft = fx.now;
       
  3343 		},
       
  3344 
       
  3345 		scrollTop: function(fx){
       
  3346 			fx.elem.scrollTop = fx.now;
       
  3347 		},
       
  3348 
       
  3349 		opacity: function(fx){
       
  3350 			jQuery.attr(fx.elem.style, "opacity", fx.now);
       
  3351 		},
       
  3352 
       
  3353 		_default: function(fx){
       
  3354 			fx.elem.style[ fx.prop ] = fx.now + fx.unit;
       
  3355 		}
       
  3356 	}
       
  3357 });
       
  3358 // The Offset Method
       
  3359 // Originally By Brandon Aaron, part of the Dimension Plugin
       
  3360 // http://jquery.com/plugins/project/dimensions
       
  3361 jQuery.fn.offset = function() {
       
  3362 	var left = 0, top = 0, elem = this[0], results;
       
  3363 
       
  3364 	if ( elem ) with ( jQuery.browser ) {
       
  3365 		var parent       = elem.parentNode,
       
  3366 		    offsetChild  = elem,
       
  3367 		    offsetParent = elem.offsetParent,
       
  3368 		    doc          = elem.ownerDocument,
       
  3369 		    safari2      = safari && parseInt(version) < 522 && !/adobeair/i.test(userAgent),
       
  3370 		    css          = jQuery.curCSS,
       
  3371 		    fixed        = css(elem, "position") == "fixed";
       
  3372 
       
  3373 		// Use getBoundingClientRect if available
       
  3374 		if ( elem.getBoundingClientRect ) {
       
  3375 			var box = elem.getBoundingClientRect();
       
  3376 
       
  3377 			// Add the document scroll offsets
       
  3378 			add(box.left + Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft),
       
  3379 				box.top  + Math.max(doc.documentElement.scrollTop,  doc.body.scrollTop));
       
  3380 
       
  3381 			// IE adds the HTML element's border, by default it is medium which is 2px
       
  3382 			// IE 6 and 7 quirks mode the border width is overwritable by the following css html { border: 0; }
       
  3383 			// IE 7 standards mode, the border is always 2px
       
  3384 			// This border/offset is typically represented by the clientLeft and clientTop properties
       
  3385 			// However, in IE6 and 7 quirks mode the clientLeft and clientTop properties are not updated when overwriting it via CSS
       
  3386 			// Therefore this method will be off by 2px in IE while in quirksmode
       
  3387 			add( -doc.documentElement.clientLeft, -doc.documentElement.clientTop );
       
  3388 
       
  3389 		// Otherwise loop through the offsetParents and parentNodes
       
  3390 		} else {
       
  3391 
       
  3392 			// Initial element offsets
       
  3393 			add( elem.offsetLeft, elem.offsetTop );
       
  3394 
       
  3395 			// Get parent offsets
       
  3396 			while ( offsetParent ) {
       
  3397 				// Add offsetParent offsets
       
  3398 				add( offsetParent.offsetLeft, offsetParent.offsetTop );
       
  3399 
       
  3400 				// Mozilla and Safari > 2 does not include the border on offset parents
       
  3401 				// However Mozilla adds the border for table or table cells
       
  3402 				if ( mozilla && !/^t(able|d|h)$/i.test(offsetParent.tagName) || safari && !safari2 )
       
  3403 					border( offsetParent );
       
  3404 
       
  3405 				// Add the document scroll offsets if position is fixed on any offsetParent
       
  3406 				if ( !fixed && css(offsetParent, "position") == "fixed" )
       
  3407 					fixed = true;
       
  3408 
       
  3409 				// Set offsetChild to previous offsetParent unless it is the body element
       
  3410 				offsetChild  = /^body$/i.test(offsetParent.tagName) ? offsetChild : offsetParent;
       
  3411 				// Get next offsetParent
       
  3412 				offsetParent = offsetParent.offsetParent;
       
  3413 			}
       
  3414 
       
  3415 			// Get parent scroll offsets
       
  3416 			while ( parent && parent.tagName && !/^body|html$/i.test(parent.tagName) ) {
       
  3417 				// Remove parent scroll UNLESS that parent is inline or a table to work around Opera inline/table scrollLeft/Top bug
       
  3418 				if ( !/^inline|table.*$/i.test(css(parent, "display")) )
       
  3419 					// Subtract parent scroll offsets
       
  3420 					add( -parent.scrollLeft, -parent.scrollTop );
       
  3421 
       
  3422 				// Mozilla does not add the border for a parent that has overflow != visible
       
  3423 				if ( mozilla && css(parent, "overflow") != "visible" )
       
  3424 					border( parent );
       
  3425 
       
  3426 				// Get next parent
       
  3427 				parent = parent.parentNode;
       
  3428 			}
       
  3429 
       
  3430 			// Safari <= 2 doubles body offsets with a fixed position element/offsetParent or absolutely positioned offsetChild
       
  3431 			// Mozilla doubles body offsets with a non-absolutely positioned offsetChild
       
  3432 			if ( (safari2 && (fixed || css(offsetChild, "position") == "absolute")) ||
       
  3433 				(mozilla && css(offsetChild, "position") != "absolute") )
       
  3434 					add( -doc.body.offsetLeft, -doc.body.offsetTop );
       
  3435 
       
  3436 			// Add the document scroll offsets if position is fixed
       
  3437 			if ( fixed )
       
  3438 				add(Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft),
       
  3439 					Math.max(doc.documentElement.scrollTop,  doc.body.scrollTop));
       
  3440 		}
       
  3441 
       
  3442 		// Return an object with top and left properties
       
  3443 		results = { top: top, left: left };
       
  3444 	}
       
  3445 
       
  3446 	function border(elem) {
       
  3447 		add( jQuery.curCSS(elem, "borderLeftWidth", true), jQuery.curCSS(elem, "borderTopWidth", true) );
       
  3448 	}
       
  3449 
       
  3450 	function add(l, t) {
       
  3451 		left += parseInt(l, 10) || 0;
       
  3452 		top += parseInt(t, 10) || 0;
       
  3453 	}
       
  3454 
       
  3455 	return results;
       
  3456 };
       
  3457 
       
  3458 
       
  3459 jQuery.fn.extend({
       
  3460 	position: function() {
       
  3461 		var left = 0, top = 0, results;
       
  3462 
       
  3463 		if ( this[0] ) {
       
  3464 			// Get *real* offsetParent
       
  3465 			var offsetParent = this.offsetParent(),
       
  3466 
       
  3467 			// Get correct offsets
       
  3468 			offset       = this.offset(),
       
  3469 			parentOffset = /^body|html$/i.test(offsetParent[0].tagName) ? { top: 0, left: 0 } : offsetParent.offset();
       
  3470 
       
  3471 			// Subtract element margins
       
  3472 			// note: when an element has margin: auto the offsetLeft and marginLeft 
       
  3473 			// are the same in Safari causing offset.left to incorrectly be 0
       
  3474 			offset.top  -= num( this, 'marginTop' );
       
  3475 			offset.left -= num( this, 'marginLeft' );
       
  3476 
       
  3477 			// Add offsetParent borders
       
  3478 			parentOffset.top  += num( offsetParent, 'borderTopWidth' );
       
  3479 			parentOffset.left += num( offsetParent, 'borderLeftWidth' );
       
  3480 
       
  3481 			// Subtract the two offsets
       
  3482 			results = {
       
  3483 				top:  offset.top  - parentOffset.top,
       
  3484 				left: offset.left - parentOffset.left
       
  3485 			};
       
  3486 		}
       
  3487 
       
  3488 		return results;
       
  3489 	},
       
  3490 
       
  3491 	offsetParent: function() {
       
  3492 		var offsetParent = this[0].offsetParent;
       
  3493 		while ( offsetParent && (!/^body|html$/i.test(offsetParent.tagName) && jQuery.css(offsetParent, 'position') == 'static') )
       
  3494 			offsetParent = offsetParent.offsetParent;
       
  3495 		return jQuery(offsetParent);
       
  3496 	}
       
  3497 });
       
  3498 
       
  3499 
       
  3500 // Create scrollLeft and scrollTop methods
       
  3501 jQuery.each( ['Left', 'Top'], function(i, name) {
       
  3502 	var method = 'scroll' + name;
       
  3503 	
       
  3504 	jQuery.fn[ method ] = function(val) {
       
  3505 		if (!this[0]) return;
       
  3506 
       
  3507 		return val != undefined ?
       
  3508 
       
  3509 			// Set the scroll offset
       
  3510 			this.each(function() {
       
  3511 				this == window || this == document ?
       
  3512 					window.scrollTo(
       
  3513 						!i ? val : jQuery(window).scrollLeft(),
       
  3514 						 i ? val : jQuery(window).scrollTop()
       
  3515 					) :
       
  3516 					this[ method ] = val;
       
  3517 			}) :
       
  3518 
       
  3519 			// Return the scroll offset
       
  3520 			this[0] == window || this[0] == document ?
       
  3521 				self[ i ? 'pageYOffset' : 'pageXOffset' ] ||
       
  3522 					jQuery.boxModel && document.documentElement[ method ] ||
       
  3523 					document.body[ method ] :
       
  3524 				this[0][ method ];
       
  3525 	};
       
  3526 });
       
  3527 // Create innerHeight, innerWidth, outerHeight and outerWidth methods
       
  3528 jQuery.each([ "Height", "Width" ], function(i, name){
       
  3529 
       
  3530 	var tl = i ? "Left"  : "Top",  // top or left
       
  3531 		br = i ? "Right" : "Bottom"; // bottom or right
       
  3532 
       
  3533 	// innerHeight and innerWidth
       
  3534 	jQuery.fn["inner" + name] = function(){
       
  3535 		return this[ name.toLowerCase() ]() +
       
  3536 			num(this, "padding" + tl) +
       
  3537 			num(this, "padding" + br);
       
  3538 	};
       
  3539 
       
  3540 	// outerHeight and outerWidth
       
  3541 	jQuery.fn["outer" + name] = function(margin) {
       
  3542 		return this["inner" + name]() +
       
  3543 			num(this, "border" + tl + "Width") +
       
  3544 			num(this, "border" + br + "Width") +
       
  3545 			(margin ?
       
  3546 				num(this, "margin" + tl) + num(this, "margin" + br) : 0);
       
  3547 	};
       
  3548 
       
  3549 });})();