Project

General

Profile

Download (115 KB) Statistics
| Branch: | Tag: | Revision:
1
/*!
2
 * jQuery JavaScript Library v1.3.1
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-01-21 20:42:16 -0500 (Wed, 21 Jan 2009)
10
 * Revision: 6158
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.makeArray(selector));
92
	},
93

    
94
	// Start with an empty selector
95
	selector: "",
96

    
97
	// The current version of jQuery being used
98
	jquery: "1.3.1",
99

    
100
	// The number of elements contained in the matched element set
101
	size: function() {
102
		return this.length;
103
	},
104

    
105
	// Get the Nth element in the matched element set OR
106
	// Get the whole matched element set as a clean array
107
	get: function( num ) {
108
		return num === undefined ?
109

    
110
			// Return a 'clean' array
111
			jQuery.makeArray( this ) :
112

    
113
			// Return just the object
114
			this[ num ];
115
	},
116

    
117
	// Take an array of elements and push it onto the stack
118
	// (returning the new matched element set)
119
	pushStack: function( elems, name, selector ) {
120
		// Build a new jQuery matched element set
121
		var ret = jQuery( elems );
122

    
123
		// Add the old object onto the stack (as a reference)
124
		ret.prevObject = this;
125

    
126
		ret.context = this.context;
127

    
128
		if ( name === "find" )
129
			ret.selector = this.selector + (this.selector ? " " : "") + selector;
130
		else if ( name )
131
			ret.selector = this.selector + "." + name + "(" + selector + ")";
132

    
133
		// Return the newly-formed element set
134
		return ret;
135
	},
136

    
137
	// Force the current matched set of elements to become
138
	// the specified array of elements (destroying the stack in the process)
139
	// You should use pushStack() in order to do this, but maintain the stack
140
	setArray: function( elems ) {
141
		// Resetting the length to 0, then using the native Array push
142
		// is a super-fast way to populate an object with array-like properties
143
		this.length = 0;
144
		Array.prototype.push.apply( this, elems );
145

    
146
		return this;
147
	},
148

    
149
	// Execute a callback for every element in the matched set.
150
	// (You can seed the arguments with an array of args, but this is
151
	// only used internally.)
152
	each: function( callback, args ) {
153
		return jQuery.each( this, callback, args );
154
	},
155

    
156
	// Determine the position of an element within
157
	// the matched set of elements
158
	index: function( elem ) {
159
		// Locate the position of the desired element
160
		return jQuery.inArray(
161
			// If it receives a jQuery object, the first element is used
162
			elem && elem.jquery ? elem[0] : elem
163
		, this );
164
	},
165

    
166
	attr: function( name, value, type ) {
167
		var options = name;
168

    
169
		// Look for the case where we're accessing a style value
170
		if ( typeof name === "string" )
171
			if ( value === undefined )
172
				return this[0] && jQuery[ type || "attr" ]( this[0], name );
173

    
174
			else {
175
				options = {};
176
				options[ name ] = value;
177
			}
178

    
179
		// Check to see if we're setting style values
180
		return this.each(function(i){
181
			// Set all the styles
182
			for ( name in options )
183
				jQuery.attr(
184
					type ?
185
						this.style :
186
						this,
187
					name, jQuery.prop( this, options[ name ], type, i, name )
188
				);
189
		});
190
	},
191

    
192
	css: function( key, value ) {
193
		// ignore negative width and height values
194
		if ( (key == 'width' || key == 'height') && parseFloat(value) < 0 )
195
			value = undefined;
196
		return this.attr( key, value, "curCSS" );
197
	},
198

    
199
	text: function( text ) {
200
		if ( typeof text !== "object" && text != null )
201
			return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
202

    
203
		var ret = "";
204

    
205
		jQuery.each( text || this, function(){
206
			jQuery.each( this.childNodes, function(){
207
				if ( this.nodeType != 8 )
208
					ret += this.nodeType != 1 ?
209
						this.nodeValue :
210
						jQuery.fn.text( [ this ] );
211
			});
212
		});
213

    
214
		return ret;
215
	},
216

    
217
	wrapAll: function( html ) {
218
		if ( this[0] ) {
219
			// The elements to wrap the target around
220
			var wrap = jQuery( html, this[0].ownerDocument ).clone();
221

    
222
			if ( this[0].parentNode )
223
				wrap.insertBefore( this[0] );
224

    
225
			wrap.map(function(){
226
				var elem = this;
227

    
228
				while ( elem.firstChild )
229
					elem = elem.firstChild;
230

    
231
				return elem;
232
			}).append(this);
233
		}
234

    
235
		return this;
236
	},
237

    
238
	wrapInner: function( html ) {
239
		return this.each(function(){
240
			jQuery( this ).contents().wrapAll( html );
241
		});
242
	},
243

    
244
	wrap: function( html ) {
245
		return this.each(function(){
246
			jQuery( this ).wrapAll( html );
247
		});
248
	},
249

    
250
	append: function() {
251
		return this.domManip(arguments, true, function(elem){
252
			if (this.nodeType == 1)
253
				this.appendChild( elem );
254
		});
255
	},
256

    
257
	prepend: function() {
258
		return this.domManip(arguments, true, function(elem){
259
			if (this.nodeType == 1)
260
				this.insertBefore( elem, this.firstChild );
261
		});
262
	},
263

    
264
	before: function() {
265
		return this.domManip(arguments, false, function(elem){
266
			this.parentNode.insertBefore( elem, this );
267
		});
268
	},
269

    
270
	after: function() {
271
		return this.domManip(arguments, false, function(elem){
272
			this.parentNode.insertBefore( elem, this.nextSibling );
273
		});
274
	},
275

    
276
	end: function() {
277
		return this.prevObject || jQuery( [] );
278
	},
279

    
280
	// For internal use only.
281
	// Behaves like an Array's .push method, not like a jQuery method.
282
	push: [].push,
283

    
284
	find: function( selector ) {
285
		if ( this.length === 1 && !/,/.test(selector) ) {
286
			var ret = this.pushStack( [], "find", selector );
287
			ret.length = 0;
288
			jQuery.find( selector, this[0], ret );
289
			return ret;
290
		} else {
291
			var elems = jQuery.map(this, function(elem){
292
				return jQuery.find( selector, elem );
293
			});
294

    
295
			return this.pushStack( /[^+>] [^+>]/.test( selector ) ?
296
				jQuery.unique( elems ) :
297
				elems, "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 clone = this.cloneNode(true),
314
					container = document.createElement("div");
315
				container.appendChild(clone);
316
				return jQuery.clean([container.innerHTML])[0];
317
			} else
318
				return this.cloneNode(true);
319
		});
320

    
321
		// Need to set the expando to null on the cloned set if it exists
322
		// removeData doesn't work here, IE removes it from the original as well
323
		// this is primarily for IE but the data expando shouldn't be copied over in any browser
324
		var clone = ret.find("*").andSelf().each(function(){
325
			if ( this[ expando ] !== undefined )
326
				this[ expando ] = null;
327
		});
328

    
329
		// Copy the events from the original to the clone
330
		if ( events === true )
331
			this.find("*").andSelf().each(function(i){
332
				if (this.nodeType == 3)
333
					return;
334
				var events = jQuery.data( this, "events" );
335

    
336
				for ( var type in events )
337
					for ( var handler in events[ type ] )
338
						jQuery.event.add( clone[ i ], type, events[ type ][ handler ], events[ type ][ handler ].data );
339
			});
340

    
341
		// Return the cloned set
342
		return ret;
343
	},
344

    
345
	filter: function( selector ) {
346
		return this.pushStack(
347
			jQuery.isFunction( selector ) &&
348
			jQuery.grep(this, function(elem, i){
349
				return selector.call( elem, i );
350
			}) ||
351

    
352
			jQuery.multiFilter( selector, jQuery.grep(this, function(elem){
353
				return elem.nodeType === 1;
354
			}) ), "filter", selector );
355
	},
356

    
357
	closest: function( selector ) {
358
		var pos = jQuery.expr.match.POS.test( selector ) ? jQuery(selector) : null;
359

    
360
		return this.map(function(){
361
			var cur = this;
362
			while ( cur && cur.ownerDocument ) {
363
				if ( pos ? pos.index(cur) > -1 : jQuery(cur).is(selector) )
364
					return cur;
365
				cur = cur.parentNode;
366
			}
367
		});
368
	},
369

    
370
	not: function( selector ) {
371
		if ( typeof selector === "string" )
372
			// test special case where just one selector is passed in
373
			if ( isSimple.test( selector ) )
374
				return this.pushStack( jQuery.multiFilter( selector, this, true ), "not", selector );
375
			else
376
				selector = jQuery.multiFilter( selector, this );
377

    
378
		var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType;
379
		return this.filter(function() {
380
			return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector;
381
		});
382
	},
383

    
384
	add: function( selector ) {
385
		return this.pushStack( jQuery.unique( jQuery.merge(
386
			this.get(),
387
			typeof selector === "string" ?
388
				jQuery( selector ) :
389
				jQuery.makeArray( selector )
390
		)));
391
	},
392

    
393
	is: function( selector ) {
394
		return !!selector && jQuery.multiFilter( selector, this ).length > 0;
395
	},
396

    
397
	hasClass: function( selector ) {
398
		return !!selector && this.is( "." + selector );
399
	},
400

    
401
	val: function( value ) {
402
		if ( value === undefined ) {			
403
			var elem = this[0];
404

    
405
			if ( elem ) {
406
				if( jQuery.nodeName( elem, 'option' ) )
407
					return (elem.attributes.value || {}).specified ? elem.value : elem.text;
408
				
409
				// We need to handle select boxes special
410
				if ( jQuery.nodeName( elem, "select" ) ) {
411
					var index = elem.selectedIndex,
412
						values = [],
413
						options = elem.options,
414
						one = elem.type == "select-one";
415

    
416
					// Nothing was selected
417
					if ( index < 0 )
418
						return null;
419

    
420
					// Loop through all the selected options
421
					for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
422
						var option = options[ i ];
423

    
424
						if ( option.selected ) {
425
							// Get the specifc value for the option
426
							value = jQuery(option).val();
427

    
428
							// We don't need an array for one selects
429
							if ( one )
430
								return value;
431

    
432
							// Multi-Selects return an array
433
							values.push( value );
434
						}
435
					}
436

    
437
					return values;				
438
				}
439

    
440
				// Everything else, we just grab the value
441
				return (elem.value || "").replace(/\r/g, "");
442

    
443
			}
444

    
445
			return undefined;
446
		}
447

    
448
		if ( typeof value === "number" )
449
			value += '';
450

    
451
		return this.each(function(){
452
			if ( this.nodeType != 1 )
453
				return;
454

    
455
			if ( jQuery.isArray(value) && /radio|checkbox/.test( this.type ) )
456
				this.checked = (jQuery.inArray(this.value, value) >= 0 ||
457
					jQuery.inArray(this.name, value) >= 0);
458

    
459
			else if ( jQuery.nodeName( this, "select" ) ) {
460
				var values = jQuery.makeArray(value);
461

    
462
				jQuery( "option", this ).each(function(){
463
					this.selected = (jQuery.inArray( this.value, values ) >= 0 ||
464
						jQuery.inArray( this.text, values ) >= 0);
465
				});
466

    
467
				if ( !values.length )
468
					this.selectedIndex = -1;
469

    
470
			} else
471
				this.value = value;
472
		});
473
	},
474

    
475
	html: function( value ) {
476
		return value === undefined ?
477
			(this[0] ?
478
				this[0].innerHTML :
479
				null) :
480
			this.empty().append( value );
481
	},
482

    
483
	replaceWith: function( value ) {
484
		return this.after( value ).remove();
485
	},
486

    
487
	eq: function( i ) {
488
		return this.slice( i, +i + 1 );
489
	},
490

    
491
	slice: function() {
492
		return this.pushStack( Array.prototype.slice.apply( this, arguments ),
493
			"slice", Array.prototype.slice.call(arguments).join(",") );
494
	},
495

    
496
	map: function( callback ) {
497
		return this.pushStack( jQuery.map(this, function(elem, i){
498
			return callback.call( elem, i, elem );
499
		}));
500
	},
501

    
502
	andSelf: function() {
503
		return this.add( this.prevObject );
504
	},
505

    
506
	domManip: function( args, table, callback ) {
507
		if ( this[0] ) {
508
			var fragment = (this[0].ownerDocument || this[0]).createDocumentFragment(),
509
				scripts = jQuery.clean( args, (this[0].ownerDocument || this[0]), fragment ),
510
				first = fragment.firstChild,
511
				extra = this.length > 1 ? fragment.cloneNode(true) : fragment;
512

    
513
			if ( first )
514
				for ( var i = 0, l = this.length; i < l; i++ )
515
					callback.call( root(this[i], first), i > 0 ? extra.cloneNode(true) : fragment );
516
			
517
			if ( scripts )
518
				jQuery.each( scripts, evalScript );
519
		}
520

    
521
		return this;
522
		
523
		function root( elem, cur ) {
524
			return table && jQuery.nodeName(elem, "table") && jQuery.nodeName(cur, "tr") ?
525
				(elem.getElementsByTagName("tbody")[0] ||
526
				elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
527
				elem;
528
		}
529
	}
530
};
531

    
532
// Give the init function the jQuery prototype for later instantiation
533
jQuery.fn.init.prototype = jQuery.fn;
534

    
535
function evalScript( i, elem ) {
536
	if ( elem.src )
537
		jQuery.ajax({
538
			url: elem.src,
539
			async: false,
540
			dataType: "script"
541
		});
542

    
543
	else
544
		jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
545

    
546
	if ( elem.parentNode )
547
		elem.parentNode.removeChild( elem );
548
}
549

    
550
function now(){
551
	return +new Date;
552
}
553

    
554
jQuery.extend = jQuery.fn.extend = function() {
555
	// copy reference to target object
556
	var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options;
557

    
558
	// Handle a deep copy situation
559
	if ( typeof target === "boolean" ) {
560
		deep = target;
561
		target = arguments[1] || {};
562
		// skip the boolean and the target
563
		i = 2;
564
	}
565

    
566
	// Handle case when target is a string or something (possible in deep copy)
567
	if ( typeof target !== "object" && !jQuery.isFunction(target) )
568
		target = {};
569

    
570
	// extend jQuery itself if only one argument is passed
571
	if ( length == i ) {
572
		target = this;
573
		--i;
574
	}
575

    
576
	for ( ; i < length; i++ )
577
		// Only deal with non-null/undefined values
578
		if ( (options = arguments[ i ]) != null )
579
			// Extend the base object
580
			for ( var name in options ) {
581
				var src = target[ name ], copy = options[ name ];
582

    
583
				// Prevent never-ending loop
584
				if ( target === copy )
585
					continue;
586

    
587
				// Recurse if we're merging object values
588
				if ( deep && copy && typeof copy === "object" && !copy.nodeType )
589
					target[ name ] = jQuery.extend( deep, 
590
						// Never move original objects, clone them
591
						src || ( copy.length != null ? [ ] : { } )
592
					, copy );
593

    
594
				// Don't bring in undefined values
595
				else if ( copy !== undefined )
596
					target[ name ] = copy;
597

    
598
			}
599

    
600
	// Return the modified object
601
	return target;
602
};
603

    
604
// exclude the following css properties to add px
605
var	exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i,
606
	// cache defaultView
607
	defaultView = document.defaultView || {},
608
	toString = Object.prototype.toString;
609

    
610
jQuery.extend({
611
	noConflict: function( deep ) {
612
		window.$ = _$;
613

    
614
		if ( deep )
615
			window.jQuery = _jQuery;
616

    
617
		return jQuery;
618
	},
619

    
620
	// See test/unit/core.js for details concerning isFunction.
621
	// Since version 1.3, DOM methods and functions like alert
622
	// aren't supported. They return false on IE (#2968).
623
	isFunction: function( obj ) {
624
		return toString.call(obj) === "[object Function]";
625
	},
626

    
627
	isArray: function( obj ) {
628
		return toString.call(obj) === "[object Array]";
629
	},
630

    
631
	// check if an element is in a (or is an) XML document
632
	isXMLDoc: function( elem ) {
633
		return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" ||
634
			!!elem.ownerDocument && jQuery.isXMLDoc( elem.ownerDocument );
635
	},
636

    
637
	// Evalulates a script in a global context
638
	globalEval: function( data ) {
639
		data = jQuery.trim( data );
640

    
641
		if ( data ) {
642
			// Inspired by code by Andrea Giammarchi
643
			// http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
644
			var head = document.getElementsByTagName("head")[0] || document.documentElement,
645
				script = document.createElement("script");
646

    
647
			script.type = "text/javascript";
648
			if ( jQuery.support.scriptEval )
649
				script.appendChild( document.createTextNode( data ) );
650
			else
651
				script.text = data;
652

    
653
			// Use insertBefore instead of appendChild  to circumvent an IE6 bug.
654
			// This arises when a base node is used (#2709).
655
			head.insertBefore( script, head.firstChild );
656
			head.removeChild( script );
657
		}
658
	},
659

    
660
	nodeName: function( elem, name ) {
661
		return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase();
662
	},
663

    
664
	// args is for internal usage only
665
	each: function( object, callback, args ) {
666
		var name, i = 0, length = object.length;
667

    
668
		if ( args ) {
669
			if ( length === undefined ) {
670
				for ( name in object )
671
					if ( callback.apply( object[ name ], args ) === false )
672
						break;
673
			} else
674
				for ( ; i < length; )
675
					if ( callback.apply( object[ i++ ], args ) === false )
676
						break;
677

    
678
		// A special, fast, case for the most common use of each
679
		} else {
680
			if ( length === undefined ) {
681
				for ( name in object )
682
					if ( callback.call( object[ name ], name, object[ name ] ) === false )
683
						break;
684
			} else
685
				for ( var value = object[0];
686
					i < length && callback.call( value, i, value ) !== false; value = object[++i] ){}
687
		}
688

    
689
		return object;
690
	},
691

    
692
	prop: function( elem, value, type, i, name ) {
693
		// Handle executable functions
694
		if ( jQuery.isFunction( value ) )
695
			value = value.call( elem, i );
696

    
697
		// Handle passing in a number to a CSS property
698
		return typeof value === "number" && type == "curCSS" && !exclude.test( name ) ?
699
			value + "px" :
700
			value;
701
	},
702

    
703
	className: {
704
		// internal only, use addClass("class")
705
		add: function( elem, classNames ) {
706
			jQuery.each((classNames || "").split(/\s+/), function(i, className){
707
				if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) )
708
					elem.className += (elem.className ? " " : "") + className;
709
			});
710
		},
711

    
712
		// internal only, use removeClass("class")
713
		remove: function( elem, classNames ) {
714
			if (elem.nodeType == 1)
715
				elem.className = classNames !== undefined ?
716
					jQuery.grep(elem.className.split(/\s+/), function(className){
717
						return !jQuery.className.has( classNames, className );
718
					}).join(" ") :
719
					"";
720
		},
721

    
722
		// internal only, use hasClass("class")
723
		has: function( elem, className ) {
724
			return elem && jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1;
725
		}
726
	},
727

    
728
	// A method for quickly swapping in/out CSS properties to get correct calculations
729
	swap: function( elem, options, callback ) {
730
		var old = {};
731
		// Remember the old values, and insert the new ones
732
		for ( var name in options ) {
733
			old[ name ] = elem.style[ name ];
734
			elem.style[ name ] = options[ name ];
735
		}
736

    
737
		callback.call( elem );
738

    
739
		// Revert the old values
740
		for ( var name in options )
741
			elem.style[ name ] = old[ name ];
742
	},
743

    
744
	css: function( elem, name, force ) {
745
		if ( name == "width" || name == "height" ) {
746
			var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ];
747

    
748
			function getWH() {
749
				val = name == "width" ? elem.offsetWidth : elem.offsetHeight;
750
				var padding = 0, border = 0;
751
				jQuery.each( which, function() {
752
					padding += parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0;
753
					border += parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0;
754
				});
755
				val -= Math.round(padding + border);
756
			}
757

    
758
			if ( jQuery(elem).is(":visible") )
759
				getWH();
760
			else
761
				jQuery.swap( elem, props, getWH );
762

    
763
			return Math.max(0, val);
764
		}
765

    
766
		return jQuery.curCSS( elem, name, force );
767
	},
768

    
769
	curCSS: function( elem, name, force ) {
770
		var ret, style = elem.style;
771

    
772
		// We need to handle opacity special in IE
773
		if ( name == "opacity" && !jQuery.support.opacity ) {
774
			ret = jQuery.attr( style, "opacity" );
775

    
776
			return ret == "" ?
777
				"1" :
778
				ret;
779
		}
780

    
781
		// Make sure we're using the right name for getting the float value
782
		if ( name.match( /float/i ) )
783
			name = styleFloat;
784

    
785
		if ( !force && style && style[ name ] )
786
			ret = style[ name ];
787

    
788
		else if ( defaultView.getComputedStyle ) {
789

    
790
			// Only "float" is needed here
791
			if ( name.match( /float/i ) )
792
				name = "float";
793

    
794
			name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase();
795

    
796
			var computedStyle = defaultView.getComputedStyle( elem, null );
797

    
798
			if ( computedStyle )
799
				ret = computedStyle.getPropertyValue( name );
800

    
801
			// We should always get a number back from opacity
802
			if ( name == "opacity" && ret == "" )
803
				ret = "1";
804

    
805
		} else if ( elem.currentStyle ) {
806
			var camelCase = name.replace(/\-(\w)/g, function(all, letter){
807
				return letter.toUpperCase();
808
			});
809

    
810
			ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ];
811

    
812
			// From the awesome hack by Dean Edwards
813
			// http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
814

    
815
			// If we're not dealing with a regular pixel number
816
			// but a number that has a weird ending, we need to convert it to pixels
817
			if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) {
818
				// Remember the original values
819
				var left = style.left, rsLeft = elem.runtimeStyle.left;
820

    
821
				// Put in the new values to get a computed value out
822
				elem.runtimeStyle.left = elem.currentStyle.left;
823
				style.left = ret || 0;
824
				ret = style.pixelLeft + "px";
825

    
826
				// Revert the changed values
827
				style.left = left;
828
				elem.runtimeStyle.left = rsLeft;
829
			}
830
		}
831

    
832
		return ret;
833
	},
834

    
835
	clean: function( elems, context, fragment ) {
836
		context = context || document;
837

    
838
		// !context.createElement fails in IE with an error but returns typeof 'object'
839
		if ( typeof context.createElement === "undefined" )
840
			context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
841

    
842
		// If a single string is passed in and it's a single tag
843
		// just do a createElement and skip the rest
844
		if ( !fragment && elems.length === 1 && typeof elems[0] === "string" ) {
845
			var match = /^<(\w+)\s*\/?>$/.exec(elems[0]);
846
			if ( match )
847
				return [ context.createElement( match[1] ) ];
848
		}
849

    
850
		var ret = [], scripts = [], div = context.createElement("div");
851

    
852
		jQuery.each(elems, function(i, elem){
853
			if ( typeof elem === "number" )
854
				elem += '';
855

    
856
			if ( !elem )
857
				return;
858

    
859
			// Convert html string into DOM nodes
860
			if ( typeof elem === "string" ) {
861
				// Fix "XHTML"-style tags in all browsers
862
				elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){
863
					return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ?
864
						all :
865
						front + "></" + tag + ">";
866
				});
867

    
868
				// Trim whitespace, otherwise indexOf won't work as expected
869
				var tags = jQuery.trim( elem ).toLowerCase();
870

    
871
				var wrap =
872
					// option or optgroup
873
					!tags.indexOf("<opt") &&
874
					[ 1, "<select multiple='multiple'>", "</select>" ] ||
875

    
876
					!tags.indexOf("<leg") &&
877
					[ 1, "<fieldset>", "</fieldset>" ] ||
878

    
879
					tags.match(/^<(thead|tbody|tfoot|colg|cap)/) &&
880
					[ 1, "<table>", "</table>" ] ||
881

    
882
					!tags.indexOf("<tr") &&
883
					[ 2, "<table><tbody>", "</tbody></table>" ] ||
884

    
885
				 	// <thead> matched above
886
					(!tags.indexOf("<td") || !tags.indexOf("<th")) &&
887
					[ 3, "<table><tbody><tr>", "</tr></tbody></table>" ] ||
888

    
889
					!tags.indexOf("<col") &&
890
					[ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ] ||
891

    
892
					// IE can't serialize <link> and <script> tags normally
893
					!jQuery.support.htmlSerialize &&
894
					[ 1, "div<div>", "</div>" ] ||
895

    
896
					[ 0, "", "" ];
897

    
898
				// Go to html and back, then peel off extra wrappers
899
				div.innerHTML = wrap[1] + elem + wrap[2];
900

    
901
				// Move to the right depth
902
				while ( wrap[0]-- )
903
					div = div.lastChild;
904

    
905
				// Remove IE's autoinserted <tbody> from table fragments
906
				if ( !jQuery.support.tbody ) {
907

    
908
					// String was a <table>, *may* have spurious <tbody>
909
					var tbody = !tags.indexOf("<table") && tags.indexOf("<tbody") < 0 ?
910
						div.firstChild && div.firstChild.childNodes :
911

    
912
						// String was a bare <thead> or <tfoot>
913
						wrap[1] == "<table>" && tags.indexOf("<tbody") < 0 ?
914
							div.childNodes :
915
							[];
916

    
917
					for ( var j = tbody.length - 1; j >= 0 ; --j )
918
						if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length )
919
							tbody[ j ].parentNode.removeChild( tbody[ j ] );
920

    
921
					}
922

    
923
				// IE completely kills leading whitespace when innerHTML is used
924
				if ( !jQuery.support.leadingWhitespace && /^\s/.test( elem ) )
925
					div.insertBefore( context.createTextNode( elem.match(/^\s*/)[0] ), div.firstChild );
926
				
927
				elem = jQuery.makeArray( div.childNodes );
928
			}
929

    
930
			if ( elem.nodeType )
931
				ret.push( elem );
932
			else
933
				ret = jQuery.merge( ret, elem );
934

    
935
		});
936

    
937
		if ( fragment ) {
938
			for ( var i = 0; ret[i]; i++ ) {
939
				if ( jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
940
					scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
941
				} else {
942
					if ( ret[i].nodeType === 1 )
943
						ret.splice.apply( ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))) );
944
					fragment.appendChild( ret[i] );
945
				}
946
			}
947
			
948
			return scripts;
949
		}
950

    
951
		return ret;
952
	},
953

    
954
	attr: function( elem, name, value ) {
955
		// don't set attributes on text and comment nodes
956
		if (!elem || elem.nodeType == 3 || elem.nodeType == 8)
957
			return undefined;
958

    
959
		var notxml = !jQuery.isXMLDoc( elem ),
960
			// Whether we are setting (or getting)
961
			set = value !== undefined;
962

    
963
		// Try to normalize/fix the name
964
		name = notxml && jQuery.props[ name ] || name;
965

    
966
		// Only do all the following if this is a node (faster for style)
967
		// IE elem.getAttribute passes even for style
968
		if ( elem.tagName ) {
969

    
970
			// These attributes require special treatment
971
			var special = /href|src|style/.test( name );
972

    
973
			// Safari mis-reports the default selected property of a hidden option
974
			// Accessing the parent's selectedIndex property fixes it
975
			if ( name == "selected" && elem.parentNode )
976
				elem.parentNode.selectedIndex;
977

    
978
			// If applicable, access the attribute via the DOM 0 way
979
			if ( name in elem && notxml && !special ) {
980
				if ( set ){
981
					// We can't allow the type property to be changed (since it causes problems in IE)
982
					if ( name == "type" && jQuery.nodeName( elem, "input" ) && elem.parentNode )
983
						throw "type property can't be changed";
984

    
985
					elem[ name ] = value;
986
				}
987

    
988
				// browsers index elements by id/name on forms, give priority to attributes.
989
				if( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) )
990
					return elem.getAttributeNode( name ).nodeValue;
991

    
992
				// elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
993
				// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
994
				if ( name == "tabIndex" ) {
995
					var attributeNode = elem.getAttributeNode( "tabIndex" );
996
					return attributeNode && attributeNode.specified
997
						? attributeNode.value
998
						: elem.nodeName.match(/(button|input|object|select|textarea)/i)
999
							? 0
1000
							: elem.nodeName.match(/^(a|area)$/i) && elem.href
1001
								? 0
1002
								: undefined;
1003
				}
1004

    
1005
				return elem[ name ];
1006
			}
1007

    
1008
			if ( !jQuery.support.style && notxml &&  name == "style" )
1009
				return jQuery.attr( elem.style, "cssText", value );
1010

    
1011
			if ( set )
1012
				// convert the value to a string (all browsers do this but IE) see #1070
1013
				elem.setAttribute( name, "" + value );
1014

    
1015
			var attr = !jQuery.support.hrefNormalized && notxml && special
1016
					// Some attributes require a special call on IE
1017
					? elem.getAttribute( name, 2 )
1018
					: elem.getAttribute( name );
1019

    
1020
			// Non-existent attributes return null, we normalize to undefined
1021
			return attr === null ? undefined : attr;
1022
		}
1023

    
1024
		// elem is actually elem.style ... set the style
1025

    
1026
		// IE uses filters for opacity
1027
		if ( !jQuery.support.opacity && name == "opacity" ) {
1028
			if ( set ) {
1029
				// IE has trouble with opacity if it does not have layout
1030
				// Force it by setting the zoom level
1031
				elem.zoom = 1;
1032

    
1033
				// Set the alpha filter to set the opacity
1034
				elem.filter = (elem.filter || "").replace( /alpha\([^)]*\)/, "" ) +
1035
					(parseInt( value ) + '' == "NaN" ? "" : "alpha(opacity=" + value * 100 + ")");
1036
			}
1037

    
1038
			return elem.filter && elem.filter.indexOf("opacity=") >= 0 ?
1039
				(parseFloat( elem.filter.match(/opacity=([^)]*)/)[1] ) / 100) + '':
1040
				"";
1041
		}
1042

    
1043
		name = name.replace(/-([a-z])/ig, function(all, letter){
1044
			return letter.toUpperCase();
1045
		});
1046

    
1047
		if ( set )
1048
			elem[ name ] = value;
1049

    
1050
		return elem[ name ];
1051
	},
1052

    
1053
	trim: function( text ) {
1054
		return (text || "").replace( /^\s+|\s+$/g, "" );
1055
	},
1056

    
1057
	makeArray: function( array ) {
1058
		var ret = [];
1059

    
1060
		if( array != null ){
1061
			var i = array.length;
1062
			// The window, strings (and functions) also have 'length'
1063
			if( i == null || typeof array === "string" || jQuery.isFunction(array) || array.setInterval )
1064
				ret[0] = array;
1065
			else
1066
				while( i )
1067
					ret[--i] = array[i];
1068
		}
1069

    
1070
		return ret;
1071
	},
1072

    
1073
	inArray: function( elem, array ) {
1074
		for ( var i = 0, length = array.length; i < length; i++ )
1075
		// Use === because on IE, window == document
1076
			if ( array[ i ] === elem )
1077
				return i;
1078

    
1079
		return -1;
1080
	},
1081

    
1082
	merge: function( first, second ) {
1083
		// We have to loop this way because IE & Opera overwrite the length
1084
		// expando of getElementsByTagName
1085
		var i = 0, elem, pos = first.length;
1086
		// Also, we need to make sure that the correct elements are being returned
1087
		// (IE returns comment nodes in a '*' query)
1088
		if ( !jQuery.support.getAll ) {
1089
			while ( (elem = second[ i++ ]) != null )
1090
				if ( elem.nodeType != 8 )
1091
					first[ pos++ ] = elem;
1092

    
1093
		} else
1094
			while ( (elem = second[ i++ ]) != null )
1095
				first[ pos++ ] = elem;
1096

    
1097
		return first;
1098
	},
1099

    
1100
	unique: function( array ) {
1101
		var ret = [], done = {};
1102

    
1103
		try {
1104

    
1105
			for ( var i = 0, length = array.length; i < length; i++ ) {
1106
				var id = jQuery.data( array[ i ] );
1107

    
1108
				if ( !done[ id ] ) {
1109
					done[ id ] = true;
1110
					ret.push( array[ i ] );
1111
				}
1112
			}
1113

    
1114
		} catch( e ) {
1115
			ret = array;
1116
		}
1117

    
1118
		return ret;
1119
	},
1120

    
1121
	grep: function( elems, callback, inv ) {
1122
		var ret = [];
1123

    
1124
		// Go through the array, only saving the items
1125
		// that pass the validator function
1126
		for ( var i = 0, length = elems.length; i < length; i++ )
1127
			if ( !inv != !callback( elems[ i ], i ) )
1128
				ret.push( elems[ i ] );
1129

    
1130
		return ret;
1131
	},
1132

    
1133
	map: function( elems, callback ) {
1134
		var ret = [];
1135

    
1136
		// Go through the array, translating each of the items to their
1137
		// new value (or values).
1138
		for ( var i = 0, length = elems.length; i < length; i++ ) {
1139
			var value = callback( elems[ i ], i );
1140

    
1141
			if ( value != null )
1142
				ret[ ret.length ] = value;
1143
		}
1144

    
1145
		return ret.concat.apply( [], ret );
1146
	}
1147
});
1148

    
1149
// Use of jQuery.browser is deprecated.
1150
// It's included for backwards compatibility and plugins,
1151
// although they should work to migrate away.
1152

    
1153
var userAgent = navigator.userAgent.toLowerCase();
1154

    
1155
// Figure out what browser is being used
1156
jQuery.browser = {
1157
	version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [0,'0'])[1],
1158
	safari: /webkit/.test( userAgent ),
1159
	opera: /opera/.test( userAgent ),
1160
	msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ),
1161
	mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent )
1162
};
1163

    
1164
jQuery.each({
1165
	parent: function(elem){return elem.parentNode;},
1166
	parents: function(elem){return jQuery.dir(elem,"parentNode");},
1167
	next: function(elem){return jQuery.nth(elem,2,"nextSibling");},
1168
	prev: function(elem){return jQuery.nth(elem,2,"previousSibling");},
1169
	nextAll: function(elem){return jQuery.dir(elem,"nextSibling");},
1170
	prevAll: function(elem){return jQuery.dir(elem,"previousSibling");},
1171
	siblings: function(elem){return jQuery.sibling(elem.parentNode.firstChild,elem);},
1172
	children: function(elem){return jQuery.sibling(elem.firstChild);},
1173
	contents: function(elem){return jQuery.nodeName(elem,"iframe")?elem.contentDocument||elem.contentWindow.document:jQuery.makeArray(elem.childNodes);}
1174
}, function(name, fn){
1175
	jQuery.fn[ name ] = function( selector ) {
1176
		var ret = jQuery.map( this, fn );
1177

    
1178
		if ( selector && typeof selector == "string" )
1179
			ret = jQuery.multiFilter( selector, ret );
1180

    
1181
		return this.pushStack( jQuery.unique( ret ), name, selector );
1182
	};
1183
});
1184

    
1185
jQuery.each({
1186
	appendTo: "append",
1187
	prependTo: "prepend",
1188
	insertBefore: "before",
1189
	insertAfter: "after",
1190
	replaceAll: "replaceWith"
1191
}, function(name, original){
1192
	jQuery.fn[ name ] = function() {
1193
		var args = arguments;
1194

    
1195
		return this.each(function(){
1196
			for ( var i = 0, length = args.length; i < length; i++ )
1197
				jQuery( args[ i ] )[ original ]( this );
1198
		});
1199
	};
1200
});
1201

    
1202
jQuery.each({
1203
	removeAttr: function( name ) {
1204
		jQuery.attr( this, name, "" );
1205
		if (this.nodeType == 1)
1206
			this.removeAttribute( name );
1207
	},
1208

    
1209
	addClass: function( classNames ) {
1210
		jQuery.className.add( this, classNames );
1211
	},
1212

    
1213
	removeClass: function( classNames ) {
1214
		jQuery.className.remove( this, classNames );
1215
	},
1216

    
1217
	toggleClass: function( classNames, state ) {
1218
		if( typeof state !== "boolean" )
1219
			state = !jQuery.className.has( this, classNames );
1220
		jQuery.className[ state ? "add" : "remove" ]( this, classNames );
1221
	},
1222

    
1223
	remove: function( selector ) {
1224
		if ( !selector || jQuery.filter( selector, [ this ] ).length ) {
1225
			// Prevent memory leaks
1226
			jQuery( "*", this ).add([this]).each(function(){
1227
				jQuery.event.remove(this);
1228
				jQuery.removeData(this);
1229
			});
1230
			if (this.parentNode)
1231
				this.parentNode.removeChild( this );
1232
		}
1233
	},
1234

    
1235
	empty: function() {
1236
		// Remove element nodes and prevent memory leaks
1237
		jQuery( ">*", this ).remove();
1238

    
1239
		// Remove any remaining nodes
1240
		while ( this.firstChild )
1241
			this.removeChild( this.firstChild );
1242
	}
1243
}, function(name, fn){
1244
	jQuery.fn[ name ] = function(){
1245
		return this.each( fn, arguments );
1246
	};
1247
});
1248

    
1249
// Helper function used by the dimensions and offset modules
1250
function num(elem, prop) {
1251
	return elem[0] && parseInt( jQuery.curCSS(elem[0], prop, true), 10 ) || 0;
1252
}
1253
var expando = "jQuery" + now(), uuid = 0, windowData = {};
1254

    
1255
jQuery.extend({
1256
	cache: {},
1257

    
1258
	data: function( elem, name, data ) {
1259
		elem = elem == window ?
1260
			windowData :
1261
			elem;
1262

    
1263
		var id = elem[ expando ];
1264

    
1265
		// Compute a unique ID for the element
1266
		if ( !id )
1267
			id = elem[ expando ] = ++uuid;
1268

    
1269
		// Only generate the data cache if we're
1270
		// trying to access or manipulate it
1271
		if ( name && !jQuery.cache[ id ] )
1272
			jQuery.cache[ id ] = {};
1273

    
1274
		// Prevent overriding the named cache with undefined values
1275
		if ( data !== undefined )
1276
			jQuery.cache[ id ][ name ] = data;
1277

    
1278
		// Return the named cache data, or the ID for the element
1279
		return name ?
1280
			jQuery.cache[ id ][ name ] :
1281
			id;
1282
	},
1283

    
1284
	removeData: function( elem, name ) {
1285
		elem = elem == window ?
1286
			windowData :
1287
			elem;
1288

    
1289
		var id = elem[ expando ];
1290

    
1291
		// If we want to remove a specific section of the element's data
1292
		if ( name ) {
1293
			if ( jQuery.cache[ id ] ) {
1294
				// Remove the section of cache data
1295
				delete jQuery.cache[ id ][ name ];
1296

    
1297
				// If we've removed all the data, remove the element's cache
1298
				name = "";
1299

    
1300
				for ( name in jQuery.cache[ id ] )
1301
					break;
1302

    
1303
				if ( !name )
1304
					jQuery.removeData( elem );
1305
			}
1306

    
1307
		// Otherwise, we want to remove all of the element's data
1308
		} else {
1309
			// Clean up the element expando
1310
			try {
1311
				delete elem[ expando ];
1312
			} catch(e){
1313
				// IE has trouble directly removing the expando
1314
				// but it's ok with using removeAttribute
1315
				if ( elem.removeAttribute )
1316
					elem.removeAttribute( expando );
1317
			}
1318

    
1319
			// Completely remove the data cache
1320
			delete jQuery.cache[ id ];
1321
		}
1322
	},
1323
	queue: function( elem, type, data ) {
1324
		if ( elem ){
1325
	
1326
			type = (type || "fx") + "queue";
1327
	
1328
			var q = jQuery.data( elem, type );
1329
	
1330
			if ( !q || jQuery.isArray(data) )
1331
				q = jQuery.data( elem, type, jQuery.makeArray(data) );
1332
			else if( data )
1333
				q.push( data );
1334
	
1335
		}
1336
		return q;
1337
	},
1338

    
1339
	dequeue: function( elem, type ){
1340
		var queue = jQuery.queue( elem, type ),
1341
			fn = queue.shift();
1342
		
1343
		if( !type || type === "fx" )
1344
			fn = queue[0];
1345
			
1346
		if( fn !== undefined )
1347
			fn.call(elem);
1348
	}
1349
});
1350

    
1351
jQuery.fn.extend({
1352
	data: function( key, value ){
1353
		var parts = key.split(".");
1354
		parts[1] = parts[1] ? "." + parts[1] : "";
1355

    
1356
		if ( value === undefined ) {
1357
			var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
1358

    
1359
			if ( data === undefined && this.length )
1360
				data = jQuery.data( this[0], key );
1361

    
1362
			return data === undefined && parts[1] ?
1363
				this.data( parts[0] ) :
1364
				data;
1365
		} else
1366
			return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function(){
1367
				jQuery.data( this, key, value );
1368
			});
1369
	},
1370

    
1371
	removeData: function( key ){
1372
		return this.each(function(){
1373
			jQuery.removeData( this, key );
1374
		});
1375
	},
1376
	queue: function(type, data){
1377
		if ( typeof type !== "string" ) {
1378
			data = type;
1379
			type = "fx";
1380
		}
1381

    
1382
		if ( data === undefined )
1383
			return jQuery.queue( this[0], type );
1384

    
1385
		return this.each(function(){
1386
			var queue = jQuery.queue( this, type, data );
1387
			
1388
			 if( type == "fx" && queue.length == 1 )
1389
				queue[0].call(this);
1390
		});
1391
	},
1392
	dequeue: function(type){
1393
		return this.each(function(){
1394
			jQuery.dequeue( this, type );
1395
		});
1396
	}
1397
});/*!
1398
 * Sizzle CSS Selector Engine - v0.9.3
1399
 *  Copyright 2009, The Dojo Foundation
1400
 *  Released under the MIT, BSD, and GPL Licenses.
1401
 *  More information: http://sizzlejs.com/
1402
 */
1403
(function(){
1404

    
1405
var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]+['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[]+)+|[>+~])(\s*,\s*)?/g,
1406
	done = 0,
1407
	toString = Object.prototype.toString;
1408

    
1409
var Sizzle = function(selector, context, results, seed) {
1410
	results = results || [];
1411
	context = context || document;
1412

    
1413
	if ( context.nodeType !== 1 && context.nodeType !== 9 )
1414
		return [];
1415
	
1416
	if ( !selector || typeof selector !== "string" ) {
1417
		return results;
1418
	}
1419

    
1420
	var parts = [], m, set, checkSet, check, mode, extra, prune = true;
1421
	
1422
	// Reset the position of the chunker regexp (start from head)
1423
	chunker.lastIndex = 0;
1424
	
1425
	while ( (m = chunker.exec(selector)) !== null ) {
1426
		parts.push( m[1] );
1427
		
1428
		if ( m[2] ) {
1429
			extra = RegExp.rightContext;
1430
			break;
1431
		}
1432
	}
1433

    
1434
	if ( parts.length > 1 && origPOS.exec( selector ) ) {
1435
		if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
1436
			set = posProcess( parts[0] + parts[1], context );
1437
		} else {
1438
			set = Expr.relative[ parts[0] ] ?
1439
				[ context ] :
1440
				Sizzle( parts.shift(), context );
1441

    
1442
			while ( parts.length ) {
1443
				selector = parts.shift();
1444

    
1445
				if ( Expr.relative[ selector ] )
1446
					selector += parts.shift();
1447

    
1448
				set = posProcess( selector, set );
1449
			}
1450
		}
1451
	} else {
1452
		var ret = seed ?
1453
			{ expr: parts.pop(), set: makeArray(seed) } :
1454
			Sizzle.find( parts.pop(), parts.length === 1 && context.parentNode ? context.parentNode : context, isXML(context) );
1455
		set = Sizzle.filter( ret.expr, ret.set );
1456

    
1457
		if ( parts.length > 0 ) {
1458
			checkSet = makeArray(set);
1459
		} else {
1460
			prune = false;
1461
		}
1462

    
1463
		while ( parts.length ) {
1464
			var cur = parts.pop(), pop = cur;
1465

    
1466
			if ( !Expr.relative[ cur ] ) {
1467
				cur = "";
1468
			} else {
1469
				pop = parts.pop();
1470
			}
1471

    
1472
			if ( pop == null ) {
1473
				pop = context;
1474
			}
1475

    
1476
			Expr.relative[ cur ]( checkSet, pop, isXML(context) );
1477
		}
1478
	}
1479

    
1480
	if ( !checkSet ) {
1481
		checkSet = set;
1482
	}
1483

    
1484
	if ( !checkSet ) {
1485
		throw "Syntax error, unrecognized expression: " + (cur || selector);
1486
	}
1487

    
1488
	if ( toString.call(checkSet) === "[object Array]" ) {
1489
		if ( !prune ) {
1490
			results.push.apply( results, checkSet );
1491
		} else if ( context.nodeType === 1 ) {
1492
			for ( var i = 0; checkSet[i] != null; i++ ) {
1493
				if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) {
1494
					results.push( set[i] );
1495
				}
1496
			}
1497
		} else {
1498
			for ( var i = 0; checkSet[i] != null; i++ ) {
1499
				if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
1500
					results.push( set[i] );
1501
				}
1502
			}
1503
		}
1504
	} else {
1505
		makeArray( checkSet, results );
1506
	}
1507

    
1508
	if ( extra ) {
1509
		Sizzle( extra, context, results, seed );
1510
	}
1511

    
1512
	return results;
1513
};
1514

    
1515
Sizzle.matches = function(expr, set){
1516
	return Sizzle(expr, null, null, set);
1517
};
1518

    
1519
Sizzle.find = function(expr, context, isXML){
1520
	var set, match;
1521

    
1522
	if ( !expr ) {
1523
		return [];
1524
	}
1525

    
1526
	for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
1527
		var type = Expr.order[i], match;
1528
		
1529
		if ( (match = Expr.match[ type ].exec( expr )) ) {
1530
			var left = RegExp.leftContext;
1531

    
1532
			if ( left.substr( left.length - 1 ) !== "\\" ) {
1533
				match[1] = (match[1] || "").replace(/\\/g, "");
1534
				set = Expr.find[ type ]( match, context, isXML );
1535
				if ( set != null ) {
1536
					expr = expr.replace( Expr.match[ type ], "" );
1537
					break;
1538
				}
1539
			}
1540
		}
1541
	}
1542

    
1543
	if ( !set ) {
1544
		set = context.getElementsByTagName("*");
1545
	}
1546

    
1547
	return {set: set, expr: expr};
1548
};
1549

    
1550
Sizzle.filter = function(expr, set, inplace, not){
1551
	var old = expr, result = [], curLoop = set, match, anyFound;
1552

    
1553
	while ( expr && set.length ) {
1554
		for ( var type in Expr.filter ) {
1555
			if ( (match = Expr.match[ type ].exec( expr )) != null ) {
1556
				var filter = Expr.filter[ type ], found, item;
1557
				anyFound = false;
1558

    
1559
				if ( curLoop == result ) {
1560
					result = [];
1561
				}
1562

    
1563
				if ( Expr.preFilter[ type ] ) {
1564
					match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not );
1565

    
1566
					if ( !match ) {
1567
						anyFound = found = true;
1568
					} else if ( match === true ) {
1569
						continue;
1570
					}
1571
				}
1572

    
1573
				if ( match ) {
1574
					for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
1575
						if ( item ) {
1576
							found = filter( item, match, i, curLoop );
1577
							var pass = not ^ !!found;
1578

    
1579
							if ( inplace && found != null ) {
1580
								if ( pass ) {
1581
									anyFound = true;
1582
								} else {
1583
									curLoop[i] = false;
1584
								}
1585
							} else if ( pass ) {
1586
								result.push( item );
1587
								anyFound = true;
1588
							}
1589
						}
1590
					}
1591
				}
1592

    
1593
				if ( found !== undefined ) {
1594
					if ( !inplace ) {
1595
						curLoop = result;
1596
					}
1597

    
1598
					expr = expr.replace( Expr.match[ type ], "" );
1599

    
1600
					if ( !anyFound ) {
1601
						return [];
1602
					}
1603

    
1604
					break;
1605
				}
1606
			}
1607
		}
1608

    
1609
		expr = expr.replace(/\s*,\s*/, "");
1610

    
1611
		// Improper expression
1612
		if ( expr == old ) {
1613
			if ( anyFound == null ) {
1614
				throw "Syntax error, unrecognized expression: " + expr;
1615
			} else {
1616
				break;
1617
			}
1618
		}
1619

    
1620
		old = expr;
1621
	}
1622

    
1623
	return curLoop;
1624
};
1625

    
1626
var Expr = Sizzle.selectors = {
1627
	order: [ "ID", "NAME", "TAG" ],
1628
	match: {
1629
		ID: /#((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,
1630
		CLASS: /\.((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,
1631
		NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF_-]|\\.)+)['"]*\]/,
1632
		ATTR: /\[\s*((?:[\w\u00c0-\uFFFF_-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
1633
		TAG: /^((?:[\w\u00c0-\uFFFF\*_-]|\\.)+)/,
1634
		CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,
1635
		POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,
1636
		PSEUDO: /:((?:[\w\u00c0-\uFFFF_-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/
1637
	},
1638
	attrMap: {
1639
		"class": "className",
1640
		"for": "htmlFor"
1641
	},
1642
	attrHandle: {
1643
		href: function(elem){
1644
			return elem.getAttribute("href");
1645
		}
1646
	},
1647
	relative: {
1648
		"+": function(checkSet, part){
1649
			for ( var i = 0, l = checkSet.length; i < l; i++ ) {
1650
				var elem = checkSet[i];
1651
				if ( elem ) {
1652
					var cur = elem.previousSibling;
1653
					while ( cur && cur.nodeType !== 1 ) {
1654
						cur = cur.previousSibling;
1655
					}
1656
					checkSet[i] = typeof part === "string" ?
1657
						cur || false :
1658
						cur === part;
1659
				}
1660
			}
1661

    
1662
			if ( typeof part === "string" ) {
1663
				Sizzle.filter( part, checkSet, true );
1664
			}
1665
		},
1666
		">": function(checkSet, part, isXML){
1667
			if ( typeof part === "string" && !/\W/.test(part) ) {
1668
				part = isXML ? part : part.toUpperCase();
1669

    
1670
				for ( var i = 0, l = checkSet.length; i < l; i++ ) {
1671
					var elem = checkSet[i];
1672
					if ( elem ) {
1673
						var parent = elem.parentNode;
1674
						checkSet[i] = parent.nodeName === part ? parent : false;
1675
					}
1676
				}
1677
			} else {
1678
				for ( var i = 0, l = checkSet.length; i < l; i++ ) {
1679
					var elem = checkSet[i];
1680
					if ( elem ) {
1681
						checkSet[i] = typeof part === "string" ?
1682
							elem.parentNode :
1683
							elem.parentNode === part;
1684
					}
1685
				}
1686

    
1687
				if ( typeof part === "string" ) {
1688
					Sizzle.filter( part, checkSet, true );
1689
				}
1690
			}
1691
		},
1692
		"": function(checkSet, part, isXML){
1693
			var doneName = "done" + (done++), checkFn = dirCheck;
1694

    
1695
			if ( !part.match(/\W/) ) {
1696
				var nodeCheck = part = isXML ? part : part.toUpperCase();
1697
				checkFn = dirNodeCheck;
1698
			}
1699

    
1700
			checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML);
1701
		},
1702
		"~": function(checkSet, part, isXML){
1703
			var doneName = "done" + (done++), checkFn = dirCheck;
1704

    
1705
			if ( typeof part === "string" && !part.match(/\W/) ) {
1706
				var nodeCheck = part = isXML ? part : part.toUpperCase();
1707
				checkFn = dirNodeCheck;
1708
			}
1709

    
1710
			checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML);
1711
		}
1712
	},
1713
	find: {
1714
		ID: function(match, context, isXML){
1715
			if ( typeof context.getElementById !== "undefined" && !isXML ) {
1716
				var m = context.getElementById(match[1]);
1717
				return m ? [m] : [];
1718
			}
1719
		},
1720
		NAME: function(match, context, isXML){
1721
			if ( typeof context.getElementsByName !== "undefined" && !isXML ) {
1722
				return context.getElementsByName(match[1]);
1723
			}
1724
		},
1725
		TAG: function(match, context){
1726
			return context.getElementsByTagName(match[1]);
1727
		}
1728
	},
1729
	preFilter: {
1730
		CLASS: function(match, curLoop, inplace, result, not){
1731
			match = " " + match[1].replace(/\\/g, "") + " ";
1732

    
1733
			var elem;
1734
			for ( var i = 0; (elem = curLoop[i]) != null; i++ ) {
1735
				if ( elem ) {
1736
					if ( not ^ (" " + elem.className + " ").indexOf(match) >= 0 ) {
1737
						if ( !inplace )
1738
							result.push( elem );
1739
					} else if ( inplace ) {
1740
						curLoop[i] = false;
1741
					}
1742
				}
1743
			}
1744

    
1745
			return false;
1746
		},
1747
		ID: function(match){
1748
			return match[1].replace(/\\/g, "");
1749
		},
1750
		TAG: function(match, curLoop){
1751
			for ( var i = 0; curLoop[i] === false; i++ ){}
1752
			return curLoop[i] && isXML(curLoop[i]) ? match[1] : match[1].toUpperCase();
1753
		},
1754
		CHILD: function(match){
1755
			if ( match[1] == "nth" ) {
1756
				// parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
1757
				var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
1758
					match[2] == "even" && "2n" || match[2] == "odd" && "2n+1" ||
1759
					!/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
1760

    
1761
				// calculate the numbers (first)n+(last) including if they are negative
1762
				match[2] = (test[1] + (test[2] || 1)) - 0;
1763
				match[3] = test[3] - 0;
1764
			}
1765

    
1766
			// TODO: Move to normal caching system
1767
			match[0] = "done" + (done++);
1768

    
1769
			return match;
1770
		},
1771
		ATTR: function(match){
1772
			var name = match[1].replace(/\\/g, "");
1773
			
1774
			if ( Expr.attrMap[name] ) {
1775
				match[1] = Expr.attrMap[name];
1776
			}
1777

    
1778
			if ( match[2] === "~=" ) {
1779
				match[4] = " " + match[4] + " ";
1780
			}
1781

    
1782
			return match;
1783
		},
1784
		PSEUDO: function(match, curLoop, inplace, result, not){
1785
			if ( match[1] === "not" ) {
1786
				// If we're dealing with a complex expression, or a simple one
1787
				if ( match[3].match(chunker).length > 1 ) {
1788
					match[3] = Sizzle(match[3], null, null, curLoop);
1789
				} else {
1790
					var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
1791
					if ( !inplace ) {
1792
						result.push.apply( result, ret );
1793
					}
1794
					return false;
1795
				}
1796
			} else if ( Expr.match.POS.test( match[0] ) ) {
1797
				return true;
1798
			}
1799
			
1800
			return match;
1801
		},
1802
		POS: function(match){
1803
			match.unshift( true );
1804
			return match;
1805
		}
1806
	},
1807
	filters: {
1808
		enabled: function(elem){
1809
			return elem.disabled === false && elem.type !== "hidden";
1810
		},
1811
		disabled: function(elem){
1812
			return elem.disabled === true;
1813
		},
1814
		checked: function(elem){
1815
			return elem.checked === true;
1816
		},
1817
		selected: function(elem){
1818
			// Accessing this property makes selected-by-default
1819
			// options in Safari work properly
1820
			elem.parentNode.selectedIndex;
1821
			return elem.selected === true;
1822
		},
1823
		parent: function(elem){
1824
			return !!elem.firstChild;
1825
		},
1826
		empty: function(elem){
1827
			return !elem.firstChild;
1828
		},
1829
		has: function(elem, i, match){
1830
			return !!Sizzle( match[3], elem ).length;
1831
		},
1832
		header: function(elem){
1833
			return /h\d/i.test( elem.nodeName );
1834
		},
1835
		text: function(elem){
1836
			return "text" === elem.type;
1837
		},
1838
		radio: function(elem){
1839
			return "radio" === elem.type;
1840
		},
1841
		checkbox: function(elem){
1842
			return "checkbox" === elem.type;
1843
		},
1844
		file: function(elem){
1845
			return "file" === elem.type;
1846
		},
1847
		password: function(elem){
1848
			return "password" === elem.type;
1849
		},
1850
		submit: function(elem){
1851
			return "submit" === elem.type;
1852
		},
1853
		image: function(elem){
1854
			return "image" === elem.type;
1855
		},
1856
		reset: function(elem){
1857
			return "reset" === elem.type;
1858
		},
1859
		button: function(elem){
1860
			return "button" === elem.type || elem.nodeName.toUpperCase() === "BUTTON";
1861
		},
1862
		input: function(elem){
1863
			return /input|select|textarea|button/i.test(elem.nodeName);
1864
		}
1865
	},
1866
	setFilters: {
1867
		first: function(elem, i){
1868
			return i === 0;
1869
		},
1870
		last: function(elem, i, match, array){
1871
			return i === array.length - 1;
1872
		},
1873
		even: function(elem, i){
1874
			return i % 2 === 0;
1875
		},
1876
		odd: function(elem, i){
1877
			return i % 2 === 1;
1878
		},
1879
		lt: function(elem, i, match){
1880
			return i < match[3] - 0;
1881
		},
1882
		gt: function(elem, i, match){
1883
			return i > match[3] - 0;
1884
		},
1885
		nth: function(elem, i, match){
1886
			return match[3] - 0 == i;
1887
		},
1888
		eq: function(elem, i, match){
1889
			return match[3] - 0 == i;
1890
		}
1891
	},
1892
	filter: {
1893
		CHILD: function(elem, match){
1894
			var type = match[1], parent = elem.parentNode;
1895

    
1896
			var doneName = match[0];
1897
			
1898
			if ( parent && (!parent[ doneName ] || !elem.nodeIndex) ) {
1899
				var count = 1;
1900

    
1901
				for ( var node = parent.firstChild; node; node = node.nextSibling ) {
1902
					if ( node.nodeType == 1 ) {
1903
						node.nodeIndex = count++;
1904
					}
1905
				}
1906

    
1907
				parent[ doneName ] = count - 1;
1908
			}
1909

    
1910
			if ( type == "first" ) {
1911
				return elem.nodeIndex == 1;
1912
			} else if ( type == "last" ) {
1913
				return elem.nodeIndex == parent[ doneName ];
1914
			} else if ( type == "only" ) {
1915
				return parent[ doneName ] == 1;
1916
			} else if ( type == "nth" ) {
1917
				var add = false, first = match[2], last = match[3];
1918

    
1919
				if ( first == 1 && last == 0 ) {
1920
					return true;
1921
				}
1922

    
1923
				if ( first == 0 ) {
1924
					if ( elem.nodeIndex == last ) {
1925
						add = true;
1926
					}
1927
				} else if ( (elem.nodeIndex - last) % first == 0 && (elem.nodeIndex - last) / first >= 0 ) {
1928
					add = true;
1929
				}
1930

    
1931
				return add;
1932
			}
1933
		},
1934
		PSEUDO: function(elem, match, i, array){
1935
			var name = match[1], filter = Expr.filters[ name ];
1936

    
1937
			if ( filter ) {
1938
				return filter( elem, i, match, array );
1939
			} else if ( name === "contains" ) {
1940
				return (elem.textContent || elem.innerText || "").indexOf(match[3]) >= 0;
1941
			} else if ( name === "not" ) {
1942
				var not = match[3];
1943

    
1944
				for ( var i = 0, l = not.length; i < l; i++ ) {
1945
					if ( not[i] === elem ) {
1946
						return false;
1947
					}
1948
				}
1949

    
1950
				return true;
1951
			}
1952
		},
1953
		ID: function(elem, match){
1954
			return elem.nodeType === 1 && elem.getAttribute("id") === match;
1955
		},
1956
		TAG: function(elem, match){
1957
			return (match === "*" && elem.nodeType === 1) || elem.nodeName === match;
1958
		},
1959
		CLASS: function(elem, match){
1960
			return match.test( elem.className );
1961
		},
1962
		ATTR: function(elem, match){
1963
			var result = Expr.attrHandle[ match[1] ] ? Expr.attrHandle[ match[1] ]( elem ) : elem[ match[1] ] || elem.getAttribute( match[1] ), value = result + "", type = match[2], check = match[4];
1964
			return result == null ?
1965
				type === "!=" :
1966
				type === "=" ?
1967
				value === check :
1968
				type === "*=" ?
1969
				value.indexOf(check) >= 0 :
1970
				type === "~=" ?
1971
				(" " + value + " ").indexOf(check) >= 0 :
1972
				!match[4] ?
1973
				result :
1974
				type === "!=" ?
1975
				value != check :
1976
				type === "^=" ?
1977
				value.indexOf(check) === 0 :
1978
				type === "$=" ?
1979
				value.substr(value.length - check.length) === check :
1980
				type === "|=" ?
1981
				value === check || value.substr(0, check.length + 1) === check + "-" :
1982
				false;
1983
		},
1984
		POS: function(elem, match, i, array){
1985
			var name = match[2], filter = Expr.setFilters[ name ];
1986

    
1987
			if ( filter ) {
1988
				return filter( elem, i, match, array );
1989
			}
1990
		}
1991
	}
1992
};
1993

    
1994
var origPOS = Expr.match.POS;
1995

    
1996
for ( var type in Expr.match ) {
1997
	Expr.match[ type ] = RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source );
1998
}
1999

    
2000
var makeArray = function(array, results) {
2001
	array = Array.prototype.slice.call( array );
2002

    
2003
	if ( results ) {
2004
		results.push.apply( results, array );
2005
		return results;
2006
	}
2007
	
2008
	return array;
2009
};
2010

    
2011
// Perform a simple check to determine if the browser is capable of
2012
// converting a NodeList to an array using builtin methods.
2013
try {
2014
	Array.prototype.slice.call( document.documentElement.childNodes );
2015

    
2016
// Provide a fallback method if it does not work
2017
} catch(e){
2018
	makeArray = function(array, results) {
2019
		var ret = results || [];
2020

    
2021
		if ( toString.call(array) === "[object Array]" ) {
2022
			Array.prototype.push.apply( ret, array );
2023
		} else {
2024
			if ( typeof array.length === "number" ) {
2025
				for ( var i = 0, l = array.length; i < l; i++ ) {
2026
					ret.push( array[i] );
2027
				}
2028
			} else {
2029
				for ( var i = 0; array[i]; i++ ) {
2030
					ret.push( array[i] );
2031
				}
2032
			}
2033
		}
2034

    
2035
		return ret;
2036
	};
2037
}
2038

    
2039
// Check to see if the browser returns elements by name when
2040
// querying by getElementById (and provide a workaround)
2041
(function(){
2042
	// We're going to inject a fake input element with a specified name
2043
	var form = document.createElement("form"),
2044
		id = "script" + (new Date).getTime();
2045
	form.innerHTML = "<input name='" + id + "'/>";
2046

    
2047
	// Inject it into the root element, check its status, and remove it quickly
2048
	var root = document.documentElement;
2049
	root.insertBefore( form, root.firstChild );
2050

    
2051
	// The workaround has to do additional checks after a getElementById
2052
	// Which slows things down for other browsers (hence the branching)
2053
	if ( !!document.getElementById( id ) ) {
2054
		Expr.find.ID = function(match, context, isXML){
2055
			if ( typeof context.getElementById !== "undefined" && !isXML ) {
2056
				var m = context.getElementById(match[1]);
2057
				return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : [];
2058
			}
2059
		};
2060

    
2061
		Expr.filter.ID = function(elem, match){
2062
			var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
2063
			return elem.nodeType === 1 && node && node.nodeValue === match;
2064
		};
2065
	}
2066

    
2067
	root.removeChild( form );
2068
})();
2069

    
2070
(function(){
2071
	// Check to see if the browser returns only elements
2072
	// when doing getElementsByTagName("*")
2073

    
2074
	// Create a fake element
2075
	var div = document.createElement("div");
2076
	div.appendChild( document.createComment("") );
2077

    
2078
	// Make sure no comments are found
2079
	if ( div.getElementsByTagName("*").length > 0 ) {
2080
		Expr.find.TAG = function(match, context){
2081
			var results = context.getElementsByTagName(match[1]);
2082

    
2083
			// Filter out possible comments
2084
			if ( match[1] === "*" ) {
2085
				var tmp = [];
2086

    
2087
				for ( var i = 0; results[i]; i++ ) {
2088
					if ( results[i].nodeType === 1 ) {
2089
						tmp.push( results[i] );
2090
					}
2091
				}
2092

    
2093
				results = tmp;
2094
			}
2095

    
2096
			return results;
2097
		};
2098
	}
2099

    
2100
	// Check to see if an attribute returns normalized href attributes
2101
	div.innerHTML = "<a href='#'></a>";
2102
	if ( div.firstChild && div.firstChild.getAttribute("href") !== "#" ) {
2103
		Expr.attrHandle.href = function(elem){
2104
			return elem.getAttribute("href", 2);
2105
		};
2106
	}
2107
})();
2108

    
2109
if ( document.querySelectorAll ) (function(){
2110
	var oldSizzle = Sizzle, div = document.createElement("div");
2111
	div.innerHTML = "<p class='TEST'></p>";
2112

    
2113
	// Safari can't handle uppercase or unicode characters when
2114
	// in quirks mode.
2115
	if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
2116
		return;
2117
	}
2118
	
2119
	Sizzle = function(query, context, extra, seed){
2120
		context = context || document;
2121

    
2122
		// Only use querySelectorAll on non-XML documents
2123
		// (ID selectors don't work in non-HTML documents)
2124
		if ( !seed && context.nodeType === 9 && !isXML(context) ) {
2125
			try {
2126
				return makeArray( context.querySelectorAll(query), extra );
2127
			} catch(e){}
2128
		}
2129
		
2130
		return oldSizzle(query, context, extra, seed);
2131
	};
2132

    
2133
	Sizzle.find = oldSizzle.find;
2134
	Sizzle.filter = oldSizzle.filter;
2135
	Sizzle.selectors = oldSizzle.selectors;
2136
	Sizzle.matches = oldSizzle.matches;
2137
})();
2138

    
2139
if ( document.getElementsByClassName && document.documentElement.getElementsByClassName ) {
2140
	Expr.order.splice(1, 0, "CLASS");
2141
	Expr.find.CLASS = function(match, context) {
2142
		return context.getElementsByClassName(match[1]);
2143
	};
2144
}
2145

    
2146
function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
2147
	for ( var i = 0, l = checkSet.length; i < l; i++ ) {
2148
		var elem = checkSet[i];
2149
		if ( elem ) {
2150
			elem = elem[dir];
2151
			var match = false;
2152

    
2153
			while ( elem && elem.nodeType ) {
2154
				var done = elem[doneName];
2155
				if ( done ) {
2156
					match = checkSet[ done ];
2157
					break;
2158
				}
2159

    
2160
				if ( elem.nodeType === 1 && !isXML )
2161
					elem[doneName] = i;
2162

    
2163
				if ( elem.nodeName === cur ) {
2164
					match = elem;
2165
					break;
2166
				}
2167

    
2168
				elem = elem[dir];
2169
			}
2170

    
2171
			checkSet[i] = match;
2172
		}
2173
	}
2174
}
2175

    
2176
function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
2177
	for ( var i = 0, l = checkSet.length; i < l; i++ ) {
2178
		var elem = checkSet[i];
2179
		if ( elem ) {
2180
			elem = elem[dir];
2181
			var match = false;
2182

    
2183
			while ( elem && elem.nodeType ) {
2184
				if ( elem[doneName] ) {
2185
					match = checkSet[ elem[doneName] ];
2186
					break;
2187
				}
2188

    
2189
				if ( elem.nodeType === 1 ) {
2190
					if ( !isXML )
2191
						elem[doneName] = i;
2192

    
2193
					if ( typeof cur !== "string" ) {
2194
						if ( elem === cur ) {
2195
							match = true;
2196
							break;
2197
						}
2198

    
2199
					} else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
2200
						match = elem;
2201
						break;
2202
					}
2203
				}
2204

    
2205
				elem = elem[dir];
2206
			}
2207

    
2208
			checkSet[i] = match;
2209
		}
2210
	}
2211
}
2212

    
2213
var contains = document.compareDocumentPosition ?  function(a, b){
2214
	return a.compareDocumentPosition(b) & 16;
2215
} : function(a, b){
2216
	return a !== b && (a.contains ? a.contains(b) : true);
2217
};
2218

    
2219
var isXML = function(elem){
2220
	return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" ||
2221
		!!elem.ownerDocument && isXML( elem.ownerDocument );
2222
};
2223

    
2224
var posProcess = function(selector, context){
2225
	var tmpSet = [], later = "", match,
2226
		root = context.nodeType ? [context] : context;
2227

    
2228
	// Position selectors must be done after the filter
2229
	// And so must :not(positional) so we move all PSEUDOs to the end
2230
	while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
2231
		later += match[0];
2232
		selector = selector.replace( Expr.match.PSEUDO, "" );
2233
	}
2234

    
2235
	selector = Expr.relative[selector] ? selector + "*" : selector;
2236

    
2237
	for ( var i = 0, l = root.length; i < l; i++ ) {
2238
		Sizzle( selector, root[i], tmpSet );
2239
	}
2240

    
2241
	return Sizzle.filter( later, tmpSet );
2242
};
2243

    
2244
// EXPOSE
2245
jQuery.find = Sizzle;
2246
jQuery.filter = Sizzle.filter;
2247
jQuery.expr = Sizzle.selectors;
2248
jQuery.expr[":"] = jQuery.expr.filters;
2249

    
2250
Sizzle.selectors.filters.hidden = function(elem){
2251
	return "hidden" === elem.type ||
2252
		jQuery.css(elem, "display") === "none" ||
2253
		jQuery.css(elem, "visibility") === "hidden";
2254
};
2255

    
2256
Sizzle.selectors.filters.visible = function(elem){
2257
	return "hidden" !== elem.type &&
2258
		jQuery.css(elem, "display") !== "none" &&
2259
		jQuery.css(elem, "visibility") !== "hidden";
2260
};
2261

    
2262
Sizzle.selectors.filters.animated = function(elem){
2263
	return jQuery.grep(jQuery.timers, function(fn){
2264
		return elem === fn.elem;
2265
	}).length;
2266
};
2267

    
2268
jQuery.multiFilter = function( expr, elems, not ) {
2269
	if ( not ) {
2270
		expr = ":not(" + expr + ")";
2271
	}
2272

    
2273
	return Sizzle.matches(expr, elems);
2274
};
2275

    
2276
jQuery.dir = function( elem, dir ){
2277
	var matched = [], cur = elem[dir];
2278
	while ( cur && cur != document ) {
2279
		if ( cur.nodeType == 1 )
2280
			matched.push( cur );
2281
		cur = cur[dir];
2282
	}
2283
	return matched;
2284
};
2285

    
2286
jQuery.nth = function(cur, result, dir, elem){
2287
	result = result || 1;
2288
	var num = 0;
2289

    
2290
	for ( ; cur; cur = cur[dir] )
2291
		if ( cur.nodeType == 1 && ++num == result )
2292
			break;
2293

    
2294
	return cur;
2295
};
2296

    
2297
jQuery.sibling = function(n, elem){
2298
	var r = [];
2299

    
2300
	for ( ; n; n = n.nextSibling ) {
2301
		if ( n.nodeType == 1 && n != elem )
2302
			r.push( n );
2303
	}
2304

    
2305
	return r;
2306
};
2307

    
2308
return;
2309

    
2310
window.Sizzle = Sizzle;
2311

    
2312
})();
2313
/*
2314
 * A number of helper functions used for managing events.
2315
 * Many of the ideas behind this code originated from
2316
 * Dean Edwards' addEvent library.
2317
 */
2318
jQuery.event = {
2319

    
2320
	// Bind an event to an element
2321
	// Original by Dean Edwards
2322
	add: function(elem, types, handler, data) {
2323
		if ( elem.nodeType == 3 || elem.nodeType == 8 )
2324
			return;
2325

    
2326
		// For whatever reason, IE has trouble passing the window object
2327
		// around, causing it to be cloned in the process
2328
		if ( elem.setInterval && elem != window )
2329
			elem = window;
2330

    
2331
		// Make sure that the function being executed has a unique ID
2332
		if ( !handler.guid )
2333
			handler.guid = this.guid++;
2334

    
2335
		// if data is passed, bind to handler
2336
		if ( data !== undefined ) {
2337
			// Create temporary function pointer to original handler
2338
			var fn = handler;
2339

    
2340
			// Create unique handler function, wrapped around original handler
2341
			handler = this.proxy( fn );
2342

    
2343
			// Store data in unique handler
2344
			handler.data = data;
2345
		}
2346

    
2347
		// Init the element's event structure
2348
		var events = jQuery.data(elem, "events") || jQuery.data(elem, "events", {}),
2349
			handle = jQuery.data(elem, "handle") || jQuery.data(elem, "handle", function(){
2350
				// Handle the second event of a trigger and when
2351
				// an event is called after a page has unloaded
2352
				return typeof jQuery !== "undefined" && !jQuery.event.triggered ?
2353
					jQuery.event.handle.apply(arguments.callee.elem, arguments) :
2354
					undefined;
2355
			});
2356
		// Add elem as a property of the handle function
2357
		// This is to prevent a memory leak with non-native
2358
		// event in IE.
2359
		handle.elem = elem;
2360

    
2361
		// Handle multiple events separated by a space
2362
		// jQuery(...).bind("mouseover mouseout", fn);
2363
		jQuery.each(types.split(/\s+/), function(index, type) {
2364
			// Namespaced event handlers
2365
			var namespaces = type.split(".");
2366
			type = namespaces.shift();
2367
			handler.type = namespaces.slice().sort().join(".");
2368

    
2369
			// Get the current list of functions bound to this event
2370
			var handlers = events[type];
2371
			
2372
			if ( jQuery.event.specialAll[type] )
2373
				jQuery.event.specialAll[type].setup.call(elem, data, namespaces);
2374

    
2375
			// Init the event handler queue
2376
			if (!handlers) {
2377
				handlers = events[type] = {};
2378

    
2379
				// Check for a special event handler
2380
				// Only use addEventListener/attachEvent if the special
2381
				// events handler returns false
2382
				if ( !jQuery.event.special[type] || jQuery.event.special[type].setup.call(elem, data, namespaces) === false ) {
2383
					// Bind the global event handler to the element
2384
					if (elem.addEventListener)
2385
						elem.addEventListener(type, handle, false);
2386
					else if (elem.attachEvent)
2387
						elem.attachEvent("on" + type, handle);
2388
				}
2389
			}
2390

    
2391
			// Add the function to the element's handler list
2392
			handlers[handler.guid] = handler;
2393

    
2394
			// Keep track of which events have been used, for global triggering
2395
			jQuery.event.global[type] = true;
2396
		});
2397

    
2398
		// Nullify elem to prevent memory leaks in IE
2399
		elem = null;
2400
	},
2401

    
2402
	guid: 1,
2403
	global: {},
2404

    
2405
	// Detach an event or set of events from an element
2406
	remove: function(elem, types, handler) {
2407
		// don't do events on text and comment nodes
2408
		if ( elem.nodeType == 3 || elem.nodeType == 8 )
2409
			return;
2410

    
2411
		var events = jQuery.data(elem, "events"), ret, index;
2412

    
2413
		if ( events ) {
2414
			// Unbind all events for the element
2415
			if ( types === undefined || (typeof types === "string" && types.charAt(0) == ".") )
2416
				for ( var type in events )
2417
					this.remove( elem, type + (types || "") );
2418
			else {
2419
				// types is actually an event object here
2420
				if ( types.type ) {
2421
					handler = types.handler;
2422
					types = types.type;
2423
				}
2424

    
2425
				// Handle multiple events seperated by a space
2426
				// jQuery(...).unbind("mouseover mouseout", fn);
2427
				jQuery.each(types.split(/\s+/), function(index, type){
2428
					// Namespaced event handlers
2429
					var namespaces = type.split(".");
2430
					type = namespaces.shift();
2431
					var namespace = RegExp("(^|\\.)" + namespaces.slice().sort().join(".*\\.") + "(\\.|$)");
2432

    
2433
					if ( events[type] ) {
2434
						// remove the given handler for the given type
2435
						if ( handler )
2436
							delete events[type][handler.guid];
2437

    
2438
						// remove all handlers for the given type
2439
						else
2440
							for ( var handle in events[type] )
2441
								// Handle the removal of namespaced events
2442
								if ( namespace.test(events[type][handle].type) )
2443
									delete events[type][handle];
2444
									
2445
						if ( jQuery.event.specialAll[type] )
2446
							jQuery.event.specialAll[type].teardown.call(elem, namespaces);
2447

    
2448
						// remove generic event handler if no more handlers exist
2449
						for ( ret in events[type] ) break;
2450
						if ( !ret ) {
2451
							if ( !jQuery.event.special[type] || jQuery.event.special[type].teardown.call(elem, namespaces) === false ) {
2452
								if (elem.removeEventListener)
2453
									elem.removeEventListener(type, jQuery.data(elem, "handle"), false);
2454
								else if (elem.detachEvent)
2455
									elem.detachEvent("on" + type, jQuery.data(elem, "handle"));
2456
							}
2457
							ret = null;
2458
							delete events[type];
2459
						}
2460
					}
2461
				});
2462
			}
2463

    
2464
			// Remove the expando if it's no longer used
2465
			for ( ret in events ) break;
2466
			if ( !ret ) {
2467
				var handle = jQuery.data( elem, "handle" );
2468
				if ( handle ) handle.elem = null;
2469
				jQuery.removeData( elem, "events" );
2470
				jQuery.removeData( elem, "handle" );
2471
			}
2472
		}
2473
	},
2474

    
2475
	// bubbling is internal
2476
	trigger: function( event, data, elem, bubbling ) {
2477
		// Event object or event type
2478
		var type = event.type || event;
2479

    
2480
		if( !bubbling ){
2481
			event = typeof event === "object" ?
2482
				// jQuery.Event object
2483
				event[expando] ? event :
2484
				// Object literal
2485
				jQuery.extend( jQuery.Event(type), event ) :
2486
				// Just the event type (string)
2487
				jQuery.Event(type);
2488

    
2489
			if ( type.indexOf("!") >= 0 ) {
2490
				event.type = type = type.slice(0, -1);
2491
				event.exclusive = true;
2492
			}
2493

    
2494
			// Handle a global trigger
2495
			if ( !elem ) {
2496
				// Don't bubble custom events when global (to avoid too much overhead)
2497
				event.stopPropagation();
2498
				// Only trigger if we've ever bound an event for it
2499
				if ( this.global[type] )
2500
					jQuery.each( jQuery.cache, function(){
2501
						if ( this.events && this.events[type] )
2502
							jQuery.event.trigger( event, data, this.handle.elem );
2503
					});
2504
			}
2505

    
2506
			// Handle triggering a single element
2507

    
2508
			// don't do events on text and comment nodes
2509
			if ( !elem || elem.nodeType == 3 || elem.nodeType == 8 )
2510
				return undefined;
2511
			
2512
			// Clean up in case it is reused
2513
			event.result = undefined;
2514
			event.target = elem;
2515
			
2516
			// Clone the incoming data, if any
2517
			data = jQuery.makeArray(data);
2518
			data.unshift( event );
2519
		}
2520

    
2521
		event.currentTarget = elem;
2522

    
2523
		// Trigger the event, it is assumed that "handle" is a function
2524
		var handle = jQuery.data(elem, "handle");
2525
		if ( handle )
2526
			handle.apply( elem, data );
2527

    
2528
		// Handle triggering native .onfoo handlers (and on links since we don't call .click() for links)
2529
		if ( (!elem[type] || (jQuery.nodeName(elem, 'a') && type == "click")) && elem["on"+type] && elem["on"+type].apply( elem, data ) === false )
2530
			event.result = false;
2531

    
2532
		// Trigger the native events (except for clicks on links)
2533
		if ( !bubbling && elem[type] && !event.isDefaultPrevented() && !(jQuery.nodeName(elem, 'a') && type == "click") ) {
2534
			this.triggered = true;
2535
			try {
2536
				elem[ type ]();
2537
			// prevent IE from throwing an error for some hidden elements
2538
			} catch (e) {}
2539
		}
2540

    
2541
		this.triggered = false;
2542

    
2543
		if ( !event.isPropagationStopped() ) {
2544
			var parent = elem.parentNode || elem.ownerDocument;
2545
			if ( parent )
2546
				jQuery.event.trigger(event, data, parent, true);
2547
		}
2548
	},
2549

    
2550
	handle: function(event) {
2551
		// returned undefined or false
2552
		var all, handlers;
2553

    
2554
		event = arguments[0] = jQuery.event.fix( event || window.event );
2555

    
2556
		// Namespaced event handlers
2557
		var namespaces = event.type.split(".");
2558
		event.type = namespaces.shift();
2559

    
2560
		// Cache this now, all = true means, any handler
2561
		all = !namespaces.length && !event.exclusive;
2562
		
2563
		var namespace = RegExp("(^|\\.)" + namespaces.slice().sort().join(".*\\.") + "(\\.|$)");
2564

    
2565
		handlers = ( jQuery.data(this, "events") || {} )[event.type];
2566

    
2567
		for ( var j in handlers ) {
2568
			var handler = handlers[j];
2569

    
2570
			// Filter the functions by class
2571
			if ( all || namespace.test(handler.type) ) {
2572
				// Pass in a reference to the handler function itself
2573
				// So that we can later remove it
2574
				event.handler = handler;
2575
				event.data = handler.data;
2576

    
2577
				var ret = handler.apply(this, arguments);
2578

    
2579
				if( ret !== undefined ){
2580
					event.result = ret;
2581
					if ( ret === false ) {
2582
						event.preventDefault();
2583
						event.stopPropagation();
2584
					}
2585
				}
2586

    
2587
				if( event.isImmediatePropagationStopped() )
2588
					break;
2589

    
2590
			}
2591
		}
2592
	},
2593

    
2594
	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(" "),
2595

    
2596
	fix: function(event) {
2597
		if ( event[expando] )
2598
			return event;
2599

    
2600
		// store a copy of the original event object
2601
		// and "clone" to set read-only properties
2602
		var originalEvent = event;
2603
		event = jQuery.Event( originalEvent );
2604

    
2605
		for ( var i = this.props.length, prop; i; ){
2606
			prop = this.props[ --i ];
2607
			event[ prop ] = originalEvent[ prop ];
2608
		}
2609

    
2610
		// Fix target property, if necessary
2611
		if ( !event.target )
2612
			event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either
2613

    
2614
		// check if target is a textnode (safari)
2615
		if ( event.target.nodeType == 3 )
2616
			event.target = event.target.parentNode;
2617

    
2618
		// Add relatedTarget, if necessary
2619
		if ( !event.relatedTarget && event.fromElement )
2620
			event.relatedTarget = event.fromElement == event.target ? event.toElement : event.fromElement;
2621

    
2622
		// Calculate pageX/Y if missing and clientX/Y available
2623
		if ( event.pageX == null && event.clientX != null ) {
2624
			var doc = document.documentElement, body = document.body;
2625
			event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc.clientLeft || 0);
2626
			event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc.clientTop || 0);
2627
		}
2628

    
2629
		// Add which for key events
2630
		if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) )
2631
			event.which = event.charCode || event.keyCode;
2632

    
2633
		// Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
2634
		if ( !event.metaKey && event.ctrlKey )
2635
			event.metaKey = event.ctrlKey;
2636

    
2637
		// Add which for click: 1 == left; 2 == middle; 3 == right
2638
		// Note: button is not normalized, so don't use it
2639
		if ( !event.which && event.button )
2640
			event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
2641

    
2642
		return event;
2643
	},
2644

    
2645
	proxy: function( fn, proxy ){
2646
		proxy = proxy || function(){ return fn.apply(this, arguments); };
2647
		// Set the guid of unique handler to the same of original handler, so it can be removed
2648
		proxy.guid = fn.guid = fn.guid || proxy.guid || this.guid++;
2649
		// So proxy can be declared as an argument
2650
		return proxy;
2651
	},
2652

    
2653
	special: {
2654
		ready: {
2655
			// Make sure the ready event is setup
2656
			setup: bindReady,
2657
			teardown: function() {}
2658
		}
2659
	},
2660
	
2661
	specialAll: {
2662
		live: {
2663
			setup: function( selector, namespaces ){
2664
				jQuery.event.add( this, namespaces[0], liveHandler );
2665
			},
2666
			teardown:  function( namespaces ){
2667
				if ( namespaces.length ) {
2668
					var remove = 0, name = RegExp("(^|\\.)" + namespaces[0] + "(\\.|$)");
2669
					
2670
					jQuery.each( (jQuery.data(this, "events").live || {}), function(){
2671
						if ( name.test(this.type) )
2672
							remove++;
2673
					});
2674
					
2675
					if ( remove < 1 )
2676
						jQuery.event.remove( this, namespaces[0], liveHandler );
2677
				}
2678
			}
2679
		}
2680
	}
2681
};
2682

    
2683
jQuery.Event = function( src ){
2684
	// Allow instantiation without the 'new' keyword
2685
	if( !this.preventDefault )
2686
		return new jQuery.Event(src);
2687
	
2688
	// Event object
2689
	if( src && src.type ){
2690
		this.originalEvent = src;
2691
		this.type = src.type;
2692
	// Event type
2693
	}else
2694
		this.type = src;
2695

    
2696
	// timeStamp is buggy for some events on Firefox(#3843)
2697
	// So we won't rely on the native value
2698
	this.timeStamp = now();
2699
	
2700
	// Mark it as fixed
2701
	this[expando] = true;
2702
};
2703

    
2704
function returnFalse(){
2705
	return false;
2706
}
2707
function returnTrue(){
2708
	return true;
2709
}
2710

    
2711
// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
2712
// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
2713
jQuery.Event.prototype = {
2714
	preventDefault: function() {
2715
		this.isDefaultPrevented = returnTrue;
2716

    
2717
		var e = this.originalEvent;
2718
		if( !e )
2719
			return;
2720
		// if preventDefault exists run it on the original event
2721
		if (e.preventDefault)
2722
			e.preventDefault();
2723
		// otherwise set the returnValue property of the original event to false (IE)
2724
		e.returnValue = false;
2725
	},
2726
	stopPropagation: function() {
2727
		this.isPropagationStopped = returnTrue;
2728

    
2729
		var e = this.originalEvent;
2730
		if( !e )
2731
			return;
2732
		// if stopPropagation exists run it on the original event
2733
		if (e.stopPropagation)
2734
			e.stopPropagation();
2735
		// otherwise set the cancelBubble property of the original event to true (IE)
2736
		e.cancelBubble = true;
2737
	},
2738
	stopImmediatePropagation:function(){
2739
		this.isImmediatePropagationStopped = returnTrue;
2740
		this.stopPropagation();
2741
	},
2742
	isDefaultPrevented: returnFalse,
2743
	isPropagationStopped: returnFalse,
2744
	isImmediatePropagationStopped: returnFalse
2745
};
2746
// Checks if an event happened on an element within another element
2747
// Used in jQuery.event.special.mouseenter and mouseleave handlers
2748
var withinElement = function(event) {
2749
	// Check if mouse(over|out) are still within the same parent element
2750
	var parent = event.relatedTarget;
2751
	// Traverse up the tree
2752
	while ( parent && parent != this )
2753
		try { parent = parent.parentNode; }
2754
		catch(e) { parent = this; }
2755
	
2756
	if( parent != this ){
2757
		// set the correct event type
2758
		event.type = event.data;
2759
		// handle event if we actually just moused on to a non sub-element
2760
		jQuery.event.handle.apply( this, arguments );
2761
	}
2762
};
2763
	
2764
jQuery.each({ 
2765
	mouseover: 'mouseenter', 
2766
	mouseout: 'mouseleave'
2767
}, function( orig, fix ){
2768
	jQuery.event.special[ fix ] = {
2769
		setup: function(){
2770
			jQuery.event.add( this, orig, withinElement, fix );
2771
		},
2772
		teardown: function(){
2773
			jQuery.event.remove( this, orig, withinElement );
2774
		}
2775
	};			   
2776
});
2777

    
2778
jQuery.fn.extend({
2779
	bind: function( type, data, fn ) {
2780
		return type == "unload" ? this.one(type, data, fn) : this.each(function(){
2781
			jQuery.event.add( this, type, fn || data, fn && data );
2782
		});
2783
	},
2784

    
2785
	one: function( type, data, fn ) {
2786
		var one = jQuery.event.proxy( fn || data, function(event) {
2787
			jQuery(this).unbind(event, one);
2788
			return (fn || data).apply( this, arguments );
2789
		});
2790
		return this.each(function(){
2791
			jQuery.event.add( this, type, one, fn && data);
2792
		});
2793
	},
2794

    
2795
	unbind: function( type, fn ) {
2796
		return this.each(function(){
2797
			jQuery.event.remove( this, type, fn );
2798
		});
2799
	},
2800

    
2801
	trigger: function( type, data ) {
2802
		return this.each(function(){
2803
			jQuery.event.trigger( type, data, this );
2804
		});
2805
	},
2806

    
2807
	triggerHandler: function( type, data ) {
2808
		if( this[0] ){
2809
			var event = jQuery.Event(type);
2810
			event.preventDefault();
2811
			event.stopPropagation();
2812
			jQuery.event.trigger( event, data, this[0] );
2813
			return event.result;
2814
		}		
2815
	},
2816

    
2817
	toggle: function( fn ) {
2818
		// Save reference to arguments for access in closure
2819
		var args = arguments, i = 1;
2820

    
2821
		// link all the functions, so any of them can unbind this click handler
2822
		while( i < args.length )
2823
			jQuery.event.proxy( fn, args[i++] );
2824

    
2825
		return this.click( jQuery.event.proxy( fn, function(event) {
2826
			// Figure out which function to execute
2827
			this.lastToggle = ( this.lastToggle || 0 ) % i;
2828

    
2829
			// Make sure that clicks stop
2830
			event.preventDefault();
2831

    
2832
			// and execute the function
2833
			return args[ this.lastToggle++ ].apply( this, arguments ) || false;
2834
		}));
2835
	},
2836

    
2837
	hover: function(fnOver, fnOut) {
2838
		return this.mouseenter(fnOver).mouseleave(fnOut);
2839
	},
2840

    
2841
	ready: function(fn) {
2842
		// Attach the listeners
2843
		bindReady();
2844

    
2845
		// If the DOM is already ready
2846
		if ( jQuery.isReady )
2847
			// Execute the function immediately
2848
			fn.call( document, jQuery );
2849

    
2850
		// Otherwise, remember the function for later
2851
		else
2852
			// Add the function to the wait list
2853
			jQuery.readyList.push( fn );
2854

    
2855
		return this;
2856
	},
2857
	
2858
	live: function( type, fn ){
2859
		var proxy = jQuery.event.proxy( fn );
2860
		proxy.guid += this.selector + type;
2861

    
2862
		jQuery(document).bind( liveConvert(type, this.selector), this.selector, proxy );
2863

    
2864
		return this;
2865
	},
2866
	
2867
	die: function( type, fn ){
2868
		jQuery(document).unbind( liveConvert(type, this.selector), fn ? { guid: fn.guid + this.selector + type } : null );
2869
		return this;
2870
	}
2871
});
2872

    
2873
function liveHandler( event ){
2874
	var check = RegExp("(^|\\.)" + event.type + "(\\.|$)"),
2875
		stop = true,
2876
		elems = [];
2877

    
2878
	jQuery.each(jQuery.data(this, "events").live || [], function(i, fn){
2879
		if ( check.test(fn.type) ) {
2880
			var elem = jQuery(event.target).closest(fn.data)[0];
2881
			if ( elem )
2882
				elems.push({ elem: elem, fn: fn });
2883
		}
2884
	});
2885

    
2886
	jQuery.each(elems, function(){
2887
		if ( this.fn.call(this.elem, event, this.fn.data) === false )
2888
			stop = false;
2889
	});
2890

    
2891
	return stop;
2892
}
2893

    
2894
function liveConvert(type, selector){
2895
	return ["live", type, selector.replace(/\./g, "`").replace(/ /g, "|")].join(".");
2896
}
2897

    
2898
jQuery.extend({
2899
	isReady: false,
2900
	readyList: [],
2901
	// Handle when the DOM is ready
2902
	ready: function() {
2903
		// Make sure that the DOM is not already loaded
2904
		if ( !jQuery.isReady ) {
2905
			// Remember that the DOM is ready
2906
			jQuery.isReady = true;
2907

    
2908
			// If there are functions bound, to execute
2909
			if ( jQuery.readyList ) {
2910
				// Execute all of them
2911
				jQuery.each( jQuery.readyList, function(){
2912
					this.call( document, jQuery );
2913
				});
2914

    
2915
				// Reset the list of functions
2916
				jQuery.readyList = null;
2917
			}
2918

    
2919
			// Trigger any bound ready events
2920
			jQuery(document).triggerHandler("ready");
2921
		}
2922
	}
2923
});
2924

    
2925
var readyBound = false;
2926

    
2927
function bindReady(){
2928
	if ( readyBound ) return;
2929
	readyBound = true;
2930

    
2931
	// Mozilla, Opera and webkit nightlies currently support this event
2932
	if ( document.addEventListener ) {
2933
		// Use the handy event callback
2934
		document.addEventListener( "DOMContentLoaded", function(){
2935
			document.removeEventListener( "DOMContentLoaded", arguments.callee, false );
2936
			jQuery.ready();
2937
		}, false );
2938

    
2939
	// If IE event model is used
2940
	} else if ( document.attachEvent ) {
2941
		// ensure firing before onload,
2942
		// maybe late but safe also for iframes
2943
		document.attachEvent("onreadystatechange", function(){
2944
			if ( document.readyState === "complete" ) {
2945
				document.detachEvent( "onreadystatechange", arguments.callee );
2946
				jQuery.ready();
2947
			}
2948
		});
2949

    
2950
		// If IE and not an iframe
2951
		// continually check to see if the document is ready
2952
		if ( document.documentElement.doScroll && typeof window.frameElement === "undefined" ) (function(){
2953
			if ( jQuery.isReady ) return;
2954

    
2955
			try {
2956
				// If IE is used, use the trick by Diego Perini
2957
				// http://javascript.nwbox.com/IEContentLoaded/
2958
				document.documentElement.doScroll("left");
2959
			} catch( error ) {
2960
				setTimeout( arguments.callee, 0 );
2961
				return;
2962
			}
2963

    
2964
			// and execute any waiting functions
2965
			jQuery.ready();
2966
		})();
2967
	}
2968

    
2969
	// A fallback to window.onload, that will always work
2970
	jQuery.event.add( window, "load", jQuery.ready );
2971
}
2972

    
2973
jQuery.each( ("blur,focus,load,resize,scroll,unload,click,dblclick," +
2974
	"mousedown,mouseup,mousemove,mouseover,mouseout,mouseenter,mouseleave," +
2975
	"change,select,submit,keydown,keypress,keyup,error").split(","), function(i, name){
2976

    
2977
	// Handle event binding
2978
	jQuery.fn[name] = function(fn){
2979
		return fn ? this.bind(name, fn) : this.trigger(name);
2980
	};
2981
});
2982

    
2983
// Prevent memory leaks in IE
2984
// And prevent errors on refresh with events like mouseover in other browsers
2985
// Window isn't included so as not to unbind existing unload events
2986
jQuery( window ).bind( 'unload', function(){ 
2987
	for ( var id in jQuery.cache )
2988
		// Skip the window
2989
		if ( id != 1 && jQuery.cache[ id ].handle )
2990
			jQuery.event.remove( jQuery.cache[ id ].handle.elem );
2991
}); 
2992
(function(){
2993

    
2994
	jQuery.support = {};
2995

    
2996
	var root = document.documentElement,
2997
		script = document.createElement("script"),
2998
		div = document.createElement("div"),
2999
		id = "script" + (new Date).getTime();
3000

    
3001
	div.style.display = "none";
3002
	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>';
3003

    
3004
	var all = div.getElementsByTagName("*"),
3005
		a = div.getElementsByTagName("a")[0];
3006

    
3007
	// Can't get basic test support
3008
	if ( !all || !all.length || !a ) {
3009
		return;
3010
	}
3011

    
3012
	jQuery.support = {
3013
		// IE strips leading whitespace when .innerHTML is used
3014
		leadingWhitespace: div.firstChild.nodeType == 3,
3015
		
3016
		// Make sure that tbody elements aren't automatically inserted
3017
		// IE will insert them into empty tables
3018
		tbody: !div.getElementsByTagName("tbody").length,
3019
		
3020
		// Make sure that you can get all elements in an <object> element
3021
		// IE 7 always returns no results
3022
		objectAll: !!div.getElementsByTagName("object")[0]
3023
			.getElementsByTagName("*").length,
3024
		
3025
		// Make sure that link elements get serialized correctly by innerHTML
3026
		// This requires a wrapper element in IE
3027
		htmlSerialize: !!div.getElementsByTagName("link").length,
3028
		
3029
		// Get the style information from getAttribute
3030
		// (IE uses .cssText insted)
3031
		style: /red/.test( a.getAttribute("style") ),
3032
		
3033
		// Make sure that URLs aren't manipulated
3034
		// (IE normalizes it by default)
3035
		hrefNormalized: a.getAttribute("href") === "/a",
3036
		
3037
		// Make sure that element opacity exists
3038
		// (IE uses filter instead)
3039
		opacity: a.style.opacity === "0.5",
3040
		
3041
		// Verify style float existence
3042
		// (IE uses styleFloat instead of cssFloat)
3043
		cssFloat: !!a.style.cssFloat,
3044

    
3045
		// Will be defined later
3046
		scriptEval: false,
3047
		noCloneEvent: true,
3048
		boxModel: null
3049
	};
3050
	
3051
	script.type = "text/javascript";
3052
	try {
3053
		script.appendChild( document.createTextNode( "window." + id + "=1;" ) );
3054
	} catch(e){}
3055

    
3056
	root.insertBefore( script, root.firstChild );
3057
	
3058
	// Make sure that the execution of code works by injecting a script
3059
	// tag with appendChild/createTextNode
3060
	// (IE doesn't support this, fails, and uses .text instead)
3061
	if ( window[ id ] ) {
3062
		jQuery.support.scriptEval = true;
3063
		delete window[ id ];
3064
	}
3065

    
3066
	root.removeChild( script );
3067

    
3068
	if ( div.attachEvent && div.fireEvent ) {
3069
		div.attachEvent("onclick", function(){
3070
			// Cloning a node shouldn't copy over any
3071
			// bound event handlers (IE does this)
3072
			jQuery.support.noCloneEvent = false;
3073
			div.detachEvent("onclick", arguments.callee);
3074
		});
3075
		div.cloneNode(true).fireEvent("onclick");
3076
	}
3077

    
3078
	// Figure out if the W3C box model works as expected
3079
	// document.body must exist before we can do this
3080
	jQuery(function(){
3081
		var div = document.createElement("div");
3082
		div.style.width = "1px";
3083
		div.style.paddingLeft = "1px";
3084

    
3085
		document.body.appendChild( div );
3086
		jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2;
3087
		document.body.removeChild( div );
3088
	});
3089
})();
3090

    
3091
var styleFloat = jQuery.support.cssFloat ? "cssFloat" : "styleFloat";
3092

    
3093
jQuery.props = {
3094
	"for": "htmlFor",
3095
	"class": "className",
3096
	"float": styleFloat,
3097
	cssFloat: styleFloat,
3098
	styleFloat: styleFloat,
3099
	readonly: "readOnly",
3100
	maxlength: "maxLength",
3101
	cellspacing: "cellSpacing",
3102
	rowspan: "rowSpan",
3103
	tabindex: "tabIndex"
3104
};
3105
jQuery.fn.extend({
3106
	// Keep a copy of the old load
3107
	_load: jQuery.fn.load,
3108

    
3109
	load: function( url, params, callback ) {
3110
		if ( typeof url !== "string" )
3111
			return this._load( url );
3112

    
3113
		var off = url.indexOf(" ");
3114
		if ( off >= 0 ) {
3115
			var selector = url.slice(off, url.length);
3116
			url = url.slice(0, off);
3117
		}
3118

    
3119
		// Default to a GET request
3120
		var type = "GET";
3121

    
3122
		// If the second parameter was provided
3123
		if ( params )
3124
			// If it's a function
3125
			if ( jQuery.isFunction( params ) ) {
3126
				// We assume that it's the callback
3127
				callback = params;
3128
				params = null;
3129

    
3130
			// Otherwise, build a param string
3131
			} else if( typeof params === "object" ) {
3132
				params = jQuery.param( params );
3133
				type = "POST";
3134
			}
3135

    
3136
		var self = this;
3137

    
3138
		// Request the remote document
3139
		jQuery.ajax({
3140
			url: url,
3141
			type: type,
3142
			dataType: "html",
3143
			data: params,
3144
			complete: function(res, status){
3145
				// If successful, inject the HTML into all the matched elements
3146
				if ( status == "success" || status == "notmodified" )
3147
					// See if a selector was specified
3148
					self.html( selector ?
3149
						// Create a dummy div to hold the results
3150
						jQuery("<div/>")
3151
							// inject the contents of the document in, removing the scripts
3152
							// to avoid any 'Permission Denied' errors in IE
3153
							.append(res.responseText.replace(/<script(.|\s)*?\/script>/g, ""))
3154

    
3155
							// Locate the specified elements
3156
							.find(selector) :
3157

    
3158
						// If not, just inject the full result
3159
						res.responseText );
3160

    
3161
				if( callback )
3162
					self.each( callback, [res.responseText, status, res] );
3163
			}
3164
		});
3165
		return this;
3166
	},
3167

    
3168
	serialize: function() {
3169
		return jQuery.param(this.serializeArray());
3170
	},
3171
	serializeArray: function() {
3172
		return this.map(function(){
3173
			return this.elements ? jQuery.makeArray(this.elements) : this;
3174
		})
3175
		.filter(function(){
3176
			return this.name && !this.disabled &&
3177
				(this.checked || /select|textarea/i.test(this.nodeName) ||
3178
					/text|hidden|password/i.test(this.type));
3179
		})
3180
		.map(function(i, elem){
3181
			var val = jQuery(this).val();
3182
			return val == null ? null :
3183
				jQuery.isArray(val) ?
3184
					jQuery.map( val, function(val, i){
3185
						return {name: elem.name, value: val};
3186
					}) :
3187
					{name: elem.name, value: val};
3188
		}).get();
3189
	}
3190
});
3191

    
3192
// Attach a bunch of functions for handling common AJAX events
3193
jQuery.each( "ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","), function(i,o){
3194
	jQuery.fn[o] = function(f){
3195
		return this.bind(o, f);
3196
	};
3197
});
3198

    
3199
var jsc = now();
3200

    
3201
jQuery.extend({
3202
  
3203
	get: function( url, data, callback, type ) {
3204
		// shift arguments if data argument was ommited
3205
		if ( jQuery.isFunction( data ) ) {
3206
			callback = data;
3207
			data = null;
3208
		}
3209

    
3210
		return jQuery.ajax({
3211
			type: "GET",
3212
			url: url,
3213
			data: data,
3214
			success: callback,
3215
			dataType: type
3216
		});
3217
	},
3218

    
3219
	getScript: function( url, callback ) {
3220
		return jQuery.get(url, null, callback, "script");
3221
	},
3222

    
3223
	getJSON: function( url, data, callback ) {
3224
		return jQuery.get(url, data, callback, "json");
3225
	},
3226

    
3227
	post: function( url, data, callback, type ) {
3228
		if ( jQuery.isFunction( data ) ) {
3229
			callback = data;
3230
			data = {};
3231
		}
3232

    
3233
		return jQuery.ajax({
3234
			type: "POST",
3235
			url: url,
3236
			data: data,
3237
			success: callback,
3238
			dataType: type
3239
		});
3240
	},
3241

    
3242
	ajaxSetup: function( settings ) {
3243
		jQuery.extend( jQuery.ajaxSettings, settings );
3244
	},
3245

    
3246
	ajaxSettings: {
3247
		url: location.href,
3248
		global: true,
3249
		type: "GET",
3250
		contentType: "application/x-www-form-urlencoded",
3251
		processData: true,
3252
		async: true,
3253
		/*
3254
		timeout: 0,
3255
		data: null,
3256
		username: null,
3257
		password: null,
3258
		*/
3259
		// Create the request object; Microsoft failed to properly
3260
		// implement the XMLHttpRequest in IE7, so we use the ActiveXObject when it is available
3261
		// This function can be overriden by calling jQuery.ajaxSetup
3262
		xhr:function(){
3263
			return window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
3264
		},
3265
		accepts: {
3266
			xml: "application/xml, text/xml",
3267
			html: "text/html",
3268
			script: "text/javascript, application/javascript",
3269
			json: "application/json, text/javascript",
3270
			text: "text/plain",
3271
			_default: "*/*"
3272
		}
3273
	},
3274

    
3275
	// Last-Modified header cache for next request
3276
	lastModified: {},
3277

    
3278
	ajax: function( s ) {
3279
		// Extend the settings, but re-extend 's' so that it can be
3280
		// checked again later (in the test suite, specifically)
3281
		s = jQuery.extend(true, s, jQuery.extend(true, {}, jQuery.ajaxSettings, s));
3282

    
3283
		var jsonp, jsre = /=\?(&|$)/g, status, data,
3284
			type = s.type.toUpperCase();
3285

    
3286
		// convert data if not already a string
3287
		if ( s.data && s.processData && typeof s.data !== "string" )
3288
			s.data = jQuery.param(s.data);
3289

    
3290
		// Handle JSONP Parameter Callbacks
3291
		if ( s.dataType == "jsonp" ) {
3292
			if ( type == "GET" ) {
3293
				if ( !s.url.match(jsre) )
3294
					s.url += (s.url.match(/\?/) ? "&" : "?") + (s.jsonp || "callback") + "=?";
3295
			} else if ( !s.data || !s.data.match(jsre) )
3296
				s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";
3297
			s.dataType = "json";
3298
		}
3299

    
3300
		// Build temporary JSONP function
3301
		if ( s.dataType == "json" && (s.data && s.data.match(jsre) || s.url.match(jsre)) ) {
3302
			jsonp = "jsonp" + jsc++;
3303

    
3304
			// Replace the =? sequence both in the query string and the data
3305
			if ( s.data )
3306
				s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");
3307
			s.url = s.url.replace(jsre, "=" + jsonp + "$1");
3308

    
3309
			// We need to make sure
3310
			// that a JSONP style response is executed properly
3311
			s.dataType = "script";
3312

    
3313
			// Handle JSONP-style loading
3314
			window[ jsonp ] = function(tmp){
3315
				data = tmp;
3316
				success();
3317
				complete();
3318
				// Garbage collect
3319
				window[ jsonp ] = undefined;
3320
				try{ delete window[ jsonp ]; } catch(e){}
3321
				if ( head )
3322
					head.removeChild( script );
3323
			};
3324
		}
3325

    
3326
		if ( s.dataType == "script" && s.cache == null )
3327
			s.cache = false;
3328

    
3329
		if ( s.cache === false && type == "GET" ) {
3330
			var ts = now();
3331
			// try replacing _= if it is there
3332
			var ret = s.url.replace(/(\?|&)_=.*?(&|$)/, "$1_=" + ts + "$2");
3333
			// if nothing was replaced, add timestamp to the end
3334
			s.url = ret + ((ret == s.url) ? (s.url.match(/\?/) ? "&" : "?") + "_=" + ts : "");
3335
		}
3336

    
3337
		// If data is available, append data to url for get requests
3338
		if ( s.data && type == "GET" ) {
3339
			s.url += (s.url.match(/\?/) ? "&" : "?") + s.data;
3340

    
3341
			// IE likes to send both get and post data, prevent this
3342
			s.data = null;
3343
		}
3344

    
3345
		// Watch for a new set of requests
3346
		if ( s.global && ! jQuery.active++ )
3347
			jQuery.event.trigger( "ajaxStart" );
3348

    
3349
		// Matches an absolute URL, and saves the domain
3350
		var parts = /^(\w+:)?\/\/([^\/?#]+)/.exec( s.url );
3351

    
3352
		// If we're requesting a remote document
3353
		// and trying to load JSON or Script with a GET
3354
		if ( s.dataType == "script" && type == "GET" && parts
3355
			&& ( parts[1] && parts[1] != location.protocol || parts[2] != location.host )){
3356

    
3357
			var head = document.getElementsByTagName("head")[0];
3358
			var script = document.createElement("script");
3359
			script.src = s.url;
3360
			if (s.scriptCharset)
3361
				script.charset = s.scriptCharset;
3362

    
3363
			// Handle Script loading
3364
			if ( !jsonp ) {
3365
				var done = false;
3366

    
3367
				// Attach handlers for all browsers
3368
				script.onload = script.onreadystatechange = function(){
3369
					if ( !done && (!this.readyState ||
3370
							this.readyState == "loaded" || this.readyState == "complete") ) {
3371
						done = true;
3372
						success();
3373
						complete();
3374
						head.removeChild( script );
3375
					}
3376
				};
3377
			}
3378

    
3379
			head.appendChild(script);
3380

    
3381
			// We handle everything using the script element injection
3382
			return undefined;
3383
		}
3384

    
3385
		var requestDone = false;
3386

    
3387
		// Create the request object
3388
		var xhr = s.xhr();
3389

    
3390
		// Open the socket
3391
		// Passing null username, generates a login popup on Opera (#2865)
3392
		if( s.username )
3393
			xhr.open(type, s.url, s.async, s.username, s.password);
3394
		else
3395
			xhr.open(type, s.url, s.async);
3396

    
3397
		// Need an extra try/catch for cross domain requests in Firefox 3
3398
		try {
3399
			// Set the correct header, if data is being sent
3400
			if ( s.data )
3401
				xhr.setRequestHeader("Content-Type", s.contentType);
3402

    
3403
			// Set the If-Modified-Since header, if ifModified mode.
3404
			if ( s.ifModified )
3405
				xhr.setRequestHeader("If-Modified-Since",
3406
					jQuery.lastModified[s.url] || "Thu, 01 Jan 1970 00:00:00 GMT" );
3407

    
3408
			// Set header so the called script knows that it's an XMLHttpRequest
3409
			xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
3410

    
3411
			// Set the Accepts header for the server, depending on the dataType
3412
			xhr.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ?
3413
				s.accepts[ s.dataType ] + ", */*" :
3414
				s.accepts._default );
3415
		} catch(e){}
3416

    
3417
		// Allow custom headers/mimetypes and early abort
3418
		if ( s.beforeSend && s.beforeSend(xhr, s) === false ) {
3419
			// Handle the global AJAX counter
3420
			if ( s.global && ! --jQuery.active )
3421
				jQuery.event.trigger( "ajaxStop" );
3422
			// close opended socket
3423
			xhr.abort();
3424
			return false;
3425
		}
3426

    
3427
		if ( s.global )
3428
			jQuery.event.trigger("ajaxSend", [xhr, s]);
3429

    
3430
		// Wait for a response to come back
3431
		var onreadystatechange = function(isTimeout){
3432
			// The request was aborted, clear the interval and decrement jQuery.active
3433
			if (xhr.readyState == 0) {
3434
				if (ival) {
3435
					// clear poll interval
3436
					clearInterval(ival);
3437
					ival = null;
3438
					// Handle the global AJAX counter
3439
					if ( s.global && ! --jQuery.active )
3440
						jQuery.event.trigger( "ajaxStop" );
3441
				}
3442
			// The transfer is complete and the data is available, or the request timed out
3443
			} else if ( !requestDone && xhr && (xhr.readyState == 4 || isTimeout == "timeout") ) {
3444
				requestDone = true;
3445

    
3446
				// clear poll interval
3447
				if (ival) {
3448
					clearInterval(ival);
3449
					ival = null;
3450
				}
3451

    
3452
				status = isTimeout == "timeout" ? "timeout" :
3453
					!jQuery.httpSuccess( xhr ) ? "error" :
3454
					s.ifModified && jQuery.httpNotModified( xhr, s.url ) ? "notmodified" :
3455
					"success";
3456

    
3457
				if ( status == "success" ) {
3458
					// Watch for, and catch, XML document parse errors
3459
					try {
3460
						// process the data (runs the xml through httpData regardless of callback)
3461
						data = jQuery.httpData( xhr, s.dataType, s );
3462
					} catch(e) {
3463
						status = "parsererror";
3464
					}
3465
				}
3466

    
3467
				// Make sure that the request was successful or notmodified
3468
				if ( status == "success" ) {
3469
					// Cache Last-Modified header, if ifModified mode.
3470
					var modRes;
3471
					try {
3472
						modRes = xhr.getResponseHeader("Last-Modified");
3473
					} catch(e) {} // swallow exception thrown by FF if header is not available
3474

    
3475
					if ( s.ifModified && modRes )
3476
						jQuery.lastModified[s.url] = modRes;
3477

    
3478
					// JSONP handles its own success callback
3479
					if ( !jsonp )
3480
						success();
3481
				} else
3482
					jQuery.handleError(s, xhr, status);
3483

    
3484
				// Fire the complete handlers
3485
				complete();
3486

    
3487
				if ( isTimeout )
3488
					xhr.abort();
3489

    
3490
				// Stop memory leaks
3491
				if ( s.async )
3492
					xhr = null;
3493
			}
3494
		};
3495

    
3496
		if ( s.async ) {
3497
			// don't attach the handler to the request, just poll it instead
3498
			var ival = setInterval(onreadystatechange, 13);
3499

    
3500
			// Timeout checker
3501
			if ( s.timeout > 0 )
3502
				setTimeout(function(){
3503
					// Check to see if the request is still happening
3504
					if ( xhr && !requestDone )
3505
						onreadystatechange( "timeout" );
3506
				}, s.timeout);
3507
		}
3508

    
3509
		// Send the data
3510
		try {
3511
			xhr.send(s.data);
3512
		} catch(e) {
3513
			jQuery.handleError(s, xhr, null, e);
3514
		}
3515

    
3516
		// firefox 1.5 doesn't fire statechange for sync requests
3517
		if ( !s.async )
3518
			onreadystatechange();
3519

    
3520
		function success(){
3521
			// If a local callback was specified, fire it and pass it the data
3522
			if ( s.success )
3523
				s.success( data, status );
3524

    
3525
			// Fire the global callback
3526
			if ( s.global )
3527
				jQuery.event.trigger( "ajaxSuccess", [xhr, s] );
3528
		}
3529

    
3530
		function complete(){
3531
			// Process result
3532
			if ( s.complete )
3533
				s.complete(xhr, status);
3534

    
3535
			// The request was completed
3536
			if ( s.global )
3537
				jQuery.event.trigger( "ajaxComplete", [xhr, s] );
3538

    
3539
			// Handle the global AJAX counter
3540
			if ( s.global && ! --jQuery.active )
3541
				jQuery.event.trigger( "ajaxStop" );
3542
		}
3543

    
3544
		// return XMLHttpRequest to allow aborting the request etc.
3545
		return xhr;
3546
	},
3547

    
3548
	handleError: function( s, xhr, status, e ) {
3549
		// If a local callback was specified, fire it
3550
		if ( s.error ) s.error( xhr, status, e );
3551

    
3552
		// Fire the global callback
3553
		if ( s.global )
3554
			jQuery.event.trigger( "ajaxError", [xhr, s, e] );
3555
	},
3556

    
3557
	// Counter for holding the number of active queries
3558
	active: 0,
3559

    
3560
	// Determines if an XMLHttpRequest was successful or not
3561
	httpSuccess: function( xhr ) {
3562
		try {
3563
			// IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450
3564
			return !xhr.status && location.protocol == "file:" ||
3565
				( xhr.status >= 200 && xhr.status < 300 ) || xhr.status == 304 || xhr.status == 1223;
3566
		} catch(e){}
3567
		return false;
3568
	},
3569

    
3570
	// Determines if an XMLHttpRequest returns NotModified
3571
	httpNotModified: function( xhr, url ) {
3572
		try {
3573
			var xhrRes = xhr.getResponseHeader("Last-Modified");
3574

    
3575
			// Firefox always returns 200. check Last-Modified date
3576
			return xhr.status == 304 || xhrRes == jQuery.lastModified[url];
3577
		} catch(e){}
3578
		return false;
3579
	},
3580

    
3581
	httpData: function( xhr, type, s ) {
3582
		var ct = xhr.getResponseHeader("content-type"),
3583
			xml = type == "xml" || !type && ct && ct.indexOf("xml") >= 0,
3584
			data = xml ? xhr.responseXML : xhr.responseText;
3585

    
3586
		if ( xml && data.documentElement.tagName == "parsererror" )
3587
			throw "parsererror";
3588
			
3589
		// Allow a pre-filtering function to sanitize the response
3590
		// s != null is checked to keep backwards compatibility
3591
		if( s && s.dataFilter )
3592
			data = s.dataFilter( data, type );
3593

    
3594
		// The filter can actually parse the response
3595
		if( typeof data === "string" ){
3596

    
3597
			// If the type is "script", eval it in global context
3598
			if ( type == "script" )
3599
				jQuery.globalEval( data );
3600

    
3601
			// Get the JavaScript object, if JSON is used.
3602
			if ( type == "json" )
3603
				data = window["eval"]("(" + data + ")");
3604
		}
3605
		
3606
		return data;
3607
	},
3608

    
3609
	// Serialize an array of form elements or a set of
3610
	// key/values into a query string
3611
	param: function( a ) {
3612
		var s = [ ];
3613

    
3614
		function add( key, value ){
3615
			s[ s.length ] = encodeURIComponent(key) + '=' + encodeURIComponent(value);
3616
		};
3617

    
3618
		// If an array was passed in, assume that it is an array
3619
		// of form elements
3620
		if ( jQuery.isArray(a) || a.jquery )
3621
			// Serialize the form elements
3622
			jQuery.each( a, function(){
3623
				add( this.name, this.value );
3624
			});
3625

    
3626
		// Otherwise, assume that it's an object of key/value pairs
3627
		else
3628
			// Serialize the key/values
3629
			for ( var j in a )
3630
				// If the value is an array then the key names need to be repeated
3631
				if ( jQuery.isArray(a[j]) )
3632
					jQuery.each( a[j], function(){
3633
						add( j, this );
3634
					});
3635
				else
3636
					add( j, jQuery.isFunction(a[j]) ? a[j]() : a[j] );
3637

    
3638
		// Return the resulting serialization
3639
		return s.join("&").replace(/%20/g, "+");
3640
	}
3641

    
3642
});
3643
var elemdisplay = {},
3644
	timerId,
3645
	fxAttrs = [
3646
		// height animations
3647
		[ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
3648
		// width animations
3649
		[ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
3650
		// opacity animations
3651
		[ "opacity" ]
3652
	];
3653

    
3654
function genFx( type, num ){
3655
	var obj = {};
3656
	jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function(){
3657
		obj[ this ] = type;
3658
	});
3659
	return obj;
3660
}
3661

    
3662
jQuery.fn.extend({
3663
	show: function(speed,callback){
3664
		if ( speed ) {
3665
			return this.animate( genFx("show", 3), speed, callback);
3666
		} else {
3667
			for ( var i = 0, l = this.length; i < l; i++ ){
3668
				var old = jQuery.data(this[i], "olddisplay");
3669
				
3670
				this[i].style.display = old || "";
3671
				
3672
				if ( jQuery.css(this[i], "display") === "none" ) {
3673
					var tagName = this[i].tagName, display;
3674
					
3675
					if ( elemdisplay[ tagName ] ) {
3676
						display = elemdisplay[ tagName ];
3677
					} else {
3678
						var elem = jQuery("<" + tagName + " />").appendTo("body");
3679
						
3680
						display = elem.css("display");
3681
						if ( display === "none" )
3682
							display = "block";
3683
						
3684
						elem.remove();
3685
						
3686
						elemdisplay[ tagName ] = display;
3687
					}
3688
					
3689
					this[i].style.display = jQuery.data(this[i], "olddisplay", display);
3690
				}
3691
			}
3692
			
3693
			return this;
3694
		}
3695
	},
3696

    
3697
	hide: function(speed,callback){
3698
		if ( speed ) {
3699
			return this.animate( genFx("hide", 3), speed, callback);
3700
		} else {
3701
			for ( var i = 0, l = this.length; i < l; i++ ){
3702
				var old = jQuery.data(this[i], "olddisplay");
3703
				if ( !old && old !== "none" )
3704
					jQuery.data(this[i], "olddisplay", jQuery.css(this[i], "display"));
3705
				this[i].style.display = "none";
3706
			}
3707
			return this;
3708
		}
3709
	},
3710

    
3711
	// Save the old toggle function
3712
	_toggle: jQuery.fn.toggle,
3713

    
3714
	toggle: function( fn, fn2 ){
3715
		var bool = typeof fn === "boolean";
3716

    
3717
		return jQuery.isFunction(fn) && jQuery.isFunction(fn2) ?
3718
			this._toggle.apply( this, arguments ) :
3719
			fn == null || bool ?
3720
				this.each(function(){
3721
					var state = bool ? fn : jQuery(this).is(":hidden");
3722
					jQuery(this)[ state ? "show" : "hide" ]();
3723
				}) :
3724
				this.animate(genFx("toggle", 3), fn, fn2);
3725
	},
3726

    
3727
	fadeTo: function(speed,to,callback){
3728
		return this.animate({opacity: to}, speed, callback);
3729
	},
3730

    
3731
	animate: function( prop, speed, easing, callback ) {
3732
		var optall = jQuery.speed(speed, easing, callback);
3733

    
3734
		return this[ optall.queue === false ? "each" : "queue" ](function(){
3735
		
3736
			var opt = jQuery.extend({}, optall), p,
3737
				hidden = this.nodeType == 1 && jQuery(this).is(":hidden"),
3738
				self = this;
3739
	
3740
			for ( p in prop ) {
3741
				if ( prop[p] == "hide" && hidden || prop[p] == "show" && !hidden )
3742
					return opt.complete.call(this);
3743

    
3744
				if ( ( p == "height" || p == "width" ) && this.style ) {
3745
					// Store display property
3746
					opt.display = jQuery.css(this, "display");
3747

    
3748
					// Make sure that nothing sneaks out
3749
					opt.overflow = this.style.overflow;
3750
				}
3751
			}
3752

    
3753
			if ( opt.overflow != null )
3754
				this.style.overflow = "hidden";
3755

    
3756
			opt.curAnim = jQuery.extend({}, prop);
3757

    
3758
			jQuery.each( prop, function(name, val){
3759
				var e = new jQuery.fx( self, opt, name );
3760

    
3761
				if ( /toggle|show|hide/.test(val) )
3762
					e[ val == "toggle" ? hidden ? "show" : "hide" : val ]( prop );
3763
				else {
3764
					var parts = val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),
3765
						start = e.cur(true) || 0;
3766

    
3767
					if ( parts ) {
3768
						var end = parseFloat(parts[2]),
3769
							unit = parts[3] || "px";
3770

    
3771
						// We need to compute starting value
3772
						if ( unit != "px" ) {
3773
							self.style[ name ] = (end || 1) + unit;
3774
							start = ((end || 1) / e.cur(true)) * start;
3775
							self.style[ name ] = start + unit;
3776
						}
3777

    
3778
						// If a +=/-= token was provided, we're doing a relative animation
3779
						if ( parts[1] )
3780
							end = ((parts[1] == "-=" ? -1 : 1) * end) + start;
3781

    
3782
						e.custom( start, end, unit );
3783
					} else
3784
						e.custom( start, val, "" );
3785
				}
3786
			});
3787

    
3788
			// For JS strict compliance
3789
			return true;
3790
		});
3791
	},
3792

    
3793
	stop: function(clearQueue, gotoEnd){
3794
		var timers = jQuery.timers;
3795

    
3796
		if (clearQueue)
3797
			this.queue([]);
3798

    
3799
		this.each(function(){
3800
			// go in reverse order so anything added to the queue during the loop is ignored
3801
			for ( var i = timers.length - 1; i >= 0; i-- )
3802
				if ( timers[i].elem == this ) {
3803
					if (gotoEnd)
3804
						// force the next step to be the last
3805
						timers[i](true);
3806
					timers.splice(i, 1);
3807
				}
3808
		});
3809

    
3810
		// start the next in the queue if the last step wasn't forced
3811
		if (!gotoEnd)
3812
			this.dequeue();
3813

    
3814
		return this;
3815
	}
3816

    
3817
});
3818

    
3819
// Generate shortcuts for custom animations
3820
jQuery.each({
3821
	slideDown: genFx("show", 1),
3822
	slideUp: genFx("hide", 1),
3823
	slideToggle: genFx("toggle", 1),
3824
	fadeIn: { opacity: "show" },
3825
	fadeOut: { opacity: "hide" }
3826
}, function( name, props ){
3827
	jQuery.fn[ name ] = function( speed, callback ){
3828
		return this.animate( props, speed, callback );
3829
	};
3830
});
3831

    
3832
jQuery.extend({
3833

    
3834
	speed: function(speed, easing, fn) {
3835
		var opt = typeof speed === "object" ? speed : {
3836
			complete: fn || !fn && easing ||
3837
				jQuery.isFunction( speed ) && speed,
3838
			duration: speed,
3839
			easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
3840
		};
3841

    
3842
		opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
3843
			jQuery.fx.speeds[opt.duration] || jQuery.fx.speeds._default;
3844

    
3845
		// Queueing
3846
		opt.old = opt.complete;
3847
		opt.complete = function(){
3848
			if ( opt.queue !== false )
3849
				jQuery(this).dequeue();
3850
			if ( jQuery.isFunction( opt.old ) )
3851
				opt.old.call( this );
3852
		};
3853

    
3854
		return opt;
3855
	},
3856

    
3857
	easing: {
3858
		linear: function( p, n, firstNum, diff ) {
3859
			return firstNum + diff * p;
3860
		},
3861
		swing: function( p, n, firstNum, diff ) {
3862
			return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
3863
		}
3864
	},
3865

    
3866
	timers: [],
3867

    
3868
	fx: function( elem, options, prop ){
3869
		this.options = options;
3870
		this.elem = elem;
3871
		this.prop = prop;
3872

    
3873
		if ( !options.orig )
3874
			options.orig = {};
3875
	}
3876

    
3877
});
3878

    
3879
jQuery.fx.prototype = {
3880

    
3881
	// Simple function for setting a style value
3882
	update: function(){
3883
		if ( this.options.step )
3884
			this.options.step.call( this.elem, this.now, this );
3885

    
3886
		(jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
3887

    
3888
		// Set display property to block for height/width animations
3889
		if ( ( this.prop == "height" || this.prop == "width" ) && this.elem.style )
3890
			this.elem.style.display = "block";
3891
	},
3892

    
3893
	// Get the current size
3894
	cur: function(force){
3895
		if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) )
3896
			return this.elem[ this.prop ];
3897

    
3898
		var r = parseFloat(jQuery.css(this.elem, this.prop, force));
3899
		return r && r > -10000 ? r : parseFloat(jQuery.curCSS(this.elem, this.prop)) || 0;
3900
	},
3901

    
3902
	// Start an animation from one number to another
3903
	custom: function(from, to, unit){
3904
		this.startTime = now();
3905
		this.start = from;
3906
		this.end = to;
3907
		this.unit = unit || this.unit || "px";
3908
		this.now = this.start;
3909
		this.pos = this.state = 0;
3910

    
3911
		var self = this;
3912
		function t(gotoEnd){
3913
			return self.step(gotoEnd);
3914
		}
3915

    
3916
		t.elem = this.elem;
3917

    
3918
		if ( t() && jQuery.timers.push(t) == 1 ) {
3919
			timerId = setInterval(function(){
3920
				var timers = jQuery.timers;
3921

    
3922
				for ( var i = 0; i < timers.length; i++ )
3923
					if ( !timers[i]() )
3924
						timers.splice(i--, 1);
3925

    
3926
				if ( !timers.length ) {
3927
					clearInterval( timerId );
3928
				}
3929
			}, 13);
3930
		}
3931
	},
3932

    
3933
	// Simple 'show' function
3934
	show: function(){
3935
		// Remember where we started, so that we can go back to it later
3936
		this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );
3937
		this.options.show = true;
3938

    
3939
		// Begin the animation
3940
		// Make sure that we start at a small width/height to avoid any
3941
		// flash of content
3942
		this.custom(this.prop == "width" || this.prop == "height" ? 1 : 0, this.cur());
3943

    
3944
		// Start by showing the element
3945
		jQuery(this.elem).show();
3946
	},
3947

    
3948
	// Simple 'hide' function
3949
	hide: function(){
3950
		// Remember where we started, so that we can go back to it later
3951
		this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );
3952
		this.options.hide = true;
3953

    
3954
		// Begin the animation
3955
		this.custom(this.cur(), 0);
3956
	},
3957

    
3958
	// Each step of an animation
3959
	step: function(gotoEnd){
3960
		var t = now();
3961

    
3962
		if ( gotoEnd || t >= this.options.duration + this.startTime ) {
3963
			this.now = this.end;
3964
			this.pos = this.state = 1;
3965
			this.update();
3966

    
3967
			this.options.curAnim[ this.prop ] = true;
3968

    
3969
			var done = true;
3970
			for ( var i in this.options.curAnim )
3971
				if ( this.options.curAnim[i] !== true )
3972
					done = false;
3973

    
3974
			if ( done ) {
3975
				if ( this.options.display != null ) {
3976
					// Reset the overflow
3977
					this.elem.style.overflow = this.options.overflow;
3978

    
3979
					// Reset the display
3980
					this.elem.style.display = this.options.display;
3981
					if ( jQuery.css(this.elem, "display") == "none" )
3982
						this.elem.style.display = "block";
3983
				}
3984

    
3985
				// Hide the element if the "hide" operation was done
3986
				if ( this.options.hide )
3987
					jQuery(this.elem).hide();
3988

    
3989
				// Reset the properties, if the item has been hidden or shown
3990
				if ( this.options.hide || this.options.show )
3991
					for ( var p in this.options.curAnim )
3992
						jQuery.attr(this.elem.style, p, this.options.orig[p]);
3993
					
3994
				// Execute the complete function
3995
				this.options.complete.call( this.elem );
3996
			}
3997

    
3998
			return false;
3999
		} else {
4000
			var n = t - this.startTime;
4001
			this.state = n / this.options.duration;
4002

    
4003
			// Perform the easing function, defaults to swing
4004
			this.pos = jQuery.easing[this.options.easing || (jQuery.easing.swing ? "swing" : "linear")](this.state, n, 0, 1, this.options.duration);
4005
			this.now = this.start + ((this.end - this.start) * this.pos);
4006

    
4007
			// Perform the next step of the animation
4008
			this.update();
4009
		}
4010

    
4011
		return true;
4012
	}
4013

    
4014
};
4015

    
4016
jQuery.extend( jQuery.fx, {
4017
	speeds:{
4018
		slow: 600,
4019
 		fast: 200,
4020
 		// Default speed
4021
 		_default: 400
4022
	},
4023
	step: {
4024

    
4025
		opacity: function(fx){
4026
			jQuery.attr(fx.elem.style, "opacity", fx.now);
4027
		},
4028

    
4029
		_default: function(fx){
4030
			if ( fx.elem.style && fx.elem.style[ fx.prop ] != null )
4031
				fx.elem.style[ fx.prop ] = fx.now + fx.unit;
4032
			else
4033
				fx.elem[ fx.prop ] = fx.now;
4034
		}
4035
	}
4036
});
4037
if ( document.documentElement["getBoundingClientRect"] )
4038
	jQuery.fn.offset = function() {
4039
		if ( !this[0] ) return { top: 0, left: 0 };
4040
		if ( this[0] === this[0].ownerDocument.body ) return jQuery.offset.bodyOffset( this[0] );
4041
		var box  = this[0].getBoundingClientRect(), doc = this[0].ownerDocument, body = doc.body, docElem = doc.documentElement,
4042
			clientTop = docElem.clientTop || body.clientTop || 0, clientLeft = docElem.clientLeft || body.clientLeft || 0,
4043
			top  = box.top  + (self.pageYOffset || jQuery.boxModel && docElem.scrollTop  || body.scrollTop ) - clientTop,
4044
			left = box.left + (self.pageXOffset || jQuery.boxModel && docElem.scrollLeft || body.scrollLeft) - clientLeft;
4045
		return { top: top, left: left };
4046
	};
4047
else 
4048
	jQuery.fn.offset = function() {
4049
		if ( !this[0] ) return { top: 0, left: 0 };
4050
		if ( this[0] === this[0].ownerDocument.body ) return jQuery.offset.bodyOffset( this[0] );
4051
		jQuery.offset.initialized || jQuery.offset.initialize();
4052

    
4053
		var elem = this[0], offsetParent = elem.offsetParent, prevOffsetParent = elem,
4054
			doc = elem.ownerDocument, computedStyle, docElem = doc.documentElement,
4055
			body = doc.body, defaultView = doc.defaultView,
4056
			prevComputedStyle = defaultView.getComputedStyle(elem, null),
4057
			top = elem.offsetTop, left = elem.offsetLeft;
4058

    
4059
		while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
4060
			computedStyle = defaultView.getComputedStyle(elem, null);
4061
			top -= elem.scrollTop, left -= elem.scrollLeft;
4062
			if ( elem === offsetParent ) {
4063
				top += elem.offsetTop, left += elem.offsetLeft;
4064
				if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && /^t(able|d|h)$/i.test(elem.tagName)) )
4065
					top  += parseInt( computedStyle.borderTopWidth,  10) || 0,
4066
					left += parseInt( computedStyle.borderLeftWidth, 10) || 0;
4067
				prevOffsetParent = offsetParent, offsetParent = elem.offsetParent;
4068
			}
4069
			if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" )
4070
				top  += parseInt( computedStyle.borderTopWidth,  10) || 0,
4071
				left += parseInt( computedStyle.borderLeftWidth, 10) || 0;
4072
			prevComputedStyle = computedStyle;
4073
		}
4074

    
4075
		if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" )
4076
			top  += body.offsetTop,
4077
			left += body.offsetLeft;
4078

    
4079
		if ( prevComputedStyle.position === "fixed" )
4080
			top  += Math.max(docElem.scrollTop, body.scrollTop),
4081
			left += Math.max(docElem.scrollLeft, body.scrollLeft);
4082

    
4083
		return { top: top, left: left };
4084
	};
4085

    
4086
jQuery.offset = {
4087
	initialize: function() {
4088
		if ( this.initialized ) return;
4089
		var body = document.body, container = document.createElement('div'), innerDiv, checkDiv, table, td, rules, prop, bodyMarginTop = body.style.marginTop,
4090
			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>';
4091

    
4092
		rules = { position: 'absolute', top: 0, left: 0, margin: 0, border: 0, width: '1px', height: '1px', visibility: 'hidden' };
4093
		for ( prop in rules ) container.style[prop] = rules[prop];
4094

    
4095
		container.innerHTML = html;
4096
		body.insertBefore(container, body.firstChild);
4097
		innerDiv = container.firstChild, checkDiv = innerDiv.firstChild, td = innerDiv.nextSibling.firstChild.firstChild;
4098

    
4099
		this.doesNotAddBorder = (checkDiv.offsetTop !== 5);
4100
		this.doesAddBorderForTableAndCells = (td.offsetTop === 5);
4101

    
4102
		innerDiv.style.overflow = 'hidden', innerDiv.style.position = 'relative';
4103
		this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5);
4104

    
4105
		body.style.marginTop = '1px';
4106
		this.doesNotIncludeMarginInBodyOffset = (body.offsetTop === 0);
4107
		body.style.marginTop = bodyMarginTop;
4108

    
4109
		body.removeChild(container);
4110
		this.initialized = true;
4111
	},
4112

    
4113
	bodyOffset: function(body) {
4114
		jQuery.offset.initialized || jQuery.offset.initialize();
4115
		var top = body.offsetTop, left = body.offsetLeft;
4116
		if ( jQuery.offset.doesNotIncludeMarginInBodyOffset )
4117
			top  += parseInt( jQuery.curCSS(body, 'marginTop',  true), 10 ) || 0,
4118
			left += parseInt( jQuery.curCSS(body, 'marginLeft', true), 10 ) || 0;
4119
		return { top: top, left: left };
4120
	}
4121
};
4122

    
4123

    
4124
jQuery.fn.extend({
4125
	position: function() {
4126
		var left = 0, top = 0, results;
4127

    
4128
		if ( this[0] ) {
4129
			// Get *real* offsetParent
4130
			var offsetParent = this.offsetParent(),
4131

    
4132
			// Get correct offsets
4133
			offset       = this.offset(),
4134
			parentOffset = /^body|html$/i.test(offsetParent[0].tagName) ? { top: 0, left: 0 } : offsetParent.offset();
4135

    
4136
			// Subtract element margins
4137
			// note: when an element has margin: auto the offsetLeft and marginLeft 
4138
			// are the same in Safari causing offset.left to incorrectly be 0
4139
			offset.top  -= num( this, 'marginTop'  );
4140
			offset.left -= num( this, 'marginLeft' );
4141

    
4142
			// Add offsetParent borders
4143
			parentOffset.top  += num( offsetParent, 'borderTopWidth'  );
4144
			parentOffset.left += num( offsetParent, 'borderLeftWidth' );
4145

    
4146
			// Subtract the two offsets
4147
			results = {
4148
				top:  offset.top  - parentOffset.top,
4149
				left: offset.left - parentOffset.left
4150
			};
4151
		}
4152

    
4153
		return results;
4154
	},
4155

    
4156
	offsetParent: function() {
4157
		var offsetParent = this[0].offsetParent || document.body;
4158
		while ( offsetParent && (!/^body|html$/i.test(offsetParent.tagName) && jQuery.css(offsetParent, 'position') == 'static') )
4159
			offsetParent = offsetParent.offsetParent;
4160
		return jQuery(offsetParent);
4161
	}
4162
});
4163

    
4164

    
4165
// Create scrollLeft and scrollTop methods
4166
jQuery.each( ['Left', 'Top'], function(i, name) {
4167
	var method = 'scroll' + name;
4168
	
4169
	jQuery.fn[ method ] = function(val) {
4170
		if (!this[0]) return null;
4171

    
4172
		return val !== undefined ?
4173

    
4174
			// Set the scroll offset
4175
			this.each(function() {
4176
				this == window || this == document ?
4177
					window.scrollTo(
4178
						!i ? val : jQuery(window).scrollLeft(),
4179
						 i ? val : jQuery(window).scrollTop()
4180
					) :
4181
					this[ method ] = val;
4182
			}) :
4183

    
4184
			// Return the scroll offset
4185
			this[0] == window || this[0] == document ?
4186
				self[ i ? 'pageYOffset' : 'pageXOffset' ] ||
4187
					jQuery.boxModel && document.documentElement[ method ] ||
4188
					document.body[ method ] :
4189
				this[0][ method ];
4190
	};
4191
});
4192
// Create innerHeight, innerWidth, outerHeight and outerWidth methods
4193
jQuery.each([ "Height", "Width" ], function(i, name){
4194

    
4195
	var tl = i ? "Left"  : "Top",  // top or left
4196
		br = i ? "Right" : "Bottom"; // bottom or right
4197

    
4198
	// innerHeight and innerWidth
4199
	jQuery.fn["inner" + name] = function(){
4200
		return this[ name.toLowerCase() ]() +
4201
			num(this, "padding" + tl) +
4202
			num(this, "padding" + br);
4203
	};
4204

    
4205
	// outerHeight and outerWidth
4206
	jQuery.fn["outer" + name] = function(margin) {
4207
		return this["inner" + name]() +
4208
			num(this, "border" + tl + "Width") +
4209
			num(this, "border" + br + "Width") +
4210
			(margin ?
4211
				num(this, "margin" + tl) + num(this, "margin" + br) : 0);
4212
	};
4213
	
4214
	var type = name.toLowerCase();
4215

    
4216
	jQuery.fn[ type ] = function( size ) {
4217
		// Get window width or height
4218
		return this[0] == window ?
4219
			// Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
4220
			document.compatMode == "CSS1Compat" && document.documentElement[ "client" + name ] ||
4221
			document.body[ "client" + name ] :
4222

    
4223
			// Get document width or height
4224
			this[0] == document ?
4225
				// Either scroll[Width/Height] or offset[Width/Height], whichever is greater
4226
				Math.max(
4227
					document.documentElement["client" + name],
4228
					document.body["scroll" + name], document.documentElement["scroll" + name],
4229
					document.body["offset" + name], document.documentElement["offset" + name]
4230
				) :
4231

    
4232
				// Get or set width or height on the element
4233
				size === undefined ?
4234
					// Get width or height on the element
4235
					(this.length ? jQuery.css( this[0], type ) : null) :
4236

    
4237
					// Set the width or height on the element (default to pixels if value is unitless)
4238
					this.css( type, typeof size === "string" ? size : size + "px" );
4239
	};
4240

    
4241
});})();
(1-1/3)