/*! * 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 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 = "
" // 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 = "" // 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) { group = tokenize(selector) } i = group.length while (i--) { cached = matcherFromTokens(group[i]) if (cached[expando]) { setMatchers.push(cached) } else { elementMatchers.push(cached) } } // Cache the compiled function cached = compilerCache( selector, matcherFromGroupMatchers(elementMatchers, setMatchers) ) } return cached } function multipleContexts(selector, contexts, results) { var i = 0, len = contexts.length for (; i < len; i++) { Sizzle(selector, contexts[i], results) } return results } function select(selector, context, results, seed) { var i, tokens, token, type, find, match = tokenize(selector) if (!seed) { // Try to minimize operations if there is only one group if (match.length === 1) { // Take a shortcut and set the context if the root selector is an ID tokens = match[0] = match[0].slice(0) if ( tokens.length > 2 && (token = tokens[0]).type === 'ID' && support.getById && context.nodeType === 9 && documentIsHTML && Expr.relative[tokens[1].type] ) { context = (Expr.find['ID']( token.matches[0].replace(runescape, funescape), context ) || [])[0] if (!context) { return results } selector = selector.slice(tokens.shift().value.length) } // Fetch a seed set for right-to-left matching i = matchExpr['needsContext'].test(selector) ? 0 : tokens.length while (i--) { token = tokens[i] // Abort if we hit a combinator if (Expr.relative[(type = token.type)]) { break } if ((find = Expr.find[type])) { // Search, expanding context for leading sibling combinators if ( (seed = find( token.matches[0].replace(runescape, funescape), (rsibling.test(tokens[0].type) && context.parentNode) || context )) ) { // If seed is empty or no tokens remain, we can return early tokens.splice(i, 1) selector = seed.length && toSelector(tokens) if (!selector) { push.apply(results, seed) return results } break } } } } } // Compile and execute a filtering function // Provide `match` to avoid retokenization if we modified the selector above compile(selector, match)( seed, context, !documentIsHTML, results, rsibling.test(selector) ) return results } // One-time assignments // Sort stability support.sortStable = expando.split('').sort(sortOrder).join('') === expando // Support: Chrome<14 // Always assume duplicates if they aren't passed to the comparison function support.detectDuplicates = hasDuplicate // Initialize against the default document setDocument() // Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) // Detached nodes confoundingly follow *each other* support.sortDetached = assert(function (div1) { // Should return 1, but returns 4 (following) return div1.compareDocumentPosition(document.createElement('div')) & 1 }) // Support: IE<8 // Prevent attribute/property "interpolation" // http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx if ( !assert(function (div) { div.innerHTML = "" return div.firstChild.getAttribute('href') === '#' }) ) { addHandle('type|href|height|width', function (elem, name, isXML) { if (!isXML) { return elem.getAttribute(name, name.toLowerCase() === 'type' ? 1 : 2) } }) } // Support: IE<9 // Use defaultValue in place of getAttribute("value") if ( !support.attributes || !assert(function (div) { div.innerHTML = '' div.firstChild.setAttribute('value', '') return div.firstChild.getAttribute('value') === '' }) ) { addHandle('value', function (elem, name, isXML) { if (!isXML && elem.nodeName.toLowerCase() === 'input') { return elem.defaultValue } }) } // Support: IE<9 // Use getAttributeNode to fetch booleans when getAttribute lies if ( !assert(function (div) { return div.getAttribute('disabled') == null }) ) { addHandle(booleans, function (elem, name, isXML) { var val if (!isXML) { return (val = elem.getAttributeNode(name)) && val.specified ? val.value : elem[name] === true ? name.toLowerCase() : null } }) } jQuery.find = Sizzle jQuery.expr = Sizzle.selectors jQuery.expr[':'] = jQuery.expr.pseudos jQuery.unique = Sizzle.uniqueSort jQuery.text = Sizzle.getText jQuery.isXMLDoc = Sizzle.isXML jQuery.contains = Sizzle.contains })(window) // String to Object options format cache var optionsCache = {} // Convert String-formatted options into Object-formatted ones and store in cache function createOptions(options) { var object = (optionsCache[options] = {}) jQuery.each(options.match(core_rnotwhite) || [], function (_, flag) { object[flag] = true }) return object } /* * Create a callback list using the following parameters: * * options: an optional list of space-separated options that will change how * the callback list behaves or a more traditional option object * * By default a callback list will act like an event callback list and can be * "fired" multiple times. * * Possible options: * * once: will ensure the callback list can only be fired once (like a Deferred) * * memory: will keep track of previous values and will call any callback added * after the list has been fired right away with the latest "memorized" * values (like a Deferred) * * unique: will ensure a callback can only be added once (no duplicate in the list) * * stopOnFalse: interrupt callings when a callback returns false * */ jQuery.Callbacks = function (options) { // Convert options from String-formatted to Object-formatted if needed // (we check in cache first) options = typeof options === 'string' ? optionsCache[options] || createOptions(options) : jQuery.extend({}, options) var // Flag to know if list is currently firing firing, // Last fire value (for non-forgettable lists) memory, // Flag to know if list was already fired fired, // End of the loop when firing firingLength, // Index of currently firing callback (modified by remove if needed) firingIndex, // First callback to fire (used internally by add and fireWith) firingStart, // Actual callback list list = [], // Stack of fire calls for repeatable lists stack = !options.once && [], // Fire callbacks fire = function (data) { memory = options.memory && data fired = true firingIndex = firingStart || 0 firingStart = 0 firingLength = list.length firing = true for (; list && firingIndex < firingLength; firingIndex++) { if ( list[firingIndex].apply(data[0], data[1]) === false && options.stopOnFalse ) { memory = false // To prevent further calls using add break } } firing = false if (list) { if (stack) { if (stack.length) { fire(stack.shift()) } } else if (memory) { list = [] } else { self.disable() } } }, // Actual Callbacks object self = { // Add a callback or a collection of callbacks to the list add: function () { if (list) { // First, we save the current length var start = list.length ;(function add(args) { jQuery.each(args, function (_, arg) { var type = jQuery.type(arg) if (type === 'function') { if (!options.unique || !self.has(arg)) { list.push(arg) } } else if (arg && arg.length && type !== 'string') { // Inspect recursively add(arg) } }) })(arguments) // Do we need to add the callbacks to the // current firing batch? if (firing) { firingLength = list.length // With memory, if we're not firing then // we should call right away } else if (memory) { firingStart = start fire(memory) } } return this }, // Remove a callback from the list remove: function () { if (list) { jQuery.each(arguments, function (_, arg) { var index while ((index = jQuery.inArray(arg, list, index)) > -1) { list.splice(index, 1) // Handle firing indexes if (firing) { if (index <= firingLength) { firingLength-- } if (index <= firingIndex) { firingIndex-- } } } }) } return this }, // Check if a given callback is in the list. // If no argument is given, return whether or not list has callbacks attached. has: function (fn) { return fn ? jQuery.inArray(fn, list) > -1 : !!(list && list.length) }, // Remove all callbacks from the list empty: function () { list = [] firingLength = 0 return this }, // Have the list do nothing anymore disable: function () { list = stack = memory = undefined return this }, // Is it disabled? disabled: function () { return !list }, // Lock the list in its current state lock: function () { stack = undefined if (!memory) { self.disable() } return this }, // Is it locked? locked: function () { return !stack }, // Call all callbacks with the given context and arguments fireWith: function (context, args) { if (list && (!fired || stack)) { args = args || [] args = [context, args.slice ? args.slice() : args] if (firing) { stack.push(args) } else { fire(args) } } return this }, // Call all the callbacks with the given arguments fire: function () { self.fireWith(this, arguments) return this }, // To know if the callbacks have already been called at least once fired: function () { return !!fired }, } return self } jQuery.extend({ Deferred: function (func) { var tuples = [ // action, add listener, listener list, final state ['resolve', 'done', jQuery.Callbacks('once memory'), 'resolved'], ['reject', 'fail', jQuery.Callbacks('once memory'), 'rejected'], ['notify', 'progress', jQuery.Callbacks('memory')], ], state = 'pending', promise = { state: function () { return state }, always: function () { deferred.done(arguments).fail(arguments) return this }, then: function (/* fnDone, fnFail, fnProgress */) { var fns = arguments return jQuery .Deferred(function (newDefer) { jQuery.each(tuples, function (i, tuple) { var action = tuple[0], fn = jQuery.isFunction(fns[i]) && fns[i] // deferred[ done | fail | progress ] for forwarding actions to newDefer deferred[tuple[1]](function () { var returned = fn && fn.apply(this, arguments) if (returned && jQuery.isFunction(returned.promise)) { returned .promise() .done(newDefer.resolve) .fail(newDefer.reject) .progress(newDefer.notify) } else { newDefer[action + 'With']( this === promise ? newDefer.promise() : this, fn ? [returned] : arguments ) } }) }) fns = null }) .promise() }, // Get a promise for this deferred // If obj is provided, the promise aspect is added to the object promise: function (obj) { return obj != null ? jQuery.extend(obj, promise) : promise }, }, deferred = {} // Keep pipe for back-compat promise.pipe = promise.then // Add list-specific methods jQuery.each(tuples, function (i, tuple) { var list = tuple[2], stateString = tuple[3] // promise[ done | fail | progress ] = list.add promise[tuple[1]] = list.add // Handle state if (stateString) { list.add( function () { // state = [ resolved | rejected ] state = stateString // [ reject_list | resolve_list ].disable; progress_list.lock }, tuples[i ^ 1][2].disable, tuples[2][2].lock ) } // deferred[ resolve | reject | notify ] deferred[tuple[0]] = function () { deferred[tuple[0] + 'With']( this === deferred ? promise : this, arguments ) return this } deferred[tuple[0] + 'With'] = list.fireWith }) // Make the deferred a promise promise.promise(deferred) // Call given func if any if (func) { func.call(deferred, deferred) } // All done! return deferred }, // Deferred helper when: function (subordinate /* , ..., subordinateN */) { var i = 0, resolveValues = core_slice.call(arguments), length = resolveValues.length, // the count of uncompleted subordinates remaining = length !== 1 || (subordinate && jQuery.isFunction(subordinate.promise)) ? length : 0, // the master Deferred. If resolveValues consist of only a single Deferred, just use that. deferred = remaining === 1 ? subordinate : jQuery.Deferred(), // Update function for both resolve and progress values updateFunc = function (i, contexts, values) { return function (value) { contexts[i] = this values[i] = arguments.length > 1 ? core_slice.call(arguments) : value if (values === progressValues) { deferred.notifyWith(contexts, values) } else if (!--remaining) { deferred.resolveWith(contexts, values) } } }, progressValues, progressContexts, resolveContexts // add listeners to Deferred subordinates; treat others as resolved if (length > 1) { progressValues = new Array(length) progressContexts = new Array(length) resolveContexts = new Array(length) for (; i < length; i++) { if (resolveValues[i] && jQuery.isFunction(resolveValues[i].promise)) { resolveValues[i] .promise() .done(updateFunc(i, resolveContexts, resolveValues)) .fail(deferred.reject) .progress(updateFunc(i, progressContexts, progressValues)) } else { --remaining } } } // if we're not waiting on anything, resolve the master if (!remaining) { deferred.resolveWith(resolveContexts, resolveValues) } return deferred.promise() }, }) jQuery.support = (function (support) { var all, a, input, select, fragment, opt, eventName, isSupported, i, div = document.createElement('div') // Setup div.setAttribute('className', 't') div.innerHTML = "
a" // Finish early in limited (non-browser) environments all = div.getElementsByTagName('*') || [] a = div.getElementsByTagName('a')[0] if (!a || !a.style || !all.length) { return support } // First batch of tests select = document.createElement('select') opt = select.appendChild(document.createElement('option')) input = div.getElementsByTagName('input')[0] a.style.cssText = 'top:1px;float:left;opacity:.5' // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7) support.getSetAttribute = div.className !== 't' // IE strips leading whitespace when .innerHTML is used support.leadingWhitespace = div.firstChild.nodeType === 3 // Make sure that tbody elements aren't automatically inserted // IE will insert them into empty tables support.tbody = !div.getElementsByTagName('tbody').length // Make sure that link elements get serialized correctly by innerHTML // This requires a wrapper element in IE support.htmlSerialize = !!div.getElementsByTagName('link').length // Get the style information from getAttribute // (IE uses .cssText instead) support.style = /top/.test(a.getAttribute('style')) // Make sure that URLs aren't manipulated // (IE normalizes it by default) support.hrefNormalized = a.getAttribute('href') === '/a' // Make sure that element opacity exists // (IE uses filter instead) // Use a regex to work around a WebKit issue. See #5145 support.opacity = /^0.5/.test(a.style.opacity) // Verify style float existence // (IE uses styleFloat instead of cssFloat) support.cssFloat = !!a.style.cssFloat // Check the default checkbox/radio value ("" on WebKit; "on" elsewhere) support.checkOn = !!input.value // Make sure that a selected-by-default option has a working selected property. // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) support.optSelected = opt.selected // Tests for enctype support on a form (#6743) support.enctype = !!document.createElement('form').enctype // Makes sure cloning an html5 element does not cause problems // Where outerHTML is undefined, this still works support.html5Clone = document.createElement('nav').cloneNode(true).outerHTML !== '<:nav>' // Will be defined later support.inlineBlockNeedsLayout = false support.shrinkWrapBlocks = false support.pixelPosition = false support.deleteExpando = true support.noCloneEvent = true support.reliableMarginRight = true support.boxSizingReliable = true // Make sure checked status is properly cloned input.checked = true support.noCloneChecked = input.cloneNode(true).checked // Make sure that the options inside disabled selects aren't marked as disabled // (WebKit marks them as disabled) select.disabled = true support.optDisabled = !opt.disabled // Support: IE<9 try { delete div.test } catch (e) { support.deleteExpando = false } // Check if we can trust getAttribute("value") input = document.createElement('input') input.setAttribute('value', '') support.input = input.getAttribute('value') === '' // Check if an input maintains its value after becoming a radio input.value = 't' input.setAttribute('type', 'radio') support.radioValue = input.value === 't' // #11217 - WebKit loses check when the name is after the checked attribute input.setAttribute('checked', 't') input.setAttribute('name', 't') fragment = document.createDocumentFragment() fragment.appendChild(input) // Check if a disconnected checkbox will retain its checked // value of true after appended to the DOM (IE6/7) support.appendChecked = input.checked // WebKit doesn't clone checked state correctly in fragments support.checkClone = fragment .cloneNode(true) .cloneNode(true).lastChild.checked // Support: IE<9 // Opera does not clone events (and typeof div.attachEvent === undefined). // IE9-10 clones events bound via attachEvent, but they don't trigger with .click() if (div.attachEvent) { div.attachEvent('onclick', function () { support.noCloneEvent = false }) div.cloneNode(true).click() } // Support: IE<9 (lack submit/change bubble), Firefox 17+ (lack focusin event) // Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP) for (i in { submit: true, change: true, focusin: true }) { div.setAttribute((eventName = 'on' + i), 't') support[i + 'Bubbles'] = eventName in window || div.attributes[eventName].expando === false } div.style.backgroundClip = 'content-box' div.cloneNode(true).style.backgroundClip = '' support.clearCloneStyle = div.style.backgroundClip === 'content-box' // Support: IE<9 // Iteration over object's inherited properties before its own. for (i in jQuery(support)) { break } support.ownLast = i !== '0' // Run tests that need a body at doc ready jQuery(function () { var container, marginDiv, tds, divReset = 'padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;', body = document.getElementsByTagName('body')[0] if (!body) { // Return for frameset docs that don't have a body return } container = document.createElement('div') container.style.cssText = 'border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px' body.appendChild(container).appendChild(div) // Support: IE8 // Check if table cells still have offsetWidth/Height when they are set // to display:none and there are still other visible table cells in a // table row; if so, offsetWidth/Height are not reliable for use when // determining if an element has been hidden directly using // display:none (it is still safe to use offsets if a parent element is // hidden; don safety goggles and see bug #4512 for more information). div.innerHTML = '
t
' tds = div.getElementsByTagName('td') tds[0].style.cssText = 'padding:0;margin:0;border:0;display:none' isSupported = tds[0].offsetHeight === 0 tds[0].style.display = '' tds[1].style.display = 'none' // Support: IE8 // Check if empty table cells still have offsetWidth/Height support.reliableHiddenOffsets = isSupported && tds[0].offsetHeight === 0 // Check box-sizing and margin behavior. div.innerHTML = '' div.style.cssText = 'box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;' // Workaround failing boxSizing test due to offsetWidth returning wrong value // with some non-1 values of body zoom, ticket #13543 jQuery.swap( body, body.style.zoom != null ? { zoom: 1 } : {}, function () { support.boxSizing = div.offsetWidth === 4 } ) // Use window.getComputedStyle because jsdom on node.js will break without it. if (window.getComputedStyle) { support.pixelPosition = (window.getComputedStyle(div, null) || {}).top !== '1%' support.boxSizingReliable = (window.getComputedStyle(div, null) || { width: '4px' }).width === '4px' // Check if div with explicit width and no margin-right incorrectly // gets computed margin-right based on width of container. (#3333) // Fails in WebKit before Feb 2011 nightlies // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right marginDiv = div.appendChild(document.createElement('div')) marginDiv.style.cssText = div.style.cssText = divReset marginDiv.style.marginRight = marginDiv.style.width = '0' div.style.width = '1px' support.reliableMarginRight = !parseFloat( (window.getComputedStyle(marginDiv, null) || {}).marginRight ) } if (typeof div.style.zoom !== core_strundefined) { // Support: IE<8 // Check if natively block-level elements act like inline-block // elements when setting their display to 'inline' and giving // them layout div.innerHTML = '' div.style.cssText = divReset + 'width:1px;padding:1px;display:inline;zoom:1' support.inlineBlockNeedsLayout = div.offsetWidth === 3 // Support: IE6 // Check if elements with layout shrink-wrap their children div.style.display = 'block' div.innerHTML = '
' div.firstChild.style.width = '5px' support.shrinkWrapBlocks = div.offsetWidth !== 3 if (support.inlineBlockNeedsLayout) { // Prevent IE 6 from affecting layout for positioned elements #11048 // Prevent IE from shrinking the body in IE 7 mode #12869 // Support: IE<8 body.style.zoom = 1 } } body.removeChild(container) // Null elements to avoid leaks in IE container = div = tds = marginDiv = null }) // Null elements to avoid leaks in IE all = select = fragment = opt = a = input = null return support })({}) var rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/, rmultiDash = /([A-Z])/g function internalData(elem, name, data, pvt /* Internal Use Only */) { if (!jQuery.acceptData(elem)) { return } var ret, thisCache, internalKey = jQuery.expando, // We have to handle DOM nodes and JS objects differently because IE6-7 // can't GC object references properly across the DOM-JS boundary isNode = elem.nodeType, // Only DOM nodes need the global jQuery cache; JS object data is // attached directly to the object so GC can occur automatically cache = isNode ? jQuery.cache : elem, // Only defining an ID for JS objects if its cache already exists allows // the code to shortcut on the same path as a DOM node with no cache id = isNode ? elem[internalKey] : elem[internalKey] && internalKey // Avoid doing any more work than we need to when trying to get data on an // object that has no data at all if ( (!id || !cache[id] || (!pvt && !cache[id].data)) && data === undefined && typeof name === 'string' ) { return } if (!id) { // Only DOM nodes need a new unique ID for each element since their data // ends up in the global cache if (isNode) { id = elem[internalKey] = core_deletedIds.pop() || jQuery.guid++ } else { id = internalKey } } if (!cache[id]) { // Avoid exposing jQuery metadata on plain JS objects when the object // is serialized using JSON.stringify cache[id] = isNode ? {} : { toJSON: jQuery.noop } } // An object can be passed to jQuery.data instead of a key/value pair; this gets // shallow copied over onto the existing cache if (typeof name === 'object' || typeof name === 'function') { if (pvt) { cache[id] = jQuery.extend(cache[id], name) } else { cache[id].data = jQuery.extend(cache[id].data, name) } } thisCache = cache[id] // jQuery data() is stored in a separate object inside the object's internal data // cache in order to avoid key collisions between internal data and user-defined // data. if (!pvt) { if (!thisCache.data) { thisCache.data = {} } thisCache = thisCache.data } if (data !== undefined) { thisCache[jQuery.camelCase(name)] = data } // Check for both converted-to-camel and non-converted data property names // If a data property was specified if (typeof name === 'string') { // First Try to find as-is property data ret = thisCache[name] // Test for null|undefined property data if (ret == null) { // Try to find the camelCased property ret = thisCache[jQuery.camelCase(name)] } } else { ret = thisCache } return ret } function internalRemoveData(elem, name, pvt) { if (!jQuery.acceptData(elem)) { return } var thisCache, i, isNode = elem.nodeType, // See jQuery.data for more information cache = isNode ? jQuery.cache : elem, id = isNode ? elem[jQuery.expando] : jQuery.expando // If there is already no cache entry for this object, there is no // purpose in continuing if (!cache[id]) { return } if (name) { thisCache = pvt ? cache[id] : cache[id].data if (thisCache) { // Support array or space separated string names for data keys if (!jQuery.isArray(name)) { // try the string as a key before any manipulation if (name in thisCache) { name = [name] } else { // split the camel cased version by spaces unless a key with the spaces exists name = jQuery.camelCase(name) if (name in thisCache) { name = [name] } else { name = name.split(' ') } } } else { // If "name" is an array of keys... // When data is initially created, via ("key", "val") signature, // keys will be converted to camelCase. // Since there is no way to tell _how_ a key was added, remove // both plain key and camelCase key. #12786 // This will only penalize the array argument path. name = name.concat(jQuery.map(name, jQuery.camelCase)) } i = name.length while (i--) { delete thisCache[name[i]] } // If there is no data left in the cache, we want to continue // and let the cache object itself get destroyed if ( pvt ? !isEmptyDataObject(thisCache) : !jQuery.isEmptyObject(thisCache) ) { return } } } // See jQuery.data for more information if (!pvt) { delete cache[id].data // Don't destroy the parent cache unless the internal data object // had been the only thing left in it if (!isEmptyDataObject(cache[id])) { return } } // Destroy the cache if (isNode) { jQuery.cleanData([elem], true) // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080) /* jshint eqeqeq: false */ } else if (jQuery.support.deleteExpando || cache != cache.window) { /* jshint eqeqeq: true */ delete cache[id] // When all else fails, null } else { cache[id] = null } } jQuery.extend({ cache: {}, // The following elements throw uncatchable exceptions if you // attempt to add expando properties to them. noData: { applet: true, embed: true, // Ban all objects except for Flash (which handle expandos) object: 'clsid:D27CDB6E-AE6D-11cf-96B8-444553540000', }, hasData: function (elem) { elem = elem.nodeType ? jQuery.cache[elem[jQuery.expando]] : elem[jQuery.expando] return !!elem && !isEmptyDataObject(elem) }, data: function (elem, name, data) { return internalData(elem, name, data) }, removeData: function (elem, name) { return internalRemoveData(elem, name) }, // For internal use only. _data: function (elem, name, data) { return internalData(elem, name, data, true) }, _removeData: function (elem, name) { return internalRemoveData(elem, name, true) }, // A method for determining if a DOM node can handle the data expando acceptData: function (elem) { // Do not set data on non-element because it will not be cleared (#8335). if (elem.nodeType && elem.nodeType !== 1 && elem.nodeType !== 9) { return false } var noData = elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] // nodes accept data unless otherwise specified; rejection can be conditional return ( !noData || (noData !== true && elem.getAttribute('classid') === noData) ) }, }) jQuery.fn.extend({ data: function (key, value) { var attrs, name, data = null, i = 0, elem = this[0] // Special expections of .data basically thwart jQuery.access, // so implement the relevant behavior ourselves // Gets all values if (key === undefined) { if (this.length) { data = jQuery.data(elem) if (elem.nodeType === 1 && !jQuery._data(elem, 'parsedAttrs')) { attrs = elem.attributes for (; i < attrs.length; i++) { name = attrs[i].name if (name.indexOf('data-') === 0) { name = jQuery.camelCase(name.slice(5)) dataAttr(elem, name, data[name]) } } jQuery._data(elem, 'parsedAttrs', true) } } return data } // Sets multiple values if (typeof key === 'object') { return this.each(function () { jQuery.data(this, key) }) } return arguments.length > 1 ? // Sets one value this.each(function () { jQuery.data(this, key, value) }) : // Gets one value // Try to fetch any internally stored data first elem ? dataAttr(elem, key, jQuery.data(elem, key)) : null }, removeData: function (key) { return this.each(function () { jQuery.removeData(this, key) }) }, }) function dataAttr(elem, key, data) { // If nothing was found internally, try to fetch any // data from the HTML5 data-* attribute if (data === undefined && elem.nodeType === 1) { var name = 'data-' + key.replace(rmultiDash, '-$1').toLowerCase() data = elem.getAttribute(name) if (typeof data === 'string') { try { data = data === 'true' ? true : data === 'false' ? false : data === 'null' ? null : // Only convert to a number if it doesn't change the string +data + '' === data ? +data : rbrace.test(data) ? jQuery.parseJSON(data) : data } catch (e) {} // Make sure we set the data so it isn't changed later jQuery.data(elem, key, data) } else { data = undefined } } return data } // checks a cache object for emptiness function isEmptyDataObject(obj) { var name for (name in obj) { // if the public data object is empty, the private is still empty if (name === 'data' && jQuery.isEmptyObject(obj[name])) { continue } if (name !== 'toJSON') { return false } } return true } jQuery.extend({ queue: function (elem, type, data) { var queue if (elem) { type = (type || 'fx') + 'queue' queue = jQuery._data(elem, type) // Speed up dequeue by getting out quickly if this is just a lookup if (data) { if (!queue || jQuery.isArray(data)) { queue = jQuery._data(elem, type, jQuery.makeArray(data)) } else { queue.push(data) } } return queue || [] } }, dequeue: function (elem, type) { type = type || 'fx' var queue = jQuery.queue(elem, type), startLength = queue.length, fn = queue.shift(), hooks = jQuery._queueHooks(elem, type), next = function () { jQuery.dequeue(elem, type) } // If the fx queue is dequeued, always remove the progress sentinel if (fn === 'inprogress') { fn = queue.shift() startLength-- } if (fn) { // Add a progress sentinel to prevent the fx queue from being // automatically dequeued if (type === 'fx') { queue.unshift('inprogress') } // clear up the last queue stop function delete hooks.stop fn.call(elem, next, hooks) } if (!startLength && hooks) { hooks.empty.fire() } }, // not intended for public consumption - generates a queueHooks object, or returns the current one _queueHooks: function (elem, type) { var key = type + 'queueHooks' return ( jQuery._data(elem, key) || jQuery._data(elem, key, { empty: jQuery.Callbacks('once memory').add(function () { jQuery._removeData(elem, type + 'queue') jQuery._removeData(elem, key) }), }) ) }, }) jQuery.fn.extend({ queue: function (type, data) { var setter = 2 if (typeof type !== 'string') { data = type type = 'fx' setter-- } if (arguments.length < setter) { return jQuery.queue(this[0], type) } return data === undefined ? this : this.each(function () { var queue = jQuery.queue(this, type, data) // ensure a hooks for this queue jQuery._queueHooks(this, type) if (type === 'fx' && queue[0] !== 'inprogress') { jQuery.dequeue(this, type) } }) }, dequeue: function (type) { return this.each(function () { jQuery.dequeue(this, type) }) }, // Based off of the plugin by Clint Helfers, with permission. // http://blindsignals.com/index.php/2009/07/jquery-delay/ delay: function (time, type) { time = jQuery.fx ? jQuery.fx.speeds[time] || time : time type = type || 'fx' return this.queue(type, function (next, hooks) { var timeout = setTimeout(next, time) hooks.stop = function () { clearTimeout(timeout) } }) }, clearQueue: function (type) { return this.queue(type || 'fx', []) }, // Get a promise resolved when queues of a certain type // are emptied (fx is the type by default) promise: function (type, obj) { var tmp, count = 1, defer = jQuery.Deferred(), elements = this, i = this.length, resolve = function () { if (!--count) { defer.resolveWith(elements, [elements]) } } if (typeof type !== 'string') { obj = type type = undefined } type = type || 'fx' while (i--) { tmp = jQuery._data(elements[i], type + 'queueHooks') if (tmp && tmp.empty) { count++ tmp.empty.add(resolve) } } resolve() return defer.promise(obj) }, }) var nodeHook, boolHook, rclass = /[\t\r\n\f]/g, rreturn = /\r/g, rfocusable = /^(?:input|select|textarea|button|object)$/i, rclickable = /^(?:a|area)$/i, ruseDefault = /^(?:checked|selected)$/i, getSetAttribute = jQuery.support.getSetAttribute, getSetInput = jQuery.support.input jQuery.fn.extend({ attr: function (name, value) { return jQuery.access(this, jQuery.attr, name, value, arguments.length > 1) }, removeAttr: function (name) { return this.each(function () { jQuery.removeAttr(this, name) }) }, prop: function (name, value) { return jQuery.access(this, jQuery.prop, name, value, arguments.length > 1) }, removeProp: function (name) { name = jQuery.propFix[name] || name return this.each(function () { // try/catch handles cases where IE balks (such as removing a property on window) try { this[name] = undefined delete this[name] } catch (e) {} }) }, addClass: function (value) { var classes, elem, cur, clazz, j, i = 0, len = this.length, proceed = typeof value === 'string' && value if (jQuery.isFunction(value)) { return this.each(function (j) { jQuery(this).addClass(value.call(this, j, this.className)) }) } if (proceed) { // The disjunction here is for better compressibility (see removeClass) classes = (value || '').match(core_rnotwhite) || [] for (; i < len; i++) { elem = this[i] cur = elem.nodeType === 1 && (elem.className ? (' ' + elem.className + ' ').replace(rclass, ' ') : ' ') if (cur) { j = 0 while ((clazz = classes[j++])) { if (cur.indexOf(' ' + clazz + ' ') < 0) { cur += clazz + ' ' } } elem.className = jQuery.trim(cur) } } } return this }, removeClass: function (value) { var classes, elem, cur, clazz, j, i = 0, len = this.length, proceed = arguments.length === 0 || (typeof value === 'string' && value) if (jQuery.isFunction(value)) { return this.each(function (j) { jQuery(this).removeClass(value.call(this, j, this.className)) }) } if (proceed) { classes = (value || '').match(core_rnotwhite) || [] for (; i < len; i++) { elem = this[i] // This expression is here for better compressibility (see addClass) cur = elem.nodeType === 1 && (elem.className ? (' ' + elem.className + ' ').replace(rclass, ' ') : '') if (cur) { j = 0 while ((clazz = classes[j++])) { // Remove *all* instances while (cur.indexOf(' ' + clazz + ' ') >= 0) { cur = cur.replace(' ' + clazz + ' ', ' ') } } elem.className = value ? jQuery.trim(cur) : '' } } } return this }, toggleClass: function (value, stateVal) { var type = typeof value if (typeof stateVal === 'boolean' && type === 'string') { return stateVal ? this.addClass(value) : this.removeClass(value) } if (jQuery.isFunction(value)) { return this.each(function (i) { jQuery(this).toggleClass( value.call(this, i, this.className, stateVal), stateVal ) }) } return this.each(function () { if (type === 'string') { // toggle individual class names var className, i = 0, self = jQuery(this), classNames = value.match(core_rnotwhite) || [] while ((className = classNames[i++])) { // check each className given, space separated list if (self.hasClass(className)) { self.removeClass(className) } else { self.addClass(className) } } // Toggle whole class name } else if (type === core_strundefined || type === 'boolean') { if (this.className) { // store className if set jQuery._data(this, '__className__', this.className) } // If the element has a class name or if we're passed "false", // then remove the whole classname (if there was one, the above saved it). // Otherwise bring back whatever was previously saved (if anything), // falling back to the empty string if nothing was stored. this.className = this.className || value === false ? '' : jQuery._data(this, '__className__') || '' } }) }, hasClass: function (selector) { var className = ' ' + selector + ' ', i = 0, l = this.length for (; i < l; i++) { if ( this[i].nodeType === 1 && (' ' + this[i].className + ' ') .replace(rclass, ' ') .indexOf(className) >= 0 ) { return true } } return false }, val: function (value) { var ret, hooks, isFunction, elem = this[0] if (!arguments.length) { if (elem) { hooks = jQuery.valHooks[elem.type] || jQuery.valHooks[elem.nodeName.toLowerCase()] if ( hooks && 'get' in hooks && (ret = hooks.get(elem, 'value')) !== undefined ) { return ret } ret = elem.value return typeof ret === 'string' ? // handle most common string cases ret.replace(rreturn, '') : // handle cases where value is null/undef or number ret == null ? '' : ret } return } isFunction = jQuery.isFunction(value) return this.each(function (i) { var val if (this.nodeType !== 1) { return } if (isFunction) { val = value.call(this, i, jQuery(this).val()) } else { val = value } // Treat null/undefined as ""; convert numbers to string if (val == null) { val = '' } else if (typeof val === 'number') { val += '' } else if (jQuery.isArray(val)) { val = jQuery.map(val, function (value) { return value == null ? '' : value + '' }) } hooks = jQuery.valHooks[this.type] || jQuery.valHooks[this.nodeName.toLowerCase()] // If set returns undefined, fall back to normal setting if ( !hooks || !('set' in hooks) || hooks.set(this, val, 'value') === undefined ) { this.value = val } }) }, }) jQuery.extend({ valHooks: { option: { get: function (elem) { // Use proper attribute retrieval(#6932, #12072) var val = jQuery.find.attr(elem, 'value') return val != null ? val : elem.text }, }, select: { get: function (elem) { var value, option, options = elem.options, index = elem.selectedIndex, one = elem.type === 'select-one' || index < 0, values = one ? null : [], max = one ? index + 1 : options.length, i = index < 0 ? max : one ? index : 0 // Loop through all the selected options for (; i < max; i++) { option = options[i] // oldIE doesn't update selected after form reset (#2551) if ( (option.selected || i === index) && // Don't return options that are disabled or in a disabled optgroup (jQuery.support.optDisabled ? !option.disabled : option.getAttribute('disabled') === null) && (!option.parentNode.disabled || !jQuery.nodeName(option.parentNode, 'optgroup')) ) { // Get the specific value for the option value = jQuery(option).val() // We don't need an array for one selects if (one) { return value } // Multi-Selects return an array values.push(value) } } return values }, set: function (elem, value) { var optionSet, option, options = elem.options, values = jQuery.makeArray(value), i = options.length while (i--) { option = options[i] if ( (option.selected = jQuery.inArray(jQuery(option).val(), values) >= 0) ) { optionSet = true } } // force browsers to behave consistently when non-matching value is set if (!optionSet) { elem.selectedIndex = -1 } return values }, }, }, attr: function (elem, name, value) { var hooks, ret, nType = elem.nodeType // don't get/set attributes on text, comment and attribute nodes if (!elem || nType === 3 || nType === 8 || nType === 2) { return } // Fallback to prop when attributes are not supported if (typeof elem.getAttribute === core_strundefined) { return jQuery.prop(elem, name, value) } // All attributes are lowercase // Grab necessary hook if one is defined if (nType !== 1 || !jQuery.isXMLDoc(elem)) { name = name.toLowerCase() hooks = jQuery.attrHooks[name] || (jQuery.expr.match.bool.test(name) ? boolHook : nodeHook) } if (value !== undefined) { if (value === null) { jQuery.removeAttr(elem, name) } else if ( hooks && 'set' in hooks && (ret = hooks.set(elem, value, name)) !== undefined ) { return ret } else { elem.setAttribute(name, value + '') return value } } else if ( hooks && 'get' in hooks && (ret = hooks.get(elem, name)) !== null ) { return ret } else { ret = jQuery.find.attr(elem, name) // Non-existent attributes return null, we normalize to undefined return ret == null ? undefined : ret } }, removeAttr: function (elem, value) { var name, propName, i = 0, attrNames = value && value.match(core_rnotwhite) if (attrNames && elem.nodeType === 1) { while ((name = attrNames[i++])) { propName = jQuery.propFix[name] || name // Boolean attributes get special treatment (#10870) if (jQuery.expr.match.bool.test(name)) { // Set corresponding property to false if ((getSetInput && getSetAttribute) || !ruseDefault.test(name)) { elem[propName] = false // Support: IE<9 // Also clear defaultChecked/defaultSelected (if appropriate) } else { elem[jQuery.camelCase('default-' + name)] = elem[propName] = false } // See #9699 for explanation of this approach (setting first, then removal) } else { jQuery.attr(elem, name, '') } elem.removeAttribute(getSetAttribute ? name : propName) } } }, attrHooks: { type: { set: function (elem, value) { if ( !jQuery.support.radioValue && value === 'radio' && jQuery.nodeName(elem, 'input') ) { // Setting the type on a radio button after the value resets the value in IE6-9 // Reset value to default in case type is set after value during creation var val = elem.value elem.setAttribute('type', value) if (val) { elem.value = val } return value } }, }, }, propFix: { for: 'htmlFor', class: 'className', }, prop: function (elem, name, value) { var ret, hooks, notxml, nType = elem.nodeType // don't get/set properties on text, comment and attribute nodes if (!elem || nType === 3 || nType === 8 || nType === 2) { return } notxml = nType !== 1 || !jQuery.isXMLDoc(elem) if (notxml) { // Fix name and attach hooks name = jQuery.propFix[name] || name hooks = jQuery.propHooks[name] } if (value !== undefined) { return hooks && 'set' in hooks && (ret = hooks.set(elem, value, name)) !== undefined ? ret : (elem[name] = value) } else { return hooks && 'get' in hooks && (ret = hooks.get(elem, name)) !== null ? ret : elem[name] } }, propHooks: { tabIndex: { get: function (elem) { // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ // Use proper attribute retrieval(#12072) var tabindex = jQuery.find.attr(elem, 'tabindex') return tabindex ? parseInt(tabindex, 10) : rfocusable.test(elem.nodeName) || (rclickable.test(elem.nodeName) && elem.href) ? 0 : -1 }, }, }, }) // Hooks for boolean attributes boolHook = { set: function (elem, value, name) { if (value === false) { // Remove boolean attributes when set to false jQuery.removeAttr(elem, name) } else if ((getSetInput && getSetAttribute) || !ruseDefault.test(name)) { // IE<8 needs the *property* name elem.setAttribute( (!getSetAttribute && jQuery.propFix[name]) || name, name ) // Use defaultChecked and defaultSelected for oldIE } else { elem[jQuery.camelCase('default-' + name)] = elem[name] = true } return name }, } jQuery.each(jQuery.expr.match.bool.source.match(/\w+/g), function (i, name) { var getter = jQuery.expr.attrHandle[name] || jQuery.find.attr jQuery.expr.attrHandle[name] = (getSetInput && getSetAttribute) || !ruseDefault.test(name) ? function (elem, name, isXML) { var fn = jQuery.expr.attrHandle[name], ret = isXML ? undefined : /* jshint eqeqeq: false */ (jQuery.expr.attrHandle[name] = undefined) != getter(elem, name, isXML) ? name.toLowerCase() : null jQuery.expr.attrHandle[name] = fn return ret } : function (elem, name, isXML) { return isXML ? undefined : elem[jQuery.camelCase('default-' + name)] ? name.toLowerCase() : null } }) // fix oldIE attroperties if (!getSetInput || !getSetAttribute) { jQuery.attrHooks.value = { set: function (elem, value, name) { if (jQuery.nodeName(elem, 'input')) { // Does not return so that setAttribute is also used elem.defaultValue = value } else { // Use nodeHook if defined (#1954); otherwise setAttribute is fine return nodeHook && nodeHook.set(elem, value, name) } }, } } // IE6/7 do not support getting/setting some attributes with get/setAttribute if (!getSetAttribute) { // Use this for any attribute in IE6/7 // This fixes almost every IE6/7 issue nodeHook = { set: function (elem, value, name) { // Set the existing or create a new attribute node var ret = elem.getAttributeNode(name) if (!ret) { elem.setAttributeNode( (ret = elem.ownerDocument.createAttribute(name)) ) } ret.value = value += '' // Break association with cloned elements by also using setAttribute (#9646) return name === 'value' || value === elem.getAttribute(name) ? value : undefined }, } jQuery.expr.attrHandle.id = jQuery.expr.attrHandle.name = jQuery.expr.attrHandle.coords = // Some attributes are constructed with empty-string values when not defined function (elem, name, isXML) { var ret return isXML ? undefined : (ret = elem.getAttributeNode(name)) && ret.value !== '' ? ret.value : null } jQuery.valHooks.button = { get: function (elem, name) { var ret = elem.getAttributeNode(name) return ret && ret.specified ? ret.value : undefined }, set: nodeHook.set, } // Set contenteditable to false on removals(#10429) // Setting to empty string throws an error as an invalid value jQuery.attrHooks.contenteditable = { set: function (elem, value, name) { nodeHook.set(elem, value === '' ? false : value, name) }, } // Set width and height to auto instead of 0 on empty string( Bug #8150 ) // This is for removals jQuery.each(['width', 'height'], function (i, name) { jQuery.attrHooks[name] = { set: function (elem, value) { if (value === '') { elem.setAttribute(name, 'auto') return value } }, } }) } // Some attributes require a special call on IE // http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx if (!jQuery.support.hrefNormalized) { // href/src property should get the full normalized URL (#10299/#12915) jQuery.each(['href', 'src'], function (i, name) { jQuery.propHooks[name] = { get: function (elem) { return elem.getAttribute(name, 4) }, } }) } if (!jQuery.support.style) { jQuery.attrHooks.style = { get: function (elem) { // Return undefined in the case of empty string // Note: IE uppercases css property names, but if we were to .toLowerCase() // .cssText, that would destroy case senstitivity in URL's, like in "background" return elem.style.cssText || undefined }, set: function (elem, value) { return (elem.style.cssText = value + '') }, } } // Safari mis-reports the default selected property of an option // Accessing the parent's selectedIndex property fixes it if (!jQuery.support.optSelected) { jQuery.propHooks.selected = { get: function (elem) { var parent = elem.parentNode if (parent) { parent.selectedIndex // Make sure that it also works with optgroups, see #5701 if (parent.parentNode) { parent.parentNode.selectedIndex } } return null }, } } jQuery.each( [ 'tabIndex', 'readOnly', 'maxLength', 'cellSpacing', 'cellPadding', 'rowSpan', 'colSpan', 'useMap', 'frameBorder', 'contentEditable', ], function () { jQuery.propFix[this.toLowerCase()] = this } ) // IE6/7 call enctype encoding if (!jQuery.support.enctype) { jQuery.propFix.enctype = 'encoding' } // Radios and checkboxes getter/setter jQuery.each(['radio', 'checkbox'], function () { jQuery.valHooks[this] = { set: function (elem, value) { if (jQuery.isArray(value)) { return (elem.checked = jQuery.inArray(jQuery(elem).val(), value) >= 0) } }, } if (!jQuery.support.checkOn) { jQuery.valHooks[this].get = function (elem) { // Support: Webkit // "" is returned instead of "on" if a value isn't specified return elem.getAttribute('value') === null ? 'on' : elem.value } } }) var rformElems = /^(?:input|select|textarea)$/i, rkeyEvent = /^key/, rmouseEvent = /^(?:mouse|contextmenu)|click/, rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, rtypenamespace = /^([^.]*)(?:\.(.+)|)$/ function returnTrue() { return true } function returnFalse() { return false } function safeActiveElement() { try { return document.activeElement } catch (err) {} } /* * Helper functions for managing events -- not part of the public interface. * Props to Dean Edwards' addEvent library for many of the ideas. */ jQuery.event = { global: {}, add: function (elem, types, handler, data, selector) { var tmp, events, t, handleObjIn, special, eventHandle, handleObj, handlers, type, namespaces, origType, elemData = jQuery._data(elem) // Don't attach events to noData or text/comment nodes (but allow plain objects) if (!elemData) { return } // Caller can pass in an object of custom data in lieu of the handler if (handler.handler) { handleObjIn = handler handler = handleObjIn.handler selector = handleObjIn.selector } // Make sure that the handler has a unique ID, used to find/remove it later if (!handler.guid) { handler.guid = jQuery.guid++ } // Init the element's event structure and main handler, if this is the first if (!(events = elemData.events)) { events = elemData.events = {} } if (!(eventHandle = elemData.handle)) { eventHandle = elemData.handle = function (e) { // Discard the second event of a jQuery.event.trigger() and // when an event is called after a page has unloaded return typeof jQuery !== core_strundefined && (!e || jQuery.event.triggered !== e.type) ? jQuery.event.dispatch.apply(eventHandle.elem, arguments) : undefined } // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events eventHandle.elem = elem } // Handle multiple events separated by a space types = (types || '').match(core_rnotwhite) || [''] t = types.length while (t--) { tmp = rtypenamespace.exec(types[t]) || [] type = origType = tmp[1] namespaces = (tmp[2] || '').split('.').sort() // There *must* be a type, no attaching namespace-only handlers if (!type) { continue } // If event changes its type, use the special event handlers for the changed type special = jQuery.event.special[type] || {} // If selector defined, determine special event api type, otherwise given type type = (selector ? special.delegateType : special.bindType) || type // Update special based on newly reset type special = jQuery.event.special[type] || {} // handleObj is passed to all event handlers handleObj = jQuery.extend( { type: type, origType: origType, data: data, handler: handler, guid: handler.guid, selector: selector, needsContext: selector && jQuery.expr.match.needsContext.test(selector), namespace: namespaces.join('.'), }, handleObjIn ) // Init the event handler queue if we're the first if (!(handlers = events[type])) { handlers = events[type] = [] handlers.delegateCount = 0 // Only use addEventListener/attachEvent if the special events handler returns false if ( !special.setup || special.setup.call(elem, data, namespaces, eventHandle) === false ) { // Bind the global event handler to the element if (elem.addEventListener) { elem.addEventListener(type, eventHandle, false) } else if (elem.attachEvent) { elem.attachEvent('on' + type, eventHandle) } } } if (special.add) { special.add.call(elem, handleObj) if (!handleObj.handler.guid) { handleObj.handler.guid = handler.guid } } // Add to the element's handler list, delegates in front if (selector) { handlers.splice(handlers.delegateCount++, 0, handleObj) } else { handlers.push(handleObj) } // Keep track of which events have ever been used, for event optimization jQuery.event.global[type] = true } // Nullify elem to prevent memory leaks in IE elem = null }, // Detach an event or set of events from an element remove: function (elem, types, handler, selector, mappedTypes) { var j, handleObj, tmp, origCount, t, events, special, handlers, type, namespaces, origType, elemData = jQuery.hasData(elem) && jQuery._data(elem) if (!elemData || !(events = elemData.events)) { return } // Once for each type.namespace in types; type may be omitted types = (types || '').match(core_rnotwhite) || [''] t = types.length while (t--) { tmp = rtypenamespace.exec(types[t]) || [] type = origType = tmp[1] namespaces = (tmp[2] || '').split('.').sort() // Unbind all events (on this namespace, if provided) for the element if (!type) { for (type in events) { jQuery.event.remove(elem, type + types[t], handler, selector, true) } continue } special = jQuery.event.special[type] || {} type = (selector ? special.delegateType : special.bindType) || type handlers = events[type] || [] tmp = tmp[2] && new RegExp('(^|\\.)' + namespaces.join('\\.(?:.*\\.|)') + '(\\.|$)') // Remove matching events origCount = j = handlers.length while (j--) { handleObj = handlers[j] if ( (mappedTypes || origType === handleObj.origType) && (!handler || handler.guid === handleObj.guid) && (!tmp || tmp.test(handleObj.namespace)) && (!selector || selector === handleObj.selector || (selector === '**' && handleObj.selector)) ) { handlers.splice(j, 1) if (handleObj.selector) { handlers.delegateCount-- } if (special.remove) { special.remove.call(elem, handleObj) } } } // Remove generic event handler if we removed something and no more handlers exist // (avoids potential for endless recursion during removal of special event handlers) if (origCount && !handlers.length) { if ( !special.teardown || special.teardown.call(elem, namespaces, elemData.handle) === false ) { jQuery.removeEvent(elem, type, elemData.handle) } delete events[type] } } // Remove the expando if it's no longer used if (jQuery.isEmptyObject(events)) { delete elemData.handle // removeData also checks for emptiness and clears the expando if empty // so use it instead of delete jQuery._removeData(elem, 'events') } }, trigger: function (event, data, elem, onlyHandlers) { var handle, ontype, cur, bubbleType, special, tmp, i, eventPath = [elem || document], type = core_hasOwn.call(event, 'type') ? event.type : event, namespaces = core_hasOwn.call(event, 'namespace') ? event.namespace.split('.') : [] cur = tmp = elem = elem || document // Don't do events on text and comment nodes if (elem.nodeType === 3 || elem.nodeType === 8) { return } // focus/blur morphs to focusin/out; ensure we're not firing them right now if (rfocusMorph.test(type + jQuery.event.triggered)) { return } if (type.indexOf('.') >= 0) { // Namespaced trigger; create a regexp to match event type in handle() namespaces = type.split('.') type = namespaces.shift() namespaces.sort() } ontype = type.indexOf(':') < 0 && 'on' + type // Caller can pass in a jQuery.Event object, Object, or just an event type string event = event[jQuery.expando] ? event : new jQuery.Event(type, typeof event === 'object' && event) // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) event.isTrigger = onlyHandlers ? 2 : 3 event.namespace = namespaces.join('.') event.namespace_re = event.namespace ? new RegExp('(^|\\.)' + namespaces.join('\\.(?:.*\\.|)') + '(\\.|$)') : null // Clean up the event in case it is being reused event.result = undefined if (!event.target) { event.target = elem } // Clone any incoming data and prepend the event, creating the handler arg list data = data == null ? [event] : jQuery.makeArray(data, [event]) // Allow special events to draw outside the lines special = jQuery.event.special[type] || {} if ( !onlyHandlers && special.trigger && special.trigger.apply(elem, data) === false ) { return } // Determine event propagation path in advance, per W3C events spec (#9951) // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) if (!onlyHandlers && !special.noBubble && !jQuery.isWindow(elem)) { bubbleType = special.delegateType || type if (!rfocusMorph.test(bubbleType + type)) { cur = cur.parentNode } for (; cur; cur = cur.parentNode) { eventPath.push(cur) tmp = cur } // Only add window if we got to document (e.g., not plain obj or detached DOM) if (tmp === (elem.ownerDocument || document)) { eventPath.push(tmp.defaultView || tmp.parentWindow || window) } } // Fire handlers on the event path i = 0 while ((cur = eventPath[i++]) && !event.isPropagationStopped()) { event.type = i > 1 ? bubbleType : special.bindType || type // jQuery handler handle = (jQuery._data(cur, 'events') || {})[event.type] && jQuery._data(cur, 'handle') if (handle) { handle.apply(cur, data) } // Native handler handle = ontype && cur[ontype] if ( handle && jQuery.acceptData(cur) && handle.apply && handle.apply(cur, data) === false ) { event.preventDefault() } } event.type = type // If nobody prevented the default action, do it now if (!onlyHandlers && !event.isDefaultPrevented()) { if ( (!special._default || special._default.apply(eventPath.pop(), data) === false) && jQuery.acceptData(elem) ) { // Call a native DOM method on the target with the same name name as the event. // Can't use an .isFunction() check here because IE6/7 fails that test. // Don't do default actions on window, that's where global variables be (#6170) if (ontype && elem[type] && !jQuery.isWindow(elem)) { // Don't re-trigger an onFOO event when we call its FOO() method tmp = elem[ontype] if (tmp) { elem[ontype] = null } // Prevent re-triggering of the same event, since we already bubbled it above jQuery.event.triggered = type try { elem[type]() } catch (e) { // IE<9 dies on focus/blur to hidden element (#1486,#12518) // only reproducible on winXP IE8 native, not IE9 in IE8 mode } jQuery.event.triggered = undefined if (tmp) { elem[ontype] = tmp } } } } return event.result }, dispatch: function (event) { // Make a writable jQuery.Event from the native event object event = jQuery.event.fix(event) var i, ret, handleObj, matched, j, handlerQueue = [], args = core_slice.call(arguments), handlers = (jQuery._data(this, 'events') || {})[event.type] || [], special = jQuery.event.special[event.type] || {} // Use the fix-ed jQuery.Event rather than the (read-only) native event args[0] = event event.delegateTarget = this // Call the preDispatch hook for the mapped type, and let it bail if desired if ( special.preDispatch && special.preDispatch.call(this, event) === false ) { return } // Determine handlers handlerQueue = jQuery.event.handlers.call(this, event, handlers) // Run delegates first; they may want to stop propagation beneath us i = 0 while ((matched = handlerQueue[i++]) && !event.isPropagationStopped()) { event.currentTarget = matched.elem j = 0 while ( (handleObj = matched.handlers[j++]) && !event.isImmediatePropagationStopped() ) { // Triggered event must either 1) have no namespace, or // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). if ( !event.namespace_re || event.namespace_re.test(handleObj.namespace) ) { event.handleObj = handleObj event.data = handleObj.data ret = ( (jQuery.event.special[handleObj.origType] || {}).handle || handleObj.handler ).apply(matched.elem, args) if (ret !== undefined) { if ((event.result = ret) === false) { event.preventDefault() event.stopPropagation() } } } } } // Call the postDispatch hook for the mapped type if (special.postDispatch) { special.postDispatch.call(this, event) } return event.result }, handlers: function (event, handlers) { var sel, handleObj, matches, i, handlerQueue = [], delegateCount = handlers.delegateCount, cur = event.target // Find delegate handlers // Black-hole SVG instance trees (#13180) // Avoid non-left-click bubbling in Firefox (#3861) if ( delegateCount && cur.nodeType && (!event.button || event.type !== 'click') ) { /* jshint eqeqeq: false */ for (; cur != this; cur = cur.parentNode || this) { /* jshint eqeqeq: true */ // Don't check non-elements (#13208) // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) if ( cur.nodeType === 1 && (cur.disabled !== true || event.type !== 'click') ) { matches = [] for (i = 0; i < delegateCount; i++) { handleObj = handlers[i] // Don't conflict with Object.prototype properties (#13203) sel = handleObj.selector + ' ' if (matches[sel] === undefined) { matches[sel] = handleObj.needsContext ? jQuery(sel, this).index(cur) >= 0 : jQuery.find(sel, this, null, [cur]).length } if (matches[sel]) { matches.push(handleObj) } } if (matches.length) { handlerQueue.push({ elem: cur, handlers: matches }) } } } } // Add the remaining (directly-bound) handlers if (delegateCount < handlers.length) { handlerQueue.push({ elem: this, handlers: handlers.slice(delegateCount), }) } return handlerQueue }, fix: function (event) { if (event[jQuery.expando]) { return event } // Create a writable copy of the event object and normalize some properties var i, prop, copy, type = event.type, originalEvent = event, fixHook = this.fixHooks[type] if (!fixHook) { this.fixHooks[type] = fixHook = rmouseEvent.test(type) ? this.mouseHooks : rkeyEvent.test(type) ? this.keyHooks : {} } copy = fixHook.props ? this.props.concat(fixHook.props) : this.props event = new jQuery.Event(originalEvent) i = copy.length while (i--) { prop = copy[i] event[prop] = originalEvent[prop] } // Support: IE<9 // Fix target property (#1925) if (!event.target) { event.target = originalEvent.srcElement || document } // Support: Chrome 23+, Safari? // Target should not be a text node (#504, #13143) if (event.target.nodeType === 3) { event.target = event.target.parentNode } // Support: IE<9 // For mouse/key events, metaKey==false if it's undefined (#3368, #11328) event.metaKey = !!event.metaKey return fixHook.filter ? fixHook.filter(event, originalEvent) : event }, // Includes some event props shared by KeyEvent and MouseEvent props: 'altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which'.split( ' ' ), fixHooks: {}, keyHooks: { props: 'char charCode key keyCode'.split(' '), filter: function (event, original) { // Add which for key events if (event.which == null) { event.which = original.charCode != null ? original.charCode : original.keyCode } return event }, }, mouseHooks: { props: 'button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement'.split( ' ' ), filter: function (event, original) { var body, eventDoc, doc, button = original.button, fromElement = original.fromElement // Calculate pageX/Y if missing and clientX/Y available if (event.pageX == null && original.clientX != null) { eventDoc = event.target.ownerDocument || document doc = eventDoc.documentElement body = eventDoc.body event.pageX = original.clientX + ((doc && doc.scrollLeft) || (body && body.scrollLeft) || 0) - ((doc && doc.clientLeft) || (body && body.clientLeft) || 0) event.pageY = original.clientY + ((doc && doc.scrollTop) || (body && body.scrollTop) || 0) - ((doc && doc.clientTop) || (body && body.clientTop) || 0) } // Add relatedTarget, if necessary if (!event.relatedTarget && fromElement) { event.relatedTarget = fromElement === event.target ? original.toElement : fromElement } // Add which for click: 1 === left; 2 === middle; 3 === right // Note: button is not normalized, so don't use it if (!event.which && button !== undefined) { event.which = button & 1 ? 1 : button & 2 ? 3 : button & 4 ? 2 : 0 } return event }, }, special: { load: { // Prevent triggered image.load events from bubbling to window.load noBubble: true, }, focus: { // Fire native event if possible so blur/focus sequence is correct trigger: function () { if (this !== safeActiveElement() && this.focus) { try { this.focus() return false } catch (e) { // Support: IE<9 // If we error on focus to hidden element (#1486, #12518), // let .trigger() run the handlers } } }, delegateType: 'focusin', }, blur: { trigger: function () { if (this === safeActiveElement() && this.blur) { this.blur() return false } }, delegateType: 'focusout', }, click: { // For checkbox, fire native event so checked state will be right trigger: function () { if ( jQuery.nodeName(this, 'input') && this.type === 'checkbox' && this.click ) { this.click() return false } }, // For cross-browser consistency, don't fire native .click() on links _default: function (event) { return jQuery.nodeName(event.target, 'a') }, }, beforeunload: { postDispatch: function (event) { // Even when returnValue equals to undefined Firefox will still show alert if (event.result !== undefined) { event.originalEvent.returnValue = event.result } }, }, }, simulate: function (type, elem, event, bubble) { // Piggyback on a donor event to simulate a different one. // Fake originalEvent to avoid donor's stopPropagation, but if the // simulated event prevents default then we do the same on the donor. var e = jQuery.extend(new jQuery.Event(), event, { type: type, isSimulated: true, originalEvent: {}, }) if (bubble) { jQuery.event.trigger(e, null, elem) } else { jQuery.event.dispatch.call(elem, e) } if (e.isDefaultPrevented()) { event.preventDefault() } }, } jQuery.removeEvent = document.removeEventListener ? function (elem, type, handle) { if (elem.removeEventListener) { elem.removeEventListener(type, handle, false) } } : function (elem, type, handle) { var name = 'on' + type if (elem.detachEvent) { // #8545, #7054, preventing memory leaks for custom events in IE6-8 // detachEvent needed property on element, by name of that event, to properly expose it to GC if (typeof elem[name] === core_strundefined) { elem[name] = null } elem.detachEvent(name, handle) } } jQuery.Event = function (src, props) { // Allow instantiation without the 'new' keyword if (!(this instanceof jQuery.Event)) { return new jQuery.Event(src, props) } // Event object if (src && src.type) { this.originalEvent = src this.type = src.type // Events bubbling up the document may have been marked as prevented // by a handler lower down the tree; reflect the correct value. this.isDefaultPrevented = src.defaultPrevented || src.returnValue === false || (src.getPreventDefault && src.getPreventDefault()) ? returnTrue : returnFalse // Event type } else { this.type = src } // Put explicitly provided properties onto the event object if (props) { jQuery.extend(this, props) } // Create a timestamp if incoming event doesn't have one this.timeStamp = (src && src.timeStamp) || jQuery.now() // Mark it as fixed this[jQuery.expando] = true } // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html jQuery.Event.prototype = { isDefaultPrevented: returnFalse, isPropagationStopped: returnFalse, isImmediatePropagationStopped: returnFalse, preventDefault: function () { var e = this.originalEvent this.isDefaultPrevented = returnTrue if (!e) { return } // If preventDefault exists, run it on the original event if (e.preventDefault) { e.preventDefault() // Support: IE // Otherwise set the returnValue property of the original event to false } else { e.returnValue = false } }, stopPropagation: function () { var e = this.originalEvent this.isPropagationStopped = returnTrue if (!e) { return } // If stopPropagation exists, run it on the original event if (e.stopPropagation) { e.stopPropagation() } // Support: IE // Set the cancelBubble property of the original event to true e.cancelBubble = true }, stopImmediatePropagation: function () { this.isImmediatePropagationStopped = returnTrue this.stopPropagation() }, } // Create mouseenter/leave events using mouseover/out and event-time checks jQuery.each( { mouseenter: 'mouseover', mouseleave: 'mouseout', }, function (orig, fix) { jQuery.event.special[orig] = { delegateType: fix, bindType: fix, handle: function (event) { var ret, target = this, related = event.relatedTarget, handleObj = event.handleObj // For mousenter/leave call the handler if related is outside the target. // NB: No relatedTarget if the mouse left/entered the browser window if ( !related || (related !== target && !jQuery.contains(target, related)) ) { event.type = handleObj.origType ret = handleObj.handler.apply(this, arguments) event.type = fix } return ret }, } } ) // IE submit delegation if (!jQuery.support.submitBubbles) { jQuery.event.special.submit = { setup: function () { // Only need this for delegated form submit events if (jQuery.nodeName(this, 'form')) { return false } // Lazy-add a submit handler when a descendant form may potentially be submitted jQuery.event.add(this, 'click._submit keypress._submit', function (e) { // Node name check avoids a VML-related crash in IE (#9807) var elem = e.target, form = jQuery.nodeName(elem, 'input') || jQuery.nodeName(elem, 'button') ? elem.form : undefined if (form && !jQuery._data(form, 'submitBubbles')) { jQuery.event.add(form, 'submit._submit', function (event) { event._submit_bubble = true }) jQuery._data(form, 'submitBubbles', true) } }) // return undefined since we don't need an event listener }, postDispatch: function (event) { // If form was submitted by the user, bubble the event up the tree if (event._submit_bubble) { delete event._submit_bubble if (this.parentNode && !event.isTrigger) { jQuery.event.simulate('submit', this.parentNode, event, true) } } }, teardown: function () { // Only need this for delegated form submit events if (jQuery.nodeName(this, 'form')) { return false } // Remove delegated handlers; cleanData eventually reaps submit handlers attached above jQuery.event.remove(this, '._submit') }, } } // IE change delegation and checkbox/radio fix if (!jQuery.support.changeBubbles) { jQuery.event.special.change = { setup: function () { if (rformElems.test(this.nodeName)) { // IE doesn't fire change on a check/radio until blur; trigger it on click // after a propertychange. Eat the blur-change in special.change.handle. // This still fires onchange a second time for check/radio after blur. if (this.type === 'checkbox' || this.type === 'radio') { jQuery.event.add(this, 'propertychange._change', function (event) { if (event.originalEvent.propertyName === 'checked') { this._just_changed = true } }) jQuery.event.add(this, 'click._change', function (event) { if (this._just_changed && !event.isTrigger) { this._just_changed = false } // Allow triggered, simulated change events (#11500) jQuery.event.simulate('change', this, event, true) }) } return false } // Delegated event; lazy-add a change handler on descendant inputs jQuery.event.add(this, 'beforeactivate._change', function (e) { var elem = e.target if ( rformElems.test(elem.nodeName) && !jQuery._data(elem, 'changeBubbles') ) { jQuery.event.add(elem, 'change._change', function (event) { if (this.parentNode && !event.isSimulated && !event.isTrigger) { jQuery.event.simulate('change', this.parentNode, event, true) } }) jQuery._data(elem, 'changeBubbles', true) } }) }, handle: function (event) { var elem = event.target // Swallow native change events from checkbox/radio, we already triggered them above if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== 'radio' && elem.type !== 'checkbox') ) { return event.handleObj.handler.apply(this, arguments) } }, teardown: function () { jQuery.event.remove(this, '._change') return !rformElems.test(this.nodeName) }, } } // Create "bubbling" focus and blur events if (!jQuery.support.focusinBubbles) { jQuery.each({ focus: 'focusin', blur: 'focusout' }, function (orig, fix) { // Attach a single capturing handler while someone wants focusin/focusout var attaches = 0, handler = function (event) { jQuery.event.simulate( fix, event.target, jQuery.event.fix(event), true ) } jQuery.event.special[fix] = { setup: function () { if (attaches++ === 0) { document.addEventListener(orig, handler, true) } }, teardown: function () { if (--attaches === 0) { document.removeEventListener(orig, handler, true) } }, } }) } jQuery.fn.extend({ on: function (types, selector, data, fn, /*INTERNAL*/ one) { var type, origFn // Types can be a map of types/handlers if (typeof types === 'object') { // ( types-Object, selector, data ) if (typeof selector !== 'string') { // ( types-Object, data ) data = data || selector selector = undefined } for (type in types) { this.on(type, selector, data, types[type], one) } return this } if (data == null && fn == null) { // ( types, fn ) fn = selector data = selector = undefined } else if (fn == null) { if (typeof selector === 'string') { // ( types, selector, fn ) fn = data data = undefined } else { // ( types, data, fn ) fn = data data = selector selector = undefined } } if (fn === false) { fn = returnFalse } else if (!fn) { return this } if (one === 1) { origFn = fn fn = function (event) { // Can use an empty set, since event contains the info jQuery().off(event) return origFn.apply(this, arguments) } // Use same guid so caller can remove using origFn fn.guid = origFn.guid || (origFn.guid = jQuery.guid++) } return this.each(function () { jQuery.event.add(this, types, fn, data, selector) }) }, one: function (types, selector, data, fn) { return this.on(types, selector, data, fn, 1) }, off: function (types, selector, fn) { var handleObj, type if (types && types.preventDefault && types.handleObj) { // ( event ) dispatched jQuery.Event handleObj = types.handleObj jQuery(types.delegateTarget).off( handleObj.namespace ? handleObj.origType + '.' + handleObj.namespace : handleObj.origType, handleObj.selector, handleObj.handler ) return this } if (typeof types === 'object') { // ( types-object [, selector] ) for (type in types) { this.off(type, selector, types[type]) } return this } if (selector === false || typeof selector === 'function') { // ( types [, fn] ) fn = selector selector = undefined } if (fn === false) { fn = returnFalse } return this.each(function () { jQuery.event.remove(this, types, fn, selector) }) }, trigger: function (type, data) { return this.each(function () { jQuery.event.trigger(type, data, this) }) }, triggerHandler: function (type, data) { var elem = this[0] if (elem) { return jQuery.event.trigger(type, data, elem, true) } }, }) var isSimple = /^.[^:#\[\.,]*$/, rparentsprev = /^(?:parents|prev(?:Until|All))/, rneedsContext = jQuery.expr.match.needsContext, // methods guaranteed to produce a unique set when starting from a unique set guaranteedUnique = { children: true, contents: true, next: true, prev: true, } jQuery.fn.extend({ find: function (selector) { var i, ret = [], self = this, len = self.length if (typeof selector !== 'string') { return this.pushStack( jQuery(selector).filter(function () { for (i = 0; i < len; i++) { if (jQuery.contains(self[i], this)) { return true } } }) ) } for (i = 0; i < len; i++) { jQuery.find(selector, self[i], ret) } // Needed because $( selector, context ) becomes $( context ).find( selector ) ret = this.pushStack(len > 1 ? jQuery.unique(ret) : ret) ret.selector = this.selector ? this.selector + ' ' + selector : selector return ret }, has: function (target) { var i, targets = jQuery(target, this), len = targets.length return this.filter(function () { for (i = 0; i < len; i++) { if (jQuery.contains(this, targets[i])) { return true } } }) }, not: function (selector) { return this.pushStack(winnow(this, selector || [], true)) }, filter: function (selector) { return this.pushStack(winnow(this, selector || [], false)) }, is: function (selector) { return !!winnow( this, // If this is a positional/relative selector, check membership in the returned set // so $("p:first").is("p:last") won't return true for a doc with two "p". typeof selector === 'string' && rneedsContext.test(selector) ? jQuery(selector) : selector || [], false ).length }, closest: function (selectors, context) { var cur, i = 0, l = this.length, ret = [], pos = rneedsContext.test(selectors) || typeof selectors !== 'string' ? jQuery(selectors, context || this.context) : 0 for (; i < l; i++) { for (cur = this[i]; cur && cur !== context; cur = cur.parentNode) { // Always skip document fragments if ( cur.nodeType < 11 && (pos ? pos.index(cur) > -1 : // Don't pass non-elements to Sizzle cur.nodeType === 1 && jQuery.find.matchesSelector(cur, selectors)) ) { cur = ret.push(cur) break } } } return this.pushStack(ret.length > 1 ? jQuery.unique(ret) : ret) }, // Determine the position of an element within // the matched set of elements index: function (elem) { // No argument, return index in parent if (!elem) { return this[0] && this[0].parentNode ? this.first().prevAll().length : -1 } // index in selector if (typeof elem === 'string') { return jQuery.inArray(this[0], jQuery(elem)) } // Locate the position of the desired element return jQuery.inArray( // If it receives a jQuery object, the first element is used elem.jquery ? elem[0] : elem, this ) }, add: function (selector, context) { var set = typeof selector === 'string' ? jQuery(selector, context) : jQuery.makeArray( selector && selector.nodeType ? [selector] : selector ), all = jQuery.merge(this.get(), set) return this.pushStack(jQuery.unique(all)) }, addBack: function (selector) { return this.add( selector == null ? this.prevObject : this.prevObject.filter(selector) ) }, }) function sibling(cur, dir) { do { cur = cur[dir] } while (cur && cur.nodeType !== 1) return cur } jQuery.each( { parent: function (elem) { var parent = elem.parentNode return parent && parent.nodeType !== 11 ? parent : null }, parents: function (elem) { return jQuery.dir(elem, 'parentNode') }, parentsUntil: function (elem, i, until) { return jQuery.dir(elem, 'parentNode', until) }, next: function (elem) { return sibling(elem, 'nextSibling') }, prev: function (elem) { return sibling(elem, 'previousSibling') }, nextAll: function (elem) { return jQuery.dir(elem, 'nextSibling') }, prevAll: function (elem) { return jQuery.dir(elem, 'previousSibling') }, nextUntil: function (elem, i, until) { return jQuery.dir(elem, 'nextSibling', until) }, prevUntil: function (elem, i, until) { return jQuery.dir(elem, 'previousSibling', until) }, siblings: function (elem) { return jQuery.sibling((elem.parentNode || {}).firstChild, elem) }, children: function (elem) { return jQuery.sibling(elem.firstChild) }, contents: function (elem) { return jQuery.nodeName(elem, 'iframe') ? elem.contentDocument || elem.contentWindow.document : jQuery.merge([], elem.childNodes) }, }, function (name, fn) { jQuery.fn[name] = function (until, selector) { var ret = jQuery.map(this, fn, until) if (name.slice(-5) !== 'Until') { selector = until } if (selector && typeof selector === 'string') { ret = jQuery.filter(selector, ret) } if (this.length > 1) { // Remove duplicates if (!guaranteedUnique[name]) { ret = jQuery.unique(ret) } // Reverse order for parents* and prev-derivatives if (rparentsprev.test(name)) { ret = ret.reverse() } } return this.pushStack(ret) } } ) jQuery.extend({ filter: function (expr, elems, not) { var elem = elems[0] if (not) { expr = ':not(' + expr + ')' } return elems.length === 1 && elem.nodeType === 1 ? jQuery.find.matchesSelector(elem, expr) ? [elem] : [] : jQuery.find.matches( expr, jQuery.grep(elems, function (elem) { return elem.nodeType === 1 }) ) }, dir: function (elem, dir, until) { var matched = [], cur = elem[dir] while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery(cur).is(until)) ) { if (cur.nodeType === 1) { matched.push(cur) } cur = cur[dir] } return matched }, sibling: function (n, elem) { var r = [] for (; n; n = n.nextSibling) { if (n.nodeType === 1 && n !== elem) { r.push(n) } } return r }, }) // Implement the identical functionality for filter and not function winnow(elements, qualifier, not) { if (jQuery.isFunction(qualifier)) { return jQuery.grep(elements, function (elem, i) { /* jshint -W018 */ return !!qualifier.call(elem, i, elem) !== not }) } if (qualifier.nodeType) { return jQuery.grep(elements, function (elem) { return (elem === qualifier) !== not }) } if (typeof qualifier === 'string') { if (isSimple.test(qualifier)) { return jQuery.filter(qualifier, elements, not) } qualifier = jQuery.filter(qualifier, elements) } return jQuery.grep(elements, function (elem) { return jQuery.inArray(elem, qualifier) >= 0 !== not }) } function createSafeFragment(document) { var list = nodeNames.split('|'), safeFrag = document.createDocumentFragment() if (safeFrag.createElement) { while (list.length) { safeFrag.createElement(list.pop()) } } return safeFrag } var nodeNames = 'abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|' + 'header|hgroup|mark|meter|nav|output|progress|section|summary|time|video', rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g, rnoshimcache = new RegExp('<(?:' + nodeNames + ')[\\s/>]', 'i'), rleadingWhitespace = /^\s+/, rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, rtagName = /<([\w:]+)/, rtbody = /\s*$/g, // We have to close these tags to support XHTML (#13200) wrapMap = { option: [1, "'], legend: [1, '
', '
'], area: [1, '', ''], param: [1, '', ''], thead: [1, '', '
'], tr: [2, '', '
'], col: [2, '', '
'], td: [3, '', '
'], // IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags, // unless wrapped in a div with non-breaking characters in front of it. _default: jQuery.support.htmlSerialize ? [0, '', ''] : [1, 'X
', '
'], }, safeFragment = createSafeFragment(document), fragmentDiv = safeFragment.appendChild(document.createElement('div')) wrapMap.optgroup = wrapMap.option wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead wrapMap.th = wrapMap.td jQuery.fn.extend({ text: function (value) { return jQuery.access( this, function (value) { return value === undefined ? jQuery.text(this) : this.empty().append( ((this[0] && this[0].ownerDocument) || document).createTextNode( value ) ) }, null, value, arguments.length ) }, append: function () { return this.domManip(arguments, function (elem) { if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { var target = manipulationTarget(this, elem) target.appendChild(elem) } }) }, prepend: function () { return this.domManip(arguments, function (elem) { if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { var target = manipulationTarget(this, elem) target.insertBefore(elem, target.firstChild) } }) }, before: function () { return this.domManip(arguments, function (elem) { if (this.parentNode) { this.parentNode.insertBefore(elem, this) } }) }, after: function () { return this.domManip(arguments, function (elem) { if (this.parentNode) { this.parentNode.insertBefore(elem, this.nextSibling) } }) }, // keepData is for internal use only--do not document remove: function (selector, keepData) { var elem, elems = selector ? jQuery.filter(selector, this) : this, i = 0 for (; (elem = elems[i]) != null; i++) { if (!keepData && elem.nodeType === 1) { jQuery.cleanData(getAll(elem)) } if (elem.parentNode) { if (keepData && jQuery.contains(elem.ownerDocument, elem)) { setGlobalEval(getAll(elem, 'script')) } elem.parentNode.removeChild(elem) } } return this }, empty: function () { var elem, i = 0 for (; (elem = this[i]) != null; i++) { // Remove element nodes and prevent memory leaks if (elem.nodeType === 1) { jQuery.cleanData(getAll(elem, false)) } // Remove any remaining nodes while (elem.firstChild) { elem.removeChild(elem.firstChild) } // If this is a select, ensure that it displays empty (#12336) // Support: IE<9 if (elem.options && jQuery.nodeName(elem, 'select')) { elem.options.length = 0 } } return this }, clone: function (dataAndEvents, deepDataAndEvents) { dataAndEvents = dataAndEvents == null ? false : dataAndEvents deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents return this.map(function () { return jQuery.clone(this, dataAndEvents, deepDataAndEvents) }) }, html: function (value) { return jQuery.access( this, function (value) { var elem = this[0] || {}, i = 0, l = this.length if (value === undefined) { return elem.nodeType === 1 ? elem.innerHTML.replace(rinlinejQuery, '') : undefined } // See if we can take a shortcut and just use innerHTML if ( typeof value === 'string' && !rnoInnerhtml.test(value) && (jQuery.support.htmlSerialize || !rnoshimcache.test(value)) && (jQuery.support.leadingWhitespace || !rleadingWhitespace.test(value)) && !wrapMap[(rtagName.exec(value) || ['', ''])[1].toLowerCase()] ) { value = value.replace(rxhtmlTag, '<$1>') try { for (; i < l; i++) { // Remove element nodes and prevent memory leaks elem = this[i] || {} if (elem.nodeType === 1) { jQuery.cleanData(getAll(elem, false)) elem.innerHTML = value } } elem = 0 // If using innerHTML throws an exception, use the fallback method } catch (e) {} } if (elem) { this.empty().append(value) } }, null, value, arguments.length ) }, replaceWith: function () { var // Snapshot the DOM in case .domManip sweeps something relevant into its fragment args = jQuery.map(this, function (elem) { return [elem.nextSibling, elem.parentNode] }), i = 0 // Make the changes, replacing each context element with the new content this.domManip( arguments, function (elem) { var next = args[i++], parent = args[i++] if (parent) { // Don't use the snapshot next if it has moved (#13810) if (next && next.parentNode !== parent) { next = this.nextSibling } jQuery(this).remove() parent.insertBefore(elem, next) } // Allow new content to include elements from the context set }, true ) // Force removal if there was no new content (e.g., from empty arguments) return i ? this : this.remove() }, detach: function (selector) { return this.remove(selector, true) }, domManip: function (args, callback, allowIntersection) { // Flatten any nested arrays args = core_concat.apply([], args) var first, node, hasScripts, scripts, doc, fragment, i = 0, l = this.length, set = this, iNoClone = l - 1, value = args[0], isFunction = jQuery.isFunction(value) // We can't cloneNode fragments that contain checked, in WebKit if ( isFunction || !( l <= 1 || typeof value !== 'string' || jQuery.support.checkClone || !rchecked.test(value) ) ) { return this.each(function (index) { var self = set.eq(index) if (isFunction) { args[0] = value.call(this, index, self.html()) } self.domManip(args, callback, allowIntersection) }) } if (l) { fragment = jQuery.buildFragment( args, this[0].ownerDocument, false, !allowIntersection && this ) first = fragment.firstChild if (fragment.childNodes.length === 1) { fragment = first } if (first) { scripts = jQuery.map(getAll(fragment, 'script'), disableScript) hasScripts = scripts.length // Use the original fragment for the last item instead of the first because it can end up // being emptied incorrectly in certain situations (#8070). for (; i < l; i++) { node = fragment if (i !== iNoClone) { node = jQuery.clone(node, true, true) // Keep references to cloned scripts for later restoration if (hasScripts) { jQuery.merge(scripts, getAll(node, 'script')) } } callback.call(this[i], node, i) } if (hasScripts) { doc = scripts[scripts.length - 1].ownerDocument // Reenable scripts jQuery.map(scripts, restoreScript) // Evaluate executable scripts on first document insertion for (i = 0; i < hasScripts; i++) { node = scripts[i] if ( rscriptType.test(node.type || '') && !jQuery._data(node, 'globalEval') && jQuery.contains(doc, node) ) { if (node.src) { // Hope ajax is available... jQuery._evalUrl(node.src) } else { jQuery.globalEval( ( node.text || node.textContent || node.innerHTML || '' ).replace(rcleanScript, '') ) } } } } // Fix #11809: Avoid leaking memory fragment = first = null } } return this }, }) // Support: IE<8 // Manipulating tables requires a tbody function manipulationTarget(elem, content) { return jQuery.nodeName(elem, 'table') && jQuery.nodeName( content.nodeType === 1 ? content : content.firstChild, 'tr' ) ? elem.getElementsByTagName('tbody')[0] || elem.appendChild(elem.ownerDocument.createElement('tbody')) : elem } // Replace/restore the type attribute of script elements for safe DOM manipulation function disableScript(elem) { elem.type = (jQuery.find.attr(elem, 'type') !== null) + '/' + elem.type return elem } function restoreScript(elem) { var match = rscriptTypeMasked.exec(elem.type) if (match) { elem.type = match[1] } else { elem.removeAttribute('type') } return elem } // Mark scripts as having already been evaluated function setGlobalEval(elems, refElements) { var elem, i = 0 for (; (elem = elems[i]) != null; i++) { jQuery._data( elem, 'globalEval', !refElements || jQuery._data(refElements[i], 'globalEval') ) } } function cloneCopyEvent(src, dest) { if (dest.nodeType !== 1 || !jQuery.hasData(src)) { return } var type, i, l, oldData = jQuery._data(src), curData = jQuery._data(dest, oldData), events = oldData.events if (events) { delete curData.handle curData.events = {} for (type in events) { for (i = 0, l = events[type].length; i < l; i++) { jQuery.event.add(dest, type, events[type][i]) } } } // make the cloned public data object a copy from the original if (curData.data) { curData.data = jQuery.extend({}, curData.data) } } function fixCloneNodeIssues(src, dest) { var nodeName, e, data // We do not need to do anything for non-Elements if (dest.nodeType !== 1) { return } nodeName = dest.nodeName.toLowerCase() // IE6-8 copies events bound via attachEvent when using cloneNode. if (!jQuery.support.noCloneEvent && dest[jQuery.expando]) { data = jQuery._data(dest) for (e in data.events) { jQuery.removeEvent(dest, e, data.handle) } // Event data gets referenced instead of copied if the expando gets copied too dest.removeAttribute(jQuery.expando) } // IE blanks contents when cloning scripts, and tries to evaluate newly-set text if (nodeName === 'script' && dest.text !== src.text) { disableScript(dest).text = src.text restoreScript(dest) // IE6-10 improperly clones children of object elements using classid. // IE10 throws NoModificationAllowedError if parent is null, #12132. } else if (nodeName === 'object') { if (dest.parentNode) { dest.outerHTML = src.outerHTML } // This path appears unavoidable for IE9. When cloning an object // element in IE9, the outerHTML strategy above is not sufficient. // If the src has innerHTML and the destination does not, // copy the src.innerHTML into the dest.innerHTML. #10324 if ( jQuery.support.html5Clone && src.innerHTML && !jQuery.trim(dest.innerHTML) ) { dest.innerHTML = src.innerHTML } } else if ( nodeName === 'input' && manipulation_rcheckableType.test(src.type) ) { // IE6-8 fails to persist the checked state of a cloned checkbox // or radio button. Worse, IE6-7 fail to give the cloned element // a checked appearance if the defaultChecked value isn't also set dest.defaultChecked = dest.checked = src.checked // IE6-7 get confused and end up setting the value of a cloned // checkbox/radio button to an empty string instead of "on" if (dest.value !== src.value) { dest.value = src.value } // IE6-8 fails to return the selected option to the default selected // state when cloning options } else if (nodeName === 'option') { dest.defaultSelected = dest.selected = src.defaultSelected // IE6-8 fails to set the defaultValue to the correct value when // cloning other types of input fields } else if (nodeName === 'input' || nodeName === 'textarea') { dest.defaultValue = src.defaultValue } } jQuery.each( { appendTo: 'append', prependTo: 'prepend', insertBefore: 'before', insertAfter: 'after', replaceAll: 'replaceWith', }, function (name, original) { jQuery.fn[name] = function (selector) { var elems, i = 0, ret = [], insert = jQuery(selector), last = insert.length - 1 for (; i <= last; i++) { elems = i === last ? this : this.clone(true) jQuery(insert[i])[original](elems) // Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get() core_push.apply(ret, elems.get()) } return this.pushStack(ret) } } ) function getAll(context, tag) { var elems, elem, i = 0, found = typeof context.getElementsByTagName !== core_strundefined ? context.getElementsByTagName(tag || '*') : typeof context.querySelectorAll !== core_strundefined ? context.querySelectorAll(tag || '*') : undefined if (!found) { for ( found = [], elems = context.childNodes || context; (elem = elems[i]) != null; i++ ) { if (!tag || jQuery.nodeName(elem, tag)) { found.push(elem) } else { jQuery.merge(found, getAll(elem, tag)) } } } return tag === undefined || (tag && jQuery.nodeName(context, tag)) ? jQuery.merge([context], found) : found } // Used in buildFragment, fixes the defaultChecked property function fixDefaultChecked(elem) { if (manipulation_rcheckableType.test(elem.type)) { elem.defaultChecked = elem.checked } } jQuery.extend({ clone: function (elem, dataAndEvents, deepDataAndEvents) { var destElements, node, clone, i, srcElements, inPage = jQuery.contains(elem.ownerDocument, elem) if ( jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test('<' + elem.nodeName + '>') ) { clone = elem.cloneNode(true) // IE<=8 does not properly clone detached, unknown element nodes } else { fragmentDiv.innerHTML = elem.outerHTML fragmentDiv.removeChild((clone = fragmentDiv.firstChild)) } if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) && (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) { // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2 destElements = getAll(clone) srcElements = getAll(elem) // Fix all IE cloning issues for (i = 0; (node = srcElements[i]) != null; ++i) { // Ensure that the destination node is not null; Fixes #9587 if (destElements[i]) { fixCloneNodeIssues(node, destElements[i]) } } } // Copy the events from the original to the clone if (dataAndEvents) { if (deepDataAndEvents) { srcElements = srcElements || getAll(elem) destElements = destElements || getAll(clone) for (i = 0; (node = srcElements[i]) != null; i++) { cloneCopyEvent(node, destElements[i]) } } else { cloneCopyEvent(elem, clone) } } // Preserve script evaluation history destElements = getAll(clone, 'script') if (destElements.length > 0) { setGlobalEval(destElements, !inPage && getAll(elem, 'script')) } destElements = srcElements = node = null // Return the cloned set return clone }, buildFragment: function (elems, context, scripts, selection) { var j, elem, contains, tmp, tag, tbody, wrap, l = elems.length, // Ensure a safe fragment safe = createSafeFragment(context), nodes = [], i = 0 for (; i < l; i++) { elem = elems[i] if (elem || elem === 0) { // Add nodes directly if (jQuery.type(elem) === 'object') { jQuery.merge(nodes, elem.nodeType ? [elem] : elem) // Convert non-html into a text node } else if (!rhtml.test(elem)) { nodes.push(context.createTextNode(elem)) // Convert html into DOM nodes } else { tmp = tmp || safe.appendChild(context.createElement('div')) // Deserialize a standard representation tag = (rtagName.exec(elem) || ['', ''])[1].toLowerCase() wrap = wrapMap[tag] || wrapMap._default tmp.innerHTML = wrap[1] + elem.replace(rxhtmlTag, '<$1>') + wrap[2] // Descend through wrappers to the right content j = wrap[0] while (j--) { tmp = tmp.lastChild } // Manually add leading whitespace removed by IE if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test(elem) ) { nodes.push( context.createTextNode(rleadingWhitespace.exec(elem)[0]) ) } // Remove IE's autoinserted from table fragments if (!jQuery.support.tbody) { // String was a , *may* have spurious elem = tag === 'table' && !rtbody.test(elem) ? tmp.firstChild : // String was a bare or wrap[1] === '
' && !rtbody.test(elem) ? tmp : 0 j = elem && elem.childNodes.length while (j--) { if ( jQuery.nodeName((tbody = elem.childNodes[j]), 'tbody') && !tbody.childNodes.length ) { elem.removeChild(tbody) } } } jQuery.merge(nodes, tmp.childNodes) // Fix #12392 for WebKit and IE > 9 tmp.textContent = '' // Fix #12392 for oldIE while (tmp.firstChild) { tmp.removeChild(tmp.firstChild) } // Remember the top-level container for proper cleanup tmp = safe.lastChild } } } // Fix #11356: Clear elements from fragment if (tmp) { safe.removeChild(tmp) } // Reset defaultChecked for any radios and checkboxes // about to be appended to the DOM in IE 6/7 (#8060) if (!jQuery.support.appendChecked) { jQuery.grep(getAll(nodes, 'input'), fixDefaultChecked) } i = 0 while ((elem = nodes[i++])) { // #4087 - If origin and destination elements are the same, and this is // that element, do not do anything if (selection && jQuery.inArray(elem, selection) !== -1) { continue } contains = jQuery.contains(elem.ownerDocument, elem) // Append to fragment tmp = getAll(safe.appendChild(elem), 'script') // Preserve script evaluation history if (contains) { setGlobalEval(tmp) } // Capture executables if (scripts) { j = 0 while ((elem = tmp[j++])) { if (rscriptType.test(elem.type || '')) { scripts.push(elem) } } } } tmp = null return safe }, cleanData: function (elems, /* internal */ acceptData) { var elem, type, id, data, i = 0, internalKey = jQuery.expando, cache = jQuery.cache, deleteExpando = jQuery.support.deleteExpando, special = jQuery.event.special for (; (elem = elems[i]) != null; i++) { if (acceptData || jQuery.acceptData(elem)) { id = elem[internalKey] data = id && cache[id] if (data) { if (data.events) { for (type in data.events) { if (special[type]) { jQuery.event.remove(elem, type) // This is a shortcut to avoid jQuery.event.remove's overhead } else { jQuery.removeEvent(elem, type, data.handle) } } } // Remove cache only if it was not already removed by jQuery.event.remove if (cache[id]) { delete cache[id] // IE does not allow us to delete expando properties from nodes, // nor does it have a removeAttribute function on Document nodes; // we must handle all of these cases if (deleteExpando) { delete elem[internalKey] } else if (typeof elem.removeAttribute !== core_strundefined) { elem.removeAttribute(internalKey) } else { elem[internalKey] = null } core_deletedIds.push(id) } } } } }, _evalUrl: function (url) { return jQuery.ajax({ url: url, type: 'GET', dataType: 'script', async: false, global: false, throws: true, }) }, }) jQuery.fn.extend({ wrapAll: function (html) { if (jQuery.isFunction(html)) { return this.each(function (i) { jQuery(this).wrapAll(html.call(this, i)) }) } if (this[0]) { // The elements to wrap the target around var wrap = jQuery(html, this[0].ownerDocument).eq(0).clone(true) if (this[0].parentNode) { wrap.insertBefore(this[0]) } wrap .map(function () { var elem = this while (elem.firstChild && elem.firstChild.nodeType === 1) { elem = elem.firstChild } return elem }) .append(this) } return this }, wrapInner: function (html) { if (jQuery.isFunction(html)) { return this.each(function (i) { jQuery(this).wrapInner(html.call(this, i)) }) } return this.each(function () { var self = jQuery(this), contents = self.contents() if (contents.length) { contents.wrapAll(html) } else { self.append(html) } }) }, wrap: function (html) { var isFunction = jQuery.isFunction(html) return this.each(function (i) { jQuery(this).wrapAll(isFunction ? html.call(this, i) : html) }) }, unwrap: function () { return this.parent() .each(function () { if (!jQuery.nodeName(this, 'body')) { jQuery(this).replaceWith(this.childNodes) } }) .end() }, }) var iframe, getStyles, curCSS, ralpha = /alpha\([^)]*\)/i, ropacity = /opacity\s*=\s*([^)]*)/, rposition = /^(top|right|bottom|left)$/, // swappable if display is none or starts with table except "table", "table-cell", or "table-caption" // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display rdisplayswap = /^(none|table(?!-c[ea]).+)/, rmargin = /^margin/, rnumsplit = new RegExp('^(' + core_pnum + ')(.*)$', 'i'), rnumnonpx = new RegExp('^(' + core_pnum + ')(?!px)[a-z%]+$', 'i'), rrelNum = new RegExp('^([+-])=(' + core_pnum + ')', 'i'), elemdisplay = { BODY: 'block' }, cssShow = { position: 'absolute', visibility: 'hidden', display: 'block' }, cssNormalTransform = { letterSpacing: 0, fontWeight: 400, }, cssExpand = ['Top', 'Right', 'Bottom', 'Left'], cssPrefixes = ['Webkit', 'O', 'Moz', 'ms'] // return a css property mapped to a potentially vendor prefixed property function vendorPropName(style, name) { // shortcut for names that are not vendor prefixed if (name in style) { return name } // check for vendor prefixed names var capName = name.charAt(0).toUpperCase() + name.slice(1), origName = name, i = cssPrefixes.length while (i--) { name = cssPrefixes[i] + capName if (name in style) { return name } } return origName } function isHidden(elem, el) { // isHidden might be called from jQuery#filter function; // in that case, element will be second argument elem = el || elem return ( jQuery.css(elem, 'display') === 'none' || !jQuery.contains(elem.ownerDocument, elem) ) } function showHide(elements, show) { var display, elem, hidden, values = [], index = 0, length = elements.length for (; index < length; index++) { elem = elements[index] if (!elem.style) { continue } values[index] = jQuery._data(elem, 'olddisplay') display = elem.style.display if (show) { // Reset the inline display of this element to learn if it is // being hidden by cascaded rules or not if (!values[index] && display === 'none') { elem.style.display = '' } // Set elements which have been overridden with display: none // in a stylesheet to whatever the default browser style is // for such an element if (elem.style.display === '' && isHidden(elem)) { values[index] = jQuery._data( elem, 'olddisplay', css_defaultDisplay(elem.nodeName) ) } } else { if (!values[index]) { hidden = isHidden(elem) if ((display && display !== 'none') || !hidden) { jQuery._data( elem, 'olddisplay', hidden ? display : jQuery.css(elem, 'display') ) } } } } // Set the display of most of the elements in a second loop // to avoid the constant reflow for (index = 0; index < length; index++) { elem = elements[index] if (!elem.style) { continue } if (!show || elem.style.display === 'none' || elem.style.display === '') { elem.style.display = show ? values[index] || '' : 'none' } } return elements } jQuery.fn.extend({ css: function (name, value) { return jQuery.access( this, function (elem, name, value) { var len, styles, map = {}, i = 0 if (jQuery.isArray(name)) { styles = getStyles(elem) len = name.length for (; i < len; i++) { map[name[i]] = jQuery.css(elem, name[i], false, styles) } return map } return value !== undefined ? jQuery.style(elem, name, value) : jQuery.css(elem, name) }, name, value, arguments.length > 1 ) }, show: function () { return showHide(this, true) }, hide: function () { return showHide(this) }, toggle: function (state) { if (typeof state === 'boolean') { return state ? this.show() : this.hide() } return this.each(function () { if (isHidden(this)) { jQuery(this).show() } else { jQuery(this).hide() } }) }, }) jQuery.extend({ // Add in style property hooks for overriding the default // behavior of getting and setting a style property cssHooks: { opacity: { get: function (elem, computed) { if (computed) { // We should always get a number back from opacity var ret = curCSS(elem, 'opacity') return ret === '' ? '1' : ret } }, }, }, // Don't automatically add "px" to these possibly-unitless properties cssNumber: { columnCount: true, fillOpacity: true, fontWeight: true, lineHeight: true, opacity: true, order: true, orphans: true, widows: true, zIndex: true, zoom: true, }, // Add in properties whose names you wish to fix before // setting or getting the value cssProps: { // normalize float css property float: jQuery.support.cssFloat ? 'cssFloat' : 'styleFloat', }, // Get and set the style property on a DOM Node style: function (elem, name, value, extra) { // Don't set styles on text and comment nodes if (!elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style) { return } // Make sure that we're working with the right name var ret, type, hooks, origName = jQuery.camelCase(name), style = elem.style name = jQuery.cssProps[origName] || (jQuery.cssProps[origName] = vendorPropName(style, origName)) // gets hook for the prefixed version // followed by the unprefixed version hooks = jQuery.cssHooks[name] || jQuery.cssHooks[origName] // Check if we're setting a value if (value !== undefined) { type = typeof value // convert relative number strings (+= or -=) to relative numbers. #7345 if (type === 'string' && (ret = rrelNum.exec(value))) { value = (ret[1] + 1) * ret[2] + parseFloat(jQuery.css(elem, name)) // Fixes bug #9237 type = 'number' } // Make sure that NaN and null values aren't set. See: #7116 if (value == null || (type === 'number' && isNaN(value))) { return } // If a number was passed in, add 'px' to the (except for certain CSS properties) if (type === 'number' && !jQuery.cssNumber[origName]) { value += 'px' } // Fixes #8908, it can be done more correctly by specifing setters in cssHooks, // but it would mean to define eight (for every problematic property) identical functions if ( !jQuery.support.clearCloneStyle && value === '' && name.indexOf('background') === 0 ) { style[name] = 'inherit' } // If a hook was provided, use that value, otherwise just set the specified value if ( !hooks || !('set' in hooks) || (value = hooks.set(elem, value, extra)) !== undefined ) { // Wrapped to prevent IE from throwing errors when 'invalid' values are provided // Fixes bug #5509 try { style[name] = value } catch (e) {} } } else { // If a hook was provided get the non-computed value from there if ( hooks && 'get' in hooks && (ret = hooks.get(elem, false, extra)) !== undefined ) { return ret } // Otherwise just get the value from the style object return style[name] } }, css: function (elem, name, extra, styles) { var num, val, hooks, origName = jQuery.camelCase(name) // Make sure that we're working with the right name name = jQuery.cssProps[origName] || (jQuery.cssProps[origName] = vendorPropName(elem.style, origName)) // gets hook for the prefixed version // followed by the unprefixed version hooks = jQuery.cssHooks[name] || jQuery.cssHooks[origName] // If a hook was provided get the computed value from there if (hooks && 'get' in hooks) { val = hooks.get(elem, true, extra) } // Otherwise, if a way to get the computed value exists, use that if (val === undefined) { val = curCSS(elem, name, styles) } //convert "normal" to computed value if (val === 'normal' && name in cssNormalTransform) { val = cssNormalTransform[name] } // Return, converting to number if forced or a qualifier was provided and val looks numeric if (extra === '' || extra) { num = parseFloat(val) return extra === true || jQuery.isNumeric(num) ? num || 0 : val } return val }, }) // NOTE: we've included the "window" in window.getComputedStyle // because jsdom on node.js will break without it. if (window.getComputedStyle) { getStyles = function (elem) { return window.getComputedStyle(elem, null) } curCSS = function (elem, name, _computed) { var width, minWidth, maxWidth, computed = _computed || getStyles(elem), // getPropertyValue is only needed for .css('filter') in IE9, see #12537 ret = computed ? computed.getPropertyValue(name) || computed[name] : undefined, style = elem.style if (computed) { if (ret === '' && !jQuery.contains(elem.ownerDocument, elem)) { ret = jQuery.style(elem, name) } // A tribute to the "awesome hack by Dean Edwards" // Chrome < 17 and Safari 5.0 uses "computed value" instead of "used value" for margin-right // Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values if (rnumnonpx.test(ret) && rmargin.test(name)) { // Remember the original values width = style.width minWidth = style.minWidth maxWidth = style.maxWidth // Put in the new values to get a computed value out style.minWidth = style.maxWidth = style.width = ret ret = computed.width // Revert the changed values style.width = width style.minWidth = minWidth style.maxWidth = maxWidth } } return ret } } else if (document.documentElement.currentStyle) { getStyles = function (elem) { return elem.currentStyle } curCSS = function (elem, name, _computed) { var left, rs, rsLeft, computed = _computed || getStyles(elem), ret = computed ? computed[name] : undefined, style = elem.style // Avoid setting ret to empty string here // so we don't default to auto if (ret == null && style && style[name]) { ret = style[name] } // From the awesome hack by Dean Edwards // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 // If we're not dealing with a regular pixel number // but a number that has a weird ending, we need to convert it to pixels // but not position css attributes, as those are proportional to the parent element instead // and we can't measure the parent instead because it might trigger a "stacking dolls" problem if (rnumnonpx.test(ret) && !rposition.test(name)) { // Remember the original values left = style.left rs = elem.runtimeStyle rsLeft = rs && rs.left // Put in the new values to get a computed value out if (rsLeft) { rs.left = elem.currentStyle.left } style.left = name === 'fontSize' ? '1em' : ret ret = style.pixelLeft + 'px' // Revert the changed values style.left = left if (rsLeft) { rs.left = rsLeft } } return ret === '' ? 'auto' : ret } } function setPositiveNumber(elem, value, subtract) { var matches = rnumsplit.exec(value) return matches ? // Guard against undefined "subtract", e.g., when used as in cssHooks Math.max(0, matches[1] - (subtract || 0)) + (matches[2] || 'px') : value } function augmentWidthOrHeight(elem, name, extra, isBorderBox, styles) { var i = extra === (isBorderBox ? 'border' : 'content') ? // If we already have the right measurement, avoid augmentation 4 : // Otherwise initialize for horizontal or vertical properties name === 'width' ? 1 : 0, val = 0 for (; i < 4; i += 2) { // both box models exclude margin, so add it if we want it if (extra === 'margin') { val += jQuery.css(elem, extra + cssExpand[i], true, styles) } if (isBorderBox) { // border-box includes padding, so remove it if we want content if (extra === 'content') { val -= jQuery.css(elem, 'padding' + cssExpand[i], true, styles) } // at this point, extra isn't border nor margin, so remove border if (extra !== 'margin') { val -= jQuery.css( elem, 'border' + cssExpand[i] + 'Width', true, styles ) } } else { // at this point, extra isn't content, so add padding val += jQuery.css(elem, 'padding' + cssExpand[i], true, styles) // at this point, extra isn't content nor padding, so add border if (extra !== 'padding') { val += jQuery.css( elem, 'border' + cssExpand[i] + 'Width', true, styles ) } } } return val } function getWidthOrHeight(elem, name, extra) { // Start with offset property, which is equivalent to the border-box value var valueIsBorderBox = true, val = name === 'width' ? elem.offsetWidth : elem.offsetHeight, styles = getStyles(elem), isBorderBox = jQuery.support.boxSizing && jQuery.css(elem, 'boxSizing', false, styles) === 'border-box' // some non-html elements return undefined for offsetWidth, so check for null/undefined // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285 // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668 if (val <= 0 || val == null) { // Fall back to computed then uncomputed css if necessary val = curCSS(elem, name, styles) if (val < 0 || val == null) { val = elem.style[name] } // Computed unit is not pixels. Stop here and return. if (rnumnonpx.test(val)) { return val } // we need the check for style in case a browser which returns unreliable values // for getComputedStyle silently falls back to the reliable elem.style valueIsBorderBox = isBorderBox && (jQuery.support.boxSizingReliable || val === elem.style[name]) // Normalize "", auto, and prepare for extra val = parseFloat(val) || 0 } // use the active box-sizing model to add/subtract irrelevant styles return ( val + augmentWidthOrHeight( elem, name, extra || (isBorderBox ? 'border' : 'content'), valueIsBorderBox, styles ) + 'px' ) } // Try to determine the default display value of an element function css_defaultDisplay(nodeName) { var doc = document, display = elemdisplay[nodeName] if (!display) { display = actualDisplay(nodeName, doc) // If the simple way fails, read from inside an iframe if (display === 'none' || !display) { // Use the already-created iframe if possible iframe = ( iframe || jQuery("