Хранилища Subversion ant

Редакция

Содержимое файла | Последнее изменение | Открыть журнал | RSS

Редакция Автор № строки Строка
19 alex-w 1
/*!
2
 * jQuery JavaScript Library v1.3.2
3
 * http://jquery.com/
4
 *
5
 * Copyright (c) 2009 John Resig
6
 * Dual licensed under the MIT and GPL licenses.
7
 * http://docs.jquery.com/License
8
 *
9
 * Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009)
10
 * Revision: 6246
11
 */
12
(function(){
13
 
14
var
15
	// Will speed up references to window, and allows munging its name.
16
	window = this,
17
	// Will speed up references to undefined, and allows munging its name.
18
	undefined,
19
	// Map over jQuery in case of overwrite
20
	_jQuery = window.jQuery,
21
	// Map over the $ in case of overwrite
22
	_$ = window.$,
23
 
24
	jQuery = window.jQuery = window.$ = function( selector, context ) {
25
		// The jQuery object is actually just the init constructor 'enhanced'
26
		return new jQuery.fn.init( selector, context );
27
	},
28
 
29
	// A simple way to check for HTML strings or ID strings
30
	// (both of which we optimize for)
31
	quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/,
32
	// Is it a simple selector
33
	isSimple = /^.[^:#\[\.,]*$/;
34
 
35
jQuery.fn = jQuery.prototype = {
36
	init: function( selector, context ) {
37
		// Make sure that a selection was provided
38
		selector = selector || document;
39
 
40
		// Handle $(DOMElement)
41
		if ( selector.nodeType ) {
42
			this[0] = selector;
43
			this.length = 1;
44
			this.context = selector;
45
			return this;
46
		}
47
		// Handle HTML strings
48
		if ( typeof selector === "string" ) {
49
			// Are we dealing with HTML string or an ID?
50
			var match = quickExpr.exec( selector );
51
 
52
			// Verify a match, and that no context was specified for #id
53
			if ( match && (match[1] || !context) ) {
54
 
55
				// HANDLE: $(html) -> $(array)
56
				if ( match[1] )
57
					selector = jQuery.clean( [ match[1] ], context );
58
 
59
				// HANDLE: $("#id")
60
				else {
61
					var elem = document.getElementById( match[3] );
62
 
63
					// Handle the case where IE and Opera return items
64
					// by name instead of ID
65
					if ( elem && elem.id != match[3] )
66
						return jQuery().find( selector );
67
 
68
					// Otherwise, we inject the element directly into the jQuery object
69
					var ret = jQuery( elem || [] );
70
					ret.context = document;
71
					ret.selector = selector;
72
					return ret;
73
				}
74
 
75
			// HANDLE: $(expr, [context])
76
			// (which is just equivalent to: $(content).find(expr)
77
			} else
78
				return jQuery( context ).find( selector );
79
 
80
		// HANDLE: $(function)
81
		// Shortcut for document ready
82
		} else if ( jQuery.isFunction( selector ) )
83
			return jQuery( document ).ready( selector );
84
 
85
		// Make sure that old selector state is passed along
86
		if ( selector.selector && selector.context ) {
87
			this.selector = selector.selector;
88
			this.context = selector.context;
89
		}
90
 
91
		return this.setArray(jQuery.isArray( selector ) ?
92
			selector :
93
			jQuery.makeArray(selector));
94
	},
95
 
96
	// Start with an empty selector
97
	selector: "",
98
 
99
	// The current version of jQuery being used
100
	jquery: "1.3.2",
101
 
102
	// The number of elements contained in the matched element set
103
	size: function() {
104
		return this.length;
105
	},
106
 
107
	// Get the Nth element in the matched element set OR
108
	// Get the whole matched element set as a clean array
109
	get: function( num ) {
110
		return num === undefined ?
111
 
112
			// Return a 'clean' array
113
			Array.prototype.slice.call( this ) :
114
 
115
			// Return just the object
116
			this[ num ];
117
	},
118
 
119
	// Take an array of elements and push it onto the stack
120
	// (returning the new matched element set)
121
	pushStack: function( elems, name, selector ) {
122
		// Build a new jQuery matched element set
123
		var ret = jQuery( elems );
124
 
125
		// Add the old object onto the stack (as a reference)
126
		ret.prevObject = this;
127
 
128
		ret.context = this.context;
129
 
130
		if ( name === "find" )
131
			ret.selector = this.selector + (this.selector ? " " : "") + selector;
132
		else if ( name )
133
			ret.selector = this.selector + "." + name + "(" + selector + ")";
134
 
135
		// Return the newly-formed element set
136
		return ret;
137
	},
138
 
139
	// Force the current matched set of elements to become
140
	// the specified array of elements (destroying the stack in the process)
141
	// You should use pushStack() in order to do this, but maintain the stack
142
	setArray: function( elems ) {
143
		// Resetting the length to 0, then using the native Array push
144
		// is a super-fast way to populate an object with array-like properties
145
		this.length = 0;
146
		Array.prototype.push.apply( this, elems );
147
 
148
		return this;
149
	},
150
 
151
	// Execute a callback for every element in the matched set.
152
	// (You can seed the arguments with an array of args, but this is
153
	// only used internally.)
154
	each: function( callback, args ) {
155
		return jQuery.each( this, callback, args );
156
	},
157
 
158
	// Determine the position of an element within
159
	// the matched set of elements
160
	index: function( elem ) {
161
		// Locate the position of the desired element
162
		return jQuery.inArray(
163
			// If it receives a jQuery object, the first element is used
164
			elem && elem.jquery ? elem[0] : elem
165
		, this );
166
	},
167
 
168
	attr: function( name, value, type ) {
169
		var options = name;
170
 
171
		// Look for the case where we're accessing a style value
172
		if ( typeof name === "string" )
173
			if ( value === undefined )
174
				return this[0] && jQuery[ type || "attr" ]( this[0], name );
175
 
176
			else {
177
				options = {};
178
				options[ name ] = value;
179
			}
180
 
181
		// Check to see if we're setting style values
182
		return this.each(function(i){
183
			// Set all the styles
184
			for ( name in options )
185
				jQuery.attr(
186
					type ?
187
						this.style :
188
						this,
189
					name, jQuery.prop( this, options[ name ], type, i, name )
190
				);
191
		});
192
	},
193
 
194
	css: function( key, value ) {
195
		// ignore negative width and height values
196
		if ( (key == 'width' || key == 'height') && parseFloat(value) < 0 )
197
			value = undefined;
198
		return this.attr( key, value, "curCSS" );
199
	},
200
 
201
	text: function( text ) {
202
		if ( typeof text !== "object" && text != null )
203
			return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
204
 
205
		var ret = "";
206
 
207
		jQuery.each( text || this, function(){
208
			jQuery.each( this.childNodes, function(){
209
				if ( this.nodeType != 8 )
210
					ret += this.nodeType != 1 ?
211
						this.nodeValue :
212
						jQuery.fn.text( [ this ] );
213
			});
214
		});
215
 
216
		return ret;
217
	},
218
 
219
	wrapAll: function( html ) {
220
		if ( this[0] ) {
221
			// The elements to wrap the target around
222
			var wrap = jQuery( html, this[0].ownerDocument ).clone();
223
 
224
			if ( this[0].parentNode )
225
				wrap.insertBefore( this[0] );
226
 
227
			wrap.map(function(){
228
				var elem = this;
229
 
230
				while ( elem.firstChild )
231
					elem = elem.firstChild;
232
 
233
				return elem;
234
			}).append(this);
235
		}
236
 
237
		return this;
238
	},
239
 
240
	wrapInner: function( html ) {
241
		return this.each(function(){
242
			jQuery( this ).contents().wrapAll( html );
243
		});
244
	},
245
 
246
	wrap: function( html ) {
247
		return this.each(function(){
248
			jQuery( this ).wrapAll( html );
249
		});
250
	},
251
 
252
	append: function() {
253
		return this.domManip(arguments, true, function(elem){
254
			if (this.nodeType == 1)
255
				this.appendChild( elem );
256
		});
257
	},
258
 
259
	prepend: function() {
260
		return this.domManip(arguments, true, function(elem){
261
			if (this.nodeType == 1)
262
				this.insertBefore( elem, this.firstChild );
263
		});
264
	},
265
 
266
	before: function() {
267
		return this.domManip(arguments, false, function(elem){
268
			this.parentNode.insertBefore( elem, this );
269
		});
270
	},
271
 
272
	after: function() {
273
		return this.domManip(arguments, false, function(elem){
274
			this.parentNode.insertBefore( elem, this.nextSibling );
275
		});
276
	},
277
 
278
	end: function() {
279
		return this.prevObject || jQuery( [] );
280
	},
281
 
282
	// For internal use only.
283
	// Behaves like an Array's method, not like a jQuery method.
284
	push: [].push,
285
	sort: [].sort,
286
	splice: [].splice,
287
 
288
	find: function( selector ) {
289
		if ( this.length === 1 ) {
290
			var ret = this.pushStack( [], "find", selector );
291
			ret.length = 0;
292
			jQuery.find( selector, this[0], ret );
293
			return ret;
294
		} else {
295
			return this.pushStack( jQuery.unique(jQuery.map(this, function(elem){
296
				return jQuery.find( selector, elem );
297
			})), "find", selector );
298
		}
299
	},
300
 
301
	clone: function( events ) {
302
		// Do the clone
303
		var ret = this.map(function(){
304
			if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) {
305
				// IE copies events bound via attachEvent when
306
				// using cloneNode. Calling detachEvent on the
307
				// clone will also remove the events from the orignal
308
				// In order to get around this, we use innerHTML.
309
				// Unfortunately, this means some modifications to
310
				// attributes in IE that are actually only stored
311
				// as properties will not be copied (such as the
312
				// the name attribute on an input).
313
				var html = this.outerHTML;
314
				if ( !html ) {
315
					var div = this.ownerDocument.createElement("div");
316
					div.appendChild( this.cloneNode(true) );
317
					html = div.innerHTML;
318
				}
319
 
320
				return jQuery.clean([html.replace(/ jQuery\d+="(?:\d+|null)"/g, "").replace(/^\s*/, "")])[0];
321
			} else
322
				return this.cloneNode(true);
323
		});
324
 
325
		// Copy the events from the original to the clone
326
		if ( events === true ) {
327
			var orig = this.find("*").andSelf(), i = 0;
328
 
329
			ret.find("*").andSelf().each(function(){
330
				if ( this.nodeName !== orig[i].nodeName )
331
					return;
332
 
333
				var events = jQuery.data( orig[i], "events" );
334
 
335
				for ( var type in events ) {
336
					for ( var handler in events[ type ] ) {
337
						jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data );
338
					}
339
				}
340
 
341
				i++;
342
			});
343
		}
344
 
345
		// Return the cloned set
346
		return ret;
347
	},
348
 
349
	filter: function( selector ) {
350
		return this.pushStack(
351
			jQuery.isFunction( selector ) &&
352
			jQuery.grep(this, function(elem, i){
353
				return selector.call( elem, i );
354
			}) ||
355
 
356
			jQuery.multiFilter( selector, jQuery.grep(this, function(elem){
357
				return elem.nodeType === 1;
358
			}) ), "filter", selector );
359
	},
360
 
361
	closest: function( selector ) {
362
		var pos = jQuery.expr.match.POS.test( selector ) ? jQuery(selector) : null,
363
			closer = 0;
364
 
365
		return this.map(function(){
366
			var cur = this;
367
			while ( cur && cur.ownerDocument ) {
368
				if ( pos ? pos.index(cur) > -1 : jQuery(cur).is(selector) ) {
369
					jQuery.data(cur, "closest", closer);
370
					return cur;
371
				}
372
				cur = cur.parentNode;
373
				closer++;
374
			}
375
		});
376
	},
377
 
378
	not: function( selector ) {
379
		if ( typeof selector === "string" )
380
			// test special case where just one selector is passed in
381
			if ( isSimple.test( selector ) )
382
				return this.pushStack( jQuery.multiFilter( selector, this, true ), "not", selector );
383
			else
384
				selector = jQuery.multiFilter( selector, this );
385
 
386
		var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType;
387
		return this.filter(function() {
388
			return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector;
389
		});
390
	},
391
 
392
	add: function( selector ) {
393
		return this.pushStack( jQuery.unique( jQuery.merge(
394
			this.get(),
395
			typeof selector === "string" ?
396
				jQuery( selector ) :
397
				jQuery.makeArray( selector )
398
		)));
399
	},
400
 
401
	is: function( selector ) {
402
		return !!selector && jQuery.multiFilter( selector, this ).length > 0;
403
	},
404
 
405
	hasClass: function( selector ) {
406
		return !!selector && this.is( "." + selector );
407
	},
408
 
409
	val: function( value ) {
410
		if ( value === undefined ) {
411
			var elem = this[0];
412
 
413
			if ( elem ) {
414
				if( jQuery.nodeName( elem, 'option' ) )
415
					return (elem.attributes.value || {}).specified ? elem.value : elem.text;
416
 
417
				// We need to handle select boxes special
418
				if ( jQuery.nodeName( elem, "select" ) ) {
419
					var index = elem.selectedIndex,
420
						values = [],
421
						options = elem.options,
422
						one = elem.type == "select-one";
423
 
424
					// Nothing was selected
425
					if ( index < 0 )
426
						return null;
427
 
428
					// Loop through all the selected options
429
					for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
430
						var option = options[ i ];
431
 
432
						if ( option.selected ) {
433
							// Get the specifc value for the option
434
							value = jQuery(option).val();
435
 
436
							// We don't need an array for one selects
437
							if ( one )
438
								return value;
439
 
440
							// Multi-Selects return an array
441
							values.push( value );
442
						}
443
					}
444
 
445
					return values;
446
				}
447
 
448
				// Everything else, we just grab the value
449
				return (elem.value || "").replace(/\r/g, "");
450
 
451
			}
452
 
453
			return undefined;
454
		}
455
 
456
		if ( typeof value === "number" )
457
			value += '';
458
 
459
		return this.each(function(){
460
			if ( this.nodeType != 1 )
461
				return;
462
 
463
			if ( jQuery.isArray(value) && /radio|checkbox/.test( this.type ) )
464
				this.checked = (jQuery.inArray(this.value, value) >= 0 ||
465
					jQuery.inArray(this.name, value) >= 0);
466
 
467
			else if ( jQuery.nodeName( this, "select" ) ) {
468
				var values = jQuery.makeArray(value);
469
 
470
				jQuery( "option", this ).each(function(){
471
					this.selected = (jQuery.inArray( this.value, values ) >= 0 ||
472
						jQuery.inArray( this.text, values ) >= 0);
473
				});
474
 
475
				if ( !values.length )
476
					this.selectedIndex = -1;
477
 
478
			} else
479
				this.value = value;
480
		});
481
	},
482
 
483
	html: function( value ) {
484
		return value === undefined ?
485
			(this[0] ?
486
				this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g, "") :
487
				null) :
488
			this.empty().append( value );
489
	},
490
 
491
	replaceWith: function( value ) {
492
		return this.after( value ).remove();
493
	},
494
 
495
	eq: function( i ) {
496
		return this.slice( i, +i + 1 );
497
	},
498
 
499
	slice: function() {
500
		return this.pushStack( Array.prototype.slice.apply( this, arguments ),
501
			"slice", Array.prototype.slice.call(arguments).join(",") );
502
	},
503
 
504
	map: function( callback ) {
505
		return this.pushStack( jQuery.map(this, function(elem, i){
506
			return callback.call( elem, i, elem );
507
		}));
508
	},
509
 
510
	andSelf: function() {
511
		return this.add( this.prevObject );
512
	},
513
 
514
	domManip: function( args, table, callback ) {
515
		if ( this[0] ) {
516
			var fragment = (this[0].ownerDocument || this[0]).createDocumentFragment(),
517
				scripts = jQuery.clean( args, (this[0].ownerDocument || this[0]), fragment ),
518
				first = fragment.firstChild;
519
 
520
			if ( first )
521
				for ( var i = 0, l = this.length; i < l; i++ )
522
					callback.call( root(this[i], first), this.length > 1 || i > 0 ?
523
							fragment.cloneNode(true) : fragment );
524
 
525
			if ( scripts )
526
				jQuery.each( scripts, evalScript );
527
		}
528
 
529
		return this;
530
 
531
		function root( elem, cur ) {
532
			return table && jQuery.nodeName(elem, "table") && jQuery.nodeName(cur, "tr") ?
533
				(elem.getElementsByTagName("tbody")[0] ||
534
				elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
535
				elem;
536
		}
537
	}
538
};
539
 
540
// Give the init function the jQuery prototype for later instantiation
541
jQuery.fn.init.prototype = jQuery.fn;
542
 
543
function evalScript( i, elem ) {
544
	if ( elem.src )
545
		jQuery.ajax({
546
			url: elem.src,
547
			async: false,
548
			dataType: "script"
549
		});
550
 
551
	else
552
		jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
553
 
554
	if ( elem.parentNode )
555
		elem.parentNode.removeChild( elem );
556
}
557
 
558
function now(){
559
	return +new Date;
560
}
561
 
562
jQuery.extend = jQuery.fn.extend = function() {
563
	// copy reference to target object
564
	var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options;
565
 
566
	// Handle a deep copy situation
567
	if ( typeof target === "boolean" ) {
568
		deep = target;
569
		target = arguments[1] || {};
570
		// skip the boolean and the target
571
		i = 2;
572
	}
573
 
574
	// Handle case when target is a string or something (possible in deep copy)
575
	if ( typeof target !== "object" && !jQuery.isFunction(target) )
576
		target = {};
577
 
578
	// extend jQuery itself if only one argument is passed
579
	if ( length == i ) {
580
		target = this;
581
		--i;
582
	}
583
 
584
	for ( ; i < length; i++ )
585
		// Only deal with non-null/undefined values
586
		if ( (options = arguments[ i ]) != null )
587
			// Extend the base object
588
			for ( var name in options ) {
589
				var src = target[ name ], copy = options[ name ];
590
 
591
				// Prevent never-ending loop
592
				if ( target === copy )
593
					continue;
594
 
595
				// Recurse if we're merging object values
596
				if ( deep && copy && typeof copy === "object" && !copy.nodeType )
597
					target[ name ] = jQuery.extend( deep,
598
						// Never move original objects, clone them
599
						src || ( copy.length != null ? [ ] : { } )
600
					, copy );
601
 
602
				// Don't bring in undefined values
603
				else if ( copy !== undefined )
604
					target[ name ] = copy;
605
 
606
			}
607
 
608
	// Return the modified object
609
	return target;
610
};
611
 
612
// exclude the following css properties to add px
613
var	exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i,
614
	// cache defaultView
615
	defaultView = document.defaultView || {},
616
	toString = Object.prototype.toString;
617
 
618
jQuery.extend({
619
	noConflict: function( deep ) {
620
		window.$ = _$;
621
 
622
		if ( deep )
623
			window.jQuery = _jQuery;
624
 
625
		return jQuery;
626
	},
627
 
628
	// See test/unit/core.js for details concerning isFunction.
629
	// Since version 1.3, DOM methods and functions like alert
630
	// aren't supported. They return false on IE (#2968).
631
	isFunction: function( obj ) {
632
		return toString.call(obj) === "[object Function]";
633
	},
634
 
635
	isArray: function( obj ) {
636
		return toString.call(obj) === "[object Array]";
637
	},
638
 
639
	// check if an element is in a (or is an) XML document
640
	isXMLDoc: function( elem ) {
641
		return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" ||
642
			!!elem.ownerDocument && jQuery.isXMLDoc( elem.ownerDocument );
643
	},
644
 
645
	// Evalulates a script in a global context
646
	globalEval: function( data ) {
647
		if ( data && /\S/.test(data) ) {
648
			// Inspired by code by Andrea Giammarchi
649
			// http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
650
			var head = document.getElementsByTagName("head")[0] || document.documentElement,
651
				script = document.createElement("script");
652
 
653
			script.type = "text/javascript";
654
			if ( jQuery.support.scriptEval )
655
				script.appendChild( document.createTextNode( data ) );
656
			else
657
				script.text = data;
658
 
659
			// Use insertBefore instead of appendChild  to circumvent an IE6 bug.
660
			// This arises when a base node is used (#2709).
661
			head.insertBefore( script, head.firstChild );
662
			head.removeChild( script );
663
		}
664
	},
665
 
666
	nodeName: function( elem, name ) {
667
		return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase();
668
	},
669
 
670
	// args is for internal usage only
671
	each: function( object, callback, args ) {
672
		var name, i = 0, length = object.length;
673
 
674
		if ( args ) {
675
			if ( length === undefined ) {
676
				for ( name in object )
677
					if ( callback.apply( object[ name ], args ) === false )
678
						break;
679
			} else
680
				for ( ; i < length; )
681
					if ( callback.apply( object[ i++ ], args ) === false )
682
						break;
683
 
684
		// A special, fast, case for the most common use of each
685
		} else {
686
			if ( length === undefined ) {
687
				for ( name in object )
688
					if ( callback.call( object[ name ], name, object[ name ] ) === false )
689
						break;
690
			} else
691
				for ( var value = object[0];
692
					i < length && callback.call( value, i, value ) !== false; value = object[++i] ){}
693
		}
694
 
695
		return object;
696
	},
697
 
698
	prop: function( elem, value, type, i, name ) {
699
		// Handle executable functions
700
		if ( jQuery.isFunction( value ) )
701
			value = value.call( elem, i );
702
 
703
		// Handle passing in a number to a CSS property
704
		return typeof value === "number" && type == "curCSS" && !exclude.test( name ) ?
705
			value + "px" :
706
			value;
707
	},
708
 
709
	className: {
710
		// internal only, use addClass("class")
711
		add: function( elem, classNames ) {
712
			jQuery.each((classNames || "").split(/\s+/), function(i, className){
713
				if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) )
714
					elem.className += (elem.className ? " " : "") + className;
715
			});
716
		},
717
 
718
		// internal only, use removeClass("class")
719
		remove: function( elem, classNames ) {
720
			if (elem.nodeType == 1)
721
				elem.className = classNames !== undefined ?
722
					jQuery.grep(elem.className.split(/\s+/), function(className){
723
						return !jQuery.className.has( classNames, className );
724
					}).join(" ") :
725
					"";
726
		},
727
 
728
		// internal only, use hasClass("class")
729
		has: function( elem, className ) {
730
			return elem && jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1;
731
		}
732
	},
733
 
734
	// A method for quickly swapping in/out CSS properties to get correct calculations
735
	swap: function( elem, options, callback ) {
736
		var old = {};
737
		// Remember the old values, and insert the new ones
738
		for ( var name in options ) {
739
			old[ name ] = elem.style[ name ];
740
			elem.style[ name ] = options[ name ];
741
		}
742
 
743
		callback.call( elem );
744
 
745
		// Revert the old values
746
		for ( var name in options )
747
			elem.style[ name ] = old[ name ];
748
	},
749
 
750
	css: function( elem, name, force, extra ) {
751
		if ( name == "width" || name == "height" ) {
752
			var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ];
753
 
754
			function getWH() {
755
				val = name == "width" ? elem.offsetWidth : elem.offsetHeight;
756
 
757
				if ( extra === "border" )
758
					return;
759
 
760
				jQuery.each( which, function() {
761
					if ( !extra )
762
						val -= parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0;
763
					if ( extra === "margin" )
764
						val += parseFloat(jQuery.curCSS( elem, "margin" + this, true)) || 0;
765
					else
766
						val -= parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0;
767
				});
768
			}
769
 
770
			if ( elem.offsetWidth !== 0 )
771
				getWH();
772
			else
773
				jQuery.swap( elem, props, getWH );
774
 
775
			return Math.max(0, Math.round(val));
776
		}
777
 
778
		return jQuery.curCSS( elem, name, force );
779
	},
780
 
781
	curCSS: function( elem, name, force ) {
782
		var ret, style = elem.style;
783
 
784
		// We need to handle opacity special in IE
785
		if ( name == "opacity" && !jQuery.support.opacity ) {
786
			ret = jQuery.attr( style, "opacity" );
787
 
788
			return ret == "" ?
789
				"1" :
790
				ret;
791
		}
792
 
793
		// Make sure we're using the right name for getting the float value
794
		if ( name.match( /float/i ) )
795
			name = styleFloat;
796
 
797
		if ( !force && style && style[ name ] )
798
			ret = style[ name ];
799
 
800
		else if ( defaultView.getComputedStyle ) {
801
 
802
			// Only "float" is needed here
803
			if ( name.match( /float/i ) )
804
				name = "float";
805
 
806
			name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase();
807
 
808
			var computedStyle = defaultView.getComputedStyle( elem, null );
809
 
810
			if ( computedStyle )
811
				ret = computedStyle.getPropertyValue( name );
812
 
813
			// We should always get a number back from opacity
814
			if ( name == "opacity" && ret == "" )
815
				ret = "1";
816
 
817
		} else if ( elem.currentStyle ) {
818
			var camelCase = name.replace(/\-(\w)/g, function(all, letter){
819
				return letter.toUpperCase();
820
			});
821
 
822
			ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ];
823
 
824
			// From the awesome hack by Dean Edwards
825
			// http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
826
 
827
			// If we're not dealing with a regular pixel number
828
			// but a number that has a weird ending, we need to convert it to pixels
829
			if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) {
830
				// Remember the original values
831
				var left = style.left, rsLeft = elem.runtimeStyle.left;
832
 
833
				// Put in the new values to get a computed value out
834
				elem.runtimeStyle.left = elem.currentStyle.left;
835
				style.left = ret || 0;
836
				ret = style.pixelLeft + "px";
837
 
838
				// Revert the changed values
839
				style.left = left;
840
				elem.runtimeStyle.left = rsLeft;
841
			}
842
		}
843
 
844
		return ret;
845
	},
846
 
847
	clean: function( elems, context, fragment ) {
848
		context = context || document;
849
 
850
		// !context.createElement fails in IE with an error but returns typeof 'object'
851
		if ( typeof context.createElement === "undefined" )
852
			context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
853
 
854
		// If a single string is passed in and it's a single tag
855
		// just do a createElement and skip the rest
856
		if ( !fragment && elems.length === 1 && typeof elems[0] === "string" ) {
857
			var match = /^<(\w+)\s*\/?>$/.exec(elems[0]);
858
			if ( match )
859
				return [ context.createElement( match[1] ) ];
860
		}
861
 
862
		var ret = [], scripts = [], div = context.createElement("div");
863
 
864
		jQuery.each(elems, function(i, elem){
865
			if ( typeof elem === "number" )
866
				elem += '';
867
 
868
			if ( !elem )
869
				return;
870
 
871
			// Convert html string into DOM nodes
872
			if ( typeof elem === "string" ) {
873
				// Fix "XHTML"-style tags in all browsers
874
				elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){
875
					return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ?
876
						all :
877
						front + "></" + tag + ">";
878
				});
879
 
880
				// Trim whitespace, otherwise indexOf won't work as expected
881
				var tags = elem.replace(/^\s+/, "").substring(0, 10).toLowerCase();
882
 
883
				var wrap =
884
					// option or optgroup
885
					!tags.indexOf("<opt") &&
886
					[ 1, "<select multiple='multiple'>", "</select>" ] ||
887
 
888
					!tags.indexOf("<leg") &&
889
					[ 1, "<fieldset>", "</fieldset>" ] ||
890
 
891
					tags.match(/^<(thead|tbody|tfoot|colg|cap)/) &&
892
					[ 1, "<table>", "</table>" ] ||
893
 
894
					!tags.indexOf("<tr") &&
895
					[ 2, "<table><tbody>", "</tbody></table>" ] ||
896
 
897
				 	// <thead> matched above
898
					(!tags.indexOf("<td") || !tags.indexOf("<th")) &&
899
					[ 3, "<table><tbody><tr>", "</tr></tbody></table>" ] ||
900
 
901
					!tags.indexOf("<col") &&
902
					[ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ] ||
903
 
904
					// IE can't serialize <link> and <script> tags normally
905
					!jQuery.support.htmlSerialize &&
906
					[ 1, "div<div>", "</div>" ] ||
907
 
908
					[ 0, "", "" ];
909
 
910
				// Go to html and back, then peel off extra wrappers
911
				div.innerHTML = wrap[1] + elem + wrap[2];
912
 
913
				// Move to the right depth
914
				while ( wrap[0]-- )
915
					div = div.lastChild;
916
 
917
				// Remove IE's autoinserted <tbody> from table fragments
918
				if ( !jQuery.support.tbody ) {
919
 
920
					// String was a <table>, *may* have spurious <tbody>
921
					var hasBody = /<tbody/i.test(elem),
922
						tbody = !tags.indexOf("<table") && !hasBody ?
923
							div.firstChild && div.firstChild.childNodes :
924
 
925
						// String was a bare <thead> or <tfoot>
926
						wrap[1] == "<table>" && !hasBody ?
927
							div.childNodes :
928
							[];
929
 
930
					for ( var j = tbody.length - 1; j >= 0 ; --j )
931
						if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length )
932
							tbody[ j ].parentNode.removeChild( tbody[ j ] );
933
 
934
					}
935
 
936
				// IE completely kills leading whitespace when innerHTML is used
937
				if ( !jQuery.support.leadingWhitespace && /^\s/.test( elem ) )
938
					div.insertBefore( context.createTextNode( elem.match(/^\s*/)[0] ), div.firstChild );
939
 
940
				elem = jQuery.makeArray( div.childNodes );
941
			}
942
 
943
			if ( elem.nodeType )
944
				ret.push( elem );
945
			else
946
				ret = jQuery.merge( ret, elem );
947
 
948
		});
949
 
950
		if ( fragment ) {
951
			for ( var i = 0; ret[i]; i++ ) {
952
				if ( jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
953
					scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
954
				} else {
955
					if ( ret[i].nodeType === 1 )
956
						ret.splice.apply( ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))) );
957
					fragment.appendChild( ret[i] );
958
				}
959
			}
960
 
961
			return scripts;
962
		}
963
 
964
		return ret;
965
	},
966
 
967
	attr: function( elem, name, value ) {
968
		// don't set attributes on text and comment nodes
969
		if (!elem || elem.nodeType == 3 || elem.nodeType == 8)
970
			return undefined;
971
 
972
		var notxml = !jQuery.isXMLDoc( elem ),
973
			// Whether we are setting (or getting)
974
			set = value !== undefined;
975
 
976
		// Try to normalize/fix the name
977
		name = notxml && jQuery.props[ name ] || name;
978
 
979
		// Only do all the following if this is a node (faster for style)
980
		// IE elem.getAttribute passes even for style
981
		if ( elem.tagName ) {
982
 
983
			// These attributes require special treatment
984
			var special = /href|src|style/.test( name );
985
 
986
			// Safari mis-reports the default selected property of a hidden option
987
			// Accessing the parent's selectedIndex property fixes it
988
			if ( name == "selected" && elem.parentNode )
989
				elem.parentNode.selectedIndex;
990
 
991
			// If applicable, access the attribute via the DOM 0 way
992
			if ( name in elem && notxml && !special ) {
993
				if ( set ){
994
					// We can't allow the type property to be changed (since it causes problems in IE)
995
					if ( name == "type" && jQuery.nodeName( elem, "input" ) && elem.parentNode )
996
						throw "type property can't be changed";
997
 
998
					elem[ name ] = value;
999
				}
1000
 
1001
				// browsers index elements by id/name on forms, give priority to attributes.
1002
				if( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) )
1003
					return elem.getAttributeNode( name ).nodeValue;
1004
 
1005
				// elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
1006
				// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
1007
				if ( name == "tabIndex" ) {
1008
					var attributeNode = elem.getAttributeNode( "tabIndex" );
1009
					return attributeNode && attributeNode.specified
1010
						? attributeNode.value
1011
						: elem.nodeName.match(/(button|input|object|select|textarea)/i)
1012
							? 0
1013
							: elem.nodeName.match(/^(a|area)$/i) && elem.href
1014
								? 0
1015
								: undefined;
1016
				}
1017
 
1018
				return elem[ name ];
1019
			}
1020
 
1021
			if ( !jQuery.support.style && notxml &&  name == "style" )
1022
				return jQuery.attr( elem.style, "cssText", value );
1023
 
1024
			if ( set )
1025
				// convert the value to a string (all browsers do this but IE) see #1070
1026
				elem.setAttribute( name, "" + value );
1027
 
1028
			var attr = !jQuery.support.hrefNormalized && notxml && special
1029
					// Some attributes require a special call on IE
1030
					? elem.getAttribute( name, 2 )
1031
					: elem.getAttribute( name );
1032
 
1033
			// Non-existent attributes return null, we normalize to undefined
1034
			return attr === null ? undefined : attr;
1035
		}
1036
 
1037
		// elem is actually elem.style ... set the style
1038
 
1039
		// IE uses filters for opacity
1040
		if ( !jQuery.support.opacity && name == "opacity" ) {
1041
			if ( set ) {
1042
				// IE has trouble with opacity if it does not have layout
1043
				// Force it by setting the zoom level
1044
				elem.zoom = 1;
1045
 
1046
				// Set the alpha filter to set the opacity
1047
				elem.filter = (elem.filter || "").replace( /alpha\([^)]*\)/, "" ) +
1048
					(parseInt( value ) + '' == "NaN" ? "" : "alpha(opacity=" + value * 100 + ")");
1049
			}
1050
 
1051
			return elem.filter && elem.filter.indexOf("opacity=") >= 0 ?
1052
				(parseFloat( elem.filter.match(/opacity=([^)]*)/)[1] ) / 100) + '':
1053
				"";
1054
		}
1055
 
1056
		name = name.replace(/-([a-z])/ig, function(all, letter){
1057
			return letter.toUpperCase();
1058
		});
1059
 
1060
		if ( set )
1061
			elem[ name ] = value;
1062
 
1063
		return elem[ name ];
1064
	},
1065
 
1066
	trim: function( text ) {
1067
		return (text || "").replace( /^\s+|\s+$/g, "" );
1068
	},
1069
 
1070
	makeArray: function( array ) {
1071
		var ret = [];
1072
 
1073
		if( array != null ){
1074
			var i = array.length;
1075
			// The window, strings (and functions) also have 'length'
1076
			if( i == null || typeof array === "string" || jQuery.isFunction(array) || array.setInterval )
1077
				ret[0] = array;
1078
			else
1079
				while( i )
1080
					ret[--i] = array[i];
1081
		}
1082
 
1083
		return ret;
1084
	},
1085
 
1086
	inArray: function( elem, array ) {
1087
		for ( var i = 0, length = array.length; i < length; i++ )
1088
		// Use === because on IE, window == document
1089
			if ( array[ i ] === elem )
1090
				return i;
1091
 
1092
		return -1;
1093
	},
1094
 
1095
	merge: function( first, second ) {
1096
		// We have to loop this way because IE & Opera overwrite the length
1097
		// expando of getElementsByTagName
1098
		var i = 0, elem, pos = first.length;
1099
		// Also, we need to make sure that the correct elements are being returned
1100
		// (IE returns comment nodes in a '*' query)
1101
		if ( !jQuery.support.getAll ) {
1102
			while ( (elem = second[ i++ ]) != null )
1103
				if ( elem.nodeType != 8 )
1104
					first[ pos++ ] = elem;
1105
 
1106
		} else
1107
			while ( (elem = second[ i++ ]) != null )
1108
				first[ pos++ ] = elem;
1109
 
1110
		return first;
1111
	},
1112
 
1113
	unique: function( array ) {
1114
		var ret = [], done = {};
1115
 
1116
		try {
1117
 
1118
			for ( var i = 0, length = array.length; i < length; i++ ) {
1119
				var id = jQuery.data( array[ i ] );
1120
 
1121
				if ( !done[ id ] ) {
1122
					done[ id ] = true;
1123
					ret.push( array[ i ] );
1124
				}
1125
			}
1126
 
1127
		} catch( e ) {
1128
			ret = array;
1129
		}
1130
 
1131
		return ret;
1132
	},
1133
 
1134
	grep: function( elems, callback, inv ) {
1135
		var ret = [];
1136
 
1137
		// Go through the array, only saving the items
1138
		// that pass the validator function
1139
		for ( var i = 0, length = elems.length; i < length; i++ )
1140
			if ( !inv != !callback( elems[ i ], i ) )
1141
				ret.push( elems[ i ] );
1142
 
1143
		return ret;
1144
	},
1145
 
1146
	map: function( elems, callback ) {
1147
		var ret = [];
1148
 
1149
		// Go through the array, translating each of the items to their
1150
		// new value (or values).
1151
		for ( var i = 0, length = elems.length; i < length; i++ ) {
1152
			var value = callback( elems[ i ], i );
1153
 
1154
			if ( value != null )
1155
				ret[ ret.length ] = value;
1156
		}
1157
 
1158
		return ret.concat.apply( [], ret );
1159
	}
1160
});
1161
 
1162
// Use of jQuery.browser is deprecated.
1163
// It's included for backwards compatibility and plugins,
1164
// although they should work to migrate away.
1165
 
1166
var userAgent = navigator.userAgent.toLowerCase();
1167
 
1168
// Figure out what browser is being used
1169
jQuery.browser = {
1170
	version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [0,'0'])[1],
1171
	safari: /webkit/.test( userAgent ),
1172
	opera: /opera/.test( userAgent ),
1173
	msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ),
1174
	mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent )
1175
};
1176
 
1177
jQuery.each({
1178
	parent: function(elem){return elem.parentNode;},
1179
	parents: function(elem){return jQuery.dir(elem,"parentNode");},
1180
	next: function(elem){return jQuery.nth(elem,2,"nextSibling");},
1181
	prev: function(elem){return jQuery.nth(elem,2,"previousSibling");},
1182
	nextAll: function(elem){return jQuery.dir(elem,"nextSibling");},
1183
	prevAll: function(elem){return jQuery.dir(elem,"previousSibling");},
1184
	siblings: function(elem){return jQuery.sibling(elem.parentNode.firstChild,elem);},
1185
	children: function(elem){return jQuery.sibling(elem.firstChild);},
1186
	contents: function(elem){return jQuery.nodeName(elem,"iframe")?elem.contentDocument||elem.contentWindow.document:jQuery.makeArray(elem.childNodes);}
1187
}, function(name, fn){
1188
	jQuery.fn[ name ] = function( selector ) {
1189
		var ret = jQuery.map( this, fn );
1190
 
1191
		if ( selector && typeof selector == "string" )
1192
			ret = jQuery.multiFilter( selector, ret );
1193
 
1194
		return this.pushStack( jQuery.unique( ret ), name, selector );
1195
	};
1196
});
1197
 
1198
jQuery.each({
1199
	appendTo: "append",
1200
	prependTo: "prepend",
1201
	insertBefore: "before",
1202
	insertAfter: "after",
1203
	replaceAll: "replaceWith"
1204
}, function(name, original){
1205
	jQuery.fn[ name ] = function( selector ) {
1206
		var ret = [], insert = jQuery( selector );
1207
 
1208
		for ( var i = 0, l = insert.length; i < l; i++ ) {
1209
			var elems = (i > 0 ? this.clone(true) : this).get();
1210
			jQuery.fn[ original ].apply( jQuery(insert[i]), elems );
1211
			ret = ret.concat( elems );
1212
		}
1213
 
1214
		return this.pushStack( ret, name, selector );
1215
	};
1216
});
1217
 
1218
jQuery.each({
1219
	removeAttr: function( name ) {
1220
		jQuery.attr( this, name, "" );
1221
		if (this.nodeType == 1)
1222
			this.removeAttribute( name );
1223
	},
1224
 
1225
	addClass: function( classNames ) {
1226
		jQuery.className.add( this, classNames );
1227
	},
1228
 
1229
	removeClass: function( classNames ) {
1230
		jQuery.className.remove( this, classNames );
1231
	},
1232
 
1233
	toggleClass: function( classNames, state ) {
1234
		if( typeof state !== "boolean" )
1235
			state = !jQuery.className.has( this, classNames );
1236
		jQuery.className[ state ? "add" : "remove" ]( this, classNames );
1237
	},
1238
 
1239
	remove: function( selector ) {
1240
		if ( !selector || jQuery.filter( selector, [ this ] ).length ) {
1241
			// Prevent memory leaks
1242
			jQuery( "*", this ).add([this]).each(function(){
1243
				jQuery.event.remove(this);
1244
				jQuery.removeData(this);
1245
			});
1246
			if (this.parentNode)
1247
				this.parentNode.removeChild( this );
1248
		}
1249
	},
1250
 
1251
	empty: function() {
1252
		// Remove element nodes and prevent memory leaks
1253
		jQuery(this).children().remove();
1254
 
1255
		// Remove any remaining nodes
1256
		while ( this.firstChild )
1257
			this.removeChild( this.firstChild );
1258
	}
1259
}, function(name, fn){
1260
	jQuery.fn[ name ] = function(){
1261
		return this.each( fn, arguments );
1262
	};
1263
});
1264
 
1265
// Helper function used by the dimensions and offset modules
1266
function num(elem, prop) {
1267
	return elem[0] && parseInt( jQuery.curCSS(elem[0], prop, true), 10 ) || 0;
1268
}
1269
var expando = "jQuery" + now(), uuid = 0, windowData = {};
1270
 
1271
jQuery.extend({
1272
	cache: {},
1273
 
1274
	data: function( elem, name, data ) {
1275
		elem = elem == window ?
1276
			windowData :
1277
			elem;
1278
 
1279
		var id = elem[ expando ];
1280
 
1281
		// Compute a unique ID for the element
1282
		if ( !id )
1283
			id = elem[ expando ] = ++uuid;
1284
 
1285
		// Only generate the data cache if we're
1286
		// trying to access or manipulate it
1287
		if ( name && !jQuery.cache[ id ] )
1288
			jQuery.cache[ id ] = {};
1289
 
1290
		// Prevent overriding the named cache with undefined values
1291
		if ( data !== undefined )
1292
			jQuery.cache[ id ][ name ] = data;
1293
 
1294
		// Return the named cache data, or the ID for the element
1295
		return name ?
1296
			jQuery.cache[ id ][ name ] :
1297
			id;
1298
	},
1299
 
1300
	removeData: function( elem, name ) {
1301
		elem = elem == window ?
1302
			windowData :
1303
			elem;
1304
 
1305
		var id = elem[ expando ];
1306
 
1307
		// If we want to remove a specific section of the element's data
1308
		if ( name ) {
1309
			if ( jQuery.cache[ id ] ) {
1310
				// Remove the section of cache data
1311
				delete jQuery.cache[ id ][ name ];
1312
 
1313
				// If we've removed all the data, remove the element's cache
1314
				name = "";
1315
 
1316
				for ( name in jQuery.cache[ id ] )
1317
					break;
1318
 
1319
				if ( !name )
1320
					jQuery.removeData( elem );
1321
			}
1322
 
1323
		// Otherwise, we want to remove all of the element's data
1324
		} else {
1325
			// Clean up the element expando
1326
			try {
1327
				delete elem[ expando ];
1328
			} catch(e){
1329
				// IE has trouble directly removing the expando
1330
				// but it's ok with using removeAttribute
1331
				if ( elem.removeAttribute )
1332
					elem.removeAttribute( expando );
1333
			}
1334
 
1335
			// Completely remove the data cache
1336
			delete jQuery.cache[ id ];
1337
		}
1338
	},
1339
	queue: function( elem, type, data ) {
1340
		if ( elem ){
1341
 
1342
			type = (type || "fx") + "queue";
1343
 
1344
			var q = jQuery.data( elem, type );
1345
 
1346
			if ( !q || jQuery.isArray(data) )
1347
				q = jQuery.data( elem, type, jQuery.makeArray(data) );
1348
			else if( data )
1349
				q.push( data );
1350
 
1351
		}
1352
		return q;
1353
	},
1354
 
1355
	dequeue: function( elem, type ){
1356
		var queue = jQuery.queue( elem, type ),
1357
			fn = queue.shift();
1358
 
1359
		if( !type || type === "fx" )
1360
			fn = queue[0];
1361
 
1362
		if( fn !== undefined )
1363
			fn.call(elem);
1364
	}
1365
});
1366
 
1367
jQuery.fn.extend({
1368
	data: function( key, value ){
1369
		var parts = key.split(".");
1370
		parts[1] = parts[1] ? "." + parts[1] : "";
1371
 
1372
		if ( value === undefined ) {
1373
			var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
1374
 
1375
			if ( data === undefined && this.length )
1376
				data = jQuery.data( this[0], key );
1377
 
1378
			return data === undefined && parts[1] ?
1379
				this.data( parts[0] ) :
1380
				data;
1381
		} else
1382
			return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function(){
1383
				jQuery.data( this, key, value );
1384
			});
1385
	},
1386
 
1387
	removeData: function( key ){
1388
		return this.each(function(){
1389
			jQuery.removeData( this, key );
1390
		});
1391
	},
1392
	queue: function(type, data){
1393
		if ( typeof type !== "string" ) {
1394
			data = type;
1395
			type = "fx";
1396
		}
1397
 
1398
		if ( data === undefined )
1399
			return jQuery.queue( this[0], type );
1400
 
1401
		return this.each(function(){
1402
			var queue = jQuery.queue( this, type, data );
1403
 
1404
			 if( type == "fx" && queue.length == 1 )
1405
				queue[0].call(this);
1406
		});
1407
	},
1408
	dequeue: function(type){
1409
		return this.each(function(){
1410
			jQuery.dequeue( this, type );
1411
		});
1412
	}
1413
});/*!
1414
 * Sizzle CSS Selector Engine - v0.9.3
1415
 *  Copyright 2009, The Dojo Foundation
1416
 *  Released under the MIT, BSD, and GPL Licenses.
1417
 *  More information: http://sizzlejs.com/
1418
 */
1419
(function(){
1420
 
1421
var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,
1422
	done = 0,
1423
	toString = Object.prototype.toString;
1424
 
1425
var Sizzle = function(selector, context, results, seed) {
1426
	results = results || [];
1427
	context = context || document;
1428
 
1429
	if ( context.nodeType !== 1 && context.nodeType !== 9 )
1430
		return [];
1431
 
1432
	if ( !selector || typeof selector !== "string" ) {
1433
		return results;
1434
	}
1435
 
1436
	var parts = [], m, set, checkSet, check, mode, extra, prune = true;
1437
 
1438
	// Reset the position of the chunker regexp (start from head)
1439
	chunker.lastIndex = 0;
1440
 
1441
	while ( (m = chunker.exec(selector)) !== null ) {
1442
		parts.push( m[1] );
1443
 
1444
		if ( m[2] ) {
1445
			extra = RegExp.rightContext;
1446
			break;
1447
		}
1448
	}
1449
 
1450
	if ( parts.length > 1 && origPOS.exec( selector ) ) {
1451
		if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
1452
			set = posProcess( parts[0] + parts[1], context );
1453
		} else {
1454
			set = Expr.relative[ parts[0] ] ?
1455
				[ context ] :
1456
				Sizzle( parts.shift(), context );
1457
 
1458
			while ( parts.length ) {
1459
				selector = parts.shift();
1460
 
1461
				if ( Expr.relative[ selector ] )
1462
					selector += parts.shift();
1463
 
1464
				set = posProcess( selector, set );
1465
			}
1466
		}
1467
	} else {
1468
		var ret = seed ?
1469
			{ expr: parts.pop(), set: makeArray(seed) } :
1470
			Sizzle.find( parts.pop(), parts.length === 1 && context.parentNode ? context.parentNode : context, isXML(context) );
1471
		set = Sizzle.filter( ret.expr, ret.set );
1472
 
1473
		if ( parts.length > 0 ) {
1474
			checkSet = makeArray(set);
1475
		} else {
1476
			prune = false;
1477
		}
1478
 
1479
		while ( parts.length ) {
1480
			var cur = parts.pop(), pop = cur;
1481
 
1482
			if ( !Expr.relative[ cur ] ) {
1483
				cur = "";
1484
			} else {
1485
				pop = parts.pop();
1486
			}
1487
 
1488
			if ( pop == null ) {
1489
				pop = context;
1490
			}
1491
 
1492
			Expr.relative[ cur ]( checkSet, pop, isXML(context) );
1493
		}
1494
	}
1495
 
1496
	if ( !checkSet ) {
1497
		checkSet = set;
1498
	}
1499
 
1500
	if ( !checkSet ) {
1501
		throw "Syntax error, unrecognized expression: " + (cur || selector);
1502
	}
1503
 
1504
	if ( toString.call(checkSet) === "[object Array]" ) {
1505
		if ( !prune ) {
1506
			results.push.apply( results, checkSet );
1507
		} else if ( context.nodeType === 1 ) {
1508
			for ( var i = 0; checkSet[i] != null; i++ ) {
1509
				if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) {
1510
					results.push( set[i] );
1511
				}
1512
			}
1513
		} else {
1514
			for ( var i = 0; checkSet[i] != null; i++ ) {
1515
				if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
1516
					results.push( set[i] );
1517
				}
1518
			}
1519
		}
1520
	} else {
1521
		makeArray( checkSet, results );
1522
	}
1523
 
1524
	if ( extra ) {
1525
		Sizzle( extra, context, results, seed );
1526
 
1527
		if ( sortOrder ) {
1528
			hasDuplicate = false;
1529
			results.sort(sortOrder);
1530
 
1531
			if ( hasDuplicate ) {
1532
				for ( var i = 1; i < results.length; i++ ) {
1533
					if ( results[i] === results[i-1] ) {
1534
						results.splice(i--, 1);
1535
					}
1536
				}
1537
			}
1538
		}
1539
	}
1540
 
1541
	return results;
1542
};
1543
 
1544
Sizzle.matches = function(expr, set){
1545
	return Sizzle(expr, null, null, set);
1546
};
1547
 
1548
Sizzle.find = function(expr, context, isXML){
1549
	var set, match;
1550
 
1551
	if ( !expr ) {
1552
		return [];
1553
	}
1554
 
1555
	for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
1556
		var type = Expr.order[i], match;
1557
 
1558
		if ( (match = Expr.match[ type ].exec( expr )) ) {
1559
			var left = RegExp.leftContext;
1560
 
1561
			if ( left.substr( left.length - 1 ) !== "\\" ) {
1562
				match[1] = (match[1] || "").replace(/\\/g, "");
1563
				set = Expr.find[ type ]( match, context, isXML );
1564
				if ( set != null ) {
1565
					expr = expr.replace( Expr.match[ type ], "" );
1566
					break;
1567
				}
1568
			}
1569
		}
1570
	}
1571
 
1572
	if ( !set ) {
1573
		set = context.getElementsByTagName("*");
1574
	}
1575
 
1576
	return {set: set, expr: expr};
1577
};
1578
 
1579
Sizzle.filter = function(expr, set, inplace, not){
1580
	var old = expr, result = [], curLoop = set, match, anyFound,
1581
		isXMLFilter = set && set[0] && isXML(set[0]);
1582
 
1583
	while ( expr && set.length ) {
1584
		for ( var type in Expr.filter ) {
1585
			if ( (match = Expr.match[ type ].exec( expr )) != null ) {
1586
				var filter = Expr.filter[ type ], found, item;
1587
				anyFound = false;
1588
 
1589
				if ( curLoop == result ) {
1590
					result = [];
1591
				}
1592
 
1593
				if ( Expr.preFilter[ type ] ) {
1594
					match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
1595
 
1596
					if ( !match ) {
1597
						anyFound = found = true;
1598
					} else if ( match === true ) {
1599
						continue;
1600
					}
1601
				}
1602
 
1603
				if ( match ) {
1604
					for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
1605
						if ( item ) {
1606
							found = filter( item, match, i, curLoop );
1607
							var pass = not ^ !!found;
1608
 
1609
							if ( inplace && found != null ) {
1610
								if ( pass ) {
1611
									anyFound = true;
1612
								} else {
1613
									curLoop[i] = false;
1614
								}
1615
							} else if ( pass ) {
1616
								result.push( item );
1617
								anyFound = true;
1618
							}
1619
						}
1620
					}
1621
				}
1622
 
1623
				if ( found !== undefined ) {
1624
					if ( !inplace ) {
1625
						curLoop = result;
1626
					}
1627
 
1628
					expr = expr.replace( Expr.match[ type ], "" );
1629
 
1630
					if ( !anyFound ) {
1631
						return [];
1632
					}
1633
 
1634
					break;
1635
				}
1636
			}
1637
		}
1638
 
1639
		// Improper expression
1640
		if ( expr == old ) {
1641
			if ( anyFound == null ) {
1642
				throw "Syntax error, unrecognized expression: " + expr;
1643
			} else {
1644
				break;
1645
			}
1646
		}
1647
 
1648
		old = expr;
1649
	}
1650
 
1651
	return curLoop;
1652
};
1653
 
1654
var Expr = Sizzle.selectors = {
1655
	order: [ "ID", "NAME", "TAG" ],
1656
	match: {
1657
		ID: /#((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,
1658
		CLASS: /\.((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,
1659
		NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF_-]|\\.)+)['"]*\]/,
1660
		ATTR: /\[\s*((?:[\w\u00c0-\uFFFF_-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
1661
		TAG: /^((?:[\w\u00c0-\uFFFF\*_-]|\\.)+)/,
1662
		CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,
1663
		POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,
1664
		PSEUDO: /:((?:[\w\u00c0-\uFFFF_-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/
1665
	},
1666
	attrMap: {
1667
		"class": "className",
1668
		"for": "htmlFor"
1669
	},
1670
	attrHandle: {
1671
		href: function(elem){
1672
			return elem.getAttribute("href");
1673
		}
1674
	},
1675
	relative: {
1676
		"+": function(checkSet, part, isXML){
1677
			var isPartStr = typeof part === "string",
1678
				isTag = isPartStr && !/\W/.test(part),
1679
				isPartStrNotTag = isPartStr && !isTag;
1680
 
1681
			if ( isTag && !isXML ) {
1682
				part = part.toUpperCase();
1683
			}
1684
 
1685
			for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
1686
				if ( (elem = checkSet[i]) ) {
1687
					while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
1688
 
1689
					checkSet[i] = isPartStrNotTag || elem && elem.nodeName === part ?
1690
						elem || false :
1691
						elem === part;
1692
				}
1693
			}
1694
 
1695
			if ( isPartStrNotTag ) {
1696
				Sizzle.filter( part, checkSet, true );
1697
			}
1698
		},
1699
		">": function(checkSet, part, isXML){
1700
			var isPartStr = typeof part === "string";
1701
 
1702
			if ( isPartStr && !/\W/.test(part) ) {
1703
				part = isXML ? part : part.toUpperCase();
1704
 
1705
				for ( var i = 0, l = checkSet.length; i < l; i++ ) {
1706
					var elem = checkSet[i];
1707
					if ( elem ) {
1708
						var parent = elem.parentNode;
1709
						checkSet[i] = parent.nodeName === part ? parent : false;
1710
					}
1711
				}
1712
			} else {
1713
				for ( var i = 0, l = checkSet.length; i < l; i++ ) {
1714
					var elem = checkSet[i];
1715
					if ( elem ) {
1716
						checkSet[i] = isPartStr ?
1717
							elem.parentNode :
1718
							elem.parentNode === part;
1719
					}
1720
				}
1721
 
1722
				if ( isPartStr ) {
1723
					Sizzle.filter( part, checkSet, true );
1724
				}
1725
			}
1726
		},
1727
		"": function(checkSet, part, isXML){
1728
			var doneName = done++, checkFn = dirCheck;
1729
 
1730
			if ( !part.match(/\W/) ) {
1731
				var nodeCheck = part = isXML ? part : part.toUpperCase();
1732
				checkFn = dirNodeCheck;
1733
			}
1734
 
1735
			checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML);
1736
		},
1737
		"~": function(checkSet, part, isXML){
1738
			var doneName = done++, checkFn = dirCheck;
1739
 
1740
			if ( typeof part === "string" && !part.match(/\W/) ) {
1741
				var nodeCheck = part = isXML ? part : part.toUpperCase();
1742
				checkFn = dirNodeCheck;
1743
			}
1744
 
1745
			checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML);
1746
		}
1747
	},
1748
	find: {
1749
		ID: function(match, context, isXML){
1750
			if ( typeof context.getElementById !== "undefined" && !isXML ) {
1751
				var m = context.getElementById(match[1]);
1752
				return m ? [m] : [];
1753
			}
1754
		},
1755
		NAME: function(match, context, isXML){
1756
			if ( typeof context.getElementsByName !== "undefined" ) {
1757
				var ret = [], results = context.getElementsByName(match[1]);
1758
 
1759
				for ( var i = 0, l = results.length; i < l; i++ ) {
1760
					if ( results[i].getAttribute("name") === match[1] ) {
1761
						ret.push( results[i] );
1762
					}
1763
				}
1764
 
1765
				return ret.length === 0 ? null : ret;
1766
			}
1767
		},
1768
		TAG: function(match, context){
1769
			return context.getElementsByTagName(match[1]);
1770
		}
1771
	},
1772
	preFilter: {
1773
		CLASS: function(match, curLoop, inplace, result, not, isXML){
1774
			match = " " + match[1].replace(/\\/g, "") + " ";
1775
 
1776
			if ( isXML ) {
1777
				return match;
1778
			}
1779
 
1780
			for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
1781
				if ( elem ) {
1782
					if ( not ^ (elem.className && (" " + elem.className + " ").indexOf(match) >= 0) ) {
1783
						if ( !inplace )
1784
							result.push( elem );
1785
					} else if ( inplace ) {
1786
						curLoop[i] = false;
1787
					}
1788
				}
1789
			}
1790
 
1791
			return false;
1792
		},
1793
		ID: function(match){
1794
			return match[1].replace(/\\/g, "");
1795
		},
1796
		TAG: function(match, curLoop){
1797
			for ( var i = 0; curLoop[i] === false; i++ ){}
1798
			return curLoop[i] && isXML(curLoop[i]) ? match[1] : match[1].toUpperCase();
1799
		},
1800
		CHILD: function(match){
1801
			if ( match[1] == "nth" ) {
1802
				// parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
1803
				var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
1804
					match[2] == "even" && "2n" || match[2] == "odd" && "2n+1" ||
1805
					!/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
1806
 
1807
				// calculate the numbers (first)n+(last) including if they are negative
1808
				match[2] = (test[1] + (test[2] || 1)) - 0;
1809
				match[3] = test[3] - 0;
1810
			}
1811
 
1812
			// TODO: Move to normal caching system
1813
			match[0] = done++;
1814
 
1815
			return match;
1816
		},
1817
		ATTR: function(match, curLoop, inplace, result, not, isXML){
1818
			var name = match[1].replace(/\\/g, "");
1819
 
1820
			if ( !isXML && Expr.attrMap[name] ) {
1821
				match[1] = Expr.attrMap[name];
1822
			}
1823
 
1824
			if ( match[2] === "~=" ) {
1825
				match[4] = " " + match[4] + " ";
1826
			}
1827
 
1828
			return match;
1829
		},
1830
		PSEUDO: function(match, curLoop, inplace, result, not){
1831
			if ( match[1] === "not" ) {
1832
				// If we're dealing with a complex expression, or a simple one
1833
				if ( match[3].match(chunker).length > 1 || /^\w/.test(match[3]) ) {
1834
					match[3] = Sizzle(match[3], null, null, curLoop);
1835
				} else {
1836
					var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
1837
					if ( !inplace ) {
1838
						result.push.apply( result, ret );
1839
					}
1840
					return false;
1841
				}
1842
			} else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
1843
				return true;
1844
			}
1845
 
1846
			return match;
1847
		},
1848
		POS: function(match){
1849
			match.unshift( true );
1850
			return match;
1851
		}
1852
	},
1853
	filters: {
1854
		enabled: function(elem){
1855
			return elem.disabled === false && elem.type !== "hidden";
1856
		},
1857
		disabled: function(elem){
1858
			return elem.disabled === true;
1859
		},
1860
		checked: function(elem){
1861
			return elem.checked === true;
1862
		},
1863
		selected: function(elem){
1864
			// Accessing this property makes selected-by-default
1865
			// options in Safari work properly
1866
			elem.parentNode.selectedIndex;
1867
			return elem.selected === true;
1868
		},
1869
		parent: function(elem){
1870
			return !!elem.firstChild;
1871
		},
1872
		empty: function(elem){
1873
			return !elem.firstChild;
1874
		},
1875
		has: function(elem, i, match){
1876
			return !!Sizzle( match[3], elem ).length;
1877
		},
1878
		header: function(elem){
1879
			return /h\d/i.test( elem.nodeName );
1880
		},
1881
		text: function(elem){
1882
			return "text" === elem.type;
1883
		},
1884
		radio: function(elem){
1885
			return "radio" === elem.type;
1886
		},
1887
		checkbox: function(elem){
1888
			return "checkbox" === elem.type;
1889
		},
1890
		file: function(elem){
1891
			return "file" === elem.type;
1892
		},
1893
		password: function(elem){
1894
			return "password" === elem.type;
1895
		},
1896
		submit: function(elem){
1897
			return "submit" === elem.type;
1898
		},
1899
		image: function(elem){
1900
			return "image" === elem.type;
1901
		},
1902
		reset: function(elem){
1903
			return "reset" === elem.type;
1904
		},
1905
		button: function(elem){
1906
			return "button" === elem.type || elem.nodeName.toUpperCase() === "BUTTON";
1907
		},
1908
		input: function(elem){
1909
			return /input|select|textarea|button/i.test(elem.nodeName);
1910
		}
1911
	},
1912
	setFilters: {
1913
		first: function(elem, i){
1914
			return i === 0;
1915
		},
1916
		last: function(elem, i, match, array){
1917
			return i === array.length - 1;
1918
		},
1919
		even: function(elem, i){
1920
			return i % 2 === 0;
1921
		},
1922
		odd: function(elem, i){
1923
			return i % 2 === 1;
1924
		},
1925
		lt: function(elem, i, match){
1926
			return i < match[3] - 0;
1927
		},
1928
		gt: function(elem, i, match){
1929
			return i > match[3] - 0;
1930
		},
1931
		nth: function(elem, i, match){
1932
			return match[3] - 0 == i;
1933
		},
1934
		eq: function(elem, i, match){
1935
			return match[3] - 0 == i;
1936
		}
1937
	},
1938
	filter: {
1939
		PSEUDO: function(elem, match, i, array){
1940
			var name = match[1], filter = Expr.filters[ name ];
1941
 
1942
			if ( filter ) {
1943
				return filter( elem, i, match, array );
1944
			} else if ( name === "contains" ) {
1945
				return (elem.textContent || elem.innerText || "").indexOf(match[3]) >= 0;
1946
			} else if ( name === "not" ) {
1947
				var not = match[3];
1948
 
1949
				for ( var i = 0, l = not.length; i < l; i++ ) {
1950
					if ( not[i] === elem ) {
1951
						return false;
1952
					}
1953
				}
1954
 
1955
				return true;
1956
			}
1957
		},
1958
		CHILD: function(elem, match){
1959
			var type = match[1], node = elem;
1960
			switch (type) {
1961
				case 'only':
1962
				case 'first':
1963
					while (node = node.previousSibling)  {
1964
						if ( node.nodeType === 1 ) return false;
1965
					}
1966
					if ( type == 'first') return true;
1967
					node = elem;
1968
				case 'last':
1969
					while (node = node.nextSibling)  {
1970
						if ( node.nodeType === 1 ) return false;
1971
					}
1972
					return true;
1973
				case 'nth':
1974
					var first = match[2], last = match[3];
1975
 
1976
					if ( first == 1 && last == 0 ) {
1977
						return true;
1978
					}
1979
 
1980
					var doneName = match[0],
1981
						parent = elem.parentNode;
1982
 
1983
					if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
1984
						var count = 0;
1985
						for ( node = parent.firstChild; node; node = node.nextSibling ) {
1986
							if ( node.nodeType === 1 ) {
1987
								node.nodeIndex = ++count;
1988
							}
1989
						}
1990
						parent.sizcache = doneName;
1991
					}
1992
 
1993
					var diff = elem.nodeIndex - last;
1994
					if ( first == 0 ) {
1995
						return diff == 0;
1996
					} else {
1997
						return ( diff % first == 0 && diff / first >= 0 );
1998
					}
1999
			}
2000
		},
2001
		ID: function(elem, match){
2002
			return elem.nodeType === 1 && elem.getAttribute("id") === match;
2003
		},
2004
		TAG: function(elem, match){
2005
			return (match === "*" && elem.nodeType === 1) || elem.nodeName === match;
2006
		},
2007
		CLASS: function(elem, match){
2008
			return (" " + (elem.className || elem.getAttribute("class")) + " ")
2009
				.indexOf( match ) > -1;
2010
		},
2011
		ATTR: function(elem, match){
2012
			var name = match[1],
2013
				result = Expr.attrHandle[ name ] ?
2014
					Expr.attrHandle[ name ]( elem ) :
2015
					elem[ name ] != null ?
2016
						elem[ name ] :
2017
						elem.getAttribute( name ),
2018
				value = result + "",
2019
				type = match[2],
2020
				check = match[4];
2021
 
2022
			return result == null ?
2023
				type === "!=" :
2024
				type === "=" ?
2025
				value === check :
2026
				type === "*=" ?
2027
				value.indexOf(check) >= 0 :
2028
				type === "~=" ?
2029
				(" " + value + " ").indexOf(check) >= 0 :
2030
				!check ?
2031
				value && result !== false :
2032
				type === "!=" ?
2033
				value != check :
2034
				type === "^=" ?
2035
				value.indexOf(check) === 0 :
2036
				type === "$=" ?
2037
				value.substr(value.length - check.length) === check :
2038
				type === "|=" ?
2039
				value === check || value.substr(0, check.length + 1) === check + "-" :
2040
				false;
2041
		},
2042
		POS: function(elem, match, i, array){
2043
			var name = match[2], filter = Expr.setFilters[ name ];
2044
 
2045
			if ( filter ) {
2046
				return filter( elem, i, match, array );
2047
			}
2048
		}
2049
	}
2050
};
2051
 
2052
var origPOS = Expr.match.POS;
2053
 
2054
for ( var type in Expr.match ) {
2055
	Expr.match[ type ] = RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source );
2056
}
2057
 
2058
var makeArray = function(array, results) {
2059
	array = Array.prototype.slice.call( array );
2060
 
2061
	if ( results ) {
2062
		results.push.apply( results, array );
2063
		return results;
2064
	}
2065
 
2066
	return array;
2067
};
2068
 
2069
// Perform a simple check to determine if the browser is capable of
2070
// converting a NodeList to an array using builtin methods.
2071
try {
2072
	Array.prototype.slice.call( document.documentElement.childNodes );
2073
 
2074
// Provide a fallback method if it does not work
2075
} catch(e){
2076
	makeArray = function(array, results) {
2077
		var ret = results || [];
2078
 
2079
		if ( toString.call(array) === "[object Array]" ) {
2080
			Array.prototype.push.apply( ret, array );
2081
		} else {
2082
			if ( typeof array.length === "number" ) {
2083
				for ( var i = 0, l = array.length; i < l; i++ ) {
2084
					ret.push( array[i] );
2085
				}
2086
			} else {
2087
				for ( var i = 0; array[i]; i++ ) {
2088
					ret.push( array[i] );
2089
				}
2090
			}
2091
		}
2092
 
2093
		return ret;
2094
	};
2095
}
2096
 
2097
var sortOrder;
2098
 
2099
if ( document.documentElement.compareDocumentPosition ) {
2100
	sortOrder = function( a, b ) {
2101
		var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
2102
		if ( ret === 0 ) {
2103
			hasDuplicate = true;
2104
		}
2105
		return ret;
2106
	};
2107
} else if ( "sourceIndex" in document.documentElement ) {
2108
	sortOrder = function( a, b ) {
2109
		var ret = a.sourceIndex - b.sourceIndex;
2110
		if ( ret === 0 ) {
2111
			hasDuplicate = true;
2112
		}
2113
		return ret;
2114
	};
2115
} else if ( document.createRange ) {
2116
	sortOrder = function( a, b ) {
2117
		var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange();
2118
		aRange.selectNode(a);
2119
		aRange.collapse(true);
2120
		bRange.selectNode(b);
2121
		bRange.collapse(true);
2122
		var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
2123
		if ( ret === 0 ) {
2124
			hasDuplicate = true;
2125
		}
2126
		return ret;
2127
	};
2128
}
2129
 
2130
// Check to see if the browser returns elements by name when
2131
// querying by getElementById (and provide a workaround)
2132
(function(){
2133
	// We're going to inject a fake input element with a specified name
2134
	var form = document.createElement("form"),
2135
		id = "script" + (new Date).getTime();
2136
	form.innerHTML = "<input name='" + id + "'/>";
2137
 
2138
	// Inject it into the root element, check its status, and remove it quickly
2139
	var root = document.documentElement;
2140
	root.insertBefore( form, root.firstChild );
2141
 
2142
	// The workaround has to do additional checks after a getElementById
2143
	// Which slows things down for other browsers (hence the branching)
2144
	if ( !!document.getElementById( id ) ) {
2145
		Expr.find.ID = function(match, context, isXML){
2146
			if ( typeof context.getElementById !== "undefined" && !isXML ) {
2147
				var m = context.getElementById(match[1]);
2148
				return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : [];
2149
			}
2150
		};
2151
 
2152
		Expr.filter.ID = function(elem, match){
2153
			var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
2154
			return elem.nodeType === 1 && node && node.nodeValue === match;
2155
		};
2156
	}
2157
 
2158
	root.removeChild( form );
2159
})();
2160
 
2161
(function(){
2162
	// Check to see if the browser returns only elements
2163
	// when doing getElementsByTagName("*")
2164
 
2165
	// Create a fake element
2166
	var div = document.createElement("div");
2167
	div.appendChild( document.createComment("") );
2168
 
2169
	// Make sure no comments are found
2170
	if ( div.getElementsByTagName("*").length > 0 ) {
2171
		Expr.find.TAG = function(match, context){
2172
			var results = context.getElementsByTagName(match[1]);
2173
 
2174
			// Filter out possible comments
2175
			if ( match[1] === "*" ) {
2176
				var tmp = [];
2177
 
2178
				for ( var i = 0; results[i]; i++ ) {
2179
					if ( results[i].nodeType === 1 ) {
2180
						tmp.push( results[i] );
2181
					}
2182
				}
2183
 
2184
				results = tmp;
2185
			}
2186
 
2187
			return results;
2188
		};
2189
	}
2190
 
2191
	// Check to see if an attribute returns normalized href attributes
2192
	div.innerHTML = "<a href='#'></a>";
2193
	if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
2194
			div.firstChild.getAttribute("href") !== "#" ) {
2195
		Expr.attrHandle.href = function(elem){
2196
			return elem.getAttribute("href", 2);
2197
		};
2198
	}
2199
})();
2200
 
2201
if ( document.querySelectorAll ) (function(){
2202
	var oldSizzle = Sizzle, div = document.createElement("div");
2203
	div.innerHTML = "<p class='TEST'></p>";
2204
 
2205
	// Safari can't handle uppercase or unicode characters when
2206
	// in quirks mode.
2207
	if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
2208
		return;
2209
	}
2210
 
2211
	Sizzle = function(query, context, extra, seed){
2212
		context = context || document;
2213
 
2214
		// Only use querySelectorAll on non-XML documents
2215
		// (ID selectors don't work in non-HTML documents)
2216
		if ( !seed && context.nodeType === 9 && !isXML(context) ) {
2217
			try {
2218
				return makeArray( context.querySelectorAll(query), extra );
2219
			} catch(e){}
2220
		}
2221
 
2222
		return oldSizzle(query, context, extra, seed);
2223
	};
2224
 
2225
	Sizzle.find = oldSizzle.find;
2226
	Sizzle.filter = oldSizzle.filter;
2227
	Sizzle.selectors = oldSizzle.selectors;
2228
	Sizzle.matches = oldSizzle.matches;
2229
})();
2230
 
2231
if ( document.getElementsByClassName && document.documentElement.getElementsByClassName ) (function(){
2232
	var div = document.createElement("div");
2233
	div.innerHTML = "<div class='test e'></div><div class='test'></div>";
2234
 
2235
	// Opera can't find a second classname (in 9.6)
2236
	if ( div.getElementsByClassName("e").length === 0 )
2237
		return;
2238
 
2239
	// Safari caches class attributes, doesn't catch changes (in 3.2)
2240
	div.lastChild.className = "e";
2241
 
2242
	if ( div.getElementsByClassName("e").length === 1 )
2243
		return;
2244
 
2245
	Expr.order.splice(1, 0, "CLASS");
2246
	Expr.find.CLASS = function(match, context, isXML) {
2247
		if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
2248
			return context.getElementsByClassName(match[1]);
2249
		}
2250
	};
2251
})();
2252
 
2253
function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
2254
	var sibDir = dir == "previousSibling" && !isXML;
2255
	for ( var i = 0, l = checkSet.length; i < l; i++ ) {
2256
		var elem = checkSet[i];
2257
		if ( elem ) {
2258
			if ( sibDir && elem.nodeType === 1 ){
2259
				elem.sizcache = doneName;
2260
				elem.sizset = i;
2261
			}
2262
			elem = elem[dir];
2263
			var match = false;
2264
 
2265
			while ( elem ) {
2266
				if ( elem.sizcache === doneName ) {
2267
					match = checkSet[elem.sizset];
2268
					break;
2269
				}
2270
 
2271
				if ( elem.nodeType === 1 && !isXML ){
2272
					elem.sizcache = doneName;
2273
					elem.sizset = i;
2274
				}
2275
 
2276
				if ( elem.nodeName === cur ) {
2277
					match = elem;
2278
					break;
2279
				}
2280
 
2281
				elem = elem[dir];
2282
			}
2283
 
2284
			checkSet[i] = match;
2285
		}
2286
	}
2287
}
2288
 
2289
function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
2290
	var sibDir = dir == "previousSibling" && !isXML;
2291
	for ( var i = 0, l = checkSet.length; i < l; i++ ) {
2292
		var elem = checkSet[i];
2293
		if ( elem ) {
2294
			if ( sibDir && elem.nodeType === 1 ) {
2295
				elem.sizcache = doneName;
2296
				elem.sizset = i;
2297
			}
2298
			elem = elem[dir];
2299
			var match = false;
2300
 
2301
			while ( elem ) {
2302
				if ( elem.sizcache === doneName ) {
2303
					match = checkSet[elem.sizset];
2304
					break;
2305
				}
2306
 
2307
				if ( elem.nodeType === 1 ) {
2308
					if ( !isXML ) {
2309
						elem.sizcache = doneName;
2310
						elem.sizset = i;
2311
					}
2312
					if ( typeof cur !== "string" ) {
2313
						if ( elem === cur ) {
2314
							match = true;
2315
							break;
2316
						}
2317
 
2318
					} else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
2319
						match = elem;
2320
						break;
2321
					}
2322
				}
2323
 
2324
				elem = elem[dir];
2325
			}
2326
 
2327
			checkSet[i] = match;
2328
		}
2329
	}
2330
}
2331
 
2332
var contains = document.compareDocumentPosition ?  function(a, b){
2333
	return a.compareDocumentPosition(b) & 16;
2334
} : function(a, b){
2335
	return a !== b && (a.contains ? a.contains(b) : true);
2336
};
2337
 
2338
var isXML = function(elem){
2339
	return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" ||
2340
		!!elem.ownerDocument && isXML( elem.ownerDocument );
2341
};
2342
 
2343
var posProcess = function(selector, context){
2344
	var tmpSet = [], later = "", match,
2345
		root = context.nodeType ? [context] : context;
2346
 
2347
	// Position selectors must be done after the filter
2348
	// And so must :not(positional) so we move all PSEUDOs to the end
2349
	while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
2350
		later += match[0];
2351
		selector = selector.replace( Expr.match.PSEUDO, "" );
2352
	}
2353
 
2354
	selector = Expr.relative[selector] ? selector + "*" : selector;
2355
 
2356
	for ( var i = 0, l = root.length; i < l; i++ ) {
2357
		Sizzle( selector, root[i], tmpSet );
2358
	}
2359
 
2360
	return Sizzle.filter( later, tmpSet );
2361
};
2362
 
2363
// EXPOSE
2364
jQuery.find = Sizzle;
2365
jQuery.filter = Sizzle.filter;
2366
jQuery.expr = Sizzle.selectors;
2367
jQuery.expr[":"] = jQuery.expr.filters;
2368
 
2369
Sizzle.selectors.filters.hidden = function(elem){
2370
	return elem.offsetWidth === 0 || elem.offsetHeight === 0;
2371
};
2372
 
2373
Sizzle.selectors.filters.visible = function(elem){
2374
	return elem.offsetWidth > 0 || elem.offsetHeight > 0;
2375
};
2376
 
2377
Sizzle.selectors.filters.animated = function(elem){
2378
	return jQuery.grep(jQuery.timers, function(fn){
2379
		return elem === fn.elem;
2380
	}).length;
2381
};
2382
 
2383
jQuery.multiFilter = function( expr, elems, not ) {
2384
	if ( not ) {
2385
		expr = ":not(" + expr + ")";
2386
	}
2387
 
2388
	return Sizzle.matches(expr, elems);
2389
};
2390
 
2391
jQuery.dir = function( elem, dir ){
2392
	var matched = [], cur = elem[dir];
2393
	while ( cur && cur != document ) {
2394
		if ( cur.nodeType == 1 )
2395
			matched.push( cur );
2396
		cur = cur[dir];
2397
	}
2398
	return matched;
2399
};
2400
 
2401
jQuery.nth = function(cur, result, dir, elem){
2402
	result = result || 1;
2403
	var num = 0;
2404
 
2405
	for ( ; cur; cur = cur[dir] )
2406
		if ( cur.nodeType == 1 && ++num == result )
2407
			break;
2408
 
2409
	return cur;
2410
};
2411
 
2412
jQuery.sibling = function(n, elem){
2413
	var r = [];
2414
 
2415
	for ( ; n; n = n.nextSibling ) {
2416
		if ( n.nodeType == 1 && n != elem )
2417
			r.push( n );
2418
	}
2419
 
2420
	return r;
2421
};
2422
 
2423
return;
2424
 
2425
window.Sizzle = Sizzle;
2426
 
2427
})();
2428
/*
2429
 * A number of helper functions used for managing events.
2430
 * Many of the ideas behind this code originated from
2431
 * Dean Edwards' addEvent library.
2432
 */
2433
jQuery.event = {
2434
 
2435
	// Bind an event to an element
2436
	// Original by Dean Edwards
2437
	add: function(elem, types, handler, data) {
2438
		if ( elem.nodeType == 3 || elem.nodeType == 8 )
2439
			return;
2440
 
2441
		// For whatever reason, IE has trouble passing the window object
2442
		// around, causing it to be cloned in the process
2443
		if ( elem.setInterval && elem != window )
2444
			elem = window;
2445
 
2446
		// Make sure that the function being executed has a unique ID
2447
		if ( !handler.guid )
2448
			handler.guid = this.guid++;
2449
 
2450
		// if data is passed, bind to handler
2451
		if ( data !== undefined ) {
2452
			// Create temporary function pointer to original handler
2453
			var fn = handler;
2454
 
2455
			// Create unique handler function, wrapped around original handler
2456
			handler = this.proxy( fn );
2457
 
2458
			// Store data in unique handler
2459
			handler.data = data;
2460
		}
2461
 
2462
		// Init the element's event structure
2463
		var events = jQuery.data(elem, "events") || jQuery.data(elem, "events", {}),
2464
			handle = jQuery.data(elem, "handle") || jQuery.data(elem, "handle", function(){
2465
				// Handle the second event of a trigger and when
2466
				// an event is called after a page has unloaded
2467
				return typeof jQuery !== "undefined" && !jQuery.event.triggered ?
2468
					jQuery.event.handle.apply(arguments.callee.elem, arguments) :
2469
					undefined;
2470
			});
2471
		// Add elem as a property of the handle function
2472
		// This is to prevent a memory leak with non-native
2473
		// event in IE.
2474
		handle.elem = elem;
2475
 
2476
		// Handle multiple events separated by a space
2477
		// jQuery(...).bind("mouseover mouseout", fn);
2478
		jQuery.each(types.split(/\s+/), function(index, type) {
2479
			// Namespaced event handlers
2480
			var namespaces = type.split(".");
2481
			type = namespaces.shift();
2482
			handler.type = namespaces.slice().sort().join(".");
2483
 
2484
			// Get the current list of functions bound to this event
2485
			var handlers = events[type];
2486
 
2487
			if ( jQuery.event.specialAll[type] )
2488
				jQuery.event.specialAll[type].setup.call(elem, data, namespaces);
2489
 
2490
			// Init the event handler queue
2491
			if (!handlers) {
2492
				handlers = events[type] = {};
2493
 
2494
				// Check for a special event handler
2495
				// Only use addEventListener/attachEvent if the special
2496
				// events handler returns false
2497
				if ( !jQuery.event.special[type] || jQuery.event.special[type].setup.call(elem, data, namespaces) === false ) {
2498
					// Bind the global event handler to the element
2499
					if (elem.addEventListener)
2500
						elem.addEventListener(type, handle, false);
2501
					else if (elem.attachEvent)
2502
						elem.attachEvent("on" + type, handle);
2503
				}
2504
			}
2505
 
2506
			// Add the function to the element's handler list
2507
			handlers[handler.guid] = handler;
2508
 
2509
			// Keep track of which events have been used, for global triggering
2510
			jQuery.event.global[type] = true;
2511
		});
2512
 
2513
		// Nullify elem to prevent memory leaks in IE
2514
		elem = null;
2515
	},
2516
 
2517
	guid: 1,
2518
	global: {},
2519
 
2520
	// Detach an event or set of events from an element
2521
	remove: function(elem, types, handler) {
2522
		// don't do events on text and comment nodes
2523
		if ( elem.nodeType == 3 || elem.nodeType == 8 )
2524
			return;
2525
 
2526
		var events = jQuery.data(elem, "events"), ret, index;
2527
 
2528
		if ( events ) {
2529
			// Unbind all events for the element
2530
			if ( types === undefined || (typeof types === "string" && types.charAt(0) == ".") )
2531
				for ( var type in events )
2532
					this.remove( elem, type + (types || "") );
2533
			else {
2534
				// types is actually an event object here
2535
				if ( types.type ) {
2536
					handler = types.handler;
2537
					types = types.type;
2538
				}
2539
 
2540
				// Handle multiple events seperated by a space
2541
				// jQuery(...).unbind("mouseover mouseout", fn);
2542
				jQuery.each(types.split(/\s+/), function(index, type){
2543
					// Namespaced event handlers
2544
					var namespaces = type.split(".");
2545
					type = namespaces.shift();
2546
					var namespace = RegExp("(^|\\.)" + namespaces.slice().sort().join(".*\\.") + "(\\.|$)");
2547
 
2548
					if ( events[type] ) {
2549
						// remove the given handler for the given type
2550
						if ( handler )
2551
							delete events[type][handler.guid];
2552
 
2553
						// remove all handlers for the given type
2554
						else
2555
							for ( var handle in events[type] )
2556
								// Handle the removal of namespaced events
2557
								if ( namespace.test(events[type][handle].type) )
2558
									delete events[type][handle];
2559
 
2560
						if ( jQuery.event.specialAll[type] )
2561
							jQuery.event.specialAll[type].teardown.call(elem, namespaces);
2562
 
2563
						// remove generic event handler if no more handlers exist
2564
						for ( ret in events[type] ) break;
2565
						if ( !ret ) {
2566
							if ( !jQuery.event.special[type] || jQuery.event.special[type].teardown.call(elem, namespaces) === false ) {
2567
								if (elem.removeEventListener)
2568
									elem.removeEventListener(type, jQuery.data(elem, "handle"), false);
2569
								else if (elem.detachEvent)
2570
									elem.detachEvent("on" + type, jQuery.data(elem, "handle"));
2571
							}
2572
							ret = null;
2573
							delete events[type];
2574
						}
2575
					}
2576
				});
2577
			}
2578
 
2579
			// Remove the expando if it's no longer used
2580
			for ( ret in events ) break;
2581
			if ( !ret ) {
2582
				var handle = jQuery.data( elem, "handle" );
2583
				if ( handle ) handle.elem = null;
2584
				jQuery.removeData( elem, "events" );
2585
				jQuery.removeData( elem, "handle" );
2586
			}
2587
		}
2588
	},
2589
 
2590
	// bubbling is internal
2591
	trigger: function( event, data, elem, bubbling ) {
2592
		// Event object or event type
2593
		var type = event.type || event;
2594
 
2595
		if( !bubbling ){
2596
			event = typeof event === "object" ?
2597
				// jQuery.Event object
2598
				event[expando] ? event :
2599
				// Object literal
2600
				jQuery.extend( jQuery.Event(type), event ) :
2601
				// Just the event type (string)
2602
				jQuery.Event(type);
2603
 
2604
			if ( type.indexOf("!") >= 0 ) {
2605
				event.type = type = type.slice(0, -1);
2606
				event.exclusive = true;
2607
			}
2608
 
2609
			// Handle a global trigger
2610
			if ( !elem ) {
2611
				// Don't bubble custom events when global (to avoid too much overhead)
2612
				event.stopPropagation();
2613
				// Only trigger if we've ever bound an event for it
2614
				if ( this.global[type] )
2615
					jQuery.each( jQuery.cache, function(){
2616
						if ( this.events && this.events[type] )
2617
							jQuery.event.trigger( event, data, this.handle.elem );
2618
					});
2619
			}
2620
 
2621
			// Handle triggering a single element
2622
 
2623
			// don't do events on text and comment nodes
2624
			if ( !elem || elem.nodeType == 3 || elem.nodeType == 8 )
2625
				return undefined;
2626
 
2627
			// Clean up in case it is reused
2628
			event.result = undefined;
2629
			event.target = elem;
2630
 
2631
			// Clone the incoming data, if any
2632
			data = jQuery.makeArray(data);
2633
			data.unshift( event );
2634
		}
2635
 
2636
		event.currentTarget = elem;
2637
 
2638
		// Trigger the event, it is assumed that "handle" is a function
2639
		var handle = jQuery.data(elem, "handle");
2640
		if ( handle )
2641
			handle.apply( elem, data );
2642
 
2643
		// Handle triggering native .onfoo handlers (and on links since we don't call .click() for links)
2644
		if ( (!elem[type] || (jQuery.nodeName(elem, 'a') && type == "click")) && elem["on"+type] && elem["on"+type].apply( elem, data ) === false )
2645
			event.result = false;
2646
 
2647
		// Trigger the native events (except for clicks on links)
2648
		if ( !bubbling && elem[type] && !event.isDefaultPrevented() && !(jQuery.nodeName(elem, 'a') && type == "click") ) {
2649
			this.triggered = true;
2650
			try {
2651
				elem[ type ]();
2652
			// prevent IE from throwing an error for some hidden elements
2653
			} catch (e) {}
2654
		}
2655
 
2656
		this.triggered = false;
2657
 
2658
		if ( !event.isPropagationStopped() ) {
2659
			var parent = elem.parentNode || elem.ownerDocument;
2660
			if ( parent )
2661
				jQuery.event.trigger(event, data, parent, true);
2662
		}
2663
	},
2664
 
2665
	handle: function(event) {
2666
		// returned undefined or false
2667
		var all, handlers;
2668
 
2669
		event = arguments[0] = jQuery.event.fix( event || window.event );
2670
		event.currentTarget = this;
2671
 
2672
		// Namespaced event handlers
2673
		var namespaces = event.type.split(".");
2674
		event.type = namespaces.shift();
2675
 
2676
		// Cache this now, all = true means, any handler
2677
		all = !namespaces.length && !event.exclusive;
2678
 
2679
		var namespace = RegExp("(^|\\.)" + namespaces.slice().sort().join(".*\\.") + "(\\.|$)");
2680
 
2681
		handlers = ( jQuery.data(this, "events") || {} )[event.type];
2682
 
2683
		for ( var j in handlers ) {
2684
			var handler = handlers[j];
2685
 
2686
			// Filter the functions by class
2687
			if ( all || namespace.test(handler.type) ) {
2688
				// Pass in a reference to the handler function itself
2689
				// So that we can later remove it
2690
				event.handler = handler;
2691
				event.data = handler.data;
2692
 
2693
				var ret = handler.apply(this, arguments);
2694
 
2695
				if( ret !== undefined ){
2696
					event.result = ret;
2697
					if ( ret === false ) {
2698
						event.preventDefault();
2699
						event.stopPropagation();
2700
					}
2701
				}
2702
 
2703
				if( event.isImmediatePropagationStopped() )
2704
					break;
2705
 
2706
			}
2707
		}
2708
	},
2709
 
2710
	props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
2711
 
2712
	fix: function(event) {
2713
		if ( event[expando] )
2714
			return event;
2715
 
2716
		// store a copy of the original event object
2717
		// and "clone" to set read-only properties
2718
		var originalEvent = event;
2719
		event = jQuery.Event( originalEvent );
2720
 
2721
		for ( var i = this.props.length, prop; i; ){
2722
			prop = this.props[ --i ];
2723
			event[ prop ] = originalEvent[ prop ];
2724
		}
2725
 
2726
		// Fix target property, if necessary
2727
		if ( !event.target )
2728
			event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either
2729
 
2730
		// check if target is a textnode (safari)
2731
		if ( event.target.nodeType == 3 )
2732
			event.target = event.target.parentNode;
2733
 
2734
		// Add relatedTarget, if necessary
2735
		if ( !event.relatedTarget && event.fromElement )
2736
			event.relatedTarget = event.fromElement == event.target ? event.toElement : event.fromElement;
2737
 
2738
		// Calculate pageX/Y if missing and clientX/Y available
2739
		if ( event.pageX == null && event.clientX != null ) {
2740
			var doc = document.documentElement, body = document.body;
2741
			event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc.clientLeft || 0);
2742
			event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc.clientTop || 0);
2743
		}
2744
 
2745
		// Add which for key events
2746
		if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) )
2747
			event.which = event.charCode || event.keyCode;
2748
 
2749
		// Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
2750
		if ( !event.metaKey && event.ctrlKey )
2751
			event.metaKey = event.ctrlKey;
2752
 
2753
		// Add which for click: 1 == left; 2 == middle; 3 == right
2754
		// Note: button is not normalized, so don't use it
2755
		if ( !event.which && event.button )
2756
			event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
2757
 
2758
		return event;
2759
	},
2760
 
2761
	proxy: function( fn, proxy ){
2762
		proxy = proxy || function(){ return fn.apply(this, arguments); };
2763
		// Set the guid of unique handler to the same of original handler, so it can be removed
2764
		proxy.guid = fn.guid = fn.guid || proxy.guid || this.guid++;
2765
		// So proxy can be declared as an argument
2766
		return proxy;
2767
	},
2768
 
2769
	special: {
2770
		ready: {
2771
			// Make sure the ready event is setup
2772
			setup: bindReady,
2773
			teardown: function() {}
2774
		}
2775
	},
2776
 
2777
	specialAll: {
2778
		live: {
2779
			setup: function( selector, namespaces ){
2780
				jQuery.event.add( this, namespaces[0], liveHandler );
2781
			},
2782
			teardown:  function( namespaces ){
2783
				if ( namespaces.length ) {
2784
					var remove = 0, name = RegExp("(^|\\.)" + namespaces[0] + "(\\.|$)");
2785
 
2786
					jQuery.each( (jQuery.data(this, "events").live || {}), function(){
2787
						if ( name.test(this.type) )
2788
							remove++;
2789
					});
2790
 
2791
					if ( remove < 1 )
2792
						jQuery.event.remove( this, namespaces[0], liveHandler );
2793
				}
2794
			}
2795
		}
2796
	}
2797
};
2798
 
2799
jQuery.Event = function( src ){
2800
	// Allow instantiation without the 'new' keyword
2801
	if( !this.preventDefault )
2802
		return new jQuery.Event(src);
2803
 
2804
	// Event object
2805
	if( src && src.type ){
2806
		this.originalEvent = src;
2807
		this.type = src.type;
2808
	// Event type
2809
	}else
2810
		this.type = src;
2811
 
2812
	// timeStamp is buggy for some events on Firefox(#3843)
2813
	// So we won't rely on the native value
2814
	this.timeStamp = now();
2815
 
2816
	// Mark it as fixed
2817
	this[expando] = true;
2818
};
2819
 
2820
function returnFalse(){
2821
	return false;
2822
}
2823
function returnTrue(){
2824
	return true;
2825
}
2826
 
2827
// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
2828
// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
2829
jQuery.Event.prototype = {
2830
	preventDefault: function() {
2831
		this.isDefaultPrevented = returnTrue;
2832
 
2833
		var e = this.originalEvent;
2834
		if( !e )
2835
			return;
2836
		// if preventDefault exists run it on the original event
2837
		if (e.preventDefault)
2838
			e.preventDefault();
2839
		// otherwise set the returnValue property of the original event to false (IE)
2840
		e.returnValue = false;
2841
	},
2842
	stopPropagation: function() {
2843
		this.isPropagationStopped = returnTrue;
2844
 
2845
		var e = this.originalEvent;
2846
		if( !e )
2847
			return;
2848
		// if stopPropagation exists run it on the original event
2849
		if (e.stopPropagation)
2850
			e.stopPropagation();
2851
		// otherwise set the cancelBubble property of the original event to true (IE)
2852
		e.cancelBubble = true;
2853
	},
2854
	stopImmediatePropagation:function(){
2855
		this.isImmediatePropagationStopped = returnTrue;
2856
		this.stopPropagation();
2857
	},
2858
	isDefaultPrevented: returnFalse,
2859
	isPropagationStopped: returnFalse,
2860
	isImmediatePropagationStopped: returnFalse
2861
};
2862
// Checks if an event happened on an element within another element
2863
// Used in jQuery.event.special.mouseenter and mouseleave handlers
2864
var withinElement = function(event) {
2865
	// Check if mouse(over|out) are still within the same parent element
2866
	var parent = event.relatedTarget;
2867
	// Traverse up the tree
2868
	while ( parent && parent != this )
2869
		try { parent = parent.parentNode; }
2870
		catch(e) { parent = this; }
2871
 
2872
	if( parent != this ){
2873
		// set the correct event type
2874
		event.type = event.data;
2875
		// handle event if we actually just moused on to a non sub-element
2876
		jQuery.event.handle.apply( this, arguments );
2877
	}
2878
};
2879
 
2880
jQuery.each({
2881
	mouseover: 'mouseenter',
2882
	mouseout: 'mouseleave'
2883
}, function( orig, fix ){
2884
	jQuery.event.special[ fix ] = {
2885
		setup: function(){
2886
			jQuery.event.add( this, orig, withinElement, fix );
2887
		},
2888
		teardown: function(){
2889
			jQuery.event.remove( this, orig, withinElement );
2890
		}
2891
	};
2892
});
2893
 
2894
jQuery.fn.extend({
2895
	bind: function( type, data, fn ) {
2896
		return type == "unload" ? this.one(type, data, fn) : this.each(function(){
2897
			jQuery.event.add( this, type, fn || data, fn && data );
2898
		});
2899
	},
2900
 
2901
	one: function( type, data, fn ) {
2902
		var one = jQuery.event.proxy( fn || data, function(event) {
2903
			jQuery(this).unbind(event, one);
2904
			return (fn || data).apply( this, arguments );
2905
		});
2906
		return this.each(function(){
2907
			jQuery.event.add( this, type, one, fn && data);
2908
		});
2909
	},
2910
 
2911
	unbind: function( type, fn ) {
2912
		return this.each(function(){
2913
			jQuery.event.remove( this, type, fn );
2914
		});
2915
	},
2916
 
2917
	trigger: function( type, data ) {
2918
		return this.each(function(){
2919
			jQuery.event.trigger( type, data, this );
2920
		});
2921
	},
2922
 
2923
	triggerHandler: function( type, data ) {
2924
		if( this[0] ){
2925
			var event = jQuery.Event(type);
2926
			event.preventDefault();
2927
			event.stopPropagation();
2928
			jQuery.event.trigger( event, data, this[0] );
2929
			return event.result;
2930
		}
2931
	},
2932
 
2933
	toggle: function( fn ) {
2934
		// Save reference to arguments for access in closure
2935
		var args = arguments, i = 1;
2936
 
2937
		// link all the functions, so any of them can unbind this click handler
2938
		while( i < args.length )
2939
			jQuery.event.proxy( fn, args[i++] );
2940
 
2941
		return this.click( jQuery.event.proxy( fn, function(event) {
2942
			// Figure out which function to execute
2943
			this.lastToggle = ( this.lastToggle || 0 ) % i;
2944
 
2945
			// Make sure that clicks stop
2946
			event.preventDefault();
2947
 
2948
			// and execute the function
2949
			return args[ this.lastToggle++ ].apply( this, arguments ) || false;
2950
		}));
2951
	},
2952
 
2953
	hover: function(fnOver, fnOut) {
2954
		return this.mouseenter(fnOver).mouseleave(fnOut);
2955
	},
2956
 
2957
	ready: function(fn) {
2958
		// Attach the listeners
2959
		bindReady();
2960
 
2961
		// If the DOM is already ready
2962
		if ( jQuery.isReady )
2963
			// Execute the function immediately
2964
			fn.call( document, jQuery );
2965
 
2966
		// Otherwise, remember the function for later
2967
		else
2968
			// Add the function to the wait list
2969
			jQuery.readyList.push( fn );
2970
 
2971
		return this;
2972
	},
2973
 
2974
	live: function( type, fn ){
2975
		var proxy = jQuery.event.proxy( fn );
2976
		proxy.guid += this.selector + type;
2977
 
2978
		jQuery(document).bind( liveConvert(type, this.selector), this.selector, proxy );
2979
 
2980
		return this;
2981
	},
2982
 
2983
	die: function( type, fn ){
2984
		jQuery(document).unbind( liveConvert(type, this.selector), fn ? { guid: fn.guid + this.selector + type } : null );
2985
		return this;
2986
	}
2987
});
2988
 
2989
function liveHandler( event ){
2990
	var check = RegExp("(^|\\.)" + event.type + "(\\.|$)"),
2991
		stop = true,
2992
		elems = [];
2993
 
2994
	jQuery.each(jQuery.data(this, "events").live || [], function(i, fn){
2995
		if ( check.test(fn.type) ) {
2996
			var elem = jQuery(event.target).closest(fn.data)[0];
2997
			if ( elem )
2998
				elems.push({ elem: elem, fn: fn });
2999
		}
3000
	});
3001
 
3002
	elems.sort(function(a,b) {
3003
		return jQuery.data(a.elem, "closest") - jQuery.data(b.elem, "closest");
3004
	});
3005
 
3006
	jQuery.each(elems, function(){
3007
		if ( this.fn.call(this.elem, event, this.fn.data) === false )
3008
			return (stop = false);
3009
	});
3010
 
3011
	return stop;
3012
}
3013
 
3014
function liveConvert(type, selector){
3015
	return ["live", type, selector.replace(/\./g, "`").replace(/ /g, "|")].join(".");
3016
}
3017
 
3018
jQuery.extend({
3019
	isReady: false,
3020
	readyList: [],
3021
	// Handle when the DOM is ready
3022
	ready: function() {
3023
		// Make sure that the DOM is not already loaded
3024
		if ( !jQuery.isReady ) {
3025
			// Remember that the DOM is ready
3026
			jQuery.isReady = true;
3027
 
3028
			// If there are functions bound, to execute
3029
			if ( jQuery.readyList ) {
3030
				// Execute all of them
3031
				jQuery.each( jQuery.readyList, function(){
3032
					this.call( document, jQuery );
3033
				});
3034
 
3035
				// Reset the list of functions
3036
				jQuery.readyList = null;
3037
			}
3038
 
3039
			// Trigger any bound ready events
3040
			jQuery(document).triggerHandler("ready");
3041
		}
3042
	}
3043
});
3044
 
3045
var readyBound = false;
3046
 
3047
function bindReady(){
3048
	if ( readyBound ) return;
3049
	readyBound = true;
3050
 
3051
	// Mozilla, Opera and webkit nightlies currently support this event
3052
	if ( document.addEventListener ) {
3053
		// Use the handy event callback
3054
		document.addEventListener( "DOMContentLoaded", function(){
3055
			document.removeEventListener( "DOMContentLoaded", arguments.callee, false );
3056
			jQuery.ready();
3057
		}, false );
3058
 
3059
	// If IE event model is used
3060
	} else if ( document.attachEvent ) {
3061
		// ensure firing before onload,
3062
		// maybe late but safe also for iframes
3063
		document.attachEvent("onreadystatechange", function(){
3064
			if ( document.readyState === "complete" ) {
3065
				document.detachEvent( "onreadystatechange", arguments.callee );
3066
				jQuery.ready();
3067
			}
3068
		});
3069
 
3070
		// If IE and not an iframe
3071
		// continually check to see if the document is ready
3072
		if ( document.documentElement.doScroll && window == window.top ) (function(){
3073
			if ( jQuery.isReady ) return;
3074
 
3075
			try {
3076
				// If IE is used, use the trick by Diego Perini
3077
				// http://javascript.nwbox.com/IEContentLoaded/
3078
				document.documentElement.doScroll("left");
3079
			} catch( error ) {
3080
				setTimeout( arguments.callee, 0 );
3081
				return;
3082
			}
3083
 
3084
			// and execute any waiting functions
3085
			jQuery.ready();
3086
		})();
3087
	}
3088
 
3089
	// A fallback to window.onload, that will always work
3090
	jQuery.event.add( window, "load", jQuery.ready );
3091
}
3092
 
3093
jQuery.each( ("blur,focus,load,resize,scroll,unload,click,dblclick," +
3094
	"mousedown,mouseup,mousemove,mouseover,mouseout,mouseenter,mouseleave," +
3095
	"change,select,submit,keydown,keypress,keyup,error").split(","), function(i, name){
3096
 
3097
	// Handle event binding
3098
	jQuery.fn[name] = function(fn){
3099
		return fn ? this.bind(name, fn) : this.trigger(name);
3100
	};
3101
});
3102
 
3103
// Prevent memory leaks in IE
3104
// And prevent errors on refresh with events like mouseover in other browsers
3105
// Window isn't included so as not to unbind existing unload events
3106
jQuery( window ).bind( 'unload', function(){
3107
	for ( var id in jQuery.cache )
3108
		// Skip the window
3109
		if ( id != 1 && jQuery.cache[ id ].handle )
3110
			jQuery.event.remove( jQuery.cache[ id ].handle.elem );
3111
});
3112
(function(){
3113
 
3114
	jQuery.support = {};
3115
 
3116
	var root = document.documentElement,
3117
		script = document.createElement("script"),
3118
		div = document.createElement("div"),
3119
		id = "script" + (new Date).getTime();
3120
 
3121
	div.style.display = "none";
3122
	div.innerHTML = '   <link/><table></table><a href="/a" style="color:red;float:left;opacity:.5;">a</a><select><option>text</option></select><object><param/></object>';
3123
 
3124
	var all = div.getElementsByTagName("*"),
3125
		a = div.getElementsByTagName("a")[0];
3126
 
3127
	// Can't get basic test support
3128
	if ( !all || !all.length || !a ) {
3129
		return;
3130
	}
3131
 
3132
	jQuery.support = {
3133
		// IE strips leading whitespace when .innerHTML is used
3134
		leadingWhitespace: div.firstChild.nodeType == 3,
3135
 
3136
		// Make sure that tbody elements aren't automatically inserted
3137
		// IE will insert them into empty tables
3138
		tbody: !div.getElementsByTagName("tbody").length,
3139
 
3140
		// Make sure that you can get all elements in an <object> element
3141
		// IE 7 always returns no results
3142
		objectAll: !!div.getElementsByTagName("object")[0]
3143
			.getElementsByTagName("*").length,
3144
 
3145
		// Make sure that link elements get serialized correctly by innerHTML
3146
		// This requires a wrapper element in IE
3147
		htmlSerialize: !!div.getElementsByTagName("link").length,
3148
 
3149
		// Get the style information from getAttribute
3150
		// (IE uses .cssText insted)
3151
		style: /red/.test( a.getAttribute("style") ),
3152
 
3153
		// Make sure that URLs aren't manipulated
3154
		// (IE normalizes it by default)
3155
		hrefNormalized: a.getAttribute("href") === "/a",
3156
 
3157
		// Make sure that element opacity exists
3158
		// (IE uses filter instead)
3159
		opacity: a.style.opacity === "0.5",
3160
 
3161
		// Verify style float existence
3162
		// (IE uses styleFloat instead of cssFloat)
3163
		cssFloat: !!a.style.cssFloat,
3164
 
3165
		// Will be defined later
3166
		scriptEval: false,
3167
		noCloneEvent: true,
3168
		boxModel: null
3169
	};
3170
 
3171
	script.type = "text/javascript";
3172
	try {
3173
		script.appendChild( document.createTextNode( "window." + id + "=1;" ) );
3174
	} catch(e){}
3175
 
3176
	root.insertBefore( script, root.firstChild );
3177
 
3178
	// Make sure that the execution of code works by injecting a script
3179
	// tag with appendChild/createTextNode
3180
	// (IE doesn't support this, fails, and uses .text instead)
3181
	if ( window[ id ] ) {
3182
		jQuery.support.scriptEval = true;
3183
		delete window[ id ];
3184
	}
3185
 
3186
	root.removeChild( script );
3187
 
3188
	if ( div.attachEvent && div.fireEvent ) {
3189
		div.attachEvent("onclick", function(){
3190
			// Cloning a node shouldn't copy over any
3191
			// bound event handlers (IE does this)
3192
			jQuery.support.noCloneEvent = false;
3193
			div.detachEvent("onclick", arguments.callee);
3194
		});
3195
		div.cloneNode(true).fireEvent("onclick");
3196
	}
3197
 
3198
	// Figure out if the W3C box model works as expected
3199
	// document.body must exist before we can do this
3200
	jQuery(function(){
3201
		var div = document.createElement("div");
3202
		div.style.width = div.style.paddingLeft = "1px";
3203
 
3204
		document.body.appendChild( div );
3205
		jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2;
3206
		document.body.removeChild( div ).style.display = 'none';
3207
	});
3208
})();
3209
 
3210
var styleFloat = jQuery.support.cssFloat ? "cssFloat" : "styleFloat";
3211
 
3212
jQuery.props = {
3213
	"for": "htmlFor",
3214
	"class": "className",
3215
	"float": styleFloat,
3216
	cssFloat: styleFloat,
3217
	styleFloat: styleFloat,
3218
	readonly: "readOnly",
3219
	maxlength: "maxLength",
3220
	cellspacing: "cellSpacing",
3221
	rowspan: "rowSpan",
3222
	tabindex: "tabIndex"
3223
};
3224
jQuery.fn.extend({
3225
	// Keep a copy of the old load
3226
	_load: jQuery.fn.load,
3227
 
3228
	load: function( url, params, callback ) {
3229
		if ( typeof url !== "string" )
3230
			return this._load( url );
3231
 
3232
		var off = url.indexOf(" ");
3233
		if ( off >= 0 ) {
3234
			var selector = url.slice(off, url.length);
3235
			url = url.slice(0, off);
3236
		}
3237
 
3238
		// Default to a GET request
3239
		var type = "GET";
3240
 
3241
		// If the second parameter was provided
3242
		if ( params )
3243
			// If it's a function
3244
			if ( jQuery.isFunction( params ) ) {
3245
				// We assume that it's the callback
3246
				callback = params;
3247
				params = null;
3248
 
3249
			// Otherwise, build a param string
3250
			} else if( typeof params === "object" ) {
3251
				params = jQuery.param( params );
3252
				type = "POST";
3253
			}
3254
 
3255
		var self = this;
3256
 
3257
		// Request the remote document
3258
		jQuery.ajax({
3259
			url: url,
3260
			type: type,
3261
			dataType: "html",
3262
			data: params,
3263
			complete: function(res, status){
3264
				// If successful, inject the HTML into all the matched elements
3265
				if ( status == "success" || status == "notmodified" )
3266
					// See if a selector was specified
3267
					self.html( selector ?
3268
						// Create a dummy div to hold the results
3269
						jQuery("<div/>")
3270
							// inject the contents of the document in, removing the scripts
3271
							// to avoid any 'Permission Denied' errors in IE
3272
							.append(res.responseText.replace(/<script(.|\s)*?\/script>/g, ""))
3273
 
3274
							// Locate the specified elements
3275
							.find(selector) :
3276
 
3277
						// If not, just inject the full result
3278
						res.responseText );
3279
 
3280
				if( callback )
3281
					self.each( callback, [res.responseText, status, res] );
3282
			}
3283
		});
3284
		return this;
3285
	},
3286
 
3287
	serialize: function() {
3288
		return jQuery.param(this.serializeArray());
3289
	},
3290
	serializeArray: function() {
3291
		return this.map(function(){
3292
			return this.elements ? jQuery.makeArray(this.elements) : this;
3293
		})
3294
		.filter(function(){
3295
			return this.name && !this.disabled &&
3296
				(this.checked || /select|textarea/i.test(this.nodeName) ||
3297
					/text|hidden|password|search/i.test(this.type));
3298
		})
3299
		.map(function(i, elem){
3300
			var val = jQuery(this).val();
3301
			return val == null ? null :
3302
				jQuery.isArray(val) ?
3303
					jQuery.map( val, function(val, i){
3304
						return {name: elem.name, value: val};
3305
					}) :
3306
					{name: elem.name, value: val};
3307
		}).get();
3308
	}
3309
});
3310
 
3311
// Attach a bunch of functions for handling common AJAX events
3312
jQuery.each( "ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","), function(i,o){
3313
	jQuery.fn[o] = function(f){
3314
		return this.bind(o, f);
3315
	};
3316
});
3317
 
3318
var jsc = now();
3319
 
3320
jQuery.extend({
3321
 
3322
	get: function( url, data, callback, type ) {
3323
		// shift arguments if data argument was ommited
3324
		if ( jQuery.isFunction( data ) ) {
3325
			callback = data;
3326
			data = null;
3327
		}
3328
 
3329
		return jQuery.ajax({
3330
			type: "GET",
3331
			url: url,
3332
			data: data,
3333
			success: callback,
3334
			dataType: type
3335
		});
3336
	},
3337
 
3338
	getScript: function( url, callback ) {
3339
		return jQuery.get(url, null, callback, "script");
3340
	},
3341
 
3342
	getJSON: function( url, data, callback ) {
3343
		return jQuery.get(url, data, callback, "json");
3344
	},
3345
 
3346
	post: function( url, data, callback, type ) {
3347
		if ( jQuery.isFunction( data ) ) {
3348
			callback = data;
3349
			data = {};
3350
		}
3351
 
3352
		return jQuery.ajax({
3353
			type: "POST",
3354
			url: url,
3355
			data: data,
3356
			success: callback,
3357
			dataType: type
3358
		});
3359
	},
3360
 
3361
	ajaxSetup: function( settings ) {
3362
		jQuery.extend( jQuery.ajaxSettings, settings );
3363
	},
3364
 
3365
	ajaxSettings: {
3366
		url: location.href,
3367
		global: true,
3368
		type: "GET",
3369
		contentType: "application/x-www-form-urlencoded",
3370
		processData: true,
3371
		async: true,
3372
		/*
3373
		timeout: 0,
3374
		data: null,
3375
		username: null,
3376
		password: null,
3377
		*/
3378
		// Create the request object; Microsoft failed to properly
3379
		// implement the XMLHttpRequest in IE7, so we use the ActiveXObject when it is available
3380
		// This function can be overriden by calling jQuery.ajaxSetup
3381
		xhr:function(){
3382
			return window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
3383
		},
3384
		accepts: {
3385
			xml: "application/xml, text/xml",
3386
			html: "text/html",
3387
			script: "text/javascript, application/javascript",
3388
			json: "application/json, text/javascript",
3389
			text: "text/plain",
3390
			_default: "*/*"
3391
		}
3392
	},
3393
 
3394
	// Last-Modified header cache for next request
3395
	lastModified: {},
3396
 
3397
	ajax: function( s ) {
3398
		// Extend the settings, but re-extend 's' so that it can be
3399
		// checked again later (in the test suite, specifically)
3400
		s = jQuery.extend(true, s, jQuery.extend(true, {}, jQuery.ajaxSettings, s));
3401
 
3402
		var jsonp, jsre = /=\?(&|$)/g, status, data,
3403
			type = s.type.toUpperCase();
3404
 
3405
		// convert data if not already a string
3406
		if ( s.data && s.processData && typeof s.data !== "string" )
3407
			s.data = jQuery.param(s.data);
3408
 
3409
		// Handle JSONP Parameter Callbacks
3410
		if ( s.dataType == "jsonp" ) {
3411
			if ( type == "GET" ) {
3412
				if ( !s.url.match(jsre) )
3413
					s.url += (s.url.match(/\?/) ? "&" : "?") + (s.jsonp || "callback") + "=?";
3414
			} else if ( !s.data || !s.data.match(jsre) )
3415
				s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";
3416
			s.dataType = "json";
3417
		}
3418
 
3419
		// Build temporary JSONP function
3420
		if ( s.dataType == "json" && (s.data && s.data.match(jsre) || s.url.match(jsre)) ) {
3421
			jsonp = "jsonp" + jsc++;
3422
 
3423
			// Replace the =? sequence both in the query string and the data
3424
			if ( s.data )
3425
				s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");
3426
			s.url = s.url.replace(jsre, "=" + jsonp + "$1");
3427
 
3428
			// We need to make sure
3429
			// that a JSONP style response is executed properly
3430
			s.dataType = "script";
3431
 
3432
			// Handle JSONP-style loading
3433
			window[ jsonp ] = function(tmp){
3434
				data = tmp;
3435
				success();
3436
				complete();
3437
				// Garbage collect
3438
				window[ jsonp ] = undefined;
3439
				try{ delete window[ jsonp ]; } catch(e){}
3440
				if ( head )
3441
					head.removeChild( script );
3442
			};
3443
		}
3444
 
3445
		if ( s.dataType == "script" && s.cache == null )
3446
			s.cache = false;
3447
 
3448
		if ( s.cache === false && type == "GET" ) {
3449
			var ts = now();
3450
			// try replacing _= if it is there
3451
			var ret = s.url.replace(/(\?|&)_=.*?(&|$)/, "$1_=" + ts + "$2");
3452
			// if nothing was replaced, add timestamp to the end
3453
			s.url = ret + ((ret == s.url) ? (s.url.match(/\?/) ? "&" : "?") + "_=" + ts : "");
3454
		}
3455
 
3456
		// If data is available, append data to url for get requests
3457
		if ( s.data && type == "GET" ) {
3458
			s.url += (s.url.match(/\?/) ? "&" : "?") + s.data;
3459
 
3460
			// IE likes to send both get and post data, prevent this
3461
			s.data = null;
3462
		}
3463
 
3464
		// Watch for a new set of requests
3465
		if ( s.global && ! jQuery.active++ )
3466
			jQuery.event.trigger( "ajaxStart" );
3467
 
3468
		// Matches an absolute URL, and saves the domain
3469
		var parts = /^(\w+:)?\/\/([^\/?#]+)/.exec( s.url );
3470
 
3471
		// If we're requesting a remote document
3472
		// and trying to load JSON or Script with a GET
3473
		if ( s.dataType == "script" && type == "GET" && parts
3474
			&& ( parts[1] && parts[1] != location.protocol || parts[2] != location.host )){
3475
 
3476
			var head = document.getElementsByTagName("head")[0];
3477
			var script = document.createElement("script");
3478
			script.src = s.url;
3479
			if (s.scriptCharset)
3480
				script.charset = s.scriptCharset;
3481
 
3482
			// Handle Script loading
3483
			if ( !jsonp ) {
3484
				var done = false;
3485
 
3486
				// Attach handlers for all browsers
3487
				script.onload = script.onreadystatechange = function(){
3488
					if ( !done && (!this.readyState ||
3489
							this.readyState == "loaded" || this.readyState == "complete") ) {
3490
						done = true;
3491
						success();
3492
						complete();
3493
 
3494
						// Handle memory leak in IE
3495
						script.onload = script.onreadystatechange = null;
3496
						head.removeChild( script );
3497
					}
3498
				};
3499
			}
3500
 
3501
			head.appendChild(script);
3502
 
3503
			// We handle everything using the script element injection
3504
			return undefined;
3505
		}
3506
 
3507
		var requestDone = false;
3508
 
3509
		// Create the request object
3510
		var xhr = s.xhr();
3511
 
3512
		// Open the socket
3513
		// Passing null username, generates a login popup on Opera (#2865)
3514
		if( s.username )
3515
			xhr.open(type, s.url, s.async, s.username, s.password);
3516
		else
3517
			xhr.open(type, s.url, s.async);
3518
 
3519
		// Need an extra try/catch for cross domain requests in Firefox 3
3520
		try {
3521
			// Set the correct header, if data is being sent
3522
			if ( s.data )
3523
				xhr.setRequestHeader("Content-Type", s.contentType);
3524
 
3525
			// Set the If-Modified-Since header, if ifModified mode.
3526
			if ( s.ifModified )
3527
				xhr.setRequestHeader("If-Modified-Since",
3528
					jQuery.lastModified[s.url] || "Thu, 01 Jan 1970 00:00:00 GMT" );
3529
 
3530
			// Set header so the called script knows that it's an XMLHttpRequest
3531
			xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
3532
 
3533
			// Set the Accepts header for the server, depending on the dataType
3534
			xhr.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ?
3535
				s.accepts[ s.dataType ] + ", */*" :
3536
				s.accepts._default );
3537
		} catch(e){}
3538
 
3539
		// Allow custom headers/mimetypes and early abort
3540
		if ( s.beforeSend && s.beforeSend(xhr, s) === false ) {
3541
			// Handle the global AJAX counter
3542
			if ( s.global && ! --jQuery.active )
3543
				jQuery.event.trigger( "ajaxStop" );
3544
			// close opended socket
3545
			xhr.abort();
3546
			return false;
3547
		}
3548
 
3549
		if ( s.global )
3550
			jQuery.event.trigger("ajaxSend", [xhr, s]);
3551
 
3552
		// Wait for a response to come back
3553
		var onreadystatechange = function(isTimeout){
3554
			// The request was aborted, clear the interval and decrement jQuery.active
3555
			if (xhr.readyState == 0) {
3556
				if (ival) {
3557
					// clear poll interval
3558
					clearInterval(ival);
3559
					ival = null;
3560
					// Handle the global AJAX counter
3561
					if ( s.global && ! --jQuery.active )
3562
						jQuery.event.trigger( "ajaxStop" );
3563
				}
3564
			// The transfer is complete and the data is available, or the request timed out
3565
			} else if ( !requestDone && xhr && (xhr.readyState == 4 || isTimeout == "timeout") ) {
3566
				requestDone = true;
3567
 
3568
				// clear poll interval
3569
				if (ival) {
3570
					clearInterval(ival);
3571
					ival = null;
3572
				}
3573
 
3574
				status = isTimeout == "timeout" ? "timeout" :
3575
					!jQuery.httpSuccess( xhr ) ? "error" :
3576
					s.ifModified && jQuery.httpNotModified( xhr, s.url ) ? "notmodified" :
3577
					"success";
3578
 
3579
				if ( status == "success" ) {
3580
					// Watch for, and catch, XML document parse errors
3581
					try {
3582
						// process the data (runs the xml through httpData regardless of callback)
3583
						data = jQuery.httpData( xhr, s.dataType, s );
3584
					} catch(e) {
3585
						status = "parsererror";
3586
					}
3587
				}
3588
 
3589
				// Make sure that the request was successful or notmodified
3590
				if ( status == "success" ) {
3591
					// Cache Last-Modified header, if ifModified mode.
3592
					var modRes;
3593
					try {
3594
						modRes = xhr.getResponseHeader("Last-Modified");
3595
					} catch(e) {} // swallow exception thrown by FF if header is not available
3596
 
3597
					if ( s.ifModified && modRes )
3598
						jQuery.lastModified[s.url] = modRes;
3599
 
3600
					// JSONP handles its own success callback
3601
					if ( !jsonp )
3602
						success();
3603
				} else
3604
					jQuery.handleError(s, xhr, status);
3605
 
3606
				// Fire the complete handlers
3607
				complete();
3608
 
3609
				if ( isTimeout )
3610
					xhr.abort();
3611
 
3612
				// Stop memory leaks
3613
				if ( s.async )
3614
					xhr = null;
3615
			}
3616
		};
3617
 
3618
		if ( s.async ) {
3619
			// don't attach the handler to the request, just poll it instead
3620
			var ival = setInterval(onreadystatechange, 13);
3621
 
3622
			// Timeout checker
3623
			if ( s.timeout > 0 )
3624
				setTimeout(function(){
3625
					// Check to see if the request is still happening
3626
					if ( xhr && !requestDone )
3627
						onreadystatechange( "timeout" );
3628
				}, s.timeout);
3629
		}
3630
 
3631
		// Send the data
3632
		try {
3633
			xhr.send(s.data);
3634
		} catch(e) {
3635
			jQuery.handleError(s, xhr, null, e);
3636
		}
3637
 
3638
		// firefox 1.5 doesn't fire statechange for sync requests
3639
		if ( !s.async )
3640
			onreadystatechange();
3641
 
3642
		function success(){
3643
			// If a local callback was specified, fire it and pass it the data
3644
			if ( s.success )
3645
				s.success( data, status );
3646
 
3647
			// Fire the global callback
3648
			if ( s.global )
3649
				jQuery.event.trigger( "ajaxSuccess", [xhr, s] );
3650
		}
3651
 
3652
		function complete(){
3653
			// Process result
3654
			if ( s.complete )
3655
				s.complete(xhr, status);
3656
 
3657
			// The request was completed
3658
			if ( s.global )
3659
				jQuery.event.trigger( "ajaxComplete", [xhr, s] );
3660
 
3661
			// Handle the global AJAX counter
3662
			if ( s.global && ! --jQuery.active )
3663
				jQuery.event.trigger( "ajaxStop" );
3664
		}
3665
 
3666
		// return XMLHttpRequest to allow aborting the request etc.
3667
		return xhr;
3668
	},
3669
 
3670
	handleError: function( s, xhr, status, e ) {
3671
		// If a local callback was specified, fire it
3672
		if ( s.error ) s.error( xhr, status, e );
3673
 
3674
		// Fire the global callback
3675
		if ( s.global )
3676
			jQuery.event.trigger( "ajaxError", [xhr, s, e] );
3677
	},
3678
 
3679
	// Counter for holding the number of active queries
3680
	active: 0,
3681
 
3682
	// Determines if an XMLHttpRequest was successful or not
3683
	httpSuccess: function( xhr ) {
3684
		try {
3685
			// IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450
3686
			return !xhr.status && location.protocol == "file:" ||
3687
				( xhr.status >= 200 && xhr.status < 300 ) || xhr.status == 304 || xhr.status == 1223;
3688
		} catch(e){}
3689
		return false;
3690
	},
3691
 
3692
	// Determines if an XMLHttpRequest returns NotModified
3693
	httpNotModified: function( xhr, url ) {
3694
		try {
3695
			var xhrRes = xhr.getResponseHeader("Last-Modified");
3696
 
3697
			// Firefox always returns 200. check Last-Modified date
3698
			return xhr.status == 304 || xhrRes == jQuery.lastModified[url];
3699
		} catch(e){}
3700
		return false;
3701
	},
3702
 
3703
	httpData: function( xhr, type, s ) {
3704
		var ct = xhr.getResponseHeader("content-type"),
3705
			xml = type == "xml" || !type && ct && ct.indexOf("xml") >= 0,
3706
			data = xml ? xhr.responseXML : xhr.responseText;
3707
 
3708
		if ( xml && data.documentElement.tagName == "parsererror" )
3709
			throw "parsererror";
3710
 
3711
		// Allow a pre-filtering function to sanitize the response
3712
		// s != null is checked to keep backwards compatibility
3713
		if( s && s.dataFilter )
3714
			data = s.dataFilter( data, type );
3715
 
3716
		// The filter can actually parse the response
3717
		if( typeof data === "string" ){
3718
 
3719
			// If the type is "script", eval it in global context
3720
			if ( type == "script" )
3721
				jQuery.globalEval( data );
3722
 
3723
			// Get the JavaScript object, if JSON is used.
3724
			if ( type == "json" )
3725
				data = window["eval"]("(" + data + ")");
3726
		}
3727
 
3728
		return data;
3729
	},
3730
 
3731
	// Serialize an array of form elements or a set of
3732
	// key/values into a query string
3733
	param: function( a ) {
3734
		var s = [ ];
3735
 
3736
		function add( key, value ){
3737
			s[ s.length ] = encodeURIComponent(key) + '=' + encodeURIComponent(value);
3738
		};
3739
 
3740
		// If an array was passed in, assume that it is an array
3741
		// of form elements
3742
		if ( jQuery.isArray(a) || a.jquery )
3743
			// Serialize the form elements
3744
			jQuery.each( a, function(){
3745
				add( this.name, this.value );
3746
			});
3747
 
3748
		// Otherwise, assume that it's an object of key/value pairs
3749
		else
3750
			// Serialize the key/values
3751
			for ( var j in a )
3752
				// If the value is an array then the key names need to be repeated
3753
				if ( jQuery.isArray(a[j]) )
3754
					jQuery.each( a[j], function(){
3755
						add( j, this );
3756
					});
3757
				else
3758
					add( j, jQuery.isFunction(a[j]) ? a[j]() : a[j] );
3759
 
3760
		// Return the resulting serialization
3761
		return s.join("&").replace(/%20/g, "+");
3762
	}
3763
 
3764
});
3765
var elemdisplay = {},
3766
	timerId,
3767
	fxAttrs = [
3768
		// height animations
3769
		[ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
3770
		// width animations
3771
		[ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
3772
		// opacity animations
3773
		[ "opacity" ]
3774
	];
3775
 
3776
function genFx( type, num ){
3777
	var obj = {};
3778
	jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function(){
3779
		obj[ this ] = type;
3780
	});
3781
	return obj;
3782
}
3783
 
3784
jQuery.fn.extend({
3785
	show: function(speed,callback){
3786
		if ( speed ) {
3787
			return this.animate( genFx("show", 3), speed, callback);
3788
		} else {
3789
			for ( var i = 0, l = this.length; i < l; i++ ){
3790
				var old = jQuery.data(this[i], "olddisplay");
3791
 
3792
				this[i].style.display = old || "";
3793
 
3794
				if ( jQuery.css(this[i], "display") === "none" ) {
3795
					var tagName = this[i].tagName, display;
3796
 
3797
					if ( elemdisplay[ tagName ] ) {
3798
						display = elemdisplay[ tagName ];
3799
					} else {
3800
						var elem = jQuery("<" + tagName + " />").appendTo("body");
3801
 
3802
						display = elem.css("display");
3803
						if ( display === "none" )
3804
							display = "block";
3805
 
3806
						elem.remove();
3807
 
3808
						elemdisplay[ tagName ] = display;
3809
					}
3810
 
3811
					jQuery.data(this[i], "olddisplay", display);
3812
				}
3813
			}
3814
 
3815
			// Set the display of the elements in a second loop
3816
			// to avoid the constant reflow
3817
			for ( var i = 0, l = this.length; i < l; i++ ){
3818
				this[i].style.display = jQuery.data(this[i], "olddisplay") || "";
3819
			}
3820
 
3821
			return this;
3822
		}
3823
	},
3824
 
3825
	hide: function(speed,callback){
3826
		if ( speed ) {
3827
			return this.animate( genFx("hide", 3), speed, callback);
3828
		} else {
3829
			for ( var i = 0, l = this.length; i < l; i++ ){
3830
				var old = jQuery.data(this[i], "olddisplay");
3831
				if ( !old && old !== "none" )
3832
					jQuery.data(this[i], "olddisplay", jQuery.css(this[i], "display"));
3833
			}
3834
 
3835
			// Set the display of the elements in a second loop
3836
			// to avoid the constant reflow
3837
			for ( var i = 0, l = this.length; i < l; i++ ){
3838
				this[i].style.display = "none";
3839
			}
3840
 
3841
			return this;
3842
		}
3843
	},
3844
 
3845
	// Save the old toggle function
3846
	_toggle: jQuery.fn.toggle,
3847
 
3848
	toggle: function( fn, fn2 ){
3849
		var bool = typeof fn === "boolean";
3850
 
3851
		return jQuery.isFunction(fn) && jQuery.isFunction(fn2) ?
3852
			this._toggle.apply( this, arguments ) :
3853
			fn == null || bool ?
3854
				this.each(function(){
3855
					var state = bool ? fn : jQuery(this).is(":hidden");
3856
					jQuery(this)[ state ? "show" : "hide" ]();
3857
				}) :
3858
				this.animate(genFx("toggle", 3), fn, fn2);
3859
	},
3860
 
3861
	fadeTo: function(speed,to,callback){
3862
		return this.animate({opacity: to}, speed, callback);
3863
	},
3864
 
3865
	animate: function( prop, speed, easing, callback ) {
3866
		var optall = jQuery.speed(speed, easing, callback);
3867
 
3868
		return this[ optall.queue === false ? "each" : "queue" ](function(){
3869
 
3870
			var opt = jQuery.extend({}, optall), p,
3871
				hidden = this.nodeType == 1 && jQuery(this).is(":hidden"),
3872
				self = this;
3873
 
3874
			for ( p in prop ) {
3875
				if ( prop[p] == "hide" && hidden || prop[p] == "show" && !hidden )
3876
					return opt.complete.call(this);
3877
 
3878
				if ( ( p == "height" || p == "width" ) && this.style ) {
3879
					// Store display property
3880
					opt.display = jQuery.css(this, "display");
3881
 
3882
					// Make sure that nothing sneaks out
3883
					opt.overflow = this.style.overflow;
3884
				}
3885
			}
3886
 
3887
			if ( opt.overflow != null )
3888
				this.style.overflow = "hidden";
3889
 
3890
			opt.curAnim = jQuery.extend({}, prop);
3891
 
3892
			jQuery.each( prop, function(name, val){
3893
				var e = new jQuery.fx( self, opt, name );
3894
 
3895
				if ( /toggle|show|hide/.test(val) )
3896
					e[ val == "toggle" ? hidden ? "show" : "hide" : val ]( prop );
3897
				else {
3898
					var parts = val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),
3899
						start = e.cur(true) || 0;
3900
 
3901
					if ( parts ) {
3902
						var end = parseFloat(parts[2]),
3903
							unit = parts[3] || "px";
3904
 
3905
						// We need to compute starting value
3906
						if ( unit != "px" ) {
3907
							self.style[ name ] = (end || 1) + unit;
3908
							start = ((end || 1) / e.cur(true)) * start;
3909
							self.style[ name ] = start + unit;
3910
						}
3911
 
3912
						// If a +=/-= token was provided, we're doing a relative animation
3913
						if ( parts[1] )
3914
							end = ((parts[1] == "-=" ? -1 : 1) * end) + start;
3915
 
3916
						e.custom( start, end, unit );
3917
					} else
3918
						e.custom( start, val, "" );
3919
				}
3920
			});
3921
 
3922
			// For JS strict compliance
3923
			return true;
3924
		});
3925
	},
3926
 
3927
	stop: function(clearQueue, gotoEnd){
3928
		var timers = jQuery.timers;
3929
 
3930
		if (clearQueue)
3931
			this.queue([]);
3932
 
3933
		this.each(function(){
3934
			// go in reverse order so anything added to the queue during the loop is ignored
3935
			for ( var i = timers.length - 1; i >= 0; i-- )
3936
				if ( timers[i].elem == this ) {
3937
					if (gotoEnd)
3938
						// force the next step to be the last
3939
						timers[i](true);
3940
					timers.splice(i, 1);
3941
				}
3942
		});
3943
 
3944
		// start the next in the queue if the last step wasn't forced
3945
		if (!gotoEnd)
3946
			this.dequeue();
3947
 
3948
		return this;
3949
	}
3950
 
3951
});
3952
 
3953
// Generate shortcuts for custom animations
3954
jQuery.each({
3955
	slideDown: genFx("show", 1),
3956
	slideUp: genFx("hide", 1),
3957
	slideToggle: genFx("toggle", 1),
3958
	fadeIn: { opacity: "show" },
3959
	fadeOut: { opacity: "hide" }
3960
}, function( name, props ){
3961
	jQuery.fn[ name ] = function( speed, callback ){
3962
		return this.animate( props, speed, callback );
3963
	};
3964
});
3965
 
3966
jQuery.extend({
3967
 
3968
	speed: function(speed, easing, fn) {
3969
		var opt = typeof speed === "object" ? speed : {
3970
			complete: fn || !fn && easing ||
3971
				jQuery.isFunction( speed ) && speed,
3972
			duration: speed,
3973
			easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
3974
		};
3975
 
3976
		opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
3977
			jQuery.fx.speeds[opt.duration] || jQuery.fx.speeds._default;
3978
 
3979
		// Queueing
3980
		opt.old = opt.complete;
3981
		opt.complete = function(){
3982
			if ( opt.queue !== false )
3983
				jQuery(this).dequeue();
3984
			if ( jQuery.isFunction( opt.old ) )
3985
				opt.old.call( this );
3986
		};
3987
 
3988
		return opt;
3989
	},
3990
 
3991
	easing: {
3992
		linear: function( p, n, firstNum, diff ) {
3993
			return firstNum + diff * p;
3994
		},
3995
		swing: function( p, n, firstNum, diff ) {
3996
			return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
3997
		}
3998
	},
3999
 
4000
	timers: [],
4001
 
4002
	fx: function( elem, options, prop ){
4003
		this.options = options;
4004
		this.elem = elem;
4005
		this.prop = prop;
4006
 
4007
		if ( !options.orig )
4008
			options.orig = {};
4009
	}
4010
 
4011
});
4012
 
4013
jQuery.fx.prototype = {
4014
 
4015
	// Simple function for setting a style value
4016
	update: function(){
4017
		if ( this.options.step )
4018
			this.options.step.call( this.elem, this.now, this );
4019
 
4020
		(jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
4021
 
4022
		// Set display property to block for height/width animations
4023
		if ( ( this.prop == "height" || this.prop == "width" ) && this.elem.style )
4024
			this.elem.style.display = "block";
4025
	},
4026
 
4027
	// Get the current size
4028
	cur: function(force){
4029
		if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) )
4030
			return this.elem[ this.prop ];
4031
 
4032
		var r = parseFloat(jQuery.css(this.elem, this.prop, force));
4033
		return r && r > -10000 ? r : parseFloat(jQuery.curCSS(this.elem, this.prop)) || 0;
4034
	},
4035
 
4036
	// Start an animation from one number to another
4037
	custom: function(from, to, unit){
4038
		this.startTime = now();
4039
		this.start = from;
4040
		this.end = to;
4041
		this.unit = unit || this.unit || "px";
4042
		this.now = this.start;
4043
		this.pos = this.state = 0;
4044
 
4045
		var self = this;
4046
		function t(gotoEnd){
4047
			return self.step(gotoEnd);
4048
		}
4049
 
4050
		t.elem = this.elem;
4051
 
4052
		if ( t() && jQuery.timers.push(t) && !timerId ) {
4053
			timerId = setInterval(function(){
4054
				var timers = jQuery.timers;
4055
 
4056
				for ( var i = 0; i < timers.length; i++ )
4057
					if ( !timers[i]() )
4058
						timers.splice(i--, 1);
4059
 
4060
				if ( !timers.length ) {
4061
					clearInterval( timerId );
4062
					timerId = undefined;
4063
				}
4064
			}, 13);
4065
		}
4066
	},
4067
 
4068
	// Simple 'show' function
4069
	show: function(){
4070
		// Remember where we started, so that we can go back to it later
4071
		this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );
4072
		this.options.show = true;
4073
 
4074
		// Begin the animation
4075
		// Make sure that we start at a small width/height to avoid any
4076
		// flash of content
4077
		this.custom(this.prop == "width" || this.prop == "height" ? 1 : 0, this.cur());
4078
 
4079
		// Start by showing the element
4080
		jQuery(this.elem).show();
4081
	},
4082
 
4083
	// Simple 'hide' function
4084
	hide: function(){
4085
		// Remember where we started, so that we can go back to it later
4086
		this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );
4087
		this.options.hide = true;
4088
 
4089
		// Begin the animation
4090
		this.custom(this.cur(), 0);
4091
	},
4092
 
4093
	// Each step of an animation
4094
	step: function(gotoEnd){
4095
		var t = now();
4096
 
4097
		if ( gotoEnd || t >= this.options.duration + this.startTime ) {
4098
			this.now = this.end;
4099
			this.pos = this.state = 1;
4100
			this.update();
4101
 
4102
			this.options.curAnim[ this.prop ] = true;
4103
 
4104
			var done = true;
4105
			for ( var i in this.options.curAnim )
4106
				if ( this.options.curAnim[i] !== true )
4107
					done = false;
4108
 
4109
			if ( done ) {
4110
				if ( this.options.display != null ) {
4111
					// Reset the overflow
4112
					this.elem.style.overflow = this.options.overflow;
4113
 
4114
					// Reset the display
4115
					this.elem.style.display = this.options.display;
4116
					if ( jQuery.css(this.elem, "display") == "none" )
4117
						this.elem.style.display = "block";
4118
				}
4119
 
4120
				// Hide the element if the "hide" operation was done
4121
				if ( this.options.hide )
4122
					jQuery(this.elem).hide();
4123
 
4124
				// Reset the properties, if the item has been hidden or shown
4125
				if ( this.options.hide || this.options.show )
4126
					for ( var p in this.options.curAnim )
4127
						jQuery.attr(this.elem.style, p, this.options.orig[p]);
4128
 
4129
				// Execute the complete function
4130
				this.options.complete.call( this.elem );
4131
			}
4132
 
4133
			return false;
4134
		} else {
4135
			var n = t - this.startTime;
4136
			this.state = n / this.options.duration;
4137
 
4138
			// Perform the easing function, defaults to swing
4139
			this.pos = jQuery.easing[this.options.easing || (jQuery.easing.swing ? "swing" : "linear")](this.state, n, 0, 1, this.options.duration);
4140
			this.now = this.start + ((this.end - this.start) * this.pos);
4141
 
4142
			// Perform the next step of the animation
4143
			this.update();
4144
		}
4145
 
4146
		return true;
4147
	}
4148
 
4149
};
4150
 
4151
jQuery.extend( jQuery.fx, {
4152
	speeds:{
4153
		slow: 600,
4154
 		fast: 200,
4155
 		// Default speed
4156
 		_default: 400
4157
	},
4158
	step: {
4159
 
4160
		opacity: function(fx){
4161
			jQuery.attr(fx.elem.style, "opacity", fx.now);
4162
		},
4163
 
4164
		_default: function(fx){
4165
			if ( fx.elem.style && fx.elem.style[ fx.prop ] != null )
4166
				fx.elem.style[ fx.prop ] = fx.now + fx.unit;
4167
			else
4168
				fx.elem[ fx.prop ] = fx.now;
4169
		}
4170
	}
4171
});
4172
if ( document.documentElement["getBoundingClientRect"] )
4173
	jQuery.fn.offset = function() {
4174
		if ( !this[0] ) return { top: 0, left: 0 };
4175
		if ( this[0] === this[0].ownerDocument.body ) return jQuery.offset.bodyOffset( this[0] );
4176
		var box  = this[0].getBoundingClientRect(), doc = this[0].ownerDocument, body = doc.body, docElem = doc.documentElement,
4177
			clientTop = docElem.clientTop || body.clientTop || 0, clientLeft = docElem.clientLeft || body.clientLeft || 0,
4178
			top  = box.top  + (self.pageYOffset || jQuery.boxModel && docElem.scrollTop  || body.scrollTop ) - clientTop,
4179
			left = box.left + (self.pageXOffset || jQuery.boxModel && docElem.scrollLeft || body.scrollLeft) - clientLeft;
4180
		return { top: top, left: left };
4181
	};
4182
else
4183
	jQuery.fn.offset = function() {
4184
		if ( !this[0] ) return { top: 0, left: 0 };
4185
		if ( this[0] === this[0].ownerDocument.body ) return jQuery.offset.bodyOffset( this[0] );
4186
		jQuery.offset.initialized || jQuery.offset.initialize();
4187
 
4188
		var elem = this[0], offsetParent = elem.offsetParent, prevOffsetParent = elem,
4189
			doc = elem.ownerDocument, computedStyle, docElem = doc.documentElement,
4190
			body = doc.body, defaultView = doc.defaultView,
4191
			prevComputedStyle = defaultView.getComputedStyle(elem, null),
4192
			top = elem.offsetTop, left = elem.offsetLeft;
4193
 
4194
		while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
4195
			computedStyle = defaultView.getComputedStyle(elem, null);
4196
			top -= elem.scrollTop, left -= elem.scrollLeft;
4197
			if ( elem === offsetParent ) {
4198
				top += elem.offsetTop, left += elem.offsetLeft;
4199
				if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && /^t(able|d|h)$/i.test(elem.tagName)) )
4200
					top  += parseInt( computedStyle.borderTopWidth,  10) || 0,
4201
					left += parseInt( computedStyle.borderLeftWidth, 10) || 0;
4202
				prevOffsetParent = offsetParent, offsetParent = elem.offsetParent;
4203
			}
4204
			if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" )
4205
				top  += parseInt( computedStyle.borderTopWidth,  10) || 0,
4206
				left += parseInt( computedStyle.borderLeftWidth, 10) || 0;
4207
			prevComputedStyle = computedStyle;
4208
		}
4209
 
4210
		if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" )
4211
			top  += body.offsetTop,
4212
			left += body.offsetLeft;
4213
 
4214
		if ( prevComputedStyle.position === "fixed" )
4215
			top  += Math.max(docElem.scrollTop, body.scrollTop),
4216
			left += Math.max(docElem.scrollLeft, body.scrollLeft);
4217
 
4218
		return { top: top, left: left };
4219
	};
4220
 
4221
jQuery.offset = {
4222
	initialize: function() {
4223
		if ( this.initialized ) return;
4224
		var body = document.body, container = document.createElement('div'), innerDiv, checkDiv, table, td, rules, prop, bodyMarginTop = body.style.marginTop,
4225
			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>';
4226
 
4227
		rules = { position: 'absolute', top: 0, left: 0, margin: 0, border: 0, width: '1px', height: '1px', visibility: 'hidden' };
4228
		for ( prop in rules ) container.style[prop] = rules[prop];
4229
 
4230
		container.innerHTML = html;
4231
		body.insertBefore(container, body.firstChild);
4232
		innerDiv = container.firstChild, checkDiv = innerDiv.firstChild, td = innerDiv.nextSibling.firstChild.firstChild;
4233
 
4234
		this.doesNotAddBorder = (checkDiv.offsetTop !== 5);
4235
		this.doesAddBorderForTableAndCells = (td.offsetTop === 5);
4236
 
4237
		innerDiv.style.overflow = 'hidden', innerDiv.style.position = 'relative';
4238
		this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5);
4239
 
4240
		body.style.marginTop = '1px';
4241
		this.doesNotIncludeMarginInBodyOffset = (body.offsetTop === 0);
4242
		body.style.marginTop = bodyMarginTop;
4243
 
4244
		body.removeChild(container);
4245
		this.initialized = true;
4246
	},
4247
 
4248
	bodyOffset: function(body) {
4249
		jQuery.offset.initialized || jQuery.offset.initialize();
4250
		var top = body.offsetTop, left = body.offsetLeft;
4251
		if ( jQuery.offset.doesNotIncludeMarginInBodyOffset )
4252
			top  += parseInt( jQuery.curCSS(body, 'marginTop',  true), 10 ) || 0,
4253
			left += parseInt( jQuery.curCSS(body, 'marginLeft', true), 10 ) || 0;
4254
		return { top: top, left: left };
4255
	}
4256
};
4257
 
4258
 
4259
jQuery.fn.extend({
4260
	position: function() {
4261
		var left = 0, top = 0, results;
4262
 
4263
		if ( this[0] ) {
4264
			// Get *real* offsetParent
4265
			var offsetParent = this.offsetParent(),
4266
 
4267
			// Get correct offsets
4268
			offset       = this.offset(),
4269
			parentOffset = /^body|html$/i.test(offsetParent[0].tagName) ? { top: 0, left: 0 } : offsetParent.offset();
4270
 
4271
			// Subtract element margins
4272
			// note: when an element has margin: auto the offsetLeft and marginLeft
4273
			// are the same in Safari causing offset.left to incorrectly be 0
4274
			offset.top  -= num( this, 'marginTop'  );
4275
			offset.left -= num( this, 'marginLeft' );
4276
 
4277
			// Add offsetParent borders
4278
			parentOffset.top  += num( offsetParent, 'borderTopWidth'  );
4279
			parentOffset.left += num( offsetParent, 'borderLeftWidth' );
4280
 
4281
			// Subtract the two offsets
4282
			results = {
4283
				top:  offset.top  - parentOffset.top,
4284
				left: offset.left - parentOffset.left
4285
			};
4286
		}
4287
 
4288
		return results;
4289
	},
4290
 
4291
	offsetParent: function() {
4292
		var offsetParent = this[0].offsetParent || document.body;
4293
		while ( offsetParent && (!/^body|html$/i.test(offsetParent.tagName) && jQuery.css(offsetParent, 'position') == 'static') )
4294
			offsetParent = offsetParent.offsetParent;
4295
		return jQuery(offsetParent);
4296
	}
4297
});
4298
 
4299
 
4300
// Create scrollLeft and scrollTop methods
4301
jQuery.each( ['Left', 'Top'], function(i, name) {
4302
	var method = 'scroll' + name;
4303
 
4304
	jQuery.fn[ method ] = function(val) {
4305
		if (!this[0]) return null;
4306
 
4307
		return val !== undefined ?
4308
 
4309
			// Set the scroll offset
4310
			this.each(function() {
4311
				this == window || this == document ?
4312
					window.scrollTo(
4313
						!i ? val : jQuery(window).scrollLeft(),
4314
						 i ? val : jQuery(window).scrollTop()
4315
					) :
4316
					this[ method ] = val;
4317
			}) :
4318
 
4319
			// Return the scroll offset
4320
			this[0] == window || this[0] == document ?
4321
				self[ i ? 'pageYOffset' : 'pageXOffset' ] ||
4322
					jQuery.boxModel && document.documentElement[ method ] ||
4323
					document.body[ method ] :
4324
				this[0][ method ];
4325
	};
4326
});
4327
// Create innerHeight, innerWidth, outerHeight and outerWidth methods
4328
jQuery.each([ "Height", "Width" ], function(i, name){
4329
 
4330
	var tl = i ? "Left"  : "Top",  // top or left
4331
		br = i ? "Right" : "Bottom", // bottom or right
4332
		lower = name.toLowerCase();
4333
 
4334
	// innerHeight and innerWidth
4335
	jQuery.fn["inner" + name] = function(){
4336
		return this[0] ?
4337
			jQuery.css( this[0], lower, false, "padding" ) :
4338
			null;
4339
	};
4340
 
4341
	// outerHeight and outerWidth
4342
	jQuery.fn["outer" + name] = function(margin) {
4343
		return this[0] ?
4344
			jQuery.css( this[0], lower, false, margin ? "margin" : "border" ) :
4345
			null;
4346
	};
4347
 
4348
	var type = name.toLowerCase();
4349
 
4350
	jQuery.fn[ type ] = function( size ) {
4351
		// Get window width or height
4352
		return this[0] == window ?
4353
			// Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
4354
			document.compatMode == "CSS1Compat" && document.documentElement[ "client" + name ] ||
4355
			document.body[ "client" + name ] :
4356
 
4357
			// Get document width or height
4358
			this[0] == document ?
4359
				// Either scroll[Width/Height] or offset[Width/Height], whichever is greater
4360
				Math.max(
4361
					document.documentElement["client" + name],
4362
					document.body["scroll" + name], document.documentElement["scroll" + name],
4363
					document.body["offset" + name], document.documentElement["offset" + name]
4364
				) :
4365
 
4366
				// Get or set width or height on the element
4367
				size === undefined ?
4368
					// Get width or height on the element
4369
					(this.length ? jQuery.css( this[0], type ) : null) :
4370
 
4371
					// Set the width or height on the element (default to pixels if value is unitless)
4372
					this.css( type, typeof size === "string" ? size : size + "px" );
4373
	};
4374
 
4375
});
4376
})();