Хранилища Subversion ant

Редакция

Редакция 19 | Содержимое файла | Сравнить с предыдущей | Последнее изменение | Открыть журнал | RSS

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