1 /*!
  2  * jQuery JavaScript Library v1.4.4
  3  * http://jquery.com/
  4  *
  5  * Copyright 2010, John Resig
  6  * Dual licensed under the MIT or GPL Version 2 licenses.
  7  * http://jquery.org/license
  8  *
  9  * Includes Sizzle.js
 10  * http://sizzlejs.com/
 11  * Copyright 2010, The Dojo Foundation
 12  * Released under the MIT, BSD, and GPL Licenses.
 13  *
 14  * Date: Thu Nov 11 19:04:53 2010 -0500
 15  */
 16 (function( window, undefined ) {
 17 
 18 // Use the correct document accordingly with window argument (sandbox)
 19 var document = window.document;
 20 var jQuery = (function() {
 21 
 22 // Define a local copy of jQuery
 23 var jQuery = function( selector, context ) {
 24 		// The jQuery object is actually just the init constructor 'enhanced'
 25 		return new jQuery.fn.init( selector, context );
 26 	},
 27 
 28 	// Map over jQuery in case of overwrite
 29 	_jQuery = window.jQuery,
 30 
 31 	// Map over the $ in case of overwrite
 32 	_$ = window.$,
 33 
 34 	// A central reference to the root jQuery(document)
 35 	rootjQuery,
 36 
 37 	// A simple way to check for HTML strings or ID strings
 38 	// (both of which we optimize for)
 39 	quickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]+)$)/,
 40 
 41 	// Is it a simple selector
 42 	isSimple = /^.[^:#\[\.,]*$/,
 43 
 44 	// Check if a string has a non-whitespace character in it
 45 	rnotwhite = /\S/,
 46 	rwhite = /\s/,
 47 
 48 	// Used for trimming whitespace
 49 	trimLeft = /^\s+/,
 50 	trimRight = /\s+$/,
 51 
 52 	// Check for non-word characters
 53 	rnonword = /\W/,
 54 
 55 	// Check for digits
 56 	rdigit = /\d/,
 57 
 58 	// Match a standalone tag
 59 	rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/,
 60 
 61 	// JSON RegExp
 62 	rvalidchars = /^[\],:{}\s]*$/,
 63 	rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,
 64 	rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
 65 	rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g,
 66 
 67 	// Useragent RegExp
 68 	rwebkit = /(webkit)[ \/]([\w.]+)/,
 69 	ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/,
 70 	rmsie = /(msie) ([\w.]+)/,
 71 	rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/,
 72 
 73 	// Keep a UserAgent string for use with jQuery.browser
 74 	userAgent = navigator.userAgent,
 75 
 76 	// For matching the engine and version of the browser
 77 	browserMatch,
 78 	
 79 	// Has the ready events already been bound?
 80 	readyBound = false,
 81 	
 82 	// The functions to execute on DOM ready
 83 	readyList = [],
 84 
 85 	// The ready event handler
 86 	DOMContentLoaded,
 87 
 88 	// Save a reference to some core methods
 89 	toString = Object.prototype.toString,
 90 	hasOwn = Object.prototype.hasOwnProperty,
 91 	push = Array.prototype.push,
 92 	slice = Array.prototype.slice,
 93 	trim = String.prototype.trim,
 94 	indexOf = Array.prototype.indexOf,
 95 	
 96 	// [[Class]] -> type pairs
 97 	class2type = {};
 98 
 99 jQuery.fn = jQuery.prototype = {
100 	init: function( selector, context ) {
101 		var match, elem, ret, doc;
102 
103 		// Handle $(""), $(null), or $(undefined)
104 		if ( !selector ) {
105 			return this;
106 		}
107 
108 		// Handle $(DOMElement)
109 		if ( selector.nodeType ) {
110 			this.context = this[0] = selector;
111 			this.length = 1;
112 			return this;
113 		}
114 		
115 		// The body element only exists once, optimize finding it
116 		if ( selector === "body" && !context && document.body ) {
117 			this.context = document;
118 			this[0] = document.body;
119 			this.selector = "body";
120 			this.length = 1;
121 			return this;
122 		}
123 
124 		// Handle HTML strings
125 		if ( typeof selector === "string" ) {
126 			// Are we dealing with HTML string or an ID?
127 			match = quickExpr.exec( selector );
128 
129 			// Verify a match, and that no context was specified for #id
130 			if ( match && (match[1] || !context) ) {
131 
132 				// HANDLE: $(html) -> $(array)
133 				if ( match[1] ) {
134 					doc = (context ? context.ownerDocument || context : document);
135 
136 					// If a single string is passed in and it's a single tag
137 					// just do a createElement and skip the rest
138 					ret = rsingleTag.exec( selector );
139 
140 					if ( ret ) {
141 						if ( jQuery.isPlainObject( context ) ) {
142 							selector = [ document.createElement( ret[1] ) ];
143 							jQuery.fn.attr.call( selector, context, true );
144 
145 						} else {
146 							selector = [ doc.createElement( ret[1] ) ];
147 						}
148 
149 					} else {
150 						ret = jQuery.buildFragment( [ match[1] ], [ doc ] );
151 						selector = (ret.cacheable ? ret.fragment.cloneNode(true) : ret.fragment).childNodes;
152 					}
153 					
154 					return jQuery.merge( this, selector );
155 					
156 				// HANDLE: $("#id")
157 				} else {
158 					elem = document.getElementById( match[2] );
159 
160 					// Check parentNode to catch when Blackberry 4.6 returns
161 					// nodes that are no longer in the document #6963
162 					if ( elem && elem.parentNode ) {
163 						// Handle the case where IE and Opera return items
164 						// by name instead of ID
165 						if ( elem.id !== match[2] ) {
166 							return rootjQuery.find( selector );
167 						}
168 
169 						// Otherwise, we inject the element directly into the jQuery object
170 						this.length = 1;
171 						this[0] = elem;
172 					}
173 
174 					this.context = document;
175 					this.selector = selector;
176 					return this;
177 				}
178 
179 			// HANDLE: $("TAG")
180 			} else if ( !context && !rnonword.test( selector ) ) {
181 				this.selector = selector;
182 				this.context = document;
183 				selector = document.getElementsByTagName( selector );
184 				return jQuery.merge( this, selector );
185 
186 			// HANDLE: $(expr, $(...))
187 			} else if ( !context || context.jquery ) {
188 				return (context || rootjQuery).find( selector );
189 
190 			// HANDLE: $(expr, context)
191 			// (which is just equivalent to: $(context).find(expr)
192 			} else {
193 				return jQuery( context ).find( selector );
194 			}
195 
196 		// HANDLE: $(function)
197 		// Shortcut for document ready
198 		} else if ( jQuery.isFunction( selector ) ) {
199 			return rootjQuery.ready( selector );
200 		}
201 
202 		if (selector.selector !== undefined) {
203 			this.selector = selector.selector;
204 			this.context = selector.context;
205 		}
206 
207 		return jQuery.makeArray( selector, this );
208 	},
209 
210 	// Start with an empty selector
211 	selector: "",
212 
213 	// The current version of jQuery being used
214 	jquery: "1.4.4",
215 
216 	// The default length of a jQuery object is 0
217 	length: 0,
218 
219 	// The number of elements contained in the matched element set
220 	size: function() {
221 		return this.length;
222 	},
223 
224 	toArray: function() {
225 		return slice.call( this, 0 );
226 	},
227 
228 	// Get the Nth element in the matched element set OR
229 	// Get the whole matched element set as a clean array
230 	get: function( num ) {
231 		return num == null ?
232 
233 			// Return a 'clean' array
234 			this.toArray() :
235 
236 			// Return just the object
237 			( num < 0 ? this.slice(num)[ 0 ] : this[ num ] );
238 	},
239 
240 	// Take an array of elements and push it onto the stack
241 	// (returning the new matched element set)
242 	pushStack: function( elems, name, selector ) {
243 		// Build a new jQuery matched element set
244 		var ret = jQuery();
245 
246 		if ( jQuery.isArray( elems ) ) {
247 			push.apply( ret, elems );
248 		
249 		} else {
250 			jQuery.merge( ret, elems );
251 		}
252 
253 		// Add the old object onto the stack (as a reference)
254 		ret.prevObject = this;
255 
256 		ret.context = this.context;
257 
258 		if ( name === "find" ) {
259 			ret.selector = this.selector + (this.selector ? " " : "") + selector;
260 		} else if ( name ) {
261 			ret.selector = this.selector + "." + name + "(" + selector + ")";
262 		}
263 
264 		// Return the newly-formed element set
265 		return ret;
266 	},
267 
268 	// Execute a callback for every element in the matched set.
269 	// (You can seed the arguments with an array of args, but this is
270 	// only used internally.)
271 	each: function( callback, args ) {
272 		return jQuery.each( this, callback, args );
273 	},
274 	
275 	ready: function( fn ) {
276 		// Attach the listeners
277 		jQuery.bindReady();
278 
279 		// If the DOM is already ready
280 		if ( jQuery.isReady ) {
281 			// Execute the function immediately
282 			fn.call( document, jQuery );
283 
284 		// Otherwise, remember the function for later
285 		} else if ( readyList ) {
286 			// Add the function to the wait list
287 			readyList.push( fn );
288 		}
289 
290 		return this;
291 	},
292 	
293 	eq: function( i ) {
294 		return i === -1 ?
295 			this.slice( i ) :
296 			this.slice( i, +i + 1 );
297 	},
298 
299 	first: function() {
300 		return this.eq( 0 );
301 	},
302 
303 	last: function() {
304 		return this.eq( -1 );
305 	},
306 
307 	slice: function() {
308 		return this.pushStack( slice.apply( this, arguments ),
309 			"slice", slice.call(arguments).join(",") );
310 	},
311 
312 	map: function( callback ) {
313 		return this.pushStack( jQuery.map(this, function( elem, i ) {
314 			return callback.call( elem, i, elem );
315 		}));
316 	},
317 	
318 	end: function() {
319 		return this.prevObject || jQuery(null);
320 	},
321 
322 	// For internal use only.
323 	// Behaves like an Array's method, not like a jQuery method.
324 	push: push,
325 	sort: [].sort,
326 	splice: [].splice
327 };
328 
329 // Give the init function the jQuery prototype for later instantiation
330 jQuery.fn.init.prototype = jQuery.fn;
331 
332 jQuery.extend = jQuery.fn.extend = function() {
333 	 var options, name, src, copy, copyIsArray, clone,
334 		target = arguments[0] || {},
335 		i = 1,
336 		length = arguments.length,
337 		deep = false;
338 
339 	// Handle a deep copy situation
340 	if ( typeof target === "boolean" ) {
341 		deep = target;
342 		target = arguments[1] || {};
343 		// skip the boolean and the target
344 		i = 2;
345 	}
346 
347 	// Handle case when target is a string or something (possible in deep copy)
348 	if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
349 		target = {};
350 	}
351 
352 	// extend jQuery itself if only one argument is passed
353 	if ( length === i ) {
354 		target = this;
355 		--i;
356 	}
357 
358 	for ( ; i < length; i++ ) {
359 		// Only deal with non-null/undefined values
360 		if ( (options = arguments[ i ]) != null ) {
361 			// Extend the base object
362 			for ( name in options ) {
363 				src = target[ name ];
364 				copy = options[ name ];
365 
366 				// Prevent never-ending loop
367 				if ( target === copy ) {
368 					continue;
369 				}
370 
371 				// Recurse if we're merging plain objects or arrays
372 				if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
373 					if ( copyIsArray ) {
374 						copyIsArray = false;
375 						clone = src && jQuery.isArray(src) ? src : [];
376 
377 					} else {
378 						clone = src && jQuery.isPlainObject(src) ? src : {};
379 					}
380 
381 					// Never move original objects, clone them
382 					target[ name ] = jQuery.extend( deep, clone, copy );
383 
384 				// Don't bring in undefined values
385 				} else if ( copy !== undefined ) {
386 					target[ name ] = copy;
387 				}
388 			}
389 		}
390 	}
391 
392 	// Return the modified object
393 	return target;
394 };
395 
396 jQuery.extend({
397 	noConflict: function( deep ) {
398 		window.$ = _$;
399 
400 		if ( deep ) {
401 			window.jQuery = _jQuery;
402 		}
403 
404 		return jQuery;
405 	},
406 	
407 	// Is the DOM ready to be used? Set to true once it occurs.
408 	isReady: false,
409 
410 	// A counter to track how many items to wait for before
411 	// the ready event fires. See #6781
412 	readyWait: 1,
413 	
414 	// Handle when the DOM is ready
415 	ready: function( wait ) {
416 		// A third-party is pushing the ready event forwards
417 		if ( wait === true ) {
418 			jQuery.readyWait--;
419 		}
420 
421 		// Make sure that the DOM is not already loaded
422 		if ( !jQuery.readyWait || (wait !== true && !jQuery.isReady) ) {
423 			// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
424 			if ( !document.body ) {
425 				return setTimeout( jQuery.ready, 1 );
426 			}
427 
428 			// Remember that the DOM is ready
429 			jQuery.isReady = true;
430 
431 			// If a normal DOM Ready event fired, decrement, and wait if need be
432 			if ( wait !== true && --jQuery.readyWait > 0 ) {
433 				return;
434 			}
435 
436 			// If there are functions bound, to execute
437 			if ( readyList ) {
438 				// Execute all of them
439 				var fn,
440 					i = 0,
441 					ready = readyList;
442 
443 				// Reset the list of functions
444 				readyList = null;
445 
446 				while ( (fn = ready[ i++ ]) ) {
447 					fn.call( document, jQuery );
448 				}
449 
450 				// Trigger any bound ready events
451 				if ( jQuery.fn.trigger ) {
452 					jQuery( document ).trigger( "ready" ).unbind( "ready" );
453 				}
454 			}
455 		}
456 	},
457 	
458 	bindReady: function() {
459 		if ( readyBound ) {
460 			return;
461 		}
462 
463 		readyBound = true;
464 
465 		// Catch cases where $(document).ready() is called after the
466 		// browser event has already occurred.
467 		if ( document.readyState === "complete" ) {
468 			// Handle it asynchronously to allow scripts the opportunity to delay ready
469 			return setTimeout( jQuery.ready, 1 );
470 		}
471 
472 		// Mozilla, Opera and webkit nightlies currently support this event
473 		if ( document.addEventListener ) {
474 			// Use the handy event callback
475 			document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
476 			
477 			// A fallback to window.onload, that will always work
478 			window.addEventListener( "load", jQuery.ready, false );
479 
480 		// If IE event model is used
481 		} else if ( document.attachEvent ) {
482 			// ensure firing before onload,
483 			// maybe late but safe also for iframes
484 			document.attachEvent("onreadystatechange", DOMContentLoaded);
485 			
486 			// A fallback to window.onload, that will always work
487 			window.attachEvent( "onload", jQuery.ready );
488 
489 			// If IE and not a frame
490 			// continually check to see if the document is ready
491 			var toplevel = false;
492 
493 			try {
494 				toplevel = window.frameElement == null;
495 			} catch(e) {}
496 
497 			if ( document.documentElement.doScroll && toplevel ) {
498 				doScrollCheck();
499 			}
500 		}
501 	},
502 
503 	// See test/unit/core.js for details concerning isFunction.
504 	// Since version 1.3, DOM methods and functions like alert
505 	// aren't supported. They return false on IE (#2968).
506 	isFunction: function( obj ) {
507 		return jQuery.type(obj) === "function";
508 	},
509 
510 	isArray: Array.isArray || function( obj ) {
511 		return jQuery.type(obj) === "array";
512 	},
513 
514 	// A crude way of determining if an object is a window
515 	isWindow: function( obj ) {
516 		return obj && typeof obj === "object" && "setInterval" in obj;
517 	},
518 
519 	isNaN: function( obj ) {
520 		return obj == null || !rdigit.test( obj ) || isNaN( obj );
521 	},
522 
523 	type: function( obj ) {
524 		return obj == null ?
525 			String( obj ) :
526 			class2type[ toString.call(obj) ] || "object";
527 	},
528 
529 	isPlainObject: function( obj ) {
530 		// Must be an Object.
531 		// Because of IE, we also have to check the presence of the constructor property.
532 		// Make sure that DOM nodes and window objects don't pass through, as well
533 		if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
534 			return false;
535 		}
536 		
537 		// Not own constructor property must be Object
538 		if ( obj.constructor &&
539 			!hasOwn.call(obj, "constructor") &&
540 			!hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
541 			return false;
542 		}
543 		
544 		// Own properties are enumerated firstly, so to speed up,
545 		// if last one is own, then all properties are own.
546 	
547 		var key;
548 		for ( key in obj ) {}
549 		
550 		return key === undefined || hasOwn.call( obj, key );
551 	},
552 
553 	isEmptyObject: function( obj ) {
554 		for ( var name in obj ) {
555 			return false;
556 		}
557 		return true;
558 	},
559 	
560 	error: function( msg ) {
561 		throw msg;
562 	},
563 	
564 	parseJSON: function( data ) {
565 		if ( typeof data !== "string" || !data ) {
566 			return null;
567 		}
568 
569 		// Make sure leading/trailing whitespace is removed (IE can't handle it)
570 		data = jQuery.trim( data );
571 		
572 		// Make sure the incoming data is actual JSON
573 		// Logic borrowed from http://json.org/json2.js
574 		if ( rvalidchars.test(data.replace(rvalidescape, "@")
575 			.replace(rvalidtokens, "]")
576 			.replace(rvalidbraces, "")) ) {
577 
578 			// Try to use the native JSON parser first
579 			return window.JSON && window.JSON.parse ?
580 				window.JSON.parse( data ) :
581 				(new Function("return " + data))();
582 
583 		} else {
584 			jQuery.error( "Invalid JSON: " + data );
585 		}
586 	},
587 
588 	noop: function() {},
589 
590 	// Evalulates a script in a global context
591 	globalEval: function( data ) {
592 		if ( data && rnotwhite.test(data) ) {
593 			// Inspired by code by Andrea Giammarchi
594 			// http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
595 			var head = document.getElementsByTagName("head")[0] || document.documentElement,
596 				script = document.createElement("script");
597 
598 			script.type = "text/javascript";
599 
600 			if ( jQuery.support.scriptEval ) {
601 				script.appendChild( document.createTextNode( data ) );
602 			} else {
603 				script.text = data;
604 			}
605 
606 			// Use insertBefore instead of appendChild to circumvent an IE6 bug.
607 			// This arises when a base node is used (#2709).
608 			head.insertBefore( script, head.firstChild );
609 			head.removeChild( script );
610 		}
611 	},
612 
613 	nodeName: function( elem, name ) {
614 		return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
615 	},
616 
617 	// args is for internal usage only
618 	each: function( object, callback, args ) {
619 		var name, i = 0,
620 			length = object.length,
621 			isObj = length === undefined || jQuery.isFunction(object);
622 
623 		if ( args ) {
624 			if ( isObj ) {
625 				for ( name in object ) {
626 					if ( callback.apply( object[ name ], args ) === false ) {
627 						break;
628 					}
629 				}
630 			} else {
631 				for ( ; i < length; ) {
632 					if ( callback.apply( object[ i++ ], args ) === false ) {
633 						break;
634 					}
635 				}
636 			}
637 
638 		// A special, fast, case for the most common use of each
639 		} else {
640 			if ( isObj ) {
641 				for ( name in object ) {
642 					if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
643 						break;
644 					}
645 				}
646 			} else {
647 				for ( var value = object[0];
648 					i < length && callback.call( value, i, value ) !== false; value = object[++i] ) {}
649 			}
650 		}
651 
652 		return object;
653 	},
654 
655 	// Use native String.trim function wherever possible
656 	trim: trim ?
657 		function( text ) {
658 			return text == null ?
659 				"" :
660 				trim.call( text );
661 		} :
662 
663 		// Otherwise use our own trimming functionality
664 		function( text ) {
665 			return text == null ?
666 				"" :
667 				text.toString().replace( trimLeft, "" ).replace( trimRight, "" );
668 		},
669 
670 	// results is for internal usage only
671 	makeArray: function( array, results ) {
672 		var ret = results || [];
673 
674 		if ( array != null ) {
675 			// The window, strings (and functions) also have 'length'
676 			// The extra typeof function check is to prevent crashes
677 			// in Safari 2 (See: #3039)
678 			// Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930
679 			var type = jQuery.type(array);
680 
681 			if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) {
682 				push.call( ret, array );
683 			} else {
684 				jQuery.merge( ret, array );
685 			}
686 		}
687 
688 		return ret;
689 	},
690 
691 	inArray: function( elem, array ) {
692 		if ( array.indexOf ) {
693 			return array.indexOf( elem );
694 		}
695 
696 		for ( var i = 0, length = array.length; i < length; i++ ) {
697 			if ( array[ i ] === elem ) {
698 				return i;
699 			}
700 		}
701 
702 		return -1;
703 	},
704 
705 	merge: function( first, second ) {
706 		var i = first.length,
707 			j = 0;
708 
709 		if ( typeof second.length === "number" ) {
710 			for ( var l = second.length; j < l; j++ ) {
711 				first[ i++ ] = second[ j ];
712 			}
713 		
714 		} else {
715 			while ( second[j] !== undefined ) {
716 				first[ i++ ] = second[ j++ ];
717 			}
718 		}
719 
720 		first.length = i;
721 
722 		return first;
723 	},
724 
725 	grep: function( elems, callback, inv ) {
726 		var ret = [], retVal;
727 		inv = !!inv;
728 
729 		// Go through the array, only saving the items
730 		// that pass the validator function
731 		for ( var i = 0, length = elems.length; i < length; i++ ) {
732 			retVal = !!callback( elems[ i ], i );
733 			if ( inv !== retVal ) {
734 				ret.push( elems[ i ] );
735 			}
736 		}
737 
738 		return ret;
739 	},
740 
741 	// arg is for internal usage only
742 	map: function( elems, callback, arg ) {
743 		var ret = [], value;
744 
745 		// Go through the array, translating each of the items to their
746 		// new value (or values).
747 		for ( var i = 0, length = elems.length; i < length; i++ ) {
748 			value = callback( elems[ i ], i, arg );
749 
750 			if ( value != null ) {
751 				ret[ ret.length ] = value;
752 			}
753 		}
754 
755 		return ret.concat.apply( [], ret );
756 	},
757 
758 	// A global GUID counter for objects
759 	guid: 1,
760 
761 	proxy: function( fn, proxy, thisObject ) {
762 		if ( arguments.length === 2 ) {
763 			if ( typeof proxy === "string" ) {
764 				thisObject = fn;
765 				fn = thisObject[ proxy ];
766 				proxy = undefined;
767 
768 			} else if ( proxy && !jQuery.isFunction( proxy ) ) {
769 				thisObject = proxy;
770 				proxy = undefined;
771 			}
772 		}
773 
774 		if ( !proxy && fn ) {
775 			proxy = function() {
776 				return fn.apply( thisObject || this, arguments );
777 			};
778 		}
779 
780 		// Set the guid of unique handler to the same of original handler, so it can be removed
781 		if ( fn ) {
782 			proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
783 		}
784 
785 		// So proxy can be declared as an argument
786 		return proxy;
787 	},
788 
789 	// Mutifunctional method to get and set values to a collection
790 	// The value/s can be optionally by executed if its a function
791 	access: function( elems, key, value, exec, fn, pass ) {
792 		var length = elems.length;
793 	
794 		// Setting many attributes
795 		if ( typeof key === "object" ) {
796 			for ( var k in key ) {
797 				jQuery.access( elems, k, key[k], exec, fn, value );
798 			}
799 			return elems;
800 		}
801 	
802 		// Setting one attribute
803 		if ( value !== undefined ) {
804 			// Optionally, function values get executed if exec is true
805 			exec = !pass && exec && jQuery.isFunction(value);
806 		
807 			for ( var i = 0; i < length; i++ ) {
808 				fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
809 			}
810 		
811 			return elems;
812 		}
813 	
814 		// Getting an attribute
815 		return length ? fn( elems[0], key ) : undefined;
816 	},
817 
818 	now: function() {
819 		return (new Date()).getTime();
820 	},
821 
822 	// Use of jQuery.browser is frowned upon.
823 	// More details: http://docs.jquery.com/Utilities/jQuery.browser
824 	uaMatch: function( ua ) {
825 		ua = ua.toLowerCase();
826 
827 		var match = rwebkit.exec( ua ) ||
828 			ropera.exec( ua ) ||
829 			rmsie.exec( ua ) ||
830 			ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) ||
831 			[];
832 
833 		return { browser: match[1] || "", version: match[2] || "0" };
834 	},
835 
836 	browser: {}
837 });
838 
839 // Populate the class2type map
840 jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) {
841 	class2type[ "[object " + name + "]" ] = name.toLowerCase();
842 });
843 
844 browserMatch = jQuery.uaMatch( userAgent );
845 if ( browserMatch.browser ) {
846 	jQuery.browser[ browserMatch.browser ] = true;
847 	jQuery.browser.version = browserMatch.version;
848 }
849 
850 // Deprecated, use jQuery.browser.webkit instead
851 if ( jQuery.browser.webkit ) {
852 	jQuery.browser.safari = true;
853 }
854 
855 if ( indexOf ) {
856 	jQuery.inArray = function( elem, array ) {
857 		return indexOf.call( array, elem );
858 	};
859 }
860 
861 // Verify that \s matches non-breaking spaces
862 // (IE fails on this test)
863 if ( !rwhite.test( "\xA0" ) ) {
864 	trimLeft = /^[\s\xA0]+/;
865 	trimRight = /[\s\xA0]+$/;
866 }
867 
868 // All jQuery objects should point back to these
869 rootjQuery = jQuery(document);
870 
871 // Cleanup functions for the document ready method
872 if ( document.addEventListener ) {
873 	DOMContentLoaded = function() {
874 		document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
875 		jQuery.ready();
876 	};
877 
878 } else if ( document.attachEvent ) {
879 	DOMContentLoaded = function() {
880 		// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
881 		if ( document.readyState === "complete" ) {
882 			document.detachEvent( "onreadystatechange", DOMContentLoaded );
883 			jQuery.ready();
884 		}
885 	};
886 }
887 
888 // The DOM ready check for Internet Explorer
889 function doScrollCheck() {
890 	if ( jQuery.isReady ) {
891 		return;
892 	}
893 
894 	try {
895 		// If IE is used, use the trick by Diego Perini
896 		// http://javascript.nwbox.com/IEContentLoaded/
897 		document.documentElement.doScroll("left");
898 	} catch(e) {
899 		setTimeout( doScrollCheck, 1 );
900 		return;
901 	}
902 
903 	// and execute any waiting functions
904 	jQuery.ready();
905 }
906 
907 // Expose jQuery to the global object
908 return (window.jQuery = window.$ = jQuery);
909 
910 })();
911 
912 
913 (function() {
914 
915 	jQuery.support = {};
916 
917 	var root = document.documentElement,
918 		script = document.createElement("script"),
919 		div = document.createElement("div"),
920 		id = "script" + jQuery.now();
921 
922 	div.style.display = "none";
923 	div.innerHTML = "   <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
924 
925 	var all = div.getElementsByTagName("*"),
926 		a = div.getElementsByTagName("a")[0],
927 		select = document.createElement("select"),
928 		opt = select.appendChild( document.createElement("option") );
929 
930 	// Can't get basic test support
931 	if ( !all || !all.length || !a ) {
932 		return;
933 	}
934 
935 	jQuery.support = {
936 		// IE strips leading whitespace when .innerHTML is used
937 		leadingWhitespace: div.firstChild.nodeType === 3,
938 
939 		// Make sure that tbody elements aren't automatically inserted
940 		// IE will insert them into empty tables
941 		tbody: !div.getElementsByTagName("tbody").length,
942 
943 		// Make sure that link elements get serialized correctly by innerHTML
944 		// This requires a wrapper element in IE
945 		htmlSerialize: !!div.getElementsByTagName("link").length,
946 
947 		// Get the style information from getAttribute
948 		// (IE uses .cssText insted)
949 		style: /red/.test( a.getAttribute("style") ),
950 
951 		// Make sure that URLs aren't manipulated
952 		// (IE normalizes it by default)
953 		hrefNormalized: a.getAttribute("href") === "/a",
954 
955 		// Make sure that element opacity exists
956 		// (IE uses filter instead)
957 		// Use a regex to work around a WebKit issue. See #5145
958 		opacity: /^0.55$/.test( a.style.opacity ),
959 
960 		// Verify style float existence
961 		// (IE uses styleFloat instead of cssFloat)
962 		cssFloat: !!a.style.cssFloat,
963 
964 		// Make sure that if no value is specified for a checkbox
965 		// that it defaults to "on".
966 		// (WebKit defaults to "" instead)
967 		checkOn: div.getElementsByTagName("input")[0].value === "on",
968 
969 		// Make sure that a selected-by-default option has a working selected property.
970 		// (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
971 		optSelected: opt.selected,
972 
973 		// Will be defined later
974 		deleteExpando: true,
975 		optDisabled: false,
976 		checkClone: false,
977 		scriptEval: false,
978 		noCloneEvent: true,
979 		boxModel: null,
980 		inlineBlockNeedsLayout: false,
981 		shrinkWrapBlocks: false,
982 		reliableHiddenOffsets: true
983 	};
984 
985 	// Make sure that the options inside disabled selects aren't marked as disabled
986 	// (WebKit marks them as diabled)
987 	select.disabled = true;
988 	jQuery.support.optDisabled = !opt.disabled;
989 
990 	script.type = "text/javascript";
991 	try {
992 		script.appendChild( document.createTextNode( "window." + id + "=1;" ) );
993 	} catch(e) {}
994 
995 	root.insertBefore( script, root.firstChild );
996 
997 	// Make sure that the execution of code works by injecting a script
998 	// tag with appendChild/createTextNode
999 	// (IE doesn't support this, fails, and uses .text instead)
1000 	if ( window[ id ] ) {
1001 		jQuery.support.scriptEval = true;
1002 		delete window[ id ];
1003 	}
1004 
1005 	// Test to see if it's possible to delete an expando from an element
1006 	// Fails in Internet Explorer
1007 	try {
1008 		delete script.test;
1009 
1010 	} catch(e) {
1011 		jQuery.support.deleteExpando = false;
1012 	}
1013 
1014 	root.removeChild( script );
1015 
1016 	if ( div.attachEvent && div.fireEvent ) {
1017 		div.attachEvent("onclick", function click() {
1018 			// Cloning a node shouldn't copy over any
1019 			// bound event handlers (IE does this)
1020 			jQuery.support.noCloneEvent = false;
1021 			div.detachEvent("onclick", click);
1022 		});
1023 		div.cloneNode(true).fireEvent("onclick");
1024 	}
1025 
1026 	div = document.createElement("div");
1027 	div.innerHTML = "<input type='radio' name='radiotest' checked='checked'/>";
1028 
1029 	var fragment = document.createDocumentFragment();
1030 	fragment.appendChild( div.firstChild );
1031 
1032 	// WebKit doesn't clone checked state correctly in fragments
1033 	jQuery.support.checkClone = fragment.cloneNode(true).cloneNode(true).lastChild.checked;
1034 
1035 	// Figure out if the W3C box model works as expected
1036 	// document.body must exist before we can do this
1037 	jQuery(function() {
1038 		var div = document.createElement("div");
1039 		div.style.width = div.style.paddingLeft = "1px";
1040 
1041 		document.body.appendChild( div );
1042 		jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2;
1043 
1044 		if ( "zoom" in div.style ) {
1045 			// Check if natively block-level elements act like inline-block
1046 			// elements when setting their display to 'inline' and giving
1047 			// them layout
1048 			// (IE < 8 does this)
1049 			div.style.display = "inline";
1050 			div.style.zoom = 1;
1051 			jQuery.support.inlineBlockNeedsLayout = div.offsetWidth === 2;
1052 
1053 			// Check if elements with layout shrink-wrap their children
1054 			// (IE 6 does this)
1055 			div.style.display = "";
1056 			div.innerHTML = "<div style='width:4px;'></div>";
1057 			jQuery.support.shrinkWrapBlocks = div.offsetWidth !== 2;
1058 		}
1059 
1060 		div.innerHTML = "<table><tr><td style='padding:0;display:none'></td><td>t</td></tr></table>";
1061 		var tds = div.getElementsByTagName("td");
1062 
1063 		// Check if table cells still have offsetWidth/Height when they are set
1064 		// to display:none and there are still other visible table cells in a
1065 		// table row; if so, offsetWidth/Height are not reliable for use when
1066 		// determining if an element has been hidden directly using
1067 		// display:none (it is still safe to use offsets if a parent element is
1068 		// hidden; don safety goggles and see bug #4512 for more information).
1069 		// (only IE 8 fails this test)
1070 		jQuery.support.reliableHiddenOffsets = tds[0].offsetHeight === 0;
1071 
1072 		tds[0].style.display = "";
1073 		tds[1].style.display = "none";
1074 
1075 		// Check if empty table cells still have offsetWidth/Height
1076 		// (IE < 8 fail this test)
1077 		jQuery.support.reliableHiddenOffsets = jQuery.support.reliableHiddenOffsets && tds[0].offsetHeight === 0;
1078 		div.innerHTML = "";
1079 
1080 		document.body.removeChild( div ).style.display = "none";
1081 		div = tds = null;
1082 	});
1083 
1084 	// Technique from Juriy Zaytsev
1085 	// http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
1086 	var eventSupported = function( eventName ) {
1087 		var el = document.createElement("div");
1088 		eventName = "on" + eventName;
1089 
1090 		var isSupported = (eventName in el);
1091 		if ( !isSupported ) {
1092 			el.setAttribute(eventName, "return;");
1093 			isSupported = typeof el[eventName] === "function";
1094 		}
1095 		el = null;
1096 
1097 		return isSupported;
1098 	};
1099 
1100 	jQuery.support.submitBubbles = eventSupported("submit");
1101 	jQuery.support.changeBubbles = eventSupported("change");
1102 
1103 	// release memory in IE
1104 	root = script = div = all = a = null;
1105 })();
1106 
1107 
1108 
1109 var windowData = {},
1110 	rbrace = /^(?:\{.*\}|\[.*\])$/;
1111 
1112 jQuery.extend({
1113 	cache: {},
1114 
1115 	// Please use with caution
1116 	uuid: 0,
1117 
1118 	// Unique for each copy of jQuery on the page	
1119 	expando: "jQuery" + jQuery.now(),
1120 
1121 	// The following elements throw uncatchable exceptions if you
1122 	// attempt to add expando properties to them.
1123 	noData: {
1124 		"embed": true,
1125 		// Ban all objects except for Flash (which handle expandos)
1126 		"object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",
1127 		"applet": true
1128 	},
1129 
1130 	data: function( elem, name, data ) {
1131 		if ( !jQuery.acceptData( elem ) ) {
1132 			return;
1133 		}
1134 
1135 		elem = elem == window ?
1136 			windowData :
1137 			elem;
1138 
1139 		var isNode = elem.nodeType,
1140 			id = isNode ? elem[ jQuery.expando ] : null,
1141 			cache = jQuery.cache, thisCache;
1142 
1143 		if ( isNode && !id && typeof name === "string" && data === undefined ) {
1144 			return;
1145 		}
1146 
1147 		// Get the data from the object directly
1148 		if ( !isNode ) {
1149 			cache = elem;
1150 
1151 		// Compute a unique ID for the element
1152 		} else if ( !id ) {
1153 			elem[ jQuery.expando ] = id = ++jQuery.uuid;
1154 		}
1155 
1156 		// Avoid generating a new cache unless none exists and we
1157 		// want to manipulate it.
1158 		if ( typeof name === "object" ) {
1159 			if ( isNode ) {
1160 				cache[ id ] = jQuery.extend(cache[ id ], name);
1161 
1162 			} else {
1163 				jQuery.extend( cache, name );
1164 			}
1165 
1166 		} else if ( isNode && !cache[ id ] ) {
1167 			cache[ id ] = {};
1168 		}
1169 
1170 		thisCache = isNode ? cache[ id ] : cache;
1171 
1172 		// Prevent overriding the named cache with undefined values
1173 		if ( data !== undefined ) {
1174 			thisCache[ name ] = data;
1175 		}
1176 
1177 		return typeof name === "string" ? thisCache[ name ] : thisCache;
1178 	},
1179 
1180 	removeData: function( elem, name ) {
1181 		if ( !jQuery.acceptData( elem ) ) {
1182 			return;
1183 		}
1184 
1185 		elem = elem == window ?
1186 			windowData :
1187 			elem;
1188 
1189 		var isNode = elem.nodeType,
1190 			id = isNode ? elem[ jQuery.expando ] : elem,
1191 			cache = jQuery.cache,
1192 			thisCache = isNode ? cache[ id ] : id;
1193 
1194 		// If we want to remove a specific section of the element's data
1195 		if ( name ) {
1196 			if ( thisCache ) {
1197 				// Remove the section of cache data
1198 				delete thisCache[ name ];
1199 
1200 				// If we've removed all the data, remove the element's cache
1201 				if ( isNode && jQuery.isEmptyObject(thisCache) ) {
1202 					jQuery.removeData( elem );
1203 				}
1204 			}
1205 
1206 		// Otherwise, we want to remove all of the element's data
1207 		} else {
1208 			if ( isNode && jQuery.support.deleteExpando ) {
1209 				delete elem[ jQuery.expando ];
1210 
1211 			} else if ( elem.removeAttribute ) {
1212 				elem.removeAttribute( jQuery.expando );
1213 
1214 			// Completely remove the data cache
1215 			} else if ( isNode ) {
1216 				delete cache[ id ];
1217 
1218 			// Remove all fields from the object
1219 			} else {
1220 				for ( var n in elem ) {
1221 					delete elem[ n ];
1222 				}
1223 			}
1224 		}
1225 	},
1226 
1227 	// A method for determining if a DOM node can handle the data expando
1228 	acceptData: function( elem ) {
1229 		if ( elem.nodeName ) {
1230 			var match = jQuery.noData[ elem.nodeName.toLowerCase() ];
1231 
1232 			if ( match ) {
1233 				return !(match === true || elem.getAttribute("classid") !== match);
1234 			}
1235 		}
1236 
1237 		return true;
1238 	}
1239 });
1240 
1241 jQuery.fn.extend({
1242 	data: function( key, value ) {
1243 		var data = null;
1244 
1245 		if ( typeof key === "undefined" ) {
1246 			if ( this.length ) {
1247 				var attr = this[0].attributes, name;
1248 				data = jQuery.data( this[0] );
1249 
1250 				for ( var i = 0, l = attr.length; i < l; i++ ) {
1251 					name = attr[i].name;
1252 
1253 					if ( name.indexOf( "data-" ) === 0 ) {
1254 						name = name.substr( 5 );
1255 						dataAttr( this[0], name, data[ name ] );
1256 					}
1257 				}
1258 			}
1259 
1260 			return data;
1261 
1262 		} else if ( typeof key === "object" ) {
1263 			return this.each(function() {
1264 				jQuery.data( this, key );
1265 			});
1266 		}
1267 
1268 		var parts = key.split(".");
1269 		parts[1] = parts[1] ? "." + parts[1] : "";
1270 
1271 		if ( value === undefined ) {
1272 			data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
1273 
1274 			// Try to fetch any internally stored data first
1275 			if ( data === undefined && this.length ) {
1276 				data = jQuery.data( this[0], key );
1277 				data = dataAttr( this[0], key, data );
1278 			}
1279 
1280 			return data === undefined && parts[1] ?
1281 				this.data( parts[0] ) :
1282 				data;
1283 
1284 		} else {
1285 			return this.each(function() {
1286 				var $this = jQuery( this ),
1287 					args = [ parts[0], value ];
1288 
1289 				$this.triggerHandler( "setData" + parts[1] + "!", args );
1290 				jQuery.data( this, key, value );
1291 				$this.triggerHandler( "changeData" + parts[1] + "!", args );
1292 			});
1293 		}
1294 	},
1295 
1296 	removeData: function( key ) {
1297 		return this.each(function() {
1298 			jQuery.removeData( this, key );
1299 		});
1300 	}
1301 });
1302 
1303 function dataAttr( elem, key, data ) {
1304 	// If nothing was found internally, try to fetch any
1305 	// data from the HTML5 data-* attribute
1306 	if ( data === undefined && elem.nodeType === 1 ) {
1307 		data = elem.getAttribute( "data-" + key );
1308 
1309 		if ( typeof data === "string" ) {
1310 			try {
1311 				data = data === "true" ? true :
1312 				data === "false" ? false :
1313 				data === "null" ? null :
1314 				!jQuery.isNaN( data ) ? parseFloat( data ) :
1315 					rbrace.test( data ) ? jQuery.parseJSON( data ) :
1316 					data;
1317 			} catch( e ) {}
1318 
1319 			// Make sure we set the data so it isn't changed later
1320 			jQuery.data( elem, key, data );
1321 
1322 		} else {
1323 			data = undefined;
1324 		}
1325 	}
1326 
1327 	return data;
1328 }
1329 
1330 
1331 
1332 
1333 jQuery.extend({
1334 	queue: function( elem, type, data ) {
1335 		if ( !elem ) {
1336 			return;
1337 		}
1338 
1339 		type = (type || "fx") + "queue";
1340 		var q = jQuery.data( elem, type );
1341 
1342 		// Speed up dequeue by getting out quickly if this is just a lookup
1343 		if ( !data ) {
1344 			return q || [];
1345 		}
1346 
1347 		if ( !q || jQuery.isArray(data) ) {
1348 			q = jQuery.data( elem, type, jQuery.makeArray(data) );
1349 
1350 		} else {
1351 			q.push( data );
1352 		}
1353 
1354 		return q;
1355 	},
1356 
1357 	dequeue: function( elem, type ) {
1358 		type = type || "fx";
1359 
1360 		var queue = jQuery.queue( elem, type ),
1361 			fn = queue.shift();
1362 
1363 		// If the fx queue is dequeued, always remove the progress sentinel
1364 		if ( fn === "inprogress" ) {
1365 			fn = queue.shift();
1366 		}
1367 
1368 		if ( fn ) {
1369 			// Add a progress sentinel to prevent the fx queue from being
1370 			// automatically dequeued
1371 			if ( type === "fx" ) {
1372 				queue.unshift("inprogress");
1373 			}
1374 
1375 			fn.call(elem, function() {
1376 				jQuery.dequeue(elem, type);
1377 			});
1378 		}
1379 	}
1380 });
1381 
1382 jQuery.fn.extend({
1383 	queue: function( type, data ) {
1384 		if ( typeof type !== "string" ) {
1385 			data = type;
1386 			type = "fx";
1387 		}
1388 
1389 		if ( data === undefined ) {
1390 			return jQuery.queue( this[0], type );
1391 		}
1392 		return this.each(function( i ) {
1393 			var queue = jQuery.queue( this, type, data );
1394 
1395 			if ( type === "fx" && queue[0] !== "inprogress" ) {
1396 				jQuery.dequeue( this, type );
1397 			}
1398 		});
1399 	},
1400 	dequeue: function( type ) {
1401 		return this.each(function() {
1402 			jQuery.dequeue( this, type );
1403 		});
1404 	},
1405 
1406 	// Based off of the plugin by Clint Helfers, with permission.
1407 	// http://blindsignals.com/index.php/2009/07/jquery-delay/
1408 	delay: function( time, type ) {
1409 		time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
1410 		type = type || "fx";
1411 
1412 		return this.queue( type, function() {
1413 			var elem = this;
1414 			setTimeout(function() {
1415 				jQuery.dequeue( elem, type );
1416 			}, time );
1417 		});
1418 	},
1419 
1420 	clearQueue: function( type ) {
1421 		return this.queue( type || "fx", [] );
1422 	}
1423 });
1424 
1425 
1426 
1427 
1428 var rclass = /[\n\t]/g,
1429 	rspaces = /\s+/,
1430 	rreturn = /\r/g,
1431 	rspecialurl = /^(?:href|src|style)$/,
1432 	rtype = /^(?:button|input)$/i,
1433 	rfocusable = /^(?:button|input|object|select|textarea)$/i,
1434 	rclickable = /^a(?:rea)?$/i,
1435 	rradiocheck = /^(?:radio|checkbox)$/i;
1436 
1437 jQuery.props = {
1438 	"for": "htmlFor",
1439 	"class": "className",
1440 	readonly: "readOnly",
1441 	maxlength: "maxLength",
1442 	cellspacing: "cellSpacing",
1443 	rowspan: "rowSpan",
1444 	colspan: "colSpan",
1445 	tabindex: "tabIndex",
1446 	usemap: "useMap",
1447 	frameborder: "frameBorder"
1448 };
1449 
1450 jQuery.fn.extend({
1451 	attr: function( name, value ) {
1452 		return jQuery.access( this, name, value, true, jQuery.attr );
1453 	},
1454 
1455 	removeAttr: function( name, fn ) {
1456 		return this.each(function(){
1457 			jQuery.attr( this, name, "" );
1458 			if ( this.nodeType === 1 ) {
1459 				this.removeAttribute( name );
1460 			}
1461 		});
1462 	},
1463 
1464 	addClass: function( value ) {
1465 		if ( jQuery.isFunction(value) ) {
1466 			return this.each(function(i) {
1467 				var self = jQuery(this);
1468 				self.addClass( value.call(this, i, self.attr("class")) );
1469 			});
1470 		}
1471 
1472 		if ( value && typeof value === "string" ) {
1473 			var classNames = (value || "").split( rspaces );
1474 
1475 			for ( var i = 0, l = this.length; i < l; i++ ) {
1476 				var elem = this[i];
1477 
1478 				if ( elem.nodeType === 1 ) {
1479 					if ( !elem.className ) {
1480 						elem.className = value;
1481 
1482 					} else {
1483 						var className = " " + elem.className + " ",
1484 							setClass = elem.className;
1485 
1486 						for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
1487 							if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) {
1488 								setClass += " " + classNames[c];
1489 							}
1490 						}
1491 						elem.className = jQuery.trim( setClass );
1492 					}
1493 				}
1494 			}
1495 		}
1496 
1497 		return this;
1498 	},
1499 
1500 	removeClass: function( value ) {
1501 		if ( jQuery.isFunction(value) ) {
1502 			return this.each(function(i) {
1503 				var self = jQuery(this);
1504 				self.removeClass( value.call(this, i, self.attr("class")) );
1505 			});
1506 		}
1507 
1508 		if ( (value && typeof value === "string") || value === undefined ) {
1509 			var classNames = (value || "").split( rspaces );
1510 
1511 			for ( var i = 0, l = this.length; i < l; i++ ) {
1512 				var elem = this[i];
1513 
1514 				if ( elem.nodeType === 1 && elem.className ) {
1515 					if ( value ) {
1516 						var className = (" " + elem.className + " ").replace(rclass, " ");
1517 						for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
1518 							className = className.replace(" " + classNames[c] + " ", " ");
1519 						}
1520 						elem.className = jQuery.trim( className );
1521 
1522 					} else {
1523 						elem.className = "";
1524 					}
1525 				}
1526 			}
1527 		}
1528 
1529 		return this;
1530 	},
1531 
1532 	toggleClass: function( value, stateVal ) {
1533 		var type = typeof value,
1534 			isBool = typeof stateVal === "boolean";
1535 
1536 		if ( jQuery.isFunction( value ) ) {
1537 			return this.each(function(i) {
1538 				var self = jQuery(this);
1539 				self.toggleClass( value.call(this, i, self.attr("class"), stateVal), stateVal );
1540 			});
1541 		}
1542 
1543 		return this.each(function() {
1544 			if ( type === "string" ) {
1545 				// toggle individual class names
1546 				var className,
1547 					i = 0,
1548 					self = jQuery( this ),
1549 					state = stateVal,
1550 					classNames = value.split( rspaces );
1551 
1552 				while ( (className = classNames[ i++ ]) ) {
1553 					// check each className given, space seperated list
1554 					state = isBool ? state : !self.hasClass( className );
1555 					self[ state ? "addClass" : "removeClass" ]( className );
1556 				}
1557 
1558 			} else if ( type === "undefined" || type === "boolean" ) {
1559 				if ( this.className ) {
1560 					// store className if set
1561 					jQuery.data( this, "__className__", this.className );
1562 				}
1563 
1564 				// toggle whole className
1565 				this.className = this.className || value === false ? "" : jQuery.data( this, "__className__" ) || "";
1566 			}
1567 		});
1568 	},
1569 
1570 	hasClass: function( selector ) {
1571 		var className = " " + selector + " ";
1572 		for ( var i = 0, l = this.length; i < l; i++ ) {
1573 			if ( (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {
1574 				return true;
1575 			}
1576 		}
1577 
1578 		return false;
1579 	},
1580 
1581 	val: function( value ) {
1582 		if ( !arguments.length ) {
1583 			var elem = this[0];
1584 
1585 			if ( elem ) {
1586 				if ( jQuery.nodeName( elem, "option" ) ) {
1587 					// attributes.value is undefined in Blackberry 4.7 but
1588 					// uses .value. See #6932
1589 					var val = elem.attributes.value;
1590 					return !val || val.specified ? elem.value : elem.text;
1591 				}
1592 
1593 				// We need to handle select boxes special
1594 				if ( jQuery.nodeName( elem, "select" ) ) {
1595 					var index = elem.selectedIndex,
1596 						values = [],
1597 						options = elem.options,
1598 						one = elem.type === "select-one";
1599 
1600 					// Nothing was selected
1601 					if ( index < 0 ) {
1602 						return null;
1603 					}
1604 
1605 					// Loop through all the selected options
1606 					for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
1607 						var option = options[ i ];
1608 
1609 						// Don't return options that are disabled or in a disabled optgroup
1610 						if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) && 
1611 								(!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) {
1612 
1613 							// Get the specific value for the option
1614 							value = jQuery(option).val();
1615 
1616 							// We don't need an array for one selects
1617 							if ( one ) {
1618 								return value;
1619 							}
1620 
1621 							// Multi-Selects return an array
1622 							values.push( value );
1623 						}
1624 					}
1625 
1626 					return values;
1627 				}
1628 
1629 				// Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
1630 				if ( rradiocheck.test( elem.type ) && !jQuery.support.checkOn ) {
1631 					return elem.getAttribute("value") === null ? "on" : elem.value;
1632 				}
1633 				
1634 
1635 				// Everything else, we just grab the value
1636 				return (elem.value || "").replace(rreturn, "");
1637 
1638 			}
1639 
1640 			return undefined;
1641 		}
1642 
1643 		var isFunction = jQuery.isFunction(value);
1644 
1645 		return this.each(function(i) {
1646 			var self = jQuery(this), val = value;
1647 
1648 			if ( this.nodeType !== 1 ) {
1649 				return;
1650 			}
1651 
1652 			if ( isFunction ) {
1653 				val = value.call(this, i, self.val());
1654 			}
1655 
1656 			// Treat null/undefined as ""; convert numbers to string
1657 			if ( val == null ) {
1658 				val = "";
1659 			} else if ( typeof val === "number" ) {
1660 				val += "";
1661 			} else if ( jQuery.isArray(val) ) {
1662 				val = jQuery.map(val, function (value) {
1663 					return value == null ? "" : value + "";
1664 				});
1665 			}
1666 
1667 			if ( jQuery.isArray(val) && rradiocheck.test( this.type ) ) {
1668 				this.checked = jQuery.inArray( self.val(), val ) >= 0;
1669 
1670 			} else if ( jQuery.nodeName( this, "select" ) ) {
1671 				var values = jQuery.makeArray(val);
1672 
1673 				jQuery( "option", this ).each(function() {
1674 					this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
1675 				});
1676 
1677 				if ( !values.length ) {
1678 					this.selectedIndex = -1;
1679 				}
1680 
1681 			} else {
1682 				this.value = val;
1683 			}
1684 		});
1685 	}
1686 });
1687 
1688 jQuery.extend({
1689 	attrFn: {
1690 		val: true,
1691 		css: true,
1692 		html: true,
1693 		text: true,
1694 		data: true,
1695 		width: true,
1696 		height: true,
1697 		offset: true
1698 	},
1699 		
1700 	attr: function( elem, name, value, pass ) {
1701 		// don't set attributes on text and comment nodes
1702 		if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
1703 			return undefined;
1704 		}
1705 
1706 		if ( pass && name in jQuery.attrFn ) {
1707 			return jQuery(elem)[name](value);
1708 		}
1709 
1710 		var notxml = elem.nodeType !== 1 || !jQuery.isXMLDoc( elem ),
1711 			// Whether we are setting (or getting)
1712 			set = value !== undefined;
1713 
1714 		// Try to normalize/fix the name
1715 		name = notxml && jQuery.props[ name ] || name;
1716 
1717 		// These attributes require special treatment
1718 		var special = rspecialurl.test( name );
1719 
1720 		// Safari mis-reports the default selected property of an option
1721 		// Accessing the parent's selectedIndex property fixes it
1722 		if ( name === "selected" && !jQuery.support.optSelected ) {
1723 			var parent = elem.parentNode;
1724 			if ( parent ) {
1725 				parent.selectedIndex;
1726 
1727 				// Make sure that it also works with optgroups, see #5701
1728 				if ( parent.parentNode ) {
1729 					parent.parentNode.selectedIndex;
1730 				}
1731 			}
1732 		}
1733 
1734 		// If applicable, access the attribute via the DOM 0 way
1735 		// 'in' checks fail in Blackberry 4.7 #6931
1736 		if ( (name in elem || elem[ name ] !== undefined) && notxml && !special ) {
1737 			if ( set ) {
1738 				// We can't allow the type property to be changed (since it causes problems in IE)
1739 				if ( name === "type" && rtype.test( elem.nodeName ) && elem.parentNode ) {
1740 					jQuery.error( "type property can't be changed" );
1741 				}
1742 
1743 				if ( value === null ) {
1744 					if ( elem.nodeType === 1 ) {
1745 						elem.removeAttribute( name );
1746 					}
1747 
1748 				} else {
1749 					elem[ name ] = value;
1750 				}
1751 			}
1752 
1753 			// browsers index elements by id/name on forms, give priority to attributes.
1754 			if ( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) ) {
1755 				return elem.getAttributeNode( name ).nodeValue;
1756 			}
1757 
1758 			// elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
1759 			// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
1760 			if ( name === "tabIndex" ) {
1761 				var attributeNode = elem.getAttributeNode( "tabIndex" );
1762 
1763 				return attributeNode && attributeNode.specified ?
1764 					attributeNode.value :
1765 					rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
1766 						0 :
1767 						undefined;
1768 			}
1769 
1770 			return elem[ name ];
1771 		}
1772 
1773 		if ( !jQuery.support.style && notxml && name === "style" ) {
1774 			if ( set ) {
1775 				elem.style.cssText = "" + value;
1776 			}
1777 
1778 			return elem.style.cssText;
1779 		}
1780 
1781 		if ( set ) {
1782 			// convert the value to a string (all browsers do this but IE) see #1070
1783 			elem.setAttribute( name, "" + value );
1784 		}
1785 
1786 		// Ensure that missing attributes return undefined
1787 		// Blackberry 4.7 returns "" from getAttribute #6938
1788 		if ( !elem.attributes[ name ] && (elem.hasAttribute && !elem.hasAttribute( name )) ) {
1789 			return undefined;
1790 		}
1791 
1792 		var attr = !jQuery.support.hrefNormalized && notxml && special ?
1793 				// Some attributes require a special call on IE
1794 				elem.getAttribute( name, 2 ) :
1795 				elem.getAttribute( name );
1796 
1797 		// Non-existent attributes return null, we normalize to undefined
1798 		return attr === null ? undefined : attr;
1799 	}
1800 });
1801 
1802 
1803 
1804 
1805 var rnamespaces = /\.(.*)$/,
1806 	rformElems = /^(?:textarea|input|select)$/i,
1807 	rperiod = /\./g,
1808 	rspace = / /g,
1809 	rescape = /[^\w\s.|`]/g,
1810 	fcleanup = function( nm ) {
1811 		return nm.replace(rescape, "\\$&");
1812 	},
1813 	focusCounts = { focusin: 0, focusout: 0 };
1814 
1815 /*
1816  * A number of helper functions used for managing events.
1817  * Many of the ideas behind this code originated 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 
1829 		// For whatever reason, IE has trouble passing the window object
1830 		// around, causing it to be cloned in the process
1831 		if ( jQuery.isWindow( elem ) && ( elem !== window && !elem.frameElement ) ) {
1832 			elem = window;
1833 		}
1834 
1835 		if ( handler === false ) {
1836 			handler = returnFalse;
1837 		} else if ( !handler ) {
1838 			// Fixes bug #7229. Fix recommended by jdalton
1839 		  return;
1840 		}
1841 
1842 		var handleObjIn, handleObj;
1843 
1844 		if ( handler.handler ) {
1845 			handleObjIn = handler;
1846 			handler = handleObjIn.handler;
1847 		}
1848 
1849 		// Make sure that the function being executed has a unique ID
1850 		if ( !handler.guid ) {
1851 			handler.guid = jQuery.guid++;
1852 		}
1853 
1854 		// Init the element's event structure
1855 		var elemData = jQuery.data( elem );
1856 
1857 		// If no elemData is found then we must be trying to bind to one of the
1858 		// banned noData elements
1859 		if ( !elemData ) {
1860 			return;
1861 		}
1862 
1863 		// Use a key less likely to result in collisions for plain JS objects.
1864 		// Fixes bug #7150.
1865 		var eventKey = elem.nodeType ? "events" : "__events__",
1866 			events = elemData[ eventKey ],
1867 			eventHandle = elemData.handle;
1868 			
1869 		if ( typeof events === "function" ) {
1870 			// On plain objects events is a fn that holds the the data
1871 			// which prevents this data from being JSON serialized
1872 			// the function does not need to be called, it just contains the data
1873 			eventHandle = events.handle;
1874 			events = events.events;
1875 
1876 		} else if ( !events ) {
1877 			if ( !elem.nodeType ) {
1878 				// On plain objects, create a fn that acts as the holder
1879 				// of the values to avoid JSON serialization of event data
1880 				elemData[ eventKey ] = elemData = function(){};
1881 			}
1882 
1883 			elemData.events = events = {};
1884 		}
1885 
1886 		if ( !eventHandle ) {
1887 			elemData.handle = eventHandle = function() {
1888 				// Handle the second event of a trigger and when
1889 				// an event is called after a page has unloaded
1890 				return typeof jQuery !== "undefined" && !jQuery.event.triggered ?
1891 					jQuery.event.handle.apply( eventHandle.elem, arguments ) :
1892 					undefined;
1893 			};
1894 		}
1895 
1896 		// Add elem as a property of the handle function
1897 		// This is to prevent a memory leak with non-native events in IE.
1898 		eventHandle.elem = elem;
1899 
1900 		// Handle multiple events separated by a space
1901 		// jQuery(...).bind("mouseover mouseout", fn);
1902 		types = types.split(" ");
1903 
1904 		var type, i = 0, namespaces;
1905 
1906 		while ( (type = types[ i++ ]) ) {
1907 			handleObj = handleObjIn ?
1908 				jQuery.extend({}, handleObjIn) :
1909 				{ handler: handler, data: data };
1910 
1911 			// Namespaced event handlers
1912 			if ( type.indexOf(".") > -1 ) {
1913 				namespaces = type.split(".");
1914 				type = namespaces.shift();
1915 				handleObj.namespace = namespaces.slice(0).sort().join(".");
1916 
1917 			} else {
1918 				namespaces = [];
1919 				handleObj.namespace = "";
1920 			}
1921 
1922 			handleObj.type = type;
1923 			if ( !handleObj.guid ) {
1924 				handleObj.guid = handler.guid;
1925 			}
1926 
1927 			// Get the current list of functions bound to this event
1928 			var handlers = events[ type ],
1929 				special = jQuery.event.special[ type ] || {};
1930 
1931 			// Init the event handler queue
1932 			if ( !handlers ) {
1933 				handlers = events[ type ] = [];
1934 
1935 				// Check for a special event handler
1936 				// Only use addEventListener/attachEvent if the special
1937 				// events handler returns false
1938 				if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
1939 					// Bind the global event handler to the element
1940 					if ( elem.addEventListener ) {
1941 						elem.addEventListener( type, eventHandle, false );
1942 
1943 					} else if ( elem.attachEvent ) {
1944 						elem.attachEvent( "on" + type, eventHandle );
1945 					}
1946 				}
1947 			}
1948 			
1949 			if ( special.add ) { 
1950 				special.add.call( elem, handleObj ); 
1951 
1952 				if ( !handleObj.handler.guid ) {
1953 					handleObj.handler.guid = handler.guid;
1954 				}
1955 			}
1956 
1957 			// Add the function to the element's handler list
1958 			handlers.push( handleObj );
1959 
1960 			// Keep track of which events have been used, for global triggering
1961 			jQuery.event.global[ type ] = true;
1962 		}
1963 
1964 		// Nullify elem to prevent memory leaks in IE
1965 		elem = null;
1966 	},
1967 
1968 	global: {},
1969 
1970 	// Detach an event or set of events from an element
1971 	remove: function( elem, types, handler, pos ) {
1972 		// don't do events on text and comment nodes
1973 		if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
1974 			return;
1975 		}
1976 
1977 		if ( handler === false ) {
1978 			handler = returnFalse;
1979 		}
1980 
1981 		var ret, type, fn, j, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType,
1982 			eventKey = elem.nodeType ? "events" : "__events__",
1983 			elemData = jQuery.data( elem ),
1984 			events = elemData && elemData[ eventKey ];
1985 
1986 		if ( !elemData || !events ) {
1987 			return;
1988 		}
1989 		
1990 		if ( typeof events === "function" ) {
1991 			elemData = events;
1992 			events = events.events;
1993 		}
1994 
1995 		// types is actually an event object here
1996 		if ( types && types.type ) {
1997 			handler = types.handler;
1998 			types = types.type;
1999 		}
2000 
2001 		// Unbind all events for the element
2002 		if ( !types || typeof types === "string" && types.charAt(0) === "." ) {
2003 			types = types || "";
2004 
2005 			for ( type in events ) {
2006 				jQuery.event.remove( elem, type + types );
2007 			}
2008 
2009 			return;
2010 		}
2011 
2012 		// Handle multiple events separated by a space
2013 		// jQuery(...).unbind("mouseover mouseout", fn);
2014 		types = types.split(" ");
2015 
2016 		while ( (type = types[ i++ ]) ) {
2017 			origType = type;
2018 			handleObj = null;
2019 			all = type.indexOf(".") < 0;
2020 			namespaces = [];
2021 
2022 			if ( !all ) {
2023 				// Namespaced event handlers
2024 				namespaces = type.split(".");
2025 				type = namespaces.shift();
2026 
2027 				namespace = new RegExp("(^|\\.)" + 
2028 					jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)");
2029 			}
2030 
2031 			eventType = events[ type ];
2032 
2033 			if ( !eventType ) {
2034 				continue;
2035 			}
2036 
2037 			if ( !handler ) {
2038 				for ( j = 0; j < eventType.length; j++ ) {
2039 					handleObj = eventType[ j ];
2040 
2041 					if ( all || namespace.test( handleObj.namespace ) ) {
2042 						jQuery.event.remove( elem, origType, handleObj.handler, j );
2043 						eventType.splice( j--, 1 );
2044 					}
2045 				}
2046 
2047 				continue;
2048 			}
2049 
2050 			special = jQuery.event.special[ type ] || {};
2051 
2052 			for ( j = pos || 0; j < eventType.length; j++ ) {
2053 				handleObj = eventType[ j ];
2054 
2055 				if ( handler.guid === handleObj.guid ) {
2056 					// remove the given handler for the given type
2057 					if ( all || namespace.test( handleObj.namespace ) ) {
2058 						if ( pos == null ) {
2059 							eventType.splice( j--, 1 );
2060 						}
2061 
2062 						if ( special.remove ) {
2063 							special.remove.call( elem, handleObj );
2064 						}
2065 					}
2066 
2067 					if ( pos != null ) {
2068 						break;
2069 					}
2070 				}
2071 			}
2072 
2073 			// remove generic event handler if no more handlers exist
2074 			if ( eventType.length === 0 || pos != null && eventType.length === 1 ) {
2075 				if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
2076 					jQuery.removeEvent( elem, type, elemData.handle );
2077 				}
2078 
2079 				ret = null;
2080 				delete events[ type ];
2081 			}
2082 		}
2083 
2084 		// Remove the expando if it's no longer used
2085 		if ( jQuery.isEmptyObject( events ) ) {
2086 			var handle = elemData.handle;
2087 			if ( handle ) {
2088 				handle.elem = null;
2089 			}
2090 
2091 			delete elemData.events;
2092 			delete elemData.handle;
2093 
2094 			if ( typeof elemData === "function" ) {
2095 				jQuery.removeData( elem, eventKey );
2096 
2097 			} else if ( jQuery.isEmptyObject( elemData ) ) {
2098 				jQuery.removeData( elem );
2099 			}
2100 		}
2101 	},
2102 
2103 	// bubbling is internal
2104 	trigger: function( event, data, elem /*, bubbling */ ) {
2105 		// Event object or event type
2106 		var type = event.type || event,
2107 			bubbling = arguments[3];
2108 
2109 		if ( !bubbling ) {
2110 			event = typeof event === "object" ?
2111 				// jQuery.Event object
2112 				event[ jQuery.expando ] ? event :
2113 				// Object literal
2114 				jQuery.extend( jQuery.Event(type), event ) :
2115 				// Just the event type (string)
2116 				jQuery.Event(type);
2117 
2118 			if ( type.indexOf("!") >= 0 ) {
2119 				event.type = type = type.slice(0, -1);
2120 				event.exclusive = true;
2121 			}
2122 
2123 			// Handle a global trigger
2124 			if ( !elem ) {
2125 				// Don't bubble custom events when global (to avoid too much overhead)
2126 				event.stopPropagation();
2127 
2128 				// Only trigger if we've ever bound an event for it
2129 				if ( jQuery.event.global[ type ] ) {
2130 					jQuery.each( jQuery.cache, function() {
2131 						if ( this.events && this.events[type] ) {
2132 							jQuery.event.trigger( event, data, this.handle.elem );
2133 						}
2134 					});
2135 				}
2136 			}
2137 
2138 			// Handle triggering a single element
2139 
2140 			// don't do events on text and comment nodes
2141 			if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
2142 				return undefined;
2143 			}
2144 
2145 			// Clean up in case it is reused
2146 			event.result = undefined;
2147 			event.target = elem;
2148 
2149 			// Clone the incoming data, if any
2150 			data = jQuery.makeArray( data );
2151 			data.unshift( event );
2152 		}
2153 
2154 		event.currentTarget = elem;
2155 
2156 		// Trigger the event, it is assumed that "handle" is a function
2157 		var handle = elem.nodeType ?
2158 			jQuery.data( elem, "handle" ) :
2159 			(jQuery.data( elem, "__events__" ) || {}).handle;
2160 
2161 		if ( handle ) {
2162 			handle.apply( elem, data );
2163 		}
2164 
2165 		var parent = elem.parentNode || elem.ownerDocument;
2166 
2167 		// Trigger an inline bound script
2168 		try {
2169 			if ( !(elem && elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()]) ) {
2170 				if ( elem[ "on" + type ] && elem[ "on" + type ].apply( elem, data ) === false ) {
2171 					event.result = false;
2172 					event.preventDefault();
2173 				}
2174 			}
2175 
2176 		// prevent IE from throwing an error for some elements with some event types, see #3533
2177 		} catch (inlineError) {}
2178 
2179 		if ( !event.isPropagationStopped() && parent ) {
2180 			jQuery.event.trigger( event, data, parent, true );
2181 
2182 		} else if ( !event.isDefaultPrevented() ) {
2183 			var old,
2184 				target = event.target,
2185 				targetType = type.replace( rnamespaces, "" ),
2186 				isClick = jQuery.nodeName( target, "a" ) && targetType === "click",
2187 				special = jQuery.event.special[ targetType ] || {};
2188 
2189 			if ( (!special._default || special._default.call( elem, event ) === false) && 
2190 				!isClick && !(target && target.nodeName && jQuery.noData[target.nodeName.toLowerCase()]) ) {
2191 
2192 				try {
2193 					if ( target[ targetType ] ) {
2194 						// Make sure that we don't accidentally re-trigger the onFOO events
2195 						old = target[ "on" + targetType ];
2196 
2197 						if ( old ) {
2198 							target[ "on" + targetType ] = null;
2199 						}
2200 
2201 						jQuery.event.triggered = true;
2202 						target[ targetType ]();
2203 					}
2204 
2205 				// prevent IE from throwing an error for some elements with some event types, see #3533
2206 				} catch (triggerError) {}
2207 
2208 				if ( old ) {
2209 					target[ "on" + targetType ] = old;
2210 				}
2211 
2212 				jQuery.event.triggered = false;
2213 			}
2214 		}
2215 	},
2216 
2217 	handle: function( event ) {
2218 		var all, handlers, namespaces, namespace_re, events,
2219 			namespace_sort = [],
2220 			args = jQuery.makeArray( arguments );
2221 
2222 		event = args[0] = jQuery.event.fix( event || window.event );
2223 		event.currentTarget = this;
2224 
2225 		// Namespaced event handlers
2226 		all = event.type.indexOf(".") < 0 && !event.exclusive;
2227 
2228 		if ( !all ) {
2229 			namespaces = event.type.split(".");
2230 			event.type = namespaces.shift();
2231 			namespace_sort = namespaces.slice(0).sort();
2232 			namespace_re = new RegExp("(^|\\.)" + namespace_sort.join("\\.(?:.*\\.)?") + "(\\.|$)");
2233 		}
2234 
2235 		event.namespace = event.namespace || namespace_sort.join(".");
2236 
2237 		events = jQuery.data(this, this.nodeType ? "events" : "__events__");
2238 
2239 		if ( typeof events === "function" ) {
2240 			events = events.events;
2241 		}
2242 
2243 		handlers = (events || {})[ event.type ];
2244 
2245 		if ( events && handlers ) {
2246 			// Clone the handlers to prevent manipulation
2247 			handlers = handlers.slice(0);
2248 
2249 			for ( var j = 0, l = handlers.length; j < l; j++ ) {
2250 				var handleObj = handlers[ j ];
2251 
2252 				// Filter the functions by class
2253 				if ( all || namespace_re.test( handleObj.namespace ) ) {
2254 					// Pass in a reference to the handler function itself
2255 					// So that we can later remove it
2256 					event.handler = handleObj.handler;
2257 					event.data = handleObj.data;
2258 					event.handleObj = handleObj;
2259 	
2260 					var ret = handleObj.handler.apply( this, args );
2261 
2262 					if ( ret !== undefined ) {
2263 						event.result = ret;
2264 						if ( ret === false ) {
2265 							event.preventDefault();
2266 							event.stopPropagation();
2267 						}
2268 					}
2269 
2270 					if ( event.isImmediatePropagationStopped() ) {
2271 						break;
2272 					}
2273 				}
2274 			}
2275 		}
2276 
2277 		return event.result;
2278 	},
2279 
2280 	props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
2281 
2282 	fix: function( event ) {
2283 		if ( event[ jQuery.expando ] ) {
2284 			return event;
2285 		}
2286 
2287 		// store a copy of the original event object
2288 		// and "clone" to set read-only properties
2289 		var originalEvent = event;
2290 		event = jQuery.Event( originalEvent );
2291 
2292 		for ( var i = this.props.length, prop; i; ) {
2293 			prop = this.props[ --i ];
2294 			event[ prop ] = originalEvent[ prop ];
2295 		}
2296 
2297 		// Fix target property, if necessary
2298 		if ( !event.target ) {
2299 			// Fixes #1925 where srcElement might not be defined either
2300 			event.target = event.srcElement || document;
2301 		}
2302 
2303 		// check if target is a textnode (safari)
2304 		if ( event.target.nodeType === 3 ) {
2305 			event.target = event.target.parentNode;
2306 		}
2307 
2308 		// Add relatedTarget, if necessary
2309 		if ( !event.relatedTarget && event.fromElement ) {
2310 			event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
2311 		}
2312 
2313 		// Calculate pageX/Y if missing and clientX/Y available
2314 		if ( event.pageX == null && event.clientX != null ) {
2315 			var doc = document.documentElement,
2316 				body = document.body;
2317 
2318 			event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
2319 			event.pageY = event.clientY + (doc && doc.scrollTop  || body && body.scrollTop  || 0) - (doc && doc.clientTop  || body && body.clientTop  || 0);
2320 		}
2321 
2322 		// Add which for key events
2323 		if ( event.which == null && (event.charCode != null || event.keyCode != null) ) {
2324 			event.which = event.charCode != null ? event.charCode : event.keyCode;
2325 		}
2326 
2327 		// Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
2328 		if ( !event.metaKey && event.ctrlKey ) {
2329 			event.metaKey = event.ctrlKey;
2330 		}
2331 
2332 		// Add which for click: 1 === left; 2 === middle; 3 === right
2333 		// Note: button is not normalized, so don't use it
2334 		if ( !event.which && event.button !== undefined ) {
2335 			event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
2336 		}
2337 
2338 		return event;
2339 	},
2340 
2341 	// Deprecated, use jQuery.guid instead
2342 	guid: 1E8,
2343 
2344 	// Deprecated, use jQuery.proxy instead
2345 	proxy: jQuery.proxy,
2346 
2347 	special: {
2348 		ready: {
2349 			// Make sure the ready event is setup
2350 			setup: jQuery.bindReady,
2351 			teardown: jQuery.noop
2352 		},
2353 
2354 		live: {
2355 			add: function( handleObj ) {
2356 				jQuery.event.add( this,
2357 					liveConvert( handleObj.origType, handleObj.selector ),
2358 					jQuery.extend({}, handleObj, {handler: liveHandler, guid: handleObj.handler.guid}) ); 
2359 			},
2360 
2361 			remove: function( handleObj ) {
2362 				jQuery.event.remove( this, liveConvert( handleObj.origType, handleObj.selector ), handleObj );
2363 			}
2364 		},
2365 
2366 		beforeunload: {
2367 			setup: function( data, namespaces, eventHandle ) {
2368 				// We only want to do this special case on windows
2369 				if ( jQuery.isWindow( this ) ) {
2370 					this.onbeforeunload = eventHandle;
2371 				}
2372 			},
2373 
2374 			teardown: function( namespaces, eventHandle ) {
2375 				if ( this.onbeforeunload === eventHandle ) {
2376 					this.onbeforeunload = null;
2377 				}
2378 			}
2379 		}
2380 	}
2381 };
2382 
2383 jQuery.removeEvent = document.removeEventListener ?
2384 	function( elem, type, handle ) {
2385 		if ( elem.removeEventListener ) {
2386 			elem.removeEventListener( type, handle, false );
2387 		}
2388 	} : 
2389 	function( elem, type, handle ) {
2390 		if ( elem.detachEvent ) {
2391 			elem.detachEvent( "on" + type, handle );
2392 		}
2393 	};
2394 
2395 jQuery.Event = function( src ) {
2396 	// Allow instantiation without the 'new' keyword
2397 	if ( !this.preventDefault ) {
2398 		return new jQuery.Event( src );
2399 	}
2400 
2401 	// Event object
2402 	if ( src && src.type ) {
2403 		this.originalEvent = src;
2404 		this.type = src.type;
2405 	// Event type
2406 	} else {
2407 		this.type = src;
2408 	}
2409 
2410 	// timeStamp is buggy for some events on Firefox(#3843)
2411 	// So we won't rely on the native value
2412 	this.timeStamp = jQuery.now();
2413 
2414 	// Mark it as fixed
2415 	this[ jQuery.expando ] = true;
2416 };
2417 
2418 function returnFalse() {
2419 	return false;
2420 }
2421 function returnTrue() {
2422 	return true;
2423 }
2424 
2425 // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
2426 // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
2427 jQuery.Event.prototype = {
2428 	preventDefault: function() {
2429 		this.isDefaultPrevented = returnTrue;
2430 
2431 		var e = this.originalEvent;
2432 		if ( !e ) {
2433 			return;
2434 		}
2435 		
2436 		// if preventDefault exists run it on the original event
2437 		if ( e.preventDefault ) {
2438 			e.preventDefault();
2439 
2440 		// otherwise set the returnValue property of the original event to false (IE)
2441 		} else {
2442 			e.returnValue = false;
2443 		}
2444 	},
2445 	stopPropagation: function() {
2446 		this.isPropagationStopped = returnTrue;
2447 
2448 		var e = this.originalEvent;
2449 		if ( !e ) {
2450 			return;
2451 		}
2452 		// if stopPropagation exists run it on the original event
2453 		if ( e.stopPropagation ) {
2454 			e.stopPropagation();
2455 		}
2456 		// otherwise set the cancelBubble property of the original event to true (IE)
2457 		e.cancelBubble = true;
2458 	},
2459 	stopImmediatePropagation: function() {
2460 		this.isImmediatePropagationStopped = returnTrue;
2461 		this.stopPropagation();
2462 	},
2463 	isDefaultPrevented: returnFalse,
2464 	isPropagationStopped: returnFalse,
2465 	isImmediatePropagationStopped: returnFalse
2466 };
2467 
2468 // Checks if an event happened on an element within another element
2469 // Used in jQuery.event.special.mouseenter and mouseleave handlers
2470 var withinElement = function( event ) {
2471 	// Check if mouse(over|out) are still within the same parent element
2472 	var parent = event.relatedTarget;
2473 
2474 	// Firefox sometimes assigns relatedTarget a XUL element
2475 	// which we cannot access the parentNode property of
2476 	try {
2477 		// Traverse up the tree
2478 		while ( parent && parent !== this ) {
2479 			parent = parent.parentNode;
2480 		}
2481 
2482 		if ( parent !== this ) {
2483 			// set the correct event type
2484 			event.type = event.data;
2485 
2486 			// handle event if we actually just moused on to a non sub-element
2487 			jQuery.event.handle.apply( this, arguments );
2488 		}
2489 
2490 	// assuming we've left the element since we most likely mousedover a xul element
2491 	} catch(e) { }
2492 },
2493 
2494 // In case of event delegation, we only need to rename the event.type,
2495 // liveHandler will take care of the rest.
2496 delegate = function( event ) {
2497 	event.type = event.data;
2498 	jQuery.event.handle.apply( this, arguments );
2499 };
2500 
2501 // Create mouseenter and mouseleave events
2502 jQuery.each({
2503 	mouseenter: "mouseover",
2504 	mouseleave: "mouseout"
2505 }, function( orig, fix ) {
2506 	jQuery.event.special[ orig ] = {
2507 		setup: function( data ) {
2508 			jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig );
2509 		},
2510 		teardown: function( data ) {
2511 			jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement );
2512 		}
2513 	};
2514 });
2515 
2516 // submit delegation
2517 if ( !jQuery.support.submitBubbles ) {
2518 
2519 	jQuery.event.special.submit = {
2520 		setup: function( data, namespaces ) {
2521 			if ( this.nodeName.toLowerCase() !== "form" ) {
2522 				jQuery.event.add(this, "click.specialSubmit", function( e ) {
2523 					var elem = e.target,
2524 						type = elem.type;
2525 
2526 					if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) {
2527 						e.liveFired = undefined;
2528 						return trigger( "submit", this, arguments );
2529 					}
2530 				});
2531 	 
2532 				jQuery.event.add(this, "keypress.specialSubmit", function( e ) {
2533 					var elem = e.target,
2534 						type = elem.type;
2535 
2536 					if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) {
2537 						e.liveFired = undefined;
2538 						return trigger( "submit", this, arguments );
2539 					}
2540 				});
2541 
2542 			} else {
2543 				return false;
2544 			}
2545 		},
2546 
2547 		teardown: function( namespaces ) {
2548 			jQuery.event.remove( this, ".specialSubmit" );
2549 		}
2550 	};
2551 
2552 }
2553 
2554 // change delegation, happens here so we have bind.
2555 if ( !jQuery.support.changeBubbles ) {
2556 
2557 	var changeFilters,
2558 
2559 	getVal = function( elem ) {
2560 		var type = elem.type, val = elem.value;
2561 
2562 		if ( type === "radio" || type === "checkbox" ) {
2563 			val = elem.checked;
2564 
2565 		} else if ( type === "select-multiple" ) {
2566 			val = elem.selectedIndex > -1 ?
2567 				jQuery.map( elem.options, function( elem ) {
2568 					return elem.selected;
2569 				}).join("-") :
2570 				"";
2571 
2572 		} else if ( elem.nodeName.toLowerCase() === "select" ) {
2573 			val = elem.selectedIndex;
2574 		}
2575 
2576 		return val;
2577 	},
2578 
2579 	testChange = function testChange( e ) {
2580 		var elem = e.target, data, val;
2581 
2582 		if ( !rformElems.test( elem.nodeName ) || elem.readOnly ) {
2583 			return;
2584 		}
2585 
2586 		data = jQuery.data( elem, "_change_data" );
2587 		val = getVal(elem);
2588 
2589 		// the current data will be also retrieved by beforeactivate
2590 		if ( e.type !== "focusout" || elem.type !== "radio" ) {
2591 			jQuery.data( elem, "_change_data", val );
2592 		}
2593 		
2594 		if ( data === undefined || val === data ) {
2595 			return;
2596 		}
2597 
2598 		if ( data != null || val ) {
2599 			e.type = "change";
2600 			e.liveFired = undefined;
2601 			return jQuery.event.trigger( e, arguments[1], elem );
2602 		}
2603 	};
2604 
2605 	jQuery.event.special.change = {
2606 		filters: {
2607 			focusout: testChange, 
2608 
2609 			beforedeactivate: testChange,
2610 
2611 			click: function( e ) {
2612 				var elem = e.target, type = elem.type;
2613 
2614 				if ( type === "radio" || type === "checkbox" || elem.nodeName.toLowerCase() === "select" ) {
2615 					return testChange.call( this, e );
2616 				}
2617 			},
2618 
2619 			// Change has to be called before submit
2620 			// Keydown will be called before keypress, which is used in submit-event delegation
2621 			keydown: function( e ) {
2622 				var elem = e.target, type = elem.type;
2623 
2624 				if ( (e.keyCode === 13 && elem.nodeName.toLowerCase() !== "textarea") ||
2625 					(e.keyCode === 32 && (type === "checkbox" || type === "radio")) ||
2626 					type === "select-multiple" ) {
2627 					return testChange.call( this, e );
2628 				}
2629 			},
2630 
2631 			// Beforeactivate happens also before the previous element is blurred
2632 			// with this event you can't trigger a change event, but you can store
2633 			// information
2634 			beforeactivate: function( e ) {
2635 				var elem = e.target;
2636 				jQuery.data( elem, "_change_data", getVal(elem) );
2637 			}
2638 		},
2639 
2640 		setup: function( data, namespaces ) {
2641 			if ( this.type === "file" ) {
2642 				return false;
2643 			}
2644 
2645 			for ( var type in changeFilters ) {
2646 				jQuery.event.add( this, type + ".specialChange", changeFilters[type] );
2647 			}
2648 
2649 			return rformElems.test( this.nodeName );
2650 		},
2651 
2652 		teardown: function( namespaces ) {
2653 			jQuery.event.remove( this, ".specialChange" );
2654 
2655 			return rformElems.test( this.nodeName );
2656 		}
2657 	};
2658 
2659 	changeFilters = jQuery.event.special.change.filters;
2660 
2661 	// Handle when the input is .focus()'d
2662 	changeFilters.focus = changeFilters.beforeactivate;
2663 }
2664 
2665 function trigger( type, elem, args ) {
2666 	args[0].type = type;
2667 	return jQuery.event.handle.apply( elem, args );
2668 }
2669 
2670 // Create "bubbling" focus and blur events
2671 if ( document.addEventListener ) {
2672 	jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
2673 		jQuery.event.special[ fix ] = {
2674 			setup: function() {
2675 				if ( focusCounts[fix]++ === 0 ) {
2676 					document.addEventListener( orig, handler, true );
2677 				}
2678 			}, 
2679 			teardown: function() { 
2680 				if ( --focusCounts[fix] === 0 ) {
2681 					document.removeEventListener( orig, handler, true );
2682 				}
2683 			}
2684 		};
2685 
2686 		function handler( e ) { 
2687 			e = jQuery.event.fix( e );
2688 			e.type = fix;
2689 			return jQuery.event.trigger( e, null, e.target );
2690 		}
2691 	});
2692 }
2693 
2694 jQuery.each(["bind", "one"], function( i, name ) {
2695 	jQuery.fn[ name ] = function( type, data, fn ) {
2696 		// Handle object literals
2697 		if ( typeof type === "object" ) {
2698 			for ( var key in type ) {
2699 				this[ name ](key, data, type[key], fn);
2700 			}
2701 			return this;
2702 		}
2703 		
2704 		if ( jQuery.isFunction( data ) || data === false ) {
2705 			fn = data;
2706 			data = undefined;
2707 		}
2708 
2709 		var handler = name === "one" ? jQuery.proxy( fn, function( event ) {
2710 			jQuery( this ).unbind( event, handler );
2711 			return fn.apply( this, arguments );
2712 		}) : fn;
2713 
2714 		if ( type === "unload" && name !== "one" ) {
2715 			this.one( type, data, fn );
2716 
2717 		} else {
2718 			for ( var i = 0, l = this.length; i < l; i++ ) {
2719 				jQuery.event.add( this[i], type, handler, data );
2720 			}
2721 		}
2722 
2723 		return this;
2724 	};
2725 });
2726 
2727 jQuery.fn.extend({
2728 	unbind: function( type, fn ) {
2729 		// Handle object literals
2730 		if ( typeof type === "object" && !type.preventDefault ) {
2731 			for ( var key in type ) {
2732 				this.unbind(key, type[key]);
2733 			}
2734 
2735 		} else {
2736 			for ( var i = 0, l = this.length; i < l; i++ ) {
2737 				jQuery.event.remove( this[i], type, fn );
2738 			}
2739 		}
2740 
2741 		return this;
2742 	},
2743 	
2744 	delegate: function( selector, types, data, fn ) {
2745 		return this.live( types, data, fn, selector );
2746 	},
2747 	
2748 	undelegate: function( selector, types, fn ) {
2749 		if ( arguments.length === 0 ) {
2750 				return this.unbind( "live" );
2751 		
2752 		} else {
2753 			return this.die( types, null, fn, selector );
2754 		}
2755 	},
2756 	
2757 	trigger: function( type, data ) {
2758 		return this.each(function() {
2759 			jQuery.event.trigger( type, data, this );
2760 		});
2761 	},
2762 
2763 	triggerHandler: function( type, data ) {
2764 		if ( this[0] ) {
2765 			var event = jQuery.Event( type );
2766 			event.preventDefault();
2767 			event.stopPropagation();
2768 			jQuery.event.trigger( event, data, this[0] );
2769 			return event.result;
2770 		}
2771 	},
2772 
2773 	toggle: function( fn ) {
2774 		// Save reference to arguments for access in closure
2775 		var args = arguments,
2776 			i = 1;
2777 
2778 		// link all the functions, so any of them can unbind this click handler
2779 		while ( i < args.length ) {
2780 			jQuery.proxy( fn, args[ i++ ] );
2781 		}
2782 
2783 		return this.click( jQuery.proxy( fn, function( event ) {
2784 			// Figure out which function to execute
2785 			var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i;
2786 			jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 );
2787 
2788 			// Make sure that clicks stop
2789 			event.preventDefault();
2790 
2791 			// and execute the function
2792 			return args[ lastToggle ].apply( this, arguments ) || false;
2793 		}));
2794 	},
2795 
2796 	hover: function( fnOver, fnOut ) {
2797 		return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
2798 	}
2799 });
2800 
2801 var liveMap = {
2802 	focus: "focusin",
2803 	blur: "focusout",
2804 	mouseenter: "mouseover",
2805 	mouseleave: "mouseout"
2806 };
2807 
2808 jQuery.each(["live", "die"], function( i, name ) {
2809 	jQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) {
2810 		var type, i = 0, match, namespaces, preType,
2811 			selector = origSelector || this.selector,
2812 			context = origSelector ? this : jQuery( this.context );
2813 		
2814 		if ( typeof types === "object" && !types.preventDefault ) {
2815 			for ( var key in types ) {
2816 				context[ name ]( key, data, types[key], selector );
2817 			}
2818 			
2819 			return this;
2820 		}
2821 
2822 		if ( jQuery.isFunction( data ) ) {
2823 			fn = data;
2824 			data = undefined;
2825 		}
2826 
2827 		types = (types || "").split(" ");
2828 
2829 		while ( (type = types[ i++ ]) != null ) {
2830 			match = rnamespaces.exec( type );
2831 			namespaces = "";
2832 
2833 			if ( match )  {
2834 				namespaces = match[0];
2835 				type = type.replace( rnamespaces, "" );
2836 			}
2837 
2838 			if ( type === "hover" ) {
2839 				types.push( "mouseenter" + namespaces, "mouseleave" + namespaces );
2840 				continue;
2841 			}
2842 
2843 			preType = type;
2844 
2845 			if ( type === "focus" || type === "blur" ) {
2846 				types.push( liveMap[ type ] + namespaces );
2847 				type = type + namespaces;
2848 
2849 			} else {
2850 				type = (liveMap[ type ] || type) + namespaces;
2851 			}
2852 
2853 			if ( name === "live" ) {
2854 				// bind live handler
2855 				for ( var j = 0, l = context.length; j < l; j++ ) {
2856 					jQuery.event.add( context[j], "live." + liveConvert( type, selector ),
2857 						{ data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } );
2858 				}
2859 
2860 			} else {
2861 				// unbind live handler
2862 				context.unbind( "live." + liveConvert( type, selector ), fn );
2863 			}
2864 		}
2865 		
2866 		return this;
2867 	};
2868 });
2869 
2870 function liveHandler( event ) {
2871 	var stop, maxLevel, related, match, handleObj, elem, j, i, l, data, close, namespace, ret,
2872 		elems = [],
2873 		selectors = [],
2874 		events = jQuery.data( this, this.nodeType ? "events" : "__events__" );
2875 
2876 	if ( typeof events === "function" ) {
2877 		events = events.events;
2878 	}
2879 
2880 	// Make sure we avoid non-left-click bubbling in Firefox (#3861)
2881 	if ( event.liveFired === this || !events || !events.live || event.button && event.type === "click" ) {
2882 		return;
2883 	}
2884 	
2885 	if ( event.namespace ) {
2886 		namespace = new RegExp("(^|\\.)" + event.namespace.split(".").join("\\.(?:.*\\.)?") + "(\\.|$)");
2887 	}
2888 
2889 	event.liveFired = this;
2890 
2891 	var live = events.live.slice(0);
2892 
2893 	for ( j = 0; j < live.length; j++ ) {
2894 		handleObj = live[j];
2895 
2896 		if ( handleObj.origType.replace( rnamespaces, "" ) === event.type ) {
2897 			selectors.push( handleObj.selector );
2898 
2899 		} else {
2900 			live.splice( j--, 1 );
2901 		}
2902 	}
2903 
2904 	match = jQuery( event.target ).closest( selectors, event.currentTarget );
2905 
2906 	for ( i = 0, l = match.length; i < l; i++ ) {
2907 		close = match[i];
2908 
2909 		for ( j = 0; j < live.length; j++ ) {
2910 			handleObj = live[j];
2911 
2912 			if ( close.selector === handleObj.selector && (!namespace || namespace.test( handleObj.namespace )) ) {
2913 				elem = close.elem;
2914 				related = null;
2915 
2916 				// Those two events require additional checking
2917 				if ( handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave" ) {
2918 					event.type = handleObj.preType;
2919 					related = jQuery( event.relatedTarget ).closest( handleObj.selector )[0];
2920 				}
2921 
2922 				if ( !related || related !== elem ) {
2923 					elems.push({ elem: elem, handleObj: handleObj, level: close.level });
2924 				}
2925 			}
2926 		}
2927 	}
2928 
2929 	for ( i = 0, l = elems.length; i < l; i++ ) {
2930 		match = elems[i];
2931 
2932 		if ( maxLevel && match.level > maxLevel ) {
2933 			break;
2934 		}
2935 
2936 		event.currentTarget = match.elem;
2937 		event.data = match.handleObj.data;
2938 		event.handleObj = match.handleObj;
2939 
2940 		ret = match.handleObj.origHandler.apply( match.elem, arguments );
2941 
2942 		if ( ret === false || event.isPropagationStopped() ) {
2943 			maxLevel = match.level;
2944 
2945 			if ( ret === false ) {
2946 				stop = false;
2947 			}
2948 			if ( event.isImmediatePropagationStopped() ) {
2949 				break;
2950 			}
2951 		}
2952 	}
2953 
2954 	return stop;
2955 }
2956 
2957 function liveConvert( type, selector ) {
2958 	return (type && type !== "*" ? type + "." : "") + selector.replace(rperiod, "`").replace(rspace, "&");
2959 }
2960 
2961 jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
2962 	"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
2963 	"change select submit keydown keypress keyup error").split(" "), function( i, name ) {
2964 
2965 	// Handle event binding
2966 	jQuery.fn[ name ] = function( data, fn ) {
2967 		if ( fn == null ) {
2968 			fn = data;
2969 			data = null;
2970 		}
2971 
2972 		return arguments.length > 0 ?
2973 			this.bind( name, data, fn ) :
2974 			this.trigger( name );
2975 	};
2976 
2977 	if ( jQuery.attrFn ) {
2978 		jQuery.attrFn[ name ] = true;
2979 	}
2980 });
2981 
2982 // Prevent memory leaks in IE
2983 // Window isn't included so as not to unbind existing unload events
2984 // More info:
2985 //  - http://isaacschlueter.com/2006/10/msie-memory-leaks/
2986 if ( window.attachEvent && !window.addEventListener ) {
2987 	jQuery(window).bind("unload", function() {
2988 		for ( var id in jQuery.cache ) {
2989 			if ( jQuery.cache[ id ].handle ) {
2990 				// Try/Catch is to handle iframes being unloaded, see #4280
2991 				try {
2992 					jQuery.event.remove( jQuery.cache[ id ].handle.elem );
2993 				} catch(e) {}
2994 			}
2995 		}
2996 	});
2997 }
2998 
2999 
3000 /*!
3001  * Sizzle CSS Selector Engine - v1.0
3002  *  Copyright 2009, The Dojo Foundation
3003  *  Released under the MIT, BSD, and GPL Licenses.
3004  *  More information: http://sizzlejs.com/
3005  */
3006 (function(){
3007 
3008 var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
3009 	done = 0,
3010 	toString = Object.prototype.toString,
3011 	hasDuplicate = false,
3012 	baseHasDuplicate = true;
3013 
3014 // Here we check if the JavaScript engine is using some sort of
3015 // optimization where it does not always call our comparision
3016 // function. If that is the case, discard the hasDuplicate value.
3017 //   Thus far that includes Google Chrome.
3018 [0, 0].sort(function() {
3019 	baseHasDuplicate = false;
3020 	return 0;
3021 });
3022 
3023 var Sizzle = function( selector, context, results, seed ) {
3024 	results = results || [];
3025 	context = context || document;
3026 
3027 	var origContext = context;
3028 
3029 	if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
3030 		return [];
3031 	}
3032 	
3033 	if ( !selector || typeof selector !== "string" ) {
3034 		return results;
3035 	}
3036 
3037 	var m, set, checkSet, extra, ret, cur, pop, i,
3038 		prune = true,
3039 		contextXML = Sizzle.isXML( context ),
3040 		parts = [],
3041 		soFar = selector;
3042 	
3043 	// Reset the position of the chunker regexp (start from head)
3044 	do {
3045 		chunker.exec( "" );
3046 		m = chunker.exec( soFar );
3047 
3048 		if ( m ) {
3049 			soFar = m[3];
3050 		
3051 			parts.push( m[1] );
3052 		
3053 			if ( m[2] ) {
3054 				extra = m[3];
3055 				break;
3056 			}
3057 		}
3058 	} while ( m );
3059 
3060 	if ( parts.length > 1 && origPOS.exec( selector ) ) {
3061 
3062 		if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
3063 			set = posProcess( parts[0] + parts[1], context );
3064 
3065 		} else {
3066 			set = Expr.relative[ parts[0] ] ?
3067 				[ context ] :
3068 				Sizzle( parts.shift(), context );
3069 
3070 			while ( parts.length ) {
3071 				selector = parts.shift();
3072 
3073 				if ( Expr.relative[ selector ] ) {
3074 					selector += parts.shift();
3075 				}
3076 				
3077 				set = posProcess( selector, set );
3078 			}
3079 		}
3080 
3081 	} else {
3082 		// Take a shortcut and set the context if the root selector is an ID
3083 		// (but not if it'll be faster if the inner selector is an ID)
3084 		if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
3085 				Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
3086 
3087 			ret = Sizzle.find( parts.shift(), context, contextXML );
3088 			context = ret.expr ?
3089 				Sizzle.filter( ret.expr, ret.set )[0] :
3090 				ret.set[0];
3091 		}
3092 
3093 		if ( context ) {
3094 			ret = seed ?
3095 				{ expr: parts.pop(), set: makeArray(seed) } :
3096 				Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
3097 
3098 			set = ret.expr ?
3099 				Sizzle.filter( ret.expr, ret.set ) :
3100 				ret.set;
3101 
3102 			if ( parts.length > 0 ) {
3103 				checkSet = makeArray( set );
3104 
3105 			} else {
3106 				prune = false;
3107 			}
3108 
3109 			while ( parts.length ) {
3110 				cur = parts.pop();
3111 				pop = cur;
3112 
3113 				if ( !Expr.relative[ cur ] ) {
3114 					cur = "";
3115 				} else {
3116 					pop = parts.pop();
3117 				}
3118 
3119 				if ( pop == null ) {
3120 					pop = context;
3121 				}
3122 
3123 				Expr.relative[ cur ]( checkSet, pop, contextXML );
3124 			}
3125 
3126 		} else {
3127 			checkSet = parts = [];
3128 		}
3129 	}
3130 
3131 	if ( !checkSet ) {
3132 		checkSet = set;
3133 	}
3134 
3135 	if ( !checkSet ) {
3136 		Sizzle.error( cur || selector );
3137 	}
3138 
3139 	if ( toString.call(checkSet) === "[object Array]" ) {
3140 		if ( !prune ) {
3141 			results.push.apply( results, checkSet );
3142 
3143 		} else if ( context && context.nodeType === 1 ) {
3144 			for ( i = 0; checkSet[i] != null; i++ ) {
3145 				if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) {
3146 					results.push( set[i] );
3147 				}
3148 			}
3149 
3150 		} else {
3151 			for ( i = 0; checkSet[i] != null; i++ ) {
3152 				if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
3153 					results.push( set[i] );
3154 				}
3155 			}
3156 		}
3157 
3158 	} else {
3159 		makeArray( checkSet, results );
3160 	}
3161 
3162 	if ( extra ) {
3163 		Sizzle( extra, origContext, results, seed );
3164 		Sizzle.uniqueSort( results );
3165 	}
3166 
3167 	return results;
3168 };
3169 
3170 Sizzle.uniqueSort = function( results ) {
3171 	if ( sortOrder ) {
3172 		hasDuplicate = baseHasDuplicate;
3173 		results.sort( sortOrder );
3174 
3175 		if ( hasDuplicate ) {
3176 			for ( var i = 1; i < results.length; i++ ) {
3177 				if ( results[i] === results[ i - 1 ] ) {
3178 					results.splice( i--, 1 );
3179 				}
3180 			}
3181 		}
3182 	}
3183 
3184 	return results;
3185 };
3186 
3187 Sizzle.matches = function( expr, set ) {
3188 	return Sizzle( expr, null, null, set );
3189 };
3190 
3191 Sizzle.matchesSelector = function( node, expr ) {
3192 	return Sizzle( expr, null, null, [node] ).length > 0;
3193 };
3194 
3195 Sizzle.find = function( expr, context, isXML ) {
3196 	var set;
3197 
3198 	if ( !expr ) {
3199 		return [];
3200 	}
3201 
3202 	for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
3203 		var match,
3204 			type = Expr.order[i];
3205 		
3206 		if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
3207 			var left = match[1];
3208 			match.splice( 1, 1 );
3209 
3210 			if ( left.substr( left.length - 1 ) !== "\\" ) {
3211 				match[1] = (match[1] || "").replace(/\\/g, "");
3212 				set = Expr.find[ type ]( match, context, isXML );
3213 
3214 				if ( set != null ) {
3215 					expr = expr.replace( Expr.match[ type ], "" );
3216 					break;
3217 				}
3218 			}
3219 		}
3220 	}
3221 
3222 	if ( !set ) {
3223 		set = context.getElementsByTagName( "*" );
3224 	}
3225 
3226 	return { set: set, expr: expr };
3227 };
3228 
3229 Sizzle.filter = function( expr, set, inplace, not ) {
3230 	var match, anyFound,
3231 		old = expr,
3232 		result = [],
3233 		curLoop = set,
3234 		isXMLFilter = set && set[0] && Sizzle.isXML( set[0] );
3235 
3236 	while ( expr && set.length ) {
3237 		for ( var type in Expr.filter ) {
3238 			if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {
3239 				var found, item,
3240 					filter = Expr.filter[ type ],
3241 					left = match[1];
3242 
3243 				anyFound = false;
3244 
3245 				match.splice(1,1);
3246 
3247 				if ( left.substr( left.length - 1 ) === "\\" ) {
3248 					continue;
3249 				}
3250 
3251 				if ( curLoop === result ) {
3252 					result = [];
3253 				}
3254 
3255 				if ( Expr.preFilter[ type ] ) {
3256 					match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
3257 
3258 					if ( !match ) {
3259 						anyFound = found = true;
3260 
3261 					} else if ( match === true ) {
3262 						continue;
3263 					}
3264 				}
3265 
3266 				if ( match ) {
3267 					for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
3268 						if ( item ) {
3269 							found = filter( item, match, i, curLoop );
3270 							var pass = not ^ !!found;
3271 
3272 							if ( inplace && found != null ) {
3273 								if ( pass ) {
3274 									anyFound = true;
3275 
3276 								} else {
3277 									curLoop[i] = false;
3278 								}
3279 
3280 							} else if ( pass ) {
3281 								result.push( item );
3282 								anyFound = true;
3283 							}
3284 						}
3285 					}
3286 				}
3287 
3288 				if ( found !== undefined ) {
3289 					if ( !inplace ) {
3290 						curLoop = result;
3291 					}
3292 
3293 					expr = expr.replace( Expr.match[ type ], "" );
3294 
3295 					if ( !anyFound ) {
3296 						return [];
3297 					}
3298 
3299 					break;
3300 				}
3301 			}
3302 		}
3303 
3304 		// Improper expression
3305 		if ( expr === old ) {
3306 			if ( anyFound == null ) {
3307 				Sizzle.error( expr );
3308 
3309 			} else {
3310 				break;
3311 			}
3312 		}
3313 
3314 		old = expr;
3315 	}
3316 
3317 	return curLoop;
3318 };
3319 
3320 Sizzle.error = function( msg ) {
3321 	throw "Syntax error, unrecognized expression: " + msg;
3322 };
3323 
3324 var Expr = Sizzle.selectors = {
3325 	order: [ "ID", "NAME", "TAG" ],
3326 
3327 	match: {
3328 		ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
3329 		CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
3330 		NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,
3331 		ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
3332 		TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,
3333 		CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+\-]*)\))?/,
3334 		POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,
3335 		PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/
3336 	},
3337 
3338 	leftMatch: {},
3339 
3340 	attrMap: {
3341 		"class": "className",
3342 		"for": "htmlFor"
3343 	},
3344 
3345 	attrHandle: {
3346 		href: function( elem ) {
3347 			return elem.getAttribute( "href" );
3348 		}
3349 	},
3350 
3351 	relative: {
3352 		"+": function(checkSet, part){
3353 			var isPartStr = typeof part === "string",
3354 				isTag = isPartStr && !/\W/.test( part ),
3355 				isPartStrNotTag = isPartStr && !isTag;
3356 
3357 			if ( isTag ) {
3358 				part = part.toLowerCase();
3359 			}
3360 
3361 			for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
3362 				if ( (elem = checkSet[i]) ) {
3363 					while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
3364 
3365 					checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?
3366 						elem || false :
3367 						elem === part;
3368 				}
3369 			}
3370 
3371 			if ( isPartStrNotTag ) {
3372 				Sizzle.filter( part, checkSet, true );
3373 			}
3374 		},
3375 
3376 		">": function( checkSet, part ) {
3377 			var elem,
3378 				isPartStr = typeof part === "string",
3379 				i = 0,
3380 				l = checkSet.length;
3381 
3382 			if ( isPartStr && !/\W/.test( part ) ) {
3383 				part = part.toLowerCase();
3384 
3385 				for ( ; i < l; i++ ) {
3386 					elem = checkSet[i];
3387 
3388 					if ( elem ) {
3389 						var parent = elem.parentNode;
3390 						checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;
3391 					}
3392 				}
3393 
3394 			} else {
3395 				for ( ; i < l; i++ ) {
3396 					elem = checkSet[i];
3397 
3398 					if ( elem ) {
3399 						checkSet[i] = isPartStr ?
3400 							elem.parentNode :
3401 							elem.parentNode === part;
3402 					}
3403 				}
3404 
3405 				if ( isPartStr ) {
3406 					Sizzle.filter( part, checkSet, true );
3407 				}
3408 			}
3409 		},
3410 
3411 		"": function(checkSet, part, isXML){
3412 			var nodeCheck,
3413 				doneName = done++,
3414 				checkFn = dirCheck;
3415 
3416 			if ( typeof part === "string" && !/\W/.test(part) ) {
3417 				part = part.toLowerCase();
3418 				nodeCheck = part;
3419 				checkFn = dirNodeCheck;
3420 			}
3421 
3422 			checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML );
3423 		},
3424 
3425 		"~": function( checkSet, part, isXML ) {
3426 			var nodeCheck,
3427 				doneName = done++,
3428 				checkFn = dirCheck;
3429 
3430 			if ( typeof part === "string" && !/\W/.test( part ) ) {
3431 				part = part.toLowerCase();
3432 				nodeCheck = part;
3433 				checkFn = dirNodeCheck;
3434 			}
3435 
3436 			checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML );
3437 		}
3438 	},
3439 
3440 	find: {
3441 		ID: function( match, context, isXML ) {
3442 			if ( typeof context.getElementById !== "undefined" && !isXML ) {
3443 				var m = context.getElementById(match[1]);
3444 				// Check parentNode to catch when Blackberry 4.6 returns
3445 				// nodes that are no longer in the document #6963
3446 				return m && m.parentNode ? [m] : [];
3447 			}
3448 		},
3449 
3450 		NAME: function( match, context ) {
3451 			if ( typeof context.getElementsByName !== "undefined" ) {
3452 				var ret = [],
3453 					results = context.getElementsByName( match[1] );
3454 
3455 				for ( var i = 0, l = results.length; i < l; i++ ) {
3456 					if ( results[i].getAttribute("name") === match[1] ) {
3457 						ret.push( results[i] );
3458 					}
3459 				}
3460 
3461 				return ret.length === 0 ? null : ret;
3462 			}
3463 		},
3464 
3465 		TAG: function( match, context ) {
3466 			return context.getElementsByTagName( match[1] );
3467 		}
3468 	},
3469 	preFilter: {
3470 		CLASS: function( match, curLoop, inplace, result, not, isXML ) {
3471 			match = " " + match[1].replace(/\\/g, "") + " ";
3472 
3473 			if ( isXML ) {
3474 				return match;
3475 			}
3476 
3477 			for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
3478 				if ( elem ) {
3479 					if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n]/g, " ").indexOf(match) >= 0) ) {
3480 						if ( !inplace ) {
3481 							result.push( elem );
3482 						}
3483 
3484 					} else if ( inplace ) {
3485 						curLoop[i] = false;
3486 					}
3487 				}
3488 			}
3489 
3490 			return false;
3491 		},
3492 
3493 		ID: function( match ) {
3494 			return match[1].replace(/\\/g, "");
3495 		},
3496 
3497 		TAG: function( match, curLoop ) {
3498 			return match[1].toLowerCase();
3499 		},
3500 
3501 		CHILD: function( match ) {
3502 			if ( match[1] === "nth" ) {
3503 				// parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
3504 				var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
3505 					match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||
3506 					!/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
3507 
3508 				// calculate the numbers (first)n+(last) including if they are negative
3509 				match[2] = (test[1] + (test[2] || 1)) - 0;
3510 				match[3] = test[3] - 0;
3511 			}
3512 
3513 			// TODO: Move to normal caching system
3514 			match[0] = done++;
3515 
3516 			return match;
3517 		},
3518 
3519 		ATTR: function( match, curLoop, inplace, result, not, isXML ) {
3520 			var name = match[1].replace(/\\/g, "");
3521 			
3522 			if ( !isXML && Expr.attrMap[name] ) {
3523 				match[1] = Expr.attrMap[name];
3524 			}
3525 
3526 			if ( match[2] === "~=" ) {
3527 				match[4] = " " + match[4] + " ";
3528 			}
3529 
3530 			return match;
3531 		},
3532 
3533 		PSEUDO: function( match, curLoop, inplace, result, not ) {
3534 			if ( match[1] === "not" ) {
3535 				// If we're dealing with a complex expression, or a simple one
3536 				if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
3537 					match[3] = Sizzle(match[3], null, null, curLoop);
3538 
3539 				} else {
3540 					var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
3541 
3542 					if ( !inplace ) {
3543 						result.push.apply( result, ret );
3544 					}
3545 
3546 					return false;
3547 				}
3548 
3549 			} else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
3550 				return true;
3551 			}
3552 			
3553 			return match;
3554 		},
3555 
3556 		POS: function( match ) {
3557 			match.unshift( true );
3558 
3559 			return match;
3560 		}
3561 	},
3562 	
3563 	filters: {
3564 		enabled: function( elem ) {
3565 			return elem.disabled === false && elem.type !== "hidden";
3566 		},
3567 
3568 		disabled: function( elem ) {
3569 			return elem.disabled === true;
3570 		},
3571 
3572 		checked: function( elem ) {
3573 			return elem.checked === true;
3574 		},
3575 		
3576 		selected: function( elem ) {
3577 			// Accessing this property makes selected-by-default
3578 			// options in Safari work properly
3579 			elem.parentNode.selectedIndex;
3580 			
3581 			return elem.selected === true;
3582 		},
3583 
3584 		parent: function( elem ) {
3585 			return !!elem.firstChild;
3586 		},
3587 
3588 		empty: function( elem ) {
3589 			return !elem.firstChild;
3590 		},
3591 
3592 		has: function( elem, i, match ) {
3593 			return !!Sizzle( match[3], elem ).length;
3594 		},
3595 
3596 		header: function( elem ) {
3597 			return (/h\d/i).test( elem.nodeName );
3598 		},
3599 
3600 		text: function( elem ) {
3601 			return "text" === elem.type;
3602 		},
3603 		radio: function( elem ) {
3604 			return "radio" === elem.type;
3605 		},
3606 
3607 		checkbox: function( elem ) {
3608 			return "checkbox" === elem.type;
3609 		},
3610 
3611 		file: function( elem ) {
3612 			return "file" === elem.type;
3613 		},
3614 		password: function( elem ) {
3615 			return "password" === elem.type;
3616 		},
3617 
3618 		submit: function( elem ) {
3619 			return "submit" === elem.type;
3620 		},
3621 
3622 		image: function( elem ) {
3623 			return "image" === elem.type;
3624 		},
3625 
3626 		reset: function( elem ) {
3627 			return "reset" === elem.type;
3628 		},
3629 
3630 		button: function( elem ) {
3631 			return "button" === elem.type || elem.nodeName.toLowerCase() === "button";
3632 		},
3633 
3634 		input: function( elem ) {
3635 			return (/input|select|textarea|button/i).test( elem.nodeName );
3636 		}
3637 	},
3638 	setFilters: {
3639 		first: function( elem, i ) {
3640 			return i === 0;
3641 		},
3642 
3643 		last: function( elem, i, match, array ) {
3644 			return i === array.length - 1;
3645 		},
3646 
3647 		even: function( elem, i ) {
3648 			return i % 2 === 0;
3649 		},
3650 
3651 		odd: function( elem, i ) {
3652 			return i % 2 === 1;
3653 		},
3654 
3655 		lt: function( elem, i, match ) {
3656 			return i < match[3] - 0;
3657 		},
3658 
3659 		gt: function( elem, i, match ) {
3660 			return i > match[3] - 0;
3661 		},
3662 
3663 		nth: function( elem, i, match ) {
3664 			return match[3] - 0 === i;
3665 		},
3666 
3667 		eq: function( elem, i, match ) {
3668 			return match[3] - 0 === i;
3669 		}
3670 	},
3671 	filter: {
3672 		PSEUDO: function( elem, match, i, array ) {
3673 			var name = match[1],
3674 				filter = Expr.filters[ name ];
3675 
3676 			if ( filter ) {
3677 				return filter( elem, i, match, array );
3678 
3679 			} else if ( name === "contains" ) {
3680 				return (elem.textContent || elem.innerText || Sizzle.getText([ elem ]) || "").indexOf(match[3]) >= 0;
3681 
3682 			} else if ( name === "not" ) {
3683 				var not = match[3];
3684 
3685 				for ( var j = 0, l = not.length; j < l; j++ ) {
3686 					if ( not[j] === elem ) {
3687 						return false;
3688 					}
3689 				}
3690 
3691 				return true;
3692 
3693 			} else {
3694 				Sizzle.error( "Syntax error, unrecognized expression: " + name );
3695 			}
3696 		},
3697 
3698 		CHILD: function( elem, match ) {
3699 			var type = match[1],
3700 				node = elem;
3701 
3702 			switch ( type ) {
3703 				case "only":
3704 				case "first":
3705 					while ( (node = node.previousSibling) )	 {
3706 						if ( node.nodeType === 1 ) { 
3707 							return false; 
3708 						}
3709 					}
3710 
3711 					if ( type === "first" ) { 
3712 						return true; 
3713 					}
3714 
3715 					node = elem;
3716 
3717 				case "last":
3718 					while ( (node = node.nextSibling) )	 {
3719 						if ( node.nodeType === 1 ) { 
3720 							return false; 
3721 						}
3722 					}
3723 
3724 					return true;
3725 
3726 				case "nth":
3727 					var first = match[2],
3728 						last = match[3];
3729 
3730 					if ( first === 1 && last === 0 ) {
3731 						return true;
3732 					}
3733 					
3734 					var doneName = match[0],
3735 						parent = elem.parentNode;
3736 	
3737 					if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
3738 						var count = 0;
3739 						
3740 						for ( node = parent.firstChild; node; node = node.nextSibling ) {
3741 							if ( node.nodeType === 1 ) {
3742 								node.nodeIndex = ++count;
3743 							}
3744 						} 
3745 
3746 						parent.sizcache = doneName;
3747 					}
3748 					
3749 					var diff = elem.nodeIndex - last;
3750 
3751 					if ( first === 0 ) {
3752 						return diff === 0;
3753 
3754 					} else {
3755 						return ( diff % first === 0 && diff / first >= 0 );
3756 					}
3757 			}
3758 		},
3759 
3760 		ID: function( elem, match ) {
3761 			return elem.nodeType === 1 && elem.getAttribute("id") === match;
3762 		},
3763 
3764 		TAG: function( elem, match ) {
3765 			return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match;
3766 		},
3767 		
3768 		CLASS: function( elem, match ) {
3769 			return (" " + (elem.className || elem.getAttribute("class")) + " ")
3770 				.indexOf( match ) > -1;
3771 		},
3772 
3773 		ATTR: function( elem, match ) {
3774 			var name = match[1],
3775 				result = Expr.attrHandle[ name ] ?
3776 					Expr.attrHandle[ name ]( elem ) :
3777 					elem[ name ] != null ?
3778 						elem[ name ] :
3779 						elem.getAttribute( name ),
3780 				value = result + "",
3781 				type = match[2],
3782 				check = match[4];
3783 
3784 			return result == null ?
3785 				type === "!=" :
3786 				type === "=" ?
3787 				value === check :
3788 				type === "*=" ?
3789 				value.indexOf(check) >= 0 :
3790 				type === "~=" ?
3791 				(" " + value + " ").indexOf(check) >= 0 :
3792 				!check ?
3793 				value && result !== false :
3794 				type === "!=" ?
3795 				value !== check :
3796 				type === "^=" ?
3797 				value.indexOf(check) === 0 :
3798 				type === "$=" ?
3799 				value.substr(value.length - check.length) === check :
3800 				type === "|=" ?
3801 				value === check || value.substr(0, check.length + 1) === check + "-" :
3802 				false;
3803 		},
3804 
3805 		POS: function( elem, match, i, array ) {
3806 			var name = match[2],
3807 				filter = Expr.setFilters[ name ];
3808 
3809 			if ( filter ) {
3810 				return filter( elem, i, match, array );
3811 			}
3812 		}
3813 	}
3814 };
3815 
3816 var origPOS = Expr.match.POS,
3817 	fescape = function(all, num){
3818 		return "\\" + (num - 0 + 1);
3819 	};
3820 
3821 for ( var type in Expr.match ) {
3822 	Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) );
3823 	Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) );
3824 }
3825 
3826 var makeArray = function( array, results ) {
3827 	array = Array.prototype.slice.call( array, 0 );
3828 
3829 	if ( results ) {
3830 		results.push.apply( results, array );
3831 		return results;
3832 	}
3833 	
3834 	return array;
3835 };
3836 
3837 // Perform a simple check to determine if the browser is capable of
3838 // converting a NodeList to an array using builtin methods.
3839 // Also verifies that the returned array holds DOM nodes
3840 // (which is not the case in the Blackberry browser)
3841 try {
3842 	Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType;
3843 
3844 // Provide a fallback method if it does not work
3845 } catch( e ) {
3846 	makeArray = function( array, results ) {
3847 		var i = 0,
3848 			ret = results || [];
3849 
3850 		if ( toString.call(array) === "[object Array]" ) {
3851 			Array.prototype.push.apply( ret, array );
3852 
3853 		} else {
3854 			if ( typeof array.length === "number" ) {
3855 				for ( var l = array.length; i < l; i++ ) {
3856 					ret.push( array[i] );
3857 				}
3858 
3859 			} else {
3860 				for ( ; array[i]; i++ ) {
3861 					ret.push( array[i] );
3862 				}
3863 			}
3864 		}
3865 
3866 		return ret;
3867 	};
3868 }
3869 
3870 var sortOrder, siblingCheck;
3871 
3872 if ( document.documentElement.compareDocumentPosition ) {
3873 	sortOrder = function( a, b ) {
3874 		if ( a === b ) {
3875 			hasDuplicate = true;
3876 			return 0;
3877 		}
3878 
3879 		if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
3880 			return a.compareDocumentPosition ? -1 : 1;
3881 		}
3882 
3883 		return a.compareDocumentPosition(b) & 4 ? -1 : 1;
3884 	};
3885 
3886 } else {
3887 	sortOrder = function( a, b ) {
3888 		var al, bl,
3889 			ap = [],
3890 			bp = [],
3891 			aup = a.parentNode,
3892 			bup = b.parentNode,
3893 			cur = aup;
3894 
3895 		// The nodes are identical, we can exit early
3896 		if ( a === b ) {
3897 			hasDuplicate = true;
3898 			return 0;
3899 
3900 		// If the nodes are siblings (or identical) we can do a quick check
3901 		} else if ( aup === bup ) {
3902 			return siblingCheck( a, b );
3903 
3904 		// If no parents were found then the nodes are disconnected
3905 		} else if ( !aup ) {
3906 			return -1;
3907 
3908 		} else if ( !bup ) {
3909 			return 1;
3910 		}
3911 
3912 		// Otherwise they're somewhere else in the tree so we need
3913 		// to build up a full list of the parentNodes for comparison
3914 		while ( cur ) {
3915 			ap.unshift( cur );
3916 			cur = cur.parentNode;
3917 		}
3918 
3919 		cur = bup;
3920 
3921 		while ( cur ) {
3922 			bp.unshift( cur );
3923 			cur = cur.parentNode;
3924 		}
3925 
3926 		al = ap.length;
3927 		bl = bp.length;
3928 
3929 		// Start walking down the tree looking for a discrepancy
3930 		for ( var i = 0; i < al && i < bl; i++ ) {
3931 			if ( ap[i] !== bp[i] ) {
3932 				return siblingCheck( ap[i], bp[i] );
3933 			}
3934 		}
3935 
3936 		// We ended someplace up the tree so do a sibling check
3937 		return i === al ?
3938 			siblingCheck( a, bp[i], -1 ) :
3939 			siblingCheck( ap[i], b, 1 );
3940 	};
3941 
3942 	siblingCheck = function( a, b, ret ) {
3943 		if ( a === b ) {
3944 			return ret;
3945 		}
3946 
3947 		var cur = a.nextSibling;
3948 
3949 		while ( cur ) {
3950 			if ( cur === b ) {
3951 				return -1;
3952 			}
3953 
3954 			cur = cur.nextSibling;
3955 		}
3956 
3957 		return 1;
3958 	};
3959 }
3960 
3961 // Utility function for retreiving the text value of an array of DOM nodes
3962 Sizzle.getText = function( elems ) {
3963 	var ret = "", elem;
3964 
3965 	for ( var i = 0; elems[i]; i++ ) {
3966 		elem = elems[i];
3967 
3968 		// Get the text from text nodes and CDATA nodes
3969 		if ( elem.nodeType === 3 || elem.nodeType === 4 ) {
3970 			ret += elem.nodeValue;
3971 
3972 		// Traverse everything else, except comment nodes
3973 		} else if ( elem.nodeType !== 8 ) {
3974 			ret += Sizzle.getText( elem.childNodes );
3975 		}
3976 	}
3977 
3978 	return ret;
3979 };
3980 
3981 // Check to see if the browser returns elements by name when
3982 // querying by getElementById (and provide a workaround)
3983 (function(){
3984 	// We're going to inject a fake input element with a specified name
3985 	var form = document.createElement("div"),
3986 		id = "script" + (new Date()).getTime(),
3987 		root = document.documentElement;
3988 
3989 	form.innerHTML = "<a name='" + id + "'/>";
3990 
3991 	// Inject it into the root element, check its status, and remove it quickly
3992 	root.insertBefore( form, root.firstChild );
3993 
3994 	// The workaround has to do additional checks after a getElementById
3995 	// Which slows things down for other browsers (hence the branching)
3996 	if ( document.getElementById( id ) ) {
3997 		Expr.find.ID = function( match, context, isXML ) {
3998 			if ( typeof context.getElementById !== "undefined" && !isXML ) {
3999 				var m = context.getElementById(match[1]);
4000 
4001 				return m ?
4002 					m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ?
4003 						[m] :
4004 						undefined :
4005 					[];
4006 			}
4007 		};
4008 
4009 		Expr.filter.ID = function( elem, match ) {
4010 			var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
4011 
4012 			return elem.nodeType === 1 && node && node.nodeValue === match;
4013 		};
4014 	}
4015 
4016 	root.removeChild( form );
4017 
4018 	// release memory in IE
4019 	root = form = null;
4020 })();
4021 
4022 (function(){
4023 	// Check to see if the browser returns only elements
4024 	// when doing getElementsByTagName("*")
4025 
4026 	// Create a fake element
4027 	var div = document.createElement("div");
4028 	div.appendChild( document.createComment("") );
4029 
4030 	// Make sure no comments are found
4031 	if ( div.getElementsByTagName("*").length > 0 ) {
4032 		Expr.find.TAG = function( match, context ) {
4033 			var results = context.getElementsByTagName( match[1] );
4034 
4035 			// Filter out possible comments
4036 			if ( match[1] === "*" ) {
4037 				var tmp = [];
4038 
4039 				for ( var i = 0; results[i]; i++ ) {
4040 					if ( results[i].nodeType === 1 ) {
4041 						tmp.push( results[i] );
4042 					}
4043 				}
4044 
4045 				results = tmp;
4046 			}
4047 
4048 			return results;
4049 		};
4050 	}
4051 
4052 	// Check to see if an attribute returns normalized href attributes
4053 	div.innerHTML = "<a href='#'></a>";
4054 
4055 	if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
4056 			div.firstChild.getAttribute("href") !== "#" ) {
4057 
4058 		Expr.attrHandle.href = function( elem ) {
4059 			return elem.getAttribute( "href", 2 );
4060 		};
4061 	}
4062 
4063 	// release memory in IE
4064 	div = null;
4065 })();
4066 
4067 if ( document.querySelectorAll ) {
4068 	(function(){
4069 		var oldSizzle = Sizzle,
4070 			div = document.createElement("div"),
4071 			id = "__sizzle__";
4072 
4073 		div.innerHTML = "<p class='TEST'></p>";
4074 
4075 		// Safari can't handle uppercase or unicode characters when
4076 		// in quirks mode.
4077 		if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
4078 			return;
4079 		}
4080 	
4081 		Sizzle = function( query, context, extra, seed ) {
4082 			context = context || document;
4083 
4084 			// Make sure that attribute selectors are quoted
4085 			query = query.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']");
4086 
4087 			// Only use querySelectorAll on non-XML documents
4088 			// (ID selectors don't work in non-HTML documents)
4089 			if ( !seed && !Sizzle.isXML(context) ) {
4090 				if ( context.nodeType === 9 ) {
4091 					try {
4092 						return makeArray( context.querySelectorAll(query), extra );
4093 					} catch(qsaError) {}
4094 
4095 				// qSA works strangely on Element-rooted queries
4096 				// We can work around this by specifying an extra ID on the root
4097 				// and working up from there (Thanks to Andrew Dupont for the technique)
4098 				// IE 8 doesn't work on object elements
4099 				} else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
4100 					var old = context.getAttribute( "id" ),
4101 						nid = old || id;
4102 
4103 					if ( !old ) {
4104 						context.setAttribute( "id", nid );
4105 					}
4106 
4107 					try {
4108 						return makeArray( context.querySelectorAll( "#" + nid + " " + query ), extra );
4109 
4110 					} catch(pseudoError) {
4111 					} finally {
4112 						if ( !old ) {
4113 							context.removeAttribute( "id" );
4114 						}
4115 					}
4116 				}
4117 			}
4118 		
4119 			return oldSizzle(query, context, extra, seed);
4120 		};
4121 
4122 		for ( var prop in oldSizzle ) {
4123 			Sizzle[ prop ] = oldSizzle[ prop ];
4124 		}
4125 
4126 		// release memory in IE
4127 		div = null;
4128 	})();
4129 }
4130 
4131 (function(){
4132 	var html = document.documentElement,
4133 		matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector,
4134 		pseudoWorks = false;
4135 
4136 	try {
4137 		// This should fail with an exception
4138 		// Gecko does not error, returns false instead
4139 		matches.call( document.documentElement, "[test!='']:sizzle" );
4140 	
4141 	} catch( pseudoError ) {
4142 		pseudoWorks = true;
4143 	}
4144 
4145 	if ( matches ) {
4146 		Sizzle.matchesSelector = function( node, expr ) {
4147 			// Make sure that attribute selectors are quoted
4148 			expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']");
4149 
4150 			if ( !Sizzle.isXML( node ) ) {
4151 				try { 
4152 					if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) {
4153 						return matches.call( node, expr );
4154 					}
4155 				} catch(e) {}
4156 			}
4157 
4158 			return Sizzle(expr, null, null, [node]).length > 0;
4159 		};
4160 	}
4161 })();
4162 
4163 (function(){
4164 	var div = document.createElement("div");
4165 
4166 	div.innerHTML = "<div class='test e'></div><div class='test'></div>";
4167 
4168 	// Opera can't find a second classname (in 9.6)
4169 	// Also, make sure that getElementsByClassName actually exists
4170 	if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) {
4171 		return;
4172 	}
4173 
4174 	// Safari caches class attributes, doesn't catch changes (in 3.2)
4175 	div.lastChild.className = "e";
4176 
4177 	if ( div.getElementsByClassName("e").length === 1 ) {
4178 		return;
4179 	}
4180 	
4181 	Expr.order.splice(1, 0, "CLASS");
4182 	Expr.find.CLASS = function( match, context, isXML ) {
4183 		if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
4184 			return context.getElementsByClassName(match[1]);
4185 		}
4186 	};
4187 
4188 	// release memory in IE
4189 	div = null;
4190 })();
4191 
4192 function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
4193 	for ( var i = 0, l = checkSet.length; i < l; i++ ) {
4194 		var elem = checkSet[i];
4195 
4196 		if ( elem ) {
4197 			var match = false;
4198 
4199 			elem = elem[dir];
4200 
4201 			while ( elem ) {
4202 				if ( elem.sizcache === doneName ) {
4203 					match = checkSet[elem.sizset];
4204 					break;
4205 				}
4206 
4207 				if ( elem.nodeType === 1 && !isXML ){
4208 					elem.sizcache = doneName;
4209 					elem.sizset = i;
4210 				}
4211 
4212 				if ( elem.nodeName.toLowerCase() === cur ) {
4213 					match = elem;
4214 					break;
4215 				}
4216 
4217 				elem = elem[dir];
4218 			}
4219 
4220 			checkSet[i] = match;
4221 		}
4222 	}
4223 }
4224 
4225 function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
4226 	for ( var i = 0, l = checkSet.length; i < l; i++ ) {
4227 		var elem = checkSet[i];
4228 
4229 		if ( elem ) {
4230 			var match = false;
4231 			
4232 			elem = elem[dir];
4233 
4234 			while ( elem ) {
4235 				if ( elem.sizcache === doneName ) {
4236 					match = checkSet[elem.sizset];
4237 					break;
4238 				}
4239 
4240 				if ( elem.nodeType === 1 ) {
4241 					if ( !isXML ) {
4242 						elem.sizcache = doneName;
4243 						elem.sizset = i;
4244 					}
4245 
4246 					if ( typeof cur !== "string" ) {
4247 						if ( elem === cur ) {
4248 							match = true;
4249 							break;
4250 						}
4251 
4252 					} else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
4253 						match = elem;
4254 						break;
4255 					}
4256 				}
4257 
4258 				elem = elem[dir];
4259 			}
4260 
4261 			checkSet[i] = match;
4262 		}
4263 	}
4264 }
4265 
4266 if ( document.documentElement.contains ) {
4267 	Sizzle.contains = function( a, b ) {
4268 		return a !== b && (a.contains ? a.contains(b) : true);
4269 	};
4270 
4271 } else if ( document.documentElement.compareDocumentPosition ) {
4272 	Sizzle.contains = function( a, b ) {
4273 		return !!(a.compareDocumentPosition(b) & 16);
4274 	};
4275 
4276 } else {
4277 	Sizzle.contains = function() {
4278 		return false;
4279 	};
4280 }
4281 
4282 Sizzle.isXML = function( elem ) {
4283 	// documentElement is verified for cases where it doesn't yet exist
4284 	// (such as loading iframes in IE - #4833) 
4285 	var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
4286 
4287 	return documentElement ? documentElement.nodeName !== "HTML" : false;
4288 };
4289 
4290 var posProcess = function( selector, context ) {
4291 	var match,
4292 		tmpSet = [],
4293 		later = "",
4294 		root = context.nodeType ? [context] : context;
4295 
4296 	// Position selectors must be done after the filter
4297 	// And so must :not(positional) so we move all PSEUDOs to the end
4298 	while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
4299 		later += match[0];
4300 		selector = selector.replace( Expr.match.PSEUDO, "" );
4301 	}
4302 
4303 	selector = Expr.relative[selector] ? selector + "*" : selector;
4304 
4305 	for ( var i = 0, l = root.length; i < l; i++ ) {
4306 		Sizzle( selector, root[i], tmpSet );
4307 	}
4308 
4309 	return Sizzle.filter( later, tmpSet );
4310 };
4311 
4312 // EXPOSE
4313 jQuery.find = Sizzle;
4314 jQuery.expr = Sizzle.selectors;
4315 jQuery.expr[":"] = jQuery.expr.filters;
4316 jQuery.unique = Sizzle.uniqueSort;
4317 jQuery.text = Sizzle.getText;
4318 jQuery.isXMLDoc = Sizzle.isXML;
4319 jQuery.contains = Sizzle.contains;
4320 
4321 
4322 })();
4323 
4324 
4325 var runtil = /Until$/,
4326 	rparentsprev = /^(?:parents|prevUntil|prevAll)/,
4327 	// Note: This RegExp should be improved, or likely pulled from Sizzle
4328 	rmultiselector = /,/,
4329 	isSimple = /^.[^:#\[\.,]*$/,
4330 	slice = Array.prototype.slice,
4331 	POS = jQuery.expr.match.POS;
4332 
4333 jQuery.fn.extend({
4334 	find: function( selector ) {
4335 		var ret = this.pushStack( "", "find", selector ),
4336 			length = 0;
4337 
4338 		for ( var i = 0, l = this.length; i < l; i++ ) {
4339 			length = ret.length;
4340 			jQuery.find( selector, this[i], ret );
4341 
4342 			if ( i > 0 ) {
4343 				// Make sure that the results are unique
4344 				for ( var n = length; n < ret.length; n++ ) {
4345 					for ( var r = 0; r < length; r++ ) {
4346 						if ( ret[r] === ret[n] ) {
4347 							ret.splice(n--, 1);
4348 							break;
4349 						}
4350 					}
4351 				}
4352 			}
4353 		}
4354 
4355 		return ret;
4356 	},
4357 
4358 	has: function( target ) {
4359 		var targets = jQuery( target );
4360 		return this.filter(function() {
4361 			for ( var i = 0, l = targets.length; i < l; i++ ) {
4362 				if ( jQuery.contains( this, targets[i] ) ) {
4363 					return true;
4364 				}
4365 			}
4366 		});
4367 	},
4368 
4369 	not: function( selector ) {
4370 		return this.pushStack( winnow(this, selector, false), "not", selector);
4371 	},
4372 
4373 	filter: function( selector ) {
4374 		return this.pushStack( winnow(this, selector, true), "filter", selector );
4375 	},
4376 	
4377 	is: function( selector ) {
4378 		return !!selector && jQuery.filter( selector, this ).length > 0;
4379 	},
4380 
4381 	closest: function( selectors, context ) {
4382 		var ret = [], i, l, cur = this[0];
4383 
4384 		if ( jQuery.isArray( selectors ) ) {
4385 			var match, selector,
4386 				matches = {},
4387 				level = 1;
4388 
4389 			if ( cur && selectors.length ) {
4390 				for ( i = 0, l = selectors.length; i < l; i++ ) {
4391 					selector = selectors[i];
4392 
4393 					if ( !matches[selector] ) {
4394 						matches[selector] = jQuery.expr.match.POS.test( selector ) ? 
4395 							jQuery( selector, context || this.context ) :
4396 							selector;
4397 					}
4398 				}
4399 
4400 				while ( cur && cur.ownerDocument && cur !== context ) {
4401 					for ( selector in matches ) {
4402 						match = matches[selector];
4403 
4404 						if ( match.jquery ? match.index(cur) > -1 : jQuery(cur).is(match) ) {
4405 							ret.push({ selector: selector, elem: cur, level: level });
4406 						}
4407 					}
4408 
4409 					cur = cur.parentNode;
4410 					level++;
4411 				}
4412 			}
4413 
4414 			return ret;
4415 		}
4416 
4417 		var pos = POS.test( selectors ) ? 
4418 			jQuery( selectors, context || this.context ) : null;
4419 
4420 		for ( i = 0, l = this.length; i < l; i++ ) {
4421 			cur = this[i];
4422 
4423 			while ( cur ) {
4424 				if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {
4425 					ret.push( cur );
4426 					break;
4427 
4428 				} else {
4429 					cur = cur.parentNode;
4430 					if ( !cur || !cur.ownerDocument || cur === context ) {
4431 						break;
4432 					}
4433 				}
4434 			}
4435 		}
4436 
4437 		ret = ret.length > 1 ? jQuery.unique(ret) : ret;
4438 		
4439 		return this.pushStack( ret, "closest", selectors );
4440 	},
4441 	
4442 	// Determine the position of an element within
4443 	// the matched set of elements
4444 	index: function( elem ) {
4445 		if ( !elem || typeof elem === "string" ) {
4446 			return jQuery.inArray( this[0],
4447 				// If it receives a string, the selector is used
4448 				// If it receives nothing, the siblings are used
4449 				elem ? jQuery( elem ) : this.parent().children() );
4450 		}
4451 		// Locate the position of the desired element
4452 		return jQuery.inArray(
4453 			// If it receives a jQuery object, the first element is used
4454 			elem.jquery ? elem[0] : elem, this );
4455 	},
4456 
4457 	add: function( selector, context ) {
4458 		var set = typeof selector === "string" ?
4459 				jQuery( selector, context || this.context ) :
4460 				jQuery.makeArray( selector ),
4461 			all = jQuery.merge( this.get(), set );
4462 
4463 		return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?
4464 			all :
4465 			jQuery.unique( all ) );
4466 	},
4467 
4468 	andSelf: function() {
4469 		return this.add( this.prevObject );
4470 	}
4471 });
4472 
4473 // A painfully simple check to see if an element is disconnected
4474 // from a document (should be improved, where feasible).
4475 function isDisconnected( node ) {
4476 	return !node || !node.parentNode || node.parentNode.nodeType === 11;
4477 }
4478 
4479 jQuery.each({
4480 	parent: function( elem ) {
4481 		var parent = elem.parentNode;
4482 		return parent && parent.nodeType !== 11 ? parent : null;
4483 	},
4484 	parents: function( elem ) {
4485 		return jQuery.dir( elem, "parentNode" );
4486 	},
4487 	parentsUntil: function( elem, i, until ) {
4488 		return jQuery.dir( elem, "parentNode", until );
4489 	},
4490 	next: function( elem ) {
4491 		return jQuery.nth( elem, 2, "nextSibling" );
4492 	},
4493 	prev: function( elem ) {
4494 		return jQuery.nth( elem, 2, "previousSibling" );
4495 	},
4496 	nextAll: function( elem ) {
4497 		return jQuery.dir( elem, "nextSibling" );
4498 	},
4499 	prevAll: function( elem ) {
4500 		return jQuery.dir( elem, "previousSibling" );
4501 	},
4502 	nextUntil: function( elem, i, until ) {
4503 		return jQuery.dir( elem, "nextSibling", until );
4504 	},
4505 	prevUntil: function( elem, i, until ) {
4506 		return jQuery.dir( elem, "previousSibling", until );
4507 	},
4508 	siblings: function( elem ) {
4509 		return jQuery.sibling( elem.parentNode.firstChild, elem );
4510 	},
4511 	children: function( elem ) {
4512 		return jQuery.sibling( elem.firstChild );
4513 	},
4514 	contents: function( elem ) {
4515 		return jQuery.nodeName( elem, "iframe" ) ?
4516 			elem.contentDocument || elem.contentWindow.document :
4517 			jQuery.makeArray( elem.childNodes );
4518 	}
4519 }, function( name, fn ) {
4520 	jQuery.fn[ name ] = function( until, selector ) {
4521 		var ret = jQuery.map( this, fn, until );
4522 		
4523 		if ( !runtil.test( name ) ) {
4524 			selector = until;
4525 		}
4526 
4527 		if ( selector && typeof selector === "string" ) {
4528 			ret = jQuery.filter( selector, ret );
4529 		}
4530 
4531 		ret = this.length > 1 ? jQuery.unique( ret ) : ret;
4532 
4533 		if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) {
4534 			ret = ret.reverse();
4535 		}
4536 
4537 		return this.pushStack( ret, name, slice.call(arguments).join(",") );
4538 	};
4539 });
4540 
4541 jQuery.extend({
4542 	filter: function( expr, elems, not ) {
4543 		if ( not ) {
4544 			expr = ":not(" + expr + ")";
4545 		}
4546 
4547 		return elems.length === 1 ?
4548 			jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :
4549 			jQuery.find.matches(expr, elems);
4550 	},
4551 	
4552 	dir: function( elem, dir, until ) {
4553 		var matched = [],
4554 			cur = elem[ dir ];
4555 
4556 		while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
4557 			if ( cur.nodeType === 1 ) {
4558 				matched.push( cur );
4559 			}
4560 			cur = cur[dir];
4561 		}
4562 		return matched;
4563 	},
4564 
4565 	nth: function( cur, result, dir, elem ) {
4566 		result = result || 1;
4567 		var num = 0;
4568 
4569 		for ( ; cur; cur = cur[dir] ) {
4570 			if ( cur.nodeType === 1 && ++num === result ) {
4571 				break;
4572 			}
4573 		}
4574 
4575 		return cur;
4576 	},
4577 
4578 	sibling: function( n, elem ) {
4579 		var r = [];
4580 
4581 		for ( ; n; n = n.nextSibling ) {
4582 			if ( n.nodeType === 1 && n !== elem ) {
4583 				r.push( n );
4584 			}
4585 		}
4586 
4587 		return r;
4588 	}
4589 });
4590 
4591 // Implement the identical functionality for filter and not
4592 function winnow( elements, qualifier, keep ) {
4593 	if ( jQuery.isFunction( qualifier ) ) {
4594 		return jQuery.grep(elements, function( elem, i ) {
4595 			var retVal = !!qualifier.call( elem, i, elem );
4596 			return retVal === keep;
4597 		});
4598 
4599 	} else if ( qualifier.nodeType ) {
4600 		return jQuery.grep(elements, function( elem, i ) {
4601 			return (elem === qualifier) === keep;
4602 		});
4603 
4604 	} else if ( typeof qualifier === "string" ) {
4605 		var filtered = jQuery.grep(elements, function( elem ) {
4606 			return elem.nodeType === 1;
4607 		});
4608 
4609 		if ( isSimple.test( qualifier ) ) {
4610 			return jQuery.filter(qualifier, filtered, !keep);
4611 		} else {
4612 			qualifier = jQuery.filter( qualifier, filtered );
4613 		}
4614 	}
4615 
4616 	return jQuery.grep(elements, function( elem, i ) {
4617 		return (jQuery.inArray( elem, qualifier ) >= 0) === keep;
4618 	});
4619 }
4620 
4621 
4622 
4623 
4624 var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g,
4625 	rleadingWhitespace = /^\s+/,
4626 	rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,
4627 	rtagName = /<([\w:]+)/,
4628 	rtbody = /<tbody/i,
4629 	rhtml = /<|&#?\w+;/,
4630 	rnocache = /<(?:script|object|embed|option|style)/i,
4631 	// checked="checked" or checked (html5)
4632 	rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
4633 	raction = /\=([^="'>\s]+\/)>/g,
4634 	wrapMap = {
4635 		option: [ 1, "<select multiple='multiple'>", "</select>" ],
4636 		legend: [ 1, "<fieldset>", "</fieldset>" ],
4637 		thead: [ 1, "<table>", "</table>" ],
4638 		tr: [ 2, "<table><tbody>", "</tbody></table>" ],
4639 		td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
4640 		col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
4641 		area: [ 1, "<map>", "</map>" ],
4642 		_default: [ 0, "", "" ]
4643 	};
4644 
4645 wrapMap.optgroup = wrapMap.option;
4646 wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
4647 wrapMap.th = wrapMap.td;
4648 
4649 // IE can't serialize <link> and <script> tags normally
4650 if ( !jQuery.support.htmlSerialize ) {
4651 	wrapMap._default = [ 1, "div<div>", "</div>" ];
4652 }
4653 
4654 jQuery.fn.extend({
4655 	text: function( text ) {
4656 		if ( jQuery.isFunction(text) ) {
4657 			return this.each(function(i) {
4658 				var self = jQuery( this );
4659 
4660 				self.text( text.call(this, i, self.text()) );
4661 			});
4662 		}
4663 
4664 		if ( typeof text !== "object" && text !== undefined ) {
4665 			return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
4666 		}
4667 
4668 		return jQuery.text( this );
4669 	},
4670 
4671 	wrapAll: function( html ) {
4672 		if ( jQuery.isFunction( html ) ) {
4673 			return this.each(function(i) {
4674 				jQuery(this).wrapAll( html.call(this, i) );
4675 			});
4676 		}
4677 
4678 		if ( this[0] ) {
4679 			// The elements to wrap the target around
4680 			var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
4681 
4682 			if ( this[0].parentNode ) {
4683 				wrap.insertBefore( this[0] );
4684 			}
4685 
4686 			wrap.map(function() {
4687 				var elem = this;
4688 
4689 				while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
4690 					elem = elem.firstChild;
4691 				}
4692 
4693 				return elem;
4694 			}).append(this);
4695 		}
4696 
4697 		return this;
4698 	},
4699 
4700 	wrapInner: function( html ) {
4701 		if ( jQuery.isFunction( html ) ) {
4702 			return this.each(function(i) {
4703 				jQuery(this).wrapInner( html.call(this, i) );
4704 			});
4705 		}
4706 
4707 		return this.each(function() {
4708 			var self = jQuery( this ),
4709 				contents = self.contents();
4710 
4711 			if ( contents.length ) {
4712 				contents.wrapAll( html );
4713 
4714 			} else {
4715 				self.append( html );
4716 			}
4717 		});
4718 	},
4719 
4720 	wrap: function( html ) {
4721 		return this.each(function() {
4722 			jQuery( this ).wrapAll( html );
4723 		});
4724 	},
4725 
4726 	unwrap: function() {
4727 		return this.parent().each(function() {
4728 			if ( !jQuery.nodeName( this, "body" ) ) {
4729 				jQuery( this ).replaceWith( this.childNodes );
4730 			}
4731 		}).end();
4732 	},
4733 
4734 	append: function() {
4735 		return this.domManip(arguments, true, function( elem ) {
4736 			if ( this.nodeType === 1 ) {
4737 				this.appendChild( elem );
4738 			}
4739 		});
4740 	},
4741 
4742 	prepend: function() {
4743 		return this.domManip(arguments, true, function( elem ) {
4744 			if ( this.nodeType === 1 ) {
4745 				this.insertBefore( elem, this.firstChild );
4746 			}
4747 		});
4748 	},
4749 
4750 	before: function() {
4751 		if ( this[0] && this[0].parentNode ) {
4752 			return this.domManip(arguments, false, function( elem ) {
4753 				this.parentNode.insertBefore( elem, this );
4754 			});
4755 		} else if ( arguments.length ) {
4756 			var set = jQuery(arguments[0]);
4757 			set.push.apply( set, this.toArray() );
4758 			return this.pushStack( set, "before", arguments );
4759 		}
4760 	},
4761 
4762 	after: function() {
4763 		if ( this[0] && this[0].parentNode ) {
4764 			return this.domManip(arguments, false, function( elem ) {
4765 				this.parentNode.insertBefore( elem, this.nextSibling );
4766 			});
4767 		} else if ( arguments.length ) {
4768 			var set = this.pushStack( this, "after", arguments );
4769 			set.push.apply( set, jQuery(arguments[0]).toArray() );
4770 			return set;
4771 		}
4772 	},
4773 	
4774 	// keepData is for internal use only--do not document
4775 	remove: function( selector, keepData ) {
4776 		for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
4777 			if ( !selector || jQuery.filter( selector, [ elem ] ).length ) {
4778 				if ( !keepData && elem.nodeType === 1 ) {
4779 					jQuery.cleanData( elem.getElementsByTagName("*") );
4780 					jQuery.cleanData( [ elem ] );
4781 				}
4782 
4783 				if ( elem.parentNode ) {
4784 					 elem.parentNode.removeChild( elem );
4785 				}
4786 			}
4787 		}
4788 		
4789 		return this;
4790 	},
4791 
4792 	empty: function() {
4793 		for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
4794 			// Remove element nodes and prevent memory leaks
4795 			if ( elem.nodeType === 1 ) {
4796 				jQuery.cleanData( elem.getElementsByTagName("*") );
4797 			}
4798 
4799 			// Remove any remaining nodes
4800 			while ( elem.firstChild ) {
4801 				elem.removeChild( elem.firstChild );
4802 			}
4803 		}
4804 		
4805 		return this;
4806 	},
4807 
4808 	clone: function( events ) {
4809 		// Do the clone
4810 		var ret = this.map(function() {
4811 			if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) {
4812 				// IE copies events bound via attachEvent when
4813 				// using cloneNode. Calling detachEvent on the
4814 				// clone will also remove the events from the orignal
4815 				// In order to get around this, we use innerHTML.
4816 				// Unfortunately, this means some modifications to
4817 				// attributes in IE that are actually only stored
4818 				// as properties will not be copied (such as the
4819 				// the name attribute on an input).
4820 				var html = this.outerHTML,
4821 					ownerDocument = this.ownerDocument;
4822 
4823 				if ( !html ) {
4824 					var div = ownerDocument.createElement("div");
4825 					div.appendChild( this.cloneNode(true) );
4826 					html = div.innerHTML;
4827 				}
4828 
4829 				return jQuery.clean([html.replace(rinlinejQuery, "")
4830 					// Handle the case in IE 8 where action=/test/> self-closes a tag
4831 					.replace(raction, '="$1">')
4832 					.replace(rleadingWhitespace, "")], ownerDocument)[0];
4833 			} else {
4834 				return this.cloneNode(true);
4835 			}
4836 		});
4837 
4838 		// Copy the events from the original to the clone
4839 		if ( events === true ) {
4840 			cloneCopyEvent( this, ret );
4841 			cloneCopyEvent( this.find("*"), ret.find("*") );
4842 		}
4843 
4844 		// Return the cloned set
4845 		return ret;
4846 	},
4847 
4848 	html: function( value ) {
4849 		if ( value === undefined ) {
4850 			return this[0] && this[0].nodeType === 1 ?
4851 				this[0].innerHTML.replace(rinlinejQuery, "") :
4852 				null;
4853 
4854 		// See if we can take a shortcut and just use innerHTML
4855 		} else if ( typeof value === "string" && !rnocache.test( value ) &&
4856 			(jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) &&
4857 			!wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) {
4858 
4859 			value = value.replace(rxhtmlTag, "<$1></$2>");
4860 
4861 			try {
4862 				for ( var i = 0, l = this.length; i < l; i++ ) {
4863 					// Remove element nodes and prevent memory leaks
4864 					if ( this[i].nodeType === 1 ) {
4865 						jQuery.cleanData( this[i].getElementsByTagName("*") );
4866 						this[i].innerHTML = value;
4867 					}
4868 				}
4869 
4870 			// If using innerHTML throws an exception, use the fallback method
4871 			} catch(e) {
4872 				this.empty().append( value );
4873 			}
4874 
4875 		} else if ( jQuery.isFunction( value ) ) {
4876 			this.each(function(i){
4877 				var self = jQuery( this );
4878 
4879 				self.html( value.call(this, i, self.html()) );
4880 			});
4881 
4882 		} else {
4883 			this.empty().append( value );
4884 		}
4885 
4886 		return this;
4887 	},
4888 
4889 	replaceWith: function( value ) {
4890 		if ( this[0] && this[0].parentNode ) {
4891 			// Make sure that the elements are removed from the DOM before they are inserted
4892 			// this can help fix replacing a parent with child elements
4893 			if ( jQuery.isFunction( value ) ) {
4894 				return this.each(function(i) {
4895 					var self = jQuery(this), old = self.html();
4896 					self.replaceWith( value.call( this, i, old ) );
4897 				});
4898 			}
4899 
4900 			if ( typeof value !== "string" ) {
4901 				value = jQuery( value ).detach();
4902 			}
4903 
4904 			return this.each(function() {
4905 				var next = this.nextSibling,
4906 					parent = this.parentNode;
4907 
4908 				jQuery( this ).remove();
4909 
4910 				if ( next ) {
4911 					jQuery(next).before( value );
4912 				} else {
4913 					jQuery(parent).append( value );
4914 				}
4915 			});
4916 		} else {
4917 			return this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value );
4918 		}
4919 	},
4920 
4921 	detach: function( selector ) {
4922 		return this.remove( selector, true );
4923 	},
4924 
4925 	domManip: function( args, table, callback ) {
4926 		var results, first, fragment, parent,
4927 			value = args[0],
4928 			scripts = [];
4929 
4930 		// We can't cloneNode fragments that contain checked, in WebKit
4931 		if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) {
4932 			return this.each(function() {
4933 				jQuery(this).domManip( args, table, callback, true );
4934 			});
4935 		}
4936 
4937 		if ( jQuery.isFunction(value) ) {
4938 			return this.each(function(i) {
4939 				var self = jQuery(this);
4940 				args[0] = value.call(this, i, table ? self.html() : undefined);
4941 				self.domManip( args, table, callback );
4942 			});
4943 		}
4944 
4945 		if ( this[0] ) {
4946 			parent = value && value.parentNode;
4947 
4948 			// If we're in a fragment, just use that instead of building a new one
4949 			if ( jQuery.support.parentNode && parent && parent.nodeType === 11 && parent.childNodes.length === this.length ) {
4950 				results = { fragment: parent };
4951 
4952 			} else {
4953 				results = jQuery.buildFragment( args, this, scripts );
4954 			}
4955 			
4956 			fragment = results.fragment;
4957 			
4958 			if ( fragment.childNodes.length === 1 ) {
4959 				first = fragment = fragment.firstChild;
4960 			} else {
4961 				first = fragment.firstChild;
4962 			}
4963 
4964 			if ( first ) {
4965 				table = table && jQuery.nodeName( first, "tr" );
4966 
4967 				for ( var i = 0, l = this.length; i < l; i++ ) {
4968 					callback.call(
4969 						table ?
4970 							root(this[i], first) :
4971 							this[i],
4972 						i > 0 || results.cacheable || this.length > 1  ?
4973 							fragment.cloneNode(true) :
4974 							fragment
4975 					);
4976 				}
4977 			}
4978 
4979 			if ( scripts.length ) {
4980 				jQuery.each( scripts, evalScript );
4981 			}
4982 		}
4983 
4984 		return this;
4985 	}
4986 });
4987 
4988 function root( elem, cur ) {
4989 	return jQuery.nodeName(elem, "table") ?
4990 		(elem.getElementsByTagName("tbody")[0] ||
4991 		elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
4992 		elem;
4993 }
4994 
4995 function cloneCopyEvent(orig, ret) {
4996 	var i = 0;
4997 
4998 	ret.each(function() {
4999 		if ( this.nodeName !== (orig[i] && orig[i].nodeName) ) {
5000 			return;
5001 		}
5002 
5003 		var oldData = jQuery.data( orig[i++] ),
5004 			curData = jQuery.data( this, oldData ),
5005 			events = oldData && oldData.events;
5006 
5007 		if ( events ) {
5008 			delete curData.handle;
5009 			curData.events = {};
5010 
5011 			for ( var type in events ) {
5012 				for ( var handler in events[ type ] ) {
5013 					jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data );
5014 				}
5015 			}
5016 		}
5017 	});
5018 }
5019 
5020 jQuery.buildFragment = function( args, nodes, scripts ) {
5021 	var fragment, cacheable, cacheresults,
5022 		doc = (nodes && nodes[0] ? nodes[0].ownerDocument || nodes[0] : document);
5023 
5024 	// Only cache "small" (1/2 KB) strings that are associated with the main document
5025 	// Cloning options loses the selected state, so don't cache them
5026 	// IE 6 doesn't like it when you put <object> or <embed> elements in a fragment
5027 	// Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache
5028 	if ( args.length === 1 && typeof args[0] === "string" && args[0].length < 512 && doc === document &&
5029 		!rnocache.test( args[0] ) && (jQuery.support.checkClone || !rchecked.test( args[0] )) ) {
5030 
5031 		cacheable = true;
5032 		cacheresults = jQuery.fragments[ args[0] ];
5033 		if ( cacheresults ) {
5034 			if ( cacheresults !== 1 ) {
5035 				fragment = cacheresults;
5036 			}
5037 		}
5038 	}
5039 
5040 	if ( !fragment ) {
5041 		fragment = doc.createDocumentFragment();
5042 		jQuery.clean( args, doc, fragment, scripts );
5043 	}
5044 
5045 	if ( cacheable ) {
5046 		jQuery.fragments[ args[0] ] = cacheresults ? fragment : 1;
5047 	}
5048 
5049 	return { fragment: fragment, cacheable: cacheable };
5050 };
5051 
5052 jQuery.fragments = {};
5053 
5054 jQuery.each({
5055 	appendTo: "append",
5056 	prependTo: "prepend",
5057 	insertBefore: "before",
5058 	insertAfter: "after",
5059 	replaceAll: "replaceWith"
5060 }, function( name, original ) {
5061 	jQuery.fn[ name ] = function( selector ) {
5062 		var ret = [],
5063 			insert = jQuery( selector ),
5064 			parent = this.length === 1 && this[0].parentNode;
5065 		
5066 		if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) {
5067 			insert[ original ]( this[0] );
5068 			return this;
5069 			
5070 		} else {
5071 			for ( var i = 0, l = insert.length; i < l; i++ ) {
5072 				var elems = (i > 0 ? this.clone(true) : this).get();
5073 				jQuery( insert[i] )[ original ]( elems );
5074 				ret = ret.concat( elems );
5075 			}
5076 		
5077 			return this.pushStack( ret, name, insert.selector );
5078 		}
5079 	};
5080 });
5081 
5082 jQuery.extend({
5083 	clean: function( elems, context, fragment, scripts ) {
5084 		context = context || document;
5085 
5086 		// !context.createElement fails in IE with an error but returns typeof 'object'
5087 		if ( typeof context.createElement === "undefined" ) {
5088 			context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
5089 		}
5090 
5091 		var ret = [];
5092 
5093 		for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
5094 			if ( typeof elem === "number" ) {
5095 				elem += "";
5096 			}
5097 
5098 			if ( !elem ) {
5099 				continue;
5100 			}
5101 
5102 			// Convert html string into DOM nodes
5103 			if ( typeof elem === "string" && !rhtml.test( elem ) ) {
5104 				elem = context.createTextNode( elem );
5105 
5106 			} else if ( typeof elem === "string" ) {
5107 				// Fix "XHTML"-style tags in all browsers
5108 				elem = elem.replace(rxhtmlTag, "<$1></$2>");
5109 
5110 				// Trim whitespace, otherwise indexOf won't work as expected
5111 				var tag = (rtagName.exec( elem ) || ["", ""])[1].toLowerCase(),
5112 					wrap = wrapMap[ tag ] || wrapMap._default,
5113 					depth = wrap[0],
5114 					div = context.createElement("div");
5115 
5116 				// Go to html and back, then peel off extra wrappers
5117 				div.innerHTML = wrap[1] + elem + wrap[2];
5118 
5119 				// Move to the right depth
5120 				while ( depth-- ) {
5121 					div = div.lastChild;
5122 				}
5123 
5124 				// Remove IE's autoinserted <tbody> from table fragments
5125 				if ( !jQuery.support.tbody ) {
5126 
5127 					// String was a <table>, *may* have spurious <tbody>
5128 					var hasBody = rtbody.test(elem),
5129 						tbody = tag === "table" && !hasBody ?
5130 							div.firstChild && div.firstChild.childNodes :
5131 
5132 							// String was a bare <thead> or <tfoot>
5133 							wrap[1] === "<table>" && !hasBody ?
5134 								div.childNodes :
5135 								[];
5136 
5137 					for ( var j = tbody.length - 1; j >= 0 ; --j ) {
5138 						if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) {
5139 							tbody[ j ].parentNode.removeChild( tbody[ j ] );
5140 						}
5141 					}
5142 
5143 				}
5144 
5145 				// IE completely kills leading whitespace when innerHTML is used
5146 				if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
5147 					div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );
5148 				}
5149 
5150 				elem = div.childNodes;
5151 			}
5152 
5153 			if ( elem.nodeType ) {
5154 				ret.push( elem );
5155 			} else {
5156 				ret = jQuery.merge( ret, elem );
5157 			}
5158 		}
5159 
5160 		if ( fragment ) {
5161 			for ( i = 0; ret[i]; i++ ) {
5162 				if ( scripts && jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
5163 					scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
5164 				
5165 				} else {
5166 					if ( ret[i].nodeType === 1 ) {
5167 						ret.splice.apply( ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))) );
5168 					}
5169 					fragment.appendChild( ret[i] );
5170 				}
5171 			}
5172 		}
5173 
5174 		return ret;
5175 	},
5176 	
5177 	cleanData: function( elems ) {
5178 		var data, id, cache = jQuery.cache,
5179 			special = jQuery.event.special,
5180 			deleteExpando = jQuery.support.deleteExpando;
5181 		
5182 		for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
5183 			if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
5184 				continue;
5185 			}
5186 
5187 			id = elem[ jQuery.expando ];
5188 			
5189 			if ( id ) {
5190 				data = cache[ id ];
5191 				
5192 				if ( data && data.events ) {
5193 					for ( var type in data.events ) {
5194 						if ( special[ type ] ) {
5195 							jQuery.event.remove( elem, type );
5196 
5197 						} else {
5198 							jQuery.removeEvent( elem, type, data.handle );
5199 						}
5200 					}
5201 				}
5202 				
5203 				if ( deleteExpando ) {
5204 					delete elem[ jQuery.expando ];
5205 
5206 				} else if ( elem.removeAttribute ) {
5207 					elem.removeAttribute( jQuery.expando );
5208 				}
5209 				
5210 				delete cache[ id ];
5211 			}
5212 		}
5213 	}
5214 });
5215 
5216 function evalScript( i, elem ) {
5217 	if ( elem.src ) {
5218 		jQuery.ajax({
5219 			url: elem.src,
5220 			async: false,
5221 			dataType: "script"
5222 		});
5223 	} else {
5224 		jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
5225 	}
5226 
5227 	if ( elem.parentNode ) {
5228 		elem.parentNode.removeChild( elem );
5229 	}
5230 }
5231 
5232 
5233 
5234 
5235 var ralpha = /alpha\([^)]*\)/i,
5236 	ropacity = /opacity=([^)]*)/,
5237 	rdashAlpha = /-([a-z])/ig,
5238 	rupper = /([A-Z])/g,
5239 	rnumpx = /^-?\d+(?:px)?$/i,
5240 	rnum = /^-?\d/,
5241 
5242 	cssShow = { position: "absolute", visibility: "hidden", display: "block" },
5243 	cssWidth = [ "Left", "Right" ],
5244 	cssHeight = [ "Top", "Bottom" ],
5245 	curCSS,
5246 
5247 	getComputedStyle,
5248 	currentStyle,
5249 
5250 	fcamelCase = function( all, letter ) {
5251 		return letter.toUpperCase();
5252 	};
5253 
5254 jQuery.fn.css = function( name, value ) {
5255 	// Setting 'undefined' is a no-op
5256 	if ( arguments.length === 2 && value === undefined ) {
5257 		return this;
5258 	}
5259 
5260 	return jQuery.access( this, name, value, true, function( elem, name, value ) {
5261 		return value !== undefined ?
5262 			jQuery.style( elem, name, value ) :
5263 			jQuery.css( elem, name );
5264 	});
5265 };
5266 
5267 jQuery.extend({
5268 	// Add in style property hooks for overriding the default
5269 	// behavior of getting and setting a style property
5270 	cssHooks: {
5271 		opacity: {
5272 			get: function( elem, computed ) {
5273 				if ( computed ) {
5274 					// We should always get a number back from opacity
5275 					var ret = curCSS( elem, "opacity", "opacity" );
5276 					return ret === "" ? "1" : ret;
5277 
5278 				} else {
5279 					return elem.style.opacity;
5280 				}
5281 			}
5282 		}
5283 	},
5284 
5285 	// Exclude the following css properties to add px
5286 	cssNumber: {
5287 		"zIndex": true,
5288 		"fontWeight": true,
5289 		"opacity": true,
5290 		"zoom": true,
5291 		"lineHeight": true
5292 	},
5293 
5294 	// Add in properties whose names you wish to fix before
5295 	// setting or getting the value
5296 	cssProps: {
5297 		// normalize float css property
5298 		"float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat"
5299 	},
5300 
5301 	// Get and set the style property on a DOM Node
5302 	style: function( elem, name, value, extra ) {
5303 		// Don't set styles on text and comment nodes
5304 		if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
5305 			return;
5306 		}
5307 
5308 		// Make sure that we're working with the right name
5309 		var ret, origName = jQuery.camelCase( name ),
5310 			style = elem.style, hooks = jQuery.cssHooks[ origName ];
5311 
5312 		name = jQuery.cssProps[ origName ] || origName;
5313 
5314 		// Check if we're setting a value
5315 		if ( value !== undefined ) {
5316 			// Make sure that NaN and null values aren't set. See: #7116
5317 			if ( typeof value === "number" && isNaN( value ) || value == null ) {
5318 				return;
5319 			}
5320 
5321 			// If a number was passed in, add 'px' to the (except for certain CSS properties)
5322 			if ( typeof value === "number" && !jQuery.cssNumber[ origName ] ) {
5323 				value += "px";
5324 			}
5325 
5326 			// If a hook was provided, use that value, otherwise just set the specified value
5327 			if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value )) !== undefined ) {
5328 				// Wrapped to prevent IE from throwing errors when 'invalid' values are provided
5329 				// Fixes bug #5509
5330 				try {
5331 					style[ name ] = value;
5332 				} catch(e) {}
5333 			}
5334 
5335 		} else {
5336 			// If a hook was provided get the non-computed value from there
5337 			if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
5338 				return ret;
5339 			}
5340 
5341 			// Otherwise just get the value from the style object
5342 			return style[ name ];
5343 		}
5344 	},
5345 
5346 	css: function( elem, name, extra ) {
5347 		// Make sure that we're working with the right name
5348 		var ret, origName = jQuery.camelCase( name ),
5349 			hooks = jQuery.cssHooks[ origName ];
5350 
5351 		name = jQuery.cssProps[ origName ] || origName;
5352 
5353 		// If a hook was provided get the computed value from there
5354 		if ( hooks && "get" in hooks && (ret = hooks.get( elem, true, extra )) !== undefined ) {
5355 			return ret;
5356 
5357 		// Otherwise, if a way to get the computed value exists, use that
5358 		} else if ( curCSS ) {
5359 			return curCSS( elem, name, origName );
5360 		}
5361 	},
5362 
5363 	// A method for quickly swapping in/out CSS properties to get correct calculations
5364 	swap: function( elem, options, callback ) {
5365 		var old = {};
5366 
5367 		// Remember the old values, and insert the new ones
5368 		for ( var name in options ) {
5369 			old[ name ] = elem.style[ name ];
5370 			elem.style[ name ] = options[ name ];
5371 		}
5372 
5373 		callback.call( elem );
5374 
5375 		// Revert the old values
5376 		for ( name in options ) {
5377 			elem.style[ name ] = old[ name ];
5378 		}
5379 	},
5380 
5381 	camelCase: function( string ) {
5382 		return string.replace( rdashAlpha, fcamelCase );
5383 	}
5384 });
5385 
5386 // DEPRECATED, Use jQuery.css() instead
5387 jQuery.curCSS = jQuery.css;
5388 
5389 jQuery.each(["height", "width"], function( i, name ) {
5390 	jQuery.cssHooks[ name ] = {
5391 		get: function( elem, computed, extra ) {
5392 			var val;
5393 
5394 			if ( computed ) {
5395 				if ( elem.offsetWidth !== 0 ) {
5396 					val = getWH( elem, name, extra );
5397 
5398 				} else {
5399 					jQuery.swap( elem, cssShow, function() {
5400 						val = getWH( elem, name, extra );
5401 					});
5402 				}
5403 
5404 				if ( val <= 0 ) {
5405 					val = curCSS( elem, name, name );
5406 
5407 					if ( val === "0px" && currentStyle ) {
5408 						val = currentStyle( elem, name, name );
5409 					}
5410 
5411 					if ( val != null ) {
5412 						// Should return "auto" instead of 0, use 0 for
5413 						// temporary backwards-compat
5414 						return val === "" || val === "auto" ? "0px" : val;
5415 					}
5416 				}
5417 
5418 				if ( val < 0 || val == null ) {
5419 					val = elem.style[ name ];
5420 
5421 					// Should return "auto" instead of 0, use 0 for
5422 					// temporary backwards-compat
5423 					return val === "" || val === "auto" ? "0px" : val;
5424 				}
5425 
5426 				return typeof val === "string" ? val : val + "px";
5427 			}
5428 		},
5429 
5430 		set: function( elem, value ) {
5431 			if ( rnumpx.test( value ) ) {
5432 				// ignore negative width and height values #1599
5433 				value = parseFloat(value);
5434 
5435 				if ( value >= 0 ) {
5436 					return value + "px";
5437 				}
5438 
5439 			} else {
5440 				return value;
5441 			}
5442 		}
5443 	};
5444 });
5445 
5446 if ( !jQuery.support.opacity ) {
5447 	jQuery.cssHooks.opacity = {
5448 		get: function( elem, computed ) {
5449 			// IE uses filters for opacity
5450 			return ropacity.test((computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "") ?
5451 				(parseFloat(RegExp.$1) / 100) + "" :
5452 				computed ? "1" : "";
5453 		},
5454 
5455 		set: function( elem, value ) {
5456 			var style = elem.style;
5457 
5458 			// IE has trouble with opacity if it does not have layout
5459 			// Force it by setting the zoom level
5460 			style.zoom = 1;
5461 
5462 			// Set the alpha filter to set the opacity
5463 			var opacity = jQuery.isNaN(value) ?
5464 				"" :
5465 				"alpha(opacity=" + value * 100 + ")",
5466 				filter = style.filter || "";
5467 
5468 			style.filter = ralpha.test(filter) ?
5469 				filter.replace(ralpha, opacity) :
5470 				style.filter + ' ' + opacity;
5471 		}
5472 	};
5473 }
5474 
5475 if ( document.defaultView && document.defaultView.getComputedStyle ) {
5476 	getComputedStyle = function( elem, newName, name ) {
5477 		var ret, defaultView, computedStyle;
5478 
5479 		name = name.replace( rupper, "-$1" ).toLowerCase();
5480 
5481 		if ( !(defaultView = elem.ownerDocument.defaultView) ) {
5482 			return undefined;
5483 		}
5484 
5485 		if ( (computedStyle = defaultView.getComputedStyle( elem, null )) ) {
5486 			ret = computedStyle.getPropertyValue( name );
5487 			if ( ret === "" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) {
5488 				ret = jQuery.style( elem, name );
5489 			}
5490 		}
5491 
5492 		return ret;
5493 	};
5494 }
5495 
5496 if ( document.documentElement.currentStyle ) {
5497 	currentStyle = function( elem, name ) {
5498 		var left, rsLeft,
5499 			ret = elem.currentStyle && elem.currentStyle[ name ],
5500 			style = elem.style;
5501 
5502 		// From the awesome hack by Dean Edwards
5503 		// http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
5504 
5505 		// If we're not dealing with a regular pixel number
5506 		// but a number that has a weird ending, we need to convert it to pixels
5507 		if ( !rnumpx.test( ret ) && rnum.test( ret ) ) {
5508 			// Remember the original values
5509 			left = style.left;
5510 			rsLeft = elem.runtimeStyle.left;
5511 
5512 			// Put in the new values to get a computed value out
5513 			elem.runtimeStyle.left = elem.currentStyle.left;
5514 			style.left = name === "fontSize" ? "1em" : (ret || 0);
5515 			ret = style.pixelLeft + "px";
5516 
5517 			// Revert the changed values
5518 			style.left = left;
5519 			elem.runtimeStyle.left = rsLeft;
5520 		}
5521 
5522 		return ret === "" ? "auto" : ret;
5523 	};
5524 }
5525 
5526 curCSS = getComputedStyle || currentStyle;
5527 
5528 function getWH( elem, name, extra ) {
5529 	var which = name === "width" ? cssWidth : cssHeight,
5530 		val = name === "width" ? elem.offsetWidth : elem.offsetHeight;
5531 
5532 	if ( extra === "border" ) {
5533 		return val;
5534 	}
5535 
5536 	jQuery.each( which, function() {
5537 		if ( !extra ) {
5538 			val -= parseFloat(jQuery.css( elem, "padding" + this )) || 0;
5539 		}
5540 
5541 		if ( extra === "margin" ) {
5542 			val += parseFloat(jQuery.css( elem, "margin" + this )) || 0;
5543 
5544 		} else {
5545 			val -= parseFloat(jQuery.css( elem, "border" + this + "Width" )) || 0;
5546 		}
5547 	});
5548 
5549 	return val;
5550 }
5551 
5552 if ( jQuery.expr && jQuery.expr.filters ) {
5553 	jQuery.expr.filters.hidden = function( elem ) {
5554 		var width = elem.offsetWidth,
5555 			height = elem.offsetHeight;
5556 
5557 		return (width === 0 && height === 0) || (!jQuery.support.reliableHiddenOffsets && (elem.style.display || jQuery.css( elem, "display" )) === "none");
5558 	};
5559 
5560 	jQuery.expr.filters.visible = function( elem ) {
5561 		return !jQuery.expr.filters.hidden( elem );
5562 	};
5563 }
5564 
5565 
5566 
5567 
5568 var jsc = jQuery.now(),
5569 	rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
5570 	rselectTextarea = /^(?:select|textarea)/i,
5571 	rinput = /^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,
5572 	rnoContent = /^(?:GET|HEAD)$/,
5573 	rbracket = /\[\]$/,
5574 	jsre = /\=\?(&|$)/,
5575 	rquery = /\?/,
5576 	rts = /([?&])_=[^&]*/,
5577 	rurl = /^(\w+:)?\/\/([^\/?#]+)/,
5578 	r20 = /%20/g,
5579 	rhash = /#.*$/,
5580 
5581 	// Keep a copy of the old load method
5582 	_load = jQuery.fn.load;
5583 
5584 jQuery.fn.extend({
5585 	load: function( url, params, callback ) {
5586 		if ( typeof url !== "string" && _load ) {
5587 			return _load.apply( this, arguments );
5588 
5589 		// Don't do a request if no elements are being requested
5590 		} else if ( !this.length ) {
5591 			return this;
5592 		}
5593 
5594 		var off = url.indexOf(" ");
5595 		if ( off >= 0 ) {
5596 			var selector = url.slice(off, url.length);
5597 			url = url.slice(0, off);
5598 		}
5599 
5600 		// Default to a GET request
5601 		var type = "GET";
5602 
5603 		// If the second parameter was provided
5604 		if ( params ) {
5605 			// If it's a function
5606 			if ( jQuery.isFunction( params ) ) {
5607 				// We assume that it's the callback
5608 				callback = params;
5609 				params = null;
5610 
5611 			// Otherwise, build a param string
5612 			} else if ( typeof params === "object" ) {
5613 				params = jQuery.param( params, jQuery.ajaxSettings.traditional );
5614 				type = "POST";
5615 			}
5616 		}
5617 
5618 		var self = this;
5619 
5620 		// Request the remote document
5621 		jQuery.ajax({
5622 			url: url,
5623 			type: type,
5624 			dataType: "html",
5625 			data: params,
5626 			complete: function( res, status ) {
5627 				// If successful, inject the HTML into all the matched elements
5628 				if ( status === "success" || status === "notmodified" ) {
5629 					// See if a selector was specified
5630 					self.html( selector ?
5631 						// Create a dummy div to hold the results
5632 						jQuery("<div>")
5633 							// inject the contents of the document in, removing the scripts
5634 							// to avoid any 'Permission Denied' errors in IE
5635 							.append(res.responseText.replace(rscript, ""))
5636 
5637 							// Locate the specified elements
5638 							.find(selector) :
5639 
5640 						// If not, just inject the full result
5641 						res.responseText );
5642 				}
5643 
5644 				if ( callback ) {
5645 					self.each( callback, [res.responseText, status, res] );
5646 				}
5647 			}
5648 		});
5649 
5650 		return this;
5651 	},
5652 
5653 	serialize: function() {
5654 		return jQuery.param(this.serializeArray());
5655 	},
5656 
5657 	serializeArray: function() {
5658 		return this.map(function() {
5659 			return this.elements ? jQuery.makeArray(this.elements) : this;
5660 		})
5661 		.filter(function() {
5662 			return this.name && !this.disabled &&
5663 				(this.checked || rselectTextarea.test(this.nodeName) ||
5664 					rinput.test(this.type));
5665 		})
5666 		.map(function( i, elem ) {
5667 			var val = jQuery(this).val();
5668 
5669 			return val == null ?
5670 				null :
5671 				jQuery.isArray(val) ?
5672 					jQuery.map( val, function( val, i ) {
5673 						return { name: elem.name, value: val };
5674 					}) :
5675 					{ name: elem.name, value: val };
5676 		}).get();
5677 	}
5678 });
5679 
5680 // Attach a bunch of functions for handling common AJAX events
5681 jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "), function( i, o ) {
5682 	jQuery.fn[o] = function( f ) {
5683 		return this.bind(o, f);
5684 	};
5685 });
5686 
5687 jQuery.extend({
5688 	get: function( url, data, callback, type ) {
5689 		// shift arguments if data argument was omited
5690 		if ( jQuery.isFunction( data ) ) {
5691 			type = type || callback;
5692 			callback = data;
5693 			data = null;
5694 		}
5695 
5696 		return jQuery.ajax({
5697 			type: "GET",
5698 			url: url,
5699 			data: data,
5700 			success: callback,
5701 			dataType: type
5702 		});
5703 	},
5704 
5705 	getScript: function( url, callback ) {
5706 		return jQuery.get(url, null, callback, "script");
5707 	},
5708 
5709 	getJSON: function( url, data, callback ) {
5710 		return jQuery.get(url, data, callback, "json");
5711 	},
5712 
5713 	post: function( url, data, callback, type ) {
5714 		// shift arguments if data argument was omited
5715 		if ( jQuery.isFunction( data ) ) {
5716 			type = type || callback;
5717 			callback = data;
5718 			data = {};
5719 		}
5720 
5721 		return jQuery.ajax({
5722 			type: "POST",
5723 			url: url,
5724 			data: data,
5725 			success: callback,
5726 			dataType: type
5727 		});
5728 	},
5729 
5730 	ajaxSetup: function( settings ) {
5731 		jQuery.extend( jQuery.ajaxSettings, settings );
5732 	},
5733 
5734 	ajaxSettings: {
5735 		url: location.href,
5736 		global: true,
5737 		type: "GET",
5738 		contentType: "application/x-www-form-urlencoded",
5739 		processData: true,
5740 		async: true,
5741 		/*
5742 		timeout: 0,
5743 		data: null,
5744 		username: null,
5745 		password: null,
5746 		traditional: false,
5747 		*/
5748 		// This function can be overriden by calling jQuery.ajaxSetup
5749 		xhr: function() {
5750 			return new window.XMLHttpRequest();
5751 		},
5752 		accepts: {
5753 			xml: "application/xml, text/xml",
5754 			html: "text/html",
5755 			script: "text/javascript, application/javascript",
5756 			json: "application/json, text/javascript",
5757 			text: "text/plain",
5758 			_default: "*/*"
5759 		}
5760 	},
5761 
5762 	ajax: function( origSettings ) {
5763 		var s = jQuery.extend(true, {}, jQuery.ajaxSettings, origSettings),
5764 			jsonp, status, data, type = s.type.toUpperCase(), noContent = rnoContent.test(type);
5765 
5766 		s.url = s.url.replace( rhash, "" );
5767 
5768 		// Use original (not extended) context object if it was provided
5769 		s.context = origSettings && origSettings.context != null ? origSettings.context : s;
5770 
5771 		// convert data if not already a string
5772 		if ( s.data && s.processData && typeof s.data !== "string" ) {
5773 			s.data = jQuery.param( s.data, s.traditional );
5774 		}
5775 
5776 		// Handle JSONP Parameter Callbacks
5777 		if ( s.dataType === "jsonp" ) {
5778 			if ( type === "GET" ) {
5779 				if ( !jsre.test( s.url ) ) {
5780 					s.url += (rquery.test( s.url ) ? "&" : "?") + (s.jsonp || "callback") + "=?";
5781 				}
5782 			} else if ( !s.data || !jsre.test(s.data) ) {
5783 				s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";
5784 			}
5785 			s.dataType = "json";
5786 		}
5787 
5788 		// Build temporary JSONP function
5789 		if ( s.dataType === "json" && (s.data && jsre.test(s.data) || jsre.test(s.url)) ) {
5790 			jsonp = s.jsonpCallback || ("jsonp" + jsc++);
5791 
5792 			// Replace the =? sequence both in the query string and the data
5793 			if ( s.data ) {
5794 				s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");
5795 			}
5796 
5797 			s.url = s.url.replace(jsre, "=" + jsonp + "$1");
5798 
5799 			// We need to make sure
5800 			// that a JSONP style response is executed properly
5801 			s.dataType = "script";
5802 
5803 			// Handle JSONP-style loading
5804 			var customJsonp = window[ jsonp ];
5805 
5806 			window[ jsonp ] = function( tmp ) {
5807 				if ( jQuery.isFunction( customJsonp ) ) {
5808 					customJsonp( tmp );
5809 
5810 				} else {
5811 					// Garbage collect
5812 					window[ jsonp ] = undefined;
5813 
5814 					try {
5815 						delete window[ jsonp ];
5816 					} catch( jsonpError ) {}
5817 				}
5818 
5819 				data = tmp;
5820 				jQuery.handleSuccess( s, xhr, status, data );
5821 				jQuery.handleComplete( s, xhr, status, data );
5822 				
5823 				if ( head ) {
5824 					head.removeChild( script );
5825 				}
5826 			};
5827 		}
5828 
5829 		if ( s.dataType === "script" && s.cache === null ) {
5830 			s.cache = false;
5831 		}
5832 
5833 		if ( s.cache === false && noContent ) {
5834 			var ts = jQuery.now();
5835 
5836 			// try replacing _= if it is there
5837 			var ret = s.url.replace(rts, "$1_=" + ts);
5838 
5839 			// if nothing was replaced, add timestamp to the end
5840 			s.url = ret + ((ret === s.url) ? (rquery.test(s.url) ? "&" : "?") + "_=" + ts : "");
5841 		}
5842 
5843 		// If data is available, append data to url for GET/HEAD requests
5844 		if ( s.data && noContent ) {
5845 			s.url += (rquery.test(s.url) ? "&" : "?") + s.data;
5846 		}
5847 
5848 		// Watch for a new set of requests
5849 		if ( s.global && jQuery.active++ === 0 ) {
5850 			jQuery.event.trigger( "ajaxStart" );
5851 		}
5852 
5853 		// Matches an absolute URL, and saves the domain
5854 		var parts = rurl.exec( s.url ),
5855 			remote = parts && (parts[1] && parts[1].toLowerCase() !== location.protocol || parts[2].toLowerCase() !== location.host);
5856 
5857 		// If we're requesting a remote document
5858 		// and trying to load JSON or Script with a GET
5859 		if ( s.dataType === "script" && type === "GET" && remote ) {
5860 			var head = document.getElementsByTagName("head")[0] || document.documentElement;
5861 			var script = document.createElement("script");
5862 			if ( s.scriptCharset ) {
5863 				script.charset = s.scriptCharset;
5864 			}
5865 			script.src = s.url;
5866 
5867 			// Handle Script loading
5868 			if ( !jsonp ) {
5869 				var done = false;
5870 
5871 				// Attach handlers for all browsers
5872 				script.onload = script.onreadystatechange = function() {
5873 					if ( !done && (!this.readyState ||
5874 							this.readyState === "loaded" || this.readyState === "complete") ) {
5875 						done = true;
5876 						jQuery.handleSuccess( s, xhr, status, data );
5877 						jQuery.handleComplete( s, xhr, status, data );
5878 
5879 						// Handle memory leak in IE
5880 						script.onload = script.onreadystatechange = null;
5881 						if ( head && script.parentNode ) {
5882 							head.removeChild( script );
5883 						}
5884 					}
5885 				};
5886 			}
5887 
5888 			// Use insertBefore instead of appendChild  to circumvent an IE6 bug.
5889 			// This arises when a base node is used (#2709 and #4378).
5890 			head.insertBefore( script, head.firstChild );
5891 
5892 			// We handle everything using the script element injection
5893 			return undefined;
5894 		}
5895 
5896 		var requestDone = false;
5897 
5898 		// Create the request object
5899 		var xhr = s.xhr();
5900 
5901 		if ( !xhr ) {
5902 			return;
5903 		}
5904 
5905 		// Open the socket
5906 		// Passing null username, generates a login popup on Opera (#2865)
5907 		if ( s.username ) {
5908 			xhr.open(type, s.url, s.async, s.username, s.password);
5909 		} else {
5910 			xhr.open(type, s.url, s.async);
5911 		}
5912 
5913 		// Need an extra try/catch for cross domain requests in Firefox 3
5914 		try {
5915 			// Set content-type if data specified and content-body is valid for this type
5916 			if ( (s.data != null && !noContent) || (origSettings && origSettings.contentType) ) {
5917 				xhr.setRequestHeader("Content-Type", s.contentType);
5918 			}
5919 
5920 			// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
5921 			if ( s.ifModified ) {
5922 				if ( jQuery.lastModified[s.url] ) {
5923 					xhr.setRequestHeader("If-Modified-Since", jQuery.lastModified[s.url]);
5924 				}
5925 
5926 				if ( jQuery.etag[s.url] ) {
5927 					xhr.setRequestHeader("If-None-Match", jQuery.etag[s.url]);
5928 				}
5929 			}
5930 
5931 			// Set header so the called script knows that it's an XMLHttpRequest
5932 			// Only send the header if it's not a remote XHR
5933 			if ( !remote ) {
5934 				xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
5935 			}
5936 
5937 			// Set the Accepts header for the server, depending on the dataType
5938 			xhr.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ?
5939 				s.accepts[ s.dataType ] + ", */*; q=0.01" :
5940 				s.accepts._default );
5941 		} catch( headerError ) {}
5942 
5943 		// Allow custom headers/mimetypes and early abort
5944 		if ( s.beforeSend && s.beforeSend.call(s.context, xhr, s) === false ) {
5945 			// Handle the global AJAX counter
5946 			if ( s.global && jQuery.active-- === 1 ) {
5947 				jQuery.event.trigger( "ajaxStop" );
5948 			}
5949 
5950 			// close opended socket
5951 			xhr.abort();
5952 			return false;
5953 		}
5954 
5955 		if ( s.global ) {
5956 			jQuery.triggerGlobal( s, "ajaxSend", [xhr, s] );
5957 		}
5958 
5959 		// Wait for a response to come back
5960 		var onreadystatechange = xhr.onreadystatechange = function( isTimeout ) {
5961 			// The request was aborted
5962 			if ( !xhr || xhr.readyState === 0 || isTimeout === "abort" ) {
5963 				// Opera doesn't call onreadystatechange before this point
5964 				// so we simulate the call
5965 				if ( !requestDone ) {
5966 					jQuery.handleComplete( s, xhr, status, data );
5967 				}
5968 
5969 				requestDone = true;
5970 				if ( xhr ) {
5971 					xhr.onreadystatechange = jQuery.noop;
5972 				}
5973 
5974 			// The transfer is complete and the data is available, or the request timed out
5975 			} else if ( !requestDone && xhr && (xhr.readyState === 4 || isTimeout === "timeout") ) {
5976 				requestDone = true;
5977 				xhr.onreadystatechange = jQuery.noop;
5978 
5979 				status = isTimeout === "timeout" ?
5980 					"timeout" :
5981 					!jQuery.httpSuccess( xhr ) ?
5982 						"error" :
5983 						s.ifModified && jQuery.httpNotModified( xhr, s.url ) ?
5984 							"notmodified" :
5985 							"success";
5986 
5987 				var errMsg;
5988 
5989 				if ( status === "success" ) {
5990 					// Watch for, and catch, XML document parse errors
5991 					try {
5992 						// process the data (runs the xml through httpData regardless of callback)
5993 						data = jQuery.httpData( xhr, s.dataType, s );
5994 					} catch( parserError ) {
5995 						status = "parsererror";
5996 						errMsg = parserError;
5997 					}
5998 				}
5999 
6000 				// Make sure that the request was successful or notmodified
6001 				if ( status === "success" || status === "notmodified" ) {
6002 					// JSONP handles its own success callback
6003 					if ( !jsonp ) {
6004 						jQuery.handleSuccess( s, xhr, status, data );
6005 					}
6006 				} else {
6007 					jQuery.handleError( s, xhr, status, errMsg );
6008 				}
6009 
6010 				// Fire the complete handlers
6011 				if ( !jsonp ) {
6012 					jQuery.handleComplete( s, xhr, status, data );
6013 				}
6014 
6015 				if ( isTimeout === "timeout" ) {
6016 					xhr.abort();
6017 				}
6018 
6019 				// Stop memory leaks
6020 				if ( s.async ) {
6021 					xhr = null;
6022 				}
6023 			}
6024 		};
6025 
6026 		// Override the abort handler, if we can (IE 6 doesn't allow it, but that's OK)
6027 		// Opera doesn't fire onreadystatechange at all on abort
6028 		try {
6029 			var oldAbort = xhr.abort;
6030 			xhr.abort = function() {
6031 				if ( xhr ) {
6032 					// oldAbort has no call property in IE7 so
6033 					// just do it this way, which works in all
6034 					// browsers
6035 					Function.prototype.call.call( oldAbort, xhr );
6036 				}
6037 
6038 				onreadystatechange( "abort" );
6039 			};
6040 		} catch( abortError ) {}
6041 
6042 		// Timeout checker
6043 		if ( s.async && s.timeout > 0 ) {
6044 			setTimeout(function() {
6045 				// Check to see if the request is still happening
6046 				if ( xhr && !requestDone ) {
6047 					onreadystatechange( "timeout" );
6048 				}
6049 			}, s.timeout);
6050 		}
6051 
6052 		// Send the data
6053 		try {
6054 			xhr.send( noContent || s.data == null ? null : s.data );
6055 
6056 		} catch( sendError ) {
6057 			jQuery.handleError( s, xhr, null, sendError );
6058 
6059 			// Fire the complete handlers
6060 			jQuery.handleComplete( s, xhr, status, data );
6061 		}
6062 
6063 		// firefox 1.5 doesn't fire statechange for sync requests
6064 		if ( !s.async ) {
6065 			onreadystatechange();
6066 		}
6067 
6068 		// return XMLHttpRequest to allow aborting the request etc.
6069 		return xhr;
6070 	},
6071 
6072 	// Serialize an array of form elements or a set of
6073 	// key/values into a query string
6074 	param: function( a, traditional ) {
6075 		var s = [],
6076 			add = function( key, value ) {
6077 				// If value is a function, invoke it and return its value
6078 				value = jQuery.isFunction(value) ? value() : value;
6079 				s[ s.length ] = encodeURIComponent(key) + "=" + encodeURIComponent(value);
6080 			};
6081 		
6082 		// Set traditional to true for jQuery <= 1.3.2 behavior.
6083 		if ( traditional === undefined ) {
6084 			traditional = jQuery.ajaxSettings.traditional;
6085 		}
6086 		
6087 		// If an array was passed in, assume that it is an array of form elements.
6088 		if ( jQuery.isArray(a) || a.jquery ) {
6089 			// Serialize the form elements
6090 			jQuery.each( a, function() {
6091 				add( this.name, this.value );
6092 			});
6093 			
6094 		} else {
6095 			// If traditional, encode the "old" way (the way 1.3.2 or older
6096 			// did it), otherwise encode params recursively.
6097 			for ( var prefix in a ) {
6098 				buildParams( prefix, a[prefix], traditional, add );
6099 			}
6100 		}
6101 
6102 		// Return the resulting serialization
6103 		return s.join("&").replace(r20, "+");
6104 	}
6105 });
6106 
6107 function buildParams( prefix, obj, traditional, add ) {
6108 	if ( jQuery.isArray(obj) && obj.length ) {
6109 		// Serialize array item.
6110 		jQuery.each( obj, function( i, v ) {
6111 			if ( traditional || rbracket.test( prefix ) ) {
6112 				// Treat each array item as a scalar.
6113 				add( prefix, v );
6114 
6115 			} else {
6116 				// If array item is non-scalar (array or object), encode its
6117 				// numeric index to resolve deserialization ambiguity issues.
6118 				// Note that rack (as of 1.0.0) can't currently deserialize
6119 				// nested arrays properly, and attempting to do so may cause
6120 				// a server error. Possible fixes are to modify rack's
6121 				// deserialization algorithm or to provide an option or flag
6122 				// to force array serialization to be shallow.
6123 				buildParams( prefix + "[" + ( typeof v === "object" || jQuery.isArray(v) ? i : "" ) + "]", v, traditional, add );
6124 			}
6125 		});
6126 			
6127 	} else if ( !traditional && obj != null && typeof obj === "object" ) {
6128 		if ( jQuery.isEmptyObject( obj ) ) {
6129 			add( prefix, "" );
6130 
6131 		// Serialize object item.
6132 		} else {
6133 			jQuery.each( obj, function( k, v ) {
6134 				buildParams( prefix + "[" + k + "]", v, traditional, add );
6135 			});
6136 		}
6137 					
6138 	} else {
6139 		// Serialize scalar item.
6140 		add( prefix, obj );
6141 	}
6142 }
6143 
6144 // This is still on the jQuery object... for now
6145 // Want to move this to jQuery.ajax some day
6146 jQuery.extend({
6147 
6148 	// Counter for holding the number of active queries
6149 	active: 0,
6150 
6151 	// Last-Modified header cache for next request
6152 	lastModified: {},
6153 	etag: {},
6154 
6155 	handleError: function( s, xhr, status, e ) {
6156 		// If a local callback was specified, fire it
6157 		if ( s.error ) {
6158 			s.error.call( s.context, xhr, status, e );
6159 		}
6160 
6161 		// Fire the global callback
6162 		if ( s.global ) {
6163 			jQuery.triggerGlobal( s, "ajaxError", [xhr, s, e] );
6164 		}
6165 	},
6166 
6167 	handleSuccess: function( s, xhr, status, data ) {
6168 		// If a local callback was specified, fire it and pass it the data
6169 		if ( s.success ) {
6170 			s.success.call( s.context, data, status, xhr );
6171 		}
6172 
6173 		// Fire the global callback
6174 		if ( s.global ) {
6175 			jQuery.triggerGlobal( s, "ajaxSuccess", [xhr, s] );
6176 		}
6177 	},
6178 
6179 	handleComplete: function( s, xhr, status ) {
6180 		// Process result
6181 		if ( s.complete ) {
6182 			s.complete.call( s.context, xhr, status );
6183 		}
6184 
6185 		// The request was completed
6186 		if ( s.global ) {
6187 			jQuery.triggerGlobal( s, "ajaxComplete", [xhr, s] );
6188 		}
6189 
6190 		// Handle the global AJAX counter
6191 		if ( s.global && jQuery.active-- === 1 ) {
6192 			jQuery.event.trigger( "ajaxStop" );
6193 		}
6194 	},
6195 		
6196 	triggerGlobal: function( s, type, args ) {
6197 		(s.context && s.context.url == null ? jQuery(s.context) : jQuery.event).trigger(type, args);
6198 	},
6199 
6200 	// Determines if an XMLHttpRequest was successful or not
6201 	httpSuccess: function( xhr ) {
6202 		try {
6203 			// IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450
6204 			return !xhr.status && location.protocol === "file:" ||
6205 				xhr.status >= 200 && xhr.status < 300 ||
6206 				xhr.status === 304 || xhr.status === 1223;
6207 		} catch(e) {}
6208 
6209 		return false;
6210 	},
6211 
6212 	// Determines if an XMLHttpRequest returns NotModified
6213 	httpNotModified: function( xhr, url ) {
6214 		var lastModified = xhr.getResponseHeader("Last-Modified"),
6215 			etag = xhr.getResponseHeader("Etag");
6216 
6217 		if ( lastModified ) {
6218 			jQuery.lastModified[url] = lastModified;
6219 		}
6220 
6221 		if ( etag ) {
6222 			jQuery.etag[url] = etag;
6223 		}
6224 
6225 		return xhr.status === 304;
6226 	},
6227 
6228 	httpData: function( xhr, type, s ) {
6229 		var ct = xhr.getResponseHeader("content-type") || "",
6230 			xml = type === "xml" || !type && ct.indexOf("xml") >= 0,
6231 			data = xml ? xhr.responseXML : xhr.responseText;
6232 
6233 		if ( xml && data.documentElement.nodeName === "parsererror" ) {
6234 			jQuery.error( "parsererror" );
6235 		}
6236 
6237 		// Allow a pre-filtering function to sanitize the response
6238 		// s is checked to keep backwards compatibility
6239 		if ( s && s.dataFilter ) {
6240 			data = s.dataFilter( data, type );
6241 		}
6242 
6243 		// The filter can actually parse the response
6244 		if ( typeof data === "string" ) {
6245 			// Get the JavaScript object, if JSON is used.
6246 			if ( type === "json" || !type && ct.indexOf("json") >= 0 ) {
6247 				data = jQuery.parseJSON( data );
6248 
6249 			// If the type is "script", eval it in global context
6250 			} else if ( type === "script" || !type && ct.indexOf("javascript") >= 0 ) {
6251 				jQuery.globalEval( data );
6252 			}
6253 		}
6254 
6255 		return data;
6256 	}
6257 
6258 });
6259 
6260 /*
6261  * Create the request object; Microsoft failed to properly
6262  * implement the XMLHttpRequest in IE7 (can't request local files),
6263  * so we use the ActiveXObject when it is available
6264  * Additionally XMLHttpRequest can be disabled in IE7/IE8 so
6265  * we need a fallback.
6266  */
6267 if ( window.ActiveXObject ) {
6268 	jQuery.ajaxSettings.xhr = function() {
6269 		if ( window.location.protocol !== "file:" ) {
6270 			try {
6271 				return new window.XMLHttpRequest();
6272 			} catch(xhrError) {}
6273 		}
6274 
6275 		try {
6276 			return new window.ActiveXObject("Microsoft.XMLHTTP");
6277 		} catch(activeError) {}
6278 	};
6279 }
6280 
6281 // Does this browser support XHR requests?
6282 jQuery.support.ajax = !!jQuery.ajaxSettings.xhr();
6283 
6284 
6285 
6286 
6287 var elemdisplay = {},
6288 	rfxtypes = /^(?:toggle|show|hide)$/,
6289 	rfxnum = /^([+\-]=)?([\d+.\-]+)(.*)$/,
6290 	timerId,
6291 	fxAttrs = [
6292 		// height animations
6293 		[ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
6294 		// width animations
6295 		[ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
6296 		// opacity animations
6297 		[ "opacity" ]
6298 	];
6299 
6300 jQuery.fn.extend({
6301 	show: function( speed, easing, callback ) {
6302 		var elem, display;
6303 
6304 		if ( speed || speed === 0 ) {
6305 			return this.animate( genFx("show", 3), speed, easing, callback);
6306 
6307 		} else {
6308 			for ( var i = 0, j = this.length; i < j; i++ ) {
6309 				elem = this[i];
6310 				display = elem.style.display;
6311 
6312 				// Reset the inline display of this element to learn if it is
6313 				// being hidden by cascaded rules or not
6314 				if ( !jQuery.data(elem, "olddisplay") && display === "none" ) {
6315 					display = elem.style.display = "";
6316 				}
6317 
6318 				// Set elements which have been overridden with display: none
6319 				// in a stylesheet to whatever the default browser style is
6320 				// for such an element
6321 				if ( display === "" && jQuery.css( elem, "display" ) === "none" ) {
6322 					jQuery.data(elem, "olddisplay", defaultDisplay(elem.nodeName));
6323 				}
6324 			}
6325 
6326 			// Set the display of most of the elements in a second loop
6327 			// to avoid the constant reflow
6328 			for ( i = 0; i < j; i++ ) {
6329 				elem = this[i];
6330 				display = elem.style.display;
6331 
6332 				if ( display === "" || display === "none" ) {
6333 					elem.style.display = jQuery.data(elem, "olddisplay") || "";
6334 				}
6335 			}
6336 
6337 			return this;
6338 		}
6339 	},
6340 
6341 	hide: function( speed, easing, callback ) {
6342 		if ( speed || speed === 0 ) {
6343 			return this.animate( genFx("hide", 3), speed, easing, callback);
6344 
6345 		} else {
6346 			for ( var i = 0, j = this.length; i < j; i++ ) {
6347 				var display = jQuery.css( this[i], "display" );
6348 
6349 				if ( display !== "none" ) {
6350 					jQuery.data( this[i], "olddisplay", display );
6351 				}
6352 			}
6353 
6354 			// Set the display of the elements in a second loop
6355 			// to avoid the constant reflow
6356 			for ( i = 0; i < j; i++ ) {
6357 				this[i].style.display = "none";
6358 			}
6359 
6360 			return this;
6361 		}
6362 	},
6363 
6364 	// Save the old toggle function
6365 	_toggle: jQuery.fn.toggle,
6366 
6367 	toggle: function( fn, fn2, callback ) {
6368 		var bool = typeof fn === "boolean";
6369 
6370 		if ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) {
6371 			this._toggle.apply( this, arguments );
6372 
6373 		} else if ( fn == null || bool ) {
6374 			this.each(function() {
6375 				var state = bool ? fn : jQuery(this).is(":hidden");
6376 				jQuery(this)[ state ? "show" : "hide" ]();
6377 			});
6378 
6379 		} else {
6380 			this.animate(genFx("toggle", 3), fn, fn2, callback);
6381 		}
6382 
6383 		return this;
6384 	},
6385 
6386 	fadeTo: function( speed, to, easing, callback ) {
6387 		return this.filter(":hidden").css("opacity", 0).show().end()
6388 					.animate({opacity: to}, speed, easing, callback);
6389 	},
6390 
6391 	animate: function( prop, speed, easing, callback ) {
6392 		var optall = jQuery.speed(speed, easing, callback);
6393 
6394 		if ( jQuery.isEmptyObject( prop ) ) {
6395 			return this.each( optall.complete );
6396 		}
6397 
6398 		return this[ optall.queue === false ? "each" : "queue" ](function() {
6399 			// XXX 'this' does not always have a nodeName when running the
6400 			// test suite
6401 
6402 			var opt = jQuery.extend({}, optall), p,
6403 				isElement = this.nodeType === 1,
6404 				hidden = isElement && jQuery(this).is(":hidden"),
6405 				self = this;
6406 
6407 			for ( p in prop ) {
6408 				var name = jQuery.camelCase( p );
6409 
6410 				if ( p !== name ) {
6411 					prop[ name ] = prop[ p ];
6412 					delete prop[ p ];
6413 					p = name;
6414 				}
6415 
6416 				if ( prop[p] === "hide" && hidden || prop[p] === "show" && !hidden ) {
6417 					return opt.complete.call(this);
6418 				}
6419 
6420 				if ( isElement && ( p === "height" || p === "width" ) ) {
6421 					// Make sure that nothing sneaks out
6422 					// Record all 3 overflow attributes because IE does not
6423 					// change the overflow attribute when overflowX and
6424 					// overflowY are set to the same value
6425 					opt.overflow = [ this.style.overflow, this.style.overflowX, this.style.overflowY ];
6426 
6427 					// Set display property to inline-block for height/width
6428 					// animations on inline elements that are having width/height
6429 					// animated
6430 					if ( jQuery.css( this, "display" ) === "inline" &&
6431 							jQuery.css( this, "float" ) === "none" ) {
6432 						if ( !jQuery.support.inlineBlockNeedsLayout ) {
6433 							this.style.display = "inline-block";
6434 
6435 						} else {
6436 							var display = defaultDisplay(this.nodeName);
6437 
6438 							// inline-level elements accept inline-block;
6439 							// block-level elements need to be inline with layout
6440 							if ( display === "inline" ) {
6441 								this.style.display = "inline-block";
6442 
6443 							} else {
6444 								this.style.display = "inline";
6445 								this.style.zoom = 1;
6446 							}
6447 						}
6448 					}
6449 				}
6450 
6451 				if ( jQuery.isArray( prop[p] ) ) {
6452 					// Create (if needed) and add to specialEasing
6453 					(opt.specialEasing = opt.specialEasing || {})[p] = prop[p][1];
6454 					prop[p] = prop[p][0];
6455 				}
6456 			}
6457 
6458 			if ( opt.overflow != null ) {
6459 				this.style.overflow = "hidden";
6460 			}
6461 
6462 			opt.curAnim = jQuery.extend({}, prop);
6463 
6464 			jQuery.each( prop, function( name, val ) {
6465 				var e = new jQuery.fx( self, opt, name );
6466 
6467 				if ( rfxtypes.test(val) ) {
6468 					e[ val === "toggle" ? hidden ? "show" : "hide" : val ]( prop );
6469 
6470 				} else {
6471 					var parts = rfxnum.exec(val),
6472 						start = e.cur() || 0;
6473 
6474 					if ( parts ) {
6475 						var end = parseFloat( parts[2] ),
6476 							unit = parts[3] || "px";
6477 
6478 						// We need to compute starting value
6479 						if ( unit !== "px" ) {
6480 							jQuery.style( self, name, (end || 1) + unit);
6481 							start = ((end || 1) / e.cur()) * start;
6482 							jQuery.style( self, name, start + unit);
6483 						}
6484 
6485 						// If a +=/-= token was provided, we're doing a relative animation
6486 						if ( parts[1] ) {
6487 							end = ((parts[1] === "-=" ? -1 : 1) * end) + start;
6488 						}
6489 
6490 						e.custom( start, end, unit );
6491 
6492 					} else {
6493 						e.custom( start, val, "" );
6494 					}
6495 				}
6496 			});
6497 
6498 			// For JS strict compliance
6499 			return true;
6500 		});
6501 	},
6502 
6503 	stop: function( clearQueue, gotoEnd ) {
6504 		var timers = jQuery.timers;
6505 
6506 		if ( clearQueue ) {
6507 			this.queue([]);
6508 		}
6509 
6510 		this.each(function() {
6511 			// go in reverse order so anything added to the queue during the loop is ignored
6512 			for ( var i = timers.length - 1; i >= 0; i-- ) {
6513 				if ( timers[i].elem === this ) {
6514 					if (gotoEnd) {
6515 						// force the next step to be the last
6516 						timers[i](true);
6517 					}
6518 
6519 					timers.splice(i, 1);
6520 				}
6521 			}
6522 		});
6523 
6524 		// start the next in the queue if the last step wasn't forced
6525 		if ( !gotoEnd ) {
6526 			this.dequeue();
6527 		}
6528 
6529 		return this;
6530 	}
6531 
6532 });
6533 
6534 function genFx( type, num ) {
6535 	var obj = {};
6536 
6537 	jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function() {
6538 		obj[ this ] = type;
6539 	});
6540 
6541 	return obj;
6542 }
6543 
6544 // Generate shortcuts for custom animations
6545 jQuery.each({
6546 	slideDown: genFx("show", 1),
6547 	slideUp: genFx("hide", 1),
6548 	slideToggle: genFx("toggle", 1),
6549 	fadeIn: { opacity: "show" },
6550 	fadeOut: { opacity: "hide" },
6551 	fadeToggle: { opacity: "toggle" }
6552 }, function( name, props ) {
6553 	jQuery.fn[ name ] = function( speed, easing, callback ) {
6554 		return this.animate( props, speed, easing, callback );
6555 	};
6556 });
6557 
6558 jQuery.extend({
6559 	speed: function( speed, easing, fn ) {
6560 		var opt = speed && typeof speed === "object" ? jQuery.extend({}, speed) : {
6561 			complete: fn || !fn && easing ||
6562 				jQuery.isFunction( speed ) && speed,
6563 			duration: speed,
6564 			easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
6565 		};
6566 
6567 		opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
6568 			opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[opt.duration] : jQuery.fx.speeds._default;
6569 
6570 		// Queueing
6571 		opt.old = opt.complete;
6572 		opt.complete = function() {
6573 			if ( opt.queue !== false ) {
6574 				jQuery(this).dequeue();
6575 			}
6576 			if ( jQuery.isFunction( opt.old ) ) {
6577 				opt.old.call( this );
6578 			}
6579 		};
6580 
6581 		return opt;
6582 	},
6583 
6584 	easing: {
6585 		linear: function( p, n, firstNum, diff ) {
6586 			return firstNum + diff * p;
6587 		},
6588 		swing: function( p, n, firstNum, diff ) {
6589 			return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
6590 		}
6591 	},
6592 
6593 	timers: [],
6594 
6595 	fx: function( elem, options, prop ) {
6596 		this.options = options;
6597 		this.elem = elem;
6598 		this.prop = prop;
6599 
6600 		if ( !options.orig ) {
6601 			options.orig = {};
6602 		}
6603 	}
6604 
6605 });
6606 
6607 jQuery.fx.prototype = {
6608 	// Simple function for setting a style value
6609 	update: function() {
6610 		if ( this.options.step ) {
6611 			this.options.step.call( this.elem, this.now, this );
6612 		}
6613 
6614 		(jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
6615 	},
6616 
6617 	// Get the current size
6618 	cur: function() {
6619 		if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) ) {
6620 			return this.elem[ this.prop ];
6621 		}
6622 
6623 		var r = parseFloat( jQuery.css( this.elem, this.prop ) );
6624 		return r && r > -10000 ? r : 0;
6625 	},
6626 
6627 	// Start an animation from one number to another
6628 	custom: function( from, to, unit ) {
6629 		var self = this,
6630 			fx = jQuery.fx;
6631 
6632 		this.startTime = jQuery.now();
6633 		this.start = from;
6634 		this.end = to;
6635 		this.unit = unit || this.unit || "px";
6636 		this.now = this.start;
6637 		this.pos = this.state = 0;
6638 
6639 		function t( gotoEnd ) {
6640 			return self.step(gotoEnd);
6641 		}
6642 
6643 		t.elem = this.elem;
6644 
6645 		if ( t() && jQuery.timers.push(t) && !timerId ) {
6646 			timerId = setInterval(fx.tick, fx.interval);
6647 		}
6648 	},
6649 
6650 	// Simple 'show' function
6651 	show: function() {
6652 		// Remember where we started, so that we can go back to it later
6653 		this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
6654 		this.options.show = true;
6655 
6656 		// Begin the animation
6657 		// Make sure that we start at a small width/height to avoid any
6658 		// flash of content
6659 		this.custom(this.prop === "width" || this.prop === "height" ? 1 : 0, this.cur());
6660 
6661 		// Start by showing the element
6662 		jQuery( this.elem ).show();
6663 	},
6664 
6665 	// Simple 'hide' function
6666 	hide: function() {
6667 		// Remember where we started, so that we can go back to it later
6668 		this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
6669 		this.options.hide = true;
6670 
6671 		// Begin the animation
6672 		this.custom(this.cur(), 0);
6673 	},
6674 
6675 	// Each step of an animation
6676 	step: function( gotoEnd ) {
6677 		var t = jQuery.now(), done = true;
6678 
6679 		if ( gotoEnd || t >= this.options.duration + this.startTime ) {
6680 			this.now = this.end;
6681 			this.pos = this.state = 1;
6682 			this.update();
6683 
6684 			this.options.curAnim[ this.prop ] = true;
6685 
6686 			for ( var i in this.options.curAnim ) {
6687 				if ( this.options.curAnim[i] !== true ) {
6688 					done = false;
6689 				}
6690 			}
6691 
6692 			if ( done ) {
6693 				// Reset the overflow
6694 				if ( this.options.overflow != null && !jQuery.support.shrinkWrapBlocks ) {
6695 					var elem = this.elem,
6696 						options = this.options;
6697 
6698 					jQuery.each( [ "", "X", "Y" ], function (index, value) {
6699 						elem.style[ "overflow" + value ] = options.overflow[index];
6700 					} );
6701 				}
6702 
6703 				// Hide the element if the "hide" operation was done
6704 				if ( this.options.hide ) {
6705 					jQuery(this.elem).hide();
6706 				}
6707 
6708 				// Reset the properties, if the item has been hidden or shown
6709 				if ( this.options.hide || this.options.show ) {
6710 					for ( var p in this.options.curAnim ) {
6711 						jQuery.style( this.elem, p, this.options.orig[p] );
6712 					}
6713 				}
6714 
6715 				// Execute the complete function
6716 				this.options.complete.call( this.elem );
6717 			}
6718 
6719 			return false;
6720 
6721 		} else {
6722 			var n = t - this.startTime;
6723 			this.state = n / this.options.duration;
6724 
6725 			// Perform the easing function, defaults to swing
6726 			var specialEasing = this.options.specialEasing && this.options.specialEasing[this.prop];
6727 			var defaultEasing = this.options.easing || (jQuery.easing.swing ? "swing" : "linear");
6728 			this.pos = jQuery.easing[specialEasing || defaultEasing](this.state, n, 0, 1, this.options.duration);
6729 			this.now = this.start + ((this.end - this.start) * this.pos);
6730 
6731 			// Perform the next step of the animation
6732 			this.update();
6733 		}
6734 
6735 		return true;
6736 	}
6737 };
6738 
6739 jQuery.extend( jQuery.fx, {
6740 	tick: function() {
6741 		var timers = jQuery.timers;
6742 
6743 		for ( var i = 0; i < timers.length; i++ ) {
6744 			if ( !timers[i]() ) {
6745 				timers.splice(i--, 1);
6746 			}
6747 		}
6748 
6749 		if ( !timers.length ) {
6750 			jQuery.fx.stop();
6751 		}
6752 	},
6753 
6754 	interval: 13,
6755 
6756 	stop: function() {
6757 		clearInterval( timerId );
6758 		timerId = null;
6759 	},
6760 
6761 	speeds: {
6762 		slow: 600,
6763 		fast: 200,
6764 		// Default speed
6765 		_default: 400
6766 	},
6767 
6768 	step: {
6769 		opacity: function( fx ) {
6770 			jQuery.style( fx.elem, "opacity", fx.now );
6771 		},
6772 
6773 		_default: function( fx ) {
6774 			if ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) {
6775 				fx.elem.style[ fx.prop ] = (fx.prop === "width" || fx.prop === "height" ? Math.max(0, fx.now) : fx.now) + fx.unit;
6776 			} else {
6777 				fx.elem[ fx.prop ] = fx.now;
6778 			}
6779 		}
6780 	}
6781 });
6782 
6783 if ( jQuery.expr && jQuery.expr.filters ) {
6784 	jQuery.expr.filters.animated = function( elem ) {
6785 		return jQuery.grep(jQuery.timers, function( fn ) {
6786 			return elem === fn.elem;
6787 		}).length;
6788 	};
6789 }
6790 
6791 function defaultDisplay( nodeName ) {
6792 	if ( !elemdisplay[ nodeName ] ) {
6793 		var elem = jQuery("<" + nodeName + ">").appendTo("body"),
6794 			display = elem.css("display");
6795 
6796 		elem.remove();
6797 
6798 		if ( display === "none" || display === "" ) {
6799 			display = "block";
6800 		}
6801 
6802 		elemdisplay[ nodeName ] = display;
6803 	}
6804 
6805 	return elemdisplay[ nodeName ];
6806 }
6807 
6808 
6809 
6810 
6811 var rtable = /^t(?:able|d|h)$/i,
6812 	rroot = /^(?:body|html)$/i;
6813 
6814 if ( "getBoundingClientRect" in document.documentElement ) {
6815 	jQuery.fn.offset = function( options ) {
6816 		var elem = this[0], box;
6817 
6818 		if ( options ) { 
6819 			return this.each(function( i ) {
6820 				jQuery.offset.setOffset( this, options, i );
6821 			});
6822 		}
6823 
6824 		if ( !elem || !elem.ownerDocument ) {
6825 			return null;
6826 		}
6827 
6828 		if ( elem === elem.ownerDocument.body ) {
6829 			return jQuery.offset.bodyOffset( elem );
6830 		}
6831 
6832 		try {
6833 			box = elem.getBoundingClientRect();
6834 		} catch(e) {}
6835 
6836 		var doc = elem.ownerDocument,
6837 			docElem = doc.documentElement;
6838 
6839 		// Make sure we're not dealing with a disconnected DOM node
6840 		if ( !box || !jQuery.contains( docElem, elem ) ) {
6841 			return box || { top: 0, left: 0 };
6842 		}
6843 
6844 		var body = doc.body,
6845 			win = getWindow(doc),
6846 			clientTop  = docElem.clientTop  || body.clientTop  || 0,
6847 			clientLeft = docElem.clientLeft || body.clientLeft || 0,
6848 			scrollTop  = (win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop  || body.scrollTop ),
6849 			scrollLeft = (win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft),
6850 			top  = box.top  + scrollTop  - clientTop,
6851 			left = box.left + scrollLeft - clientLeft;
6852 
6853 		return { top: top, left: left };
6854 	};
6855 
6856 } else {
6857 	jQuery.fn.offset = function( options ) {
6858 		var elem = this[0];
6859 
6860 		if ( options ) { 
6861 			return this.each(function( i ) {
6862 				jQuery.offset.setOffset( this, options, i );
6863 			});
6864 		}
6865 
6866 		if ( !elem || !elem.ownerDocument ) {
6867 			return null;
6868 		}
6869 
6870 		if ( elem === elem.ownerDocument.body ) {
6871 			return jQuery.offset.bodyOffset( elem );
6872 		}
6873 
6874 		jQuery.offset.initialize();
6875 
6876 		var computedStyle,
6877 			offsetParent = elem.offsetParent,
6878 			prevOffsetParent = elem,
6879 			doc = elem.ownerDocument,
6880 			docElem = doc.documentElement,
6881 			body = doc.body,
6882 			defaultView = doc.defaultView,
6883 			prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle,
6884 			top = elem.offsetTop,
6885 			left = elem.offsetLeft;
6886 
6887 		while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
6888 			if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
6889 				break;
6890 			}
6891 
6892 			computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle;
6893 			top  -= elem.scrollTop;
6894 			left -= elem.scrollLeft;
6895 
6896 			if ( elem === offsetParent ) {
6897 				top  += elem.offsetTop;
6898 				left += elem.offsetLeft;
6899 
6900 				if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && rtable.test(elem.nodeName)) ) {
6901 					top  += parseFloat( computedStyle.borderTopWidth  ) || 0;
6902 					left += parseFloat( computedStyle.borderLeftWidth ) || 0;
6903 				}
6904 
6905 				prevOffsetParent = offsetParent;
6906 				offsetParent = elem.offsetParent;
6907 			}
6908 
6909 			if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) {
6910 				top  += parseFloat( computedStyle.borderTopWidth  ) || 0;
6911 				left += parseFloat( computedStyle.borderLeftWidth ) || 0;
6912 			}
6913 
6914 			prevComputedStyle = computedStyle;
6915 		}
6916 
6917 		if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) {
6918 			top  += body.offsetTop;
6919 			left += body.offsetLeft;
6920 		}
6921 
6922 		if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
6923 			top  += Math.max( docElem.scrollTop, body.scrollTop );
6924 			left += Math.max( docElem.scrollLeft, body.scrollLeft );
6925 		}
6926 
6927 		return { top: top, left: left };
6928 	};
6929 }
6930 
6931 jQuery.offset = {
6932 	initialize: function() {
6933 		var body = document.body, container = document.createElement("div"), innerDiv, checkDiv, table, td, bodyMarginTop = parseFloat( jQuery.css(body, "marginTop") ) || 0,
6934 			html = "<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";
6935 
6936 		jQuery.extend( container.style, { position: "absolute", top: 0, left: 0, margin: 0, border: 0, width: "1px", height: "1px", visibility: "hidden" } );
6937 
6938 		container.innerHTML = html;
6939 		body.insertBefore( container, body.firstChild );
6940 		innerDiv = container.firstChild;
6941 		checkDiv = innerDiv.firstChild;
6942 		td = innerDiv.nextSibling.firstChild.firstChild;
6943 
6944 		this.doesNotAddBorder = (checkDiv.offsetTop !== 5);
6945 		this.doesAddBorderForTableAndCells = (td.offsetTop === 5);
6946 
6947 		checkDiv.style.position = "fixed";
6948 		checkDiv.style.top = "20px";
6949 
6950 		// safari subtracts parent border width here which is 5px
6951 		this.supportsFixedPosition = (checkDiv.offsetTop === 20 || checkDiv.offsetTop === 15);
6952 		checkDiv.style.position = checkDiv.style.top = "";
6953 
6954 		innerDiv.style.overflow = "hidden";
6955 		innerDiv.style.position = "relative";
6956 
6957 		this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5);
6958 
6959 		this.doesNotIncludeMarginInBodyOffset = (body.offsetTop !== bodyMarginTop);
6960 
6961 		body.removeChild( container );
6962 		body = container = innerDiv = checkDiv = table = td = null;
6963 		jQuery.offset.initialize = jQuery.noop;
6964 	},
6965 
6966 	bodyOffset: function( body ) {
6967 		var top = body.offsetTop,
6968 			left = body.offsetLeft;
6969 
6970 		jQuery.offset.initialize();
6971 
6972 		if ( jQuery.offset.doesNotIncludeMarginInBodyOffset ) {
6973 			top  += parseFloat( jQuery.css(body, "marginTop") ) || 0;
6974 			left += parseFloat( jQuery.css(body, "marginLeft") ) || 0;
6975 		}
6976 
6977 		return { top: top, left: left };
6978 	},
6979 	
6980 	setOffset: function( elem, options, i ) {
6981 		var position = jQuery.css( elem, "position" );
6982 
6983 		// set position first, in-case top/left are set even on static elem
6984 		if ( position === "static" ) {
6985 			elem.style.position = "relative";
6986 		}
6987 
6988 		var curElem = jQuery( elem ),
6989 			curOffset = curElem.offset(),
6990 			curCSSTop = jQuery.css( elem, "top" ),
6991 			curCSSLeft = jQuery.css( elem, "left" ),
6992 			calculatePosition = (position === "absolute" && jQuery.inArray('auto', [curCSSTop, curCSSLeft]) > -1),
6993 			props = {}, curPosition = {}, curTop, curLeft;
6994 
6995 		// need to be able to calculate position if either top or left is auto and position is absolute
6996 		if ( calculatePosition ) {
6997 			curPosition = curElem.position();
6998 		}
6999 
7000 		curTop  = calculatePosition ? curPosition.top  : parseInt( curCSSTop,  10 ) || 0;
7001 		curLeft = calculatePosition ? curPosition.left : parseInt( curCSSLeft, 10 ) || 0;
7002 
7003 		if ( jQuery.isFunction( options ) ) {
7004 			options = options.call( elem, i, curOffset );
7005 		}
7006 
7007 		if (options.top != null) {
7008 			props.top = (options.top - curOffset.top) + curTop;
7009 		}
7010 		if (options.left != null) {
7011 			props.left = (options.left - curOffset.left) + curLeft;
7012 		}
7013 		
7014 		if ( "using" in options ) {
7015 			options.using.call( elem, props );
7016 		} else {
7017 			curElem.css( props );
7018 		}
7019 	}
7020 };
7021 
7022 
7023 jQuery.fn.extend({
7024 	position: function() {
7025 		if ( !this[0] ) {
7026 			return null;
7027 		}
7028 
7029 		var elem = this[0],
7030 
7031 		// Get *real* offsetParent
7032 		offsetParent = this.offsetParent(),
7033 
7034 		// Get correct offsets
7035 		offset       = this.offset(),
7036 		parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();
7037 
7038 		// Subtract element margins
7039 		// note: when an element has margin: auto the offsetLeft and marginLeft
7040 		// are the same in Safari causing offset.left to incorrectly be 0
7041 		offset.top  -= parseFloat( jQuery.css(elem, "marginTop") ) || 0;
7042 		offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0;
7043 
7044 		// Add offsetParent borders
7045 		parentOffset.top  += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0;
7046 		parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0;
7047 
7048 		// Subtract the two offsets
7049 		return {
7050 			top:  offset.top  - parentOffset.top,
7051 			left: offset.left - parentOffset.left
7052 		};
7053 	},
7054 
7055 	offsetParent: function() {
7056 		return this.map(function() {
7057 			var offsetParent = this.offsetParent || document.body;
7058 			while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) {
7059 				offsetParent = offsetParent.offsetParent;
7060 			}
7061 			return offsetParent;
7062 		});
7063 	}
7064 });
7065 
7066 
7067 // Create scrollLeft and scrollTop methods
7068 jQuery.each( ["Left", "Top"], function( i, name ) {
7069 	var method = "scroll" + name;
7070 
7071 	jQuery.fn[ method ] = function(val) {
7072 		var elem = this[0], win;
7073 		
7074 		if ( !elem ) {
7075 			return null;
7076 		}
7077 
7078 		if ( val !== undefined ) {
7079 			// Set the scroll offset
7080 			return this.each(function() {
7081 				win = getWindow( this );
7082 
7083 				if ( win ) {
7084 					win.scrollTo(
7085 						!i ? val : jQuery(win).scrollLeft(),
7086 						 i ? val : jQuery(win).scrollTop()
7087 					);
7088 
7089 				} else {
7090 					this[ method ] = val;
7091 				}
7092 			});
7093 		} else {
7094 			win = getWindow( elem );
7095 
7096 			// Return the scroll offset
7097 			return win ? ("pageXOffset" in win) ? win[ i ? "pageYOffset" : "pageXOffset" ] :
7098 				jQuery.support.boxModel && win.document.documentElement[ method ] ||
7099 					win.document.body[ method ] :
7100 				elem[ method ];
7101 		}
7102 	};
7103 });
7104 
7105 function getWindow( elem ) {
7106 	return jQuery.isWindow( elem ) ?
7107 		elem :
7108 		elem.nodeType === 9 ?
7109 			elem.defaultView || elem.parentWindow :
7110 			false;
7111 }
7112 
7113 
7114 
7115 
7116 // Create innerHeight, innerWidth, outerHeight and outerWidth methods
7117 jQuery.each([ "Height", "Width" ], function( i, name ) {
7118 
7119 	var type = name.toLowerCase();
7120 
7121 	// innerHeight and innerWidth
7122 	jQuery.fn["inner" + name] = function() {
7123 		return this[0] ?
7124 			parseFloat( jQuery.css( this[0], type, "padding" ) ) :
7125 			null;
7126 	};
7127 
7128 	// outerHeight and outerWidth
7129 	jQuery.fn["outer" + name] = function( margin ) {
7130 		return this[0] ?
7131 			parseFloat( jQuery.css( this[0], type, margin ? "margin" : "border" ) ) :
7132 			null;
7133 	};
7134 
7135 	jQuery.fn[ type ] = function( size ) {
7136 		// Get window width or height
7137 		var elem = this[0];
7138 		if ( !elem ) {
7139 			return size == null ? null : this;
7140 		}
7141 		
7142 		if ( jQuery.isFunction( size ) ) {
7143 			return this.each(function( i ) {
7144 				var self = jQuery( this );
7145 				self[ type ]( size.call( this, i, self[ type ]() ) );
7146 			});
7147 		}
7148 
7149 		if ( jQuery.isWindow( elem ) ) {
7150 			// Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
7151 			return elem.document.compatMode === "CSS1Compat" && elem.document.documentElement[ "client" + name ] ||
7152 				elem.document.body[ "client" + name ];
7153 
7154 		// Get document width or height
7155 		} else if ( elem.nodeType === 9 ) {
7156 			// Either scroll[Width/Height] or offset[Width/Height], whichever is greater
7157 			return Math.max(
7158 				elem.documentElement["client" + name],
7159 				elem.body["scroll" + name], elem.documentElement["scroll" + name],
7160 				elem.body["offset" + name], elem.documentElement["offset" + name]
7161 			);
7162 
7163 		// Get or set width or height on the element
7164 		} else if ( size === undefined ) {
7165 			var orig = jQuery.css( elem, type ),
7166 				ret = parseFloat( orig );
7167 
7168 			return jQuery.isNaN( ret ) ? orig : ret;
7169 
7170 		// Set the width or height on the element (default to pixels if value is unitless)
7171 		} else {
7172 			return this.css( type, typeof size === "string" ? size : size + "px" );
7173 		}
7174 	};
7175 
7176 });
7177 
7178 
7179 })(window);
7180