Changeset - 71aa61315a9c
[Not reviewed]
0 0 1
Joar Wandborg - 8 years ago 2013-10-23 18:24:22
joar@wandborg.se
Added the jQuery js file
1 file changed with 9789 insertions and 0 deletions:
0 comments (0 inline, 0 general)
jquery-1.10.2.js
Show inline comments
 
new file 100644
 
/*!
 
 * jQuery JavaScript Library v1.10.2
 
 * http://jquery.com/
 
 *
 
 * Includes Sizzle.js
 
 * http://sizzlejs.com/
 
 *
 
 * Copyright 2005, 2013 jQuery Foundation, Inc. and other contributors
 
 * Released under the MIT license
 
 * http://jquery.org/license
 
 *
 
 * Date: 2013-07-03T13:48Z
 
 */
 
(function( window, undefined ) {
 

	
 
// Can't do this because several apps including ASP.NET trace
 
// the stack via arguments.caller.callee and Firefox dies if
 
// you try to trace through "use strict" call chains. (#13335)
 
// Support: Firefox 18+
 
//"use strict";
 
var
 
	// The deferred used on DOM ready
 
	readyList,
 

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

	
 
	// Support: IE<10
 
	// For `typeof xmlNode.method` instead of `xmlNode.method !== undefined`
 
	core_strundefined = typeof undefined,
 

	
 
	// Use the correct document accordingly with window argument (sandbox)
 
	location = window.location,
 
	document = window.document,
 
	docElem = document.documentElement,
 

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

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

	
 
	// [[Class]] -> type pairs
 
	class2type = {},
 

	
 
	// List of deleted data cache ids, so we can reuse them
 
	core_deletedIds = [],
 

	
 
	core_version = "1.10.2",
 

	
 
	// Save a reference to some core methods
 
	core_concat = core_deletedIds.concat,
 
	core_push = core_deletedIds.push,
 
	core_slice = core_deletedIds.slice,
 
	core_indexOf = core_deletedIds.indexOf,
 
	core_toString = class2type.toString,
 
	core_hasOwn = class2type.hasOwnProperty,
 
	core_trim = core_version.trim,
 

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

	
 
	// Used for matching numbers
 
	core_pnum = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,
 

	
 
	// Used for splitting on whitespace
 
	core_rnotwhite = /\S+/g,
 

	
 
	// Make sure we trim BOM and NBSP (here's looking at you, Safari 5.0 and IE)
 
	rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
 

	
 
	// A simple way to check for HTML strings
 
	// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
 
	// Strict HTML recognition (#11290: must start with <)
 
	rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
 

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

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

	
 
	// Matches dashed string for camelizing
 
	rmsPrefix = /^-ms-/,
 
	rdashAlpha = /-([\da-z])/gi,
 

	
 
	// Used by jQuery.camelCase as callback to replace()
 
	fcamelCase = function( all, letter ) {
 
		return letter.toUpperCase();
 
	},
 

	
 
	// The ready event handler
 
	completed = function( event ) {
 

	
 
		// readyState === "complete" is good enough for us to call the dom ready in oldIE
 
		if ( document.addEventListener || event.type === "load" || document.readyState === "complete" ) {
 
			detach();
 
			jQuery.ready();
 
		}
 
	},
 
	// Clean-up method for dom ready events
 
	detach = function() {
 
		if ( document.addEventListener ) {
 
			document.removeEventListener( "DOMContentLoaded", completed, false );
 
			window.removeEventListener( "load", completed, false );
 

	
 
		} else {
 
			document.detachEvent( "onreadystatechange", completed );
 
			window.detachEvent( "onload", completed );
 
		}
 
	};
 

	
 
jQuery.fn = jQuery.prototype = {
 
	// The current version of jQuery being used
 
	jquery: core_version,
 

	
 
	constructor: jQuery,
 
	init: function( selector, context, rootjQuery ) {
 
		var match, elem;
 

	
 
		// HANDLE: $(""), $(null), $(undefined), $(false)
 
		if ( !selector ) {
 
			return this;
 
		}
 

	
 
		// Handle HTML strings
 
		if ( typeof selector === "string" ) {
 
			if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
 
				// Assume that strings that start and end with <> are HTML and skip the regex check
 
				match = [ null, selector, null ];
 

	
 
			} else {
 
				match = rquickExpr.exec( selector );
 
			}
 

	
 
			// Match html or make sure no context is specified for #id
 
			if ( match && (match[1] || !context) ) {
 

	
 
				// HANDLE: $(html) -> $(array)
 
				if ( match[1] ) {
 
					context = context instanceof jQuery ? context[0] : context;
 

	
 
					// scripts is true for back-compat
 
					jQuery.merge( this, jQuery.parseHTML(
 
						match[1],
 
						context && context.nodeType ? context.ownerDocument || context : document,
 
						true
 
					) );
 

	
 
					// HANDLE: $(html, props)
 
					if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {
 
						for ( match in context ) {
 
							// Properties of context are called as methods if possible
 
							if ( jQuery.isFunction( this[ match ] ) ) {
 
								this[ match ]( context[ match ] );
 

	
 
							// ...and otherwise set as attributes
 
							} else {
 
								this.attr( match, context[ match ] );
 
							}
 
						}
 
					}
 

	
 
					return this;
 

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

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

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

	
 
					this.context = document;
 
					this.selector = selector;
 
					return this;
 
				}
 

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

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

	
 
		// HANDLE: $(DOMElement)
 
		} else if ( selector.nodeType ) {
 
			this.context = this[0] = selector;
 
			this.length = 1;
 
			return this;
 

	
 
		// HANDLE: $(function)
 
		// Shortcut for document ready
 
		} else if ( jQuery.isFunction( selector ) ) {
 
			return rootjQuery.ready( selector );
 
		}
 

	
 
		if ( selector.selector !== undefined ) {
 
			this.selector = selector.selector;
 
			this.context = selector.context;
 
		}
 

	
 
		return jQuery.makeArray( selector, this );
 
	},
 

	
 
	// Start with an empty selector
 
	selector: "",
 

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

	
 
	toArray: function() {
 
		return core_slice.call( this );
 
	},
 

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

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

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

	
 
	// Take an array of elements and push it onto the stack
 
	// (returning the new matched element set)
 
	pushStack: function( elems ) {
 

	
 
		// Build a new jQuery matched element set
 
		var ret = jQuery.merge( this.constructor(), elems );
 

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

	
 
		// Return the newly-formed element set
 
		return ret;
 
	},
 

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

	
 
	ready: function( fn ) {
 
		// Add the callback
 
		jQuery.ready.promise().done( fn );
 

	
 
		return this;
 
	},
 

	
 
	slice: function() {
 
		return this.pushStack( core_slice.apply( this, arguments ) );
 
	},
 

	
 
	first: function() {
 
		return this.eq( 0 );
 
	},
 

	
 
	last: function() {
 
		return this.eq( -1 );
 
	},
 

	
 
	eq: function( i ) {
 
		var len = this.length,
 
			j = +i + ( i < 0 ? len : 0 );
 
		return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );
 
	},
 

	
 
	map: function( callback ) {
 
		return this.pushStack( jQuery.map(this, function( elem, i ) {
 
			return callback.call( elem, i, elem );
 
		}));
 
	},
 

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

	
 
	// For internal use only.
 
	// Behaves like an Array's method, not like a jQuery method.
 
	push: core_push,
 
	sort: [].sort,
 
	splice: [].splice
 
};
 

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

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

	
 
	// Handle a deep copy situation
 
	if ( typeof target === "boolean" ) {
 
		deep = target;
 
		target = arguments[1] || {};
 
		// skip the boolean and the target
 
		i = 2;
 
	}
 

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

	
 
	// extend jQuery itself if only one argument is passed
 
	if ( length === i ) {
 
		target = this;
 
		--i;
 
	}
 

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

	
 
				// Prevent never-ending loop
 
				if ( target === copy ) {
 
					continue;
 
				}
 

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

	
 
					} else {
 
						clone = src && jQuery.isPlainObject(src) ? src : {};
 
					}
 

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

	
 
				// Don't bring in undefined values
 
				} else if ( copy !== undefined ) {
 
					target[ name ] = copy;
 
				}
 
			}
 
		}
 
	}
 

	
 
	// Return the modified object
 
	return target;
 
};
 

	
 
jQuery.extend({
 
	// Unique for each copy of jQuery on the page
 
	// Non-digits removed to match rinlinejQuery
 
	expando: "jQuery" + ( core_version + Math.random() ).replace( /\D/g, "" ),
 

	
 
	noConflict: function( deep ) {
 
		if ( window.$ === jQuery ) {
 
			window.$ = _$;
 
		}
 

	
 
		if ( deep && window.jQuery === jQuery ) {
 
			window.jQuery = _jQuery;
 
		}
 

	
 
		return jQuery;
 
	},
 

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

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

	
 
	// Hold (or release) the ready event
 
	holdReady: function( hold ) {
 
		if ( hold ) {
 
			jQuery.readyWait++;
 
		} else {
 
			jQuery.ready( true );
 
		}
 
	},
 

	
 
	// Handle when the DOM is ready
 
	ready: function( wait ) {
 

	
 
		// Abort if there are pending holds or we're already ready
 
		if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
 
			return;
 
		}
 

	
 
		// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
 
		if ( !document.body ) {
 
			return setTimeout( jQuery.ready );
 
		}
 

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

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

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

	
 
		// Trigger any bound ready events
 
		if ( jQuery.fn.trigger ) {
 
			jQuery( document ).trigger("ready").off("ready");
 
		}
 
	},
 

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

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

	
 
	isWindow: function( obj ) {
 
		/* jshint eqeqeq: false */
 
		return obj != null && obj == obj.window;
 
	},
 

	
 
	isNumeric: function( obj ) {
 
		return !isNaN( parseFloat(obj) ) && isFinite( obj );
 
	},
 

	
 
	type: function( obj ) {
 
		if ( obj == null ) {
 
			return String( obj );
 
		}
 
		return typeof obj === "object" || typeof obj === "function" ?
 
			class2type[ core_toString.call(obj) ] || "object" :
 
			typeof obj;
 
	},
 

	
 
	isPlainObject: function( obj ) {
 
		var key;
 

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

	
 
		try {
 
			// Not own constructor property must be Object
 
			if ( obj.constructor &&
 
				!core_hasOwn.call(obj, "constructor") &&
 
				!core_hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
 
				return false;
 
			}
 
		} catch ( e ) {
 
			// IE8,9 Will throw exceptions on certain host objects #9897
 
			return false;
 
		}
 

	
 
		// Support: IE<9
 
		// Handle iteration over inherited properties before own properties.
 
		if ( jQuery.support.ownLast ) {
 
			for ( key in obj ) {
 
				return core_hasOwn.call( obj, key );
 
			}
 
		}
 

	
 
		// Own properties are enumerated firstly, so to speed up,
 
		// if last one is own, then all properties are own.
 
		for ( key in obj ) {}
 

	
 
		return key === undefined || core_hasOwn.call( obj, key );
 
	},
 

	
 
	isEmptyObject: function( obj ) {
 
		var name;
 
		for ( name in obj ) {
 
			return false;
 
		}
 
		return true;
 
	},
 

	
 
	error: function( msg ) {
 
		throw new Error( msg );
 
	},
 

	
 
	// data: string of html
 
	// context (optional): If specified, the fragment will be created in this context, defaults to document
 
	// keepScripts (optional): If true, will include scripts passed in the html string
 
	parseHTML: function( data, context, keepScripts ) {
 
		if ( !data || typeof data !== "string" ) {
 
			return null;
 
		}
 
		if ( typeof context === "boolean" ) {
 
			keepScripts = context;
 
			context = false;
 
		}
 
		context = context || document;
 

	
 
		var parsed = rsingleTag.exec( data ),
 
			scripts = !keepScripts && [];
 

	
 
		// Single tag
 
		if ( parsed ) {
 
			return [ context.createElement( parsed[1] ) ];
 
		}
 

	
 
		parsed = jQuery.buildFragment( [ data ], context, scripts );
 
		if ( scripts ) {
 
			jQuery( scripts ).remove();
 
		}
 
		return jQuery.merge( [], parsed.childNodes );
 
	},
 

	
 
	parseJSON: function( data ) {
 
		// Attempt to parse using the native JSON parser first
 
		if ( window.JSON && window.JSON.parse ) {
 
			return window.JSON.parse( data );
 
		}
 

	
 
		if ( data === null ) {
 
			return data;
 
		}
 

	
 
		if ( typeof data === "string" ) {
 

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

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

	
 
					return ( new Function( "return " + data ) )();
 
				}
 
			}
 
		}
 

	
 
		jQuery.error( "Invalid JSON: " + data );
 
	},
 

	
 
	// Cross-browser xml parsing
 
	parseXML: function( data ) {
 
		var xml, tmp;
 
		if ( !data || typeof data !== "string" ) {
 
			return null;
 
		}
 
		try {
 
			if ( window.DOMParser ) { // Standard
 
				tmp = new DOMParser();
 
				xml = tmp.parseFromString( data , "text/xml" );
 
			} else { // IE
 
				xml = new ActiveXObject( "Microsoft.XMLDOM" );
 
				xml.async = "false";
 
				xml.loadXML( data );
 
			}
 
		} catch( e ) {
 
			xml = undefined;
 
		}
 
		if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) {
 
			jQuery.error( "Invalid XML: " + data );
 
		}
 
		return xml;
 
	},
 

	
 
	noop: function() {},
 

	
 
	// Evaluates a script in a global context
 
	// Workarounds based on findings by Jim Driscoll
 
	// http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
 
	globalEval: function( data ) {
 
		if ( data && jQuery.trim( data ) ) {
 
			// We use execScript on Internet Explorer
 
			// We use an anonymous function so that context is window
 
			// rather than jQuery in Firefox
 
			( window.execScript || function( data ) {
 
				window[ "eval" ].call( window, data );
 
			} )( data );
 
		}
 
	},
 

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

	
 
	nodeName: function( elem, name ) {
 
		return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
 
	},
 

	
 
	// args is for internal usage only
 
	each: function( obj, callback, args ) {
 
		var value,
 
			i = 0,
 
			length = obj.length,
 
			isArray = isArraylike( obj );
 

	
 
		if ( args ) {
 
			if ( isArray ) {
 
				for ( ; i < length; i++ ) {
 
					value = callback.apply( obj[ i ], args );
 

	
 
					if ( value === false ) {
 
						break;
 
					}
 
				}
 
			} else {
 
				for ( i in obj ) {
 
					value = callback.apply( obj[ i ], args );
 

	
 
					if ( value === false ) {
 
						break;
 
					}
 
				}
 
			}
 

	
 
		// A special, fast, case for the most common use of each
 
		} else {
 
			if ( isArray ) {
 
				for ( ; i < length; i++ ) {
 
					value = callback.call( obj[ i ], i, obj[ i ] );
 

	
 
					if ( value === false ) {
 
						break;
 
					}
 
				}
 
			} else {
 
				for ( i in obj ) {
 
					value = callback.call( obj[ i ], i, obj[ i ] );
 

	
 
					if ( value === false ) {
 
						break;
 
					}
 
				}
 
			}
 
		}
 

	
 
		return obj;
 
	},
 

	
 
	// Use native String.trim function wherever possible
 
	trim: core_trim && !core_trim.call("\uFEFF\xA0") ?
 
		function( text ) {
 
			return text == null ?
 
				"" :
 
				core_trim.call( text );
 
		} :
 

	
 
		// Otherwise use our own trimming functionality
 
		function( text ) {
 
			return text == null ?
 
				"" :
 
				( text + "" ).replace( rtrim, "" );
 
		},
 

	
 
	// results is for internal usage only
 
	makeArray: function( arr, results ) {
 
		var ret = results || [];
 

	
 
		if ( arr != null ) {
 
			if ( isArraylike( Object(arr) ) ) {
 
				jQuery.merge( ret,
 
					typeof arr === "string" ?
 
					[ arr ] : arr
 
				);
 
			} else {
 
				core_push.call( ret, arr );
 
			}
 
		}
 

	
 
		return ret;
 
	},
 

	
 
	inArray: function( elem, arr, i ) {
 
		var len;
 

	
 
		if ( arr ) {
 
			if ( core_indexOf ) {
 
				return core_indexOf.call( arr, elem, i );
 
			}
 

	
 
			len = arr.length;
 
			i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;
 

	
 
			for ( ; i < len; i++ ) {
 
				// Skip accessing in sparse arrays
 
				if ( i in arr && arr[ i ] === elem ) {
 
					return i;
 
				}
 
			}
 
		}
 

	
 
		return -1;
 
	},
 

	
 
	merge: function( first, second ) {
 
		var l = second.length,
 
			i = first.length,
 
			j = 0;
 

	
 
		if ( typeof l === "number" ) {
 
			for ( ; j < l; j++ ) {
 
				first[ i++ ] = second[ j ];
 
			}
 
		} else {
 
			while ( second[j] !== undefined ) {
 
				first[ i++ ] = second[ j++ ];
 
			}
 
		}
 

	
 
		first.length = i;
 

	
 
		return first;
 
	},
 

	
 
	grep: function( elems, callback, inv ) {
 
		var retVal,
 
			ret = [],
 
			i = 0,
 
			length = elems.length;
 
		inv = !!inv;
 

	
 
		// Go through the array, only saving the items
 
		// that pass the validator function
 
		for ( ; i < length; i++ ) {
 
			retVal = !!callback( elems[ i ], i );
 
			if ( inv !== retVal ) {
 
				ret.push( elems[ i ] );
 
			}
 
		}
 

	
 
		return ret;
 
	},
 

	
 
	// arg is for internal usage only
 
	map: function( elems, callback, arg ) {
 
		var value,
 
			i = 0,
 
			length = elems.length,
 
			isArray = isArraylike( elems ),
 
			ret = [];
 

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

	
 
				if ( value != null ) {
 
					ret[ ret.length ] = value;
 
				}
 
			}
 

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

	
 
				if ( value != null ) {
 
					ret[ ret.length ] = value;
 
				}
 
			}
 
		}
 

	
 
		// Flatten any nested arrays
 
		return core_concat.apply( [], ret );
 
	},
 

	
 
	// A global GUID counter for objects
 
	guid: 1,
 

	
 
	// Bind a function to a context, optionally partially applying any
 
	// arguments.
 
	proxy: function( fn, context ) {
 
		var args, proxy, tmp;
 

	
 
		if ( typeof context === "string" ) {
 
			tmp = fn[ context ];
 
			context = fn;
 
			fn = tmp;
 
		}
 

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

	
 
		// Simulated bind
 
		args = core_slice.call( arguments, 2 );
 
		proxy = function() {
 
			return fn.apply( context || this, args.concat( core_slice.call( arguments ) ) );
 
		};
 

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

	
 
		return proxy;
 
	},
 

	
 
	// Multifunctional method to get and set values of a collection
 
	// The value/s can optionally be executed if it's a function
 
	access: function( elems, fn, key, value, chainable, emptyGet, raw ) {
 
		var i = 0,
 
			length = elems.length,
 
			bulk = key == null;
 

	
 
		// Sets many values
 
		if ( jQuery.type( key ) === "object" ) {
 
			chainable = true;
 
			for ( i in key ) {
 
				jQuery.access( elems, fn, i, key[i], true, emptyGet, raw );
 
			}
 

	
 
		// Sets one value
 
		} else if ( value !== undefined ) {
 
			chainable = true;
 

	
 
			if ( !jQuery.isFunction( value ) ) {
 
				raw = true;
 
			}
 

	
 
			if ( bulk ) {
 
				// Bulk operations run against the entire set
 
				if ( raw ) {
 
					fn.call( elems, value );
 
					fn = null;
 

	
 
				// ...except when executing function values
 
				} else {
 
					bulk = fn;
 
					fn = function( elem, key, value ) {
 
						return bulk.call( jQuery( elem ), value );
 
					};
 
				}
 
			}
 

	
 
			if ( fn ) {
 
				for ( ; i < length; i++ ) {
 
					fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) );
 
				}
 
			}
 
		}
 

	
 
		return chainable ?
 
			elems :
 

	
 
			// Gets
 
			bulk ?
 
				fn.call( elems ) :
 
				length ? fn( elems[0], key ) : emptyGet;
 
	},
 

	
 
	now: function() {
 
		return ( new Date() ).getTime();
 
	},
 

	
 
	// A method for quickly swapping in/out CSS properties to get correct calculations.
 
	// Note: this method belongs to the css module but it's needed here for the support module.
 
	// If support gets modularized, this method should be moved back to the css module.
 
	swap: function( elem, options, callback, args ) {
 
		var ret, name,
 
			old = {};
 

	
 
		// Remember the old values, and insert the new ones
 
		for ( name in options ) {
 
			old[ name ] = elem.style[ name ];
 
			elem.style[ name ] = options[ name ];
 
		}
 

	
 
		ret = callback.apply( elem, args || [] );
 

	
 
		// Revert the old values
 
		for ( name in options ) {
 
			elem.style[ name ] = old[ name ];
 
		}
 

	
 
		return ret;
 
	}
 
});
 

	
 
jQuery.ready.promise = function( obj ) {
 
	if ( !readyList ) {
 

	
 
		readyList = jQuery.Deferred();
 

	
 
		// Catch cases where $(document).ready() is called after the browser event has already occurred.
 
		// we once tried to use readyState "interactive" here, but it caused issues like the one
 
		// discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15
 
		if ( document.readyState === "complete" ) {
 
			// Handle it asynchronously to allow scripts the opportunity to delay ready
 
			setTimeout( jQuery.ready );
 

	
 
		// Standards-based browsers support DOMContentLoaded
 
		} else if ( document.addEventListener ) {
 
			// Use the handy event callback
 
			document.addEventListener( "DOMContentLoaded", completed, false );
 

	
 
			// A fallback to window.onload, that will always work
 
			window.addEventListener( "load", completed, false );
 

	
 
		// If IE event model is used
 
		} else {
 
			// Ensure firing before onload, maybe late but safe also for iframes
 
			document.attachEvent( "onreadystatechange", completed );
 

	
 
			// A fallback to window.onload, that will always work
 
			window.attachEvent( "onload", completed );
 

	
 
			// If IE and not a frame
 
			// continually check to see if the document is ready
 
			var top = false;
 

	
 
			try {
 
				top = window.frameElement == null && document.documentElement;
 
			} catch(e) {}
 

	
 
			if ( top && top.doScroll ) {
 
				(function doScrollCheck() {
 
					if ( !jQuery.isReady ) {
 

	
 
						try {
 
							// Use the trick by Diego Perini
 
							// http://javascript.nwbox.com/IEContentLoaded/
 
							top.doScroll("left");
 
						} catch(e) {
 
							return setTimeout( doScrollCheck, 50 );
 
						}
 

	
 
						// detach all dom ready events
 
						detach();
 

	
 
						// and execute any waiting functions
 
						jQuery.ready();
 
					}
 
				})();
 
			}
 
		}
 
	}
 
	return readyList.promise( obj );
 
};
 

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

	
 
function isArraylike( obj ) {
 
	var length = obj.length,
 
		type = jQuery.type( obj );
 

	
 
	if ( jQuery.isWindow( obj ) ) {
 
		return false;
 
	}
 

	
 
	if ( obj.nodeType === 1 && length ) {
 
		return true;
 
	}
 

	
 
	return type === "array" || type !== "function" &&
 
		( length === 0 ||
 
		typeof length === "number" && length > 0 && ( length - 1 ) in obj );
 
}
 

	
 
// All jQuery objects should point back to these
 
rootjQuery = jQuery(document);
 
/*!
 
 * Sizzle CSS Selector Engine v1.10.2
 
 * http://sizzlejs.com/
 
 *
 
 * Copyright 2013 jQuery Foundation, Inc. and other contributors
 
 * Released under the MIT license
 
 * http://jquery.org/license
 
 *
 
 * Date: 2013-07-03
 
 */
 
(function( window, undefined ) {
 

	
 
var i,
 
	support,
 
	cachedruns,
 
	Expr,
 
	getText,
 
	isXML,
 
	compile,
 
	outermostContext,
 
	sortInput,
 

	
 
	// Local document vars
 
	setDocument,
 
	document,
 
	docElem,
 
	documentIsHTML,
 
	rbuggyQSA,
 
	rbuggyMatches,
 
	matches,
 
	contains,
 

	
 
	// Instance-specific data
 
	expando = "sizzle" + -(new Date()),
 
	preferredDoc = window.document,
 
	dirruns = 0,
 
	done = 0,
 
	classCache = createCache(),
 
	tokenCache = createCache(),
 
	compilerCache = createCache(),
 
	hasDuplicate = false,
 
	sortOrder = function( a, b ) {
 
		if ( a === b ) {
 
			hasDuplicate = true;
 
			return 0;
 
		}
 
		return 0;
 
	},
 

	
 
	// General-purpose constants
 
	strundefined = typeof undefined,
 
	MAX_NEGATIVE = 1 << 31,
 

	
 
	// Instance methods
 
	hasOwn = ({}).hasOwnProperty,
 
	arr = [],
 
	pop = arr.pop,
 
	push_native = arr.push,
 
	push = arr.push,
 
	slice = arr.slice,
 
	// Use a stripped-down indexOf if we can't use a native one
 
	indexOf = arr.indexOf || function( elem ) {
 
		var i = 0,
 
			len = this.length;
 
		for ( ; i < len; i++ ) {
 
			if ( this[i] === elem ) {
 
				return i;
 
			}
 
		}
 
		return -1;
 
	},
 

	
 
	booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
 

	
 
	// Regular expressions
 

	
 
	// Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace
 
	whitespace = "[\\x20\\t\\r\\n\\f]",
 
	// http://www.w3.org/TR/css3-syntax/#characters
 
	characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
 

	
 
	// Loosely modeled on CSS identifier characters
 
	// An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors
 
	// Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
 
	identifier = characterEncoding.replace( "w", "w#" ),
 

	
 
	// Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors
 
	attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace +
 
		"*(?:([*^$|!~]?=)" + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]",
 

	
 
	// Prefer arguments quoted,
 
	//   then not containing pseudos/brackets,
 
	//   then attribute selectors/non-parenthetical expressions,
 
	//   then anything else
 
	// These preferences are here to reduce the number of selectors
 
	//   needing tokenize in the PSEUDO preFilter
 
	pseudos = ":(" + characterEncoding + ")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|" + attributes.replace( 3, 8 ) + ")*)|.*)\\)|)",
 

	
 
	// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
 
	rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
 

	
 
	rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
 
	rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
 

	
 
	rsibling = new RegExp( whitespace + "*[+~]" ),
 
	rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*)" + whitespace + "*\\]", "g" ),
 

	
 
	rpseudo = new RegExp( pseudos ),
 
	ridentifier = new RegExp( "^" + identifier + "$" ),
 

	
 
	matchExpr = {
 
		"ID": new RegExp( "^#(" + characterEncoding + ")" ),
 
		"CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ),
 
		"TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ),
 
		"ATTR": new RegExp( "^" + attributes ),
 
		"PSEUDO": new RegExp( "^" + pseudos ),
 
		"CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
 
			"*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
 
			"*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
 
		"bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
 
		// For use in libraries implementing .is()
 
		// We use this for POS matching in `select`
 
		"needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
 
			whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
 
	},
 

	
 
	rnative = /^[^{]+\{\s*\[native \w/,
 

	
 
	// Easily-parseable/retrievable ID or TAG or CLASS selectors
 
	rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
 

	
 
	rinputs = /^(?:input|select|textarea|button)$/i,
 
	rheader = /^h\d$/i,
 

	
 
	rescape = /'|\\/g,
 

	
 
	// CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
 
	runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
 
	funescape = function( _, escaped, escapedWhitespace ) {
 
		var high = "0x" + escaped - 0x10000;
 
		// NaN means non-codepoint
 
		// Support: Firefox
 
		// Workaround erroneous numeric interpretation of +"0x"
 
		return high !== high || escapedWhitespace ?
 
			escaped :
 
			// BMP codepoint
 
			high < 0 ?
 
				String.fromCharCode( high + 0x10000 ) :
 
				// Supplemental Plane codepoint (surrogate pair)
 
				String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
 
	};
 

	
 
// Optimize for push.apply( _, NodeList )
 
try {
 
	push.apply(
 
		(arr = slice.call( preferredDoc.childNodes )),
 
		preferredDoc.childNodes
 
	);
 
	// Support: Android<4.0
 
	// Detect silently failing push.apply
 
	arr[ preferredDoc.childNodes.length ].nodeType;
 
} catch ( e ) {
 
	push = { apply: arr.length ?
 

	
 
		// Leverage slice if possible
 
		function( target, els ) {
 
			push_native.apply( target, slice.call(els) );
 
		} :
 

	
 
		// Support: IE<9
 
		// Otherwise append directly
 
		function( target, els ) {
 
			var j = target.length,
 
				i = 0;
 
			// Can't trust NodeList.length
 
			while ( (target[j++] = els[i++]) ) {}
 
			target.length = j - 1;
 
		}
 
	};
 
}
 

	
 
function Sizzle( selector, context, results, seed ) {
 
	var match, elem, m, nodeType,
 
		// QSA vars
 
		i, groups, old, nid, newContext, newSelector;
 

	
 
	if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
 
		setDocument( context );
 
	}
 

	
 
	context = context || document;
 
	results = results || [];
 

	
 
	if ( !selector || typeof selector !== "string" ) {
 
		return results;
 
	}
 

	
 
	if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) {
 
		return [];
 
	}
 

	
 
	if ( documentIsHTML && !seed ) {
 

	
 
		// Shortcuts
 
		if ( (match = rquickExpr.exec( selector )) ) {
 
			// Speed-up: Sizzle("#ID")
 
			if ( (m = match[1]) ) {
 
				if ( nodeType === 9 ) {
 
					elem = context.getElementById( m );
 
					// Check parentNode to catch when Blackberry 4.6 returns
 
					// nodes that are no longer in the document #6963
 
					if ( elem && elem.parentNode ) {
 
						// Handle the case where IE, Opera, and Webkit return items
 
						// by name instead of ID
 
						if ( elem.id === m ) {
 
							results.push( elem );
 
							return results;
 
						}
 
					} else {
 
						return results;
 
					}
 
				} else {
 
					// Context is not a document
 
					if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&
 
						contains( context, elem ) && elem.id === m ) {
 
						results.push( elem );
 
						return results;
 
					}
 
				}
 

	
 
			// Speed-up: Sizzle("TAG")
 
			} else if ( match[2] ) {
 
				push.apply( results, context.getElementsByTagName( selector ) );
 
				return results;
 

	
 
			// Speed-up: Sizzle(".CLASS")
 
			} else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) {
 
				push.apply( results, context.getElementsByClassName( m ) );
 
				return results;
 
			}
 
		}
 

	
 
		// QSA path
 
		if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
 
			nid = old = expando;
 
			newContext = context;
 
			newSelector = nodeType === 9 && selector;
 

	
 
			// qSA works strangely on Element-rooted queries
 
			// We can work around this by specifying an extra ID on the root
 
			// and working up from there (Thanks to Andrew Dupont for the technique)
 
			// IE 8 doesn't work on object elements
 
			if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
 
				groups = tokenize( selector );
 

	
 
				if ( (old = context.getAttribute("id")) ) {
 
					nid = old.replace( rescape, "\\$&" );
 
				} else {
 
					context.setAttribute( "id", nid );
 
				}
 
				nid = "[id='" + nid + "'] ";
 

	
 
				i = groups.length;
 
				while ( i-- ) {
 
					groups[i] = nid + toSelector( groups[i] );
 
				}
 
				newContext = rsibling.test( selector ) && context.parentNode || context;
 
				newSelector = groups.join(",");
 
			}
 

	
 
			if ( newSelector ) {
 
				try {
 
					push.apply( results,
 
						newContext.querySelectorAll( newSelector )
 
					);
 
					return results;
 
				} catch(qsaError) {
 
				} finally {
 
					if ( !old ) {
 
						context.removeAttribute("id");
 
					}
 
				}
 
			}
 
		}
 
	}
 

	
 
	// All others
 
	return select( selector.replace( rtrim, "$1" ), context, results, seed );
 
}
 

	
 
/**
 
 * Create key-value caches of limited size
 
 * @returns {Function(string, Object)} Returns the Object data after storing it on itself with
 
 *	property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
 
 *	deleting the oldest entry
 
 */
 
function createCache() {
 
	var keys = [];
 

	
 
	function cache( key, value ) {
 
		// Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
 
		if ( keys.push( key += " " ) > Expr.cacheLength ) {
 
			// Only keep the most recent entries
 
			delete cache[ keys.shift() ];
 
		}
 
		return (cache[ key ] = value);
 
	}
 
	return cache;
 
}
 

	
 
/**
 
 * Mark a function for special use by Sizzle
 
 * @param {Function} fn The function to mark
 
 */
 
function markFunction( fn ) {
 
	fn[ expando ] = true;
 
	return fn;
 
}
 

	
 
/**
 
 * Support testing using an element
 
 * @param {Function} fn Passed the created div and expects a boolean result
 
 */
 
function assert( fn ) {
 
	var div = document.createElement("div");
 

	
 
	try {
 
		return !!fn( div );
 
	} catch (e) {
 
		return false;
 
	} finally {
 
		// Remove from its parent by default
 
		if ( div.parentNode ) {
 
			div.parentNode.removeChild( div );
 
		}
 
		// release memory in IE
 
		div = null;
 
	}
 
}
 

	
 
/**
 
 * Adds the same handler for all of the specified attrs
 
 * @param {String} attrs Pipe-separated list of attributes
 
 * @param {Function} handler The method that will be applied
 
 */
 
function addHandle( attrs, handler ) {
 
	var arr = attrs.split("|"),
 
		i = attrs.length;
 

	
 
	while ( i-- ) {
 
		Expr.attrHandle[ arr[i] ] = handler;
 
	}
 
}
 

	
 
/**
 
 * Checks document order of two siblings
 
 * @param {Element} a
 
 * @param {Element} b
 
 * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
 
 */
 
function siblingCheck( a, b ) {
 
	var cur = b && a,
 
		diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
 
			( ~b.sourceIndex || MAX_NEGATIVE ) -
 
			( ~a.sourceIndex || MAX_NEGATIVE );
 

	
 
	// Use IE sourceIndex if available on both nodes
 
	if ( diff ) {
 
		return diff;
 
	}
 

	
 
	// Check if b follows a
 
	if ( cur ) {
 
		while ( (cur = cur.nextSibling) ) {
 
			if ( cur === b ) {
 
				return -1;
 
			}
 
		}
 
	}
 

	
 
	return a ? 1 : -1;
 
}
 

	
 
/**
 
 * Returns a function to use in pseudos for input types
 
 * @param {String} type
 
 */
 
function createInputPseudo( type ) {
 
	return function( elem ) {
 
		var name = elem.nodeName.toLowerCase();
 
		return name === "input" && elem.type === type;
 
	};
 
}
 

	
 
/**
 
 * Returns a function to use in pseudos for buttons
 
 * @param {String} type
 
 */
 
function createButtonPseudo( type ) {
 
	return function( elem ) {
 
		var name = elem.nodeName.toLowerCase();
 
		return (name === "input" || name === "button") && elem.type === type;
 
	};
 
}
 

	
 
/**
 
 * Returns a function to use in pseudos for positionals
 
 * @param {Function} fn
 
 */
 
function createPositionalPseudo( fn ) {
 
	return markFunction(function( argument ) {
 
		argument = +argument;
 
		return markFunction(function( seed, matches ) {
 
			var j,
 
				matchIndexes = fn( [], seed.length, argument ),
 
				i = matchIndexes.length;
 

	
 
			// Match elements found at the specified indexes
 
			while ( i-- ) {
 
				if ( seed[ (j = matchIndexes[i]) ] ) {
 
					seed[j] = !(matches[j] = seed[j]);
 
				}
 
			}
 
		});
 
	});
 
}
 

	
 
/**
 
 * Detect xml
 
 * @param {Element|Object} elem An element or a document
 
 */
 
isXML = Sizzle.isXML = function( elem ) {
 
	// documentElement is verified for cases where it doesn't yet exist
 
	// (such as loading iframes in IE - #4833)
 
	var documentElement = elem && (elem.ownerDocument || elem).documentElement;
 
	return documentElement ? documentElement.nodeName !== "HTML" : false;
 
};
 

	
 
// Expose support vars for convenience
 
support = Sizzle.support = {};
 

	
 
/**
 
 * Sets document-related variables once based on the current document
 
 * @param {Element|Object} [doc] An element or document object to use to set the document
 
 * @returns {Object} Returns the current document
 
 */
 
setDocument = Sizzle.setDocument = function( node ) {
 
	var doc = node ? node.ownerDocument || node : preferredDoc,
 
		parent = doc.defaultView;
 

	
 
	// If no document and documentElement is available, return
 
	if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
 
		return document;
 
	}
 

	
 
	// Set our document
 
	document = doc;
 
	docElem = doc.documentElement;
 

	
 
	// Support tests
 
	documentIsHTML = !isXML( doc );
 

	
 
	// Support: IE>8
 
	// If iframe document is assigned to "document" variable and if iframe has been reloaded,
 
	// IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936
 
	// IE6-8 do not support the defaultView property so parent will be undefined
 
	if ( parent && parent.attachEvent && parent !== parent.top ) {
 
		parent.attachEvent( "onbeforeunload", function() {
 
			setDocument();
 
		});
 
	}
 

	
 
	/* Attributes
 
	---------------------------------------------------------------------- */
 

	
 
	// Support: IE<8
 
	// Verify that getAttribute really returns attributes and not properties (excepting IE8 booleans)
 
	support.attributes = assert(function( div ) {
 
		div.className = "i";
 
		return !div.getAttribute("className");
 
	});
 

	
 
	/* getElement(s)By*
 
	---------------------------------------------------------------------- */
 

	
 
	// Check if getElementsByTagName("*") returns only elements
 
	support.getElementsByTagName = assert(function( div ) {
 
		div.appendChild( doc.createComment("") );
 
		return !div.getElementsByTagName("*").length;
 
	});
 

	
 
	// Check if getElementsByClassName can be trusted
 
	support.getElementsByClassName = assert(function( div ) {
 
		div.innerHTML = "<div class='a'></div><div class='a i'></div>";
 

	
 
		// Support: Safari<4
 
		// Catch class over-caching
 
		div.firstChild.className = "i";
 
		// Support: Opera<10
 
		// Catch gEBCN failure to find non-leading classes
 
		return div.getElementsByClassName("i").length === 2;
 
	});
 

	
 
	// Support: IE<10
 
	// Check if getElementById returns elements by name
 
	// The broken getElementById methods don't pick up programatically-set names,
 
	// so use a roundabout getElementsByName test
 
	support.getById = assert(function( div ) {
 
		docElem.appendChild( div ).id = expando;
 
		return !doc.getElementsByName || !doc.getElementsByName( expando ).length;
 
	});
 

	
 
	// ID find and filter
 
	if ( support.getById ) {
 
		Expr.find["ID"] = function( id, context ) {
 
			if ( typeof context.getElementById !== strundefined && documentIsHTML ) {
 
				var m = context.getElementById( id );
 
				// Check parentNode to catch when Blackberry 4.6 returns
 
				// nodes that are no longer in the document #6963
 
				return m && m.parentNode ? [m] : [];
 
			}
 
		};
 
		Expr.filter["ID"] = function( id ) {
 
			var attrId = id.replace( runescape, funescape );
 
			return function( elem ) {
 
				return elem.getAttribute("id") === attrId;
 
			};
 
		};
 
	} else {
 
		// Support: IE6/7
 
		// getElementById is not reliable as a find shortcut
 
		delete Expr.find["ID"];
 

	
 
		Expr.filter["ID"] =  function( id ) {
 
			var attrId = id.replace( runescape, funescape );
 
			return function( elem ) {
 
				var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id");
 
				return node && node.value === attrId;
 
			};
 
		};
 
	}
 

	
 
	// Tag
 
	Expr.find["TAG"] = support.getElementsByTagName ?
 
		function( tag, context ) {
 
			if ( typeof context.getElementsByTagName !== strundefined ) {
 
				return context.getElementsByTagName( tag );
 
			}
 
		} :
 
		function( tag, context ) {
 
			var elem,
 
				tmp = [],
 
				i = 0,
 
				results = context.getElementsByTagName( tag );
 

	
 
			// Filter out possible comments
 
			if ( tag === "*" ) {
 
				while ( (elem = results[i++]) ) {
 
					if ( elem.nodeType === 1 ) {
 
						tmp.push( elem );
 
					}
 
				}
 

	
 
				return tmp;
 
			}
 
			return results;
 
		};
 

	
 
	// Class
 
	Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
 
		if ( typeof context.getElementsByClassName !== strundefined && documentIsHTML ) {
 
			return context.getElementsByClassName( className );
 
		}
 
	};
 

	
 
	/* QSA/matchesSelector
 
	---------------------------------------------------------------------- */
 

	
 
	// QSA and matchesSelector support
 

	
 
	// matchesSelector(:active) reports false when true (IE9/Opera 11.5)
 
	rbuggyMatches = [];
 

	
 
	// qSa(:focus) reports false when true (Chrome 21)
 
	// We allow this because of a bug in IE8/9 that throws an error
 
	// whenever `document.activeElement` is accessed on an iframe
 
	// So, we allow :focus to pass through QSA all the time to avoid the IE error
 
	// See http://bugs.jquery.com/ticket/13378
 
	rbuggyQSA = [];
 

	
 
	if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) {
 
		// Build QSA regex
 
		// Regex strategy adopted from Diego Perini
 
		assert(function( div ) {
 
			// Select is set to empty string on purpose
 
			// This is to test IE's treatment of not explicitly
 
			// setting a boolean content attribute,
 
			// since its presence should be enough
 
			// http://bugs.jquery.com/ticket/12359
 
			div.innerHTML = "<select><option selected=''></option></select>";
 

	
 
			// Support: IE8
 
			// Boolean attributes and "value" are not treated correctly
 
			if ( !div.querySelectorAll("[selected]").length ) {
 
				rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
 
			}
 

	
 
			// Webkit/Opera - :checked should return selected option elements
 
			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
 
			// IE8 throws error here and will not see later tests
 
			if ( !div.querySelectorAll(":checked").length ) {
 
				rbuggyQSA.push(":checked");
 
			}
 
		});
 

	
 
		assert(function( div ) {
 

	
 
			// Support: Opera 10-12/IE8
 
			// ^= $= *= and empty values
 
			// Should not select anything
 
			// Support: Windows 8 Native Apps
 
			// The type attribute is restricted during .innerHTML assignment
 
			var input = doc.createElement("input");
 
			input.setAttribute( "type", "hidden" );
 
			div.appendChild( input ).setAttribute( "t", "" );
 

	
 
			if ( div.querySelectorAll("[t^='']").length ) {
 
				rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
 
			}
 

	
 
			// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
 
			// IE8 throws error here and will not see later tests
 
			if ( !div.querySelectorAll(":enabled").length ) {
 
				rbuggyQSA.push( ":enabled", ":disabled" );
 
			}
 

	
 
			// Opera 10-11 does not throw on post-comma invalid pseudos
 
			div.querySelectorAll("*,:x");
 
			rbuggyQSA.push(",.*:");
 
		});
 
	}
 

	
 
	if ( (support.matchesSelector = rnative.test( (matches = docElem.webkitMatchesSelector ||
 
		docElem.mozMatchesSelector ||
 
		docElem.oMatchesSelector ||
 
		docElem.msMatchesSelector) )) ) {
 

	
 
		assert(function( div ) {
 
			// Check to see if it's possible to do matchesSelector
 
			// on a disconnected node (IE 9)
 
			support.disconnectedMatch = matches.call( div, "div" );
 

	
 
			// This should fail with an exception
 
			// Gecko does not error, returns false instead
 
			matches.call( div, "[s!='']:x" );
 
			rbuggyMatches.push( "!=", pseudos );
 
		});
 
	}
 

	
 
	rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
 
	rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
 

	
 
	/* Contains
 
	---------------------------------------------------------------------- */
 

	
 
	// Element contains another
 
	// Purposefully does not implement inclusive descendent
 
	// As in, an element does not contain itself
 
	contains = rnative.test( docElem.contains ) || docElem.compareDocumentPosition ?
 
		function( a, b ) {
 
			var adown = a.nodeType === 9 ? a.documentElement : a,
 
				bup = b && b.parentNode;
 
			return a === bup || !!( bup && bup.nodeType === 1 && (
 
				adown.contains ?
 
					adown.contains( bup ) :
 
					a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
 
			));
 
		} :
 
		function( a, b ) {
 
			if ( b ) {
 
				while ( (b = b.parentNode) ) {
 
					if ( b === a ) {
 
						return true;
 
					}
 
				}
 
			}
 
			return false;
 
		};
 

	
 
	/* Sorting
 
	---------------------------------------------------------------------- */
 

	
 
	// Document order sorting
 
	sortOrder = docElem.compareDocumentPosition ?
 
	function( a, b ) {
 

	
 
		// Flag for duplicate removal
 
		if ( a === b ) {
 
			hasDuplicate = true;
 
			return 0;
 
		}
 

	
 
		var compare = b.compareDocumentPosition && a.compareDocumentPosition && a.compareDocumentPosition( b );
 

	
 
		if ( compare ) {
 
			// Disconnected nodes
 
			if ( compare & 1 ||
 
				(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
 

	
 
				// Choose the first element that is related to our preferred document
 
				if ( a === doc || contains(preferredDoc, a) ) {
 
					return -1;
 
				}
 
				if ( b === doc || contains(preferredDoc, b) ) {
 
					return 1;
 
				}
 

	
 
				// Maintain original order
 
				return sortInput ?
 
					( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
 
					0;
 
			}
 

	
 
			return compare & 4 ? -1 : 1;
 
		}
 

	
 
		// Not directly comparable, sort on existence of method
 
		return a.compareDocumentPosition ? -1 : 1;
 
	} :
 
	function( a, b ) {
 
		var cur,
 
			i = 0,
 
			aup = a.parentNode,
 
			bup = b.parentNode,
 
			ap = [ a ],
 
			bp = [ b ];
 

	
 
		// Exit early if the nodes are identical
 
		if ( a === b ) {
 
			hasDuplicate = true;
 
			return 0;
 

	
 
		// Parentless nodes are either documents or disconnected
 
		} else if ( !aup || !bup ) {
 
			return a === doc ? -1 :
 
				b === doc ? 1 :
 
				aup ? -1 :
 
				bup ? 1 :
 
				sortInput ?
 
				( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
 
				0;
 

	
 
		// If the nodes are siblings, we can do a quick check
 
		} else if ( aup === bup ) {
 
			return siblingCheck( a, b );
 
		}
 

	
 
		// Otherwise we need full lists of their ancestors for comparison
 
		cur = a;
 
		while ( (cur = cur.parentNode) ) {
 
			ap.unshift( cur );
 
		}
 
		cur = b;
 
		while ( (cur = cur.parentNode) ) {
 
			bp.unshift( cur );
 
		}
 

	
 
		// Walk down the tree looking for a discrepancy
 
		while ( ap[i] === bp[i] ) {
 
			i++;
 
		}
 

	
 
		return i ?
 
			// Do a sibling check if the nodes have a common ancestor
 
			siblingCheck( ap[i], bp[i] ) :
 

	
 
			// Otherwise nodes in our document sort first
 
			ap[i] === preferredDoc ? -1 :
 
			bp[i] === preferredDoc ? 1 :
 
			0;
 
	};
 

	
 
	return doc;
 
};
 

	
 
Sizzle.matches = function( expr, elements ) {
 
	return Sizzle( expr, null, null, elements );
 
};
 

	
 
Sizzle.matchesSelector = function( elem, expr ) {
 
	// Set document vars if needed
 
	if ( ( elem.ownerDocument || elem ) !== document ) {
 
		setDocument( elem );
 
	}
 

	
 
	// Make sure that attribute selectors are quoted
 
	expr = expr.replace( rattributeQuotes, "='$1']" );
 

	
 
	if ( support.matchesSelector && documentIsHTML &&
 
		( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
 
		( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {
 

	
 
		try {
 
			var ret = matches.call( elem, expr );
 

	
 
			// IE 9's matchesSelector returns false on disconnected nodes
 
			if ( ret || support.disconnectedMatch ||
 
					// As well, disconnected nodes are said to be in a document
 
					// fragment in IE 9
 
					elem.document && elem.document.nodeType !== 11 ) {
 
				return ret;
 
			}
 
		} catch(e) {}
 
	}
 

	
 
	return Sizzle( expr, document, null, [elem] ).length > 0;
 
};
 

	
 
Sizzle.contains = function( context, elem ) {
 
	// Set document vars if needed
 
	if ( ( context.ownerDocument || context ) !== document ) {
 
		setDocument( context );
 
	}
 
	return contains( context, elem );
 
};
 

	
 
Sizzle.attr = function( elem, name ) {
 
	// Set document vars if needed
 
	if ( ( elem.ownerDocument || elem ) !== document ) {
 
		setDocument( elem );
 
	}
 

	
 
	var fn = Expr.attrHandle[ name.toLowerCase() ],
 
		// Don't get fooled by Object.prototype properties (jQuery #13807)
 
		val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
 
			fn( elem, name, !documentIsHTML ) :
 
			undefined;
 

	
 
	return val === undefined ?
 
		support.attributes || !documentIsHTML ?
 
			elem.getAttribute( name ) :
 
			(val = elem.getAttributeNode(name)) && val.specified ?
 
				val.value :
 
				null :
 
		val;
 
};
 

	
 
Sizzle.error = function( msg ) {
 
	throw new Error( "Syntax error, unrecognized expression: " + msg );
 
};
 

	
 
/**
 
 * Document sorting and removing duplicates
 
 * @param {ArrayLike} results
 
 */
 
Sizzle.uniqueSort = function( results ) {
 
	var elem,
 
		duplicates = [],
 
		j = 0,
 
		i = 0;
 

	
 
	// Unless we *know* we can detect duplicates, assume their presence
 
	hasDuplicate = !support.detectDuplicates;
 
	sortInput = !support.sortStable && results.slice( 0 );
 
	results.sort( sortOrder );
 

	
 
	if ( hasDuplicate ) {
 
		while ( (elem = results[i++]) ) {
 
			if ( elem === results[ i ] ) {
 
				j = duplicates.push( i );
 
			}
 
		}
 
		while ( j-- ) {
 
			results.splice( duplicates[ j ], 1 );
 
		}
 
	}
 

	
 
	return results;
 
};
 

	
 
/**
 
 * Utility function for retrieving the text value of an array of DOM nodes
 
 * @param {Array|Element} elem
 
 */
 
getText = Sizzle.getText = function( elem ) {
 
	var node,
 
		ret = "",
 
		i = 0,
 
		nodeType = elem.nodeType;
 

	
 
	if ( !nodeType ) {
 
		// If no nodeType, this is expected to be an array
 
		for ( ; (node = elem[i]); i++ ) {
 
			// Do not traverse comment nodes
 
			ret += getText( node );
 
		}
 
	} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
 
		// Use textContent for elements
 
		// innerText usage removed for consistency of new lines (see #11153)
 
		if ( typeof elem.textContent === "string" ) {
 
			return elem.textContent;
 
		} else {
 
			// Traverse its children
 
			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
 
				ret += getText( elem );
 
			}
 
		}
 
	} else if ( nodeType === 3 || nodeType === 4 ) {
 
		return elem.nodeValue;
 
	}
 
	// Do not include comment or processing instruction nodes
 

	
 
	return ret;
 
};
 

	
 
Expr = Sizzle.selectors = {
 

	
 
	// Can be adjusted by the user
 
	cacheLength: 50,
 

	
 
	createPseudo: markFunction,
 

	
 
	match: matchExpr,
 

	
 
	attrHandle: {},
 

	
 
	find: {},
 

	
 
	relative: {
 
		">": { dir: "parentNode", first: true },
 
		" ": { dir: "parentNode" },
 
		"+": { dir: "previousSibling", first: true },
 
		"~": { dir: "previousSibling" }
 
	},
 

	
 
	preFilter: {
 
		"ATTR": function( match ) {
 
			match[1] = match[1].replace( runescape, funescape );
 

	
 
			// Move the given value to match[3] whether quoted or unquoted
 
			match[3] = ( match[4] || match[5] || "" ).replace( runescape, funescape );
 

	
 
			if ( match[2] === "~=" ) {
 
				match[3] = " " + match[3] + " ";
 
			}
 

	
 
			return match.slice( 0, 4 );
 
		},
 

	
 
		"CHILD": function( match ) {
 
			/* matches from matchExpr["CHILD"]
 
				1 type (only|nth|...)
 
				2 what (child|of-type)
 
				3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
 
				4 xn-component of xn+y argument ([+-]?\d*n|)
 
				5 sign of xn-component
 
				6 x of xn-component
 
				7 sign of y-component
 
				8 y of y-component
 
			*/
 
			match[1] = match[1].toLowerCase();
 

	
 
			if ( match[1].slice( 0, 3 ) === "nth" ) {
 
				// nth-* requires argument
 
				if ( !match[3] ) {
 
					Sizzle.error( match[0] );
 
				}
 

	
 
				// numeric x and y parameters for Expr.filter.CHILD
 
				// remember that false/true cast respectively to 0/1
 
				match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
 
				match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
 

	
 
			// other types prohibit arguments
 
			} else if ( match[3] ) {
 
				Sizzle.error( match[0] );
 
			}
 

	
 
			return match;
 
		},
 

	
 
		"PSEUDO": function( match ) {
 
			var excess,
 
				unquoted = !match[5] && match[2];
 

	
 
			if ( matchExpr["CHILD"].test( match[0] ) ) {
 
				return null;
 
			}
 

	
 
			// Accept quoted arguments as-is
 
			if ( match[3] && match[4] !== undefined ) {
 
				match[2] = match[4];
 

	
 
			// Strip excess characters from unquoted arguments
 
			} else if ( unquoted && rpseudo.test( unquoted ) &&
 
				// Get excess from tokenize (recursively)
 
				(excess = tokenize( unquoted, true )) &&
 
				// advance to the next closing parenthesis
 
				(excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
 

	
 
				// excess is a negative index
 
				match[0] = match[0].slice( 0, excess );
 
				match[2] = unquoted.slice( 0, excess );
 
			}
 

	
 
			// Return only captures needed by the pseudo filter method (type and argument)
 
			return match.slice( 0, 3 );
 
		}
 
	},
 

	
 
	filter: {
 

	
 
		"TAG": function( nodeNameSelector ) {
 
			var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
 
			return nodeNameSelector === "*" ?
 
				function() { return true; } :
 
				function( elem ) {
 
					return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
 
				};
 
		},
 

	
 
		"CLASS": function( className ) {
 
			var pattern = classCache[ className + " " ];
 

	
 
			return pattern ||
 
				(pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
 
				classCache( className, function( elem ) {
 
					return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute("class") || "" );
 
				});
 
		},
 

	
 
		"ATTR": function( name, operator, check ) {
 
			return function( elem ) {
 
				var result = Sizzle.attr( elem, name );
 

	
 
				if ( result == null ) {
 
					return operator === "!=";
 
				}
 
				if ( !operator ) {
 
					return true;
 
				}
 

	
 
				result += "";
 

	
 
				return operator === "=" ? result === check :
 
					operator === "!=" ? result !== check :
 
					operator === "^=" ? check && result.indexOf( check ) === 0 :
 
					operator === "*=" ? check && result.indexOf( check ) > -1 :
 
					operator === "$=" ? check && result.slice( -check.length ) === check :
 
					operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 :
 
					operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
 
					false;
 
			};
 
		},
 

	
 
		"CHILD": function( type, what, argument, first, last ) {
 
			var simple = type.slice( 0, 3 ) !== "nth",
 
				forward = type.slice( -4 ) !== "last",
 
				ofType = what === "of-type";
 

	
 
			return first === 1 && last === 0 ?
 

	
 
				// Shortcut for :nth-*(n)
 
				function( elem ) {
 
					return !!elem.parentNode;
 
				} :
 

	
 
				function( elem, context, xml ) {
 
					var cache, outerCache, node, diff, nodeIndex, start,
 
						dir = simple !== forward ? "nextSibling" : "previousSibling",
 
						parent = elem.parentNode,
 
						name = ofType && elem.nodeName.toLowerCase(),
 
						useCache = !xml && !ofType;
 

	
 
					if ( parent ) {
 

	
 
						// :(first|last|only)-(child|of-type)
 
						if ( simple ) {
 
							while ( dir ) {
 
								node = elem;
 
								while ( (node = node[ dir ]) ) {
 
									if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {
 
										return false;
 
									}
 
								}
 
								// Reverse direction for :only-* (if we haven't yet done so)
 
								start = dir = type === "only" && !start && "nextSibling";
 
							}
 
							return true;
 
						}
 

	
 
						start = [ forward ? parent.firstChild : parent.lastChild ];
 

	
 
						// non-xml :nth-child(...) stores cache data on `parent`
 
						if ( forward && useCache ) {
 
							// Seek `elem` from a previously-cached index
 
							outerCache = parent[ expando ] || (parent[ expando ] = {});
 
							cache = outerCache[ type ] || [];
 
							nodeIndex = cache[0] === dirruns && cache[1];
 
							diff = cache[0] === dirruns && cache[2];
 
							node = nodeIndex && parent.childNodes[ nodeIndex ];
 

	
 
							while ( (node = ++nodeIndex && node && node[ dir ] ||
 

	
 
								// Fallback to seeking `elem` from the start
 
								(diff = nodeIndex = 0) || start.pop()) ) {
 

	
 
								// When found, cache indexes on `parent` and break
 
								if ( node.nodeType === 1 && ++diff && node === elem ) {
 
									outerCache[ type ] = [ dirruns, nodeIndex, diff ];
 
									break;
 
								}
 
							}
 

	
 
						// Use previously-cached element index if available
 
						} else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) {
 
							diff = cache[1];
 

	
 
						// xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...)
 
						} else {
 
							// Use the same loop as above to seek `elem` from the start
 
							while ( (node = ++nodeIndex && node && node[ dir ] ||
 
								(diff = nodeIndex = 0) || start.pop()) ) {
 

	
 
								if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) {
 
									// Cache the index of each encountered element
 
									if ( useCache ) {
 
										(node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];
 
									}
 

	
 
									if ( node === elem ) {
 
										break;
 
									}
 
								}
 
							}
 
						}
 

	
 
						// Incorporate the offset, then check against cycle size
 
						diff -= last;
 
						return diff === first || ( diff % first === 0 && diff / first >= 0 );
 
					}
 
				};
 
		},
 

	
 
		"PSEUDO": function( pseudo, argument ) {
 
			// pseudo-class names are case-insensitive
 
			// http://www.w3.org/TR/selectors/#pseudo-classes
 
			// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
 
			// Remember that setFilters inherits from pseudos
 
			var args,
 
				fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
 
					Sizzle.error( "unsupported pseudo: " + pseudo );
 

	
 
			// The user may use createPseudo to indicate that
 
			// arguments are needed to create the filter function
 
			// just as Sizzle does
 
			if ( fn[ expando ] ) {
 
				return fn( argument );
 
			}
 

	
 
			// But maintain support for old signatures
 
			if ( fn.length > 1 ) {
 
				args = [ pseudo, pseudo, "", argument ];
 
				return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
 
					markFunction(function( seed, matches ) {
 
						var idx,
 
							matched = fn( seed, argument ),
 
							i = matched.length;
 
						while ( i-- ) {
 
							idx = indexOf.call( seed, matched[i] );
 
							seed[ idx ] = !( matches[ idx ] = matched[i] );
 
						}
 
					}) :
 
					function( elem ) {
 
						return fn( elem, 0, args );
 
					};
 
			}
 

	
 
			return fn;
 
		}
 
	},
 

	
 
	pseudos: {
 
		// Potentially complex pseudos
 
		"not": markFunction(function( selector ) {
 
			// Trim the selector passed to compile
 
			// to avoid treating leading and trailing
 
			// spaces as combinators
 
			var input = [],
 
				results = [],
 
				matcher = compile( selector.replace( rtrim, "$1" ) );
 

	
 
			return matcher[ expando ] ?
 
				markFunction(function( seed, matches, context, xml ) {
 
					var elem,
 
						unmatched = matcher( seed, null, xml, [] ),
 
						i = seed.length;
 

	
 
					// Match elements unmatched by `matcher`
 
					while ( i-- ) {
 
						if ( (elem = unmatched[i]) ) {
 
							seed[i] = !(matches[i] = elem);
 
						}
 
					}
 
				}) :
 
				function( elem, context, xml ) {
 
					input[0] = elem;
 
					matcher( input, null, xml, results );
 
					return !results.pop();
 
				};
 
		}),
 

	
 
		"has": markFunction(function( selector ) {
 
			return function( elem ) {
 
				return Sizzle( selector, elem ).length > 0;
 
			};
 
		}),
 

	
 
		"contains": markFunction(function( text ) {
 
			return function( elem ) {
 
				return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
 
			};
 
		}),
 

	
 
		// "Whether an element is represented by a :lang() selector
 
		// is based solely on the element's language value
 
		// being equal to the identifier C,
 
		// or beginning with the identifier C immediately followed by "-".
 
		// The matching of C against the element's language value is performed case-insensitively.
 
		// The identifier C does not have to be a valid language name."
 
		// http://www.w3.org/TR/selectors/#lang-pseudo
 
		"lang": markFunction( function( lang ) {
 
			// lang value must be a valid identifier
 
			if ( !ridentifier.test(lang || "") ) {
 
				Sizzle.error( "unsupported lang: " + lang );
 
			}
 
			lang = lang.replace( runescape, funescape ).toLowerCase();
 
			return function( elem ) {
 
				var elemLang;
 
				do {
 
					if ( (elemLang = documentIsHTML ?
 
						elem.lang :
 
						elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
 

	
 
						elemLang = elemLang.toLowerCase();
 
						return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
 
					}
 
				} while ( (elem = elem.parentNode) && elem.nodeType === 1 );
 
				return false;
 
			};
 
		}),
 

	
 
		// Miscellaneous
 
		"target": function( elem ) {
 
			var hash = window.location && window.location.hash;
 
			return hash && hash.slice( 1 ) === elem.id;
 
		},
 

	
 
		"root": function( elem ) {
 
			return elem === docElem;
 
		},
 

	
 
		"focus": function( elem ) {
 
			return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
 
		},
 

	
 
		// Boolean properties
 
		"enabled": function( elem ) {
 
			return elem.disabled === false;
 
		},
 

	
 
		"disabled": function( elem ) {
 
			return elem.disabled === true;
 
		},
 

	
 
		"checked": function( elem ) {
 
			// In CSS3, :checked should return both checked and selected elements
 
			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
 
			var nodeName = elem.nodeName.toLowerCase();
 
			return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
 
		},
 

	
 
		"selected": function( elem ) {
 
			// Accessing this property makes selected-by-default
 
			// options in Safari work properly
 
			if ( elem.parentNode ) {
 
				elem.parentNode.selectedIndex;
 
			}
 

	
 
			return elem.selected === true;
 
		},
 

	
 
		// Contents
 
		"empty": function( elem ) {
 
			// http://www.w3.org/TR/selectors/#empty-pseudo
 
			// :empty is only affected by element nodes and content nodes(including text(3), cdata(4)),
 
			//   not comment, processing instructions, or others
 
			// Thanks to Diego Perini for the nodeName shortcut
 
			//   Greater than "@" means alpha characters (specifically not starting with "#" or "?")
 
			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
 
				if ( elem.nodeName > "@" || elem.nodeType === 3 || elem.nodeType === 4 ) {
 
					return false;
 
				}
 
			}
 
			return true;
 
		},
 

	
 
		"parent": function( elem ) {
 
			return !Expr.pseudos["empty"]( elem );
 
		},
 

	
 
		// Element/input types
 
		"header": function( elem ) {
 
			return rheader.test( elem.nodeName );
 
		},
 

	
 
		"input": function( elem ) {
 
			return rinputs.test( elem.nodeName );
 
		},
 

	
 
		"button": function( elem ) {
 
			var name = elem.nodeName.toLowerCase();
 
			return name === "input" && elem.type === "button" || name === "button";
 
		},
 

	
 
		"text": function( elem ) {
 
			var attr;
 
			// IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)
 
			// use getAttribute instead to test this case
 
			return elem.nodeName.toLowerCase() === "input" &&
 
				elem.type === "text" &&
 
				( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === elem.type );
 
		},
 

	
 
		// Position-in-collection
 
		"first": createPositionalPseudo(function() {
 
			return [ 0 ];
 
		}),
 

	
 
		"last": createPositionalPseudo(function( matchIndexes, length ) {
 
			return [ length - 1 ];
 
		}),
 

	
 
		"eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
 
			return [ argument < 0 ? argument + length : argument ];
 
		}),
 

	
 
		"even": createPositionalPseudo(function( matchIndexes, length ) {
 
			var i = 0;
 
			for ( ; i < length; i += 2 ) {
 
				matchIndexes.push( i );
 
			}
 
			return matchIndexes;
 
		}),
 

	
 
		"odd": createPositionalPseudo(function( matchIndexes, length ) {
 
			var i = 1;
 
			for ( ; i < length; i += 2 ) {
 
				matchIndexes.push( i );
 
			}
 
			return matchIndexes;
 
		}),
 

	
 
		"lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
 
			var i = argument < 0 ? argument + length : argument;
 
			for ( ; --i >= 0; ) {
 
				matchIndexes.push( i );
 
			}
 
			return matchIndexes;
 
		}),
 

	
 
		"gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
 
			var i = argument < 0 ? argument + length : argument;
 
			for ( ; ++i < length; ) {
 
				matchIndexes.push( i );
 
			}
 
			return matchIndexes;
 
		})
 
	}
 
};
 

	
 
Expr.pseudos["nth"] = Expr.pseudos["eq"];
 

	
 
// Add button/input type pseudos
 
for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
 
	Expr.pseudos[ i ] = createInputPseudo( i );
 
}
 
for ( i in { submit: true, reset: true } ) {
 
	Expr.pseudos[ i ] = createButtonPseudo( i );
 
}
 

	
 
// Easy API for creating new setFilters
 
function setFilters() {}
 
setFilters.prototype = Expr.filters = Expr.pseudos;
 
Expr.setFilters = new setFilters();
 

	
 
function tokenize( selector, parseOnly ) {
 
	var matched, match, tokens, type,
 
		soFar, groups, preFilters,
 
		cached = tokenCache[ selector + " " ];
 

	
 
	if ( cached ) {
 
		return parseOnly ? 0 : cached.slice( 0 );
 
	}
 

	
 
	soFar = selector;
 
	groups = [];
 
	preFilters = Expr.preFilter;
 

	
 
	while ( soFar ) {
 

	
 
		// Comma and first run
 
		if ( !matched || (match = rcomma.exec( soFar )) ) {
 
			if ( match ) {
 
				// Don't consume trailing commas as valid
 
				soFar = soFar.slice( match[0].length ) || soFar;
 
			}
 
			groups.push( tokens = [] );
 
		}
 

	
 
		matched = false;
 

	
 
		// Combinators
 
		if ( (match = rcombinators.exec( soFar )) ) {
 
			matched = match.shift();
 
			tokens.push({
 
				value: matched,
 
				// Cast descendant combinators to space
 
				type: match[0].replace( rtrim, " " )
 
			});
 
			soFar = soFar.slice( matched.length );
 
		}
 

	
 
		// Filters
 
		for ( type in Expr.filter ) {
 
			if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
 
				(match = preFilters[ type ]( match ))) ) {
 
				matched = match.shift();
 
				tokens.push({
 
					value: matched,
 
					type: type,
 
					matches: match
 
				});
 
				soFar = soFar.slice( matched.length );
 
			}
 
		}
 

	
 
		if ( !matched ) {
 
			break;
 
		}
 
	}
 

	
 
	// Return the length of the invalid excess
 
	// if we're just parsing
 
	// Otherwise, throw an error or return tokens
 
	return parseOnly ?
 
		soFar.length :
 
		soFar ?
 
			Sizzle.error( selector ) :
 
			// Cache the tokens
 
			tokenCache( selector, groups ).slice( 0 );
 
}
 

	
 
function toSelector( tokens ) {
 
	var i = 0,
 
		len = tokens.length,
 
		selector = "";
 
	for ( ; i < len; i++ ) {
 
		selector += tokens[i].value;
 
	}
 
	return selector;
 
}
 

	
 
function addCombinator( matcher, combinator, base ) {
 
	var dir = combinator.dir,
 
		checkNonElements = base && dir === "parentNode",
 
		doneName = done++;
 

	
 
	return combinator.first ?
 
		// Check against closest ancestor/preceding element
 
		function( elem, context, xml ) {
 
			while ( (elem = elem[ dir ]) ) {
 
				if ( elem.nodeType === 1 || checkNonElements ) {
 
					return matcher( elem, context, xml );
 
				}
 
			}
 
		} :
 

	
 
		// Check against all ancestor/preceding elements
 
		function( elem, context, xml ) {
 
			var data, cache, outerCache,
 
				dirkey = dirruns + " " + doneName;
 

	
 
			// We can't set arbitrary data on XML nodes, so they don't benefit from dir caching
 
			if ( xml ) {
 
				while ( (elem = elem[ dir ]) ) {
 
					if ( elem.nodeType === 1 || checkNonElements ) {
 
						if ( matcher( elem, context, xml ) ) {
 
							return true;
 
						}
 
					}
 
				}
 
			} else {
 
				while ( (elem = elem[ dir ]) ) {
 
					if ( elem.nodeType === 1 || checkNonElements ) {
 
						outerCache = elem[ expando ] || (elem[ expando ] = {});
 
						if ( (cache = outerCache[ dir ]) && cache[0] === dirkey ) {
 
							if ( (data = cache[1]) === true || data === cachedruns ) {
 
								return data === true;
 
							}
 
						} else {
 
							cache = outerCache[ dir ] = [ dirkey ];
 
							cache[1] = matcher( elem, context, xml ) || cachedruns;
 
							if ( cache[1] === true ) {
 
								return true;
 
							}
 
						}
 
					}
 
				}
 
			}
 
		};
 
}
 

	
 
function elementMatcher( matchers ) {
 
	return matchers.length > 1 ?
 
		function( elem, context, xml ) {
 
			var i = matchers.length;
 
			while ( i-- ) {
 
				if ( !matchers[i]( elem, context, xml ) ) {
 
					return false;
 
				}
 
			}
 
			return true;
 
		} :
 
		matchers[0];
 
}
 

	
 
function condense( unmatched, map, filter, context, xml ) {
 
	var elem,
 
		newUnmatched = [],
 
		i = 0,
 
		len = unmatched.length,
 
		mapped = map != null;
 

	
 
	for ( ; i < len; i++ ) {
 
		if ( (elem = unmatched[i]) ) {
 
			if ( !filter || filter( elem, context, xml ) ) {
 
				newUnmatched.push( elem );
 
				if ( mapped ) {
 
					map.push( i );
 
				}
 
			}
 
		}
 
	}
 

	
 
	return newUnmatched;
 
}
 

	
 
function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
 
	if ( postFilter && !postFilter[ expando ] ) {
 
		postFilter = setMatcher( postFilter );
 
	}
 
	if ( postFinder && !postFinder[ expando ] ) {
 
		postFinder = setMatcher( postFinder, postSelector );
 
	}
 
	return markFunction(function( seed, results, context, xml ) {
 
		var temp, i, elem,
 
			preMap = [],
 
			postMap = [],
 
			preexisting = results.length,
 

	
 
			// Get initial elements from seed or context
 
			elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
 

	
 
			// Prefilter to get matcher input, preserving a map for seed-results synchronization
 
			matcherIn = preFilter && ( seed || !selector ) ?
 
				condense( elems, preMap, preFilter, context, xml ) :
 
				elems,
 

	
 
			matcherOut = matcher ?
 
				// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
 
				postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
 

	
 
					// ...intermediate processing is necessary
 
					[] :
 

	
 
					// ...otherwise use results directly
 
					results :
 
				matcherIn;
 

	
 
		// Find primary matches
 
		if ( matcher ) {
 
			matcher( matcherIn, matcherOut, context, xml );
 
		}
 

	
 
		// Apply postFilter
 
		if ( postFilter ) {
 
			temp = condense( matcherOut, postMap );
 
			postFilter( temp, [], context, xml );
 

	
 
			// Un-match failing elements by moving them back to matcherIn
 
			i = temp.length;
 
			while ( i-- ) {
 
				if ( (elem = temp[i]) ) {
 
					matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
 
				}
 
			}
 
		}
 

	
 
		if ( seed ) {
 
			if ( postFinder || preFilter ) {
 
				if ( postFinder ) {
 
					// Get the final matcherOut by condensing this intermediate into postFinder contexts
 
					temp = [];
 
					i = matcherOut.length;
 
					while ( i-- ) {
 
						if ( (elem = matcherOut[i]) ) {
 
							// Restore matcherIn since elem is not yet a final match
 
							temp.push( (matcherIn[i] = elem) );
 
						}
 
					}
 
					postFinder( null, (matcherOut = []), temp, xml );
 
				}
 

	
 
				// Move matched elements from seed to results to keep them synchronized
 
				i = matcherOut.length;
 
				while ( i-- ) {
 
					if ( (elem = matcherOut[i]) &&
 
						(temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) {
 

	
 
						seed[temp] = !(results[temp] = elem);
 
					}
 
				}
 
			}
 

	
 
		// Add elements to results, through postFinder if defined
 
		} else {
 
			matcherOut = condense(
 
				matcherOut === results ?
 
					matcherOut.splice( preexisting, matcherOut.length ) :
 
					matcherOut
 
			);
 
			if ( postFinder ) {
 
				postFinder( null, results, matcherOut, xml );
 
			} else {
 
				push.apply( results, matcherOut );
 
			}
 
		}
 
	});
 
}
 

	
 
function matcherFromTokens( tokens ) {
 
	var checkContext, matcher, j,
 
		len = tokens.length,
 
		leadingRelative = Expr.relative[ tokens[0].type ],
 
		implicitRelative = leadingRelative || Expr.relative[" "],
 
		i = leadingRelative ? 1 : 0,
 

	
 
		// The foundational matcher ensures that elements are reachable from top-level context(s)
 
		matchContext = addCombinator( function( elem ) {
 
			return elem === checkContext;
 
		}, implicitRelative, true ),
 
		matchAnyContext = addCombinator( function( elem ) {
 
			return indexOf.call( checkContext, elem ) > -1;
 
		}, implicitRelative, true ),
 
		matchers = [ function( elem, context, xml ) {
 
			return ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
 
				(checkContext = context).nodeType ?
 
					matchContext( elem, context, xml ) :
 
					matchAnyContext( elem, context, xml ) );
 
		} ];
 

	
 
	for ( ; i < len; i++ ) {
 
		if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
 
			matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
 
		} else {
 
			matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
 

	
 
			// Return special upon seeing a positional matcher
 
			if ( matcher[ expando ] ) {
 
				// Find the next relative operator (if any) for proper handling
 
				j = ++i;
 
				for ( ; j < len; j++ ) {
 
					if ( Expr.relative[ tokens[j].type ] ) {
 
						break;
 
					}
 
				}
 
				return setMatcher(
 
					i > 1 && elementMatcher( matchers ),
 
					i > 1 && toSelector(
 
						// If the preceding token was a descendant combinator, insert an implicit any-element `*`
 
						tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
 
					).replace( rtrim, "$1" ),
 
					matcher,
 
					i < j && matcherFromTokens( tokens.slice( i, j ) ),
 
					j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
 
					j < len && toSelector( tokens )
 
				);
 
			}
 
			matchers.push( matcher );
 
		}
 
	}
 

	
 
	return elementMatcher( matchers );
 
}
 

	
 
function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
 
	// A counter to specify which element is currently being matched
 
	var matcherCachedRuns = 0,
 
		bySet = setMatchers.length > 0,
 
		byElement = elementMatchers.length > 0,
 
		superMatcher = function( seed, context, xml, results, expandContext ) {
 
			var elem, j, matcher,
 
				setMatched = [],
 
				matchedCount = 0,
 
				i = "0",
 
				unmatched = seed && [],
 
				outermost = expandContext != null,
 
				contextBackup = outermostContext,
 
				// We must always have either seed elements or context
 
				elems = seed || byElement && Expr.find["TAG"]( "*", expandContext && context.parentNode || context ),
 
				// Use integer dirruns iff this is the outermost matcher
 
				dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1);
 

	
 
			if ( outermost ) {
 
				outermostContext = context !== document && context;
 
				cachedruns = matcherCachedRuns;
 
			}
 

	
 
			// Add elements passing elementMatchers directly to results
 
			// Keep `i` a string if there are no elements so `matchedCount` will be "00" below
 
			for ( ; (elem = elems[i]) != null; i++ ) {
 
				if ( byElement && elem ) {
 
					j = 0;
 
					while ( (matcher = elementMatchers[j++]) ) {
 
						if ( matcher( elem, context, xml ) ) {
 
							results.push( elem );
 
							break;
 
						}
 
					}
 
					if ( outermost ) {
 
						dirruns = dirrunsUnique;
 
						cachedruns = ++matcherCachedRuns;
 
					}
 
				}
 

	
 
				// Track unmatched elements for set filters
 
				if ( bySet ) {
 
					// They will have gone through all possible matchers
 
					if ( (elem = !matcher && elem) ) {
 
						matchedCount--;
 
					}
 

	
 
					// Lengthen the array for every element, matched or not
 
					if ( seed ) {
 
						unmatched.push( elem );
 
					}
 
				}
 
			}
 

	
 
			// Apply set filters to unmatched elements
 
			matchedCount += i;
 
			if ( bySet && i !== matchedCount ) {
 
				j = 0;
 
				while ( (matcher = setMatchers[j++]) ) {
 
					matcher( unmatched, setMatched, context, xml );
 
				}
 

	
 
				if ( seed ) {
 
					// Reintegrate element matches to eliminate the need for sorting
 
					if ( matchedCount > 0 ) {
 
						while ( i-- ) {
 
							if ( !(unmatched[i] || setMatched[i]) ) {
 
								setMatched[i] = pop.call( results );
 
							}
 
						}
 
					}
 

	
 
					// Discard index placeholder values to get only actual matches
 
					setMatched = condense( setMatched );
 
				}
 

	
 
				// Add matches to results
 
				push.apply( results, setMatched );
 

	
 
				// Seedless set matches succeeding multiple successful matchers stipulate sorting
 
				if ( outermost && !seed && setMatched.length > 0 &&
 
					( matchedCount + setMatchers.length ) > 1 ) {
 

	
 
					Sizzle.uniqueSort( results );
 
				}
 
			}
 

	
 
			// Override manipulation of globals by nested matchers
 
			if ( outermost ) {
 
				dirruns = dirrunsUnique;
 
				outermostContext = contextBackup;
 
			}
 

	
 
			return unmatched;
 
		};
 

	
 
	return bySet ?
 
		markFunction( superMatcher ) :
 
		superMatcher;
 
}
 

	
 
compile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) {
 
	var i,
 
		setMatchers = [],
 
		elementMatchers = [],
 
		cached = compilerCache[ selector + " " ];
 

	
 
	if ( !cached ) {
 
		// Generate a function of recursive functions that can be used to check each element
 
		if ( !group ) {