Revision 153d4ab8

b/ui/static/snf/js/lib/jquery-1.6.4.js
1
/*!
2
 * jQuery JavaScript Library v1.6.4
3
 * http://jquery.com/
4
 *
5
 * Copyright 2011, John Resig
6
 * Dual licensed under the MIT or GPL Version 2 licenses.
7
 * http://jquery.org/license
8
 *
9
 * Includes Sizzle.js
10
 * http://sizzlejs.com/
11
 * Copyright 2011, The Dojo Foundation
12
 * Released under the MIT, BSD, and GPL Licenses.
13
 *
14
 * Date: Mon Sep 12 18:54:48 2011 -0400
15
 */
16
(function( window, undefined ) {
17

  
18
// Use the correct document accordingly with window argument (sandbox)
19
var document = window.document,
20
	navigator = window.navigator,
21
	location = window.location;
22
var jQuery = (function() {
23

  
24
// Define a local copy of jQuery
25
var jQuery = function( selector, context ) {
26
		// The jQuery object is actually just the init constructor 'enhanced'
27
		return new jQuery.fn.init( selector, context, rootjQuery );
28
	},
29

  
30
	// Map over jQuery in case of overwrite
31
	_jQuery = window.jQuery,
32

  
33
	// Map over the $ in case of overwrite
34
	_$ = window.$,
35

  
36
	// A central reference to the root jQuery(document)
37
	rootjQuery,
38

  
39
	// A simple way to check for HTML strings or ID strings
40
	// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
41
	quickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,
42

  
43
	// Check if a string has a non-whitespace character in it
44
	rnotwhite = /\S/,
45

  
46
	// Used for trimming whitespace
47
	trimLeft = /^\s+/,
48
	trimRight = /\s+$/,
49

  
50
	// Check for digits
51
	rdigit = /\d/,
52

  
53
	// Match a standalone tag
54
	rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/,
55

  
56
	// JSON RegExp
57
	rvalidchars = /^[\],:{}\s]*$/,
58
	rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,
59
	rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
60
	rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g,
61

  
62
	// Useragent RegExp
63
	rwebkit = /(webkit)[ \/]([\w.]+)/,
64
	ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/,
65
	rmsie = /(msie) ([\w.]+)/,
66
	rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/,
67

  
68
	// Matches dashed string for camelizing
69
	rdashAlpha = /-([a-z]|[0-9])/ig,
70
	rmsPrefix = /^-ms-/,
71

  
72
	// Used by jQuery.camelCase as callback to replace()
73
	fcamelCase = function( all, letter ) {
74
		return ( letter + "" ).toUpperCase();
75
	},
76

  
77
	// Keep a UserAgent string for use with jQuery.browser
78
	userAgent = navigator.userAgent,
79

  
80
	// For matching the engine and version of the browser
81
	browserMatch,
82

  
83
	// The deferred used on DOM ready
84
	readyList,
85

  
86
	// The ready event handler
87
	DOMContentLoaded,
88

  
89
	// Save a reference to some core methods
90
	toString = Object.prototype.toString,
91
	hasOwn = Object.prototype.hasOwnProperty,
92
	push = Array.prototype.push,
93
	slice = Array.prototype.slice,
94
	trim = String.prototype.trim,
95
	indexOf = Array.prototype.indexOf,
96

  
97
	// [[Class]] -> type pairs
98
	class2type = {};
99

  
100
jQuery.fn = jQuery.prototype = {
101
	constructor: jQuery,
102
	init: function( selector, context, rootjQuery ) {
103
		var match, elem, ret, doc;
104

  
105
		// Handle $(""), $(null), or $(undefined)
106
		if ( !selector ) {
107
			return this;
108
		}
109

  
110
		// Handle $(DOMElement)
111
		if ( selector.nodeType ) {
112
			this.context = this[0] = selector;
113
			this.length = 1;
114
			return this;
115
		}
116

  
117
		// The body element only exists once, optimize finding it
118
		if ( selector === "body" && !context && document.body ) {
119
			this.context = document;
120
			this[0] = document.body;
121
			this.selector = selector;
122
			this.length = 1;
123
			return this;
124
		}
125

  
126
		// Handle HTML strings
127
		if ( typeof selector === "string" ) {
128
			// Are we dealing with HTML string or an ID?
129
			if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
130
				// Assume that strings that start and end with <> are HTML and skip the regex check
131
				match = [ null, selector, null ];
132

  
133
			} else {
134
				match = quickExpr.exec( selector );
135
			}
136

  
137
			// Verify a match, and that no context was specified for #id
138
			if ( match && (match[1] || !context) ) {
139

  
140
				// HANDLE: $(html) -> $(array)
141
				if ( match[1] ) {
142
					context = context instanceof jQuery ? context[0] : context;
143
					doc = (context ? context.ownerDocument || context : document);
144

  
145
					// If a single string is passed in and it's a single tag
146
					// just do a createElement and skip the rest
147
					ret = rsingleTag.exec( selector );
148

  
149
					if ( ret ) {
150
						if ( jQuery.isPlainObject( context ) ) {
151
							selector = [ document.createElement( ret[1] ) ];
152
							jQuery.fn.attr.call( selector, context, true );
153

  
154
						} else {
155
							selector = [ doc.createElement( ret[1] ) ];
156
						}
157

  
158
					} else {
159
						ret = jQuery.buildFragment( [ match[1] ], [ doc ] );
160
						selector = (ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment).childNodes;
161
					}
162

  
163
					return jQuery.merge( this, selector );
164

  
165
				// HANDLE: $("#id")
166
				} else {
167
					elem = document.getElementById( match[2] );
168

  
169
					// Check parentNode to catch when Blackberry 4.6 returns
170
					// nodes that are no longer in the document #6963
171
					if ( elem && elem.parentNode ) {
172
						// Handle the case where IE and Opera return items
173
						// by name instead of ID
174
						if ( elem.id !== match[2] ) {
175
							return rootjQuery.find( selector );
176
						}
177

  
178
						// Otherwise, we inject the element directly into the jQuery object
179
						this.length = 1;
180
						this[0] = elem;
181
					}
182

  
183
					this.context = document;
184
					this.selector = selector;
185
					return this;
186
				}
187

  
188
			// HANDLE: $(expr, $(...))
189
			} else if ( !context || context.jquery ) {
190
				return (context || rootjQuery).find( selector );
191

  
192
			// HANDLE: $(expr, context)
193
			// (which is just equivalent to: $(context).find(expr)
194
			} else {
195
				return this.constructor( context ).find( selector );
196
			}
197

  
198
		// HANDLE: $(function)
199
		// Shortcut for document ready
200
		} else if ( jQuery.isFunction( selector ) ) {
201
			return rootjQuery.ready( selector );
202
		}
203

  
204
		if (selector.selector !== undefined) {
205
			this.selector = selector.selector;
206
			this.context = selector.context;
207
		}
208

  
209
		return jQuery.makeArray( selector, this );
210
	},
211

  
212
	// Start with an empty selector
213
	selector: "",
214

  
215
	// The current version of jQuery being used
216
	jquery: "1.6.4",
217

  
218
	// The default length of a jQuery object is 0
219
	length: 0,
220

  
221
	// The number of elements contained in the matched element set
222
	size: function() {
223
		return this.length;
224
	},
225

  
226
	toArray: function() {
227
		return slice.call( this, 0 );
228
	},
229

  
230
	// Get the Nth element in the matched element set OR
231
	// Get the whole matched element set as a clean array
232
	get: function( num ) {
233
		return num == null ?
234

  
235
			// Return a 'clean' array
236
			this.toArray() :
237

  
238
			// Return just the object
239
			( num < 0 ? this[ this.length + num ] : this[ num ] );
240
	},
241

  
242
	// Take an array of elements and push it onto the stack
243
	// (returning the new matched element set)
244
	pushStack: function( elems, name, selector ) {
245
		// Build a new jQuery matched element set
246
		var ret = this.constructor();
247

  
248
		if ( jQuery.isArray( elems ) ) {
249
			push.apply( ret, elems );
250

  
251
		} else {
252
			jQuery.merge( ret, elems );
253
		}
254

  
255
		// Add the old object onto the stack (as a reference)
256
		ret.prevObject = this;
257

  
258
		ret.context = this.context;
259

  
260
		if ( name === "find" ) {
261
			ret.selector = this.selector + (this.selector ? " " : "") + selector;
262
		} else if ( name ) {
263
			ret.selector = this.selector + "." + name + "(" + selector + ")";
264
		}
265

  
266
		// Return the newly-formed element set
267
		return ret;
268
	},
269

  
270
	// Execute a callback for every element in the matched set.
271
	// (You can seed the arguments with an array of args, but this is
272
	// only used internally.)
273
	each: function( callback, args ) {
274
		return jQuery.each( this, callback, args );
275
	},
276

  
277
	ready: function( fn ) {
278
		// Attach the listeners
279
		jQuery.bindReady();
280

  
281
		// Add the callback
282
		readyList.done( fn );
283

  
284
		return this;
285
	},
286

  
287
	eq: function( i ) {
288
		return i === -1 ?
289
			this.slice( i ) :
290
			this.slice( i, +i + 1 );
291
	},
292

  
293
	first: function() {
294
		return this.eq( 0 );
295
	},
296

  
297
	last: function() {
298
		return this.eq( -1 );
299
	},
300

  
301
	slice: function() {
302
		return this.pushStack( slice.apply( this, arguments ),
303
			"slice", slice.call(arguments).join(",") );
304
	},
305

  
306
	map: function( callback ) {
307
		return this.pushStack( jQuery.map(this, function( elem, i ) {
308
			return callback.call( elem, i, elem );
309
		}));
310
	},
311

  
312
	end: function() {
313
		return this.prevObject || this.constructor(null);
314
	},
315

  
316
	// For internal use only.
317
	// Behaves like an Array's method, not like a jQuery method.
318
	push: push,
319
	sort: [].sort,
320
	splice: [].splice
321
};
322

  
323
// Give the init function the jQuery prototype for later instantiation
324
jQuery.fn.init.prototype = jQuery.fn;
325

  
326
jQuery.extend = jQuery.fn.extend = function() {
327
	var options, name, src, copy, copyIsArray, clone,
328
		target = arguments[0] || {},
329
		i = 1,
330
		length = arguments.length,
331
		deep = false;
332

  
333
	// Handle a deep copy situation
334
	if ( typeof target === "boolean" ) {
335
		deep = target;
336
		target = arguments[1] || {};
337
		// skip the boolean and the target
338
		i = 2;
339
	}
340

  
341
	// Handle case when target is a string or something (possible in deep copy)
342
	if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
343
		target = {};
344
	}
345

  
346
	// extend jQuery itself if only one argument is passed
347
	if ( length === i ) {
348
		target = this;
349
		--i;
350
	}
351

  
352
	for ( ; i < length; i++ ) {
353
		// Only deal with non-null/undefined values
354
		if ( (options = arguments[ i ]) != null ) {
355
			// Extend the base object
356
			for ( name in options ) {
357
				src = target[ name ];
358
				copy = options[ name ];
359

  
360
				// Prevent never-ending loop
361
				if ( target === copy ) {
362
					continue;
363
				}
364

  
365
				// Recurse if we're merging plain objects or arrays
366
				if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
367
					if ( copyIsArray ) {
368
						copyIsArray = false;
369
						clone = src && jQuery.isArray(src) ? src : [];
370

  
371
					} else {
372
						clone = src && jQuery.isPlainObject(src) ? src : {};
373
					}
374

  
375
					// Never move original objects, clone them
376
					target[ name ] = jQuery.extend( deep, clone, copy );
377

  
378
				// Don't bring in undefined values
379
				} else if ( copy !== undefined ) {
380
					target[ name ] = copy;
381
				}
382
			}
383
		}
384
	}
385

  
386
	// Return the modified object
387
	return target;
388
};
389

  
390
jQuery.extend({
391
	noConflict: function( deep ) {
392
		if ( window.$ === jQuery ) {
393
			window.$ = _$;
394
		}
395

  
396
		if ( deep && window.jQuery === jQuery ) {
397
			window.jQuery = _jQuery;
398
		}
399

  
400
		return jQuery;
401
	},
402

  
403
	// Is the DOM ready to be used? Set to true once it occurs.
404
	isReady: false,
405

  
406
	// A counter to track how many items to wait for before
407
	// the ready event fires. See #6781
408
	readyWait: 1,
409

  
410
	// Hold (or release) the ready event
411
	holdReady: function( hold ) {
412
		if ( hold ) {
413
			jQuery.readyWait++;
414
		} else {
415
			jQuery.ready( true );
416
		}
417
	},
418

  
419
	// Handle when the DOM is ready
420
	ready: function( wait ) {
421
		// Either a released hold or an DOMready/load event and not yet ready
422
		if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) {
423
			// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
424
			if ( !document.body ) {
425
				return setTimeout( jQuery.ready, 1 );
426
			}
427

  
428
			// Remember that the DOM is ready
429
			jQuery.isReady = true;
430

  
431
			// If a normal DOM Ready event fired, decrement, and wait if need be
432
			if ( wait !== true && --jQuery.readyWait > 0 ) {
433
				return;
434
			}
435

  
436
			// If there are functions bound, to execute
437
			readyList.resolveWith( document, [ jQuery ] );
438

  
439
			// Trigger any bound ready events
440
			if ( jQuery.fn.trigger ) {
441
				jQuery( document ).trigger( "ready" ).unbind( "ready" );
442
			}
443
		}
444
	},
445

  
446
	bindReady: function() {
447
		if ( readyList ) {
448
			return;
449
		}
450

  
451
		readyList = jQuery._Deferred();
452

  
453
		// Catch cases where $(document).ready() is called after the
454
		// browser event has already occurred.
455
		if ( document.readyState === "complete" ) {
456
			// Handle it asynchronously to allow scripts the opportunity to delay ready
457
			return setTimeout( jQuery.ready, 1 );
458
		}
459

  
460
		// Mozilla, Opera and webkit nightlies currently support this event
461
		if ( document.addEventListener ) {
462
			// Use the handy event callback
463
			document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
464

  
465
			// A fallback to window.onload, that will always work
466
			window.addEventListener( "load", jQuery.ready, false );
467

  
468
		// If IE event model is used
469
		} else if ( document.attachEvent ) {
470
			// ensure firing before onload,
471
			// maybe late but safe also for iframes
472
			document.attachEvent( "onreadystatechange", DOMContentLoaded );
473

  
474
			// A fallback to window.onload, that will always work
475
			window.attachEvent( "onload", jQuery.ready );
476

  
477
			// If IE and not a frame
478
			// continually check to see if the document is ready
479
			var toplevel = false;
480

  
481
			try {
482
				toplevel = window.frameElement == null;
483
			} catch(e) {}
484

  
485
			if ( document.documentElement.doScroll && toplevel ) {
486
				doScrollCheck();
487
			}
488
		}
489
	},
490

  
491
	// See test/unit/core.js for details concerning isFunction.
492
	// Since version 1.3, DOM methods and functions like alert
493
	// aren't supported. They return false on IE (#2968).
494
	isFunction: function( obj ) {
495
		return jQuery.type(obj) === "function";
496
	},
497

  
498
	isArray: Array.isArray || function( obj ) {
499
		return jQuery.type(obj) === "array";
500
	},
501

  
502
	// A crude way of determining if an object is a window
503
	isWindow: function( obj ) {
504
		return obj && typeof obj === "object" && "setInterval" in obj;
505
	},
506

  
507
	isNaN: function( obj ) {
508
		return obj == null || !rdigit.test( obj ) || isNaN( obj );
509
	},
510

  
511
	type: function( obj ) {
512
		return obj == null ?
513
			String( obj ) :
514
			class2type[ toString.call(obj) ] || "object";
515
	},
516

  
517
	isPlainObject: function( obj ) {
518
		// Must be an Object.
519
		// Because of IE, we also have to check the presence of the constructor property.
520
		// Make sure that DOM nodes and window objects don't pass through, as well
521
		if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
522
			return false;
523
		}
524

  
525
		try {
526
			// Not own constructor property must be Object
527
			if ( obj.constructor &&
528
				!hasOwn.call(obj, "constructor") &&
529
				!hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
530
				return false;
531
			}
532
		} catch ( e ) {
533
			// IE8,9 Will throw exceptions on certain host objects #9897
534
			return false;
535
		}
536

  
537
		// Own properties are enumerated firstly, so to speed up,
538
		// if last one is own, then all properties are own.
539

  
540
		var key;
541
		for ( key in obj ) {}
542

  
543
		return key === undefined || hasOwn.call( obj, key );
544
	},
545

  
546
	isEmptyObject: function( obj ) {
547
		for ( var name in obj ) {
548
			return false;
549
		}
550
		return true;
551
	},
552

  
553
	error: function( msg ) {
554
		throw msg;
555
	},
556

  
557
	parseJSON: function( data ) {
558
		if ( typeof data !== "string" || !data ) {
559
			return null;
560
		}
561

  
562
		// Make sure leading/trailing whitespace is removed (IE can't handle it)
563
		data = jQuery.trim( data );
564

  
565
		// Attempt to parse using the native JSON parser first
566
		if ( window.JSON && window.JSON.parse ) {
567
			return window.JSON.parse( data );
568
		}
569

  
570
		// Make sure the incoming data is actual JSON
571
		// Logic borrowed from http://json.org/json2.js
572
		if ( rvalidchars.test( data.replace( rvalidescape, "@" )
573
			.replace( rvalidtokens, "]" )
574
			.replace( rvalidbraces, "")) ) {
575

  
576
			return (new Function( "return " + data ))();
577

  
578
		}
579
		jQuery.error( "Invalid JSON: " + data );
580
	},
581

  
582
	// Cross-browser xml parsing
583
	parseXML: function( data ) {
584
		var xml, tmp;
585
		try {
586
			if ( window.DOMParser ) { // Standard
587
				tmp = new DOMParser();
588
				xml = tmp.parseFromString( data , "text/xml" );
589
			} else { // IE
590
				xml = new ActiveXObject( "Microsoft.XMLDOM" );
591
				xml.async = "false";
592
				xml.loadXML( data );
593
			}
594
		} catch( e ) {
595
			xml = undefined;
596
		}
597
		if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) {
598
			jQuery.error( "Invalid XML: " + data );
599
		}
600
		return xml;
601
	},
602

  
603
	noop: function() {},
604

  
605
	// Evaluates a script in a global context
606
	// Workarounds based on findings by Jim Driscoll
607
	// http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
608
	globalEval: function( data ) {
609
		if ( data && rnotwhite.test( data ) ) {
610
			// We use execScript on Internet Explorer
611
			// We use an anonymous function so that context is window
612
			// rather than jQuery in Firefox
613
			( window.execScript || function( data ) {
614
				window[ "eval" ].call( window, data );
615
			} )( data );
616
		}
617
	},
618

  
619
	// Convert dashed to camelCase; used by the css and data modules
620
	// Microsoft forgot to hump their vendor prefix (#9572)
621
	camelCase: function( string ) {
622
		return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
623
	},
624

  
625
	nodeName: function( elem, name ) {
626
		return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
627
	},
628

  
629
	// args is for internal usage only
630
	each: function( object, callback, args ) {
631
		var name, i = 0,
632
			length = object.length,
633
			isObj = length === undefined || jQuery.isFunction( object );
634

  
635
		if ( args ) {
636
			if ( isObj ) {
637
				for ( name in object ) {
638
					if ( callback.apply( object[ name ], args ) === false ) {
639
						break;
640
					}
641
				}
642
			} else {
643
				for ( ; i < length; ) {
644
					if ( callback.apply( object[ i++ ], args ) === false ) {
645
						break;
646
					}
647
				}
648
			}
649

  
650
		// A special, fast, case for the most common use of each
651
		} else {
652
			if ( isObj ) {
653
				for ( name in object ) {
654
					if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
655
						break;
656
					}
657
				}
658
			} else {
659
				for ( ; i < length; ) {
660
					if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) {
661
						break;
662
					}
663
				}
664
			}
665
		}
666

  
667
		return object;
668
	},
669

  
670
	// Use native String.trim function wherever possible
671
	trim: trim ?
672
		function( text ) {
673
			return text == null ?
674
				"" :
675
				trim.call( text );
676
		} :
677

  
678
		// Otherwise use our own trimming functionality
679
		function( text ) {
680
			return text == null ?
681
				"" :
682
				text.toString().replace( trimLeft, "" ).replace( trimRight, "" );
683
		},
684

  
685
	// results is for internal usage only
686
	makeArray: function( array, results ) {
687
		var ret = results || [];
688

  
689
		if ( array != null ) {
690
			// The window, strings (and functions) also have 'length'
691
			// The extra typeof function check is to prevent crashes
692
			// in Safari 2 (See: #3039)
693
			// Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930
694
			var type = jQuery.type( array );
695

  
696
			if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) {
697
				push.call( ret, array );
698
			} else {
699
				jQuery.merge( ret, array );
700
			}
701
		}
702

  
703
		return ret;
704
	},
705

  
706
	inArray: function( elem, array ) {
707
		if ( !array ) {
708
			return -1;
709
		}
710

  
711
		if ( indexOf ) {
712
			return indexOf.call( array, elem );
713
		}
714

  
715
		for ( var i = 0, length = array.length; i < length; i++ ) {
716
			if ( array[ i ] === elem ) {
717
				return i;
718
			}
719
		}
720

  
721
		return -1;
722
	},
723

  
724
	merge: function( first, second ) {
725
		var i = first.length,
726
			j = 0;
727

  
728
		if ( typeof second.length === "number" ) {
729
			for ( var l = second.length; j < l; j++ ) {
730
				first[ i++ ] = second[ j ];
731
			}
732

  
733
		} else {
734
			while ( second[j] !== undefined ) {
735
				first[ i++ ] = second[ j++ ];
736
			}
737
		}
738

  
739
		first.length = i;
740

  
741
		return first;
742
	},
743

  
744
	grep: function( elems, callback, inv ) {
745
		var ret = [], retVal;
746
		inv = !!inv;
747

  
748
		// Go through the array, only saving the items
749
		// that pass the validator function
750
		for ( var i = 0, length = elems.length; i < length; i++ ) {
751
			retVal = !!callback( elems[ i ], i );
752
			if ( inv !== retVal ) {
753
				ret.push( elems[ i ] );
754
			}
755
		}
756

  
757
		return ret;
758
	},
759

  
760
	// arg is for internal usage only
761
	map: function( elems, callback, arg ) {
762
		var value, key, ret = [],
763
			i = 0,
764
			length = elems.length,
765
			// jquery objects are treated as arrays
766
			isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ;
767

  
768
		// Go through the array, translating each of the items to their
769
		if ( isArray ) {
770
			for ( ; i < length; i++ ) {
771
				value = callback( elems[ i ], i, arg );
772

  
773
				if ( value != null ) {
774
					ret[ ret.length ] = value;
775
				}
776
			}
777

  
778
		// Go through every key on the object,
779
		} else {
780
			for ( key in elems ) {
781
				value = callback( elems[ key ], key, arg );
782

  
783
				if ( value != null ) {
784
					ret[ ret.length ] = value;
785
				}
786
			}
787
		}
788

  
789
		// Flatten any nested arrays
790
		return ret.concat.apply( [], ret );
791
	},
792

  
793
	// A global GUID counter for objects
794
	guid: 1,
795

  
796
	// Bind a function to a context, optionally partially applying any
797
	// arguments.
798
	proxy: function( fn, context ) {
799
		if ( typeof context === "string" ) {
800
			var tmp = fn[ context ];
801
			context = fn;
802
			fn = tmp;
803
		}
804

  
805
		// Quick check to determine if target is callable, in the spec
806
		// this throws a TypeError, but we will just return undefined.
807
		if ( !jQuery.isFunction( fn ) ) {
808
			return undefined;
809
		}
810

  
811
		// Simulated bind
812
		var args = slice.call( arguments, 2 ),
813
			proxy = function() {
814
				return fn.apply( context, args.concat( slice.call( arguments ) ) );
815
			};
816

  
817
		// Set the guid of unique handler to the same of original handler, so it can be removed
818
		proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
819

  
820
		return proxy;
821
	},
822

  
823
	// Mutifunctional method to get and set values to a collection
824
	// The value/s can optionally be executed if it's a function
825
	access: function( elems, key, value, exec, fn, pass ) {
826
		var length = elems.length;
827

  
828
		// Setting many attributes
829
		if ( typeof key === "object" ) {
830
			for ( var k in key ) {
831
				jQuery.access( elems, k, key[k], exec, fn, value );
832
			}
833
			return elems;
834
		}
835

  
836
		// Setting one attribute
837
		if ( value !== undefined ) {
838
			// Optionally, function values get executed if exec is true
839
			exec = !pass && exec && jQuery.isFunction(value);
840

  
841
			for ( var i = 0; i < length; i++ ) {
842
				fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
843
			}
844

  
845
			return elems;
846
		}
847

  
848
		// Getting an attribute
849
		return length ? fn( elems[0], key ) : undefined;
850
	},
851

  
852
	now: function() {
853
		return (new Date()).getTime();
854
	},
855

  
856
	// Use of jQuery.browser is frowned upon.
857
	// More details: http://docs.jquery.com/Utilities/jQuery.browser
858
	uaMatch: function( ua ) {
859
		ua = ua.toLowerCase();
860

  
861
		var match = rwebkit.exec( ua ) ||
862
			ropera.exec( ua ) ||
863
			rmsie.exec( ua ) ||
864
			ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) ||
865
			[];
866

  
867
		return { browser: match[1] || "", version: match[2] || "0" };
868
	},
869

  
870
	sub: function() {
871
		function jQuerySub( selector, context ) {
872
			return new jQuerySub.fn.init( selector, context );
873
		}
874
		jQuery.extend( true, jQuerySub, this );
875
		jQuerySub.superclass = this;
876
		jQuerySub.fn = jQuerySub.prototype = this();
877
		jQuerySub.fn.constructor = jQuerySub;
878
		jQuerySub.sub = this.sub;
879
		jQuerySub.fn.init = function init( selector, context ) {
880
			if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) {
881
				context = jQuerySub( context );
882
			}
883

  
884
			return jQuery.fn.init.call( this, selector, context, rootjQuerySub );
885
		};
886
		jQuerySub.fn.init.prototype = jQuerySub.fn;
887
		var rootjQuerySub = jQuerySub(document);
888
		return jQuerySub;
889
	},
890

  
891
	browser: {}
892
});
893

  
894
// Populate the class2type map
895
jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) {
896
	class2type[ "[object " + name + "]" ] = name.toLowerCase();
897
});
898

  
899
browserMatch = jQuery.uaMatch( userAgent );
900
if ( browserMatch.browser ) {
901
	jQuery.browser[ browserMatch.browser ] = true;
902
	jQuery.browser.version = browserMatch.version;
903
}
904

  
905
// Deprecated, use jQuery.browser.webkit instead
906
if ( jQuery.browser.webkit ) {
907
	jQuery.browser.safari = true;
908
}
909

  
910
// IE doesn't match non-breaking spaces with \s
911
if ( rnotwhite.test( "\xA0" ) ) {
912
	trimLeft = /^[\s\xA0]+/;
913
	trimRight = /[\s\xA0]+$/;
914
}
915

  
916
// All jQuery objects should point back to these
917
rootjQuery = jQuery(document);
918

  
919
// Cleanup functions for the document ready method
920
if ( document.addEventListener ) {
921
	DOMContentLoaded = function() {
922
		document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
923
		jQuery.ready();
924
	};
925

  
926
} else if ( document.attachEvent ) {
927
	DOMContentLoaded = function() {
928
		// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
929
		if ( document.readyState === "complete" ) {
930
			document.detachEvent( "onreadystatechange", DOMContentLoaded );
931
			jQuery.ready();
932
		}
933
	};
934
}
935

  
936
// The DOM ready check for Internet Explorer
937
function doScrollCheck() {
938
	if ( jQuery.isReady ) {
939
		return;
940
	}
941

  
942
	try {
943
		// If IE is used, use the trick by Diego Perini
944
		// http://javascript.nwbox.com/IEContentLoaded/
945
		document.documentElement.doScroll("left");
946
	} catch(e) {
947
		setTimeout( doScrollCheck, 1 );
948
		return;
949
	}
950

  
951
	// and execute any waiting functions
952
	jQuery.ready();
953
}
954

  
955
return jQuery;
956

  
957
})();
958

  
959

  
960
var // Promise methods
961
	promiseMethods = "done fail isResolved isRejected promise then always pipe".split( " " ),
962
	// Static reference to slice
963
	sliceDeferred = [].slice;
964

  
965
jQuery.extend({
966
	// Create a simple deferred (one callbacks list)
967
	_Deferred: function() {
968
		var // callbacks list
969
			callbacks = [],
970
			// stored [ context , args ]
971
			fired,
972
			// to avoid firing when already doing so
973
			firing,
974
			// flag to know if the deferred has been cancelled
975
			cancelled,
976
			// the deferred itself
977
			deferred  = {
978

  
979
				// done( f1, f2, ...)
980
				done: function() {
981
					if ( !cancelled ) {
982
						var args = arguments,
983
							i,
984
							length,
985
							elem,
986
							type,
987
							_fired;
988
						if ( fired ) {
989
							_fired = fired;
990
							fired = 0;
991
						}
992
						for ( i = 0, length = args.length; i < length; i++ ) {
993
							elem = args[ i ];
994
							type = jQuery.type( elem );
995
							if ( type === "array" ) {
996
								deferred.done.apply( deferred, elem );
997
							} else if ( type === "function" ) {
998
								callbacks.push( elem );
999
							}
1000
						}
1001
						if ( _fired ) {
1002
							deferred.resolveWith( _fired[ 0 ], _fired[ 1 ] );
1003
						}
1004
					}
1005
					return this;
1006
				},
1007

  
1008
				// resolve with given context and args
1009
				resolveWith: function( context, args ) {
1010
					if ( !cancelled && !fired && !firing ) {
1011
						// make sure args are available (#8421)
1012
						args = args || [];
1013
						firing = 1;
1014
						try {
1015
							while( callbacks[ 0 ] ) {
1016
								callbacks.shift().apply( context, args );
1017
							}
1018
						}
1019
						finally {
1020
							fired = [ context, args ];
1021
							firing = 0;
1022
						}
1023
					}
1024
					return this;
1025
				},
1026

  
1027
				// resolve with this as context and given arguments
1028
				resolve: function() {
1029
					deferred.resolveWith( this, arguments );
1030
					return this;
1031
				},
1032

  
1033
				// Has this deferred been resolved?
1034
				isResolved: function() {
1035
					return !!( firing || fired );
1036
				},
1037

  
1038
				// Cancel
1039
				cancel: function() {
1040
					cancelled = 1;
1041
					callbacks = [];
1042
					return this;
1043
				}
1044
			};
1045

  
1046
		return deferred;
1047
	},
1048

  
1049
	// Full fledged deferred (two callbacks list)
1050
	Deferred: function( func ) {
1051
		var deferred = jQuery._Deferred(),
1052
			failDeferred = jQuery._Deferred(),
1053
			promise;
1054
		// Add errorDeferred methods, then and promise
1055
		jQuery.extend( deferred, {
1056
			then: function( doneCallbacks, failCallbacks ) {
1057
				deferred.done( doneCallbacks ).fail( failCallbacks );
1058
				return this;
1059
			},
1060
			always: function() {
1061
				return deferred.done.apply( deferred, arguments ).fail.apply( this, arguments );
1062
			},
1063
			fail: failDeferred.done,
1064
			rejectWith: failDeferred.resolveWith,
1065
			reject: failDeferred.resolve,
1066
			isRejected: failDeferred.isResolved,
1067
			pipe: function( fnDone, fnFail ) {
1068
				return jQuery.Deferred(function( newDefer ) {
1069
					jQuery.each( {
1070
						done: [ fnDone, "resolve" ],
1071
						fail: [ fnFail, "reject" ]
1072
					}, function( handler, data ) {
1073
						var fn = data[ 0 ],
1074
							action = data[ 1 ],
1075
							returned;
1076
						if ( jQuery.isFunction( fn ) ) {
1077
							deferred[ handler ](function() {
1078
								returned = fn.apply( this, arguments );
1079
								if ( returned && jQuery.isFunction( returned.promise ) ) {
1080
									returned.promise().then( newDefer.resolve, newDefer.reject );
1081
								} else {
1082
									newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] );
1083
								}
1084
							});
1085
						} else {
1086
							deferred[ handler ]( newDefer[ action ] );
1087
						}
1088
					});
1089
				}).promise();
1090
			},
1091
			// Get a promise for this deferred
1092
			// If obj is provided, the promise aspect is added to the object
1093
			promise: function( obj ) {
1094
				if ( obj == null ) {
1095
					if ( promise ) {
1096
						return promise;
1097
					}
1098
					promise = obj = {};
1099
				}
1100
				var i = promiseMethods.length;
1101
				while( i-- ) {
1102
					obj[ promiseMethods[i] ] = deferred[ promiseMethods[i] ];
1103
				}
1104
				return obj;
1105
			}
1106
		});
1107
		// Make sure only one callback list will be used
1108
		deferred.done( failDeferred.cancel ).fail( deferred.cancel );
1109
		// Unexpose cancel
1110
		delete deferred.cancel;
1111
		// Call given func if any
1112
		if ( func ) {
1113
			func.call( deferred, deferred );
1114
		}
1115
		return deferred;
1116
	},
1117

  
1118
	// Deferred helper
1119
	when: function( firstParam ) {
1120
		var args = arguments,
1121
			i = 0,
1122
			length = args.length,
1123
			count = length,
1124
			deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ?
1125
				firstParam :
1126
				jQuery.Deferred();
1127
		function resolveFunc( i ) {
1128
			return function( value ) {
1129
				args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value;
1130
				if ( !( --count ) ) {
1131
					// Strange bug in FF4:
1132
					// Values changed onto the arguments object sometimes end up as undefined values
1133
					// outside the $.when method. Cloning the object into a fresh array solves the issue
1134
					deferred.resolveWith( deferred, sliceDeferred.call( args, 0 ) );
1135
				}
1136
			};
1137
		}
1138
		if ( length > 1 ) {
1139
			for( ; i < length; i++ ) {
1140
				if ( args[ i ] && jQuery.isFunction( args[ i ].promise ) ) {
1141
					args[ i ].promise().then( resolveFunc(i), deferred.reject );
1142
				} else {
1143
					--count;
1144
				}
1145
			}
1146
			if ( !count ) {
1147
				deferred.resolveWith( deferred, args );
1148
			}
1149
		} else if ( deferred !== firstParam ) {
1150
			deferred.resolveWith( deferred, length ? [ firstParam ] : [] );
1151
		}
1152
		return deferred.promise();
1153
	}
1154
});
1155

  
1156

  
1157

  
1158
jQuery.support = (function() {
1159

  
1160
	var div = document.createElement( "div" ),
1161
		documentElement = document.documentElement,
1162
		all,
1163
		a,
1164
		select,
1165
		opt,
1166
		input,
1167
		marginDiv,
1168
		support,
1169
		fragment,
1170
		body,
1171
		testElementParent,
1172
		testElement,
1173
		testElementStyle,
1174
		tds,
1175
		events,
1176
		eventName,
1177
		i,
1178
		isSupported;
1179

  
1180
	// Preliminary tests
1181
	div.setAttribute("className", "t");
1182
	div.innerHTML = "   <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
1183

  
1184

  
1185
	all = div.getElementsByTagName( "*" );
1186
	a = div.getElementsByTagName( "a" )[ 0 ];
1187

  
1188
	// Can't get basic test support
1189
	if ( !all || !all.length || !a ) {
1190
		return {};
1191
	}
1192

  
1193
	// First batch of supports tests
1194
	select = document.createElement( "select" );
1195
	opt = select.appendChild( document.createElement("option") );
1196
	input = div.getElementsByTagName( "input" )[ 0 ];
1197

  
1198
	support = {
1199
		// IE strips leading whitespace when .innerHTML is used
1200
		leadingWhitespace: ( div.firstChild.nodeType === 3 ),
1201

  
1202
		// Make sure that tbody elements aren't automatically inserted
1203
		// IE will insert them into empty tables
1204
		tbody: !div.getElementsByTagName( "tbody" ).length,
1205

  
1206
		// Make sure that link elements get serialized correctly by innerHTML
1207
		// This requires a wrapper element in IE
1208
		htmlSerialize: !!div.getElementsByTagName( "link" ).length,
1209

  
1210
		// Get the style information from getAttribute
1211
		// (IE uses .cssText instead)
1212
		style: /top/.test( a.getAttribute("style") ),
1213

  
1214
		// Make sure that URLs aren't manipulated
1215
		// (IE normalizes it by default)
1216
		hrefNormalized: ( a.getAttribute( "href" ) === "/a" ),
1217

  
1218
		// Make sure that element opacity exists
1219
		// (IE uses filter instead)
1220
		// Use a regex to work around a WebKit issue. See #5145
1221
		opacity: /^0.55$/.test( a.style.opacity ),
1222

  
1223
		// Verify style float existence
1224
		// (IE uses styleFloat instead of cssFloat)
1225
		cssFloat: !!a.style.cssFloat,
1226

  
1227
		// Make sure that if no value is specified for a checkbox
1228
		// that it defaults to "on".
1229
		// (WebKit defaults to "" instead)
1230
		checkOn: ( input.value === "on" ),
1231

  
1232
		// Make sure that a selected-by-default option has a working selected property.
1233
		// (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
1234
		optSelected: opt.selected,
1235

  
1236
		// Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)
1237
		getSetAttribute: div.className !== "t",
1238

  
1239
		// Will be defined later
1240
		submitBubbles: true,
1241
		changeBubbles: true,
1242
		focusinBubbles: false,
1243
		deleteExpando: true,
1244
		noCloneEvent: true,
1245
		inlineBlockNeedsLayout: false,
1246
		shrinkWrapBlocks: false,
1247
		reliableMarginRight: true
1248
	};
1249

  
1250
	// Make sure checked status is properly cloned
1251
	input.checked = true;
1252
	support.noCloneChecked = input.cloneNode( true ).checked;
1253

  
1254
	// Make sure that the options inside disabled selects aren't marked as disabled
1255
	// (WebKit marks them as disabled)
1256
	select.disabled = true;
1257
	support.optDisabled = !opt.disabled;
1258

  
1259
	// Test to see if it's possible to delete an expando from an element
1260
	// Fails in Internet Explorer
1261
	try {
1262
		delete div.test;
1263
	} catch( e ) {
1264
		support.deleteExpando = false;
1265
	}
1266

  
1267
	if ( !div.addEventListener && div.attachEvent && div.fireEvent ) {
1268
		div.attachEvent( "onclick", function() {
1269
			// Cloning a node shouldn't copy over any
1270
			// bound event handlers (IE does this)
1271
			support.noCloneEvent = false;
1272
		});
1273
		div.cloneNode( true ).fireEvent( "onclick" );
1274
	}
1275

  
1276
	// Check if a radio maintains it's value
1277
	// after being appended to the DOM
1278
	input = document.createElement("input");
1279
	input.value = "t";
1280
	input.setAttribute("type", "radio");
1281
	support.radioValue = input.value === "t";
1282

  
1283
	input.setAttribute("checked", "checked");
1284
	div.appendChild( input );
1285
	fragment = document.createDocumentFragment();
1286
	fragment.appendChild( div.firstChild );
1287

  
1288
	// WebKit doesn't clone checked state correctly in fragments
1289
	support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;
1290

  
1291
	div.innerHTML = "";
1292

  
1293
	// Figure out if the W3C box model works as expected
1294
	div.style.width = div.style.paddingLeft = "1px";
1295

  
1296
	body = document.getElementsByTagName( "body" )[ 0 ];
1297
	// We use our own, invisible, body unless the body is already present
1298
	// in which case we use a div (#9239)
1299
	testElement = document.createElement( body ? "div" : "body" );
1300
	testElementStyle = {
1301
		visibility: "hidden",
1302
		width: 0,
1303
		height: 0,
1304
		border: 0,
1305
		margin: 0,
1306
		background: "none"
1307
	};
1308
	if ( body ) {
1309
		jQuery.extend( testElementStyle, {
1310
			position: "absolute",
1311
			left: "-1000px",
1312
			top: "-1000px"
1313
		});
1314
	}
1315
	for ( i in testElementStyle ) {
1316
		testElement.style[ i ] = testElementStyle[ i ];
1317
	}
1318
	testElement.appendChild( div );
1319
	testElementParent = body || documentElement;
1320
	testElementParent.insertBefore( testElement, testElementParent.firstChild );
1321

  
1322
	// Check if a disconnected checkbox will retain its checked
1323
	// value of true after appended to the DOM (IE6/7)
1324
	support.appendChecked = input.checked;
1325

  
1326
	support.boxModel = div.offsetWidth === 2;
1327

  
1328
	if ( "zoom" in div.style ) {
1329
		// Check if natively block-level elements act like inline-block
1330
		// elements when setting their display to 'inline' and giving
1331
		// them layout
1332
		// (IE < 8 does this)
1333
		div.style.display = "inline";
1334
		div.style.zoom = 1;
1335
		support.inlineBlockNeedsLayout = ( div.offsetWidth === 2 );
1336

  
1337
		// Check if elements with layout shrink-wrap their children
1338
		// (IE 6 does this)
1339
		div.style.display = "";
1340
		div.innerHTML = "<div style='width:4px;'></div>";
1341
		support.shrinkWrapBlocks = ( div.offsetWidth !== 2 );
1342
	}
1343

  
1344
	div.innerHTML = "<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>";
1345
	tds = div.getElementsByTagName( "td" );
1346

  
1347
	// Check if table cells still have offsetWidth/Height when they are set
1348
	// to display:none and there are still other visible table cells in a
1349
	// table row; if so, offsetWidth/Height are not reliable for use when
1350
	// determining if an element has been hidden directly using
1351
	// display:none (it is still safe to use offsets if a parent element is
1352
	// hidden; don safety goggles and see bug #4512 for more information).
1353
	// (only IE 8 fails this test)
1354
	isSupported = ( tds[ 0 ].offsetHeight === 0 );
1355

  
1356
	tds[ 0 ].style.display = "";
1357
	tds[ 1 ].style.display = "none";
1358

  
1359
	// Check if empty table cells still have offsetWidth/Height
1360
	// (IE < 8 fail this test)
1361
	support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );
1362
	div.innerHTML = "";
1363

  
1364
	// Check if div with explicit width and no margin-right incorrectly
1365
	// gets computed margin-right based on width of container. For more
1366
	// info see bug #3333
1367
	// Fails in WebKit before Feb 2011 nightlies
1368
	// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
1369
	if ( document.defaultView && document.defaultView.getComputedStyle ) {
1370
		marginDiv = document.createElement( "div" );
1371
		marginDiv.style.width = "0";
1372
		marginDiv.style.marginRight = "0";
1373
		div.appendChild( marginDiv );
1374
		support.reliableMarginRight =
1375
			( parseInt( ( document.defaultView.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0;
1376
	}
1377

  
1378
	// Remove the body element we added
1379
	testElement.innerHTML = "";
1380
	testElementParent.removeChild( testElement );
1381

  
1382
	// Technique from Juriy Zaytsev
1383
	// http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
1384
	// We only care about the case where non-standard event systems
1385
	// are used, namely in IE. Short-circuiting here helps us to
1386
	// avoid an eval call (in setAttribute) which can cause CSP
1387
	// to go haywire. See: https://developer.mozilla.org/en/Security/CSP
1388
	if ( div.attachEvent ) {
1389
		for( i in {
1390
			submit: 1,
1391
			change: 1,
1392
			focusin: 1
1393
		} ) {
1394
			eventName = "on" + i;
1395
			isSupported = ( eventName in div );
1396
			if ( !isSupported ) {
1397
				div.setAttribute( eventName, "return;" );
1398
				isSupported = ( typeof div[ eventName ] === "function" );
1399
			}
1400
			support[ i + "Bubbles" ] = isSupported;
1401
		}
1402
	}
1403

  
1404
	// Null connected elements to avoid leaks in IE
1405
	testElement = fragment = select = opt = body = marginDiv = div = input = null;
1406

  
1407
	return support;
1408
})();
1409

  
1410
// Keep track of boxModel
1411
jQuery.boxModel = jQuery.support.boxModel;
1412

  
1413

  
1414

  
1415

  
1416
var rbrace = /^(?:\{.*\}|\[.*\])$/,
1417
	rmultiDash = /([A-Z])/g;
1418

  
1419
jQuery.extend({
1420
	cache: {},
1421

  
1422
	// Please use with caution
1423
	uuid: 0,
1424

  
1425
	// Unique for each copy of jQuery on the page
1426
	// Non-digits removed to match rinlinejQuery
1427
	expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ),
1428

  
1429
	// The following elements throw uncatchable exceptions if you
1430
	// attempt to add expando properties to them.
1431
	noData: {
1432
		"embed": true,
1433
		// Ban all objects except for Flash (which handle expandos)
1434
		"object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",
1435
		"applet": true
1436
	},
1437

  
1438
	hasData: function( elem ) {
1439
		elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];
1440

  
1441
		return !!elem && !isEmptyDataObject( elem );
1442
	},
1443

  
1444
	data: function( elem, name, data, pvt /* Internal Use Only */ ) {
1445
		if ( !jQuery.acceptData( elem ) ) {
1446
			return;
1447
		}
1448

  
1449
		var thisCache, ret,
1450
			internalKey = jQuery.expando,
1451
			getByName = typeof name === "string",
1452

  
1453
			// We have to handle DOM nodes and JS objects differently because IE6-7
1454
			// can't GC object references properly across the DOM-JS boundary
1455
			isNode = elem.nodeType,
1456

  
1457
			// Only DOM nodes need the global jQuery cache; JS object data is
1458
			// attached directly to the object so GC can occur automatically
1459
			cache = isNode ? jQuery.cache : elem,
1460

  
1461
			// Only defining an ID for JS objects if its cache already exists allows
1462
			// the code to shortcut on the same path as a DOM node with no cache
1463
			id = isNode ? elem[ jQuery.expando ] : elem[ jQuery.expando ] && jQuery.expando;
1464

  
1465
		// Avoid doing any more work than we need to when trying to get data on an
1466
		// object that has no data at all
1467
		if ( (!id || (pvt && id && (cache[ id ] && !cache[ id ][ internalKey ]))) && getByName && data === undefined ) {
1468
			return;
1469
		}
1470

  
1471
		if ( !id ) {
1472
			// Only DOM nodes need a new unique ID for each element since their data
1473
			// ends up in the global cache
1474
			if ( isNode ) {
1475
				elem[ jQuery.expando ] = id = ++jQuery.uuid;
1476
			} else {
1477
				id = jQuery.expando;
1478
			}
1479
		}
1480

  
1481
		if ( !cache[ id ] ) {
1482
			cache[ id ] = {};
1483

  
1484
			// TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery
1485
			// metadata on plain JS objects when the object is serialized using
1486
			// JSON.stringify
1487
			if ( !isNode ) {
1488
				cache[ id ].toJSON = jQuery.noop;
1489
			}
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff