pax_global_header00006660000000000000000000000064122675537070014530gustar00rootroot0000000000000052 comment=917b312f1d0777d3cccf6ceace2621bb9e8009b2 sizzle-1.10.17/000077500000000000000000000000001226755370700132175ustar00rootroot00000000000000sizzle-1.10.17/.bowerrc000066400000000000000000000000451226755370700146620ustar00rootroot00000000000000{ "directory": "bower_components" }sizzle-1.10.17/.editorconfig000066400000000000000000000003411226755370700156720ustar00rootroot00000000000000# This file is for unifying the coding style for different editors and IDEs # editorconfig.org root = true [*] end_of_line = lf charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true indent_style = tab sizzle-1.10.17/.gitattributes000066400000000000000000000000201226755370700161020ustar00rootroot00000000000000* text=auto sizzle-1.10.17/.gitignore000066400000000000000000000001361226755370700152070ustar00rootroot00000000000000.project .settings *~ *.diff *.patch *.sizecache.json .DS_Store node_modules bower_components sizzle-1.10.17/.jshintrc000066400000000000000000000003631226755370700150460ustar00rootroot00000000000000{ "boss": true, "curly": true, "eqeqeq": true, "eqnull": true, "expr": true, "immed": true, "noarg": true, "onevar": true, "quotmark": "double", "smarttabs": true, "trailing": true, "undef": true, "unused": true, "node": true } sizzle-1.10.17/.mailmap000066400000000000000000000110141226755370700146350ustar00rootroot00000000000000Adam Coulombe Adam J. Sontag Alexander Farkas Alexander Farkas Alexis Abril Andrew E Monat Anton Matzneller Anton Matzneller Batiste Bieler Benjamin Truyman Brandon Aaron Carl Danley Carl Fürstenberg Carl Fürstenberg Charles McNulty Corey Frang Dan Heberden Daniel Chatfield Daniel Gálvez Danil Somsikov Dave Methvin Dave Reed David Fox Devin Cooper Dmitry Gusev Earle Castledine Erick Ruiz de Chávez Gianni Alessandro Chiappetta Heungsub Lee Iraê Carvalho Isaac Z. Schlueter Ismail Khair James Burke James Padolsey Jay Merrifield Jay Merrifield Jean Boussier Jephte Clain Jess Thrysoee Joao Henrique de Andrade Bruni Joe Presbrey John Resig John Resig Jordan Boesch Josh Varner Julian Aubourg Julian Aubourg Julian Aubourg Jörn Zaefferer Jörn Zaefferer Jörn Zaefferer Karl Swedberg Kris Borchers Lee Carpenter Li Xudong Louis-Rémi Babé Louis-Rémi Babé Louis-Rémi Babé Louis-Rémi Babé Marcel Greter Matthias Jäggli Michael Murray Michał Gołębiowski Michał Gołębiowski Mike Alsup Nguyen Phuc Lam Oleg Gaidarenko Rafaël Blais Masson Richard D. Worth Rick Waldron Rick Waldron Robert Katić Ron Otten Sai Lung Wong Scott González Scott Jehl Sebastian Burkhard Timmy Willison Timmy Willison Timo Tijhof TJ Holowaychuk Tom H Fuertes Tom H Fuertes Tom H Fuertes Tom Viner Xavi Ramirez Xavier Montillet Yehuda Katz Yehuda Katz Yehuda Katz Yehuda Katz Yiming He Andrew Chalkley Fabio Buffoni Stefan Bauckmeier  Dušan B. Jovanovic Riccardo De Agostini Vitya Muhachev sizzle-1.10.17/.travis.yml000066400000000000000000000000441226755370700153260ustar00rootroot00000000000000language: node_js node_js: - '0.10' sizzle-1.10.17/AUTHORS.txt000066400000000000000000000026501226755370700151100ustar00rootroot00000000000000Authors ordered by first contribution. John Resig Cheah Chu Yeow Andrew Chalkley Fabio Buffoni Stefan Bauckmeier  Brandon Aaron Anton Kovalyov Dušan B. Jovanovic Riccardo De Agostini Fabian Jakobs Karl Swedberg Jake Archibald Colin Snover Anton Matzneller Dave Methvin Corey Frang Mathias Bynens John Firebaugh Timmy Willison Mike Sherov Rock Hymas Yehuda Katz Jörn Zaefferer Richard Gibson Vitya Muhachev Henri Wiechers Alan Plum Chad Killingsworth Markus Staab Timo Tijhof Diego Tres Jonathan Sampson Pascal Borreli Daniel Herman Frederic Junod Mitch Foley Dan Burzo sizzle-1.10.17/CONTRIBUTING.md000066400000000000000000000020271226755370700154510ustar00rootroot00000000000000Welcome! Thanks for your interest in contributing to Sizzle. You're **almost** in the right place. More information on how to contribute to this and all other jQuery Foundation projects is over at [contribute.jquery.org](http://contribute.jquery.org). You'll definitely want to take a look at the articles on contributing [code](http://contribute.jquery.org/code). You may also want to take a look at our [commit & pull request guide](http://contribute.jquery.org/commits-and-pull-requests/) and [style guides](http://contribute.jquery.org/style-guide/) for instructions on how to maintain your fork and submit your code. Before we can merge any pull request, we'll also need you to sign our [contributor license agreement](http://contribute.jquery.org/cla). You can find us on [IRC](http://irc.jquery.org), specifically in #jquery-dev should you have any questions. If you've never contributed to open source before, we've put together [a short guide with tips, tricks, and ideas on getting started](http://contribute.jquery.org/open-source/). sizzle-1.10.17/Gruntfile.js000066400000000000000000000055361226755370700155250ustar00rootroot00000000000000module.exports = function( grunt ) { "use strict"; var gzip = require( "gzip-js" ), files = { source: "src/sizzle.js", speed: "speed/speed.js", tests: "test/unit/*.js", grunt: [ "Gruntfile.js", "tasks/*" ] }; // Project configuration. grunt.initConfig({ pkg: grunt.file.readJSON( "package.json" ), qunit: { files: [ "test/index.html" ] }, compile: { all: { dest: "dist/sizzle.js", src: "src/sizzle.js" } }, version: { files: [ "package.json", "bower.json" ] }, uglify: { all: { files: { "dist/sizzle.min.js": [ "dist/sizzle.js" ] }, options: { compress: { hoist_funs: false, loops: false }, banner: "/*! Sizzle v<%= pkg.version %> | (c) 2013 jQuery Foundation, Inc. | jquery.org/license */", sourceMap: "dist/sizzle.min.map", beautify: { ascii_only: true } } } }, compare_size: { files: [ "dist/sizzle.js", "dist/sizzle.min.js" ], options: { compress: { gz: function( contents ) { return gzip.zip( contents, {} ).length; } }, cache: "dist/.sizecache.json" } }, bowercopy: { options: { clean: true }, speed: { options: { destPrefix: "speed/libs" }, files: { "requirejs/require.js": "requirejs/require.js", "requirejs-domready/domReady.js": "requirejs-domready/domReady.js", "requirejs-text/text.js": "requirejs-text/text.js", "benchmark/benchmark.js": "benchmark/benchmark.js" } }, "test/libs/qunit": "qunit/qunit" }, jshint: { source: { src: files.source, options: { jshintrc: "src/.jshintrc" } }, grunt: { src: files.grunt, options: { jshintrc: ".jshintrc" } }, speed: { src: files.speed, options: { jshintrc: "speed/.jshintrc" } }, tests: { src: files.tests, options: { jshintrc: "test/.jshintrc" } } }, jscs: { // Can't check the actual source file until // https://github.com/mdevils/node-jscs/pull/90 is merged files: [ files.grunt, files.speed ], options: { preset: "jquery", } }, jsonlint: { pkg: { src: [ "package.json" ] }, bower: { src: [ "bower.json" ] } }, watch: { files: [ files.source, files.grunt, files.speed, "<%= jshint.tests.src %>", "{package,bower}.json", "test/index.html" ], tasks: "default" } }); // Integrate Sizzle specific tasks grunt.loadTasks( "tasks" ); // Load dev dependencies require( "load-grunt-tasks" )( grunt ); grunt.registerTask( "lint", [ "jsonlint", "jshint", "jscs" ] ); grunt.registerTask( "build", [ "lint", "compile", "uglify", "dist" ] ); grunt.registerTask( "test", [ "lint", "qunit" ] ); grunt.registerTask( "default", [ "build", "qunit", "compare_size" ] ); // Task aliases grunt.registerTask( "bower", "bowercopy" ); }; sizzle-1.10.17/MIT-LICENSE.txt000066400000000000000000000021131226755370700154660ustar00rootroot00000000000000Copyright 2013 jQuery Foundation and other contributors http://jquery.com/ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. sizzle-1.10.17/README.md000066400000000000000000000045511226755370700145030ustar00rootroot00000000000000# Sizzle __A pure-JavaScript CSS selector engine designed to be easily dropped in to a host library.__ - [More information](http://sizzlejs.com/) - [Documentation](https://github.com/jquery/sizzle/wiki/Sizzle-Documentation) - [Browser support](https://github.com/jquery/sizzle/wiki/Sizzle-Documentation#wiki-browsers) Contribution Guides --------------------------- In the spirit of open source software development, jQuery always encourages community code contribution. To help you get started and before you jump into writing code, be sure to read these important contribution guidelines thoroughly: 1. [Getting Involved](http://contribute.jquery.org/) 2. [JavaScript Style Guide](http://contribute.jquery.org/style-guide/js/) 3. [Writing Code for jQuery Foundation Projects](http://contribute.jquery.org/code/) What you need to build Sizzle --------------------------- In order to build Sizzle, you need to have Node.js/npm latest and git 1.7 or later. (Earlier versions might work OK, but are not tested.) For Windows you have to download and install [git](http://git-scm.com/downloads) and [Node.js](http://nodejs.org/download/). Mac OS users should install [Homebrew](http://mxcl.github.com/homebrew/). Once Homebrew is installed, run `brew install git` to install git, and `brew install node` to install Node.js. Linux/BSD users should use their appropriate package managers to install git and Node.js, or build from source if you swing that way. Easy-peasy. How to build Sizzle ---------------------------- Clone a copy of the main Sizzle git repo by running: ```bash git clone git://github.com/jquery/sizzle.git ``` In the `sizzle/dist` folder you will find build version of sizzle along with the minified copy and associated map file. Testing ---------------------------- - Run `npm install`, it's also preferable (but not necessarily) to globally install `grunt-cli` package – `npm install -g grunt-cli` - Open `test/index.html` in the browser or run `npm test` or `grunt test` on the command line - The actual unit tests are in the `test/unit` directory. Developing with [grunt](http://gruntjs.com) ---------------------------- - `npm run build` or `grunt` will lint, build, test, and compare the sizes of the built files. - `npm start` or `grunt watch` can be run to re-lint, re-build, and re-test files as you change them. - `grunt -help` will show other available commands sizzle-1.10.17/bower.json000066400000000000000000000006251226755370700152330ustar00rootroot00000000000000{ "name": "sizzle", "version": "1.10.17", "main": "./dist/sizzle.js", "devDependencies": { "qunit": "~1.12.0", "benchmark": "~1.0.0", "requirejs": "~2.1.8", "requirejs-domready": "~2.0.1", "requirejs-text": "~2.0.10" }, "ignore": [ "**/.*", "package.json", "bower.json", "speed", "Makefile", "*.md", "*.txt", "src", "Gruntfile.js" ] } sizzle-1.10.17/dist/000077500000000000000000000000001226755370700141625ustar00rootroot00000000000000sizzle-1.10.17/dist/sizzle.js000066400000000000000000001615721226755370700160540ustar00rootroot00000000000000/*! * Sizzle CSS Selector Engine v1.10.17 * http://sizzlejs.com/ * * Copyright 2013 jQuery Foundation, Inc. and other contributors * Released under the MIT license * http://jquery.org/license * * Date: 2014-01-21 */ (function( window ) { var i, support, Expr, getText, isXML, compile, select, outermostContext, sortInput, hasDuplicate, // 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(), sortOrder = function( a, b ) { if ( a === b ) { hasDuplicate = true; } 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 + "*" ), 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" ) }, rinputs = /^(?:input|select|textarea|button)$/i, rheader = /^h\d$/i, rnative = /^[^{]+\{\s*\[native \w/, // Easily-parseable/retrievable ID or TAG or CLASS selectors rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, rsibling = /[+~]/, 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 : high < 0 ? // BMP codepoint 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 (jQuery #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 ) && testContext( 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]); } } }); }); } /** * Checks a node for validity as a Sizzle context * @param {Element|Object=} context * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value */ function testContext( context ) { return context && typeof context.getElementsByTagName !== strundefined && context; } // Expose support vars for convenience support = Sizzle.support = {}; /** * Detects XML nodes * @param {Element|Object} elem An element or a document * @returns {Boolean} True iff elem is a non-HTML XML node */ 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; }; /** * 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 hasCompare, 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 !== parent.top ) { // IE11 does not have attachEvent, so all must suffer if ( parent.addEventListener ) { parent.addEventListener( "unload", function() { setDocument(); }, false ); } else if ( parent.attachEvent ) { parent.attachEvent( "onunload", 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 = rnative.test( doc.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, Opera 10-12 // Nothing should be selected when empty strings follow ^= or $= or *= if ( div.querySelectorAll("[t^='']").length ) { rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); } // 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: Windows 8 Native Apps // The type and name attributes are restricted during .innerHTML assignment var input = doc.createElement("input"); input.setAttribute( "type", "hidden" ); div.appendChild( input ).setAttribute( "name", "D" ); // Support: IE8 // Enforce case-sensitivity of name attribute if ( div.querySelectorAll("[name=d]").length ) { rbuggyQSA.push( "name" + 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 ---------------------------------------------------------------------- */ hasCompare = rnative.test( docElem.compareDocumentPosition ); // Element contains another // Purposefully does not implement inclusive descendent // As in, an element does not contain itself contains = hasCompare || rnative.test( docElem.contains ) ? 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 = hasCompare ? function( a, b ) { // Flag for duplicate removal if ( a === b ) { hasDuplicate = true; return 0; } // Sort on method existence if only one input has compareDocumentPosition var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; if ( compare ) { return compare; } // Calculate position if both inputs belong to the same document compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ? a.compareDocumentPosition( b ) : // Otherwise we know they are disconnected 1; // 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 || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { return -1; } if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { return 1; } // Maintain original order return sortInput ? ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : 0; } return compare & 4 ? -1 : 1; } : function( a, b ) { // Exit early if the nodes are identical if ( a === b ) { hasDuplicate = true; return 0; } var cur, i = 0, aup = a.parentNode, bup = b.parentNode, ap = [ a ], bp = [ b ]; // Parentless nodes are either documents or disconnected 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 ? val : support.attributes || !documentIsHTML ? elem.getAttribute( name ) : (val = elem.getAttributeNode(name)) && val.specified ? val.value : null; }; 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 ); } } // Clear input after sorting to release objects // See https://github.com/jquery/sizzle/pull/225 sortInput = null; 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 while ( (node = elem[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 (jQuery #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 negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), // but not by others (comment: 8; processing instruction: 7; etc.) // nodeType < 6 works because attributes (2) do not appear as children for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { if ( elem.nodeType < 6 ) { 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; return elem.nodeName.toLowerCase() === "input" && elem.type === "text" && // Support: IE<8 // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" ); }, // 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 oldCache, outerCache, newCache = [ 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 ( (oldCache = outerCache[ dir ]) && oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { // Assign to newCache so results back-propagate to previous elements return (newCache[ 2 ] = oldCache[ 2 ]); } else { // Reuse newcache so results back-propagate to previous elements outerCache[ dir ] = newCache; // A match means we're done; a fail means we have to keep checking if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { 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 multipleContexts( selector, contexts, results ) { var i = 0, len = contexts.length; for ( ; i < len; i++ ) { Sizzle( selector, contexts[i], results ); } return results; } 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 ) { var bySet = setMatchers.length > 0, byElement = elementMatchers.length > 0, superMatcher = function( seed, context, xml, results, outermost ) { var elem, j, matcher, matchedCount = 0, i = "0", unmatched = seed && [], setMatched = [], contextBackup = outermostContext, // We must always have either seed elements or outermost context elems = seed || byElement && Expr.find["TAG"]( "*", outermost ), // Use integer dirruns iff this is the outermost matcher dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), len = elems.length; if ( outermost ) { outermostContext = context !== document && context; } // Add elements passing elementMatchers directly to results // Keep `i` a string if there are no elements so `matchedCount` will be "00" below // Support: IE<9, Safari // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id for ( ; i !== len && (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; } } // 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, match /* 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 ( !match ) { match = tokenize( selector ); } i = match.length; while ( i-- ) { cached = matcherFromTokens( match[i] ); if ( cached[ expando ] ) { setMatchers.push( cached ); } else { elementMatchers.push( cached ); } } // Cache the compiled function cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); // Save selector and tokenization cached.selector = selector; cached.match = match; } return cached; }; /** * A low-level selection function that works with Sizzle's compiled * selector functions * @param {String|Function} selector A selector or a pre-compiled * selector function built with Sizzle.compile * @param {Element} context * @param {Array} [results] * @param {Array} [seed] A set of elements to match against */ select = Sizzle.select = function( selector, context, results, seed ) { var i, tokens, token, type, find, match, compiled; results = results || []; if ( typeof selector === "function" ) { compiled = selector; match = compiled.match; selector = compiled.selector; } else { 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 ( !compiled && 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 ) && testContext( 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 if one is not provided // Provide `match` to avoid retokenization if we modified the selector above ( compiled || compile( selector, match ) )( seed, context, !documentIsHTML, results, rsibling.test( selector ) && testContext( context.parentNode ) || context ); 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 elem[ name ] === true ? name.toLowerCase() : (val = elem.getAttributeNode( name )) && val.specified ? val.value : null; } }); } // EXPOSE if ( typeof define === "function" && define.amd ) { define(function() { return Sizzle; }); // Sizzle requires that there be a global window in Common-JS like environments } else if ( typeof module !== "undefined" && module.exports ) { module.exports = Sizzle; } else { window.Sizzle = Sizzle; } // EXPOSE })( window ); sizzle-1.10.17/dist/sizzle.min.js000066400000000000000000000441161226755370700166300ustar00rootroot00000000000000/*! Sizzle v1.10.17 | (c) 2013 jQuery Foundation, Inc. | jquery.org/license */ !function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t="sizzle"+-new Date,u=a.document,v=0,w=0,x=fb(),y=fb(),z=fb(),A=function(a,b){return a===b&&(k=!0),0},B="undefined",C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=E.indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]===a)return b;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N=M.replace("w","w#"),O="\\["+L+"*("+M+")"+L+"*(?:([*^$|!~]?=)"+L+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+N+")|)|)"+L+"*\\]",P=":("+M+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+O.replace(3,8)+")*)|.*)\\)|)",Q=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),R=new RegExp("^"+L+"*,"+L+"*"),S=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),T=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),U=new RegExp(P),V=new RegExp("^"+N+"$"),W={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+O),PSEUDO:new RegExp("^"+P),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},X=/^(?:input|select|textarea|button)$/i,Y=/^h\d$/i,Z=/^[^{]+\{\s*\[native \w/,$=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,_=/[+~]/,ab=/'|\\/g,bb=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),cb=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)};try{H.apply(E=I.call(u.childNodes),u.childNodes),E[u.childNodes.length].nodeType}catch(db){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function eb(a,b,d,e){var f,g,i,j,k,n,q,r,v,w;if((b?b.ownerDocument||b:u)!==m&&l(b),b=b||m,d=d||[],!a||"string"!=typeof a)return d;if(1!==(j=b.nodeType)&&9!==j)return[];if(o&&!e){if(f=$.exec(a))if(i=f[1]){if(9===j){if(g=b.getElementById(i),!g||!g.parentNode)return d;if(g.id===i)return d.push(g),d}else if(b.ownerDocument&&(g=b.ownerDocument.getElementById(i))&&s(b,g)&&g.id===i)return d.push(g),d}else{if(f[2])return H.apply(d,b.getElementsByTagName(a)),d;if((i=f[3])&&c.getElementsByClassName&&b.getElementsByClassName)return H.apply(d,b.getElementsByClassName(i)),d}if(c.qsa&&(!p||!p.test(a))){if(r=q=t,v=b,w=9===j&&a,1===j&&"object"!==b.nodeName.toLowerCase()){n=pb(a),(q=b.getAttribute("id"))?r=q.replace(ab,"\\$&"):b.setAttribute("id",r),r="[id='"+r+"'] ",k=n.length;while(k--)n[k]=r+qb(n[k]);v=_.test(a)&&nb(b.parentNode)||b,w=n.join(",")}if(w)try{return H.apply(d,v.querySelectorAll(w)),d}catch(x){}finally{q||b.removeAttribute("id")}}}return h(a.replace(Q,"$1"),b,d,e)}function fb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function gb(a){return a[t]=!0,a}function hb(a){var b=m.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ib(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function jb(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function kb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function lb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function mb(a){return gb(function(b){return b=+b,gb(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function nb(a){return a&&typeof a.getElementsByTagName!==B&&a}c=eb.support={},f=eb.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},l=eb.setDocument=function(a){var b,e=a?a.ownerDocument||a:u,g=e.defaultView;return e!==m&&9===e.nodeType&&e.documentElement?(m=e,n=e.documentElement,o=!f(e),g&&g!==g.top&&(g.addEventListener?g.addEventListener("unload",function(){l()},!1):g.attachEvent&&g.attachEvent("onunload",function(){l()})),c.attributes=hb(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=hb(function(a){return a.appendChild(e.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Z.test(e.getElementsByClassName)&&hb(function(a){return a.innerHTML="
",a.firstChild.className="i",2===a.getElementsByClassName("i").length}),c.getById=hb(function(a){return n.appendChild(a).id=t,!e.getElementsByName||!e.getElementsByName(t).length}),c.getById?(d.find.ID=function(a,b){if(typeof b.getElementById!==B&&o){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(bb,cb);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(bb,cb);return function(a){var c=typeof a.getAttributeNode!==B&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return typeof b.getElementsByTagName!==B?b.getElementsByTagName(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return typeof b.getElementsByClassName!==B&&o?b.getElementsByClassName(a):void 0},q=[],p=[],(c.qsa=Z.test(e.querySelectorAll))&&(hb(function(a){a.innerHTML="",a.querySelectorAll("[t^='']").length&&p.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||p.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll(":checked").length||p.push(":checked")}),hb(function(a){var b=e.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&p.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||p.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),p.push(",.*:")})),(c.matchesSelector=Z.test(r=n.webkitMatchesSelector||n.mozMatchesSelector||n.oMatchesSelector||n.msMatchesSelector))&&hb(function(a){c.disconnectedMatch=r.call(a,"div"),r.call(a,"[s!='']:x"),q.push("!=",P)}),p=p.length&&new RegExp(p.join("|")),q=q.length&&new RegExp(q.join("|")),b=Z.test(n.compareDocumentPosition),s=b||Z.test(n.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},A=b?function(a,b){if(a===b)return k=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===e||a.ownerDocument===u&&s(u,a)?-1:b===e||b.ownerDocument===u&&s(u,b)?1:j?J.call(j,a)-J.call(j,b):0:4&d?-1:1)}:function(a,b){if(a===b)return k=!0,0;var c,d=0,f=a.parentNode,g=b.parentNode,h=[a],i=[b];if(!f||!g)return a===e?-1:b===e?1:f?-1:g?1:j?J.call(j,a)-J.call(j,b):0;if(f===g)return jb(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?jb(h[d],i[d]):h[d]===u?-1:i[d]===u?1:0},e):m},eb.matches=function(a,b){return eb(a,null,null,b)},eb.matchesSelector=function(a,b){if((a.ownerDocument||a)!==m&&l(a),b=b.replace(T,"='$1']"),!(!c.matchesSelector||!o||q&&q.test(b)||p&&p.test(b)))try{var d=r.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return eb(b,m,null,[a]).length>0},eb.contains=function(a,b){return(a.ownerDocument||a)!==m&&l(a),s(a,b)},eb.attr=function(a,b){(a.ownerDocument||a)!==m&&l(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!o):void 0;return void 0!==f?f:c.attributes||!o?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},eb.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},eb.uniqueSort=function(a){var b,d=[],e=0,f=0;if(k=!c.detectDuplicates,j=!c.sortStable&&a.slice(0),a.sort(A),k){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return j=null,a},e=eb.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=eb.selectors={cacheLength:50,createPseudo:gb,match:W,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(bb,cb),a[3]=(a[4]||a[5]||"").replace(bb,cb),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||eb.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&eb.error(a[0]),a},PSEUDO:function(a){var b,c=!a[5]&&a[2];return W.CHILD.test(a[0])?null:(a[3]&&void 0!==a[4]?a[2]=a[4]:c&&U.test(c)&&(b=pb(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(bb,cb).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=x[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&x(a,function(a){return b.test("string"==typeof a.className&&a.className||typeof a.getAttribute!==B&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=eb.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[t]||(q[t]={}),j=k[a]||[],n=j[0]===v&&j[1],m=j[0]===v&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[v,n,m];break}}else if(s&&(j=(b[t]||(b[t]={}))[a])&&j[0]===v)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[t]||(l[t]={}))[a]=[v,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||eb.error("unsupported pseudo: "+a);return e[t]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?gb(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J.call(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:gb(function(a){var b=[],c=[],d=g(a.replace(Q,"$1"));return d[t]?gb(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),!c.pop()}}),has:gb(function(a){return function(b){return eb(a,b).length>0}}),contains:gb(function(a){return function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:gb(function(a){return V.test(a||"")||eb.error("unsupported lang: "+a),a=a.replace(bb,cb).toLowerCase(),function(b){var c;do if(c=o?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===n},focus:function(a){return a===m.activeElement&&(!m.hasFocus||m.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Y.test(a.nodeName)},input:function(a){return X.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:mb(function(){return[0]}),last:mb(function(a,b){return[b-1]}),eq:mb(function(a,b,c){return[0>c?c+b:c]}),even:mb(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:mb(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:mb(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:mb(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function rb(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=w++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[v,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[t]||(b[t]={}),(h=i[d])&&h[0]===v&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function sb(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function tb(a,b,c){for(var d=0,e=b.length;e>d;d++)eb(a,b[d],c);return c}function ub(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function vb(a,b,c,d,e,f){return d&&!d[t]&&(d=vb(d)),e&&!e[t]&&(e=vb(e,f)),gb(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||tb(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ub(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ub(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J.call(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ub(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function wb(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],j=g?1:0,k=rb(function(a){return a===b},h,!0),l=rb(function(a){return J.call(b,a)>-1},h,!0),m=[function(a,c,d){return!g&&(d||c!==i)||((b=c).nodeType?k(a,c,d):l(a,c,d))}];f>j;j++)if(c=d.relative[a[j].type])m=[rb(sb(m),c)];else{if(c=d.filter[a[j].type].apply(null,a[j].matches),c[t]){for(e=++j;f>e;e++)if(d.relative[a[e].type])break;return vb(j>1&&sb(m),j>1&&qb(a.slice(0,j-1).concat({value:" "===a[j-2].type?"*":""})).replace(Q,"$1"),c,e>j&&wb(a.slice(j,e)),f>e&&wb(a=a.slice(e)),f>e&&qb(a))}m.push(c)}return sb(m)}function xb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,j,k){var l,n,o,p=0,q="0",r=f&&[],s=[],t=i,u=f||e&&d.find.TAG("*",k),w=v+=null==t?1:Math.random()||.1,x=u.length;for(k&&(i=g!==m&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){n=0;while(o=a[n++])if(o(l,g,h)){j.push(l);break}k&&(v=w)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){n=0;while(o=b[n++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=F.call(j));s=ub(s)}H.apply(j,s),k&&!f&&s.length>0&&p+b.length>1&&eb.uniqueSort(j)}return k&&(v=w,i=t),r};return c?gb(f):f}g=eb.compile=function(a,b){var c,d=[],e=[],f=z[a+" "];if(!f){b||(b=pb(a)),c=b.length;while(c--)f=wb(b[c]),f[t]?d.push(f):e.push(f);f=z(a,xb(e,d)),f.selector=a,f.match=b}return f},h=eb.select=function(a,b,e,f){var h,i,j,k,l,m,n;if(e=e||[],"function"==typeof a?(n=a,m=n.match,a=n.selector):m=pb(a),!f&&1===m.length){if(i=m[0]=m[0].slice(0),!n&&i.length>2&&"ID"===(j=i[0]).type&&c.getById&&9===b.nodeType&&o&&d.relative[i[1].type]){if(b=(d.find.ID(j.matches[0].replace(bb,cb),b)||[])[0],!b)return e;a=a.slice(i.shift().value.length)}h=W.needsContext.test(a)?0:i.length;while(h--){if(j=i[h],d.relative[k=j.type])break;if((l=d.find[k])&&(f=l(j.matches[0].replace(bb,cb),_.test(i[0].type)&&nb(b.parentNode)||b))){if(i.splice(h,1),a=f.length&&qb(i),!a)return H.apply(e,f),e;break}}}return(n||g(a,m))(f,b,!o,e,_.test(a)&&nb(b.parentNode)||b),e},c.sortStable=t.split("").sort(A).join("")===t,c.detectDuplicates=!!k,l(),c.sortDetached=hb(function(a){return 1&a.compareDocumentPosition(m.createElement("div"))}),hb(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||ib("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&hb(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ib("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),hb(function(a){return null==a.getAttribute("disabled")})||ib(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),"function"==typeof define&&define.amd?define(function(){return eb}):"undefined"!=typeof module&&module.exports?module.exports=eb:a.Sizzle=eb}(window); //# sourceMappingURL=dist/sizzle.min.mapsizzle-1.10.17/dist/sizzle.min.map000066400000000000000000000705071226755370700167740ustar00rootroot00000000000000{"version":3,"file":"sizzle.min.js","sources":["sizzle.js"],"names":["window","i","support","Expr","getText","isXML","compile","select","outermostContext","sortInput","hasDuplicate","setDocument","document","docElem","documentIsHTML","rbuggyQSA","rbuggyMatches","matches","contains","expando","Date","preferredDoc","dirruns","done","classCache","createCache","tokenCache","compilerCache","sortOrder","a","b","strundefined","MAX_NEGATIVE","hasOwn","hasOwnProperty","arr","pop","push_native","push","slice","indexOf","elem","len","this","length","booleans","whitespace","characterEncoding","identifier","replace","attributes","pseudos","rtrim","RegExp","rcomma","rcombinators","rattributeQuotes","rpseudo","ridentifier","matchExpr","ID","CLASS","TAG","ATTR","PSEUDO","CHILD","bool","needsContext","rinputs","rheader","rnative","rquickExpr","rsibling","rescape","runescape","funescape","_","escaped","escapedWhitespace","high","String","fromCharCode","apply","call","childNodes","nodeType","e","target","els","j","Sizzle","selector","context","results","seed","match","m","groups","old","nid","newContext","newSelector","ownerDocument","exec","getElementById","parentNode","id","getElementsByTagName","getElementsByClassName","qsa","test","nodeName","toLowerCase","tokenize","getAttribute","setAttribute","toSelector","testContext","join","querySelectorAll","qsaError","removeAttribute","keys","cache","key","value","cacheLength","shift","markFunction","fn","assert","div","createElement","removeChild","addHandle","attrs","handler","split","attrHandle","siblingCheck","cur","diff","sourceIndex","nextSibling","createInputPseudo","type","name","createButtonPseudo","createPositionalPseudo","argument","matchIndexes","documentElement","node","hasCompare","doc","parent","defaultView","top","addEventListener","attachEvent","className","appendChild","createComment","innerHTML","firstChild","getById","getElementsByName","find","filter","attrId","getAttributeNode","tag","tmp","input","matchesSelector","webkitMatchesSelector","mozMatchesSelector","oMatchesSelector","msMatchesSelector","disconnectedMatch","compareDocumentPosition","adown","bup","compare","sortDetached","aup","ap","bp","unshift","expr","elements","ret","attr","val","undefined","specified","error","msg","Error","uniqueSort","duplicates","detectDuplicates","sortStable","sort","splice","textContent","nodeValue","selectors","createPseudo","relative",">","dir","first"," ","+","~","preFilter","excess","unquoted","nodeNameSelector","pattern","operator","check","result","what","last","simple","forward","ofType","xml","outerCache","nodeIndex","start","useCache","lastChild","pseudo","args","setFilters","idx","matched","not","matcher","unmatched","has","text","innerText","lang","elemLang","hash","location","root","focus","activeElement","hasFocus","href","tabIndex","enabled","disabled","checked","selected","selectedIndex","empty","header","button","eq","even","odd","lt","gt","radio","checkbox","file","password","image","submit","reset","prototype","filters","parseOnly","tokens","soFar","preFilters","cached","addCombinator","combinator","base","checkNonElements","doneName","oldCache","newCache","elementMatcher","matchers","multipleContexts","contexts","condense","map","newUnmatched","mapped","setMatcher","postFilter","postFinder","postSelector","temp","preMap","postMap","preexisting","elems","matcherIn","matcherOut","matcherFromTokens","checkContext","leadingRelative","implicitRelative","matchContext","matchAnyContext","concat","matcherFromGroupMatchers","elementMatchers","setMatchers","bySet","byElement","superMatcher","outermost","matchedCount","setMatched","contextBackup","dirrunsUnique","Math","random","token","compiled","div1","defaultValue","define","amd","module","exports"],"mappings":";CAUA,SAAWA,GAEX,GAAIC,GACHC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EAGAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EAGAC,EAAU,UAAY,GAAKC,MAC3BC,EAAerB,EAAOY,SACtBU,EAAU,EACVC,EAAO,EACPC,EAAaC,KACbC,EAAaD,KACbE,EAAgBF,KAChBG,EAAY,SAAUC,EAAGC,GAIxB,MAHKD,KAAMC,IACVpB,GAAe,GAET,GAIRqB,EAAe,YACfC,EAAe,GAAK,GAGpBC,KAAcC,eACdC,KACAC,EAAMD,EAAIC,IACVC,EAAcF,EAAIG,KAClBA,EAAOH,EAAIG,KACXC,EAAQJ,EAAII,MAEZC,EAAUL,EAAIK,SAAW,SAAUC,GAGlC,IAFA,GAAIxC,GAAI,EACPyC,EAAMC,KAAKC,OACAF,EAAJzC,EAASA,IAChB,GAAK0C,KAAK1C,KAAOwC,EAChB,MAAOxC,EAGT,OAAO,IAGR4C,EAAW,6HAKXC,EAAa,sBAEbC,EAAoB,mCAKpBC,EAAaD,EAAkBE,QAAS,IAAK,MAG7CC,EAAa,MAAQJ,EAAa,KAAOC,EAAoB,IAAMD,EAClE,mBAAqBA,EAAa,wCAA0CE,EAAa,QAAUF,EAAa,OAQjHK,EAAU,KAAOJ,EAAoB,mEAAqEG,EAAWD,QAAS,EAAG,GAAM,eAGvIG,EAAQ,GAAIC,QAAQ,IAAMP,EAAa,8BAAgCA,EAAa,KAAM,KAE1FQ,EAAS,GAAID,QAAQ,IAAMP,EAAa,KAAOA,EAAa,KAC5DS,EAAe,GAAIF,QAAQ,IAAMP,EAAa,WAAaA,EAAa,IAAMA,EAAa,KAE3FU,EAAmB,GAAIH,QAAQ,IAAMP,EAAa,iBAAmBA,EAAa,OAAQ,KAE1FW,EAAU,GAAIJ,QAAQF,GACtBO,EAAc,GAAIL,QAAQ,IAAML,EAAa,KAE7CW,GACCC,GAAM,GAAIP,QAAQ,MAAQN,EAAoB,KAC9Cc,MAAS,GAAIR,QAAQ,QAAUN,EAAoB,KACnDe,IAAO,GAAIT,QAAQ,KAAON,EAAkBE,QAAS,IAAK,MAAS,KACnEc,KAAQ,GAAIV,QAAQ,IAAMH,GAC1Bc,OAAU,GAAIX,QAAQ,IAAMF,GAC5Bc,MAAS,GAAIZ,QAAQ,yDAA2DP,EAC/E,+BAAiCA,EAAa,cAAgBA,EAC9D,aAAeA,EAAa,SAAU,KACvCoB,KAAQ,GAAIb,QAAQ,OAASR,EAAW,KAAM,KAG9CsB,aAAgB,GAAId,QAAQ,IAAMP,EAAa,mDAC9CA,EAAa,mBAAqBA,EAAa,mBAAoB,MAGrEsB,EAAU,sCACVC,EAAU,SAEVC,EAAU,yBAGVC,EAAa,mCAEbC,EAAW,OACXC,GAAU,QAGVC,GAAY,GAAIrB,QAAQ,qBAAuBP,EAAa,MAAQA,EAAa,OAAQ,MACzF6B,GAAY,SAAUC,EAAGC,EAASC,GACjC,GAAIC,GAAO,KAAOF,EAAU,KAI5B,OAAOE,KAASA,GAAQD,EACvBD,EACO,EAAPE,EAECC,OAAOC,aAAcF,EAAO,OAE5BC,OAAOC,aAAcF,GAAQ,GAAK,MAAe,KAAPA,EAAe,OAI7D,KACCzC,EAAK4C,MACH/C,EAAMI,EAAM4C,KAAM9D,EAAa+D,YAChC/D,EAAa+D,YAIdjD,EAAKd,EAAa+D,WAAWxC,QAASyC,SACrC,MAAQC,IACThD,GAAS4C,MAAO/C,EAAIS,OAGnB,SAAU2C,EAAQC,GACjBnD,EAAY6C,MAAOK,EAAQhD,EAAM4C,KAAKK,KAKvC,SAAUD,EAAQC,GACjB,GAAIC,GAAIF,EAAO3C,OACd3C,EAAI,CAEL,OAASsF,EAAOE,KAAOD,EAAIvF,MAC3BsF,EAAO3C,OAAS6C,EAAI,IAKvB,QAASC,IAAQC,EAAUC,EAASC,EAASC,GAC5C,GAAIC,GAAOtD,EAAMuD,EAAGX,EAEnBpF,EAAGgG,EAAQC,EAAKC,EAAKC,EAAYC,CASlC,KAPOT,EAAUA,EAAQU,eAAiBV,EAAUvE,KAAmBT,GACtED,EAAaiF,GAGdA,EAAUA,GAAWhF,EACrBiF,EAAUA,OAEJF,GAAgC,gBAAbA,GACxB,MAAOE,EAGR,IAAuC,KAAjCR,EAAWO,EAAQP,WAAgC,IAAbA,EAC3C,QAGD,IAAKvE,IAAmBgF,EAAO,CAG9B,GAAMC,EAAQxB,EAAWgC,KAAMZ,GAE9B,GAAMK,EAAID,EAAM,IACf,GAAkB,IAAbV,EAAiB,CAIrB,GAHA5C,EAAOmD,EAAQY,eAAgBR,IAG1BvD,IAAQA,EAAKgE,WAQjB,MAAOZ,EALP,IAAKpD,EAAKiE,KAAOV,EAEhB,MADAH,GAAQvD,KAAMG,GACPoD,MAOT,IAAKD,EAAQU,gBAAkB7D,EAAOmD,EAAQU,cAAcE,eAAgBR,KAC3E9E,EAAU0E,EAASnD,IAAUA,EAAKiE,KAAOV,EAEzC,MADAH,GAAQvD,KAAMG,GACPoD,MAKH,CAAA,GAAKE,EAAM,GAEjB,MADAzD,GAAK4C,MAAOW,EAASD,EAAQe,qBAAsBhB,IAC5CE,CAGD,KAAMG,EAAID,EAAM,KAAO7F,EAAQ0G,wBAA0BhB,EAAQgB,uBAEvE,MADAtE,GAAK4C,MAAOW,EAASD,EAAQgB,uBAAwBZ,IAC9CH,EAKT,GAAK3F,EAAQ2G,OAAS9F,IAAcA,EAAU+F,KAAMnB,IAAc,CASjE,GARAQ,EAAMD,EAAM/E,EACZiF,EAAaR,EACbS,EAA2B,IAAbhB,GAAkBM,EAMd,IAAbN,GAAqD,WAAnCO,EAAQmB,SAASC,cAA6B,CACpEf,EAASgB,GAAUtB,IAEbO,EAAMN,EAAQsB,aAAa,OAChCf,EAAMD,EAAIjD,QAASwB,GAAS,QAE5BmB,EAAQuB,aAAc,KAAMhB,GAE7BA,EAAM,QAAUA,EAAM,MAEtBlG,EAAIgG,EAAOrD,MACX,OAAQ3C,IACPgG,EAAOhG,GAAKkG,EAAMiB,GAAYnB,EAAOhG,GAEtCmG,GAAa5B,EAASsC,KAAMnB,IAAc0B,GAAazB,EAAQa,aAAgBb,EAC/ES,EAAcJ,EAAOqB,KAAK,KAG3B,GAAKjB,EACJ,IAIC,MAHA/D,GAAK4C,MAAOW,EACXO,EAAWmB,iBAAkBlB,IAEvBR,EACN,MAAM2B,IACN,QACKtB,GACLN,EAAQ6B,gBAAgB,QAQ7B,MAAOlH,GAAQoF,EAAS1C,QAASG,EAAO,MAAQwC,EAASC,EAASC,GASnE,QAASrE,MACR,GAAIiG,KAEJ,SAASC,GAAOC,EAAKC,GAMpB,MAJKH,GAAKpF,KAAMsF,EAAM,KAAQzH,EAAK2H,mBAE3BH,GAAOD,EAAKK,SAEZJ,EAAOC,EAAM,KAAQC,EAE9B,MAAOF,GAOR,QAASK,IAAcC,GAEtB,MADAA,GAAI9G,IAAY,EACT8G,EAOR,QAASC,IAAQD,GAChB,GAAIE,GAAMvH,EAASwH,cAAc,MAEjC,KACC,QAASH,EAAIE,GACZ,MAAO7C,GACR,OAAO,EACN,QAEI6C,EAAI1B,YACR0B,EAAI1B,WAAW4B,YAAaF,GAG7BA,EAAM,MASR,QAASG,IAAWC,EAAOC,GAC1B,GAAIrG,GAAMoG,EAAME,MAAM,KACrBxI,EAAIsI,EAAM3F,MAEX,OAAQ3C,IACPE,EAAKuI,WAAYvG,EAAIlC,IAAOuI,EAU9B,QAASG,IAAc9G,EAAGC,GACzB,GAAI8G,GAAM9G,GAAKD,EACdgH,EAAOD,GAAsB,IAAf/G,EAAEwD,UAAiC,IAAfvD,EAAEuD,YAChCvD,EAAEgH,aAAe9G,KACjBH,EAAEiH,aAAe9G,EAGtB,IAAK6G,EACJ,MAAOA,EAIR,IAAKD,EACJ,MAASA,EAAMA,EAAIG,YAClB,GAAKH,IAAQ9G,EACZ,MAAO,EAKV,OAAOD,GAAI,EAAI,GAOhB,QAASmH,IAAmBC,GAC3B,MAAO,UAAUxG,GAChB,GAAIyG,GAAOzG,EAAKsE,SAASC,aACzB,OAAgB,UAATkC,GAAoBzG,EAAKwG,OAASA,GAQ3C,QAASE,IAAoBF,GAC5B,MAAO,UAAUxG,GAChB,GAAIyG,GAAOzG,EAAKsE,SAASC,aACzB,QAAiB,UAATkC,GAA6B,WAATA,IAAsBzG,EAAKwG,OAASA,GAQlE,QAASG,IAAwBnB,GAChC,MAAOD,IAAa,SAAUqB,GAE7B,MADAA,IAAYA,EACLrB,GAAa,SAAUlC,EAAM7E,GACnC,GAAIwE,GACH6D,EAAerB,KAAQnC,EAAKlD,OAAQyG,GACpCpJ,EAAIqJ,EAAa1G,MAGlB,OAAQ3C,IACF6F,EAAOL,EAAI6D,EAAarJ,MAC5B6F,EAAKL,KAAOxE,EAAQwE,GAAKK,EAAKL,SAYnC,QAAS4B,IAAazB,GACrB,MAAOA,UAAkBA,GAAQe,uBAAyB5E,GAAgB6D,EAI3E1F,EAAUwF,GAAOxF,WAOjBG,EAAQqF,GAAOrF,MAAQ,SAAUoC,GAGhC,GAAI8G,GAAkB9G,IAASA,EAAK6D,eAAiB7D,GAAM8G,eAC3D,OAAOA,GAA+C,SAA7BA,EAAgBxC,UAAsB,GAQhEpG,EAAc+E,GAAO/E,YAAc,SAAU6I,GAC5C,GAAIC,GACHC,EAAMF,EAAOA,EAAKlD,eAAiBkD,EAAOnI,EAC1CsI,EAASD,EAAIE,WAGd,OAAKF,KAAQ9I,GAA6B,IAAjB8I,EAAIrE,UAAmBqE,EAAIH,iBAKpD3I,EAAW8I,EACX7I,EAAU6I,EAAIH,gBAGdzI,GAAkBT,EAAOqJ,GAMpBC,GAAUA,IAAWA,EAAOE,MAE3BF,EAAOG,iBACXH,EAAOG,iBAAkB,SAAU,WAClCnJ,MACE,GACQgJ,EAAOI,aAClBJ,EAAOI,YAAa,WAAY,WAC/BpJ,OAUHT,EAAQgD,WAAagF,GAAO,SAAUC,GAErC,MADAA,GAAI6B,UAAY,KACR7B,EAAIjB,aAAa,eAO1BhH,EAAQyG,qBAAuBuB,GAAO,SAAUC,GAE/C,MADAA,GAAI8B,YAAaP,EAAIQ,cAAc,MAC3B/B,EAAIxB,qBAAqB,KAAK/D,SAIvC1C,EAAQ0G,uBAAyBtC,EAAQwC,KAAM4C,EAAI9C,yBAA4BsB,GAAO,SAAUC,GAQ/F,MAPAA,GAAIgC,UAAY,+CAIhBhC,EAAIiC,WAAWJ,UAAY,IAGuB,IAA3C7B,EAAIvB,uBAAuB,KAAKhE,SAOxC1C,EAAQmK,QAAUnC,GAAO,SAAUC,GAElC,MADAtH,GAAQoJ,YAAa9B,GAAMzB,GAAKvF,GACxBuI,EAAIY,oBAAsBZ,EAAIY,kBAAmBnJ,GAAUyB,SAI/D1C,EAAQmK,SACZlK,EAAKoK,KAAS,GAAI,SAAU7D,EAAId,GAC/B,SAAYA,GAAQY,iBAAmBzE,GAAgBjB,EAAiB,CACvE,GAAIkF,GAAIJ,EAAQY,eAAgBE,EAGhC,OAAOV,IAAKA,EAAES,YAAcT,QAG9B7F,EAAKqK,OAAW,GAAI,SAAU9D,GAC7B,GAAI+D,GAAS/D,EAAGzD,QAASyB,GAAWC,GACpC,OAAO,UAAUlC,GAChB,MAAOA,GAAKyE,aAAa,QAAUuD,YAM9BtK,GAAKoK,KAAS,GAErBpK,EAAKqK,OAAW,GAAK,SAAU9D,GAC9B,GAAI+D,GAAS/D,EAAGzD,QAASyB,GAAWC,GACpC,OAAO,UAAUlC,GAChB,GAAI+G,SAAc/G,GAAKiI,mBAAqB3I,GAAgBU,EAAKiI,iBAAiB,KAClF,OAAOlB,IAAQA,EAAK3B,QAAU4C,KAMjCtK,EAAKoK,KAAU,IAAIrK,EAAQyG,qBAC1B,SAAUgE,EAAK/E,GACd,aAAYA,GAAQe,uBAAyB5E,EACrC6D,EAAQe,qBAAsBgE,GADtC,QAID,SAAUA,EAAK/E,GACd,GAAInD,GACHmI,KACA3K,EAAI,EACJ4F,EAAUD,EAAQe,qBAAsBgE,EAGzC,IAAa,MAARA,EAAc,CAClB,MAASlI,EAAOoD,EAAQ5F,KACA,IAAlBwC,EAAK4C,UACTuF,EAAItI,KAAMG,EAIZ,OAAOmI,GAER,MAAO/E,IAIT1F,EAAKoK,KAAY,MAAIrK,EAAQ0G,wBAA0B,SAAUoD,EAAWpE,GAC3E,aAAYA,GAAQgB,yBAA2B7E,GAAgBjB,EACvD8E,EAAQgB,uBAAwBoD,GADxC,QAWDhJ,KAOAD,MAEMb,EAAQ2G,IAAMvC,EAAQwC,KAAM4C,EAAInC,qBAGrCW,GAAO,SAAUC,GAMhBA,EAAIgC,UAAY,sDAIXhC,EAAIZ,iBAAiB,WAAW3E,QACpC7B,EAAUuB,KAAM,SAAWQ,EAAa,gBAKnCqF,EAAIZ,iBAAiB,cAAc3E,QACxC7B,EAAUuB,KAAM,MAAQQ,EAAa,aAAeD,EAAW,KAM1DsF,EAAIZ,iBAAiB,YAAY3E,QACtC7B,EAAUuB,KAAK,cAIjB4F,GAAO,SAAUC,GAGhB,GAAI0C,GAAQnB,EAAItB,cAAc,QAC9ByC,GAAM1D,aAAc,OAAQ,UAC5BgB,EAAI8B,YAAaY,GAAQ1D,aAAc,OAAQ,KAI1CgB,EAAIZ,iBAAiB,YAAY3E,QACrC7B,EAAUuB,KAAM,OAASQ,EAAa,eAKjCqF,EAAIZ,iBAAiB,YAAY3E,QACtC7B,EAAUuB,KAAM,WAAY,aAI7B6F,EAAIZ,iBAAiB,QACrBxG,EAAUuB,KAAK,YAIXpC,EAAQ4K,gBAAkBxG,EAAQwC,KAAO7F,EAAUJ,EAAQkK,uBAChElK,EAAQmK,oBACRnK,EAAQoK,kBACRpK,EAAQqK,qBAERhD,GAAO,SAAUC,GAGhBjI,EAAQiL,kBAAoBlK,EAAQkE,KAAMgD,EAAK,OAI/ClH,EAAQkE,KAAMgD,EAAK,aACnBnH,EAAcsB,KAAM,KAAMa,KAI5BpC,EAAYA,EAAU6B,QAAU,GAAIS,QAAQtC,EAAUuG,KAAK,MAC3DtG,EAAgBA,EAAc4B,QAAU,GAAIS,QAAQrC,EAAcsG,KAAK,MAIvEmC,EAAanF,EAAQwC,KAAMjG,EAAQuK,yBAKnClK,EAAWuI,GAAcnF,EAAQwC,KAAMjG,EAAQK,UAC9C,SAAUW,EAAGC,GACZ,GAAIuJ,GAAuB,IAAfxJ,EAAEwD,SAAiBxD,EAAE0H,gBAAkB1H,EAClDyJ,EAAMxJ,GAAKA,EAAE2E,UACd,OAAO5E,KAAMyJ,MAAWA,GAAwB,IAAjBA,EAAIjG,YAClCgG,EAAMnK,SACLmK,EAAMnK,SAAUoK,GAChBzJ,EAAEuJ,yBAA8D,GAAnCvJ,EAAEuJ,wBAAyBE,MAG3D,SAAUzJ,EAAGC,GACZ,GAAKA,EACJ,MAASA,EAAIA,EAAE2E,WACd,GAAK3E,IAAMD,EACV,OAAO,CAIV,QAAO,GAOTD,EAAY6H,EACZ,SAAU5H,EAAGC,GAGZ,GAAKD,IAAMC,EAEV,MADApB,IAAe,EACR,CAIR,IAAI6K,IAAW1J,EAAEuJ,yBAA2BtJ,EAAEsJ,uBAC9C,OAAKG,GACGA,GAIRA,GAAY1J,EAAEyE,eAAiBzE,MAAUC,EAAEwE,eAAiBxE,GAC3DD,EAAEuJ,wBAAyBtJ,GAG3B,EAGc,EAAVyJ,IACFrL,EAAQsL,cAAgB1J,EAAEsJ,wBAAyBvJ,KAAQ0J,EAGxD1J,IAAM6H,GAAO7H,EAAEyE,gBAAkBjF,GAAgBH,EAASG,EAAcQ,GACrE,GAEHC,IAAM4H,GAAO5H,EAAEwE,gBAAkBjF,GAAgBH,EAASG,EAAcS,GACrE,EAIDrB,EACJ+B,EAAQ2C,KAAM1E,EAAWoB,GAAMW,EAAQ2C,KAAM1E,EAAWqB,GAC1D,EAGe,EAAVyJ,EAAc,GAAK,IAE3B,SAAU1J,EAAGC,GAEZ,GAAKD,IAAMC,EAEV,MADApB,IAAe,EACR,CAGR,IAAIkI,GACH3I,EAAI,EACJwL,EAAM5J,EAAE4E,WACR6E,EAAMxJ,EAAE2E,WACRiF,GAAO7J,GACP8J,GAAO7J,EAGR,KAAM2J,IAAQH,EACb,MAAOzJ,KAAM6H,EAAM,GAClB5H,IAAM4H,EAAM,EACZ+B,EAAM,GACNH,EAAM,EACN7K,EACE+B,EAAQ2C,KAAM1E,EAAWoB,GAAMW,EAAQ2C,KAAM1E,EAAWqB,GAC1D,CAGK,IAAK2J,IAAQH,EACnB,MAAO3C,IAAc9G,EAAGC,EAIzB8G,GAAM/G,CACN,OAAS+G,EAAMA,EAAInC,WAClBiF,EAAGE,QAAShD,EAEbA,GAAM9G,CACN,OAAS8G,EAAMA,EAAInC,WAClBkF,EAAGC,QAAShD,EAIb,OAAQ8C,EAAGzL,KAAO0L,EAAG1L,GACpBA,GAGD,OAAOA,GAEN0I,GAAc+C,EAAGzL,GAAI0L,EAAG1L,IAGxByL,EAAGzL,KAAOoB,EAAe,GACzBsK,EAAG1L,KAAOoB,EAAe,EACzB,GAGKqI,GA7VC9I,GAgWT8E,GAAOzE,QAAU,SAAU4K,EAAMC,GAChC,MAAOpG,IAAQmG,EAAM,KAAM,KAAMC,IAGlCpG,GAAOoF,gBAAkB,SAAUrI,EAAMoJ,GASxC,IAPOpJ,EAAK6D,eAAiB7D,KAAW7B,GACvCD,EAAa8B,GAIdoJ,EAAOA,EAAK5I,QAASO,EAAkB,aAElCtD,EAAQ4K,kBAAmBhK,GAC5BE,GAAkBA,EAAc8F,KAAM+E,IACtC9K,GAAkBA,EAAU+F,KAAM+E,IAErC,IACC,GAAIE,GAAM9K,EAAQkE,KAAM1C,EAAMoJ,EAG9B,IAAKE,GAAO7L,EAAQiL,mBAGlB1I,EAAK7B,UAAuC,KAA3B6B,EAAK7B,SAASyE,SAChC,MAAO0G,GAEP,MAAMzG,IAGT,MAAOI,IAAQmG,EAAMjL,EAAU,MAAO6B,IAAQG,OAAS,GAGxD8C,GAAOxE,SAAW,SAAU0E,EAASnD,GAKpC,OAHOmD,EAAQU,eAAiBV,KAAchF,GAC7CD,EAAaiF,GAEP1E,EAAU0E,EAASnD,IAG3BiD,GAAOsG,KAAO,SAAUvJ,EAAMyG,IAEtBzG,EAAK6D,eAAiB7D,KAAW7B,GACvCD,EAAa8B,EAGd,IAAIwF,GAAK9H,EAAKuI,WAAYQ,EAAKlC,eAE9BiF,EAAMhE,GAAMhG,EAAOkD,KAAMhF,EAAKuI,WAAYQ,EAAKlC,eAC9CiB,EAAIxF,EAAMyG,GAAOpI,GACjBoL,MAEF,OAAeA,UAARD,EACNA,EACA/L,EAAQgD,aAAepC,EACtB2B,EAAKyE,aAAcgC,IAClB+C,EAAMxJ,EAAKiI,iBAAiBxB,KAAU+C,EAAIE,UAC1CF,EAAIpE,MACJ,MAGJnC,GAAO0G,MAAQ,SAAUC,GACxB,KAAM,IAAIC,OAAO,0CAA4CD,IAO9D3G,GAAO6G,WAAa,SAAU1G,GAC7B,GAAIpD,GACH+J,KACA/G,EAAI,EACJxF,EAAI,CAOL,IAJAS,GAAgBR,EAAQuM,iBACxBhM,GAAaP,EAAQwM,YAAc7G,EAAQtD,MAAO,GAClDsD,EAAQ8G,KAAM/K,GAETlB,EAAe,CACnB,MAAS+B,EAAOoD,EAAQ5F,KAClBwC,IAASoD,EAAS5F,KACtBwF,EAAI+G,EAAWlK,KAAMrC,GAGvB,OAAQwF,IACPI,EAAQ+G,OAAQJ,EAAY/G,GAAK,GAQnC,MAFAhF,GAAY,KAELoF,GAORzF,EAAUsF,GAAOtF,QAAU,SAAUqC,GACpC,GAAI+G,GACHuC,EAAM,GACN9L,EAAI,EACJoF,EAAW5C,EAAK4C,QAEjB,IAAMA,GAMC,GAAkB,IAAbA,GAA+B,IAAbA,GAA+B,KAAbA,EAAkB,CAGjE,GAAiC,gBAArB5C,GAAKoK,YAChB,MAAOpK,GAAKoK,WAGZ,KAAMpK,EAAOA,EAAK2H,WAAY3H,EAAMA,EAAOA,EAAKsG,YAC/CgD,GAAO3L,EAASqC,OAGZ,IAAkB,IAAb4C,GAA+B,IAAbA,EAC7B,MAAO5C,GAAKqK,cAhBZ,OAAStD,EAAO/G,EAAKxC,KAEpB8L,GAAO3L,EAASoJ,EAkBlB,OAAOuC,IAGR5L,EAAOuF,GAAOqH,WAGbjF,YAAa,GAEbkF,aAAchF,GAEdjC,MAAOpC,EAEP+E,cAEA6B,QAEA0C,UACCC,KAAOC,IAAK,aAAcC,OAAO,GACjCC,KAAOF,IAAK,cACZG,KAAOH,IAAK,kBAAmBC,OAAO,GACtCG,KAAOJ,IAAK,oBAGbK,WACCzJ,KAAQ,SAAUgC,GAUjB,MATAA,GAAM,GAAKA,EAAM,GAAG9C,QAASyB,GAAWC,IAGxCoB,EAAM,IAAOA,EAAM,IAAMA,EAAM,IAAM,IAAK9C,QAASyB,GAAWC,IAE5C,OAAboB,EAAM,KACVA,EAAM,GAAK,IAAMA,EAAM,GAAK,KAGtBA,EAAMxD,MAAO,EAAG,IAGxB0B,MAAS,SAAU8B,GA6BlB,MAlBAA,GAAM,GAAKA,EAAM,GAAGiB,cAEY,QAA3BjB,EAAM,GAAGxD,MAAO,EAAG,IAEjBwD,EAAM,IACXL,GAAO0G,MAAOrG,EAAM,IAKrBA,EAAM,KAAQA,EAAM,GAAKA,EAAM,IAAMA,EAAM,IAAM,GAAK,GAAmB,SAAbA,EAAM,IAA8B,QAAbA,EAAM,KACzFA,EAAM,KAAUA,EAAM,GAAKA,EAAM,IAAqB,QAAbA,EAAM,KAGpCA,EAAM,IACjBL,GAAO0G,MAAOrG,EAAM,IAGdA,GAGR/B,OAAU,SAAU+B,GACnB,GAAI0H,GACHC,GAAY3H,EAAM,IAAMA,EAAM,EAE/B,OAAKpC,GAAiB,MAAEmD,KAAMf,EAAM,IAC5B,MAIHA,EAAM,IAAmBmG,SAAbnG,EAAM,GACtBA,EAAM,GAAKA,EAAM,GAGN2H,GAAYjK,EAAQqD,KAAM4G,KAEpCD,EAASxG,GAAUyG,GAAU,MAE7BD,EAASC,EAASlL,QAAS,IAAKkL,EAAS9K,OAAS6K,GAAWC,EAAS9K,UAGvEmD,EAAM,GAAKA,EAAM,GAAGxD,MAAO,EAAGkL,GAC9B1H,EAAM,GAAK2H,EAASnL,MAAO,EAAGkL,IAIxB1H,EAAMxD,MAAO,EAAG,MAIzBiI,QAEC1G,IAAO,SAAU6J,GAChB,GAAI5G,GAAW4G,EAAiB1K,QAASyB,GAAWC,IAAYqC,aAChE,OAA4B,MAArB2G,EACN,WAAa,OAAO,GACpB,SAAUlL,GACT,MAAOA,GAAKsE,UAAYtE,EAAKsE,SAASC,gBAAkBD,IAI3DlD,MAAS,SAAUmG,GAClB,GAAI4D,GAAUpM,EAAYwI,EAAY,IAEtC,OAAO4D,KACLA,EAAU,GAAIvK,QAAQ,MAAQP,EAAa,IAAMkH,EAAY,IAAMlH,EAAa,SACjFtB,EAAYwI,EAAW,SAAUvH,GAChC,MAAOmL,GAAQ9G,KAAgC,gBAAnBrE,GAAKuH,WAA0BvH,EAAKuH,iBAAoBvH,GAAKyE,eAAiBnF,GAAgBU,EAAKyE,aAAa,UAAY,OAI3JnD,KAAQ,SAAUmF,EAAM2E,EAAUC,GACjC,MAAO,UAAUrL,GAChB,GAAIsL,GAASrI,GAAOsG,KAAMvJ,EAAMyG,EAEhC,OAAe,OAAV6E,EACgB,OAAbF,EAEFA,GAINE,GAAU,GAEU,MAAbF,EAAmBE,IAAWD,EACvB,OAAbD,EAAoBE,IAAWD,EAClB,OAAbD,EAAoBC,GAAqC,IAA5BC,EAAOvL,QAASsL,GAChC,OAAbD,EAAoBC,GAASC,EAAOvL,QAASsL,GAAU,GAC1C,OAAbD,EAAoBC,GAASC,EAAOxL,OAAQuL,EAAMlL,UAAakL,EAClD,OAAbD,GAAsB,IAAME,EAAS,KAAMvL,QAASsL,GAAU,GACjD,OAAbD,EAAoBE,IAAWD,GAASC,EAAOxL,MAAO,EAAGuL,EAAMlL,OAAS,KAAQkL,EAAQ,KACxF,IAZO,IAgBV7J,MAAS,SAAUgF,EAAM+E,EAAM3E,EAAU+D,EAAOa,GAC/C,GAAIC,GAAgC,QAAvBjF,EAAK1G,MAAO,EAAG,GAC3B4L,EAA+B,SAArBlF,EAAK1G,MAAO,IACtB6L,EAAkB,YAATJ,CAEV,OAAiB,KAAVZ,GAAwB,IAATa,EAGrB,SAAUxL,GACT,QAASA,EAAKgE,YAGf,SAAUhE,EAAMmD,EAASyI,GACxB,GAAI1G,GAAO2G,EAAY9E,EAAMX,EAAM0F,EAAWC,EAC7CrB,EAAMe,IAAWC,EAAU,cAAgB,kBAC3CxE,EAASlH,EAAKgE,WACdyC,EAAOkF,GAAU3L,EAAKsE,SAASC,cAC/ByH,GAAYJ,IAAQD,CAErB,IAAKzE,EAAS,CAGb,GAAKuE,EAAS,CACb,MAAQf,EAAM,CACb3D,EAAO/G,CACP,OAAS+G,EAAOA,EAAM2D,GACrB,GAAKiB,EAAS5E,EAAKzC,SAASC,gBAAkBkC,EAAyB,IAAlBM,EAAKnE,SACzD,OAAO,CAITmJ,GAAQrB,EAAe,SAATlE,IAAoBuF,GAAS,cAE5C,OAAO,EAMR,GAHAA,GAAUL,EAAUxE,EAAOS,WAAaT,EAAO+E,WAG1CP,GAAWM,EAAW,CAE1BH,EAAa3E,EAAQxI,KAAcwI,EAAQxI,OAC3CwG,EAAQ2G,EAAYrF,OACpBsF,EAAY5G,EAAM,KAAOrG,GAAWqG,EAAM,GAC1CkB,EAAOlB,EAAM,KAAOrG,GAAWqG,EAAM,GACrC6B,EAAO+E,GAAa5E,EAAOvE,WAAYmJ,EAEvC,OAAS/E,IAAS+E,GAAa/E,GAAQA,EAAM2D,KAG3CtE,EAAO0F,EAAY,IAAMC,EAAMpM,MAGhC,GAAuB,IAAlBoH,EAAKnE,YAAoBwD,GAAQW,IAAS/G,EAAO,CACrD6L,EAAYrF,IAAW3H,EAASiN,EAAW1F,EAC3C,YAKI,IAAK4F,IAAa9G,GAASlF,EAAMtB,KAAcsB,EAAMtB,QAAkB8H,KAAWtB,EAAM,KAAOrG,EACrGuH,EAAOlB,EAAM,OAKb,OAAS6B,IAAS+E,GAAa/E,GAAQA,EAAM2D,KAC3CtE,EAAO0F,EAAY,IAAMC,EAAMpM,MAEhC,IAAOgM,EAAS5E,EAAKzC,SAASC,gBAAkBkC,EAAyB,IAAlBM,EAAKnE,aAAsBwD,IAE5E4F,KACHjF,EAAMrI,KAAcqI,EAAMrI,QAAkB8H,IAAW3H,EAASuH,IAG7DW,IAAS/G,GACb,KAQJ,OADAoG,IAAQoF,EACDpF,IAASuE,GAAWvE,EAAOuE,IAAU,GAAKvE,EAAOuE,GAAS,KAKrEpJ,OAAU,SAAU2K,EAAQtF,GAK3B,GAAIuF,GACH3G,EAAK9H,EAAKgD,QAASwL,IAAYxO,EAAK0O,WAAYF,EAAO3H,gBACtDtB,GAAO0G,MAAO,uBAAyBuC,EAKzC,OAAK1G,GAAI9G,GACD8G,EAAIoB,GAIPpB,EAAGrF,OAAS,GAChBgM,GAASD,EAAQA,EAAQ,GAAItF,GACtBlJ,EAAK0O,WAAW3M,eAAgByM,EAAO3H,eAC7CgB,GAAa,SAAUlC,EAAM7E,GAC5B,GAAI6N,GACHC,EAAU9G,EAAInC,EAAMuD,GACpBpJ,EAAI8O,EAAQnM,MACb,OAAQ3C,IACP6O,EAAMtM,EAAQ2C,KAAMW,EAAMiJ,EAAQ9O,IAClC6F,EAAMgJ,KAAW7N,EAAS6N,GAAQC,EAAQ9O,MAG5C,SAAUwC,GACT,MAAOwF,GAAIxF,EAAM,EAAGmM,KAIhB3G,IAIT9E,SAEC6L,IAAOhH,GAAa,SAAUrC,GAI7B,GAAIkF,MACHhF,KACAoJ,EAAU3O,EAASqF,EAAS1C,QAASG,EAAO,MAE7C,OAAO6L,GAAS9N,GACf6G,GAAa,SAAUlC,EAAM7E,EAAS2E,EAASyI,GAC9C,GAAI5L,GACHyM,EAAYD,EAASnJ,EAAM,KAAMuI,MACjCpO,EAAI6F,EAAKlD,MAGV,OAAQ3C,KACDwC,EAAOyM,EAAUjP,MACtB6F,EAAK7F,KAAOgB,EAAQhB,GAAKwC,MAI5B,SAAUA,EAAMmD,EAASyI,GAGxB,MAFAxD,GAAM,GAAKpI,EACXwM,EAASpE,EAAO,KAAMwD,EAAKxI,IACnBA,EAAQzD,SAInB+M,IAAOnH,GAAa,SAAUrC,GAC7B,MAAO,UAAUlD,GAChB,MAAOiD,IAAQC,EAAUlD,GAAOG,OAAS,KAI3C1B,SAAY8G,GAAa,SAAUoH,GAClC,MAAO,UAAU3M,GAChB,OAASA,EAAKoK,aAAepK,EAAK4M,WAAajP,EAASqC,IAASD,QAAS4M,GAAS,MAWrFE,KAAQtH,GAAc,SAAUsH,GAM/B,MAJM5L,GAAYoD,KAAKwI,GAAQ,KAC9B5J,GAAO0G,MAAO,qBAAuBkD,GAEtCA,EAAOA,EAAKrM,QAASyB,GAAWC,IAAYqC,cACrC,SAAUvE,GAChB,GAAI8M,EACJ,GACC,IAAMA,EAAWzO,EAChB2B,EAAK6M,KACL7M,EAAKyE,aAAa,aAAezE,EAAKyE,aAAa,QAGnD,MADAqI,GAAWA,EAASvI,cACbuI,IAAaD,GAA2C,IAAnCC,EAAS/M,QAAS8M,EAAO,YAE5C7M,EAAOA,EAAKgE,aAAiC,IAAlBhE,EAAK4C,SAC3C,QAAO,KAKTE,OAAU,SAAU9C,GACnB,GAAI+M,GAAOxP,EAAOyP,UAAYzP,EAAOyP,SAASD,IAC9C,OAAOA,IAAQA,EAAKjN,MAAO,KAAQE,EAAKiE,IAGzCgJ,KAAQ,SAAUjN,GACjB,MAAOA,KAAS5B,GAGjB8O,MAAS,SAAUlN,GAClB,MAAOA,KAAS7B,EAASgP,iBAAmBhP,EAASiP,UAAYjP,EAASiP,gBAAkBpN,EAAKwG,MAAQxG,EAAKqN,OAASrN,EAAKsN,WAI7HC,QAAW,SAAUvN,GACpB,MAAOA,GAAKwN,YAAa,GAG1BA,SAAY,SAAUxN,GACrB,MAAOA,GAAKwN,YAAa,GAG1BC,QAAW,SAAUzN,GAGpB,GAAIsE,GAAWtE,EAAKsE,SAASC,aAC7B,OAAqB,UAAbD,KAA0BtE,EAAKyN,SAA0B,WAAbnJ,KAA2BtE,EAAK0N,UAGrFA,SAAY,SAAU1N,GAOrB,MAJKA,GAAKgE,YACThE,EAAKgE,WAAW2J,cAGV3N,EAAK0N,YAAa,GAI1BE,MAAS,SAAU5N,GAKlB,IAAMA,EAAOA,EAAK2H,WAAY3H,EAAMA,EAAOA,EAAKsG,YAC/C,GAAKtG,EAAK4C,SAAW,EACpB,OAAO,CAGT,QAAO,GAGRsE,OAAU,SAAUlH,GACnB,OAAQtC,EAAKgD,QAAe,MAAGV,IAIhC6N,OAAU,SAAU7N,GACnB,MAAO4B,GAAQyC,KAAMrE,EAAKsE,WAG3B8D,MAAS,SAAUpI,GAClB,MAAO2B,GAAQ0C,KAAMrE,EAAKsE,WAG3BwJ,OAAU,SAAU9N,GACnB,GAAIyG,GAAOzG,EAAKsE,SAASC,aACzB,OAAgB,UAATkC,GAAkC,WAAdzG,EAAKwG,MAA8B,WAATC,GAGtDkG,KAAQ,SAAU3M,GACjB,GAAIuJ,EACJ,OAAuC,UAAhCvJ,EAAKsE,SAASC,eACN,SAAdvE,EAAKwG,OAImC,OAArC+C,EAAOvJ,EAAKyE,aAAa,UAA2C,SAAvB8E,EAAKhF,gBAIvDoG,MAAShE,GAAuB,WAC/B,OAAS,KAGV6E,KAAQ7E,GAAuB,SAAUE,EAAc1G,GACtD,OAASA,EAAS,KAGnB4N,GAAMpH,GAAuB,SAAUE,EAAc1G,EAAQyG,GAC5D,OAAoB,EAAXA,EAAeA,EAAWzG,EAASyG,KAG7CoH,KAAQrH,GAAuB,SAAUE,EAAc1G,GAEtD,IADA,GAAI3C,GAAI,EACI2C,EAAJ3C,EAAYA,GAAK,EACxBqJ,EAAahH,KAAMrC,EAEpB,OAAOqJ,KAGRoH,IAAOtH,GAAuB,SAAUE,EAAc1G,GAErD,IADA,GAAI3C,GAAI,EACI2C,EAAJ3C,EAAYA,GAAK,EACxBqJ,EAAahH,KAAMrC,EAEpB,OAAOqJ,KAGRqH,GAAMvH,GAAuB,SAAUE,EAAc1G,EAAQyG,GAE5D,IADA,GAAIpJ,GAAe,EAAXoJ,EAAeA,EAAWzG,EAASyG,IACjCpJ,GAAK,GACdqJ,EAAahH,KAAMrC,EAEpB,OAAOqJ,KAGRsH,GAAMxH,GAAuB,SAAUE,EAAc1G,EAAQyG,GAE5D,IADA,GAAIpJ,GAAe,EAAXoJ,EAAeA,EAAWzG,EAASyG,IACjCpJ,EAAI2C,GACb0G,EAAahH,KAAMrC,EAEpB,OAAOqJ,OAKVnJ,EAAKgD,QAAa,IAAIhD,EAAKgD,QAAY,EAGvC,KAAMlD,KAAO4Q,OAAO,EAAMC,UAAU,EAAMC,MAAM,EAAMC,UAAU,EAAMC,OAAO,GAC5E9Q,EAAKgD,QAASlD,GAAM+I,GAAmB/I,EAExC,KAAMA,KAAOiR,QAAQ,EAAMC,OAAO,GACjChR,EAAKgD,QAASlD,GAAMkJ,GAAoBlJ,EAIzC,SAAS4O,OACTA,GAAWuC,UAAYjR,EAAKkR,QAAUlR,EAAKgD,QAC3ChD,EAAK0O,WAAa,GAAIA,GAEtB,SAAS5H,IAAUtB,EAAU2L,GAC5B,GAAIvC,GAAShJ,EAAOwL,EAAQtI,EAC3BuI,EAAOvL,EAAQwL,EACfC,EAAShQ,EAAYiE,EAAW,IAEjC,IAAK+L,EACJ,MAAOJ,GAAY,EAAII,EAAOnP,MAAO,EAGtCiP,GAAQ7L,EACRM,KACAwL,EAAatR,EAAKqN,SAElB,OAAQgE,EAAQ,GAGTzC,IAAYhJ,EAAQzC,EAAOiD,KAAMiL,OACjCzL,IAEJyL,EAAQA,EAAMjP,MAAOwD,EAAM,GAAGnD,SAAY4O,GAE3CvL,EAAO3D,KAAOiP,OAGfxC,GAAU,GAGJhJ,EAAQxC,EAAagD,KAAMiL,MAChCzC,EAAUhJ,EAAMgC,QAChBwJ,EAAOjP,MACNuF,MAAOkH,EAEP9F,KAAMlD,EAAM,GAAG9C,QAASG,EAAO,OAEhCoO,EAAQA,EAAMjP,MAAOwM,EAAQnM,QAI9B,KAAMqG,IAAQ9I,GAAKqK,SACZzE,EAAQpC,EAAWsF,GAAO1C,KAAMiL,KAAcC,EAAYxI,MAC9DlD,EAAQ0L,EAAYxI,GAAQlD,MAC7BgJ,EAAUhJ,EAAMgC,QAChBwJ,EAAOjP,MACNuF,MAAOkH,EACP9F,KAAMA,EACNhI,QAAS8E,IAEVyL,EAAQA,EAAMjP,MAAOwM,EAAQnM,QAI/B,KAAMmM,EACL,MAOF,MAAOuC,GACNE,EAAM5O,OACN4O,EACC9L,GAAO0G,MAAOzG,GAEdjE,EAAYiE,EAAUM,GAAS1D,MAAO,GAGzC,QAAS6E,IAAYmK,GAIpB,IAHA,GAAItR,GAAI,EACPyC,EAAM6O,EAAO3O,OACb+C,EAAW,GACAjD,EAAJzC,EAASA,IAChB0F,GAAY4L,EAAOtR,GAAG4H,KAEvB,OAAOlC,GAGR,QAASgM,IAAe1C,EAAS2C,EAAYC,GAC5C,GAAI1E,GAAMyE,EAAWzE,IACpB2E,EAAmBD,GAAgB,eAAR1E,EAC3B4E,EAAWxQ,GAEZ,OAAOqQ,GAAWxE,MAEjB,SAAU3K,EAAMmD,EAASyI,GACxB,MAAS5L,EAAOA,EAAM0K,GACrB,GAAuB,IAAlB1K,EAAK4C,UAAkByM,EAC3B,MAAO7C,GAASxM,EAAMmD,EAASyI,IAMlC,SAAU5L,EAAMmD,EAASyI,GACxB,GAAI2D,GAAU1D,EACb2D,GAAa3Q,EAASyQ,EAGvB,IAAK1D,GACJ,MAAS5L,EAAOA,EAAM0K,GACrB,IAAuB,IAAlB1K,EAAK4C,UAAkByM,IACtB7C,EAASxM,EAAMmD,EAASyI,GAC5B,OAAO,MAKV,OAAS5L,EAAOA,EAAM0K,GACrB,GAAuB,IAAlB1K,EAAK4C,UAAkByM,EAAmB,CAE9C,GADAxD,EAAa7L,EAAMtB,KAAcsB,EAAMtB,QACjC6Q,EAAW1D,EAAYnB,KAC5B6E,EAAU,KAAQ1Q,GAAW0Q,EAAU,KAAQD,EAG/C,MAAQE,GAAU,GAAMD,EAAU,EAMlC,IAHA1D,EAAYnB,GAAQ8E,EAGdA,EAAU,GAAMhD,EAASxM,EAAMmD,EAASyI,GAC7C,OAAO,IASf,QAAS6D,IAAgBC,GACxB,MAAOA,GAASvP,OAAS,EACxB,SAAUH,EAAMmD,EAASyI,GACxB,GAAIpO,GAAIkS,EAASvP,MACjB,OAAQ3C,IACP,IAAMkS,EAASlS,GAAIwC,EAAMmD,EAASyI,GACjC,OAAO,CAGT,QAAO,GAER8D,EAAS,GAGX,QAASC,IAAkBzM,EAAU0M,EAAUxM,GAG9C,IAFA,GAAI5F,GAAI,EACPyC,EAAM2P,EAASzP,OACJF,EAAJzC,EAASA,IAChByF,GAAQC,EAAU0M,EAASpS,GAAI4F,EAEhC,OAAOA,GAGR,QAASyM,IAAUpD,EAAWqD,EAAK/H,EAAQ5E,EAASyI,GAOnD,IANA,GAAI5L,GACH+P,KACAvS,EAAI,EACJyC,EAAMwM,EAAUtM,OAChB6P,EAAgB,MAAPF,EAEE7P,EAAJzC,EAASA,KACVwC,EAAOyM,EAAUjP,OAChBuK,GAAUA,EAAQ/H,EAAMmD,EAASyI,MACtCmE,EAAalQ,KAAMG,GACdgQ,GACJF,EAAIjQ,KAAMrC,GAMd,OAAOuS,GAGR,QAASE,IAAYlF,EAAW7H,EAAUsJ,EAAS0D,EAAYC,EAAYC,GAO1E,MANKF,KAAeA,EAAYxR,KAC/BwR,EAAaD,GAAYC,IAErBC,IAAeA,EAAYzR,KAC/ByR,EAAaF,GAAYE,EAAYC,IAE/B7K,GAAa,SAAUlC,EAAMD,EAASD,EAASyI,GACrD,GAAIyE,GAAM7S,EAAGwC,EACZsQ,KACAC,KACAC,EAAcpN,EAAQjD,OAGtBsQ,EAAQpN,GAAQsM,GAAkBzM,GAAY,IAAKC,EAAQP,UAAaO,GAAYA,MAGpFuN,GAAY3F,IAAe1H,GAASH,EAEnCuN,EADAZ,GAAUY,EAAOH,EAAQvF,EAAW5H,EAASyI,GAG9C+E,EAAanE,EAEZ2D,IAAgB9M,EAAO0H,EAAYyF,GAAeN,MAMjD9M,EACDsN,CAQF,IALKlE,GACJA,EAASkE,EAAWC,EAAYxN,EAASyI,GAIrCsE,EAAa,CACjBG,EAAOR,GAAUc,EAAYJ,GAC7BL,EAAYG,KAAUlN,EAASyI,GAG/BpO,EAAI6S,EAAKlQ,MACT,OAAQ3C,KACDwC,EAAOqQ,EAAK7S,MACjBmT,EAAYJ,EAAQ/S,MAASkT,EAAWH,EAAQ/S,IAAOwC,IAK1D,GAAKqD,GACJ,GAAK8M,GAAcpF,EAAY,CAC9B,GAAKoF,EAAa,CAEjBE,KACA7S,EAAImT,EAAWxQ,MACf,OAAQ3C,KACDwC,EAAO2Q,EAAWnT,KAEvB6S,EAAKxQ,KAAO6Q,EAAUlT,GAAKwC,EAG7BmQ,GAAY,KAAOQ,KAAkBN,EAAMzE,GAI5CpO,EAAImT,EAAWxQ,MACf,OAAQ3C,KACDwC,EAAO2Q,EAAWnT,MACtB6S,EAAOF,EAAapQ,EAAQ2C,KAAMW,EAAMrD,GAASsQ,EAAO9S,IAAM,KAE/D6F,EAAKgN,KAAUjN,EAAQiN,GAAQrQ,SAOlC2Q,GAAad,GACZc,IAAevN,EACduN,EAAWxG,OAAQqG,EAAaG,EAAWxQ,QAC3CwQ,GAEGR,EACJA,EAAY,KAAM/M,EAASuN,EAAY/E,GAEvC/L,EAAK4C,MAAOW,EAASuN,KAMzB,QAASC,IAAmB9B,GAqB3B,IApBA,GAAI+B,GAAcrE,EAASxJ,EAC1B/C,EAAM6O,EAAO3O,OACb2Q,EAAkBpT,EAAK8M,SAAUsE,EAAO,GAAGtI,MAC3CuK,EAAmBD,GAAmBpT,EAAK8M,SAAS,KACpDhN,EAAIsT,EAAkB,EAAI,EAG1BE,EAAe9B,GAAe,SAAUlP,GACvC,MAAOA,KAAS6Q,GACdE,GAAkB,GACrBE,EAAkB/B,GAAe,SAAUlP,GAC1C,MAAOD,GAAQ2C,KAAMmO,EAAc7Q,GAAS,IAC1C+Q,GAAkB,GACrBrB,GAAa,SAAU1P,EAAMmD,EAASyI,GACrC,OAAUkF,IAAqBlF,GAAOzI,IAAYpF,MAChD8S,EAAe1N,GAASP,SACxBoO,EAAchR,EAAMmD,EAASyI,GAC7BqF,EAAiBjR,EAAMmD,EAASyI,MAGxB3L,EAAJzC,EAASA,IAChB,GAAMgP,EAAU9O,EAAK8M,SAAUsE,EAAOtR,GAAGgJ,MACxCkJ,GAAaR,GAAcO,GAAgBC,GAAYlD,QACjD,CAIN,GAHAA,EAAU9O,EAAKqK,OAAQ+G,EAAOtR,GAAGgJ,MAAO/D,MAAO,KAAMqM,EAAOtR,GAAGgB,SAG1DgO,EAAS9N,GAAY,CAGzB,IADAsE,IAAMxF,EACMyC,EAAJ+C,EAASA,IAChB,GAAKtF,EAAK8M,SAAUsE,EAAO9L,GAAGwD,MAC7B,KAGF,OAAOyJ,IACNzS,EAAI,GAAKiS,GAAgBC,GACzBlS,EAAI,GAAKmH,GAERmK,EAAOhP,MAAO,EAAGtC,EAAI,GAAI0T,QAAS9L,MAAgC,MAAzB0J,EAAQtR,EAAI,GAAIgJ,KAAe,IAAM,MAC7EhG,QAASG,EAAO,MAClB6L,EACIxJ,EAAJxF,GAASoT,GAAmB9B,EAAOhP,MAAOtC,EAAGwF,IACzC/C,EAAJ+C,GAAW4N,GAAoB9B,EAASA,EAAOhP,MAAOkD,IAClD/C,EAAJ+C,GAAW2B,GAAYmK,IAGzBY,EAAS7P,KAAM2M,GAIjB,MAAOiD,IAAgBC,GAGxB,QAASyB,IAA0BC,EAAiBC,GACnD,GAAIC,GAAQD,EAAYlR,OAAS,EAChCoR,EAAYH,EAAgBjR,OAAS,EACrCqR,EAAe,SAAUnO,EAAMF,EAASyI,EAAKxI,EAASqO,GACrD,GAAIzR,GAAMgD,EAAGwJ,EACZkF,EAAe,EACflU,EAAI,IACJiP,EAAYpJ,MACZsO,KACAC,EAAgB7T,EAEhB0S,EAAQpN,GAAQkO,GAAa7T,EAAKoK,KAAU,IAAG,IAAK2J,GAEpDI,EAAiBhT,GAA4B,MAAjB+S,EAAwB,EAAIE,KAAKC,UAAY,GACzE9R,EAAMwQ,EAAMtQ,MAUb,KARKsR,IACJ1T,EAAmBoF,IAAYhF,GAAYgF,GAOpC3F,IAAMyC,GAA4B,OAApBD,EAAOyQ,EAAMjT,IAAaA,IAAM,CACrD,GAAK+T,GAAavR,EAAO,CACxBgD,EAAI,CACJ,OAASwJ,EAAU4E,EAAgBpO,KAClC,GAAKwJ,EAASxM,EAAMmD,EAASyI,GAAQ,CACpCxI,EAAQvD,KAAMG,EACd,OAGGyR,IACJ5S,EAAUgT,GAKPP,KAEEtR,GAAQwM,GAAWxM,IACxB0R,IAIIrO,GACJoJ,EAAU5M,KAAMG,IAOnB,GADA0R,GAAgBlU,EACX8T,GAAS9T,IAAMkU,EAAe,CAClC1O,EAAI,CACJ,OAASwJ,EAAU6E,EAAYrO,KAC9BwJ,EAASC,EAAWkF,EAAYxO,EAASyI,EAG1C,IAAKvI,EAAO,CAEX,GAAKqO,EAAe,EACnB,MAAQlU,IACAiP,EAAUjP,IAAMmU,EAAWnU,KACjCmU,EAAWnU,GAAKmC,EAAI+C,KAAMU,GAM7BuO,GAAa9B,GAAU8B,GAIxB9R,EAAK4C,MAAOW,EAASuO,GAGhBF,IAAcpO,GAAQsO,EAAWxR,OAAS,GAC5CuR,EAAeL,EAAYlR,OAAW,GAExC8C,GAAO6G,WAAY1G,GAUrB,MALKqO,KACJ5S,EAAUgT,EACV9T,EAAmB6T,GAGbnF,EAGT,OAAO6E,GACN/L,GAAciM,GACdA,EAGF3T,EAAUoF,GAAOpF,QAAU,SAAUqF,EAAUI,GAC9C,GAAI9F,GACH6T,KACAD,KACAnC,EAAS/P,EAAegE,EAAW,IAEpC,KAAM+L,EAAS,CAER3L,IACLA,EAAQkB,GAAUtB,IAEnB1F,EAAI8F,EAAMnD,MACV,OAAQ3C,IACPyR,EAAS2B,GAAmBtN,EAAM9F,IAC7ByR,EAAQvQ,GACZ2S,EAAYxR,KAAMoP,GAElBmC,EAAgBvR,KAAMoP,EAKxBA,GAAS/P,EAAegE,EAAUiO,GAA0BC,EAAiBC,IAG7EpC,EAAO/L,SAAWA,EAClB+L,EAAO3L,MAAQA,EAEhB,MAAO2L,IAYRnR,EAASmF,GAAOnF,OAAS,SAAUoF,EAAUC,EAASC,EAASC,GAC9D,GAAI7F,GAAGsR,EAAQkD,EAAOxL,EAAMsB,EAAMxE,EAAO2O,CAYzC,IAVA7O,EAAUA,MAEe,kBAAbF,IACX+O,EAAW/O,EACXI,EAAQ2O,EAAS3O,MACjBJ,EAAW+O,EAAS/O,UAEpBI,EAAQkB,GAAUtB,IAGbG,GAEiB,IAAjBC,EAAMnD,OAAe,CAIzB,GADA2O,EAASxL,EAAM,GAAKA,EAAM,GAAGxD,MAAO,IAC9BmS,GACJnD,EAAO3O,OAAS,GAAkC,QAA5B6R,EAAQlD,EAAO,IAAItI,MACzC/I,EAAQmK,SAAgC,IAArBzE,EAAQP,UAAkBvE,GAC7CX,EAAK8M,SAAUsE,EAAO,GAAGtI,MAAS,CAGnC,GADArD,GAAYzF,EAAKoK,KAAS,GAAGkK,EAAMxT,QAAQ,GAAGgC,QAAQyB,GAAWC,IAAYiB,QAAkB,IACzFA,EACL,MAAOC,EAERF,GAAWA,EAASpD,MAAOgP,EAAOxJ,QAAQF,MAAMjF,QAIjD3C,EAAI0D,EAAwB,aAAEmD,KAAMnB,GAAa,EAAI4L,EAAO3O,MAC5D,OAAQ3C,IAAM,CAIb,GAHAwU,EAAQlD,EAAOtR,GAGVE,EAAK8M,SAAWhE,EAAOwL,EAAMxL,MACjC,KAED,KAAMsB,EAAOpK,EAAKoK,KAAMtB,MAEjBnD,EAAOyE,EACZkK,EAAMxT,QAAQ,GAAGgC,QAASyB,GAAWC,IACrCH,EAASsC,KAAMyK,EAAO,GAAGtI,OAAU5B,GAAazB,EAAQa,aAAgBb,IACpE,CAKJ,GAFA2L,EAAO3E,OAAQ3M,EAAG,GAClB0F,EAAWG,EAAKlD,QAAUwE,GAAYmK,IAChC5L,EAEL,MADArD,GAAK4C,MAAOW,EAASC,GACdD,CAGR,SAgBL,OAPE6O,GAAYpU,EAASqF,EAAUI,IAChCD,EACAF,GACC9E,EACD+E,EACArB,EAASsC,KAAMnB,IAAc0B,GAAazB,EAAQa,aAAgBb,GAE5DC,GAMR3F,EAAQwM,WAAavL,EAAQsH,MAAM,IAAIkE,KAAM/K,GAAY0F,KAAK,MAAQnG,EAItEjB,EAAQuM,mBAAqB/L,EAG7BC,IAIAT,EAAQsL,aAAetD,GAAO,SAAUyM,GAEvC,MAAuE,GAAhEA,EAAKvJ,wBAAyBxK,EAASwH,cAAc,UAMvDF,GAAO,SAAUC,GAEtB,MADAA,GAAIgC,UAAY,mBAC+B,MAAxChC,EAAIiC,WAAWlD,aAAa,WAEnCoB,GAAW,yBAA0B,SAAU7F,EAAMyG,EAAM7I,GAC1D,MAAMA,GAAN,OACQoC,EAAKyE,aAAcgC,EAA6B,SAAvBA,EAAKlC,cAA2B,EAAI,KAOjE9G,EAAQgD,YAAegF,GAAO,SAAUC,GAG7C,MAFAA,GAAIgC,UAAY,WAChBhC,EAAIiC,WAAWjD,aAAc,QAAS,IACY,KAA3CgB,EAAIiC,WAAWlD,aAAc,YAEpCoB,GAAW,QAAS,SAAU7F,EAAMyG,EAAM7I,GACzC,MAAMA,IAAyC,UAAhCoC,EAAKsE,SAASC,cAA7B,OACQvE,EAAKmS,eAOT1M,GAAO,SAAUC,GACtB,MAAuC,OAAhCA,EAAIjB,aAAa,eAExBoB,GAAWzF,EAAU,SAAUJ,EAAMyG,EAAM7I,GAC1C,GAAI4L,EACJ,OAAM5L,GAAN,OACQoC,EAAMyG,MAAW,EAAOA,EAAKlC,eACjCiF,EAAMxJ,EAAKiI,iBAAkBxB,KAAW+C,EAAIE,UAC7CF,EAAIpE,MACL,OAMmB,kBAAXgN,SAAyBA,OAAOC,IAC3CD,OAAO,WAAa,MAAOnP,MAEE,mBAAXqP,SAA0BA,OAAOC,QACnDD,OAAOC,QAAUtP,GAEjB1F,EAAO0F,OAASA,IAIb1F"}sizzle-1.10.17/package.json000066400000000000000000000023501226755370700155050ustar00rootroot00000000000000{ "name": "sizzle", "title": "Sizzle", "description": "A pure-JavaScript, bottom-up CSS selector engine designed to be easily dropped in to a host library.", "version": "1.10.17", "homepage": "http://sizzlejs.com", "author": { "name": "jQuery Foundation and other contributors", "url": "https://github.com/jquery/sizzle/blob/master/AUTHORS.txt" }, "repository": { "type": "git", "url": "https://github.com/jquery/sizzle.git" }, "bugs": { "url": "https://github.com/jquery/sizzle/issues" }, "licenses": [ { "type": "MIT", "url": "https://github.com/jquery/jquery/blob/master/MIT-LICENSE.txt" } ], "dependencies": {}, "devDependencies": { "grunt": "0.4.2", "grunt-cli": "0.1.11", "grunt-contrib-jshint": "0.7.2", "grunt-contrib-qunit": "0.3.0", "grunt-contrib-uglify": "0.2.7", "grunt-contrib-watch": "0.5.3", "grunt-compare-size": "0.4.0", "grunt-git-authors": "1.2.0", "grunt-jsonlint": "1.0.4", "grunt-bowercopy": "0.5.0", "grunt-jscs-checker": "0.3.0", "gzip-js": "0.3.2", "load-grunt-tasks": "0.2.1", "testswarm": "1.1.0" }, "scripts": { "build": "npm install && grunt", "start": "grunt watch", "test": "grunt test" }, "keywords": [ "sizzle", "selector", "jquery" ] } sizzle-1.10.17/speed/000077500000000000000000000000001226755370700143175ustar00rootroot00000000000000sizzle-1.10.17/speed/.jshintrc000066400000000000000000000005231226755370700161440ustar00rootroot00000000000000{ "boss": true, "curly": true, "eqeqeq": true, "eqnull": true, "expr": true, "immed": true, "noarg": true, "onevar": true, "quotmark": "double", "smarttabs": true, "trailing": true, "undef": true, "unused": true, "evil": true, "regexdash": true, "browser": true, "wsh": true, "predef": [ "console", "require" ] } sizzle-1.10.17/speed/data/000077500000000000000000000000001226755370700152305ustar00rootroot00000000000000sizzle-1.10.17/speed/data/checkJava.js000066400000000000000000000010541226755370700174450ustar00rootroot00000000000000/* * Check the necessity of the java applet and add it if needed */ define(function() { var measured, perfNow, begin = new Date; // is the applet permitted? if ( !/[?&]nojava=true(?:&|$)/.test(window.location.search) ) { // is the applet really needed? while (!(measured = new Date - begin)) { } if ( measured !== 1 && !( (perfNow = window.performance) && typeof (perfNow.now || perfNow.webkitNow) === "function" ) ) { // load applet document.write(""); } } }); sizzle-1.10.17/speed/data/selector.html000066400000000000000000004027571226755370700177550ustar00rootroot00000000000000 Sizzle Performance Suite HTML

W3C

Selectors Level 3

W3C Recommendation 29 September 2011

This version:
http://www.w3.org/TR/2011/REC-css3-selectors-20110929/
Latest version:
http://www.w3.org/TR/css3-selectors/
Latest Selectors specification:
http://www.w3.org/TR/selectors/
Previous version:
http://www.w3.org/TR/2009/PR-css3-selectors-20091215/
Editors:
Tantek Çelik (Invited Expert)
Elika J. Etemad (Invited Expert)
Daniel Glazman (Disruptive Innovations SARL)
Ian Hickson (Google)
Peter Linss (former editor, Netscape/AOL)
John Williams (former editor, Quark, Inc.)

Please refer to the errata for this document, which may include some normative corrections.

See also translations.


Abstract

Selectors are patterns that match against elements in a tree, and as such form one of several technologies that can be used to select nodes in an XML document. Selectors have been optimized for use with HTML and XML, and are designed to be usable in performance-critical code.

CSS (Cascading Style Sheets) is a language for describing the rendering of HTML and XML documents on screen, on paper, in speech, etc. CSS uses Selectors for binding style properties to elements in the document.

This document describes the selectors that already exist in CSS1 [CSS1] and CSS2 [CSS21], and further introduces new selectors for CSS3 and other languages that may need them.

Selectors define the following function:

expression ∗ element → boolean

That is, given an element and a selector, this specification defines whether that element matches the selector.

These expressions can also be used, for instance, to select a set of elements, or a single element from a set of elements, by evaluating the expression across all the elements in a subtree. STTS (Simple Tree Transformation Sheets), a language for transforming XML trees, uses this mechanism. [STTS3]

Status of this document

This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.

This document was produced by the CSS Working Group as a Proposed Recommendation.

A W3C Recommendation is a mature document that has been widely reviewed and has been shown to be implementable. W3C encourages everybody to implement this specification. Comments may be sent to the (archived) public mailing list www-style@w3.org (see instructions). When sending e-mail, please put the text “css3-selectors” in the subject, preferably like this: “[css3-selectors] …summary of comment…

This document has been reviewed by W3C Members, by software developers, and by other W3C groups and interested parties, and is endorsed by the Director as a W3C Recommendation. It is a stable document and may be used as reference material or cited from another document. W3C's role in making the Recommendation is to draw attention to the specification and to promote its widespread deployment. This enhances the functionality and interoperability of the Web.

This document was produced by a group operating under the 5 February 2004 W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.

A separate implementation report contains a test suite and shows several implementations of the specification.

This document is the same as the previous, Proposed Recommendation version, except for editorial changes to the front matter, and updating of references.

Table of Contents

1. Introduction

Selectors Level 1 and Selectors Level 2 are defined as the subsets of selector functionality defined in the CSS1 and CSS2.1 specifications, respectively.

1.1. Dependencies

Some features of this specification are specific to CSS, or have particular limitations or rules specific to CSS. In this specification, these have been described in terms of CSS2.1. [CSS21]

1.2. Terminology

All of the text of this specification is normative except examples, notes, and sections explicitly marked as non-normative.

Additional terminology is defined in the Definitions section of [CSS21]. Examples of document source code and fragments are given in XML [[XML10] or HTML [[HTML40]] syntax.

1.3. Changes from CSS2

This section is non-normative.

The main differences between the selectors in CSS2 and those in Selectors are:

  • the list of basic definitions (selector, group of selectors, simple selector, etc.) has been changed; in particular, what was referred to in CSS2 as a simple selector is now called a sequence of simple selectors, and the term "simple selector" is now used for the components of this sequence
  • an optional namespace component is now allowed in element type selectors, the universal selector and attribute selectors
  • a new combinator has been introduced
  • new simple selectors including substring matching attribute selectors, and new pseudo-classes
  • new pseudo-elements, and introduction of the "::" convention for pseudo-elements
  • the grammar has been rewritten
  • profiles to be added to specifications integrating Selectors and defining the set of selectors which is actually supported by each specification
  • Selectors are now a CSS3 Module and an independent specification; other specifications can now refer to this document independently of CSS
  • the specification now has its own test suite

2. Selectors

This section is non-normative, as it merely summarizes the following sections.

A Selector represents a structure. This structure can be used as a condition (e.g. in a CSS rule) that determines which elements a selector matches in the document tree, or as a flat description of the HTML or XML fragment corresponding to that structure.

Selectors may range from simple element names to rich contextual representations.

The following table summarizes the Selector syntax:

Pattern Meaning Described in section First defined in CSS level
* any element Universal selector 2
E an element of type E Type selector 1
E[foo] an E element with a "foo" attribute Attribute selectors 2
E[foo="bar"] an E element whose "foo" attribute value is exactly equal to "bar" Attribute selectors 2
E[foo~="bar"] an E element whose "foo" attribute value is a list of whitespace-separated values, one of which is exactly equal to "bar" Attribute selectors 2
E[foo^="bar"] an E element whose "foo" attribute value begins exactly with the string "bar" Attribute selectors 3
E[foo$="bar"] an E element whose "foo" attribute value ends exactly with the string "bar" Attribute selectors 3
E[foo*="bar"] an E element whose "foo" attribute value contains the substring "bar" Attribute selectors 3
E[foo|="en"] an E element whose "foo" attribute has a hyphen-separated list of values beginning (from the left) with "en" Attribute selectors 2
E:root an E element, root of the document Structural pseudo-classes 3
E:nth-child(n) an E element, the n-th child of its parent Structural pseudo-classes 3
E:nth-last-child(n) an E element, the n-th child of its parent, counting from the last one Structural pseudo-classes 3
E:nth-of-type(n) an E element, the n-th sibling of its type Structural pseudo-classes 3
E:nth-last-of-type(n) an E element, the n-th sibling of its type, counting from the last one Structural pseudo-classes 3
E:first-child an E element, first child of its parent Structural pseudo-classes 2
E:last-child an E element, last child of its parent Structural pseudo-classes 3
E:first-of-type an E element, first sibling of its type Structural pseudo-classes 3
E:last-of-type an E element, last sibling of its type Structural pseudo-classes 3
E:only-child an E element, only child of its parent Structural pseudo-classes 3
E:only-of-type an E element, only sibling of its type Structural pseudo-classes 3
E:empty an E element that has no children (including text nodes) Structural pseudo-classes 3
E:link
E:visited
an E element being the source anchor of a hyperlink of which the target is not yet visited (:link) or already visited (:visited) The link pseudo-classes 1
E:active
E:hover
E:focus
an E element during certain user actions The user action pseudo-classes 1 and 2
E:target an E element being the target of the referring URI The target pseudo-class 3
E:lang(fr) an element of type E in language "fr" (the document language specifies how language is determined) The :lang() pseudo-class 2
E:enabled
E:disabled
a user interface element E which is enabled or disabled The UI element states pseudo-classes 3
E:checked a user interface element E which is checked (for instance a radio-button or checkbox) The UI element states pseudo-classes 3
E::first-line the first formatted line of an E element The ::first-line pseudo-element 1
E::first-letter the first formatted letter of an E element The ::first-letter pseudo-element 1
E::before generated content before an E element The ::before pseudo-element 2
E::after generated content after an E element The ::after pseudo-element 2
E.warning an E element whose class is "warning" (the document language specifies how class is determined). Class selectors 1
E#myid an E element with ID equal to "myid". ID selectors 1
E:not(s) an E element that does not match simple selector s Negation pseudo-class 3
E F an F element descendant of an E element Descendant combinator 1
E > F an F element child of an E element Child combinator 2
E + F an F element immediately preceded by an E element Adjacent sibling combinator 2
E ~ F an F element preceded by an E element General sibling combinator 3

The meaning of each selector is derived from the table above by prepending "matches" to the contents of each cell in the "Meaning" column.

3. Case sensitivity

All Selectors syntax is case-insensitive within the ASCII range (i.e. [a-z] and [A-Z] are equivalent), except for parts that are not under the control of Selectors. The case sensitivity of document language element names, attribute names, and attribute values in selectors depends on the document language. For example, in HTML, element names are case-insensitive, but in XML, they are case-sensitive. Case sensitivity of namespace prefixes is defined in [CSS3NAMESPACE].

4. Selector syntax

A selector is a chain of one or more sequences of simple selectors separated by combinators. One pseudo-element may be appended to the last sequence of simple selectors in a selector.

A sequence of simple selectors is a chain of simple selectors that are not separated by a combinator. It always begins with a type selector or a universal selector. No other type selector or universal selector is allowed in the sequence.

A simple selector is either a type selector, universal selector, attribute selector, class selector, ID selector, or pseudo-class.

Combinators are: whitespace, "greater-than sign" (U+003E, >), "plus sign" (U+002B, +) and "tilde" (U+007E, ~). White space may appear between a combinator and the simple selectors around it. Only the characters "space" (U+0020), "tab" (U+0009), "line feed" (U+000A), "carriage return" (U+000D), and "form feed" (U+000C) can occur in whitespace. Other space-like characters, such as "em-space" (U+2003) and "ideographic space" (U+3000), are never part of whitespace.

The elements of a document tree that are represented by a selector are the subjects of the selector. A selector consisting of a single sequence of simple selectors represents any element satisfying its requirements. Prepending another sequence of simple selectors and a combinator to a sequence imposes additional matching constraints, so the subjects of a selector are always a subset of the elements represented by the last sequence of simple selectors.

An empty selector, containing no sequence of simple selectors and no pseudo-element, is an invalid selector.

Characters in Selectors can be escaped with a backslash according to the same escaping rules as CSS. [CSS21].

Certain selectors support namespace prefixes. The mechanism by which namespace prefixes are declared should be specified by the language that uses Selectors. If the language does not specify a namespace prefix declaration mechanism, then no prefixes are declared. In CSS, namespace prefixes are declared with the @namespace rule. [CSS3NAMESPACE]

5. Groups of selectors

A comma-separated list of selectors represents the union of all elements selected by each of the individual selectors in the list. (A comma is U+002C.) For example, in CSS when several selectors share the same declarations, they may be grouped into a comma-separated list. White space may appear before and/or after the comma.

CSS example:

In this example, we condense three rules with identical declarations into one. Thus,

h1 { font-family: sans-serif }
			h2 { font-family: sans-serif }
			h3 { font-family: sans-serif }

is equivalent to:

h1, h2, h3 { font-family: sans-serif }

Warning: the equivalence is true in this example because all the selectors are valid selectors. If just one of these selectors were invalid, the entire group of selectors would be invalid. This would invalidate the rule for all three heading elements, whereas in the former case only one of the three individual heading rules would be invalidated.

Invalid CSS example:

h1 { font-family: sans-serif }
			h2..foo { font-family: sans-serif }
			h3 { font-family: sans-serif }

is not equivalent to:

h1, h2..foo, h3 { font-family: sans-serif }

because the above selector (h1, h2..foo, h3) is entirely invalid and the entire style rule is dropped. (When the selectors are not grouped, only the rule for h2..foo is dropped.)

6. Simple selectors

6.1. Type selector

A type selector is the name of a document language element type written using the syntax of CSS qualified names [CSS3NAMESPACE]. A type selector represents an instance of the element type in the document tree.

Example:

The following selector represents an h1 element in the document tree:

h1

6.1.1. Type selectors and namespaces

Type selectors allow an optional namespace component: a namespace prefix that has been previously declared may be prepended to the element name separated by the namespace separator "vertical bar" (U+007C, |). (See, e.g., [XML-NAMES] for the use of namespaces in XML.)

The namespace component may be left empty (no prefix before the namespace separator) to indicate that the selector is only to represent elements with no namespace.

An asterisk may be used for the namespace prefix, indicating that the selector represents elements in any namespace (including elements with no namespace).

Element type selectors that have no namespace component (no namespace separator) represent elements without regard to the element's namespace (equivalent to "*|") unless a default namespace has been declared for namespaced selectors (e.g. in CSS, in the style sheet). If a default namespace has been declared, such selectors will represent only elements in the default namespace.

A type selector containing a namespace prefix that has not been previously declared for namespaced selectors is an invalid selector.

In a namespace-aware client, the name part of element type selectors (the part after the namespace separator, if it is present) will only match against the local part of the element's qualified name.

In summary:

ns|E
elements with name E in namespace ns
*|E
elements with name E in any namespace, including those without a namespace
|E
elements with name E without a namespace
E
if no default namespace has been declared for selectors, this is equivalent to *|E. Otherwise it is equivalent to ns|E where ns is the default namespace.

CSS examples:

@namespace foo url(http://www.example.com);
			foo|h1 { color: blue }  /* first rule */
			foo|* { color: yellow } /* second rule */
			|h1 { color: red }      /* ...*/
			*|h1 { color: green }
			h1 { color: green }

The first rule (not counting the @namespace at-rule) will match only h1 elements in the "http://www.example.com" namespace.

The second rule will match all elements in the "http://www.example.com" namespace.

The third rule will match only h1 elements with no namespace.

The fourth rule will match h1 elements in any namespace (including those without any namespace).

The last rule is equivalent to the fourth rule because no default namespace has been defined.

6.2. Universal selector

The universal selector, written as a CSS qualified name [CSS3NAMESPACE] with an asterisk (* U+002A) as the local name, represents the qualified name of any element type. It represents any single element in the document tree in any namespace (including those without a namespace) if no default namespace has been specified for selectors. If a default namespace has been specified, see Universal selector and Namespaces below.

If a universal selector represented by * (i.e. without a namespace prefix) is not the only component of a sequence of simple selectors selectors or is immediately followed by a pseudo-element, then the * may be omitted and the universal selector's presence implied.

Examples:

  • *[hreflang|=en] and [hreflang|=en] are equivalent,
  • *.warning and .warning are equivalent,
  • *#myid and #myid are equivalent.

Note: it is recommended that the * not be omitted, because it decreases the potential confusion between, for example, div :first-child and div:first-child. Here, div *:first-child is more readable.

6.2.1. Universal selector and namespaces

The universal selector allows an optional namespace component. It is used as follows:

ns|*
all elements in namespace ns
*|*
all elements
|*
all elements without a namespace
*
if no default namespace has been specified, this is equivalent to *|*. Otherwise it is equivalent to ns|* where ns is the default namespace.

A universal selector containing a namespace prefix that has not been previously declared is an invalid selector.

6.3. Attribute selectors

Selectors allow the representation of an element's attributes. When a selector is used as an expression to match against an element, attribute selectors must be considered to match an element if that element has an attribute that matches the attribute represented by the attribute selector.

6.3.1. Attribute presence and value selectors

CSS2 introduced four attribute selectors:

[att]
Represents an element with the att attribute, whatever the value of the attribute.
[att=val]
Represents an element with the att attribute whose value is exactly "val".
[att~=val]
Represents an element with the att attribute whose value is a whitespace-separated list of words, one of which is exactly "val". If "val" contains whitespace, it will never represent anything (since the words are separated by spaces). Also if "val" is the empty string, it will never represent anything.
[att|=val]
Represents an element with the att attribute, its value either being exactly "val" or beginning with "val" immediately followed by "-" (U+002D). This is primarily intended to allow language subcode matches (e.g., the hreflang attribute on the a element in HTML) as described in BCP 47 ([BCP47]) or its successor. For lang (or xml:lang) language subcode matching, please see the :lang pseudo-class.

Attribute values must be CSS identifiers or strings. [CSS21] The case-sensitivity of attribute names and values in selectors depends on the document language.

Examples:

The following attribute selector represents an h1 element that carries the title attribute, whatever its value:

h1[title]

In the following example, the selector represents a span element whose class attribute has exactly the value "example":

span[class="example"]

Multiple attribute selectors can be used to represent several attributes of an element, or several conditions on the same attribute. Here, the selector represents a span element whose hello attribute has exactly the value "Cleveland" and whose goodbye attribute has exactly the value "Columbus":

span[hello="Cleveland"][goodbye="Columbus"]

The following CSS rules illustrate the differences between "=" and "~=". The first selector would match, for example, an a element with the value "copyright copyleft copyeditor" on a rel attribute. The second selector would only match an a element with an href attribute having the exact value "http://www.w3.org/".

a[rel~="copyright"] { ... }
			a[href="http://www.w3.org/"] { ... }

The following selector represents an a element whose hreflang attribute is exactly "fr".

a[hreflang=fr]

The following selector represents an a element for which the value of the hreflang attribute begins with "en", including "en", "en-US", and "en-scouse":

a[hreflang|="en"]

The following selectors represent a DIALOGUE element whenever it has one of two different values for an attribute character:

DIALOGUE[character=romeo]
			DIALOGUE[character=juliet]

6.3.2. Substring matching attribute selectors

Three additional attribute selectors are provided for matching substrings in the value of an attribute:

[att^=val]
Represents an element with the att attribute whose value begins with the prefix "val". If "val" is the empty string then the selector does not represent anything.
[att$=val]
Represents an element with the att attribute whose value ends with the suffix "val". If "val" is the empty string then the selector does not represent anything.
[att*=val]
Represents an element with the att attribute whose value contains at least one instance of the substring "val". If "val" is the empty string then the selector does not represent anything.

Attribute values must be CSS identifiers or strings. [CSS21] The case-sensitivity of attribute names in selectors depends on the document language.

Examples:

The following selector represents an HTML object, referencing an image:

object[type^="image/"]

The following selector represents an HTML anchor a with an href attribute whose value ends with ".html".

a[href$=".html"]

The following selector represents an HTML paragraph with a title attribute whose value contains the substring "hello"

p[title*="hello"]

6.3.3. Attribute selectors and namespaces

The attribute name in an attribute selector is given as a CSS qualified name: a namespace prefix that has been previously declared may be prepended to the attribute name separated by the namespace separator "vertical bar" (|). In keeping with the Namespaces in the XML recommendation, default namespaces do not apply to attributes, therefore attribute selectors without a namespace component apply only to attributes that have no namespace (equivalent to "|attr"; these attributes are said to be in the "per-element-type namespace partition"). An asterisk may be used for the namespace prefix indicating that the selector is to match all attribute names without regard to the attribute's namespace.

An attribute selector with an attribute name containing a namespace prefix that has not been previously declared is an invalid selector.

CSS examples:

@namespace foo "http://www.example.com";
			[foo|att=val] { color: blue }
			[*|att] { color: yellow }
			[|att] { color: green }
			[att] { color: green }

The first rule will match only elements with the attribute att in the "http://www.example.com" namespace with the value "val".

The second rule will match only elements with the attribute att regardless of the namespace of the attribute (including no namespace).

The last two rules are equivalent and will match only elements with the attribute att where the attribute is not in a namespace.

6.3.4. Default attribute values in DTDs

Attribute selectors represent attribute values in the document tree. How that document tree is constructed is outside the scope of Selectors. In some document formats default attribute values can be defined in a DTD or elsewhere, but these can only be selected by attribute selectors if they appear in the document tree. Selectors should be designed so that they work whether or not the default values are included in the document tree.

For example, a XML UA may, but is not required to read an "external subset" of the DTD but is required to look for default attribute values in the document's "internal subset." (See, e.g., [XML10] for definitions of these subsets.) Depending on the UA, a default attribute value defined in the external subset of the DTD might or might not appear in the document tree.

A UA that recognizes an XML namespace may, but is not required to use its knowledge of that namespace to treat default attribute values as if they were present in the document. (For example, an XHTML UA is not required to use its built-in knowledge of the XHTML DTD. See, e.g., [XML-NAMES] for details on namespaces in XML 1.0.)

Note: Typically, implementations choose to ignore external subsets. This corresponds to the behaviour of non-validating processors as defined by the XML specification.

Example:

Consider an element EXAMPLE with an attribute radix that has a default value of "decimal". The DTD fragment might be

<!ATTLIST EXAMPLE radix (decimal,octal) "decimal">

If the style sheet contains the rules

EXAMPLE[radix=decimal] { /*... default property settings ...*/ }
			EXAMPLE[radix=octal]   { /*... other settings...*/ }

the first rule might not match elements whose radix attribute is set by default, i.e. not set explicitly. To catch all cases, the attribute selector for the default value must be dropped:

EXAMPLE                { /*... default property settings ...*/ }
			EXAMPLE[radix=octal]   { /*... other settings...*/ }

Here, because the selector EXAMPLE[radix=octal] is more specific than the type selector alone, the style declarations in the second rule will override those in the first for elements that have a radix attribute value of "octal". Care has to be taken that all property declarations that are to apply only to the default case are overridden in the non-default cases' style rules.

6.4. Class selectors

Working with HTML, authors may use the "period" notation (also known as "full stop", U+002E, .) as an alternative to the ~= notation when representing the class attribute. Thus, for HTML, div.value and div[class~=value] have the same meaning. The attribute value must immediately follow the full stop (.).

UAs may apply selectors using the period (.) notation in XML documents if the UA has namespace-specific knowledge that allows it to determine which attribute is the "class" attribute for the respective namespace. One such example of namespace-specific knowledge is the prose in the specification for a particular namespace (e.g. SVG 1.0 [SVG11] describes the SVG class attribute and how a UA should interpret it, and similarly MathML 1.01 [MATHML] describes the MathML class attribute.)

CSS examples:

We can assign style information to all elements with class~="pastoral" as follows:

*.pastoral { color: green }  /* all elements with class~=pastoral */

or just

.pastoral { color: green }  /* all elements with class~=pastoral */

The following assigns style only to H1 elements with class~="pastoral":

H1.pastoral { color: green }  /* H1 elements with class~=pastoral */

Given these rules, the first H1 instance below would not have green text, while the second would:

<H1>Not green</H1>
			<H1 class="pastoral">Very green</H1>

The following rule matches any P element whose class attribute has been assigned a list of whitespace-separated values that includes both pastoral and marine:

p.pastoral.marine { color: green }

This rule matches when class="pastoral blue aqua marine" but does not match for class="pastoral blue".

Note: Because CSS gives considerable power to the "class" attribute, authors could conceivably design their own "document language" based on elements with almost no associated presentation (such as DIV and SPAN in HTML) and assigning style information through the "class" attribute. Authors should avoid this practice since the structural elements of a document language often have recognized and accepted meanings and author-defined classes may not.

Note: If an element has multiple class attributes, their values must be concatenated with spaces between the values before searching for the class. As of this time the working group is not aware of any manner in which this situation can be reached, however, so this behavior is explicitly non-normative in this specification.

6.5. ID selectors

Document languages may contain attributes that are declared to be of type ID. What makes attributes of type ID special is that no two such attributes can have the same value in a conformant document, regardless of the type of the elements that carry them; whatever the document language, an ID typed attribute can be used to uniquely identify its element. In HTML all ID attributes are named "id"; XML applications may name ID attributes differently, but the same restriction applies.

An ID-typed attribute of a document language allows authors to assign an identifier to one element instance in the document tree. An ID selector contains a "number sign" (U+0023, #) immediately followed by the ID value, which must be an CSS identifiers. An ID selector represents an element instance that has an identifier that matches the identifier in the ID selector.

Selectors does not specify how a UA knows the ID-typed attribute of an element. The UA may, e.g., read a document's DTD, have the information hard-coded or ask the user.

Examples:

The following ID selector represents an h1 element whose ID-typed attribute has the value "chapter1":

h1#chapter1

The following ID selector represents any element whose ID-typed attribute has the value "chapter1":

#chapter1

The following selector represents any element whose ID-typed attribute has the value "z98y".

*#z98y

Note: In XML 1.0 [XML10], the information about which attribute contains an element's IDs is contained in a DTD or a schema. When parsing XML, UAs do not always read the DTD, and thus may not know what the ID of an element is (though a UA may have namespace-specific knowledge that allows it to determine which attribute is the ID attribute for that namespace). If a style sheet author knows or suspects that a UA may not know what the ID of an element is, he should use normal attribute selectors instead: [name=p371] instead of #p371.

If an element has multiple ID attributes, all of them must be treated as IDs for that element for the purposes of the ID selector. Such a situation could be reached using mixtures of xml:id, DOM3 Core, XML DTDs, and namespace-specific knowledge.

6.6. Pseudo-classes

The pseudo-class concept is introduced to permit selection based on information that lies outside of the document tree or that cannot be expressed using the other simple selectors.

A pseudo-class always consists of a "colon" (:) followed by the name of the pseudo-class and optionally by a value between parentheses.

Pseudo-classes are allowed in all sequences of simple selectors contained in a selector. Pseudo-classes are allowed anywhere in sequences of simple selectors, after the leading type selector or universal selector (possibly omitted). Pseudo-class names are case-insensitive. Some pseudo-classes are mutually exclusive, while others can be applied simultaneously to the same element. Pseudo-classes may be dynamic, in the sense that an element may acquire or lose a pseudo-class while a user interacts with the document.

6.6.1. Dynamic pseudo-classes

Dynamic pseudo-classes classify elements on characteristics other than their name, attributes, or content, in principle characteristics that cannot be deduced from the document tree.

Dynamic pseudo-classes do not appear in the document source or document tree.

User agents commonly display unvisited links differently from previously visited ones. Selectors provides the pseudo-classes :link and :visited to distinguish them:

  • The :link pseudo-class applies to links that have not yet been visited.
  • The :visited pseudo-class applies once the link has been visited by the user.

After some amount of time, user agents may choose to return a visited link to the (unvisited) ‘:link’ state.

The two states are mutually exclusive.

Example:

The following selector represents links carrying class external and already visited:

a.external:visited

Note: It is possible for style sheet authors to abuse the :link and :visited pseudo-classes to determine which sites a user has visited without the user's consent.

UAs may therefore treat all links as unvisited links, or implement other measures to preserve the user's privacy while rendering visited and unvisited links differently.

6.6.1.2. The user action pseudo-classes :hover, :active, and :focus

Interactive user agents sometimes change the rendering in response to user actions. Selectors provides three pseudo-classes for the selection of an element the user is acting on.

  • The :hover pseudo-class applies while the user designates an element with a pointing device, but does not necessarily activate it. For example, a visual user agent could apply this pseudo-class when the cursor (mouse pointer) hovers over a box generated by the element. User agents not that do not support interactive media do not have to support this pseudo-class. Some conforming user agents that support interactive media may not be able to support this pseudo-class (e.g., a pen device that does not detect hovering).
  • The :active pseudo-class applies while an element is being activated by the user. For example, between the times the user presses the mouse button and releases it. On systems with more than one mouse button, :active applies only to the primary or primary activation button (typically the "left" mouse button), and any aliases thereof.
  • The :focus pseudo-class applies while an element has the focus (accepts keyboard or mouse events, or other forms of input).

There may be document language or implementation specific limits on which elements can become :active or acquire :focus.

These pseudo-classes are not mutually exclusive. An element may match several pseudo-classes at the same time.

Selectors doesn't define if the parent of an element that is ‘:active’ or ‘:hover’ is also in that state.

Note: If the ‘:hover’ state applies to an element because its child is designated by a pointing device, then it's possible for ‘:hover’ to apply to an element that is not underneath the pointing device.

Examples:

a:link    /* unvisited links */
			a:visited /* visited links */
			a:hover   /* user hovers */
			a:active  /* active links */

An example of combining dynamic pseudo-classes:

a:focus
			a:focus:hover

The last selector matches a elements that are in the pseudo-class :focus and in the pseudo-class :hover.

Note: An element can be both ‘:visited’ and ‘:active’ (or ‘:link’ and ‘:active’).

6.6.2. The target pseudo-class :target

Some URIs refer to a location within a resource. This kind of URI ends with a "number sign" (#) followed by an anchor identifier (called the fragment identifier).

URIs with fragment identifiers link to a certain element within the document, known as the target element. For instance, here is a URI pointing to an anchor named section_2 in an HTML document:

http://example.com/html/top.html#section_2

A target element can be represented by the :target pseudo-class. If the document's URI has no fragment identifier, then the document has no target element.

Example:

p.note:target

This selector represents a p element of class note that is the target element of the referring URI.

CSS example:

Here, the :target pseudo-class is used to make the target element red and place an image before it, if there is one:

*:target { color : red }
			*:target::before { content : url(target.png) }

6.6.3. The language pseudo-class :lang

If the document language specifies how the human language of an element is determined, it is possible to write selectors that represent an element based on its language. For example, in HTML [HTML401], the language is determined by a combination of the lang attribute and possibly information from the meta elements or the protocol (such as HTTP headers). XML uses an attribute called xml:lang, and there may be other document language-specific methods for determining the language.

The pseudo-class :lang(C) represents an element that is in language C. Whether an element is represented by a :lang() selector is based solely on the element's language value (normalized to BCP 47 syntax if necessary) being equal to the identifier C, or beginning with the identifier C immediately followed by "-" (U+002D). 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.

C must be a valid CSS identifier [CSS21] and must not be empty. (Otherwise, the selector is invalid.)

Note: It is recommended that documents and protocols indicate language using codes from BCP 47 [BCP47] or its successor, and by means of "xml:lang" attributes in the case of XML-based documents [XML10]. See "FAQ: Two-letter or three-letter language codes."

Examples:

The two following selectors represent an HTML document that is in Belgian French or German. The two next selectors represent q quotations in an arbitrary element in Belgian French or German.

html:lang(fr-be)
			html:lang(de)
			:lang(fr-be) > q
			:lang(de) > q

The difference between :lang(C) and the ‘|=’ operator is that the ‘|=’ operator only performs a comparison against a given attribute on the element, while the :lang(C) pseudo-class uses the UAs knowledge of the document's semantics to perform the comparison.

In this HTML example, only the BODY matches [lang|=fr] (because it has a LANG attribute) but both the BODY and the P match :lang(fr) (because both are in French). The P does not match the [lang|=fr] because it does not have a LANG attribute.

<body lang=fr>
			<p>Je suis français.</p>
			</body>

6.6.4. The UI element states pseudo-classes

6.6.4.1. The :enabled and :disabled pseudo-classes

The :enabled pseudo-class represents user interface elements that are in an enabled state; such elements have a corresponding disabled state.

Conversely, the :disabled pseudo-class represents user interface elements that are in a disabled state; such elements have a corresponding enabled state.

What constitutes an enabled state, a disabled state, and a user interface element is language-dependent. In a typical document most elements will be neither :enabled nor :disabled.

Note: CSS properties that might affect a user’s ability to interact with a given user interface element do not affect whether it matches :enabled or :disabled; e.g., the display and visibility properties have no effect on the enabled/disabled state of an element.

6.6.4.2. The :checked pseudo-class

Radio and checkbox elements can be toggled by the user. Some menu items are "checked" when the user selects them. When such elements are toggled "on" the :checked pseudo-class applies. While the :checked pseudo-class is dynamic in nature, and can altered by user action, since it can also be based on the presence of semantic attributes in the document, it applies to all media. For example, the :checked pseudo-class initially applies to such elements that have the HTML4 selected and checked attributes as described in Section 17.2.1 of HTML4, but of course the user can toggle "off" such elements in which case the :checked pseudo-class would no longer apply.

6.6.4.3. The :indeterminate pseudo-class

Note: Radio and checkbox elements can be toggled by the user, but are sometimes in an indeterminate state, neither checked nor unchecked. This can be due to an element attribute, or DOM manipulation.

A future version of this specification may introduce an :indeterminate pseudo-class that applies to such elements.

6.6.5. Structural pseudo-classes

Selectors introduces the concept of structural pseudo-classes to permit selection based on extra information that lies in the document tree but cannot be represented by other simple selectors or combinators.

Standalone text and other non-element nodes are not counted when calculating the position of an element in the list of children of its parent. When calculating the position of an element in the list of children of its parent, the index numbering starts at 1.

6.6.5.1. :root pseudo-class

The :root pseudo-class represents an element that is the root of the document. In HTML 4, this is always the HTML element.

6.6.5.2. :nth-child() pseudo-class

The :nth-child(an+b) pseudo-class notation represents an element that has an+b-1 siblings before it in the document tree, for any positive integer or zero value of n, and has a parent element. For values of a and b greater than zero, this effectively divides the element's children into groups of a elements (the last group taking the remainder), and selecting the bth element of each group. For example, this allows the selectors to address every other row in a table, and could be used to alternate the color of paragraph text in a cycle of four. The a and b values must be integers (positive, negative, or zero). The index of the first child of an element is 1.

In addition to this, :nth-child() can take ‘odd’ and ‘even’ as arguments instead. ‘odd’ has the same signification as 2n+1, and ‘even’ has the same signification as 2n.

The argument to :nth-child() must match the grammar below, where INTEGER matches the token [0-9]+ and the rest of the tokenization is given by the Lexical scanner in section 10.2:

nth
		: S* [ ['-'|'+']? INTEGER? {N} [ S* ['-'|'+'] S* INTEGER ]? |
		['-'|'+']? INTEGER | {O}{D}{D} | {E}{V}{E}{N} ] S*
		;

Examples:

tr:nth-child(2n+1) /* represents every odd row of an HTML table */
			tr:nth-child(odd)  /* same */
			tr:nth-child(2n+0) /* represents every even row of an HTML table */
			tr:nth-child(even) /* same */

			/* Alternate paragraph colours in CSS */
			p:nth-child(4n+1) { color: navy; }
			p:nth-child(4n+2) { color: green; }
			p:nth-child(4n+3) { color: maroon; }
			p:nth-child(4n+4) { color: purple; }

When the value b is preceded by a negative sign, the "+" character in the expression must be removed (it is effectively replaced by the "-" character indicating the negative value of b).

Examples:

:nth-child(10n-1)  /* represents the 9th, 19th, 29th, etc, element */
			:nth-child(10n+9)  /* Same */
			:nth-child(10n+-1) /* Syntactically invalid, and would be ignored */

When a=0, the an part need not be included (unless the b part is already omitted). When an is not included and b is non-negative, the + sign before b (when allowed) may also be omitted. In this case the syntax simplifies to :nth-child(b).

Examples:

foo:nth-child(0n+5)   /* represents an element foo that is the 5th child
			of its parent element */
			foo:nth-child(5)      /* same */

When a=1, or a=-1, the number may be omitted from the rule.

Examples:

The following selectors are therefore equivalent:

bar:nth-child(1n+0)   /* represents all bar elements, specificity (0,1,1) */
			bar:nth-child(n+0)    /* same */
			bar:nth-child(n)      /* same */
			bar                   /* same but lower specificity (0,0,1) */

If b=0, then every ath element is picked. In such a case, the +b (or -b) part may be omitted unless the a part is already omitted.

Examples:

tr:nth-child(2n+0) /* represents every even row of an HTML table */
			tr:nth-child(2n) /* same */

Whitespace is permitted after the "(", before the ")", and on either side of the "+" or "-" that separates the an and b parts when both are present.

Valid Examples with white space:

:nth-child( 3n + 1 )
			:nth-child( +3n - 2 )
			:nth-child( -n+ 6)
			:nth-child( +6 )
		

Invalid Examples with white space:

:nth-child(3 n)
			:nth-child(+ 2n)
			:nth-child(+ 2)
		

If both a and b are equal to zero, the pseudo-class represents no element in the document tree.

The value a can be negative, but only the positive values of an+b, for n≥0, may represent an element in the document tree.

Example:

html|tr:nth-child(-n+6)  /* represents the 6 first rows of XHTML tables */
6.6.5.3. :nth-last-child() pseudo-class

The :nth-last-child(an+b) pseudo-class notation represents an element that has an+b-1 siblings after it in the document tree, for any positive integer or zero value of n, and has a parent element. See :nth-child() pseudo-class for the syntax of its argument. It also accepts the ‘even’ and ‘odd’ values as arguments.

Examples:

tr:nth-last-child(-n+2)    /* represents the two last rows of an HTML table */

			foo:nth-last-child(odd)    /* represents all odd foo elements in their parent element,
			counting from the last one */
6.6.5.4. :nth-of-type() pseudo-class

The :nth-of-type(an+b) pseudo-class notation represents an element that has an+b-1 siblings with the same expanded element name before it in the document tree, for any zero or positive integer value of n, and has a parent element. See :nth-child() pseudo-class for the syntax of its argument. It also accepts the ‘even’ and ‘odd’ values.

CSS example:

This allows an author to alternate the position of floated images:

img:nth-of-type(2n+1) { float: right; }
			img:nth-of-type(2n) { float: left; }
6.6.5.5. :nth-last-of-type() pseudo-class

The :nth-last-of-type(an+b) pseudo-class notation represents an element that has an+b-1 siblings with the same expanded element name after it in the document tree, for any zero or positive integer value of n, and has a parent element. See :nth-child() pseudo-class for the syntax of its argument. It also accepts the ‘even’ and ‘odd’ values.

Example:

To represent all h2 children of an XHTML body except the first and last, one could use the following selector:

body > h2:nth-of-type(n+2):nth-last-of-type(n+2)

In this case, one could also use :not(), although the selector ends up being just as long:

body > h2:not(:first-of-type):not(:last-of-type)
6.6.5.6. :first-child pseudo-class

Same as :nth-child(1). The :first-child pseudo-class represents an element that is the first child of some other element.

Examples:

The following selector represents a p element that is the first child of a div element:

div > p:first-child

This selector can represent the p inside the div of the following fragment:

<p> The last P before the note.</p>
			<div class="note">
			<p> The first P inside the note.</p>
			</div>
but cannot represent the second p in the following fragment:
<p> The last P before the note.</p>
			<div class="note">
			<h2> Note </h2>
			<p> The first P inside the note.</p>
			</div>

The following two selectors are usually equivalent:

* > a:first-child /* a is first child of any element */
			a:first-child /* Same (assuming a is not the root element) */
6.6.5.7. :last-child pseudo-class

Same as :nth-last-child(1). The :last-child pseudo-class represents an element that is the last child of some other element.

Example:

The following selector represents a list item li that is the last child of an ordered list ol.

ol > li:last-child
6.6.5.8. :first-of-type pseudo-class

Same as :nth-of-type(1). The :first-of-type pseudo-class represents an element that is the first sibling of its type in the list of children of its parent element.

Example:

The following selector represents a definition title dt inside a definition list dl, this dt being the first of its type in the list of children of its parent element.

dl dt:first-of-type

It is a valid description for the first two dt elements in the following example but not for the third one:

<dl>
			<dt>gigogne</dt>
			<dd>
			<dl>
			<dt>fusée</dt>
			<dd>multistage rocket</dd>
			<dt>table</dt>
			<dd>nest of tables</dd>
			</dl>
			</dd>
			</dl>
6.6.5.9. :last-of-type pseudo-class

Same as :nth-last-of-type(1). The :last-of-type pseudo-class represents an element that is the last sibling of its type in the list of children of its parent element.

Example:

The following selector represents the last data cell td of a table row tr.

tr > td:last-of-type
6.6.5.10. :only-child pseudo-class

Represents an element that has a parent element and whose parent element has no other element children. Same as :first-child:last-child or :nth-child(1):nth-last-child(1), but with a lower specificity.

6.6.5.11. :only-of-type pseudo-class

Represents an element that has a parent element and whose parent element has no other element children with the same expanded element name. Same as :first-of-type:last-of-type or :nth-of-type(1):nth-last-of-type(1), but with a lower specificity.

6.6.5.12. :empty pseudo-class

The :empty pseudo-class represents an element that has no children at all. In terms of the document tree, only element nodes and content nodes (such as DOM [DOM-LEVEL-3-CORE] text nodes, CDATA nodes, and entity references) whose data has a non-zero length must be considered as affecting emptiness; comments, processing instructions, and other nodes must not affect whether an element is considered empty or not.

Examples:

p:empty is a valid representation of the following fragment:

<p></p>

foo:empty is not a valid representation for the following fragments:

<foo>bar</foo>
<foo><bar>bla</bar></foo>
<foo>this is not <bar>:empty</bar></foo>

6.6.6. Blank

This section intentionally left blank. (This section previously defined a :contains() pseudo-class.)

6.6.7. The negation pseudo-class

The negation pseudo-class, :not(X), is a functional notation taking a simple selector (excluding the negation pseudo-class itself) as an argument. It represents an element that is not represented by its argument.

Negations may not be nested; :not(:not(...)) is invalid. Note also that since pseudo-elements are not simple selectors, they are not a valid argument to :not().

Examples:

The following selector matches all button elements in an HTML document that are not disabled.

button:not([DISABLED])

The following selector represents all but FOO elements.

*:not(FOO)

The following group of selectors represents all HTML elements except links.

html|*:not(:link):not(:visited)

Default namespace declarations do not affect the argument of the negation pseudo-class unless the argument is a universal selector or a type selector.

Examples:

Assuming that the default namespace is bound to "http://example.com/", the following selector represents all elements that are not in that namespace:

*|*:not(*)

The following selector matches any element that is not being hovered, regardless of its namespace. In particular, it is not limited to only matching elements in the default namespace that are not being hovered, and elements not in the default namespace don't match the rule when they are being hovered.

*|*:not(:hover)

Note: the :not() pseudo allows useless selectors to be written. For instance :not(*|*), which represents no element at all, or foo:not(bar), which is equivalent to foo but with a higher specificity.

7. Pseudo-elements

Pseudo-elements create abstractions about the document tree beyond those specified by the document language. For instance, document languages do not offer mechanisms to access the first letter or first line of an element's content. Pseudo-elements allow authors to refer to this otherwise inaccessible information. Pseudo-elements may also provide authors a way to refer to content that does not exist in the source document (e.g., the ::before and ::after pseudo-elements give access to generated content).

A pseudo-element is made of two colons (::) followed by the name of the pseudo-element.

This :: notation is introduced by the current document in order to establish a discrimination between pseudo-classes and pseudo-elements. For compatibility with existing style sheets, user agents must also accept the previous one-colon notation for pseudo-elements introduced in CSS levels 1 and 2 (namely, :first-line, :first-letter, :before and :after). This compatibility is not allowed for the new pseudo-elements introduced in this specification.

Only one pseudo-element may appear per selector, and if present it must appear after the sequence of simple selectors that represents the subjects of the selector. Note: A future version of this specification may allow multiple pseudo-elements per selector.

7.1. The ::first-line pseudo-element

The ::first-line pseudo-element describes the contents of the first formatted line of an element.

CSS example:

p::first-line { text-transform: uppercase }

The above rule means "change the letters of the first line of every p element to uppercase".

The selector p::first-line does not match any real document element. It does match a pseudo-element that conforming user agents will insert at the beginning of every p element.

Note that the length of the first line depends on a number of factors, including the width of the page, the font size, etc. Thus, an ordinary HTML paragraph such as:

<P>This is a somewhat long HTML 
		paragraph that will be broken into several 
		lines. The first line will be identified
		by a fictional tag sequence. The other lines 
		will be treated as ordinary lines in the 
		paragraph.</P>
	

the lines of which happen to be broken as follows:

THIS IS A SOMEWHAT LONG HTML PARAGRAPH THAT
		will be broken into several lines. The first
		line will be identified by a fictional tag 
		sequence. The other lines will be treated as 
		ordinary lines in the paragraph.
	

This paragraph might be "rewritten" by user agents to include the fictional tag sequence for ::first-line. This fictional tag sequence helps to show how properties are inherited.

<P><P::first-line> This is a somewhat long HTML 
		paragraph that </P::first-line> will be broken into several
		lines. The first line will be identified 
		by a fictional tag sequence. The other lines 
		will be treated as ordinary lines in the 
		paragraph.</P>
	

If a pseudo-element breaks up a real element, the desired effect can often be described by a fictional tag sequence that closes and then re-opens the element. Thus, if we mark up the previous paragraph with a span element:

<P><SPAN class="test"> This is a somewhat long HTML
		paragraph that will be broken into several
		lines.</SPAN> The first line will be identified
		by a fictional tag sequence. The other lines 
		will be treated as ordinary lines in the 
		paragraph.</P>
	

the user agent could simulate start and end tags for span when inserting the fictional tag sequence for ::first-line.

<P><P::first-line><SPAN class="test"> This is a
		somewhat long HTML
		paragraph that will </SPAN></P::first-line><SPAN class="test"> be
		broken into several
		lines.</SPAN> The first line will be identified
		by a fictional tag sequence. The other lines
		will be treated as ordinary lines in the 
		paragraph.</P>
	

7.1.1. First formatted line definition in CSS

In CSS, the ::first-line pseudo-element can only have an effect when attached to a block-like container such as a block box, inline-block, table-caption, or table-cell.

The first formatted line of an element may occur inside a block-level descendant in the same flow (i.e., a block-level descendant that is not out-of-flow due to floating or positioning). For example, the first line of the DIV in <DIV><P>This line...</P></DIV> is the first line of the P (assuming that both P and DIV are block-level).

The first line of a table-cell or inline-block cannot be the first formatted line of an ancestor element. Thus, in <DIV><P STYLE="display: inline-block">Hello<BR>Goodbye</P> etcetera</DIV> the first formatted line of the DIV is not the line "Hello".

Note: Note that the first line of the p in this fragment: <p><br>First... doesn't contain any letters (assuming the default style for br in HTML 4). The word "First" is not on the first formatted line.

A UA should act as if the fictional start tags of the ::first-line pseudo-elements were nested just inside the innermost enclosing block-level element. (Since CSS1 and CSS2 were silent on this case, authors should not rely on this behavior.) For example, the fictional tag sequence for

<DIV>
		<P>First paragraph</P>
		<P>Second paragraph</P>
		</DIV>
	

is

<DIV>
		<P><DIV::first-line><P::first-line>First paragraph</P::first-line></DIV::first-line></P>
		<P><P::first-line>Second paragraph</P::first-line></P>
		</DIV>
	

The ::first-line pseudo-element is similar to an inline-level element, but with certain restrictions. The following CSS properties apply to a ::first-line pseudo-element: font properties, color property, background properties, ‘word-spacing’, ‘letter-spacing’, ‘text-decoration’, ‘vertical-align’, ‘text-transform’, ‘line-height’. UAs may apply other properties as well.

During CSS inheritance, the portion of a child element that occurs on the first line only inherits properties applicable to the ::first-line pseudo-element from the ::first-line pseudo-element. For all other properties inheritence is from the non-pseudo-element parent of the first line pseudo element. (The portion of a child element that does not occur on the first line always inherits from the parent of that child.)

7.2. The ::first-letter pseudo-element

The ::first-letter pseudo-element represents the first letter of an element, if it is not preceded by any other content (such as images or inline tables) on its line. The ::first-letter pseudo-element may be used for "initial caps" and "drop caps", which are common typographical effects.

Punctuation (i.e, characters defined in Unicode in the "open" (Ps), "close" (Pe), "initial" (Pi). "final" (Pf) and "other" (Po) punctuation classes), that precedes or follows the first letter should be included. [UNICODE]

The ::first-letter also applies if the first letter is in fact a digit, e.g., the "6" in "67 million dollars is a lot of money."

Note: In some cases the ::first-letter pseudo-element should include more than just the first non-punctuation character on a line. For example, combining characters must be kept with their base character. Additionally, some languages may have specific rules about how to treat certain letter combinations. The UA definition of ::first-letter should include at least the default grapheme cluster as defined by UAX29 and may include more than that as appropriate. In Dutch, for example, if the letter combination "ij" appears at the beginning of an element, both letters should be considered within the ::first-letter pseudo-element. [UAX29]

If the letters that would form the ::first-letter are not in the same element, such as "‘T" in <p>'<em>T..., the UA may create a ::first-letter pseudo-element from one of the elements, both elements, or simply not create a pseudo-element.

Similarly, if the first letter(s) of the block are not at the start of the line (for example due to bidirectional reordering), then the UA need not create the pseudo-element(s).

Example:

The following CSS and HTML example illustrates how overlapping pseudo-elements may interact. The first letter of each P element will be green with a font size of ’24pt'. The rest of the first formatted line will be ‘blue’ while the rest of the paragraph will be ‘red’.

p { color: red; font-size: 12pt }
			p::first-letter { color: green; font-size: 200% }
			p::first-line { color: blue }

			<P>Some text that ends up on two lines</P>

Assuming that a line break will occur before the word "ends", the fictional tag sequence for this fragment might be:

<P>
			<P::first-line>
			<P::first-letter> 
			S 
			</P::first-letter>ome text that 
			</P::first-line> 
			ends up on two lines 
			</P>

Note that the ::first-letter element is inside the ::first-line element. Properties set on ::first-line are inherited by ::first-letter, but are overridden if the same property is set on ::first-letter.

The first letter must occur on the first formatted line. For example, in this HTML fragment: <p><br>First... the first line doesn't contain any letters and ::first-letter doesn't match anything (assuming the default style for br in HTML 4). In particular, it does not match the "F" of "First."

7.2.1. Application in CSS

In CSS, the ::first-letter pseudo-element applies to block-like containers such as block, list-item, table-cell, table-caption, and inline-block elements. Note: A future version of this specification may allow this pseudo-element to apply to more display types.

The ::first-letter pseudo-element can be used with all such elements that contain text, or that have a descendant in the same flow that contains text. A UA should act as if the fictional start tag of the ::first-letter pseudo-element is just before the first text of the element, even if that first text is in a descendant.

Example:

The fictional tag sequence for this HTML fragment:

<div>
			<p>The first text.

is:

<div>
			<p><div::first-letter><p::first-letter>T</...></...>he first text.

In CSS the first letter of a table-cell or inline-block cannot be the first letter of an ancestor element. Thus, in <DIV><P STYLE="display: inline-block">Hello<BR>Goodbye</P> etcetera</DIV> the first letter of the DIV is not the letter "H". In fact, the DIV doesn't have a first letter.

If an element is a list item (‘display: list-item’), the ::first-letter applies to the first letter in the principal box after the marker. UAs may ignore ::first-letter on list items with ‘list-style-position: inside’. If an element has ::before or ::after content, the ::first-letter applies to the first letter of the element including that content.

Example:

After the rule p::before {content: "Note: "}, the selector p::first-letter matches the "N" of "Note".

In CSS a ::first-line pseudo-element is similar to an inline-level element if its ‘float’ property is ‘none’; otherwise, it is similar to a floated element. The following properties that apply to ::first-letter pseudo-elements: font properties, ‘text-decoration’, ‘text-transform’, ‘letter-spacing’, ‘word-spacing’ (when appropriate), ‘line-height’, ‘float’, ‘vertical-align’ (only if ‘float’ is ‘none’), margin properties, padding properties, border properties, color property, background properties. UAs may apply other properties as well. To allow UAs to render a typographically correct drop cap or initial cap, the UA may choose a line-height, width and height based on the shape of the letter, unlike for normal elements.

Example:

This CSS and HTML example shows a possible rendering of an initial cap. Note that the ‘line-height’ that is inherited by the ::first-letter pseudo-element is 1.1, but the UA in this example has computed the height of the first letter differently, so that it doesn't cause any unnecessary space between the first two lines. Also note that the fictional start tag of the first letter is inside the span, and thus the font weight of the first letter is normal, not bold as the span:

p { line-height: 1.1 }
			p::first-letter { font-size: 3em; font-weight: normal }
			span { font-weight: bold }
			...
			<p><span>Het hemelsche</span> gerecht heeft zich ten lange lesten<br>
			Erbarremt over my en mijn benaeuwde vesten<br>
			En arme burgery, en op mijn volcx gebed<br>
			En dagelix geschrey de bange stad ontzet.
		

The following CSS will make a drop cap initial letter span about two lines:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
			<HTML>
			<HEAD>
			<TITLE>Drop cap initial letter</TITLE>
			<STYLE type="text/css">
			P               { font-size: 12pt; line-height: 1.2 }
			P::first-letter { font-size: 200%; font-weight: bold; float: left }
			SPAN            { text-transform: uppercase }
			</STYLE>
			</HEAD>
			<BODY>
			<P><SPAN>The first</SPAN> few words of an article
			in The Economist.</P>
			</BODY>
			</HTML>
		

This example might be formatted as follows:

The fictional tag sequence is:

<P>
			<SPAN>
			<P::first-letter>
			T
			</P::first-letter>he first
			</SPAN> 
			few words of an article in the Economist.
			</P>
		

Note that the ::first-letter pseudo-element tags abut the content (i.e., the initial character), while the ::first-line pseudo-element start tag is inserted right after the start tag of the block element.

In order to achieve traditional drop caps formatting, user agents may approximate font sizes, for example to align baselines. Also, the glyph outline may be taken into account when formatting.

7.3. Blank

This section intentionally left blank. (This section previously defined a ::selection pseudo-element.)

7.4. The ::before and ::after pseudo-elements

The ::before and ::after pseudo-elements can be used to describe generated content before or after an element's content. They are explained in CSS 2.1 [CSS21].

When the ::first-letter and ::first-line pseudo-elements are applied to an element having content generated using ::before or ::after, they apply to the first letter or line of the element including the generated content.

8. Combinators

8.1. Descendant combinator

At times, authors may want selectors to describe an element that is the descendant of another element in the document tree (e.g., "an EM element that is contained within an H1 element"). Descendant combinators express such a relationship. A descendant combinator is whitespace that separates two sequences of simple selectors. A selector of the form "A B" represents an element B that is an arbitrary descendant of some ancestor element A.

Examples:

For example, consider the following selector:

h1 em

It represents an em element being the descendant of an h1 element. It is a correct and valid, but partial, description of the following fragment:

<h1>This <span class="myclass">headline
			is <em>very</em> important</span></h1>

The following selector:

div * p

represents a p element that is a grandchild or later descendant of a div element. Note the whitespace on either side of the "*" is not part of the universal selector; the whitespace is a combinator indicating that the div must be the ancestor of some element, and that that element must be an ancestor of the p.

The following selector, which combines descendant combinators and attribute selectors, represents an element that (1) has the href attribute set and (2) is inside a p that is itself inside a div:

div p *[href]

8.2. Child combinators

A child combinator describes a childhood relationship between two elements. A child combinator is made of the "greater-than sign" (U+003E, >) character and separates two sequences of simple selectors.

Examples:

The following selector represents a p element that is child of body:

body > p

The following example combines descendant combinators and child combinators.

div ol>li p

It represents a p element that is a descendant of an li element; the li element must be the child of an ol element; the ol element must be a descendant of a div. Notice that the optional white space around the ">" combinator has been left out.

For information on selecting the first child of an element, please see the section on the :first-child pseudo-class above.

8.3. Sibling combinators

There are two different sibling combinators: the adjacent sibling combinator and the general sibling combinator. In both cases, non-element nodes (e.g. text between elements) are ignored when considering adjacency of elements.

8.3.1. Adjacent sibling combinator

The adjacent sibling combinator is made of the "plus sign" (U+002B, +) character that separates two sequences of simple selectors. The elements represented by the two sequences share the same parent in the document tree and the element represented by the first sequence immediately precedes the element represented by the second one.

Examples:

The following selector represents a p element immediately following a math element:

math + p

The following selector is conceptually similar to the one in the previous example, except that it adds an attribute selector — it adds a constraint to the h1 element, that it must have class="opener":

h1.opener + h2

8.3.2. General sibling combinator

The general sibling combinator is made of the "tilde" (U+007E, ~) character that separates two sequences of simple selectors. The elements represented by the two sequences share the same parent in the document tree and the element represented by the first sequence precedes (not necessarily immediately) the element represented by the second one.

Example:

h1 ~ pre

represents a pre element following an h1. It is a correct and valid, but partial, description of:

<h1>Definition of the function a</h1>
			<p>Function a(x) has to be applied to all figures in the table.</p>
			<pre>function a(x) = 12x/13.5</pre>

9. Calculating a selector's specificity

A selector's specificity is calculated as follows:

  • count the number of ID selectors in the selector (= a)
  • count the number of class selectors, attributes selectors, and pseudo-classes in the selector (= b)
  • count the number of type selectors and pseudo-elements in the selector (= c)
  • ignore the universal selector

Selectors inside the negation pseudo-class are counted like any other, but the negation itself does not count as a pseudo-class.

Concatenating the three numbers a-b-c (in a number system with a large base) gives the specificity.

Examples:

*               /* a=0 b=0 c=0 -> specificity =   0 */
			LI              /* a=0 b=0 c=1 -> specificity =   1 */
			UL LI           /* a=0 b=0 c=2 -> specificity =   2 */
			UL OL+LI        /* a=0 b=0 c=3 -> specificity =   3 */
			H1 + *[REL=up]  /* a=0 b=1 c=1 -> specificity =  11 */
			UL OL LI.red    /* a=0 b=1 c=3 -> specificity =  13 */
			LI.red.level    /* a=0 b=2 c=1 -> specificity =  21 */
			#x34y           /* a=1 b=0 c=0 -> specificity = 100 */
			#s12:not(FOO)   /* a=1 b=0 c=1 -> specificity = 101 */
		

Note: Repeated occurrances of the same simple selector are allowed and do increase specificity.

Note: the specificity of the styles specified in an HTML style attribute is described in CSS 2.1. [CSS21].

10. The grammar of Selectors

10.1. Grammar

The grammar below defines the syntax of Selectors. It is globally LL(1) and can be locally LL(2) (but note that most UAs should not use it directly, since it doesn't express the parsing conventions). The format of the productions is optimized for human consumption and some shorthand notations beyond Yacc (see [YACC]) are used:

  • *: 0 or more
  • +: 1 or more
  • ?: 0 or 1
  • |: separates alternatives
  • [ ]: grouping

The productions are:

selectors_group
		: selector [ COMMA S* selector ]*
		;

		selector
		: simple_selector_sequence [ combinator simple_selector_sequence ]*
		;

		combinator
		/* combinators can be surrounded by whitespace */
		: PLUS S* | GREATER S* | TILDE S* | S+
		;

		simple_selector_sequence
		: [ type_selector | universal ]
		[ HASH | class | attrib | pseudo | negation ]*
		| [ HASH | class | attrib | pseudo | negation ]+
		;

		type_selector
		: [ namespace_prefix ]? element_name
		;

		namespace_prefix
		: [ IDENT | '*' ]? '|'
		;

		element_name
		: IDENT
		;

		universal
		: [ namespace_prefix ]? '*'
		;

		class
		: '.' IDENT
		;

		attrib
		: '[' S* [ namespace_prefix ]? IDENT S*
		[ [ PREFIXMATCH |
		SUFFIXMATCH |
		SUBSTRINGMATCH |
		'=' |
		INCLUDES |
		DASHMATCH ] S* [ IDENT | STRING ] S*
		]? ']'
		;

		pseudo
		/* '::' starts a pseudo-element, ':' a pseudo-class */
		/* Exceptions: :first-line, :first-letter, :before and :after. */
		/* Note that pseudo-elements are restricted to one per selector and */
		/* occur only in the last simple_selector_sequence. */
		: ':' ':'? [ IDENT | functional_pseudo ]
		;

		functional_pseudo
		: FUNCTION S* expression ')'
		;

		expression
		/* In CSS3, the expressions are identifiers, strings, */
		/* or of the form "an+b" */
		: [ [ PLUS | '-' | DIMENSION | NUMBER | STRING | IDENT ] S* ]+
		;

		negation
		: NOT S* negation_arg S* ')'
		;

		negation_arg
		: type_selector | universal | HASH | class | attrib | pseudo
		;

10.2. Lexical scanner

The following is the tokenizer, written in Flex (see [FLEX]) notation. The tokenizer is case-insensitive.

The two occurrences of "\377" represent the highest character number that current versions of Flex can deal with (decimal 255). They should be read as "\4177777" (decimal 1114111), which is the highest possible code point in Unicode/ISO-10646. [UNICODE]

%option case-insensitive

		ident     [-]?{nmstart}{nmchar}*
		name      {nmchar}+
		nmstart   [_a-z]|{nonascii}|{escape}
		nonascii  [^\0-\177]
		unicode   \\[0-9a-f]{1,6}(\r\n|[ \n\r\t\f])?
		escape    {unicode}|\\[^\n\r\f0-9a-f]
		nmchar    [_a-z0-9-]|{nonascii}|{escape}
		num       [0-9]+|[0-9]*\.[0-9]+
		string    {string1}|{string2}
		string1   \"([^\n\r\f\\"]|\\{nl}|{nonascii}|{escape})*\"
		string2   \'([^\n\r\f\\']|\\{nl}|{nonascii}|{escape})*\'
		invalid   {invalid1}|{invalid2}
		invalid1  \"([^\n\r\f\\"]|\\{nl}|{nonascii}|{escape})*
		invalid2  \'([^\n\r\f\\']|\\{nl}|{nonascii}|{escape})*
		nl        \n|\r\n|\r|\f
		w         [ \t\r\n\f]*

		D         d|\\0{0,4}(44|64)(\r\n|[ \t\r\n\f])?
		E         e|\\0{0,4}(45|65)(\r\n|[ \t\r\n\f])?
		N         n|\\0{0,4}(4e|6e)(\r\n|[ \t\r\n\f])?|\\n
		O         o|\\0{0,4}(4f|6f)(\r\n|[ \t\r\n\f])?|\\o
		T         t|\\0{0,4}(54|74)(\r\n|[ \t\r\n\f])?|\\t
		V         v|\\0{0,4}(58|78)(\r\n|[ \t\r\n\f])?|\\v

		%%

		[ \t\r\n\f]+     return S;

		"~="             return INCLUDES;
		"|="             return DASHMATCH;
		"^="             return PREFIXMATCH;
		"$="             return SUFFIXMATCH;
		"*="             return SUBSTRINGMATCH;
		{ident}          return IDENT;
		{string}         return STRING;
		{ident}"("       return FUNCTION;
		{num}            return NUMBER;
		"#"{name}        return HASH;
		{w}"+"           return PLUS;
		{w}">"           return GREATER;
		{w}","           return COMMA;
		{w}"~"           return TILDE;
		":"{N}{O}{T}"("  return NOT;
		@{ident}         return ATKEYWORD;
		{invalid}        return INVALID;
		{num}%           return PERCENTAGE;
		{num}{ident}     return DIMENSION;
		"<!--"           return CDO;
		"-->"            return CDC;

		\/\*[^*]*\*+([^/*][^*]*\*+)*\/                    /* ignore comments */

		.                return *yytext;
	

11. Profiles

Each specification using Selectors must define the subset of Selectors it allows and excludes, and describe the local meaning of all the components of that subset.

Non normative examples:

Selectors profile
Specification CSS level 1
Accepts type selectors
class selectors
ID selectors
:link, :visited and :active pseudo-classes
descendant combinator
::first-line and ::first-letter pseudo-elements
Excludes

universal selector
attribute selectors
:hover and :focus pseudo-classes
:target pseudo-class
:lang() pseudo-class
all UI element states pseudo-classes
all structural pseudo-classes
negation pseudo-class
::before and ::after pseudo-elements
child combinators
sibling combinators

namespaces

Extra constraints only one class selector allowed per sequence of simple selectors


Selectors profile
Specification CSS level 2
Accepts type selectors
universal selector
attribute presence and values selectors
class selectors
ID selectors
:link, :visited, :active, :hover, :focus, :lang() and :first-child pseudo-classes
descendant combinator
child combinator
adjacent sibling combinator
::first-line and ::first-letter pseudo-elements
::before and ::after pseudo-elements
Excludes

substring matching attribute selectors
:target pseudo-classes
all UI element states pseudo-classes
all structural pseudo-classes other than :first-child
negation pseudo-class
general sibling combinators

namespaces

Extra constraints more than one class selector per sequence of simple selectors (CSS1 constraint) allowed

In CSS, selectors express pattern matching rules that determine which style rules apply to elements in the document tree.

The following selector (CSS level 2) will match all anchors a with attribute name set inside a section 1 header h1:

h1 a[name]

All CSS declarations attached to such a selector are applied to elements matching it.

Selectors profile
Specification STTS 3
Accepts

type selectors
universal selectors
attribute selectors
class selectors
ID selectors
all structural pseudo-classes
all combinators

namespaces

Excludes non-accepted pseudo-classes
pseudo-elements
Extra constraints some selectors and combinators are not allowed in fragment descriptions on the right side of STTS declarations.

Selectors can be used in STTS 3 in two different manners:

  1. a selection mechanism equivalent to CSS selection mechanism: declarations attached to a given selector are applied to elements matching that selector,
  2. fragment descriptions that appear on the right side of declarations.

12. Conformance and requirements

This section defines conformance with the present specification only.

The inability of a user agent to implement part of this specification due to the limitations of a particular device (e.g., non interactive user agents will probably not implement dynamic pseudo-classes because they make no sense without interactivity) does not imply non-conformance.

All specifications reusing Selectors must contain a Profile listing the subset of Selectors it accepts or excludes, and describing the constraints it adds to the current specification.

Invalidity is caused by a parsing error, e.g. an unrecognized token or a token which is not allowed at the current parsing point.

User agents must observe the rules for handling parsing errors:

  • a simple selector containing an undeclared namespace prefix is invalid
  • a selector containing an invalid simple selector, an invalid combinator or an invalid token is invalid.
  • a group of selectors containing an invalid selector is invalid.

Specifications reusing Selectors must define how to handle parsing errors. (In the case of CSS, the entire rule in which the selector is used is dropped.)

13. Tests

This specification has a test suite allowing user agents to verify their basic conformance to the specification. This test suite does not pretend to be exhaustive and does not cover all possible combined cases of Selectors.

14. Acknowledgements

The CSS working group would like to thank everyone who has sent comments on this specification over the years.

In particular, the working group would like to extend special thanks to Donna McManus, Justin Baker, Joel Sklar, and Molly Ives Brower who performed the final editorial review of the last call draft. The working group would also like to thank Adam Kuehn, Boris Zbarsky, David Perrell, Elliotte Harold, Matthew Raymond, Ruud Steltenpool, Patrick Garies, Anton Prowse, and the W3C Internationalization Working Group for their last call comments and kind words.

15. References

15.1. Normative References

[CSS21]
Bert Bos; et al. Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification. 07 June 2011. W3C Recommendation. URL: http://www.w3.org/TR/2011/REC-CSS2-20110607/
[CSS3NAMESPACE]
Elika J. Etemad; Anne van Kesteren. CSS Namespaces Module. 29 September 2011. W3C Recommendation. URL: http://www.w3.org/TR/2011/REC-css3-namespace-20110929/
[FLEX]
Flex: The Lexical Scanner Generator. Version 2.3.7, ISBN 1882114213
[UNICODE]
The Unicode Consortium. The Unicode Standard, Version 6.0.0, (Mountain View, CA: The Unicode Consortium, 2011. ISBN 978-1-936213-01-6) and as updated from time to time by the publication of new versions. (See http://www.unicode.org/unicode/standard/versions/ for the latest version and additional information on versions of the standard and of the Unicode Character Database).
Available at http://www.unicode.org/versions/Unicode6.0.0/
[YACC]
S. C. Johnson. YACC - Yet another compiler compiler. Murray Hill. 1975. Technical Report.

15.2. Informative References

[BCP47]
A. Phillips; M. DavisTags for Identifying Languages and Matching of Language Tags. September 2009. Internet Best Current Practice 47. URL: http://www.rfc-editor.org/rfc/bcp/bcp47.txt
[CSS1]
Håkon Wium Lie; Bert Bos. Cascading Style Sheets (CSS1) Level 1 Specification. 11 April 2008. W3C Recommendation. URL: http://www.w3.org/TR/2008/REC-CSS1-20080411
[DOM-LEVEL-3-CORE]
Gavin Nicol; et al. Document Object Model (DOM) Level 3 Core Specification. 7 April 2004. W3C Recommendation. URL: http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407
[HTML401]
David Raggett; Ian Jacobs; Arnaud Le Hors. HTML 4.01 Specification. 24 December 1999. W3C Recommendation. URL: http://www.w3.org/TR/1999/REC-html401-19991224
[MATHML]
Patrick Ion; Robert Miner. Mathematical Markup Language (MathML) 1.01 Specification. 7 July 1999. W3C Recommendation. URL: http://www.w3.org/1999/07/REC-MathML-19990707
[STTS3]
Daniel Glazman. Simple Tree Transformation Sheets 3. Electricité de France. 11 November 1998. Submission to the W3C. URL: http://www.w3.org/TR/NOTE-STTS3
[SVG11]
Erik Dahlström et. al. Scalable Vector Graphics (SVG) 1.1 Specification. 16 August 2011. W3C Recommendation. URL: http://www.w3.org/TR/2011/REC-SVG11-20110816/
[UAX29]
Mark Davis. Text Boundaries. 25 March 2005. Unicode Standard Annex #29. URL: http://www.unicode.org/unicode/reports/tr29/tr29-9.html
[XML-NAMES]
Tim Bray; et al. Namespaces in XML 1.0 (Third Edition). 6 August 2009. W3C Proposed Edited Recommendation. URL: http://www.w3.org/TR/2009/PER-xml-names-20090806
[XML10]
C. M. Sperberg-McQueen; et al. Extensible Markup Language (XML) 1.0 (Fifth Edition). 10 February 1998. W3C Proposed Edited Recommendation. Revised 5 February 2008 URL: http://www.w3.org/TR/2008/PER-xml-20080205
sizzle-1.10.17/speed/frameworks/000077500000000000000000000000001226755370700164775ustar00rootroot00000000000000sizzle-1.10.17/speed/frameworks/dojo.js000066400000000000000000022173631226755370700200060ustar00rootroot00000000000000/* Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved. Available via Academic Free License >= 2.1 OR the modified BSD license. see: http://dojotoolkit.org/license for details */ /* This is an optimized version of Dojo, built for deployment and not for development. To get sources and documentation, please visit: http://dojotoolkit.org */ (function( userConfig, defaultConfig ){ // summary: // This is the "source loader" and is the entry point for Dojo during development. You may also load Dojo with // any AMD-compliant loader via the package main module dojo/main. // description: // This is the "source loader" for Dojo. It provides an AMD-compliant loader that can be configured // to operate in either synchronous or asynchronous modes. After the loader is defined, dojo is loaded // IAW the package main module dojo/main. In the event you wish to use a foreign loader, you may load dojo as a package // via the package main module dojo/main and this loader is not required; see dojo/package.json for details. // // In order to keep compatibility with the v1.x line, this loader includes additional machinery that enables // the dojo.provide, dojo.require et al API. This machinery is loaded by default, but may be dynamically removed // via the has.js API and statically removed via the build system. // // This loader includes sniffing machinery to determine the environment; the following environments are supported: // // - browser // - node.js // - rhino // // This is the so-called "source loader". As such, it includes many optional features that may be discadred by // building a customized verion with the build system. // Design and Implementation Notes // // This is a dojo-specific adaption of bdLoad, donated to the dojo foundation by Altoviso LLC. // // This function defines an AMD-compliant (http://wiki.commonjs.org/wiki/Modules/AsynchronousDefinition) // loader that can be configured to operate in either synchronous or asynchronous modes. // // Since this machinery implements a loader, it does not have the luxury of using a load system and/or // leveraging a utility library. This results in an unpleasantly long file; here is a road map of the contents: // // 1. Small library for use implementing the loader. // 2. Define the has.js API; this is used throughout the loader to bracket features. // 3. Define the node.js and rhino sniffs and sniff. // 4. Define the loader's data. // 5. Define the configuration machinery. // 6. Define the script element sniffing machinery and sniff for configuration data. // 7. Configure the loader IAW the provided user, default, and sniffing data. // 8. Define the global require function. // 9. Define the module resolution machinery. // 10. Define the module and plugin module definition machinery // 11. Define the script injection machinery. // 12. Define the window load detection. // 13. Define the logging API. // 14. Define the tracing API. // 16. Define the AMD define function. // 17. Define the dojo v1.x provide/require machinery--so called "legacy" modes. // 18. Publish global variables. // // Language and Acronyms and Idioms // // moduleId: a CJS module identifier, (used for public APIs) // mid: moduleId (used internally) // packageId: a package identifier (used for public APIs) // pid: packageId (used internally); the implied system or default package has pid==="" // pack: package is used internally to reference a package object (since javascript has reserved words including "package") // prid: plugin resource identifier // The integer constant 1 is used in place of true and 0 in place of false. // define a minimal library to help build the loader var noop = function(){ }, isEmpty = function(it){ for(var p in it){ return 0; } return 1; }, toString = {}.toString, isFunction = function(it){ return toString.call(it) == "[object Function]"; }, isString = function(it){ return toString.call(it) == "[object String]"; }, isArray = function(it){ return toString.call(it) == "[object Array]"; }, forEach = function(vector, callback){ if(vector){ for(var i = 0; i < vector.length;){ callback(vector[i++]); } } }, mix = function(dest, src){ for(var p in src){ dest[p] = src[p]; } return dest; }, makeError = function(error, info){ return mix(new Error(error), {src:"dojoLoader", info:info}); }, uidSeed = 1, uid = function(){ // Returns a unique indentifier (within the lifetime of the document) of the form /_d+/. return "_" + uidSeed++; }, // FIXME: how to doc window.require() api // this will be the global require function; define it immediately so we can start hanging things off of it req = function( config, //(object, optional) hash of configuration properties dependencies, //(array of commonjs.moduleId, optional) list of modules to be loaded before applying callback callback //(function, optional) lamda expression to apply to module values implied by dependencies ){ return contextRequire(config, dependencies, callback, 0, req); }, // the loader uses the has.js API to control feature inclusion/exclusion; define then use throughout global = this, doc = global.document, element = doc && doc.createElement("DiV"), has = req.has = function(name){ return isFunction(hasCache[name]) ? (hasCache[name] = hasCache[name](global, doc, element)) : hasCache[name]; }, hasCache = has.cache = defaultConfig.hasCache; has.add = function(name, test, now, force){ (hasCache[name]===undefined || force) && (hasCache[name] = test); return now && has(name); }; 0 && has.add("host-node", userConfig.has && "host-node" in userConfig.has ? userConfig.has["host-node"] : (typeof process == "object" && process.versions && process.versions.node && process.versions.v8)); if( 0 ){ // fixup the default config for node.js environment require("./_base/configNode.js").config(defaultConfig); // remember node's require (with respect to baseUrl==dojo's root) defaultConfig.loaderPatch.nodeRequire = require; } 0 && has.add("host-rhino", userConfig.has && "host-rhino" in userConfig.has ? userConfig.has["host-rhino"] : (typeof load == "function" && (typeof Packages == "function" || typeof Packages == "object"))); if( 0 ){ // owing to rhino's lame feature that hides the source of the script, give the user a way to specify the baseUrl... for(var baseUrl = userConfig.baseUrl || ".", arg, rhinoArgs = this.arguments, i = 0; i < rhinoArgs.length;){ arg = (rhinoArgs[i++] + "").split("="); if(arg[0] == "baseUrl"){ baseUrl = arg[1]; break; } } load(baseUrl + "/_base/configRhino.js"); rhinoDojoConfig(defaultConfig, baseUrl, rhinoArgs); } // userConfig has tests override defaultConfig has tests; do this after the environment detection because // the environment detection usually sets some has feature values in the hasCache. for(var p in userConfig.has){ has.add(p, userConfig.has[p], 0, 1); } // // define the loader data // // the loader will use these like symbols if the loader has the traceApi; otherwise // define magic numbers so that modules can be provided as part of defaultConfig var requested = 1, arrived = 2, nonmodule = 3, executing = 4, executed = 5; if( 0 ){ // these make debugging nice; but using strings for symbols is a gross rookie error; don't do it for production code requested = "requested"; arrived = "arrived"; nonmodule = "not-a-module"; executing = "executing"; executed = "executed"; } var legacyMode = 0, sync = "sync", xd = "xd", syncExecStack = [], dojoRequirePlugin = 0, checkDojoRequirePlugin = noop, transformToAmd = noop, getXhr; if( 1 ){ req.isXdUrl = noop; req.initSyncLoader = function(dojoRequirePlugin_, checkDojoRequirePlugin_, transformToAmd_){ // the first dojo/_base/loader loaded gets to define these variables; they are designed to work // in the presense of zero to many mapped dojo/_base/loaders if(!dojoRequirePlugin){ dojoRequirePlugin = dojoRequirePlugin_; checkDojoRequirePlugin = checkDojoRequirePlugin_; transformToAmd = transformToAmd_; } return { sync:sync, requested:requested, arrived:arrived, nonmodule:nonmodule, executing:executing, executed:executed, syncExecStack:syncExecStack, modules:modules, execQ:execQ, getModule:getModule, injectModule:injectModule, setArrived:setArrived, signal:signal, finishExec:finishExec, execModule:execModule, dojoRequirePlugin:dojoRequirePlugin, getLegacyMode:function(){return legacyMode;}, guardCheckComplete:guardCheckComplete }; }; if( 1 ){ // in legacy sync mode, the loader needs a minimal XHR library var locationProtocol = location.protocol, locationHost = location.host; req.isXdUrl = function(url){ if(/^\./.test(url)){ // begins with a dot is always relative to page URL; therefore not xdomain return false; } if(/^\/\//.test(url)){ // for v1.6- backcompat, url starting with // indicates xdomain return true; } // get protocol and host // \/+ takes care of the typical file protocol that looks like file:///drive/path/to/file // locationHost is falsy if file protocol => if locationProtocol matches and is "file:", || will return false var match = url.match(/^([^\/\:]+\:)\/+([^\/]+)/); return match && (match[1] != locationProtocol || (locationHost && match[2] != locationHost)); }; // note: to get the file:// protocol to work in FF, you must set security.fileuri.strict_origin_policy to false in about:config 1 || has.add("dojo-xhr-factory", 1); has.add("dojo-force-activex-xhr", 1 && !doc.addEventListener && window.location.protocol == "file:"); has.add("native-xhr", typeof XMLHttpRequest != "undefined"); if(has("native-xhr") && !has("dojo-force-activex-xhr")){ getXhr = function(){ return new XMLHttpRequest(); }; }else{ // if in the browser an old IE; find an xhr for(var XMLHTTP_PROGIDS = ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0'], progid, i = 0; i < 3;){ try{ progid = XMLHTTP_PROGIDS[i++]; if(new ActiveXObject(progid)){ // this progid works; therefore, use it from now on break; } }catch(e){ // squelch; we're just trying to find a good ActiveX progid // if they all fail, then progid ends up as the last attempt and that will signal the error // the first time the client actually tries to exec an xhr } } getXhr = function(){ return new ActiveXObject(progid); }; } req.getXhr = getXhr; has.add("dojo-gettext-api", 1); req.getText = function(url, async, onLoad){ var xhr = getXhr(); xhr.open('GET', fixupUrl(url), false); xhr.send(null); if(xhr.status == 200 || (!location.host && !xhr.status)){ if(onLoad){ onLoad(xhr.responseText, async); } }else{ throw makeError("xhrFailed", xhr.status); } return xhr.responseText; }; } }else{ req.async = 1; } // // loader eval // var eval_ = // use the function constructor so our eval is scoped close to (but not in) in the global space with minimal pollution new Function('return eval(arguments[0]);'); req.eval = function(text, hint){ return eval_(text + "\r\n////@ sourceURL=" + hint); }; // // loader micro events API // var listenerQueues = {}, error = "error", signal = req.signal = function(type, args){ var queue = listenerQueues[type]; // notice we run a copy of the queue; this allows listeners to add/remove // other listeners without affecting this particular signal forEach(queue && queue.slice(0), function(listener){ listener.apply(null, isArray(args) ? args : [args]); }); }, on = req.on = function(type, listener){ // notice a queue is not created until a client actually connects var queue = listenerQueues[type] || (listenerQueues[type] = []); queue.push(listener); return { remove:function(){ for(var i = 0; i (alias, actual) = [], paths // CommonJS paths = {}, pathsMapProg // list of (from-path, to-path, regex, length) derived from paths; // a "program" to apply paths; see computeMapProg = [], packs // a map from packageId to package configuration object; see fixupPackageInfo = {}, map = req.map // AMD map config variable; dojo/_base/kernel needs req.map to figure out the scope map = {}, mapProgs // vector of quads as described by computeMapProg; map-key is AMD map key, map-value is AMD map value = [], modules // A hash:(mid) --> (module-object) the module namespace // // pid: the package identifier to which the module belongs (e.g., "dojo"); "" indicates the system or default package // mid: the fully-resolved (i.e., mappings have been applied) module identifier without the package identifier (e.g., "dojo/io/script") // url: the URL from which the module was retrieved // pack: the package object of the package to which the module belongs // executed: 0 => not executed; executing => in the process of tranversing deps and running factory; executed => factory has been executed // deps: the dependency vector for this module (vector of modules objects) // def: the factory for this module // result: the result of the running the factory for this module // injected: (0 | requested | arrived) the status of the module; nonmodule means the resource did not call define // load: plugin load function; applicable only for plugins // // Modules go through several phases in creation: // // 1. Requested: some other module's definition or a require application contained the requested module in // its dependency vector or executing code explicitly demands a module via req.require. // // 2. Injected: a script element has been appended to the insert-point element demanding the resource implied by the URL // // 3. Loaded: the resource injected in [2] has been evalated. // // 4. Defined: the resource contained a define statement that advised the loader about the module. Notice that some // resources may just contain a bundle of code and never formally define a module via define // // 5. Evaluated: the module was defined via define and the loader has evaluated the factory and computed a result. = {}, cacheBust // query string to append to module URLs to bust browser cache = "", cache // hash:(mid | url)-->(function | string) // // A cache of resources. The resources arrive via a config.cache object, which is a hash from either mid --> function or // url --> string. The url key is distinguished from the mid key by always containing the prefix "url:". url keys as provided // by config.cache always have a string value that represents the contents of the resource at the given url. mid keys as provided // by configl.cache always have a function value that causes the same code to execute as if the module was script injected. // // Both kinds of key-value pairs are entered into cache via the function consumePendingCache, which may relocate keys as given // by any mappings *iff* the config.cache was received as part of a module resource request. // // Further, for mid keys, the implied url is computed and the value is entered into that key as well. This allows mapped modules // to retrieve cached items that may have arrived consequent to another namespace. // = {}, urlKeyPrefix // the prefix to prepend to a URL key in the cache. = "url:", pendingCacheInsert // hash:(mid)-->(function) // // Gives a set of cache modules pending entry into cache. When cached modules are published to the loader, they are // entered into pendingCacheInsert; modules are then pressed into cache upon (1) AMD define or (2) upon receiving another // independent set of cached modules. (1) is the usual case, and this case allows normalizing mids given in the pending // cache for the local configuration, possibly relocating modules. = {}, dojoSniffConfig // map of configuration variables // give the data-dojo-config as sniffed from the document (if any) = {}; if( 1 ){ var consumePendingCacheInsert = function(referenceModule){ var p, item, match, now, m; for(p in pendingCacheInsert){ item = pendingCacheInsert[p]; match = p.match(/^url\:(.+)/); if(match){ cache[urlKeyPrefix + toUrl(match[1], referenceModule)] = item; }else if(p=="*now"){ now = item; }else if(p!="*noref"){ m = getModuleInfo(p, referenceModule); cache[m.mid] = cache[urlKeyPrefix + m.url] = item; } } if(now){ now(createRequire(referenceModule)); } pendingCacheInsert = {}; }, escapeString = function(s){ return s.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, function(c){ return "\\" + c; }); }, computeMapProg = function(map, dest){ // This routine takes a map as represented by a JavaScript object and initializes dest, a vector of // quads of (map-key, map-value, refex-for-map-key, length-of-map-key), sorted decreasing by length- // of-map-key. The regex looks for the map-key followed by either "/" or end-of-string at the beginning // of a the search source. Notice the map-value is irrelevent to the algorithm dest.splice(0, dest.length); for(var p in map){ dest.push([ p, map[p], new RegExp("^" + escapeString(p) + "(\/|$)"), p.length]); } dest.sort(function(lhs, rhs){ return rhs[3] - lhs[3]; }); return dest; }, fixupPackageInfo = function(packageInfo){ // calculate the precise (name, location, main, mappings) for a package var name = packageInfo.name; if(!name){ // packageInfo must be a string that gives the name name = packageInfo; packageInfo = {name:name}; } packageInfo = mix({main:"main"}, packageInfo); packageInfo.location = packageInfo.location ? packageInfo.location : name; // packageMap is depricated in favor of AMD map if(packageInfo.packageMap){ map[name] = packageInfo.packageMap; } if(!packageInfo.main.indexOf("./")){ packageInfo.main = packageInfo.main.substring(2); } // now that we've got a fully-resolved package object, push it into the configuration packs[name] = packageInfo; }, config = function(config, booting, referenceModule){ for(var p in config){ if(p=="waitSeconds"){ req.waitms = (config[p] || 0) * 1000; } if(p=="cacheBust"){ cacheBust = config[p] ? (isString(config[p]) ? config[p] : (new Date()).getTime() + "") : ""; } if(p=="baseUrl" || p=="combo"){ req[p] = config[p]; } if( 1 && p=="async"){ // falsy or "sync" => legacy sync loader // "xd" => sync but loading xdomain tree and therefore loading asynchronously (not configurable, set automatically by the loader) // "legacyAsync" => permanently in "xd" by choice // "debugAtAllCosts" => trying to load everything via script injection (not implemented) // otherwise, must be truthy => AMD // legacyMode: sync | legacyAsync | xd | false var mode = config[p]; req.legacyMode = legacyMode = (isString(mode) && /sync|legacyAsync/.test(mode) ? mode : (!mode ? sync : false)); req.async = !legacyMode; } if(config[p]!==hasCache){ // accumulate raw config info for client apps which can use this to pass their own config req.rawConfig[p] = config[p]; p!="has" && has.add("config-"+p, config[p], 0, booting); } } // make sure baseUrl exists if(!req.baseUrl){ req.baseUrl = "./"; } // make sure baseUrl ends with a slash if(!/\/$/.test(req.baseUrl)){ req.baseUrl += "/"; } // now do the special work for has, packages, packagePaths, paths, aliases, and cache for(p in config.has){ has.add(p, config.has[p], 0, booting); } // for each package found in any packages config item, augment the packs map owned by the loader forEach(config.packages, fixupPackageInfo); // for each packagePath found in any packagePaths config item, augment the packageConfig // packagePaths is depricated; remove in 2.0 for(baseUrl in config.packagePaths){ forEach(config.packagePaths[baseUrl], function(packageInfo){ var location = baseUrl + "/" + packageInfo; if(isString(packageInfo)){ packageInfo = {name:packageInfo}; } packageInfo.location = location; fixupPackageInfo(packageInfo); }); } // notice that computeMapProg treats the dest as a reference; therefore, if/when that variable // is published (see dojo-publish-privates), the published variable will always hold a valid value. // this must come after all package processing since package processing may mutate map computeMapProg(mix(map, config.map), mapProgs); forEach(mapProgs, function(item){ item[1] = computeMapProg(item[1], []); if(item[0]=="*"){ mapProgs.star = item[1]; } }); // push in any paths and recompute the internal pathmap computeMapProg(mix(paths, config.paths), pathsMapProg); // aliases forEach(config.aliases, function(pair){ if(isString(pair[0])){ pair[0] = new RegExp("^" + escapeString(pair[0]) + "$"); } aliases.push(pair); }); for(p in config.config){ var module = getModule(p, referenceModule); module.config = mix(module.config || {}, config.config[p]); } // push in any new cache values if(config.cache){ consumePendingCacheInsert(); pendingCacheInsert = config.cache; if(config.cache["*noref"]){ consumePendingCacheInsert(); } } signal("config", [config, req.rawConfig]); }; // // execute the various sniffs; userConfig can override and value // if(has("dojo-cdn") || 1 ){ // the sniff regex looks for a src attribute ending in dojo.js, optionally preceeded with a path. // match[3] returns the path to dojo.js (if any) without the trailing slash. This is used for the // dojo location on CDN deployments and baseUrl when either/both of these are not provided // explicitly in the config data; this is the 1.6- behavior. var scripts = doc.getElementsByTagName("script"), i = 0, script, dojoDir, src, match; while(i < scripts.length){ script = scripts[i++]; if((src = script.getAttribute("src")) && (match = src.match(/(((.*)\/)|^)dojo\.js(\W|$)/i))){ // sniff dojoDir and baseUrl dojoDir = match[3] || ""; defaultConfig.baseUrl = defaultConfig.baseUrl || dojoDir; // sniff configuration on attribute in script element src = (script.getAttribute("data-dojo-config") || script.getAttribute("djConfig")); if(src){ dojoSniffConfig = req.eval("({ " + src + " })", "data-dojo-config"); } // sniff requirejs attribute if( 0 ){ var dataMain = script.getAttribute("data-main"); if(dataMain){ dojoSniffConfig.deps = dojoSniffConfig.deps || [dataMain]; } } break; } } } if( 0 ){ // pass down doh.testConfig from parent as if it were a data-dojo-config try{ if(window.parent != window && window.parent.require){ var doh = window.parent.require("doh"); doh && mix(dojoSniffConfig, doh.testConfig); } }catch(e){} } // configure the loader; let the user override defaults req.rawConfig = {}; config(defaultConfig, 1); // do this before setting userConfig/sniffConfig to allow userConfig/sniff overrides if(has("dojo-cdn")){ packs.dojo.location = dojoDir; if(dojoDir){ dojoDir += "/"; } packs.dijit.location = dojoDir + "../dijit/"; packs.dojox.location = dojoDir + "../dojox/"; } config(userConfig, 1); config(dojoSniffConfig, 1); }else{ // no config API, assume defaultConfig has everything the loader needs...for the entire lifetime of the application paths = defaultConfig.paths; pathsMapProg = defaultConfig.pathsMapProg; packs = defaultConfig.packs; aliases = defaultConfig.aliases; mapProgs = defaultConfig.mapProgs; modules = defaultConfig.modules; cache = defaultConfig.cache; cacheBust = defaultConfig.cacheBust; // remember the default config for other processes (e.g., dojo/config) req.rawConfig = defaultConfig; } if( 0 ){ req.combo = req.combo || {add:noop}; var comboPending = 0, combosPending = [], comboPendingTimer = null; } // build the loader machinery iaw configuration, including has feature tests var injectDependencies = function(module){ // checkComplete!=0 holds the idle signal; we're not idle if we're injecting dependencies guardCheckComplete(function(){ forEach(module.deps, injectModule); if( 0 && comboPending && !comboPendingTimer){ comboPendingTimer = setTimeout(function() { comboPending = 0; comboPendingTimer = null; req.combo.done(function(mids, url) { var onLoadCallback= function(){ // defQ is a vector of module definitions 1-to-1, onto mids runDefQ(0, mids); checkComplete(); }; combosPending.push(mids); injectingModule = mids; req.injectUrl(url, onLoadCallback, mids); injectingModule = 0; }, req); }, 0); } }); }, contextRequire = function(a1, a2, a3, referenceModule, contextRequire){ var module, syntheticMid; if(isString(a1)){ // signature is (moduleId) module = getModule(a1, referenceModule, true); if(module && module.executed){ return module.result; } throw makeError("undefinedModule", a1); } if(!isArray(a1)){ // a1 is a configuration config(a1, 0, referenceModule); // juggle args; (a2, a3) may be (dependencies, callback) a1 = a2; a2 = a3; } if(isArray(a1)){ // signature is (requestList [,callback]) if(!a1.length){ a2 && a2(); }else{ syntheticMid = "require*" + uid(); // resolve the request list with respect to the reference module for(var mid, deps = [], i = 0; i < a1.length;){ mid = a1[i++]; deps.push(getModule(mid, referenceModule)); } // construct a synthetic module to control execution of the requestList, and, optionally, callback module = mix(makeModuleInfo("", syntheticMid, 0, ""), { injected: arrived, deps: deps, def: a2 || noop, require: referenceModule ? referenceModule.require : req, gc: 1 //garbage collect }); modules[module.mid] = module; // checkComplete!=0 holds the idle signal; we're not idle if we're injecting dependencies injectDependencies(module); // try to immediately execute // if already traversing a factory tree, then strict causes circular dependency to abort the execution; maybe // it's possible to execute this require later after the current traversal completes and avoid the circular dependency. // ...but *always* insist on immediate in synch mode var strict = checkCompleteGuard && legacyMode!=sync; guardCheckComplete(function(){ execModule(module, strict); }); if(!module.executed){ // some deps weren't on board or circular dependency detected and strict; therefore, push into the execQ execQ.push(module); } checkComplete(); } } return contextRequire; }, createRequire = function(module){ if(!module){ return req; } var result = module.require; if(!result){ result = function(a1, a2, a3){ return contextRequire(a1, a2, a3, module, result); }; module.require = mix(result, req); result.module = module; result.toUrl = function(name){ return toUrl(name, module); }; result.toAbsMid = function(mid){ return toAbsMid(mid, module); }; if( 0 ){ result.undef = function(mid){ req.undef(mid, module); }; } if( 1 ){ result.syncLoadNls = function(mid){ var nlsModuleInfo = getModuleInfo(mid, module), nlsModule = modules[nlsModuleInfo.mid]; if(!nlsModule || !nlsModule.executed){ cached = cache[nlsModuleInfo.mid] || cache[urlKeyPrefix + nlsModuleInfo.url]; if(cached){ evalModuleText(cached); nlsModule = modules[nlsModuleInfo.mid]; } } return nlsModule && nlsModule.executed && nlsModule.result; }; } } return result; }, execQ = // The list of modules that need to be evaluated. [], defQ = // The queue of define arguments sent to loader. [], waiting = // The set of modules upon which the loader is waiting for definition to arrive {}, setRequested = function(module){ module.injected = requested; waiting[module.mid] = 1; if(module.url){ waiting[module.url] = module.pack || 1; } startTimer(); }, setArrived = function(module){ module.injected = arrived; delete waiting[module.mid]; if(module.url){ delete waiting[module.url]; } if(isEmpty(waiting)){ clearTimer(); 1 && legacyMode==xd && (legacyMode = sync); } }, execComplete = req.idle = // says the loader has completed (or not) its work function(){ return !defQ.length && isEmpty(waiting) && !execQ.length && !checkCompleteGuard; }, runMapProg = function(targetMid, map){ // search for targetMid in map; return the map item if found; falsy otherwise if(map){ for(var i = 0; i < map.length; i++){ if(map[i][2].test(targetMid)){ return map[i]; } } } return 0; }, compactPath = function(path){ var result = [], segment, lastSegment; path = path.replace(/\\/g, '/').split('/'); while(path.length){ segment = path.shift(); if(segment==".." && result.length && lastSegment!=".."){ result.pop(); lastSegment = result[result.length - 1]; }else if(segment!="."){ result.push(lastSegment= segment); } // else ignore "." } return result.join("/"); }, makeModuleInfo = function(pid, mid, pack, url){ if( 1 ){ var xd= req.isXdUrl(url); return {pid:pid, mid:mid, pack:pack, url:url, executed:0, def:0, isXd:xd, isAmd:!!(xd || (packs[pid] && packs[pid].isAmd))}; }else{ return {pid:pid, mid:mid, pack:pack, url:url, executed:0, def:0}; } }, getModuleInfo_ = function(mid, referenceModule, packs, modules, baseUrl, mapProgs, pathsMapProg, alwaysCreate){ // arguments are passed instead of using lexical variables so that this function my be used independent of the loader (e.g., the builder) // alwaysCreate is useful in this case so that getModuleInfo never returns references to real modules owned by the loader var pid, pack, midInPackage, mapProg, mapItem, url, result, isRelative, requestedMid; requestedMid = mid; isRelative = /^\./.test(mid); if(/(^\/)|(\:)|(\.js$)/.test(mid) || (isRelative && !referenceModule)){ // absolute path or protocol of .js filetype, or relative path but no reference module and therefore relative to page // whatever it is, it's not a module but just a URL of some sort // note: pid===0 indicates the routine is returning an unmodified mid return makeModuleInfo(0, mid, 0, mid); }else{ // relative module ids are relative to the referenceModule; get rid of any dots mid = compactPath(isRelative ? (referenceModule.mid + "/../" + mid) : mid); if(/^\./.test(mid)){ throw makeError("irrationalPath", mid); } // at this point, mid is an absolute mid // map the mid if(referenceModule){ mapItem = runMapProg(referenceModule.mid, mapProgs); } mapItem = mapItem || mapProgs.star; mapItem = mapItem && runMapProg(mid, mapItem[1]); if(mapItem){ mid = mapItem[1] + mid.substring(mapItem[3]); } match = mid.match(/^([^\/]+)(\/(.+))?$/); pid = match ? match[1] : ""; if((pack = packs[pid])){ mid = pid + "/" + (midInPackage = (match[3] || pack.main)); }else{ pid = ""; } // search aliases var candidateLength = 0, candidate = 0; forEach(aliases, function(pair){ var match = mid.match(pair[0]); if(match && match.length>candidateLength){ candidate = isFunction(pair[1]) ? mid.replace(pair[0], pair[1]) : pair[1]; } }); if(candidate){ return getModuleInfo_(candidate, 0, packs, modules, baseUrl, mapProgs, pathsMapProg, alwaysCreate); } result = modules[mid]; if(result){ return alwaysCreate ? makeModuleInfo(result.pid, result.mid, result.pack, result.url) : modules[mid]; } } // get here iff the sought-after module does not yet exist; therefore, we need to compute the URL given the // fully resolved (i.e., all relative indicators and package mapping resolved) module id // note: pid!==0 indicates the routine is returning a url that has .js appended unmodified mid mapItem = runMapProg(mid, pathsMapProg); if(mapItem){ url = mapItem[1] + mid.substring(mapItem[3]); }else if(pid){ url = pack.location + "/" + midInPackage; }else if(has("config-tlmSiblingOfDojo")){ url = "../" + mid; }else{ url = mid; } // if result is not absolute, add baseUrl if(!(/(^\/)|(\:)/.test(url))){ url = baseUrl + url; } url += ".js"; return makeModuleInfo(pid, mid, pack, compactPath(url)); }, getModuleInfo = function(mid, referenceModule){ return getModuleInfo_(mid, referenceModule, packs, modules, req.baseUrl, mapProgs, pathsMapProg); }, resolvePluginResourceId = function(plugin, prid, referenceModule){ return plugin.normalize ? plugin.normalize(prid, function(mid){return toAbsMid(mid, referenceModule);}) : toAbsMid(prid, referenceModule); }, dynamicPluginUidGenerator = 0, getModule = function(mid, referenceModule, immediate){ // compute and optionally construct (if necessary) the module implied by the mid with respect to referenceModule var match, plugin, prid, result; match = mid.match(/^(.+?)\!(.*)$/); if(match){ // name was ! plugin = getModule(match[1], referenceModule, immediate); if( 1 && legacyMode == sync && !plugin.executed){ injectModule(plugin); if(plugin.injected===arrived && !plugin.executed){ guardCheckComplete(function(){ execModule(plugin); }); } if(plugin.executed){ promoteModuleToPlugin(plugin); }else{ // we are in xdomain mode for some reason execQ.unshift(plugin); } } if(plugin.executed === executed && !plugin.load){ // executed the module not knowing it was a plugin promoteModuleToPlugin(plugin); } // if the plugin has not been loaded, then can't resolve the prid and must assume this plugin is dynamic until we find out otherwise if(plugin.load){ prid = resolvePluginResourceId(plugin, match[2], referenceModule); mid = (plugin.mid + "!" + (plugin.dynamic ? ++dynamicPluginUidGenerator + "!" : "") + prid); }else{ prid = match[2]; mid = plugin.mid + "!" + (++dynamicPluginUidGenerator) + "!waitingForPlugin"; } result = {plugin:plugin, mid:mid, req:createRequire(referenceModule), prid:prid}; }else{ result = getModuleInfo(mid, referenceModule); } return modules[result.mid] || (!immediate && (modules[result.mid] = result)); }, toAbsMid = req.toAbsMid = function(mid, referenceModule){ return getModuleInfo(mid, referenceModule).mid; }, toUrl = req.toUrl = function(name, referenceModule){ var moduleInfo = getModuleInfo(name+"/x", referenceModule), url= moduleInfo.url; return fixupUrl(moduleInfo.pid===0 ? // if pid===0, then name had a protocol or absolute path; either way, toUrl is the identify function in such cases name : // "/x.js" since getModuleInfo automatically appends ".js" and we appended "/x" to make name look likde a module id url.substring(0, url.length-5) ); }, nonModuleProps = { injected: arrived, executed: executed, def: nonmodule, result: nonmodule }, makeCjs = function(mid){ return modules[mid] = mix({mid:mid}, nonModuleProps); }, cjsRequireModule = makeCjs("require"), cjsExportsModule = makeCjs("exports"), cjsModuleModule = makeCjs("module"), runFactory = function(module, args){ req.trace("loader-run-factory", [module.mid]); var factory = module.def, result; 1 && syncExecStack.unshift(module); if(has("config-dojo-loader-catches")){ try{ result= isFunction(factory) ? factory.apply(null, args) : factory; }catch(e){ signal(error, module.result = makeError("factoryThrew", [module, e])); } }else{ result= isFunction(factory) ? factory.apply(null, args) : factory; } module.result = result===undefined && module.cjs ? module.cjs.exports : result; 1 && syncExecStack.shift(module); }, abortExec = {}, defOrder = 0, promoteModuleToPlugin = function(pluginModule){ var plugin = pluginModule.result; pluginModule.dynamic = plugin.dynamic; pluginModule.normalize = plugin.normalize; pluginModule.load = plugin.load; return pluginModule; }, resolvePluginLoadQ = function(plugin){ // plugins is a newly executed module that has a loadQ waiting to run // step 1: traverse the loadQ and fixup the mid and prid; remember the map from original mid to new mid // recall the original mid was created before the plugin was on board and therefore it was impossible to // compute the final mid; accordingly, prid may or may not change, but the mid will definitely change var map = {}; forEach(plugin.loadQ, function(pseudoPluginResource){ // manufacture and insert the real module in modules var prid = resolvePluginResourceId(plugin, pseudoPluginResource.prid, pseudoPluginResource.req.module), mid = plugin.dynamic ? pseudoPluginResource.mid.replace(/waitingForPlugin$/, prid) : (plugin.mid + "!" + prid), pluginResource = mix(mix({}, pseudoPluginResource), {mid:mid, prid:prid, injected:0}); if(!modules[mid]){ // create a new (the real) plugin resource and inject it normally now that the plugin is on board injectPlugin(modules[mid] = pluginResource); } // else this was a duplicate request for the same (plugin, rid) for a nondynamic plugin // pluginResource is really just a placeholder with the wrong mid (because we couldn't calculate it until the plugin was on board) // mark is as arrived and delete it from modules; the real module was requested above map[pseudoPluginResource.mid] = modules[mid]; setArrived(pseudoPluginResource); delete modules[pseudoPluginResource.mid]; }); plugin.loadQ = 0; // step2: replace all references to any placeholder modules with real modules var substituteModules = function(module){ for(var replacement, deps = module.deps || [], i = 0; i")]); return (!module.def || strict) ? abortExec : (module.cjs && module.cjs.exports); } // at this point the module is either not executed or fully executed if(!module.executed){ if(!module.def){ return abortExec; } var mid = module.mid, deps = module.deps || [], arg, argResult, args = [], i = 0; if( 0 ){ circleTrace.push(mid); req.trace("loader-exec-module", ["exec", circleTrace.length, mid]); } // for circular dependencies, assume the first module encountered was executed OK // modules that circularly depend on a module that has not run its factory will get // the premade cjs.exports===module.result. They can take a reference to this object and/or // add properties to it. When the module finally runs its factory, the factory can // read/write/replace this object. Notice that so long as the object isn't replaced, any // reference taken earlier while walking the deps list is still valid. module.executed = executing; while(i < deps.length){ arg = deps[i++]; argResult = ((arg === cjsRequireModule) ? createRequire(module) : ((arg === cjsExportsModule) ? module.cjs.exports : ((arg === cjsModuleModule) ? module.cjs : execModule(arg, strict)))); if(argResult === abortExec){ module.executed = 0; req.trace("loader-exec-module", ["abort", mid]); 0 && circleTrace.pop(); return abortExec; } args.push(argResult); } runFactory(module, args); finishExec(module); 0 && circleTrace.pop(); } // at this point the module is guaranteed fully executed return module.result; }, checkCompleteGuard = 0, guardCheckComplete = function(proc){ try{ checkCompleteGuard++; proc(); }finally{ checkCompleteGuard--; } if(execComplete()){ signal("idle", []); } }, checkComplete = function(){ // keep going through the execQ as long as at least one factory is executed // plugins, recursion, cached modules all make for many execution path possibilities if(checkCompleteGuard){ return; } guardCheckComplete(function(){ checkDojoRequirePlugin(); for(var currentDefOrder, module, i = 0; i < execQ.length;){ currentDefOrder = defOrder; module = execQ[i]; execModule(module); if(currentDefOrder!=defOrder){ // defOrder was bumped one or more times indicating something was executed (note, this indicates // the execQ was modified, maybe a lot (for example a later module causes an earlier module to execute) checkDojoRequirePlugin(); i = 0; }else{ // nothing happened; check the next module in the exec queue i++; } } }); }; if( 0 ){ req.undef = function(moduleId, referenceModule){ // In order to reload a module, it must be undefined (this routine) and then re-requested. // This is useful for testing frameworks (at least). var module = getModule(moduleId, referenceModule); setArrived(module); delete modules[module.mid]; }; } if( 1 ){ if(has("dojo-loader-eval-hint-url")===undefined){ has.add("dojo-loader-eval-hint-url", 1); } var fixupUrl= function(url){ url += ""; // make sure url is a Javascript string (some paths may be a Java string) return url + (cacheBust ? ((/\?/.test(url) ? "&" : "?") + cacheBust) : ""); }, injectPlugin = function( module ){ // injects the plugin module given by module; may have to inject the plugin itself var plugin = module.plugin; if(plugin.executed === executed && !plugin.load){ // executed the module not knowing it was a plugin promoteModuleToPlugin(plugin); } var onLoad = function(def){ module.result = def; setArrived(module); finishExec(module); checkComplete(); }; if(plugin.load){ plugin.load(module.prid, module.req, onLoad); }else if(plugin.loadQ){ plugin.loadQ.push(module); }else{ // the unshift instead of push is important: we don't want plugins to execute as // dependencies of some other module because this may cause circles when the plugin // loadQ is run; also, generally, we want plugins to run early since they may load // several other modules and therefore can potentially unblock many modules plugin.loadQ = [module]; execQ.unshift(plugin); injectModule(plugin); } }, // for IE, injecting a module may result in a recursive execution if the module is in the cache cached = 0, injectingModule = 0, injectingCachedModule = 0, evalModuleText = function(text, module){ // see def() for the injectingCachedModule bracket; it simply causes a short, safe curcuit if(has("config-stripStrict")){ text = text.replace(/"use strict"/g, ''); } injectingCachedModule = 1; if(has("config-dojo-loader-catches")){ try{ if(text===cached){ cached.call(null); }else{ req.eval(text, has("dojo-loader-eval-hint-url") ? module.url : module.mid); } }catch(e){ signal(error, makeError("evalModuleThrew", module)); } }else{ if(text===cached){ cached.call(null); }else{ req.eval(text, has("dojo-loader-eval-hint-url") ? module.url : module.mid); } } injectingCachedModule = 0; }, injectModule = function(module){ // Inject the module. In the browser environment, this means appending a script element into // the document; in other environments, it means loading a file. // // If in synchronous mode, then get the module synchronously if it's not xdomainLoading. var mid = module.mid, url = module.url; if(module.executed || module.injected || waiting[mid] || (module.url && ((module.pack && waiting[module.url]===module.pack) || waiting[module.url]==1))){ return; } setRequested(module); if( 0 ){ var viaCombo = 0; if(module.plugin && module.plugin.isCombo){ // a combo plugin; therefore, must be handled by combo service // the prid should have already been converted to a URL (if required by the plugin) during // the normalze process; in any event, there is no way for the loader to know how to // to the conversion; therefore the third argument is zero req.combo.add(module.plugin.mid, module.prid, 0, req); viaCombo = 1; }else if(!module.plugin){ viaCombo = req.combo.add(0, module.mid, module.url, req); } if(viaCombo){ comboPending= 1; return; } } if(module.plugin){ injectPlugin(module); return; } // else a normal module (not a plugin) var onLoadCallback = function(){ runDefQ(module); if(module.injected !== arrived){ // the script that contained the module arrived and has been executed yet // nothing was added to the defQ (so it wasn't an AMD module) and the module // wasn't marked as arrived by dojo.provide (so it wasn't a v1.6- module); // therefore, it must not have been a module; adjust state accordingly setArrived(module); mix(module, nonModuleProps); req.trace("loader-define-nonmodule", [module.url]); } if( 1 && legacyMode){ // must call checkComplete even in for sync loader because we may be in xdomainLoading mode; // but, if xd loading, then don't call checkComplete until out of the current sync traversal // in order to preserve order of execution of the dojo.required modules !syncExecStack.length && checkComplete(); }else{ checkComplete(); } }; cached = cache[mid] || cache[urlKeyPrefix + module.url]; if(cached){ req.trace("loader-inject", ["cache", module.mid, url]); evalModuleText(cached, module); onLoadCallback(); return; } if( 1 && legacyMode){ if(module.isXd){ // switch to async mode temporarily; if current legacyMode!=sync, then is must be one of {legacyAsync, xd, false} legacyMode==sync && (legacyMode = xd); // fall through and load via script injection }else if(module.isAmd && legacyMode!=sync){ // fall through and load via script injection }else{ // mode may be sync, xd/legacyAsync, or async; module may be AMD or legacy; but module is always located on the same domain var xhrCallback = function(text){ if(legacyMode==sync){ // the top of syncExecStack gives the current synchronously executing module; the loader needs // to know this if it has to switch to async loading in the middle of evaluating a legacy module // this happens when a modules dojo.require's a module that must be loaded async because it's xdomain // (using unshift/shift because there is no back() methods for Javascript arrays) syncExecStack.unshift(module); evalModuleText(text, module); syncExecStack.shift(); // maybe the module was an AMD module runDefQ(module); // legacy modules never get to defineModule() => cjs and injected never set; also evaluation implies executing if(!module.cjs){ setArrived(module); finishExec(module); } if(module.finish){ // while synchronously evaluating this module, dojo.require was applied referencing a module // that had to be loaded async; therefore, the loader stopped answering all dojo.require // requests so they could be answered completely in the correct sequence; module.finish gives // the list of dojo.requires that must be re-applied once all target modules are available; // make a synthetic module to execute the dojo.require's in the correct order // compute a guarnateed-unique mid for the synthetic finish module; remember the finish vector; remove it from the reference module // TODO: can we just leave the module.finish...what's it hurting? var finishMid = mid + "*finish", finish = module.finish; delete module.finish; def(finishMid, ["dojo", ("dojo/require!" + finish.join(",")).replace(/\./g, "/")], function(dojo){ forEach(finish, function(mid){ dojo.require(mid); }); }); // unshift, not push, which causes the current traversal to be reattempted from the top execQ.unshift(getModule(finishMid)); } onLoadCallback(); }else{ text = transformToAmd(module, text); if(text){ evalModuleText(text, module); onLoadCallback(); }else{ // if transformToAmd returned falsy, then the module was already AMD and it can be script-injected // do so to improve debugability(even though it means another download...which probably won't happen with a good browser cache) injectingModule = module; req.injectUrl(fixupUrl(url), onLoadCallback, module); injectingModule = 0; } } }; req.trace("loader-inject", ["xhr", module.mid, url, legacyMode!=sync]); if(has("config-dojo-loader-catches")){ try{ req.getText(url, legacyMode!=sync, xhrCallback); }catch(e){ signal(error, makeError("xhrInjectFailed", [module, e])); } }else{ req.getText(url, legacyMode!=sync, xhrCallback); } return; } } // else async mode or fell through in xdomain loading mode; either way, load by script injection req.trace("loader-inject", ["script", module.mid, url]); injectingModule = module; req.injectUrl(fixupUrl(url), onLoadCallback, module); injectingModule = 0; }, defineModule = function(module, deps, def){ req.trace("loader-define-module", [module.mid, deps]); if( 0 && module.plugin && module.plugin.isCombo){ // the module is a plugin resource loaded by the combo service // note: check for module.plugin should be enough since normal plugin resources should // not follow this path; module.plugin.isCombo is future-proofing belt and suspenders module.result = isFunction(def) ? def() : def; setArrived(module); finishExec(module); return module; }; var mid = module.mid; if(module.injected === arrived){ signal(error, makeError("multipleDefine", module)); return module; } mix(module, { deps: deps, def: def, cjs: { id: module.mid, uri: module.url, exports: (module.result = {}), setExports: function(exports){ module.cjs.exports = exports; }, config:function(){ return module.config; } } }); // resolve deps with respect to this module for(var i = 0; i < deps.length; i++){ deps[i] = getModule(deps[i], module); } if( 1 && legacyMode && !waiting[mid]){ // the module showed up without being asked for; it was probably in a // return new NodeList(); // dojo/NodeList }; =====*/ // the query that is returned from this module is slightly different than dojo.query, // because dojo.query has to maintain backwards compatibility with returning a // true array which has performance problems. The query returned from the module // does not use true arrays, but rather inherits from Array, making it much faster to // instantiate. dojo.query = queryForEngine(defaultEngine, function(array){ // call it without the new operator to invoke the back-compat behavior that returns a true array return NodeList(array); // dojo/NodeList }); query.load = function(id, parentRequire, loaded){ // summary: // can be used as AMD plugin to conditionally load new query engine // example: // | require(["dojo/query!custom"], function(qsa){ // | // loaded selector/custom.js as engine // | qsa("#foobar").forEach(...); // | }); loader.load(id, parentRequire, function(engine){ loaded(queryForEngine(engine, NodeList)); }); }; dojo._filterQueryResult = query._filterResult = function(nodes, selector, root){ return new NodeList(query.filter(nodes, selector, root)); }; dojo.NodeList = query.NodeList = NodeList; return query; }); }, 'dojo/has':function(){ define(["require", "module"], function(require, module){ // module: // dojo/has // summary: // Defines the has.js API and several feature tests used by dojo. // description: // This module defines the has API as described by the project has.js with the following additional features: // // - the has test cache is exposed at has.cache. // - the method has.add includes a forth parameter that controls whether or not existing tests are replaced // - the loader's has cache may be optionally copied into this module's has cahce. // // This module adopted from https://github.com/phiggins42/has.js; thanks has.js team! // try to pull the has implementation from the loader; both the dojo loader and bdLoad provide one // if using a foreign loader, then the has cache may be initialized via the config object for this module // WARNING: if a foreign loader defines require.has to be something other than the has.js API, then this implementation fail var has = require.has || function(){}; if(! 1 ){ var isBrowser = // the most fundamental decision: are we in the browser? typeof window != "undefined" && typeof location != "undefined" && typeof document != "undefined" && window.location == location && window.document == document, // has API variables global = this, doc = isBrowser && document, element = doc && doc.createElement("DiV"), cache = (module.config && module.config()) || {}; has = function(name){ // summary: // Return the current value of the named feature. // // name: String|Integer // The name (if a string) or identifier (if an integer) of the feature to test. // // description: // Returns the value of the feature named by name. The feature must have been // previously added to the cache by has.add. return typeof cache[name] == "function" ? (cache[name] = cache[name](global, doc, element)) : cache[name]; // Boolean }; has.cache = cache; has.add = function(name, test, now, force){ // summary: // Register a new feature test for some named feature. // name: String|Integer // The name (if a string) or identifier (if an integer) of the feature to test. // test: Function // A test function to register. If a function, queued for testing until actually // needed. The test function should return a boolean indicating // the presence of a feature or bug. // now: Boolean? // Optional. Omit if `test` is not a function. Provides a way to immediately // run the test and cache the result. // force: Boolean? // Optional. If the test already exists and force is truthy, then the existing // test will be replaced; otherwise, add does not replace an existing test (that // is, by default, the first test advice wins). // example: // A redundant test, testFn with immediate execution: // | has.add("javascript", function(){ return true; }, true); // // example: // Again with the redundantness. You can do this in your tests, but we should // not be doing this in any internal has.js tests // | has.add("javascript", true); // // example: // Three things are passed to the testFunction. `global`, `document`, and a generic element // from which to work your test should the need arise. // | has.add("bug-byid", function(g, d, el){ // | // g == global, typically window, yadda yadda // | // d == document object // | // el == the generic element. a `has` element. // | return false; // fake test, byid-when-form-has-name-matching-an-id is slightly longer // | }); (typeof cache[name]=="undefined" || force) && (cache[name]= test); return now && has(name); }; // since we're operating under a loader that doesn't provide a has API, we must explicitly initialize // has as it would have otherwise been initialized by the dojo loader; use has.add to the builder // can optimize these away iff desired 1 || has.add("host-browser", isBrowser); 1 || has.add("dom", isBrowser); 1 || has.add("dojo-dom-ready-api", 1); 1 || has.add("dojo-sniff", 1); } if( 1 ){ // Common application level tests has.add("dom-addeventlistener", !!document.addEventListener); has.add("touch", "ontouchstart" in document); // I don't know if any of these tests are really correct, just a rough guess has.add("device-width", screen.availWidth || innerWidth); // Tests for DOMNode.attributes[] behavior: // - dom-attributes-explicit - attributes[] only lists explicitly user specified attributes // - dom-attributes-specified-flag (IE8) - need to check attr.specified flag to skip attributes user didn't specify // - Otherwise, in IE6-7. attributes[] will list hundreds of values, so need to do outerHTML to get attrs instead. var form = document.createElement("form"); has.add("dom-attributes-explicit", form.attributes.length == 0); // W3C has.add("dom-attributes-specified-flag", form.attributes.length > 0 && form.attributes.length < 40); // IE8 } has.clearElement = function(element){ // summary: // Deletes the contents of the element passed to test functions. element.innerHTML= ""; return element; }; has.normalize = function(id, toAbsMid){ // summary: // Resolves id into a module id based on possibly-nested tenary expression that branches on has feature test value(s). // // toAbsMid: Function // Resolves a relative module id into an absolute module id var tokens = id.match(/[\?:]|[^:\?]*/g), i = 0, get = function(skip){ var term = tokens[i++]; if(term == ":"){ // empty string module name, resolves to 0 return 0; }else{ // postfixed with a ? means it is a feature to branch on, the term is the name of the feature if(tokens[i++] == "?"){ if(!skip && has(term)){ // matched the feature, get the first value from the options return get(); }else{ // did not match, get the second value, passing over the first get(true); return get(skip); } } // a module return term || 0; } }; id = get(); return id && toAbsMid(id); }; has.load = function(id, parentRequire, loaded){ // summary: // Conditional loading of AMD modules based on a has feature test value. // id: String // Gives the resolved module id to load. // parentRequire: Function // The loader require function with respect to the module that contained the plugin resource in it's // dependency list. // loaded: Function // Callback to loader that consumes result of plugin demand. if(id){ parentRequire([id], loaded); }else{ loaded(); } }; return has; }); }, 'dojo/_base/loader':function(){ define(["./kernel", "../has", "require", "module", "./json", "./lang", "./array"], function(dojo, has, require, thisModule, json, lang, array) { // module: // dojo/_base/loader // This module defines the v1.x synchronous loader API. // signal the loader in sync mode... //>>pure-amd if (! 1 ){ console.error("cannot load the Dojo v1.x loader with a foreign loader"); return 0; } 1 || has.add("dojo-fast-sync-require", 1); var makeErrorToken = function(id){ return {src:thisModule.id, id:id}; }, slashName = function(name){ return name.replace(/\./g, "/"); }, buildDetectRe = /\/\/>>built/, dojoRequireCallbacks = [], dojoRequireModuleStack = [], dojoRequirePlugin = function(mid, require, loaded){ dojoRequireCallbacks.push(loaded); array.forEach(mid.split(","), function(mid){ var module = getModule(mid, require.module); dojoRequireModuleStack.push(module); injectModule(module); }); checkDojoRequirePlugin(); }, checkDojoRequirePlugin = ( 1 ? // This version of checkDojoRequirePlugin makes the observation that all dojoRequireCallbacks can be released // when all *non-dojo/require!, dojo/loadInit!* modules are either executed, not requested, or arrived. This is // the case since there are no more modules the loader is waiting for, therefore, dojo/require! must have // everything it needs on board. // // The potential weakness of this algorithm is that dojo/require will not execute callbacks until *all* dependency // trees are ready. It is possible that some trees may be ready earlier than others, and this extra wait is non-optimal. // Still, for big projects, this seems better than the original algorithm below that proved slow in some cases. // Note, however, the original algorithm had the potential to execute partial trees, but that potential was never enabled. // There are also other optimization available with the original algorithm that have not been explored. function(){ var module, mid; for(mid in modules){ module = modules[mid]; if(module.noReqPluginCheck===undefined){ // tag the module as either a loadInit or require plugin or not for future reference module.noReqPluginCheck = /loadInit\!/.test(mid) || /require\!/.test(mid) ? 1 : 0; } if(!module.executed && !module.noReqPluginCheck && module.injected==requested){ return; } } guardCheckComplete(function(){ var oldCallbacks = dojoRequireCallbacks; dojoRequireCallbacks = []; array.forEach(oldCallbacks, function(cb){cb(1);}); }); } : (function(){ // Note: this is the original checkDojoRequirePlugin that is much slower than the algorithm above. However, we know it // works, so we leave it here in case the algorithm above fails in some corner case. // // checkDojoRequirePlugin inspects all of the modules demanded by a dojo/require! dependency // to see if they have arrived. The loader does not release *any* of these modules to be instantiated // until *all* of these modules are on board, thereby preventing the evaluation of a module with dojo.require's // that reference modules that are not available. // // The algorithm works by traversing the dependency graphs (remember, there can be cycles so they are not trees) // of each module in the dojoRequireModuleStack array (which contains the list of modules demanded by dojo/require!). // The moment a single module is discovered that is missing, the algorithm gives up and indicates that not all // modules are on board. dojo/loadInit! and dojo/require! are ignored because there dependencies are inserted // directly in dojoRequireModuleStack. For example, if "your/module" module depends on "dojo/require!my/module", then // *both* "dojo/require!my/module" and "my/module" will be in dojoRequireModuleStack. Obviously, if "my/module" // is on board, then "dojo/require!my/module" is also satisfied, so the algorithm doesn't check for "dojo/require!my/module". // // Note: inserting a dojo/require! dependency in the dojoRequireModuleStack achieves nothing // with the current algorithm; however, having such modules present makes it possible to optimize the algorithm // // Note: prior versions of this algorithm had an optimization that signaled loaded on dojo/require! dependencies // individually (rather than waiting for them all to be resolved). The implementation proved problematic with cycles // and plugins. However, it is possible to reattach that strategy in the future. // a set from module-id to {undefined | 1 | 0}, where... // undefined => the module has not been inspected // 0 => the module or at least one of its dependencies has not arrived // 1 => the module is a loadInit! or require! plugin resource, or is currently being traversed (therefore, assume // OK until proven otherwise), or has been completely traversed and all dependencies have arrived var touched, traverse = function(m){ touched[m.mid] = 1; for(var t, module, deps = m.deps || [], i= 0; i a built module, always AMD // extractResult==0 => no sync API return 0; } // manufacture a synthetic module id that can never be a real mdule id (just like require does) id = module.mid + "-*loadInit"; // construct the dojo/loadInit names vector which causes any relocated names to be defined as lexical variables under their not-relocated name // the dojo/loadInit plugin assumes the first name in names is "dojo" for(var p in getModule("dojo", module).result.scopeMap){ names.push(p); namesAsStrings.push('"' + p + '"'); } // rewrite the module as a synthetic dojo/loadInit plugin resource + the module expressed as an AMD module that depends on this synthetic resource // don't have to map dojo/init since that will occur when the dependency is resolved return "// xdomain rewrite of " + module.mid + "\n" + "define('" + id + "',{\n" + "\tnames:" + dojo.toJson(names) + ",\n" + "\tdef:function(" + names.join(",") + "){" + extractResult[1] + "}" + "});\n\n" + "define(" + dojo.toJson(names.concat(["dojo/loadInit!"+id])) + ", function(" + names.join(",") + "){\n" + extractResult[0] + "});"; }, loaderVars = require.initSyncLoader(dojoRequirePlugin, checkDojoRequirePlugin, transformToAmd), sync = loaderVars.sync, requested = loaderVars.requested, arrived = loaderVars.arrived, nonmodule = loaderVars.nonmodule, executing = loaderVars.executing, executed = loaderVars.executed, syncExecStack = loaderVars.syncExecStack, modules = loaderVars.modules, execQ = loaderVars.execQ, getModule = loaderVars.getModule, injectModule = loaderVars.injectModule, setArrived = loaderVars.setArrived, signal = loaderVars.signal, finishExec = loaderVars.finishExec, execModule = loaderVars.execModule, getLegacyMode = loaderVars.getLegacyMode, guardCheckComplete = loaderVars.guardCheckComplete; // there is exactly one dojoRequirePlugin among possibly-many dojo/_base/loader's (owing to mapping) dojoRequirePlugin = loaderVars.dojoRequirePlugin; dojo.provide = function(mid){ var executingModule = syncExecStack[0], module = lang.mixin(getModule(slashName(mid), require.module), { executed:executing, result:lang.getObject(mid, true) }); setArrived(module); if(executingModule){ (executingModule.provides || (executingModule.provides = [])).push(function(){ module.result = lang.getObject(mid); delete module.provides; module.executed!==executed && finishExec(module); }); }// else dojo.provide called not consequent to loading; therefore, give up trying to publish module value to loader namespace return module.result; }; has.add("config-publishRequireResult", 1, 0, 0); dojo.require = function(moduleName, omitModuleCheck) { // summary: // loads a Javascript module from the appropriate URI // // moduleName: String // module name to load, using periods for separators, // e.g. "dojo.date.locale". Module paths are de-referenced by dojo's // internal mapping of locations to names and are disambiguated by // longest prefix. See `dojo.registerModulePath()` for details on // registering new modules. // // omitModuleCheck: Boolean? // if `true`, omitModuleCheck skips the step of ensuring that the // loaded file actually defines the symbol it is referenced by. // For example if it called as `dojo.require("a.b.c")` and the // file located at `a/b/c.js` does not define an object `a.b.c`, // and exception will be throws whereas no exception is raised // when called as `dojo.require("a.b.c", true)` // // description: // Modules are loaded via dojo.require by using one of two loaders: the normal loader // and the xdomain loader. The xdomain loader is used when dojo was built with a // custom build that specified loader=xdomain and the module lives on a modulePath // that is a whole URL, with protocol and a domain. The versions of Dojo that are on // the Google and AOL CDNs use the xdomain loader. // // If the module is loaded via the xdomain loader, it is an asynchronous load, since // the module is added via a dynamically created script tag. This // means that dojo.require() can return before the module has loaded. However, this // should only happen in the case where you do dojo.require calls in the top-level // HTML page, or if you purposely avoid the loader checking for dojo.require // dependencies in your module by using a syntax like dojo["require"] to load the module. // // Sometimes it is useful to not have the loader detect the dojo.require calls in the // module so that you can dynamically load the modules as a result of an action on the // page, instead of right at module load time. // // Also, for script blocks in an HTML page, the loader does not pre-process them, so // it does not know to download the modules before the dojo.require calls occur. // // So, in those two cases, when you want on-the-fly module loading or for script blocks // in the HTML page, special care must be taken if the dojo.required code is loaded // asynchronously. To make sure you can execute code that depends on the dojo.required // modules, be sure to add the code that depends on the modules in a dojo.addOnLoad() // callback. dojo.addOnLoad waits for all outstanding modules to finish loading before // executing. // // This type of syntax works with both xdomain and normal loaders, so it is good // practice to always use this idiom for on-the-fly code loading and in HTML script // blocks. If at some point you change loaders and where the code is loaded from, // it will all still work. // // More on how dojo.require // `dojo.require("A.B")` first checks to see if symbol A.B is // defined. If it is, it is simply returned (nothing to do). // // If it is not defined, it will look for `A/B.js` in the script root // directory. // // `dojo.require` throws an exception if it cannot find a file // to load, or if the symbol `A.B` is not defined after loading. // // It returns the object `A.B`, but note the caveats above about on-the-fly loading and // HTML script blocks when the xdomain loader is loading a module. // // `dojo.require()` does nothing about importing symbols into // the current namespace. It is presumed that the caller will // take care of that. // // example: // To use dojo.require in conjunction with dojo.ready: // // | dojo.require("foo"); // | dojo.require("bar"); // | dojo.addOnLoad(function(){ // | //you can now safely do something with foo and bar // | }); // // example: // For example, to import all symbols into a local block, you might write: // // | with (dojo.require("A.B")) { // | ... // | } // // And to import just the leaf symbol to a local variable: // // | var B = dojo.require("A.B"); // | ... // // returns: // the required namespace object function doRequire(mid, omitModuleCheck){ var module = getModule(slashName(mid), require.module); if(syncExecStack.length && syncExecStack[0].finish){ // switched to async loading in the middle of evaluating a legacy module; stop // applying dojo.require so the remaining dojo.requires are applied in order syncExecStack[0].finish.push(mid); return undefined; } // recall module.executed has values {0, executing, executed}; therefore, truthy indicates executing or executed if(module.executed){ return module.result; } omitModuleCheck && (module.result = nonmodule); // rcg...why here and in two lines?? var currentMode = getLegacyMode(); // recall, in sync mode to inject is to *eval* the module text // if the module is a legacy module, this is the same as executing // but if the module is an AMD module, this means defining, not executing injectModule(module); // the inject may have changed the mode currentMode = getLegacyMode(); // in sync mode to dojo.require is to execute if(module.executed!==executed && module.injected===arrived){ // the module was already here before injectModule was called probably finishing up a xdomain // load, but maybe a module given to the loader directly rather than having the loader retrieve it loaderVars.guardCheckComplete(function(){ execModule(module); }); } if(module.executed){ return module.result; } if(currentMode==sync){ // the only way to get here is in sync mode and dojo.required a module that // * was loaded async in the injectModule application a few lines up // * was an AMD module that had deps that are being loaded async and therefore couldn't execute if(module.cjs){ // the module was an AMD module; unshift, not push, which causes the current traversal to be reattempted from the top execQ.unshift(module); }else{ // the module was a legacy module syncExecStack.length && (syncExecStack[0].finish= [mid]); } }else{ // the loader wasn't in sync mode on entry; probably async mode; therefore, no expectation of getting // the module value synchronously; make sure it gets executed though execQ.push(module); } return undefined; } var result = doRequire(moduleName, omitModuleCheck); if(has("config-publishRequireResult") && !lang.exists(moduleName) && result!==undefined){ lang.setObject(moduleName, result); } return result; }; dojo.loadInit = function(f) { f(); }; dojo.registerModulePath = function(/*String*/moduleName, /*String*/prefix){ // summary: // Maps a module name to a path // description: // An unregistered module is given the default path of ../[module], // relative to Dojo root. For example, module acme is mapped to // ../acme. If you want to use a different module name, use // dojo.registerModulePath. // example: // If your dojo.js is located at this location in the web root: // | /myapp/js/dojo/dojo/dojo.js // and your modules are located at: // | /myapp/js/foo/bar.js // | /myapp/js/foo/baz.js // | /myapp/js/foo/thud/xyzzy.js // Your application can tell Dojo to locate the "foo" namespace by calling: // | dojo.registerModulePath("foo", "../../foo"); // At which point you can then use dojo.require() to load the // modules (assuming they provide() the same things which are // required). The full code might be: // | // | var paths = {}; paths[moduleName.replace(/\./g, "/")] = prefix; require({paths:paths}); }; dojo.platformRequire = function(/*Object*/modMap){ // summary: // require one or more modules based on which host environment // Dojo is currently operating in // description: // This method takes a "map" of arrays which one can use to // optionally load dojo modules. The map is indexed by the // possible dojo.name_ values, with two additional values: // "default" and "common". The items in the "default" array will // be loaded if none of the other items have been choosen based on // dojo.name_, set by your host environment. The items in the // "common" array will *always* be loaded, regardless of which // list is chosen. // example: // | dojo.platformRequire({ // | browser: [ // | "foo.sample", // simple module // | "foo.test", // | ["foo.bar.baz", true] // skip object check in _loadModule (dojo.require) // | ], // | default: [ "foo.sample._base" ], // | common: [ "important.module.common" ] // | }); var result = (modMap.common || []).concat(modMap[dojo._name] || modMap["default"] || []), temp; while(result.length){ if(lang.isArray(temp = result.shift())){ dojo.require.apply(dojo, temp); }else{ dojo.require(temp); } } }; dojo.requireIf = dojo.requireAfterIf = function(/*Boolean*/ condition, /*String*/ moduleName, /*Boolean?*/omitModuleCheck){ // summary: // If the condition is true then call `dojo.require()` for the specified // resource // // example: // | dojo.requireIf(dojo.isBrowser, "my.special.Module"); if(condition){ dojo.require(moduleName, omitModuleCheck); } }; dojo.requireLocalization = function(/*String*/moduleName, /*String*/bundleName, /*String?*/locale){ require(["../i18n"], function(i18n){ i18n.getLocalization(moduleName, bundleName, locale); }); }; return { // summary: // This module defines the v1.x synchronous loader API. extractLegacyApiApplications:extractLegacyApiApplications, require:dojoRequirePlugin, loadInit:dojoLoadInitPlugin }; }); }, 'dojo/json':function(){ define(["./has"], function(has){ "use strict"; var hasJSON = typeof JSON != "undefined"; has.add("json-parse", hasJSON); // all the parsers work fine // Firefox 3.5/Gecko 1.9 fails to use replacer in stringify properly https://bugzilla.mozilla.org/show_bug.cgi?id=509184 has.add("json-stringify", hasJSON && JSON.stringify({a:0}, function(k,v){return v||1;}) == '{"a":1}'); if(has("json-stringify")){ return JSON; }else{ var escapeString = function(/*String*/str){ // summary: // Adds escape sequences for non-visual characters, double quote and // backslash and surrounds with double quotes to form a valid string // literal. return ('"' + str.replace(/(["\\])/g, '\\$1') + '"'). replace(/[\f]/g, "\\f").replace(/[\b]/g, "\\b").replace(/[\n]/g, "\\n"). replace(/[\t]/g, "\\t").replace(/[\r]/g, "\\r"); // string }; return { // summary: // Functions to parse and serialize JSON parse: has("json-parse") ? JSON.parse : function(str, strict){ // summary: // Parses a [JSON](http://json.org) string to return a JavaScript object. // description: // This function follows [native JSON API](https://developer.mozilla.org/en/JSON) // Throws for invalid JSON strings. This delegates to eval() if native JSON // support is not available. By default this will evaluate any valid JS expression. // With the strict parameter set to true, the parser will ensure that only // valid JSON strings are parsed (otherwise throwing an error). Without the strict // parameter, the content passed to this method must come // from a trusted source. // str: // a string literal of a JSON item, for instance: // `'{ "foo": [ "bar", 1, { "baz": "thud" } ] }'` // strict: // When set to true, this will ensure that only valid, secure JSON is ever parsed. // Make sure this is set to true for untrusted content. Note that on browsers/engines // without native JSON support, setting this to true will run slower. if(strict && !/^([\s\[\{]*(?:"(?:\\.|[^"])+"|-?\d[\d\.]*(?:[Ee][+-]?\d+)?|null|true|false|)[\s\]\}]*(?:,|:|$))+$/.test(str)){ throw new SyntaxError("Invalid characters in JSON"); } return eval('(' + str + ')'); }, stringify: function(value, replacer, spacer){ // summary: // Returns a [JSON](http://json.org) serialization of an object. // description: // Returns a [JSON](http://json.org) serialization of an object. // This function follows [native JSON API](https://developer.mozilla.org/en/JSON) // Note that this doesn't check for infinite recursion, so don't do that! // value: // A value to be serialized. // replacer: // A replacer function that is called for each value and can return a replacement // spacer: // A spacer string to be used for pretty printing of JSON // example: // simple serialization of a trivial object // | define(["dojo/json"], function(JSON){ // | var jsonStr = JSON.stringify({ howdy: "stranger!", isStrange: true }); // | doh.is('{"howdy":"stranger!","isStrange":true}', jsonStr); var undef; if(typeof replacer == "string"){ spacer = replacer; replacer = null; } function stringify(it, indent, key){ if(replacer){ it = replacer(key, it); } var val, objtype = typeof it; if(objtype == "number"){ return isFinite(it) ? it + "" : "null"; } if(objtype == "boolean"){ return it + ""; } if(it === null){ return "null"; } if(typeof it == "string"){ return escapeString(it); } if(objtype == "function" || objtype == "undefined"){ return undef; // undefined } // short-circuit for objects that support "json" serialization // if they return "self" then just pass-through... if(typeof it.toJSON == "function"){ return stringify(it.toJSON(key), indent, key); } if(it instanceof Date){ return '"{FullYear}-{Month+}-{Date}T{Hours}:{Minutes}:{Seconds}Z"'.replace(/\{(\w+)(\+)?\}/g, function(t, prop, plus){ var num = it["getUTC" + prop]() + (plus ? 1 : 0); return num < 10 ? "0" + num : num; }); } if(it.valueOf() !== it){ // primitive wrapper, try again unwrapped: return stringify(it.valueOf(), indent, key); } var nextIndent= spacer ? (indent + spacer) : ""; /* we used to test for DOM nodes and throw, but FF serializes them as {}, so cross-browser consistency is probably not efficiently attainable */ var sep = spacer ? " " : ""; var newLine = spacer ? "\n" : ""; // array if(it instanceof Array){ var itl = it.length, res = []; for(key = 0; key < itl; key++){ var obj = it[key]; val = stringify(obj, nextIndent, key); if(typeof val != "string"){ val = "null"; } res.push(newLine + nextIndent + val); } return "[" + res.join(",") + newLine + indent + "]"; } // generic object code path var output = []; for(key in it){ var keyStr; if(it.hasOwnProperty(key)){ if(typeof key == "number"){ keyStr = '"' + key + '"'; }else if(typeof key == "string"){ keyStr = escapeString(key); }else{ // skip non-string or number keys continue; } val = stringify(it[key], nextIndent, key); if(typeof val != "string"){ // skip non-serializable values continue; } // At this point, the most non-IE browsers don't get in this branch // (they have native JSON), so push is definitely the way to output.push(newLine + nextIndent + keyStr + ":" + sep + val); } } return "{" + output.join(",") + newLine + indent + "}"; // String } return stringify(value, "", ""); } }; } }); }, 'dojo/_base/declare':function(){ define(["./kernel", "../has", "./lang"], function(dojo, has, lang){ // module: // dojo/_base/declare var mix = lang.mixin, op = Object.prototype, opts = op.toString, xtor = new Function, counter = 0, cname = "constructor"; function err(msg, cls){ throw new Error("declare" + (cls ? " " + cls : "") + ": " + msg); } // C3 Method Resolution Order (see http://www.python.org/download/releases/2.3/mro/) function c3mro(bases, className){ var result = [], roots = [{cls: 0, refs: []}], nameMap = {}, clsCount = 1, l = bases.length, i = 0, j, lin, base, top, proto, rec, name, refs; // build a list of bases naming them if needed for(; i < l; ++i){ base = bases[i]; if(!base){ err("mixin #" + i + " is unknown. Did you use dojo.require to pull it in?", className); }else if(opts.call(base) != "[object Function]"){ err("mixin #" + i + " is not a callable constructor.", className); } lin = base._meta ? base._meta.bases : [base]; top = 0; // add bases to the name map for(j = lin.length - 1; j >= 0; --j){ proto = lin[j].prototype; if(!proto.hasOwnProperty("declaredClass")){ proto.declaredClass = "uniqName_" + (counter++); } name = proto.declaredClass; if(!nameMap.hasOwnProperty(name)){ nameMap[name] = {count: 0, refs: [], cls: lin[j]}; ++clsCount; } rec = nameMap[name]; if(top && top !== rec){ rec.refs.push(top); ++top.count; } top = rec; } ++top.count; roots[0].refs.push(top); } // remove classes without external references recursively while(roots.length){ top = roots.pop(); result.push(top.cls); --clsCount; // optimization: follow a single-linked chain while(refs = top.refs, refs.length == 1){ top = refs[0]; if(!top || --top.count){ // branch or end of chain => do not end to roots top = 0; break; } result.push(top.cls); --clsCount; } if(top){ // branch for(i = 0, l = refs.length; i < l; ++i){ top = refs[i]; if(!--top.count){ roots.push(top); } } } } if(clsCount){ err("can't build consistent linearization", className); } // calculate the superclass offset base = bases[0]; result[0] = base ? base._meta && base === result[result.length - base._meta.bases.length] ? base._meta.bases.length : 1 : 0; return result; } function inherited(args, a, f){ var name, chains, bases, caller, meta, base, proto, opf, pos, cache = this._inherited = this._inherited || {}; // crack arguments if(typeof args == "string"){ name = args; args = a; a = f; } f = 0; caller = args.callee; name = name || caller.nom; if(!name){ err("can't deduce a name to call inherited()", this.declaredClass); } meta = this.constructor._meta; bases = meta.bases; pos = cache.p; if(name != cname){ // method if(cache.c !== caller){ // cache bust pos = 0; base = bases[0]; meta = base._meta; if(meta.hidden[name] !== caller){ // error detection chains = meta.chains; if(chains && typeof chains[name] == "string"){ err("calling chained method with inherited: " + name, this.declaredClass); } // find caller do{ meta = base._meta; proto = base.prototype; if(meta && (proto[name] === caller && proto.hasOwnProperty(name) || meta.hidden[name] === caller)){ break; } }while(base = bases[++pos]); // intentional assignment pos = base ? pos : -1; } } // find next base = bases[++pos]; if(base){ proto = base.prototype; if(base._meta && proto.hasOwnProperty(name)){ f = proto[name]; }else{ opf = op[name]; do{ proto = base.prototype; f = proto[name]; if(f && (base._meta ? proto.hasOwnProperty(name) : f !== opf)){ break; } }while(base = bases[++pos]); // intentional assignment } } f = base && f || op[name]; }else{ // constructor if(cache.c !== caller){ // cache bust pos = 0; meta = bases[0]._meta; if(meta && meta.ctor !== caller){ // error detection chains = meta.chains; if(!chains || chains.constructor !== "manual"){ err("calling chained constructor with inherited", this.declaredClass); } // find caller while(base = bases[++pos]){ // intentional assignment meta = base._meta; if(meta && meta.ctor === caller){ break; } } pos = base ? pos : -1; } } // find next while(base = bases[++pos]){ // intentional assignment meta = base._meta; f = meta ? meta.ctor : base; if(f){ break; } } f = base && f; } // cache the found super method cache.c = f; cache.p = pos; // now we have the result if(f){ return a === true ? f : f.apply(this, a || args); } // intentionally no return if a super method was not found } function getInherited(name, args){ if(typeof name == "string"){ return this.__inherited(name, args, true); } return this.__inherited(name, true); } function inherited__debug(args, a1, a2){ var f = this.getInherited(args, a1); if(f){ return f.apply(this, a2 || a1 || args); } // intentionally no return if a super method was not found } var inheritedImpl = dojo.config.isDebug ? inherited__debug : inherited; // emulation of "instanceof" function isInstanceOf(cls){ var bases = this.constructor._meta.bases; for(var i = 0, l = bases.length; i < l; ++i){ if(bases[i] === cls){ return true; } } return this instanceof cls; } function mixOwn(target, source){ // add props adding metadata for incoming functions skipping a constructor for(var name in source){ if(name != cname && source.hasOwnProperty(name)){ target[name] = source[name]; } } if(has("bug-for-in-skips-shadowed")){ for(var extraNames= lang._extraNames, i= extraNames.length; i;){ name = extraNames[--i]; if(name != cname && source.hasOwnProperty(name)){ target[name] = source[name]; } } } } // implementation of safe mixin function function safeMixin(target, source){ // summary: // Mix in properties skipping a constructor and decorating functions // like it is done by declare(). // target: Object // Target object to accept new properties. // source: Object // Source object for new properties. // description: // This function is used to mix in properties like lang.mixin does, // but it skips a constructor property and decorates functions like // declare() does. // // It is meant to be used with classes and objects produced with // declare. Functions mixed in with dojo.safeMixin can use // this.inherited() like normal methods. // // This function is used to implement extend() method of a constructor // produced with declare(). // // example: // | var A = declare(null, { // | m1: function(){ // | console.log("A.m1"); // | }, // | m2: function(){ // | console.log("A.m2"); // | } // | }); // | var B = declare(A, { // | m1: function(){ // | this.inherited(arguments); // | console.log("B.m1"); // | } // | }); // | B.extend({ // | m2: function(){ // | this.inherited(arguments); // | console.log("B.m2"); // | } // | }); // | var x = new B(); // | dojo.safeMixin(x, { // | m1: function(){ // | this.inherited(arguments); // | console.log("X.m1"); // | }, // | m2: function(){ // | this.inherited(arguments); // | console.log("X.m2"); // | } // | }); // | x.m2(); // | // prints: // | // A.m1 // | // B.m1 // | // X.m1 var name, t; // add props adding metadata for incoming functions skipping a constructor for(name in source){ t = source[name]; if((t !== op[name] || !(name in op)) && name != cname){ if(opts.call(t) == "[object Function]"){ // non-trivial function method => attach its name t.nom = name; } target[name] = t; } } if(has("bug-for-in-skips-shadowed")){ for(var extraNames= lang._extraNames, i= extraNames.length; i;){ name = extraNames[--i]; t = source[name]; if((t !== op[name] || !(name in op)) && name != cname){ if(opts.call(t) == "[object Function]"){ // non-trivial function method => attach its name t.nom = name; } target[name] = t; } } } return target; } function extend(source){ declare.safeMixin(this.prototype, source); return this; } function createSubclass(mixins){ return declare([this].concat(mixins)); } // chained constructor compatible with the legacy declare() function chainedConstructor(bases, ctorSpecial){ return function(){ var a = arguments, args = a, a0 = a[0], f, i, m, l = bases.length, preArgs; if(!(this instanceof a.callee)){ // not called via new, so force it return applyNew(a); } //this._inherited = {}; // perform the shaman's rituals of the original declare() // 1) call two types of the preamble if(ctorSpecial && (a0 && a0.preamble || this.preamble)){ // full blown ritual preArgs = new Array(bases.length); // prepare parameters preArgs[0] = a; for(i = 0;;){ // process the preamble of the 1st argument a0 = a[0]; if(a0){ f = a0.preamble; if(f){ a = f.apply(this, a) || a; } } // process the preamble of this class f = bases[i].prototype; f = f.hasOwnProperty("preamble") && f.preamble; if(f){ a = f.apply(this, a) || a; } // one peculiarity of the preamble: // it is called if it is not needed, // e.g., there is no constructor to call // let's watch for the last constructor // (see ticket #9795) if(++i == l){ break; } preArgs[i] = a; } } // 2) call all non-trivial constructors using prepared arguments for(i = l - 1; i >= 0; --i){ f = bases[i]; m = f._meta; f = m ? m.ctor : f; if(f){ f.apply(this, preArgs ? preArgs[i] : a); } } // 3) continue the original ritual: call the postscript f = this.postscript; if(f){ f.apply(this, args); } }; } // chained constructor compatible with the legacy declare() function singleConstructor(ctor, ctorSpecial){ return function(){ var a = arguments, t = a, a0 = a[0], f; if(!(this instanceof a.callee)){ // not called via new, so force it return applyNew(a); } //this._inherited = {}; // perform the shaman's rituals of the original declare() // 1) call two types of the preamble if(ctorSpecial){ // full blown ritual if(a0){ // process the preamble of the 1st argument f = a0.preamble; if(f){ t = f.apply(this, t) || t; } } f = this.preamble; if(f){ // process the preamble of this class f.apply(this, t); // one peculiarity of the preamble: // it is called even if it is not needed, // e.g., there is no constructor to call // let's watch for the last constructor // (see ticket #9795) } } // 2) call a constructor if(ctor){ ctor.apply(this, a); } // 3) continue the original ritual: call the postscript f = this.postscript; if(f){ f.apply(this, a); } }; } // plain vanilla constructor (can use inherited() to call its base constructor) function simpleConstructor(bases){ return function(){ var a = arguments, i = 0, f, m; if(!(this instanceof a.callee)){ // not called via new, so force it return applyNew(a); } //this._inherited = {}; // perform the shaman's rituals of the original declare() // 1) do not call the preamble // 2) call the top constructor (it can use this.inherited()) for(; f = bases[i]; ++i){ // intentional assignment m = f._meta; f = m ? m.ctor : f; if(f){ f.apply(this, a); break; } } // 3) call the postscript f = this.postscript; if(f){ f.apply(this, a); } }; } function chain(name, bases, reversed){ return function(){ var b, m, f, i = 0, step = 1; if(reversed){ i = bases.length - 1; step = -1; } for(; b = bases[i]; i += step){ // intentional assignment m = b._meta; f = (m ? m.hidden : b.prototype)[name]; if(f){ f.apply(this, arguments); } } }; } // forceNew(ctor) // return a new object that inherits from ctor.prototype but // without actually running ctor on the object. function forceNew(ctor){ // create object with correct prototype using a do-nothing // constructor xtor.prototype = ctor.prototype; var t = new xtor; xtor.prototype = null; // clean up return t; } // applyNew(args) // just like 'new ctor()' except that the constructor and its arguments come // from args, which must be an array or an arguments object function applyNew(args){ // create an object with ctor's prototype but without // calling ctor on it. var ctor = args.callee, t = forceNew(ctor); // execute the real constructor on the new object ctor.apply(t, args); return t; } function declare(className, superclass, props){ // summary: // Create a feature-rich constructor from compact notation. // className: String? // The optional name of the constructor (loosely, a "class") // stored in the "declaredClass" property in the created prototype. // It will be used as a global name for a created constructor. // superclass: Function|Function[] // May be null, a Function, or an Array of Functions. This argument // specifies a list of bases (the left-most one is the most deepest // base). // props: Object // An object whose properties are copied to the created prototype. // Add an instance-initialization function by making it a property // named "constructor". // returns: dojo/_base/declare.__DeclareCreatedObject // New constructor function. // description: // Create a constructor using a compact notation for inheritance and // prototype extension. // // Mixin ancestors provide a type of multiple inheritance. // Prototypes of mixin ancestors are copied to the new class: // changes to mixin prototypes will not affect classes to which // they have been mixed in. // // Ancestors can be compound classes created by this version of // declare(). In complex cases all base classes are going to be // linearized according to C3 MRO algorithm // (see http://www.python.org/download/releases/2.3/mro/ for more // details). // // "className" is cached in "declaredClass" property of the new class, // if it was supplied. The immediate super class will be cached in // "superclass" property of the new class. // // Methods in "props" will be copied and modified: "nom" property // (the declared name of the method) will be added to all copied // functions to help identify them for the internal machinery. Be // very careful, while reusing methods: if you use the same // function under different names, it can produce errors in some // cases. // // It is possible to use constructors created "manually" (without // declare()) as bases. They will be called as usual during the // creation of an instance, their methods will be chained, and even // called by "this.inherited()". // // Special property "-chains-" governs how to chain methods. It is // a dictionary, which uses method names as keys, and hint strings // as values. If a hint string is "after", this method will be // called after methods of its base classes. If a hint string is // "before", this method will be called before methods of its base // classes. // // If "constructor" is not mentioned in "-chains-" property, it will // be chained using the legacy mode: using "after" chaining, // calling preamble() method before each constructor, if available, // and calling postscript() after all constructors were executed. // If the hint is "after", it is chained as a regular method, but // postscript() will be called after the chain of constructors. // "constructor" cannot be chained "before", but it allows // a special hint string: "manual", which means that constructors // are not going to be chained in any way, and programmer will call // them manually using this.inherited(). In the latter case // postscript() will be called after the construction. // // All chaining hints are "inherited" from base classes and // potentially can be overridden. Be very careful when overriding // hints! Make sure that all chained methods can work in a proposed // manner of chaining. // // Once a method was chained, it is impossible to unchain it. The // only exception is "constructor". You don't need to define a // method in order to supply a chaining hint. // // If a method is chained, it cannot use this.inherited() because // all other methods in the hierarchy will be called automatically. // // Usually constructors and initializers of any kind are chained // using "after" and destructors of any kind are chained as // "before". Note that chaining assumes that chained methods do not // return any value: any returned value will be discarded. // // example: // | declare("my.classes.bar", my.classes.foo, { // | // properties to be added to the class prototype // | someValue: 2, // | // initialization function // | constructor: function(){ // | this.myComplicatedObject = new ReallyComplicatedObject(); // | }, // | // other functions // | someMethod: function(){ // | doStuff(); // | } // | }); // // example: // | var MyBase = declare(null, { // | // constructor, properties, and methods go here // | // ... // | }); // | var MyClass1 = declare(MyBase, { // | // constructor, properties, and methods go here // | // ... // | }); // | var MyClass2 = declare(MyBase, { // | // constructor, properties, and methods go here // | // ... // | }); // | var MyDiamond = declare([MyClass1, MyClass2], { // | // constructor, properties, and methods go here // | // ... // | }); // // example: // | var F = function(){ console.log("raw constructor"); }; // | F.prototype.method = function(){ // | console.log("raw method"); // | }; // | var A = declare(F, { // | constructor: function(){ // | console.log("A.constructor"); // | }, // | method: function(){ // | console.log("before calling F.method..."); // | this.inherited(arguments); // | console.log("...back in A"); // | } // | }); // | new A().method(); // | // will print: // | // raw constructor // | // A.constructor // | // before calling F.method... // | // raw method // | // ...back in A // // example: // | var A = declare(null, { // | "-chains-": { // | destroy: "before" // | } // | }); // | var B = declare(A, { // | constructor: function(){ // | console.log("B.constructor"); // | }, // | destroy: function(){ // | console.log("B.destroy"); // | } // | }); // | var C = declare(B, { // | constructor: function(){ // | console.log("C.constructor"); // | }, // | destroy: function(){ // | console.log("C.destroy"); // | } // | }); // | new C().destroy(); // | // prints: // | // B.constructor // | // C.constructor // | // C.destroy // | // B.destroy // // example: // | var A = declare(null, { // | "-chains-": { // | constructor: "manual" // | } // | }); // | var B = declare(A, { // | constructor: function(){ // | // ... // | // call the base constructor with new parameters // | this.inherited(arguments, [1, 2, 3]); // | // ... // | } // | }); // // example: // | var A = declare(null, { // | "-chains-": { // | m1: "before" // | }, // | m1: function(){ // | console.log("A.m1"); // | }, // | m2: function(){ // | console.log("A.m2"); // | } // | }); // | var B = declare(A, { // | "-chains-": { // | m2: "after" // | }, // | m1: function(){ // | console.log("B.m1"); // | }, // | m2: function(){ // | console.log("B.m2"); // | } // | }); // | var x = new B(); // | x.m1(); // | // prints: // | // B.m1 // | // A.m1 // | x.m2(); // | // prints: // | // A.m2 // | // B.m2 // crack parameters if(typeof className != "string"){ props = superclass; superclass = className; className = ""; } props = props || {}; var proto, i, t, ctor, name, bases, chains, mixins = 1, parents = superclass; // build a prototype if(opts.call(superclass) == "[object Array]"){ // C3 MRO bases = c3mro(superclass, className); t = bases[0]; mixins = bases.length - t; superclass = bases[mixins]; }else{ bases = [0]; if(superclass){ if(opts.call(superclass) == "[object Function]"){ t = superclass._meta; bases = bases.concat(t ? t.bases : superclass); }else{ err("base class is not a callable constructor.", className); } }else if(superclass !== null){ err("unknown base class. Did you use dojo.require to pull it in?", className); } } if(superclass){ for(i = mixins - 1;; --i){ proto = forceNew(superclass); if(!i){ // stop if nothing to add (the last base) break; } // mix in properties t = bases[i]; (t._meta ? mixOwn : mix)(proto, t.prototype); // chain in new constructor ctor = new Function; ctor.superclass = superclass; ctor.prototype = proto; superclass = proto.constructor = ctor; } }else{ proto = {}; } // add all properties declare.safeMixin(proto, props); // add constructor t = props.constructor; if(t !== op.constructor){ t.nom = cname; proto.constructor = t; } // collect chains and flags for(i = mixins - 1; i; --i){ // intentional assignment t = bases[i]._meta; if(t && t.chains){ chains = mix(chains || {}, t.chains); } } if(proto["-chains-"]){ chains = mix(chains || {}, proto["-chains-"]); } // build ctor t = !chains || !chains.hasOwnProperty(cname); bases[0] = ctor = (chains && chains.constructor === "manual") ? simpleConstructor(bases) : (bases.length == 1 ? singleConstructor(props.constructor, t) : chainedConstructor(bases, t)); // add meta information to the constructor ctor._meta = {bases: bases, hidden: props, chains: chains, parents: parents, ctor: props.constructor}; ctor.superclass = superclass && superclass.prototype; ctor.extend = extend; ctor.createSubclass = createSubclass; ctor.prototype = proto; proto.constructor = ctor; // add "standard" methods to the prototype proto.getInherited = getInherited; proto.isInstanceOf = isInstanceOf; proto.inherited = inheritedImpl; proto.__inherited = inherited; // add name if specified if(className){ proto.declaredClass = className; lang.setObject(className, ctor); } // build chains and add them to the prototype if(chains){ for(name in chains){ if(proto[name] && typeof chains[name] == "string" && name != cname){ t = proto[name] = chain(name, bases, chains[name] === "after"); t.nom = name; } } } // chained methods do not return values // no need to chain "invisible" functions return ctor; // Function } /*===== declare.__DeclareCreatedObject = { // summary: // dojo/_base/declare() returns a constructor `C`. `new C()` returns an Object with the following // methods, in addition to the methods and properties specified via the arguments passed to declare(). inherited: function(name, args, newArgs){ // summary: // Calls a super method. // name: String? // The optional method name. Should be the same as the caller's // name. Usually "name" is specified in complex dynamic cases, when // the calling method was dynamically added, undecorated by // declare(), and it cannot be determined. // args: Arguments // The caller supply this argument, which should be the original // "arguments". // newArgs: Object? // If "true", the found function will be returned without // executing it. // If Array, it will be used to call a super method. Otherwise // "args" will be used. // returns: // Whatever is returned by a super method, or a super method itself, // if "true" was specified as newArgs. // description: // This method is used inside method of classes produced with // declare() to call a super method (next in the chain). It is // used for manually controlled chaining. Consider using the regular // chaining, because it is faster. Use "this.inherited()" only in // complex cases. // // This method cannot me called from automatically chained // constructors including the case of a special (legacy) // constructor chaining. It cannot be called from chained methods. // // If "this.inherited()" cannot find the next-in-chain method, it // does nothing and returns "undefined". The last method in chain // can be a default method implemented in Object, which will be // called last. // // If "name" is specified, it is assumed that the method that // received "args" is the parent method for this call. It is looked // up in the chain list and if it is found the next-in-chain method // is called. If it is not found, the first-in-chain method is // called. // // If "name" is not specified, it will be derived from the calling // method (using a methoid property "nom"). // // example: // | var B = declare(A, { // | method1: function(a, b, c){ // | this.inherited(arguments); // | }, // | method2: function(a, b){ // | return this.inherited(arguments, [a + b]); // | } // | }); // | // next method is not in the chain list because it is added // | // manually after the class was created. // | B.prototype.method3 = function(){ // | console.log("This is a dynamically-added method."); // | this.inherited("method3", arguments); // | }; // example: // | var B = declare(A, { // | method: function(a, b){ // | var super = this.inherited(arguments, true); // | // ... // | if(!super){ // | console.log("there is no super method"); // | return 0; // | } // | return super.apply(this, arguments); // | } // | }); return {}; // Object }, getInherited: function(name, args){ // summary: // Returns a super method. // name: String? // The optional method name. Should be the same as the caller's // name. Usually "name" is specified in complex dynamic cases, when // the calling method was dynamically added, undecorated by // declare(), and it cannot be determined. // args: Arguments // The caller supply this argument, which should be the original // "arguments". // returns: // Returns a super method (Function) or "undefined". // description: // This method is a convenience method for "this.inherited()". // It uses the same algorithm but instead of executing a super // method, it returns it, or "undefined" if not found. // // example: // | var B = declare(A, { // | method: function(a, b){ // | var super = this.getInherited(arguments); // | // ... // | if(!super){ // | console.log("there is no super method"); // | return 0; // | } // | return super.apply(this, arguments); // | } // | }); return {}; // Object }, isInstanceOf: function(cls){ // summary: // Checks the inheritance chain to see if it is inherited from this // class. // cls: Function // Class constructor. // returns: // "true", if this object is inherited from this class, "false" // otherwise. // description: // This method is used with instances of classes produced with // declare() to determine of they support a certain interface or // not. It models "instanceof" operator. // // example: // | var A = declare(null, { // | // constructor, properties, and methods go here // | // ... // | }); // | var B = declare(null, { // | // constructor, properties, and methods go here // | // ... // | }); // | var C = declare([A, B], { // | // constructor, properties, and methods go here // | // ... // | }); // | var D = declare(A, { // | // constructor, properties, and methods go here // | // ... // | }); // | // | var a = new A(), b = new B(), c = new C(), d = new D(); // | // | console.log(a.isInstanceOf(A)); // true // | console.log(b.isInstanceOf(A)); // false // | console.log(c.isInstanceOf(A)); // true // | console.log(d.isInstanceOf(A)); // true // | // | console.log(a.isInstanceOf(B)); // false // | console.log(b.isInstanceOf(B)); // true // | console.log(c.isInstanceOf(B)); // true // | console.log(d.isInstanceOf(B)); // false // | // | console.log(a.isInstanceOf(C)); // false // | console.log(b.isInstanceOf(C)); // false // | console.log(c.isInstanceOf(C)); // true // | console.log(d.isInstanceOf(C)); // false // | // | console.log(a.isInstanceOf(D)); // false // | console.log(b.isInstanceOf(D)); // false // | console.log(c.isInstanceOf(D)); // false // | console.log(d.isInstanceOf(D)); // true return {}; // Object }, extend: function(source){ // summary: // Adds all properties and methods of source to constructor's // prototype, making them available to all instances created with // constructor. This method is specific to constructors created with // declare(). // source: Object // Source object which properties are going to be copied to the // constructor's prototype. // description: // Adds source properties to the constructor's prototype. It can // override existing properties. // // This method is similar to dojo.extend function, but it is specific // to constructors produced by declare(). It is implemented // using dojo.safeMixin, and it skips a constructor property, // and properly decorates copied functions. // // example: // | var A = declare(null, { // | m1: function(){}, // | s1: "Popokatepetl" // | }); // | A.extend({ // | m1: function(){}, // | m2: function(){}, // | f1: true, // | d1: 42 // | }); } }; =====*/ // For back-compat, remove for 2.0 dojo.safeMixin = declare.safeMixin = safeMixin; dojo.declare = declare; return declare; }); }, 'dojo/dom':function(){ define(["./sniff", "./_base/lang", "./_base/window"], function(has, lang, win){ // module: // dojo/dom // FIXME: need to add unit tests for all the semi-public methods if(has("ie") <= 7){ try{ document.execCommand("BackgroundImageCache", false, true); }catch(e){ // sane browsers don't have cache "issues" } } // ============================= // DOM Functions // ============================= // the result object var dom = { // summary: // This module defines the core dojo DOM API. }; if(has("ie")){ dom.byId = function(id, doc){ if(typeof id != "string"){ return id; } var _d = doc || win.doc, te = id && _d.getElementById(id); // attributes.id.value is better than just id in case the // user has a name=id inside a form if(te && (te.attributes.id.value == id || te.id == id)){ return te; }else{ var eles = _d.all[id]; if(!eles || eles.nodeName){ eles = [eles]; } // if more than 1, choose first with the correct id var i = 0; while((te = eles[i++])){ if((te.attributes && te.attributes.id && te.attributes.id.value == id) || te.id == id){ return te; } } } }; }else{ dom.byId = function(id, doc){ // inline'd type check. // be sure to return null per documentation, to match IE branch. return ((typeof id == "string") ? (doc || win.doc).getElementById(id) : id) || null; // DOMNode }; } /*===== dom.byId = function(id, doc){ // summary: // Returns DOM node with matching `id` attribute or falsy value (ex: null or undefined) // if not found. If `id` is a DomNode, this function is a no-op. // // id: String|DOMNode // A string to match an HTML id attribute or a reference to a DOM Node // // doc: Document? // Document to work in. Defaults to the current value of // dojo.doc. Can be used to retrieve // node references from other documents. // // example: // Look up a node by ID: // | var n = dojo.byId("foo"); // // example: // Check if a node exists, and use it. // | var n = dojo.byId("bar"); // | if(n){ doStuff() ... } // // example: // Allow string or DomNode references to be passed to a custom function: // | var foo = function(nodeOrId){ // | nodeOrId = dojo.byId(nodeOrId); // | // ... more stuff // | } }; =====*/ dom.isDescendant = function(/*DOMNode|String*/ node, /*DOMNode|String*/ ancestor){ // summary: // Returns true if node is a descendant of ancestor // node: DOMNode|String // string id or node reference to test // ancestor: DOMNode|String // string id or node reference of potential parent to test against // // example: // Test is node id="bar" is a descendant of node id="foo" // | if(dojo.isDescendant("bar", "foo")){ ... } try{ node = dom.byId(node); ancestor = dom.byId(ancestor); while(node){ if(node == ancestor){ return true; // Boolean } node = node.parentNode; } }catch(e){ /* squelch, return false */ } return false; // Boolean }; // TODO: do we need this function in the base? dom.setSelectable = function(/*DOMNode|String*/ node, /*Boolean*/ selectable){ // summary: // Enable or disable selection on a node // node: DOMNode|String // id or reference to node // selectable: Boolean // state to put the node in. false indicates unselectable, true // allows selection. // example: // Make the node id="bar" unselectable // | dojo.setSelectable("bar"); // example: // Make the node id="bar" selectable // | dojo.setSelectable("bar", true); node = dom.byId(node); if(has("mozilla")){ node.style.MozUserSelect = selectable ? "" : "none"; }else if(has("khtml") || has("webkit")){ node.style.KhtmlUserSelect = selectable ? "auto" : "none"; }else if(has("ie")){ var v = (node.unselectable = selectable ? "" : "on"), cs = node.getElementsByTagName("*"), i = 0, l = cs.length; for(; i < l; ++i){ cs.item(i).unselectable = v; } } //FIXME: else? Opera? }; return dom; }); }, 'dojo/_base/browser':function(){ if(require.has){ require.has.add("config-selectorEngine", "acme"); } define([ "../ready", "./kernel", "./connect", // until we decide if connect is going back into non-browser environments "./unload", "./window", "./event", "./html", "./NodeList", "../query", "./xhr", "./fx"], function(dojo){ // module: // dojo/_base/browser /*===== return { // summary: // This module causes the browser-only base modules to be loaded. }; =====*/ return dojo; }); }, 'dojo/selector/acme':function(){ define([ "../dom", "../sniff", "../_base/array", "../_base/lang", "../_base/window" ], function(dom, has, array, lang, win){ // module: // dojo/selector/acme /* acme architectural overview: acme is a relatively full-featured CSS3 query library. It is designed to take any valid CSS3 selector and return the nodes matching the selector. To do this quickly, it processes queries in several steps, applying caching where profitable. The steps (roughly in reverse order of the way they appear in the code): 1.) check to see if we already have a "query dispatcher" - if so, use that with the given parameterization. Skip to step 4. 2.) attempt to determine which branch to dispatch the query to: - JS (optimized DOM iteration) - native (FF3.1+, Safari 3.1+, IE 8+) 3.) tokenize and convert to executable "query dispatcher" - this is where the lion's share of the complexity in the system lies. In the DOM version, the query dispatcher is assembled as a chain of "yes/no" test functions pertaining to a section of a simple query statement (".blah:nth-child(odd)" but not "div div", which is 2 simple statements). Individual statement dispatchers are cached (to prevent re-definition) as are entire dispatch chains (to make re-execution of the same query fast) 4.) the resulting query dispatcher is called in the passed scope (by default the top-level document) - for DOM queries, this results in a recursive, top-down evaluation of nodes based on each simple query section - for native implementations, this may mean working around spec bugs. So be it. 5.) matched nodes are pruned to ensure they are unique (if necessary) */ //////////////////////////////////////////////////////////////////////// // Toolkit aliases //////////////////////////////////////////////////////////////////////// // if you are extracting acme for use in your own system, you will // need to provide these methods and properties. No other porting should be // necessary, save for configuring the system to use a class other than // dojo/NodeList as the return instance instantiator var trim = lang.trim; var each = array.forEach; var getDoc = function(){ return win.doc; }; // NOTE(alex): the spec is idiotic. CSS queries should ALWAYS be case-sensitive, but nooooooo var cssCaseBug = (getDoc().compatMode) == "BackCompat"; //////////////////////////////////////////////////////////////////////// // Global utilities //////////////////////////////////////////////////////////////////////// var specials = ">~+"; // global thunk to determine whether we should treat the current query as // case sensitive or not. This switch is flipped by the query evaluator // based on the document passed as the context to search. var caseSensitive = false; // how high? var yesman = function(){ return true; }; //////////////////////////////////////////////////////////////////////// // Tokenizer //////////////////////////////////////////////////////////////////////// var getQueryParts = function(query){ // summary: // state machine for query tokenization // description: // instead of using a brittle and slow regex-based CSS parser, // acme implements an AST-style query representation. This // representation is only generated once per query. For example, // the same query run multiple times or under different root nodes // does not re-parse the selector expression but instead uses the // cached data structure. The state machine implemented here // terminates on the last " " (space) character and returns an // ordered array of query component structures (or "parts"). Each // part represents an operator or a simple CSS filtering // expression. The structure for parts is documented in the code // below. // NOTE: // this code is designed to run fast and compress well. Sacrifices // to readability and maintainability have been made. Your best // bet when hacking the tokenizer is to put The Donnas on *really* // loud (may we recommend their "Spend The Night" release?) and // just assume you're gonna make mistakes. Keep the unit tests // open and run them frequently. Knowing is half the battle ;-) if(specials.indexOf(query.slice(-1)) >= 0){ // if we end with a ">", "+", or "~", that means we're implicitly // searching all children, so make it explicit query += " * "; }else{ // if you have not provided a terminator, one will be provided for // you... query += " "; } var ts = function(/*Integer*/ s, /*Integer*/ e){ // trim and slice. // take an index to start a string slice from and an end position // and return a trimmed copy of that sub-string return trim(query.slice(s, e)); }; // the overall data graph of the full query, as represented by queryPart objects var queryParts = []; // state keeping vars var inBrackets = -1, inParens = -1, inMatchFor = -1, inPseudo = -1, inClass = -1, inId = -1, inTag = -1, currentQuoteChar, lc = "", cc = "", pStart; // iteration vars var x = 0, // index in the query ql = query.length, currentPart = null, // data structure representing the entire clause _cp = null; // the current pseudo or attr matcher // several temporary variables are assigned to this structure during a // potential sub-expression match: // attr: // a string representing the current full attribute match in a // bracket expression // type: // if there's an operator in a bracket expression, this is // used to keep track of it // value: // the internals of parenthetical expression for a pseudo. for // :nth-child(2n+1), value might be "2n+1" var endTag = function(){ // called when the tokenizer hits the end of a particular tag name. // Re-sets state variables for tag matching and sets up the matcher // to handle the next type of token (tag or operator). if(inTag >= 0){ var tv = (inTag == x) ? null : ts(inTag, x); // .toLowerCase(); currentPart[ (specials.indexOf(tv) < 0) ? "tag" : "oper" ] = tv; inTag = -1; } }; var endId = function(){ // called when the tokenizer might be at the end of an ID portion of a match if(inId >= 0){ currentPart.id = ts(inId, x).replace(/\\/g, ""); inId = -1; } }; var endClass = function(){ // called when the tokenizer might be at the end of a class name // match. CSS allows for multiple classes, so we augment the // current item with another class in its list if(inClass >= 0){ currentPart.classes.push(ts(inClass + 1, x).replace(/\\/g, "")); inClass = -1; } }; var endAll = function(){ // at the end of a simple fragment, so wall off the matches endId(); endTag(); endClass(); }; var endPart = function(){ endAll(); if(inPseudo >= 0){ currentPart.pseudos.push({ name: ts(inPseudo + 1, x) }); } // hint to the selector engine to tell it whether or not it // needs to do any iteration. Many simple selectors don't, and // we can avoid significant construction-time work by advising // the system to skip them currentPart.loops = ( currentPart.pseudos.length || currentPart.attrs.length || currentPart.classes.length ); currentPart.oquery = currentPart.query = ts(pStart, x); // save the full expression as a string // otag/tag are hints to suggest to the system whether or not // it's an operator or a tag. We save a copy of otag since the // tag name is cast to upper-case in regular HTML matches. The // system has a global switch to figure out if the current // expression needs to be case sensitive or not and it will use // otag or tag accordingly currentPart.otag = currentPart.tag = (currentPart["oper"]) ? null : (currentPart.tag || "*"); if(currentPart.tag){ // if we're in a case-insensitive HTML doc, we likely want // the toUpperCase when matching on element.tagName. If we // do it here, we can skip the string op per node // comparison currentPart.tag = currentPart.tag.toUpperCase(); } // add the part to the list if(queryParts.length && (queryParts[queryParts.length-1].oper)){ // operators are always infix, so we remove them from the // list and attach them to the next match. The evaluator is // responsible for sorting out how to handle them. currentPart.infixOper = queryParts.pop(); currentPart.query = currentPart.infixOper.query + " " + currentPart.query; /* console.debug( "swapping out the infix", currentPart.infixOper, "and attaching it to", currentPart); */ } queryParts.push(currentPart); currentPart = null; }; // iterate over the query, character by character, building up a // list of query part objects for(; lc=cc, cc=query.charAt(x), x < ql; x++){ // cc: the current character in the match // lc: the last character (if any) // someone is trying to escape something, so don't try to match any // fragments. We assume we're inside a literal. if(lc == "\\"){ continue; } if(!currentPart){ // a part was just ended or none has yet been created // NOTE: I hate all this alloc, but it's shorter than writing tons of if's pStart = x; // rules describe full CSS sub-expressions, like: // #someId // .className:first-child // but not: // thinger > div.howdy[type=thinger] // the indidual components of the previous query would be // split into 3 parts that would be represented a structure like: // [ // { // query: "thinger", // tag: "thinger", // }, // { // query: "div.howdy[type=thinger]", // classes: ["howdy"], // infixOper: { // query: ">", // oper: ">", // } // }, // ] currentPart = { query: null, // the full text of the part's rule pseudos: [], // CSS supports multiple pseud-class matches in a single rule attrs: [], // CSS supports multi-attribute match, so we need an array classes: [], // class matches may be additive, e.g.: .thinger.blah.howdy tag: null, // only one tag... oper: null, // ...or operator per component. Note that these wind up being exclusive. id: null, // the id component of a rule getTag: function(){ return caseSensitive ? this.otag : this.tag; } }; // if we don't have a part, we assume we're going to start at // the beginning of a match, which should be a tag name. This // might fault a little later on, but we detect that and this // iteration will still be fine. inTag = x; } // Skip processing all quoted characters. // If we are inside quoted text then currentQuoteChar stores the character that began the quote, // thus that character that will end it. if(currentQuoteChar){ if(cc == currentQuoteChar){ currentQuoteChar = null; } continue; }else if (cc == "'" || cc == '"'){ currentQuoteChar = cc; continue; } if(inBrackets >= 0){ // look for a the close first if(cc == "]"){ // if we're in a [...] clause and we end, do assignment if(!_cp.attr){ // no attribute match was previously begun, so we // assume this is an attribute existence match in the // form of [someAttributeName] _cp.attr = ts(inBrackets+1, x); }else{ // we had an attribute already, so we know that we're // matching some sort of value, as in [attrName=howdy] _cp.matchFor = ts((inMatchFor||inBrackets+1), x); } var cmf = _cp.matchFor; if(cmf){ // try to strip quotes from the matchFor value. We want // [attrName=howdy] to match the same // as [attrName = 'howdy' ] if( (cmf.charAt(0) == '"') || (cmf.charAt(0) == "'") ){ _cp.matchFor = cmf.slice(1, -1); } } // remove backslash escapes from an attribute match, since DOM // querying will get attribute values without backslashes if(_cp.matchFor){ _cp.matchFor = _cp.matchFor.replace(/\\/g, ""); } // end the attribute by adding it to the list of attributes. currentPart.attrs.push(_cp); _cp = null; // necessary? inBrackets = inMatchFor = -1; }else if(cc == "="){ // if the last char was an operator prefix, make sure we // record it along with the "=" operator. var addToCc = ("|~^$*".indexOf(lc) >=0 ) ? lc : ""; _cp.type = addToCc+cc; _cp.attr = ts(inBrackets+1, x-addToCc.length); inMatchFor = x+1; } // now look for other clause parts }else if(inParens >= 0){ // if we're in a parenthetical expression, we need to figure // out if it's attached to a pseudo-selector rule like // :nth-child(1) if(cc == ")"){ if(inPseudo >= 0){ _cp.value = ts(inParens+1, x); } inPseudo = inParens = -1; } }else if(cc == "#"){ // start of an ID match endAll(); inId = x+1; }else if(cc == "."){ // start of a class match endAll(); inClass = x; }else if(cc == ":"){ // start of a pseudo-selector match endAll(); inPseudo = x; }else if(cc == "["){ // start of an attribute match. endAll(); inBrackets = x; // provide a new structure for the attribute match to fill-in _cp = { /*===== attr: null, type: null, matchFor: null =====*/ }; }else if(cc == "("){ // we really only care if we've entered a parenthetical // expression if we're already inside a pseudo-selector match if(inPseudo >= 0){ // provide a new structure for the pseudo match to fill-in _cp = { name: ts(inPseudo+1, x), value: null }; currentPart.pseudos.push(_cp); } inParens = x; }else if( (cc == " ") && // if it's a space char and the last char is too, consume the // current one without doing more work (lc != cc) ){ endPart(); } } return queryParts; }; //////////////////////////////////////////////////////////////////////// // DOM query infrastructure //////////////////////////////////////////////////////////////////////// var agree = function(first, second){ // the basic building block of the yes/no chaining system. agree(f1, // f2) generates a new function which returns the boolean results of // both of the passed functions to a single logical-anded result. If // either are not passed, the other is used exclusively. if(!first){ return second; } if(!second){ return first; } return function(){ return first.apply(window, arguments) && second.apply(window, arguments); }; }; var getArr = function(i, arr){ // helps us avoid array alloc when we don't need it var r = arr||[]; // FIXME: should this be 'new d._NodeListCtor()' ? if(i){ r.push(i); } return r; }; var _isElement = function(n){ return (1 == n.nodeType); }; // FIXME: need to coalesce _getAttr with defaultGetter var blank = ""; var _getAttr = function(elem, attr){ if(!elem){ return blank; } if(attr == "class"){ return elem.className || blank; } if(attr == "for"){ return elem.htmlFor || blank; } if(attr == "style"){ return elem.style.cssText || blank; } return (caseSensitive ? elem.getAttribute(attr) : elem.getAttribute(attr, 2)) || blank; }; var attrs = { "*=": function(attr, value){ return function(elem){ // E[foo*="bar"] // an E element whose "foo" attribute value contains // the substring "bar" return (_getAttr(elem, attr).indexOf(value)>=0); }; }, "^=": function(attr, value){ // E[foo^="bar"] // an E element whose "foo" attribute value begins exactly // with the string "bar" return function(elem){ return (_getAttr(elem, attr).indexOf(value)==0); }; }, "$=": function(attr, value){ // E[foo$="bar"] // an E element whose "foo" attribute value ends exactly // with the string "bar" return function(elem){ var ea = " "+_getAttr(elem, attr); var lastIndex = ea.lastIndexOf(value); return lastIndex > -1 && (lastIndex==(ea.length-value.length)); }; }, "~=": function(attr, value){ // E[foo~="bar"] // an E element whose "foo" attribute value is a list of // space-separated values, one of which is exactly equal // to "bar" // return "[contains(concat(' ',@"+attr+",' '), ' "+ value +" ')]"; var tval = " "+value+" "; return function(elem){ var ea = " "+_getAttr(elem, attr)+" "; return (ea.indexOf(tval)>=0); }; }, "|=": function(attr, value){ // E[hreflang|="en"] // an E element whose "hreflang" attribute has a // hyphen-separated list of values beginning (from the // left) with "en" var valueDash = value+"-"; return function(elem){ var ea = _getAttr(elem, attr); return ( (ea == value) || (ea.indexOf(valueDash)==0) ); }; }, "=": function(attr, value){ return function(elem){ return (_getAttr(elem, attr) == value); }; } }; // avoid testing for node type if we can. Defining this in the negative // here to avoid negation in the fast path. var _noNES = (typeof getDoc().firstChild.nextElementSibling == "undefined"); var _ns = !_noNES ? "nextElementSibling" : "nextSibling"; var _ps = !_noNES ? "previousElementSibling" : "previousSibling"; var _simpleNodeTest = (_noNES ? _isElement : yesman); var _lookLeft = function(node){ // look left while(node = node[_ps]){ if(_simpleNodeTest(node)){ return false; } } return true; }; var _lookRight = function(node){ // look right while(node = node[_ns]){ if(_simpleNodeTest(node)){ return false; } } return true; }; var getNodeIndex = function(node){ var root = node.parentNode; root = root.nodeType != 7 ? root : root.nextSibling; // PROCESSING_INSTRUCTION_NODE var i = 0, tret = root.children || root.childNodes, ci = (node["_i"]||node.getAttribute("_i")||-1), cl = (root["_l"]|| (typeof root.getAttribute !== "undefined" ? root.getAttribute("_l") : -1)); if(!tret){ return -1; } var l = tret.length; // we calculate the parent length as a cheap way to invalidate the // cache. It's not 100% accurate, but it's much more honest than what // other libraries do if( cl == l && ci >= 0 && cl >= 0 ){ // if it's legit, tag and release return ci; } // else re-key things if(has("ie") && typeof root.setAttribute !== "undefined"){ root.setAttribute("_l", l); }else{ root["_l"] = l; } ci = -1; for(var te = root["firstElementChild"]||root["firstChild"]; te; te = te[_ns]){ if(_simpleNodeTest(te)){ if(has("ie")){ te.setAttribute("_i", ++i); }else{ te["_i"] = ++i; } if(node === te){ // NOTE: // shortcutting the return at this step in indexing works // very well for benchmarking but we avoid it here since // it leads to potential O(n^2) behavior in sequential // getNodexIndex operations on a previously un-indexed // parent. We may revisit this at a later time, but for // now we just want to get the right answer more often // than not. ci = i; } } } return ci; }; var isEven = function(elem){ return !((getNodeIndex(elem)) % 2); }; var isOdd = function(elem){ return ((getNodeIndex(elem)) % 2); }; var pseudos = { "checked": function(name, condition){ return function(elem){ return !!("checked" in elem ? elem.checked : elem.selected); }; }, "disabled": function(name, condition){ return function(elem){ return elem.disabled; }; }, "enabled": function(name, condition){ return function(elem){ return !elem.disabled; }; }, "first-child": function(){ return _lookLeft; }, "last-child": function(){ return _lookRight; }, "only-child": function(name, condition){ return function(node){ return _lookLeft(node) && _lookRight(node); }; }, "empty": function(name, condition){ return function(elem){ // DomQuery and jQuery get this wrong, oddly enough. // The CSS 3 selectors spec is pretty explicit about it, too. var cn = elem.childNodes; var cnl = elem.childNodes.length; // if(!cnl){ return true; } for(var x=cnl-1; x >= 0; x--){ var nt = cn[x].nodeType; if((nt === 1)||(nt == 3)){ return false; } } return true; }; }, "contains": function(name, condition){ var cz = condition.charAt(0); if( cz == '"' || cz == "'" ){ //remove quote condition = condition.slice(1, -1); } return function(elem){ return (elem.innerHTML.indexOf(condition) >= 0); }; }, "not": function(name, condition){ var p = getQueryParts(condition)[0]; var ignores = { el: 1 }; if(p.tag != "*"){ ignores.tag = 1; } if(!p.classes.length){ ignores.classes = 1; } var ntf = getSimpleFilterFunc(p, ignores); return function(elem){ return (!ntf(elem)); }; }, "nth-child": function(name, condition){ var pi = parseInt; // avoid re-defining function objects if we can if(condition == "odd"){ return isOdd; }else if(condition == "even"){ return isEven; } // FIXME: can we shorten this? if(condition.indexOf("n") != -1){ var tparts = condition.split("n", 2); var pred = tparts[0] ? ((tparts[0] == '-') ? -1 : pi(tparts[0])) : 1; var idx = tparts[1] ? pi(tparts[1]) : 0; var lb = 0, ub = -1; if(pred > 0){ if(idx < 0){ idx = (idx % pred) && (pred + (idx % pred)); }else if(idx>0){ if(idx >= pred){ lb = idx - idx % pred; } idx = idx % pred; } }else if(pred<0){ pred *= -1; // idx has to be greater than 0 when pred is negative; // shall we throw an error here? if(idx > 0){ ub = idx; idx = idx % pred; } } if(pred > 0){ return function(elem){ var i = getNodeIndex(elem); return (i>=lb) && (ub<0 || i<=ub) && ((i % pred) == idx); }; }else{ condition = idx; } } var ncount = pi(condition); return function(elem){ return (getNodeIndex(elem) == ncount); }; } }; var defaultGetter = (has("ie") && (has("ie") < 9 || has("quirks"))) ? function(cond){ var clc = cond.toLowerCase(); if(clc == "class"){ cond = "className"; } return function(elem){ return (caseSensitive ? elem.getAttribute(cond) : elem[cond]||elem[clc]); }; } : function(cond){ return function(elem){ return (elem && elem.getAttribute && elem.hasAttribute(cond)); }; }; var getSimpleFilterFunc = function(query, ignores){ // generates a node tester function based on the passed query part. The // query part is one of the structures generated by the query parser // when it creates the query AST. The "ignores" object specifies which // (if any) tests to skip, allowing the system to avoid duplicating // work where it may have already been taken into account by other // factors such as how the nodes to test were fetched in the first // place if(!query){ return yesman; } ignores = ignores||{}; var ff = null; if(!("el" in ignores)){ ff = agree(ff, _isElement); } if(!("tag" in ignores)){ if(query.tag != "*"){ ff = agree(ff, function(elem){ return (elem && ((caseSensitive ? elem.tagName : elem.tagName.toUpperCase()) == query.getTag())); }); } } if(!("classes" in ignores)){ each(query.classes, function(cname, idx, arr){ // get the class name /* var isWildcard = cname.charAt(cname.length-1) == "*"; if(isWildcard){ cname = cname.substr(0, cname.length-1); } // I dislike the regex thing, even if memoized in a cache, but it's VERY short var re = new RegExp("(?:^|\\s)" + cname + (isWildcard ? ".*" : "") + "(?:\\s|$)"); */ var re = new RegExp("(?:^|\\s)" + cname + "(?:\\s|$)"); ff = agree(ff, function(elem){ return re.test(elem.className); }); ff.count = idx; }); } if(!("pseudos" in ignores)){ each(query.pseudos, function(pseudo){ var pn = pseudo.name; if(pseudos[pn]){ ff = agree(ff, pseudos[pn](pn, pseudo.value)); } }); } if(!("attrs" in ignores)){ each(query.attrs, function(attr){ var matcher; var a = attr.attr; // type, attr, matchFor if(attr.type && attrs[attr.type]){ matcher = attrs[attr.type](a, attr.matchFor); }else if(a.length){ matcher = defaultGetter(a); } if(matcher){ ff = agree(ff, matcher); } }); } if(!("id" in ignores)){ if(query.id){ ff = agree(ff, function(elem){ return (!!elem && (elem.id == query.id)); }); } } if(!ff){ if(!("default" in ignores)){ ff = yesman; } } return ff; }; var _nextSibling = function(filterFunc){ return function(node, ret, bag){ while(node = node[_ns]){ if(_noNES && (!_isElement(node))){ continue; } if( (!bag || _isUnique(node, bag)) && filterFunc(node) ){ ret.push(node); } break; } return ret; }; }; var _nextSiblings = function(filterFunc){ return function(root, ret, bag){ var te = root[_ns]; while(te){ if(_simpleNodeTest(te)){ if(bag && !_isUnique(te, bag)){ break; } if(filterFunc(te)){ ret.push(te); } } te = te[_ns]; } return ret; }; }; // get an array of child *elements*, skipping text and comment nodes var _childElements = function(filterFunc){ filterFunc = filterFunc||yesman; return function(root, ret, bag){ // get an array of child elements, skipping text and comment nodes var te, x = 0, tret = root.children || root.childNodes; while(te = tret[x++]){ if( _simpleNodeTest(te) && (!bag || _isUnique(te, bag)) && (filterFunc(te, x)) ){ ret.push(te); } } return ret; }; }; // test to see if node is below root var _isDescendant = function(node, root){ var pn = node.parentNode; while(pn){ if(pn == root){ break; } pn = pn.parentNode; } return !!pn; }; var _getElementsFuncCache = {}; var getElementsFunc = function(query){ var retFunc = _getElementsFuncCache[query.query]; // if we've got a cached dispatcher, just use that if(retFunc){ return retFunc; } // else, generate a new on // NOTE: // this function returns a function that searches for nodes and // filters them. The search may be specialized by infix operators // (">", "~", or "+") else it will default to searching all // descendants (the " " selector). Once a group of children is // found, a test function is applied to weed out the ones we // don't want. Many common cases can be fast-pathed. We spend a // lot of cycles to create a dispatcher that doesn't do more work // than necessary at any point since, unlike this function, the // dispatchers will be called every time. The logic of generating // efficient dispatchers looks like this in pseudo code: // // # if it's a purely descendant query (no ">", "+", or "~" modifiers) // if infixOperator == " ": // if only(id): // return def(root): // return d.byId(id, root); // // elif id: // return def(root): // return filter(d.byId(id, root)); // // elif cssClass && getElementsByClassName: // return def(root): // return filter(root.getElementsByClassName(cssClass)); // // elif only(tag): // return def(root): // return root.getElementsByTagName(tagName); // // else: // # search by tag name, then filter // return def(root): // return filter(root.getElementsByTagName(tagName||"*")); // // elif infixOperator == ">": // # search direct children // return def(root): // return filter(root.children); // // elif infixOperator == "+": // # search next sibling // return def(root): // return filter(root.nextElementSibling); // // elif infixOperator == "~": // # search rightward siblings // return def(root): // return filter(nextSiblings(root)); var io = query.infixOper; var oper = (io ? io.oper : ""); // the default filter func which tests for all conditions in the query // part. This is potentially inefficient, so some optimized paths may // re-define it to test fewer things. var filterFunc = getSimpleFilterFunc(query, { el: 1 }); var qt = query.tag; var wildcardTag = ("*" == qt); var ecs = getDoc()["getElementsByClassName"]; if(!oper){ // if there's no infix operator, then it's a descendant query. ID // and "elements by class name" variants can be accelerated so we // call them out explicitly: if(query.id){ // testing shows that the overhead of yesman() is acceptable // and can save us some bytes vs. re-defining the function // everywhere. filterFunc = (!query.loops && wildcardTag) ? yesman : getSimpleFilterFunc(query, { el: 1, id: 1 }); retFunc = function(root, arr){ var te = dom.byId(query.id, (root.ownerDocument||root)); if(!te || !filterFunc(te)){ return; } if(9 == root.nodeType){ // if root's a doc, we just return directly return getArr(te, arr); }else{ // otherwise check ancestry if(_isDescendant(te, root)){ return getArr(te, arr); } } }; }else if( ecs && // isAlien check. Workaround for Prototype.js being totally evil/dumb. /\{\s*\[native code\]\s*\}/.test(String(ecs)) && query.classes.length && !cssCaseBug ){ // it's a class-based query and we've got a fast way to run it. // ignore class and ID filters since we will have handled both filterFunc = getSimpleFilterFunc(query, { el: 1, classes: 1, id: 1 }); var classesString = query.classes.join(" "); retFunc = function(root, arr, bag){ var ret = getArr(0, arr), te, x=0; var tret = root.getElementsByClassName(classesString); while((te = tret[x++])){ if(filterFunc(te, root) && _isUnique(te, bag)){ ret.push(te); } } return ret; }; }else if(!wildcardTag && !query.loops){ // it's tag only. Fast-path it. retFunc = function(root, arr, bag){ var ret = getArr(0, arr), te, x=0; var tag = query.getTag(), tret = tag ? root.getElementsByTagName(tag) : []; while((te = tret[x++])){ if(_isUnique(te, bag)){ ret.push(te); } } return ret; }; }else{ // the common case: // a descendant selector without a fast path. By now it's got // to have a tag selector, even if it's just "*" so we query // by that and filter filterFunc = getSimpleFilterFunc(query, { el: 1, tag: 1, id: 1 }); retFunc = function(root, arr, bag){ var ret = getArr(0, arr), te, x=0; // we use getTag() to avoid case sensitivity issues var tag = query.getTag(), tret = tag ? root.getElementsByTagName(tag) : []; while((te = tret[x++])){ if(filterFunc(te, root) && _isUnique(te, bag)){ ret.push(te); } } return ret; }; } }else{ // the query is scoped in some way. Instead of querying by tag we // use some other collection to find candidate nodes var skipFilters = { el: 1 }; if(wildcardTag){ skipFilters.tag = 1; } filterFunc = getSimpleFilterFunc(query, skipFilters); if("+" == oper){ retFunc = _nextSibling(filterFunc); }else if("~" == oper){ retFunc = _nextSiblings(filterFunc); }else if(">" == oper){ retFunc = _childElements(filterFunc); } } // cache it and return return _getElementsFuncCache[query.query] = retFunc; }; var filterDown = function(root, queryParts){ // NOTE: // this is the guts of the DOM query system. It takes a list of // parsed query parts and a root and finds children which match // the selector represented by the parts var candidates = getArr(root), qp, x, te, qpl = queryParts.length, bag, ret; for(var i = 0; i < qpl; i++){ ret = []; qp = queryParts[i]; x = candidates.length - 1; if(x > 0){ // if we have more than one root at this level, provide a new // hash to use for checking group membership but tell the // system not to post-filter us since we will already have been // guaranteed to be unique bag = {}; ret.nozip = true; } var gef = getElementsFunc(qp); for(var j = 0; (te = candidates[j]); j++){ // for every root, get the elements that match the descendant // selector, adding them to the "ret" array and filtering them // via membership in this level's bag. If there are more query // parts, then this level's return will be used as the next // level's candidates gef(te, ret, bag); } if(!ret.length){ break; } candidates = ret; } return ret; }; //////////////////////////////////////////////////////////////////////// // the query runner //////////////////////////////////////////////////////////////////////// // these are the primary caches for full-query results. The query // dispatcher functions are generated then stored here for hash lookup in // the future var _queryFuncCacheDOM = {}, _queryFuncCacheQSA = {}; // this is the second level of splitting, from full-length queries (e.g., // "div.foo .bar") into simple query expressions (e.g., ["div.foo", // ".bar"]) var getStepQueryFunc = function(query){ var qparts = getQueryParts(trim(query)); // if it's trivial, avoid iteration and zipping costs if(qparts.length == 1){ // we optimize this case here to prevent dispatch further down the // chain, potentially slowing things down. We could more elegantly // handle this in filterDown(), but it's slower for simple things // that need to be fast (e.g., "#someId"). var tef = getElementsFunc(qparts[0]); return function(root){ var r = tef(root, []); if(r){ r.nozip = true; } return r; }; } // otherwise, break it up and return a runner that iterates over the parts recursively return function(root){ return filterDown(root, qparts); }; }; // NOTES: // * we can't trust QSA for anything but document-rooted queries, so // caching is split into DOM query evaluators and QSA query evaluators // * caching query results is dirty and leak-prone (or, at a minimum, // prone to unbounded growth). Other toolkits may go this route, but // they totally destroy their own ability to manage their memory // footprint. If we implement it, it should only ever be with a fixed // total element reference # limit and an LRU-style algorithm since JS // has no weakref support. Caching compiled query evaluators is also // potentially problematic, but even on large documents the size of the // query evaluators is often < 100 function objects per evaluator (and // LRU can be applied if it's ever shown to be an issue). // * since IE's QSA support is currently only for HTML documents and even // then only in IE 8's "standards mode", we have to detect our dispatch // route at query time and keep 2 separate caches. Ugg. // we need to determine if we think we can run a given query via // querySelectorAll or if we'll need to fall back on DOM queries to get // there. We need a lot of information about the environment and the query // to make the determination (e.g. does it support QSA, does the query in // question work in the native QSA impl, etc.). // IE QSA queries may incorrectly include comment nodes, so we throw the // zipping function into "remove" comments mode instead of the normal "skip // it" which every other QSA-clued browser enjoys var noZip = has("ie") ? "commentStrip" : "nozip"; var qsa = "querySelectorAll"; var qsaAvail = !!getDoc()[qsa]; //Don't bother with n+3 type of matches, IE complains if we modify those. var infixSpaceRe = /\\[>~+]|n\+\d|([^ \\])?([>~+])([^ =])?/g; var infixSpaceFunc = function(match, pre, ch, post){ return ch ? (pre ? pre + " " : "") + ch + (post ? " " + post : "") : /*n+3*/ match; }; //Don't apply the infixSpaceRe to attribute value selectors var attRe = /([^[]*)([^\]]*])?/g; var attFunc = function(match, nonAtt, att){ return nonAtt.replace(infixSpaceRe, infixSpaceFunc) + (att||""); }; var getQueryFunc = function(query, forceDOM){ //Normalize query. The CSS3 selectors spec allows for omitting spaces around //infix operators, >, ~ and + //Do the work here since detection for spaces is used as a simple "not use QSA" //test below. query = query.replace(attRe, attFunc); if(qsaAvail){ // if we've got a cached variant and we think we can do it, run it! var qsaCached = _queryFuncCacheQSA[query]; if(qsaCached && !forceDOM){ return qsaCached; } } // else if we've got a DOM cached variant, assume that we already know // all we need to and use it var domCached = _queryFuncCacheDOM[query]; if(domCached){ return domCached; } // TODO: // today we're caching DOM and QSA branches separately so we // recalc useQSA every time. If we had a way to tag root+query // efficiently, we'd be in good shape to do a global cache. var qcz = query.charAt(0); var nospace = (-1 == query.indexOf(" ")); // byId searches are wicked fast compared to QSA, even when filtering // is required if( (query.indexOf("#") >= 0) && (nospace) ){ forceDOM = true; } var useQSA = ( qsaAvail && (!forceDOM) && // as per CSS 3, we can't currently start w/ combinator: // http://www.w3.org/TR/css3-selectors/#w3cselgrammar (specials.indexOf(qcz) == -1) && // IE's QSA impl sucks on pseudos (!has("ie") || (query.indexOf(":") == -1)) && (!(cssCaseBug && (query.indexOf(".") >= 0))) && // FIXME: // need to tighten up browser rules on ":contains" and "|=" to // figure out which aren't good // Latest webkit (around 531.21.8) does not seem to do well with :checked on option // elements, even though according to spec, selected options should // match :checked. So go nonQSA for it: // http://bugs.dojotoolkit.org/ticket/5179 (query.indexOf(":contains") == -1) && (query.indexOf(":checked") == -1) && (query.indexOf("|=") == -1) // some browsers don't grok it ); // TODO: // if we've got a descendant query (e.g., "> .thinger" instead of // just ".thinger") in a QSA-able doc, but are passed a child as a // root, it should be possible to give the item a synthetic ID and // trivially rewrite the query to the form "#synid > .thinger" to // use the QSA branch if(useQSA){ var tq = (specials.indexOf(query.charAt(query.length-1)) >= 0) ? (query + " *") : query; return _queryFuncCacheQSA[query] = function(root){ try{ // the QSA system contains an egregious spec bug which // limits us, effectively, to only running QSA queries over // entire documents. See: // http://ejohn.org/blog/thoughts-on-queryselectorall/ // despite this, we can also handle QSA runs on simple // selectors, but we don't want detection to be expensive // so we're just checking for the presence of a space char // right now. Not elegant, but it's cheaper than running // the query parser when we might not need to if(!((9 == root.nodeType) || nospace)){ throw ""; } var r = root[qsa](tq); // skip expensive duplication checks and just wrap in a NodeList r[noZip] = true; return r; }catch(e){ // else run the DOM branch on this query, ensuring that we // default that way in the future return getQueryFunc(query, true)(root); } }; }else{ // DOM branch var parts = query.match(/([^\s,](?:"(?:\\.|[^"])+"|'(?:\\.|[^'])+'|[^,])*)/g); return _queryFuncCacheDOM[query] = ((parts.length < 2) ? // if not a compound query (e.g., ".foo, .bar"), cache and return a dispatcher getStepQueryFunc(query) : // if it *is* a complex query, break it up into its // constituent parts and return a dispatcher that will // merge the parts when run function(root){ var pindex = 0, // avoid array alloc for every invocation ret = [], tp; while((tp = parts[pindex++])){ ret = ret.concat(getStepQueryFunc(tp)(root)); } return ret; } ); } }; var _zipIdx = 0; // NOTE: // this function is Moo inspired, but our own impl to deal correctly // with XML in IE var _nodeUID = has("ie") ? function(node){ if(caseSensitive){ // XML docs don't have uniqueID on their nodes return (node.getAttribute("_uid") || node.setAttribute("_uid", ++_zipIdx) || _zipIdx); }else{ return node.uniqueID; } } : function(node){ return (node._uid || (node._uid = ++_zipIdx)); }; // determine if a node in is unique in a "bag". In this case we don't want // to flatten a list of unique items, but rather just tell if the item in // question is already in the bag. Normally we'd just use hash lookup to do // this for us but IE's DOM is busted so we can't really count on that. On // the upside, it gives us a built in unique ID function. var _isUnique = function(node, bag){ if(!bag){ return 1; } var id = _nodeUID(node); if(!bag[id]){ return bag[id] = 1; } return 0; }; // attempt to efficiently determine if an item in a list is a dupe, // returning a list of "uniques", hopefully in document order var _zipIdxName = "_zipIdx"; var _zip = function(arr){ if(arr && arr.nozip){ return arr; } var ret = []; if(!arr || !arr.length){ return ret; } if(arr[0]){ ret.push(arr[0]); } if(arr.length < 2){ return ret; } _zipIdx++; // we have to fork here for IE and XML docs because we can't set // expandos on their nodes (apparently). *sigh* var x, te; if(has("ie") && caseSensitive){ var szidx = _zipIdx+""; arr[0].setAttribute(_zipIdxName, szidx); for(x = 1; te = arr[x]; x++){ if(arr[x].getAttribute(_zipIdxName) != szidx){ ret.push(te); } te.setAttribute(_zipIdxName, szidx); } }else if(has("ie") && arr.commentStrip){ try{ for(x = 1; te = arr[x]; x++){ if(_isElement(te)){ ret.push(te); } } }catch(e){ /* squelch */ } }else{ if(arr[0]){ arr[0][_zipIdxName] = _zipIdx; } for(x = 1; te = arr[x]; x++){ if(arr[x][_zipIdxName] != _zipIdx){ ret.push(te); } te[_zipIdxName] = _zipIdx; } } return ret; }; // the main executor var query = function(/*String*/ query, /*String|DOMNode?*/ root){ // summary: // Returns nodes which match the given CSS3 selector, searching the // entire document by default but optionally taking a node to scope // the search by. Returns an array. // description: // dojo.query() is the swiss army knife of DOM node manipulation in // Dojo. Much like Prototype's "$$" (bling-bling) function or JQuery's // "$" function, dojo.query provides robust, high-performance // CSS-based node selector support with the option of scoping searches // to a particular sub-tree of a document. // // Supported Selectors: // -------------------- // // acme supports a rich set of CSS3 selectors, including: // // - class selectors (e.g., `.foo`) // - node type selectors like `span` // - ` ` descendant selectors // - `>` child element selectors // - `#foo` style ID selectors // - `*` universal selector // - `~`, the preceded-by sibling selector // - `+`, the immediately preceded-by sibling selector // - attribute queries: // - `[foo]` attribute presence selector // - `[foo='bar']` attribute value exact match // - `[foo~='bar']` attribute value list item match // - `[foo^='bar']` attribute start match // - `[foo$='bar']` attribute end match // - `[foo*='bar']` attribute substring match // - `:first-child`, `:last-child`, and `:only-child` positional selectors // - `:empty` content emtpy selector // - `:checked` pseudo selector // - `:nth-child(n)`, `:nth-child(2n+1)` style positional calculations // - `:nth-child(even)`, `:nth-child(odd)` positional selectors // - `:not(...)` negation pseudo selectors // // Any legal combination of these selectors will work with // `dojo.query()`, including compound selectors ("," delimited). // Very complex and useful searches can be constructed with this // palette of selectors and when combined with functions for // manipulation presented by dojo/NodeList, many types of DOM // manipulation operations become very straightforward. // // Unsupported Selectors: // ---------------------- // // While dojo.query handles many CSS3 selectors, some fall outside of // what's reasonable for a programmatic node querying engine to // handle. Currently unsupported selectors include: // // - namespace-differentiated selectors of any form // - all `::` pseduo-element selectors // - certain pseudo-selectors which don't get a lot of day-to-day use: // - `:root`, `:lang()`, `:target`, `:focus` // - all visual and state selectors: // - `:root`, `:active`, `:hover`, `:visited`, `:link`, // `:enabled`, `:disabled` // - `:*-of-type` pseudo selectors // // dojo.query and XML Documents: // ----------------------------- // // `dojo.query` (as of dojo 1.2) supports searching XML documents // in a case-sensitive manner. If an HTML document is served with // a doctype that forces case-sensitivity (e.g., XHTML 1.1 // Strict), dojo.query() will detect this and "do the right // thing". Case sensitivity is dependent upon the document being // searched and not the query used. It is therefore possible to // use case-sensitive queries on strict sub-documents (iframes, // etc.) or XML documents while still assuming case-insensitivity // for a host/root document. // // Non-selector Queries: // --------------------- // // If something other than a String is passed for the query, // `dojo.query` will return a new `dojo/NodeList` instance // constructed from that parameter alone and all further // processing will stop. This means that if you have a reference // to a node or NodeList, you can quickly construct a new NodeList // from the original by calling `dojo.query(node)` or // `dojo.query(list)`. // // query: // The CSS3 expression to match against. For details on the syntax of // CSS3 selectors, see // root: // A DOMNode (or node id) to scope the search from. Optional. // returns: Array // example: // search the entire document for elements with the class "foo": // | dojo.query(".foo"); // these elements will match: // | // | // |

// example: // search the entire document for elements with the classes "foo" *and* "bar": // | dojo.query(".foo.bar"); // these elements will match: // | // while these will not: // | // |

// example: // find `` elements which are descendants of paragraphs and // which have a "highlighted" class: // | dojo.query("p span.highlighted"); // the innermost span in this fragment matches: // |

// | ... // | ... // | // |

// example: // set an "odd" class on all odd table rows inside of the table // `#tabular_data`, using the `>` (direct child) selector to avoid // affecting any nested tables: // | dojo.query("#tabular_data > tbody > tr:nth-child(odd)").addClass("odd"); // example: // remove all elements with the class "error" from the document // and store them in a list: // | var errors = dojo.query(".error").orphan(); // example: // add an onclick handler to every submit button in the document // which causes the form to be sent via Ajax instead: // | dojo.query("input[type='submit']").onclick(function(e){ // | dojo.stopEvent(e); // prevent sending the form // | var btn = e.target; // | dojo.xhrPost({ // | form: btn.form, // | load: function(data){ // | // replace the form with the response // | var div = dojo.doc.createElement("div"); // | dojo.place(div, btn.form, "after"); // | div.innerHTML = data; // | dojo.style(btn.form, "display", "none"); // | } // | }); // | }); root = root || getDoc(); // throw the big case sensitivity switch var od = root.ownerDocument || root; // root is either Document or a node inside the document caseSensitive = (od.createElement("div").tagName === "div"); // NOTE: // adding "true" as the 2nd argument to getQueryFunc is useful for // testing the DOM branch without worrying about the // behavior/performance of the QSA branch. var r = getQueryFunc(query)(root); // FIXME: // need to investigate this branch WRT #8074 and #8075 if(r && r.nozip){ return r; } return _zip(r); // dojo/NodeList }; query.filter = function(/*Node[]*/ nodeList, /*String*/ filter, /*String|DOMNode?*/ root){ // summary: // function for filtering a NodeList based on a selector, optimized for simple selectors var tmpNodeList = [], parts = getQueryParts(filter), filterFunc = (parts.length == 1 && !/[^\w#\.]/.test(filter)) ? getSimpleFilterFunc(parts[0]) : function(node){ return array.indexOf(query(filter, dom.byId(root)), node) != -1; }; for(var x = 0, te; te = nodeList[x]; x++){ if(filterFunc(te)){ tmpNodeList.push(te); } } return tmpNodeList; }; return query; }); }, 'dojo/errors/RequestTimeoutError':function(){ define("dojo/errors/RequestTimeoutError", ['./create', './RequestError'], function(create, RequestError){ // module: // dojo/errors/RequestTimeoutError /*===== return function(){ // summary: // TODOC }; =====*/ return create("RequestTimeoutError", null, RequestError, { dojoType: "timeout" }); }); }, 'dojo/dom-geometry':function(){ define(["./sniff", "./_base/window","./dom", "./dom-style"], function(has, win, dom, style){ // module: // dojo/dom-geometry // the result object var geom = { // summary: // This module defines the core dojo DOM geometry API. }; // Box functions will assume this model. // On IE/Opera, BORDER_BOX will be set if the primary document is in quirks mode. // Can be set to change behavior of box setters. // can be either: // "border-box" // "content-box" (default) geom.boxModel = "content-box"; // We punt per-node box mode testing completely. // If anybody cares, we can provide an additional (optional) unit // that overrides existing code to include per-node box sensitivity. // Opera documentation claims that Opera 9 uses border-box in BackCompat mode. // but experiments (Opera 9.10.8679 on Windows Vista) indicate that it actually continues to use content-box. // IIRC, earlier versions of Opera did in fact use border-box. // Opera guys, this is really confusing. Opera being broken in quirks mode is not our fault. if(has("ie") /*|| has("opera")*/){ // client code may have to adjust if compatMode varies across iframes geom.boxModel = document.compatMode == "BackCompat" ? "border-box" : "content-box"; } geom.getPadExtents = function getPadExtents(/*DomNode*/ node, /*Object*/ computedStyle){ // summary: // Returns object with special values specifically useful for node // fitting. // description: // Returns an object with `w`, `h`, `l`, `t` properties: // | l/t/r/b = left/top/right/bottom padding (respectively) // | w = the total of the left and right padding // | h = the total of the top and bottom padding // If 'node' has position, l/t forms the origin for child nodes. // The w/h are used for calculating boxes. // Normally application code will not need to invoke this // directly, and will use the ...box... functions instead. // node: DOMNode // computedStyle: Object? // This parameter accepts computed styles object. // If this parameter is omitted, the functions will call // dojo.getComputedStyle to get one. It is a better way, calling // dojo.computedStyle once, and then pass the reference to this // computedStyle parameter. Wherever possible, reuse the returned // object of dojo/dom-style.getComputedStyle(). node = dom.byId(node); var s = computedStyle || style.getComputedStyle(node), px = style.toPixelValue, l = px(node, s.paddingLeft), t = px(node, s.paddingTop), r = px(node, s.paddingRight), b = px(node, s.paddingBottom); return {l: l, t: t, r: r, b: b, w: l + r, h: t + b}; }; var none = "none"; geom.getBorderExtents = function getBorderExtents(/*DomNode*/ node, /*Object*/ computedStyle){ // summary: // returns an object with properties useful for noting the border // dimensions. // description: // - l/t/r/b = the sum of left/top/right/bottom border (respectively) // - w = the sum of the left and right border // - h = the sum of the top and bottom border // // The w/h are used for calculating boxes. // Normally application code will not need to invoke this // directly, and will use the ...box... functions instead. // node: DOMNode // computedStyle: Object? // This parameter accepts computed styles object. // If this parameter is omitted, the functions will call // dojo.getComputedStyle to get one. It is a better way, calling // dojo.computedStyle once, and then pass the reference to this // computedStyle parameter. Wherever possible, reuse the returned // object of dojo/dom-style.getComputedStyle(). node = dom.byId(node); var px = style.toPixelValue, s = computedStyle || style.getComputedStyle(node), l = s.borderLeftStyle != none ? px(node, s.borderLeftWidth) : 0, t = s.borderTopStyle != none ? px(node, s.borderTopWidth) : 0, r = s.borderRightStyle != none ? px(node, s.borderRightWidth) : 0, b = s.borderBottomStyle != none ? px(node, s.borderBottomWidth) : 0; return {l: l, t: t, r: r, b: b, w: l + r, h: t + b}; }; geom.getPadBorderExtents = function getPadBorderExtents(/*DomNode*/ node, /*Object*/ computedStyle){ // summary: // Returns object with properties useful for box fitting with // regards to padding. // description: // - l/t/r/b = the sum of left/top/right/bottom padding and left/top/right/bottom border (respectively) // - w = the sum of the left and right padding and border // - h = the sum of the top and bottom padding and border // // The w/h are used for calculating boxes. // Normally application code will not need to invoke this // directly, and will use the ...box... functions instead. // node: DOMNode // computedStyle: Object? // This parameter accepts computed styles object. // If this parameter is omitted, the functions will call // dojo.getComputedStyle to get one. It is a better way, calling // dojo.computedStyle once, and then pass the reference to this // computedStyle parameter. Wherever possible, reuse the returned // object of dojo/dom-style.getComputedStyle(). node = dom.byId(node); var s = computedStyle || style.getComputedStyle(node), p = geom.getPadExtents(node, s), b = geom.getBorderExtents(node, s); return { l: p.l + b.l, t: p.t + b.t, r: p.r + b.r, b: p.b + b.b, w: p.w + b.w, h: p.h + b.h }; }; geom.getMarginExtents = function getMarginExtents(node, computedStyle){ // summary: // returns object with properties useful for box fitting with // regards to box margins (i.e., the outer-box). // // - l/t = marginLeft, marginTop, respectively // - w = total width, margin inclusive // - h = total height, margin inclusive // // The w/h are used for calculating boxes. // Normally application code will not need to invoke this // directly, and will use the ...box... functions instead. // node: DOMNode // computedStyle: Object? // This parameter accepts computed styles object. // If this parameter is omitted, the functions will call // dojo.getComputedStyle to get one. It is a better way, calling // dojo.computedStyle once, and then pass the reference to this // computedStyle parameter. Wherever possible, reuse the returned // object of dojo/dom-style.getComputedStyle(). node = dom.byId(node); var s = computedStyle || style.getComputedStyle(node), px = style.toPixelValue, l = px(node, s.marginLeft), t = px(node, s.marginTop), r = px(node, s.marginRight), b = px(node, s.marginBottom); return {l: l, t: t, r: r, b: b, w: l + r, h: t + b}; }; // Box getters work in any box context because offsetWidth/clientWidth // are invariant wrt box context // // They do *not* work for display: inline objects that have padding styles // because the user agent ignores padding (it's bogus styling in any case) // // Be careful with IMGs because they are inline or block depending on // browser and browser mode. // Although it would be easier to read, there are not separate versions of // _getMarginBox for each browser because: // 1. the branching is not expensive // 2. factoring the shared code wastes cycles (function call overhead) // 3. duplicating the shared code wastes bytes geom.getMarginBox = function getMarginBox(/*DomNode*/ node, /*Object*/ computedStyle){ // summary: // returns an object that encodes the width, height, left and top // positions of the node's margin box. // node: DOMNode // computedStyle: Object? // This parameter accepts computed styles object. // If this parameter is omitted, the functions will call // dojo.getComputedStyle to get one. It is a better way, calling // dojo.computedStyle once, and then pass the reference to this // computedStyle parameter. Wherever possible, reuse the returned // object of dojo/dom-style.getComputedStyle(). node = dom.byId(node); var s = computedStyle || style.getComputedStyle(node), me = geom.getMarginExtents(node, s), l = node.offsetLeft - me.l, t = node.offsetTop - me.t, p = node.parentNode, px = style.toPixelValue, pcs; if(has("mozilla")){ // Mozilla: // If offsetParent has a computed overflow != visible, the offsetLeft is decreased // by the parent's border. // We don't want to compute the parent's style, so instead we examine node's // computed left/top which is more stable. var sl = parseFloat(s.left), st = parseFloat(s.top); if(!isNaN(sl) && !isNaN(st)){ l = sl; t = st; }else{ // If child's computed left/top are not parseable as a number (e.g. "auto"), we // have no choice but to examine the parent's computed style. if(p && p.style){ pcs = style.getComputedStyle(p); if(pcs.overflow != "visible"){ l += pcs.borderLeftStyle != none ? px(node, pcs.borderLeftWidth) : 0; t += pcs.borderTopStyle != none ? px(node, pcs.borderTopWidth) : 0; } } } }else if(has("opera") || (has("ie") == 8 && !has("quirks"))){ // On Opera and IE 8, offsetLeft/Top includes the parent's border if(p){ pcs = style.getComputedStyle(p); l -= pcs.borderLeftStyle != none ? px(node, pcs.borderLeftWidth) : 0; t -= pcs.borderTopStyle != none ? px(node, pcs.borderTopWidth) : 0; } } return {l: l, t: t, w: node.offsetWidth + me.w, h: node.offsetHeight + me.h}; }; geom.getContentBox = function getContentBox(node, computedStyle){ // summary: // Returns an object that encodes the width, height, left and top // positions of the node's content box, irrespective of the // current box model. // node: DOMNode // computedStyle: Object? // This parameter accepts computed styles object. // If this parameter is omitted, the functions will call // dojo.getComputedStyle to get one. It is a better way, calling // dojo.computedStyle once, and then pass the reference to this // computedStyle parameter. Wherever possible, reuse the returned // object of dojo/dom-style.getComputedStyle(). // clientWidth/Height are important since the automatically account for scrollbars // fallback to offsetWidth/Height for special cases (see #3378) node = dom.byId(node); var s = computedStyle || style.getComputedStyle(node), w = node.clientWidth, h, pe = geom.getPadExtents(node, s), be = geom.getBorderExtents(node, s); if(!w){ w = node.offsetWidth; h = node.offsetHeight; }else{ h = node.clientHeight; be.w = be.h = 0; } // On Opera, offsetLeft includes the parent's border if(has("opera")){ pe.l += be.l; pe.t += be.t; } return {l: pe.l, t: pe.t, w: w - pe.w - be.w, h: h - pe.h - be.h}; }; // Box setters depend on box context because interpretation of width/height styles // vary wrt box context. // // The value of boxModel is used to determine box context. // boxModel can be set directly to change behavior. // // Beware of display: inline objects that have padding styles // because the user agent ignores padding (it's a bogus setup anyway) // // Be careful with IMGs because they are inline or block depending on // browser and browser mode. // // Elements other than DIV may have special quirks, like built-in // margins or padding, or values not detectable via computedStyle. // In particular, margins on TABLE do not seems to appear // at all in computedStyle on Mozilla. function setBox(/*DomNode*/ node, /*Number?*/ l, /*Number?*/ t, /*Number?*/ w, /*Number?*/ h, /*String?*/ u){ // summary: // sets width/height/left/top in the current (native) box-model // dimensions. Uses the unit passed in u. // node: // DOM Node reference. Id string not supported for performance // reasons. // l: // left offset from parent. // t: // top offset from parent. // w: // width in current box model. // h: // width in current box model. // u: // unit measure to use for other measures. Defaults to "px". u = u || "px"; var s = node.style; if(!isNaN(l)){ s.left = l + u; } if(!isNaN(t)){ s.top = t + u; } if(w >= 0){ s.width = w + u; } if(h >= 0){ s.height = h + u; } } function isButtonTag(/*DomNode*/ node){ // summary: // True if the node is BUTTON or INPUT.type="button". return node.tagName.toLowerCase() == "button" || node.tagName.toLowerCase() == "input" && (node.getAttribute("type") || "").toLowerCase() == "button"; // boolean } function usesBorderBox(/*DomNode*/ node){ // summary: // True if the node uses border-box layout. // We could test the computed style of node to see if a particular box // has been specified, but there are details and we choose not to bother. // TABLE and BUTTON (and INPUT type=button) are always border-box by default. // If you have assigned a different box to either one via CSS then // box functions will break. return geom.boxModel == "border-box" || node.tagName.toLowerCase() == "table" || isButtonTag(node); // boolean } geom.setContentSize = function setContentSize(/*DomNode*/ node, /*Object*/ box, /*Object*/ computedStyle){ // summary: // Sets the size of the node's contents, irrespective of margins, // padding, or borders. // node: DOMNode // box: Object // hash with optional "w", and "h" properties for "width", and "height" // respectively. All specified properties should have numeric values in whole pixels. // computedStyle: Object? // This parameter accepts computed styles object. // If this parameter is omitted, the functions will call // dojo.getComputedStyle to get one. It is a better way, calling // dojo.computedStyle once, and then pass the reference to this // computedStyle parameter. Wherever possible, reuse the returned // object of dojo/dom-style.getComputedStyle(). node = dom.byId(node); var w = box.w, h = box.h; if(usesBorderBox(node)){ var pb = geom.getPadBorderExtents(node, computedStyle); if(w >= 0){ w += pb.w; } if(h >= 0){ h += pb.h; } } setBox(node, NaN, NaN, w, h); }; var nilExtents = {l: 0, t: 0, w: 0, h: 0}; geom.setMarginBox = function setMarginBox(/*DomNode*/ node, /*Object*/ box, /*Object*/ computedStyle){ // summary: // sets the size of the node's margin box and placement // (left/top), irrespective of box model. Think of it as a // passthrough to setBox that handles box-model vagaries for // you. // node: DOMNode // box: Object // hash with optional "l", "t", "w", and "h" properties for "left", "right", "width", and "height" // respectively. All specified properties should have numeric values in whole pixels. // computedStyle: Object? // This parameter accepts computed styles object. // If this parameter is omitted, the functions will call // dojo.getComputedStyle to get one. It is a better way, calling // dojo.computedStyle once, and then pass the reference to this // computedStyle parameter. Wherever possible, reuse the returned // object of dojo/dom-style.getComputedStyle(). node = dom.byId(node); var s = computedStyle || style.getComputedStyle(node), w = box.w, h = box.h, // Some elements have special padding, margin, and box-model settings. // To use box functions you may need to set padding, margin explicitly. // Controlling box-model is harder, in a pinch you might set dojo/dom-geometry.boxModel. pb = usesBorderBox(node) ? nilExtents : geom.getPadBorderExtents(node, s), mb = geom.getMarginExtents(node, s); if(has("webkit")){ // on Safari (3.1.2), button nodes with no explicit size have a default margin // setting an explicit size eliminates the margin. // We have to swizzle the width to get correct margin reading. if(isButtonTag(node)){ var ns = node.style; if(w >= 0 && !ns.width){ ns.width = "4px"; } if(h >= 0 && !ns.height){ ns.height = "4px"; } } } if(w >= 0){ w = Math.max(w - pb.w - mb.w, 0); } if(h >= 0){ h = Math.max(h - pb.h - mb.h, 0); } setBox(node, box.l, box.t, w, h); }; // ============================= // Positioning // ============================= geom.isBodyLtr = function isBodyLtr(/*Document?*/ doc){ // summary: // Returns true if the current language is left-to-right, and false otherwise. // doc: Document? // Optional document to query. If unspecified, use win.doc. // returns: Boolean doc = doc || win.doc; return (win.body(doc).dir || doc.documentElement.dir || "ltr").toLowerCase() == "ltr"; // Boolean }; geom.docScroll = function docScroll(/*Document?*/ doc){ // summary: // Returns an object with {node, x, y} with corresponding offsets. // doc: Document? // Optional document to query. If unspecified, use win.doc. // returns: Object doc = doc || win.doc; var node = win.doc.parentWindow || win.doc.defaultView; // use UI window, not dojo.global window. TODO: use dojo/window::get() except for circular dependency problem return "pageXOffset" in node ? {x: node.pageXOffset, y: node.pageYOffset } : (node = has("quirks") ? win.body(doc) : doc.documentElement) && {x: geom.fixIeBiDiScrollLeft(node.scrollLeft || 0, doc), y: node.scrollTop || 0 }; }; if(has("ie")){ geom.getIeDocumentElementOffset = function getIeDocumentElementOffset(/*Document?*/ doc){ // summary: // returns the offset in x and y from the document body to the // visual edge of the page for IE // doc: Document? // Optional document to query. If unspecified, use win.doc. // description: // The following values in IE contain an offset: // | event.clientX // | event.clientY // | node.getBoundingClientRect().left // | node.getBoundingClientRect().top // But other position related values do not contain this offset, // such as node.offsetLeft, node.offsetTop, node.style.left and // node.style.top. The offset is always (2, 2) in LTR direction. // When the body is in RTL direction, the offset counts the width // of left scroll bar's width. This function computes the actual // offset. //NOTE: assumes we're being called in an IE browser doc = doc || win.doc; var de = doc.documentElement; // only deal with HTML element here, position() handles body/quirks if(has("ie") < 8){ var r = de.getBoundingClientRect(), // works well for IE6+ l = r.left, t = r.top; if(has("ie") < 7){ l += de.clientLeft; // scrollbar size in strict/RTL, or, t += de.clientTop; // HTML border size in strict } return { x: l < 0 ? 0 : l, // FRAME element border size can lead to inaccurate negative values y: t < 0 ? 0 : t }; }else{ return { x: 0, y: 0 }; } }; } geom.fixIeBiDiScrollLeft = function fixIeBiDiScrollLeft(/*Integer*/ scrollLeft, /*Document?*/ doc){ // summary: // In RTL direction, scrollLeft should be a negative value, but IE // returns a positive one. All codes using documentElement.scrollLeft // must call this function to fix this error, otherwise the position // will offset to right when there is a horizontal scrollbar. // scrollLeft: Number // doc: Document? // Optional document to query. If unspecified, use win.doc. // returns: Number // In RTL direction, scrollLeft should be a negative value, but IE // returns a positive one. All codes using documentElement.scrollLeft // must call this function to fix this error, otherwise the position // will offset to right when there is a horizontal scrollbar. doc = doc || win.doc; var ie = has("ie"); if(ie && !geom.isBodyLtr(doc)){ var qk = has("quirks"), de = qk ? win.body(doc) : doc.documentElement, pwin = win.global; // TODO: use winUtils.get(doc) after resolving circular dependency b/w dom-geometry.js and dojo/window.js if(ie == 6 && !qk && pwin.frameElement && de.scrollHeight > de.clientHeight){ scrollLeft += de.clientLeft; // workaround ie6+strict+rtl+iframe+vertical-scrollbar bug where clientWidth is too small by clientLeft pixels } return (ie < 8 || qk) ? (scrollLeft + de.clientWidth - de.scrollWidth) : -scrollLeft; // Integer } return scrollLeft; // Integer }; geom.position = function(/*DomNode*/ node, /*Boolean?*/ includeScroll){ // summary: // Gets the position and size of the passed element relative to // the viewport (if includeScroll==false), or relative to the // document root (if includeScroll==true). // // description: // Returns an object of the form: // `{ x: 100, y: 300, w: 20, h: 15 }`. // If includeScroll==true, the x and y values will include any // document offsets that may affect the position relative to the // viewport. // Uses the border-box model (inclusive of border and padding but // not margin). Does not act as a setter. // node: DOMNode|String // includeScroll: Boolean? // returns: Object node = dom.byId(node); var db = win.body(node.ownerDocument), ret = node.getBoundingClientRect(); ret = {x: ret.left, y: ret.top, w: ret.right - ret.left, h: ret.bottom - ret.top}; if(has("ie")){ // On IE there's a 2px offset that we need to adjust for, see dojo.getIeDocumentElementOffset() var offset = geom.getIeDocumentElementOffset(node.ownerDocument); // fixes the position in IE, quirks mode ret.x -= offset.x + (has("quirks") ? db.clientLeft + db.offsetLeft : 0); ret.y -= offset.y + (has("quirks") ? db.clientTop + db.offsetTop : 0); } // account for document scrolling // if offsetParent is used, ret value already includes scroll position // so we may have to actually remove that value if !includeScroll if(includeScroll){ var scroll = geom.docScroll(node.ownerDocument); ret.x += scroll.x; ret.y += scroll.y; } return ret; // Object }; // random "private" functions wildly used throughout the toolkit geom.getMarginSize = function getMarginSize(/*DomNode*/ node, /*Object*/ computedStyle){ // summary: // returns an object that encodes the width and height of // the node's margin box // node: DOMNode|String // computedStyle: Object? // This parameter accepts computed styles object. // If this parameter is omitted, the functions will call // dojo.getComputedStyle to get one. It is a better way, calling // dojo.computedStyle once, and then pass the reference to this // computedStyle parameter. Wherever possible, reuse the returned // object of dojo/dom-style.getComputedStyle(). node = dom.byId(node); var me = geom.getMarginExtents(node, computedStyle || style.getComputedStyle(node)); var size = node.getBoundingClientRect(); return { w: (size.right - size.left) + me.w, h: (size.bottom - size.top) + me.h }; }; geom.normalizeEvent = function(event){ // summary: // Normalizes the geometry of a DOM event, normalizing the pageX, pageY, // offsetX, offsetY, layerX, and layerX properties // event: Object if(!("layerX" in event)){ event.layerX = event.offsetX; event.layerY = event.offsetY; } if(!has("dom-addeventlistener")){ // old IE version // FIXME: scroll position query is duped from dojo.html to // avoid dependency on that entire module. Now that HTML is in // Base, we should convert back to something similar there. var se = event.target; var doc = (se && se.ownerDocument) || document; // DO NOT replace the following to use dojo.body(), in IE, document.documentElement should be used // here rather than document.body var docBody = has("quirks") ? doc.body : doc.documentElement; var offset = geom.getIeDocumentElementOffset(doc); event.pageX = event.clientX + geom.fixIeBiDiScrollLeft(docBody.scrollLeft || 0, doc) - offset.x; event.pageY = event.clientY + (docBody.scrollTop || 0) - offset.y; } }; // TODO: evaluate separate getters/setters for position and sizes? return geom; }); }, 'dojo/dom-style':function(){ define("dojo/dom-style", ["./sniff", "./dom"], function(has, dom){ // module: // dojo/dom-style // ============================= // Style Functions // ============================= // getComputedStyle drives most of the style code. // Wherever possible, reuse the returned object. // // API functions below that need to access computed styles accept an // optional computedStyle parameter. // If this parameter is omitted, the functions will call getComputedStyle themselves. // This way, calling code can access computedStyle once, and then pass the reference to // multiple API functions. // Although we normally eschew argument validation at this // level, here we test argument 'node' for (duck)type, // by testing nodeType, ecause 'document' is the 'parentNode' of 'body' // it is frequently sent to this function even // though it is not Element. var getComputedStyle, style = { // summary: // This module defines the core dojo DOM style API. }; if(has("webkit")){ getComputedStyle = function(/*DomNode*/ node){ var s; if(node.nodeType == 1){ var dv = node.ownerDocument.defaultView; s = dv.getComputedStyle(node, null); if(!s && node.style){ node.style.display = ""; s = dv.getComputedStyle(node, null); } } return s || {}; }; }else if(has("ie") && (has("ie") < 9 || has("quirks"))){ getComputedStyle = function(node){ // IE (as of 7) doesn't expose Element like sane browsers // currentStyle can be null on IE8! return node.nodeType == 1 /* ELEMENT_NODE*/ && node.currentStyle ? node.currentStyle : {}; }; }else{ getComputedStyle = function(node){ return node.nodeType == 1 /* ELEMENT_NODE*/ ? node.ownerDocument.defaultView.getComputedStyle(node, null) : {}; }; } style.getComputedStyle = getComputedStyle; /*===== style.getComputedStyle = function(node){ // summary: // Returns a "computed style" object. // // description: // Gets a "computed style" object which can be used to gather // information about the current state of the rendered node. // // Note that this may behave differently on different browsers. // Values may have different formats and value encodings across // browsers. // // Note also that this method is expensive. Wherever possible, // reuse the returned object. // // Use the dojo.style() method for more consistent (pixelized) // return values. // // node: DOMNode // A reference to a DOM node. Does NOT support taking an // ID string for speed reasons. // example: // | dojo.getComputedStyle(dojo.byId('foo')).borderWidth; // // example: // Reusing the returned object, avoiding multiple lookups: // | var cs = dojo.getComputedStyle(dojo.byId("someNode")); // | var w = cs.width, h = cs.height; return; // CSS2Properties }; =====*/ var toPixel; if(!has("ie")){ toPixel = function(element, value){ // style values can be floats, client code may want // to round for integer pixels. return parseFloat(value) || 0; }; }else{ toPixel = function(element, avalue){ if(!avalue){ return 0; } // on IE7, medium is usually 4 pixels if(avalue == "medium"){ return 4; } // style values can be floats, client code may // want to round this value for integer pixels. if(avalue.slice && avalue.slice(-2) == 'px'){ return parseFloat(avalue); } var s = element.style, rs = element.runtimeStyle, cs = element.currentStyle, sLeft = s.left, rsLeft = rs.left; rs.left = cs.left; try{ // 'avalue' may be incompatible with style.left, which can cause IE to throw // this has been observed for border widths using "thin", "medium", "thick" constants // those particular constants could be trapped by a lookup // but perhaps there are more s.left = avalue; avalue = s.pixelLeft; }catch(e){ avalue = 0; } s.left = sLeft; rs.left = rsLeft; return avalue; }; } style.toPixelValue = toPixel; /*===== style.toPixelValue = function(node, value){ // summary: // converts style value to pixels on IE or return a numeric value. // node: DOMNode // value: String // returns: Number }; =====*/ // FIXME: there opacity quirks on FF that we haven't ported over. Hrm. var astr = "DXImageTransform.Microsoft.Alpha"; var af = function(n, f){ try{ return n.filters.item(astr); }catch(e){ return f ? {} : null; } }; var _getOpacity = has("ie") < 9 || (has("ie") && has("quirks")) ? function(node){ try{ return af(node).Opacity / 100; // Number }catch(e){ return 1; // Number } } : function(node){ return getComputedStyle(node).opacity; }; var _setOpacity = has("ie") < 9 || (has("ie") && has("quirks")) ? function(/*DomNode*/ node, /*Number*/ opacity){ var ov = opacity * 100, opaque = opacity == 1; node.style.zoom = opaque ? "" : 1; if(!af(node)){ if(opaque){ return opacity; } node.style.filter += " progid:" + astr + "(Opacity=" + ov + ")"; }else{ af(node, 1).Opacity = ov; } // on IE7 Alpha(Filter opacity=100) makes text look fuzzy so disable it altogether (bug #2661), //but still update the opacity value so we can get a correct reading if it is read later. af(node, 1).Enabled = !opaque; if(node.tagName.toLowerCase() == "tr"){ for(var td = node.firstChild; td; td = td.nextSibling){ if(td.tagName.toLowerCase() == "td"){ _setOpacity(td, opacity); } } } return opacity; } : function(node, opacity){ return node.style.opacity = opacity; }; var _pixelNamesCache = { left: true, top: true }; var _pixelRegExp = /margin|padding|width|height|max|min|offset/; // |border function _toStyleValue(node, type, value){ //TODO: should we really be doing string case conversion here? Should we cache it? Need to profile! type = type.toLowerCase(); if(has("ie")){ if(value == "auto"){ if(type == "height"){ return node.offsetHeight; } if(type == "width"){ return node.offsetWidth; } } if(type == "fontweight"){ switch(value){ case 700: return "bold"; case 400: default: return "normal"; } } } if(!(type in _pixelNamesCache)){ _pixelNamesCache[type] = _pixelRegExp.test(type); } return _pixelNamesCache[type] ? toPixel(node, value) : value; } var _floatStyle = has("ie") ? "styleFloat" : "cssFloat", _floatAliases = {"cssFloat": _floatStyle, "styleFloat": _floatStyle, "float": _floatStyle}; // public API style.get = function getStyle(/*DOMNode|String*/ node, /*String?*/ name){ // summary: // Accesses styles on a node. // description: // Getting the style value uses the computed style for the node, so the value // will be a calculated value, not just the immediate node.style value. // Also when getting values, use specific style names, // like "borderBottomWidth" instead of "border" since compound values like // "border" are not necessarily reflected as expected. // If you want to get node dimensions, use `dojo.marginBox()`, // `dojo.contentBox()` or `dojo.position()`. // node: DOMNode|String // id or reference to node to get style for // name: String? // the style property to get // example: // Passing only an ID or node returns the computed style object of // the node: // | dojo.getStyle("thinger"); // example: // Passing a node and a style property returns the current // normalized, computed value for that property: // | dojo.getStyle("thinger", "opacity"); // 1 by default var n = dom.byId(node), l = arguments.length, op = (name == "opacity"); if(l == 2 && op){ return _getOpacity(n); } name = _floatAliases[name] || name; var s = style.getComputedStyle(n); return (l == 1) ? s : _toStyleValue(n, name, s[name] || n.style[name]); /* CSS2Properties||String||Number */ }; style.set = function setStyle(/*DOMNode|String*/ node, /*String|Object*/ name, /*String?*/ value){ // summary: // Sets styles on a node. // node: DOMNode|String // id or reference to node to set style for // name: String|Object // the style property to set in DOM-accessor format // ("borderWidth", not "border-width") or an object with key/value // pairs suitable for setting each property. // value: String? // If passed, sets value on the node for style, handling // cross-browser concerns. When setting a pixel value, // be sure to include "px" in the value. For instance, top: "200px". // Otherwise, in some cases, some browsers will not apply the style. // // example: // Passing a node, a style property, and a value changes the // current display of the node and returns the new computed value // | dojo.setStyle("thinger", "opacity", 0.5); // == 0.5 // // example: // Passing a node, an object-style style property sets each of the values in turn and returns the computed style object of the node: // | dojo.setStyle("thinger", { // | "opacity": 0.5, // | "border": "3px solid black", // | "height": "300px" // | }); // // example: // When the CSS style property is hyphenated, the JavaScript property is camelCased. // font-size becomes fontSize, and so on. // | dojo.setStyle("thinger",{ // | fontSize:"14pt", // | letterSpacing:"1.2em" // | }); // // example: // dojo/NodeList implements .style() using the same syntax, omitting the "node" parameter, calling // dojo.style() on every element of the list. See: `dojo.query()` and `dojo/NodeList` // | dojo.query(".someClassName").style("visibility","hidden"); // | // or // | dojo.query("#baz > div").style({ // | opacity:0.75, // | fontSize:"13pt" // | }); var n = dom.byId(node), l = arguments.length, op = (name == "opacity"); name = _floatAliases[name] || name; if(l == 3){ return op ? _setOpacity(n, value) : n.style[name] = value; // Number } for(var x in name){ style.set(node, x, name[x]); } return style.getComputedStyle(n); }; return style; }); }, 'dojo/dom-prop':function(){ define(["exports", "./_base/kernel", "./sniff", "./_base/lang", "./dom", "./dom-style", "./dom-construct", "./_base/connect"], function(exports, dojo, has, lang, dom, style, ctr, conn){ // module: // dojo/dom-prop // summary: // This module defines the core dojo DOM properties API. // Indirectly depends on dojo.empty() and dojo.toDom(). // TODOC: summary not showing up in output, see https://github.com/csnover/js-doc-parse/issues/42 // ============================= // Element properties Functions // ============================= // helper to connect events var _evtHdlrMap = {}, _ctr = 0, _attrId = dojo._scopeName + "attrid"; exports.names = { // properties renamed to avoid clashes with reserved words "class": "className", "for": "htmlFor", // properties written as camelCase tabindex: "tabIndex", readonly: "readOnly", colspan: "colSpan", frameborder: "frameBorder", rowspan: "rowSpan", valuetype: "valueType" }; exports.get = function getProp(/*DOMNode|String*/ node, /*String*/ name){ // summary: // Gets a property on an HTML element. // description: // Handles normalized getting of properties on DOM nodes. // // node: DOMNode|String // id or reference to the element to get the property on // name: String // the name of the property to get. // returns: // the value of the requested property or its default value // // example: // | // get the current value of the "foo" property on a node // | dojo.getProp(dojo.byId("nodeId"), "foo"); // | // or we can just pass the id: // | dojo.getProp("nodeId", "foo"); node = dom.byId(node); var lc = name.toLowerCase(), propName = exports.names[lc] || name; return node[propName]; // Anything }; exports.set = function setProp(/*DOMNode|String*/ node, /*String|Object*/ name, /*String?*/ value){ // summary: // Sets a property on an HTML element. // description: // Handles normalized setting of properties on DOM nodes. // // When passing functions as values, note that they will not be // directly assigned to slots on the node, but rather the default // behavior will be removed and the new behavior will be added // using `dojo.connect()`, meaning that event handler properties // will be normalized and that some caveats with regards to // non-standard behaviors for onsubmit apply. Namely that you // should cancel form submission using `dojo.stopEvent()` on the // passed event object instead of returning a boolean value from // the handler itself. // node: DOMNode|String // id or reference to the element to set the property on // name: String|Object // the name of the property to set, or a hash object to set // multiple properties at once. // value: String? // The value to set for the property // returns: // the DOM node // // example: // | // use prop() to set the tab index // | dojo.setProp("nodeId", "tabIndex", 3); // | // // example: // Set multiple values at once, including event handlers: // | dojo.setProp("formId", { // | "foo": "bar", // | "tabIndex": -1, // | "method": "POST", // | "onsubmit": function(e){ // | // stop submitting the form. Note that the IE behavior // | // of returning true or false will have no effect here // | // since our handler is connect()ed to the built-in // | // onsubmit behavior and so we need to use // | // dojo.stopEvent() to ensure that the submission // | // doesn't proceed. // | dojo.stopEvent(e); // | // | // submit the form with Ajax // | dojo.xhrPost({ form: "formId" }); // | } // | }); // // example: // Style is s special case: Only set with an object hash of styles // | dojo.setProp("someNode",{ // | id:"bar", // | style:{ // | width:"200px", height:"100px", color:"#000" // | } // | }); // // example: // Again, only set style as an object hash of styles: // | var obj = { color:"#fff", backgroundColor:"#000" }; // | dojo.setProp("someNode", "style", obj); // | // | // though shorter to use `dojo.style()` in this case: // | dojo.style("someNode", obj); node = dom.byId(node); var l = arguments.length; if(l == 2 && typeof name != "string"){ // inline'd type check // the object form of setter: the 2nd argument is a dictionary for(var x in name){ exports.set(node, x, name[x]); } return node; // DomNode } var lc = name.toLowerCase(), propName = exports.names[lc] || name; if(propName == "style" && typeof value != "string"){ // inline'd type check // special case: setting a style style.set(node, value); return node; // DomNode } if(propName == "innerHTML"){ // special case: assigning HTML // the hash lists elements with read-only innerHTML on IE if(has("ie") && node.tagName.toLowerCase() in {col: 1, colgroup: 1, table: 1, tbody: 1, tfoot: 1, thead: 1, tr: 1, title: 1}){ ctr.empty(node); node.appendChild(ctr.toDom(value, node.ownerDocument)); }else{ node[propName] = value; } return node; // DomNode } if(lang.isFunction(value)){ // special case: assigning an event handler // clobber if we can var attrId = node[_attrId]; if(!attrId){ attrId = _ctr++; node[_attrId] = attrId; } if(!_evtHdlrMap[attrId]){ _evtHdlrMap[attrId] = {}; } var h = _evtHdlrMap[attrId][propName]; if(h){ //h.remove(); conn.disconnect(h); }else{ try{ delete node[propName]; }catch(e){} } // ensure that event objects are normalized, etc. if(value){ //_evtHdlrMap[attrId][propName] = on(node, propName, value); _evtHdlrMap[attrId][propName] = conn.connect(node, propName, value); }else{ node[propName] = null; } return node; // DomNode } node[propName] = value; return node; // DomNode }; }); }, 'dojo/when':function(){ define([ "./Deferred", "./promise/Promise" ], function(Deferred, Promise){ "use strict"; // module: // dojo/when return function when(valueOrPromise, callback, errback, progback){ // summary: // Transparently applies callbacks to values and/or promises. // description: // Accepts promises but also transparently handles non-promises. If no // callbacks are provided returns a promise, regardless of the initial // value. Foreign promises are converted. // // If callbacks are provided and the initial value is not a promise, // the callback is executed immediately with no error handling. Returns // a promise if the initial value is a promise, or the result of the // callback otherwise. // valueOrPromise: // Either a regular value or an object with a `then()` method that // follows the Promises/A specification. // callback: Function? // Callback to be invoked when the promise is resolved, or a non-promise // is received. // errback: Function? // Callback to be invoked when the promise is rejected. // progback: Function? // Callback to be invoked when the promise emits a progress update. // returns: dojo/promise/Promise // Promise, or if a callback is provided, the result of the callback. var receivedPromise = valueOrPromise && typeof valueOrPromise.then === "function"; var nativePromise = receivedPromise && valueOrPromise instanceof Promise; if(!receivedPromise){ if(callback){ return callback(valueOrPromise); }else{ return new Deferred().resolve(valueOrPromise); } }else if(!nativePromise){ var deferred = new Deferred(valueOrPromise.cancel); valueOrPromise.then(deferred.resolve, deferred.reject, deferred.progress); valueOrPromise = deferred.promise; } if(callback || errback || progback){ return valueOrPromise.then(callback, errback, progback); } return valueOrPromise; }; }); }, 'dojo/dom-attr':function(){ define(["exports", "./sniff", "./_base/lang", "./dom", "./dom-style", "./dom-prop"], function(exports, has, lang, dom, style, prop){ // module: // dojo/dom-attr // summary: // This module defines the core dojo DOM attributes API. // TODOC: summary not showing up in output see https://github.com/csnover/js-doc-parse/issues/42 // ============================= // Element attribute Functions // ============================= // This module will be obsolete soon. Use dojo/prop instead. // dojo.attr() should conform to http://www.w3.org/TR/DOM-Level-2-Core/ // attribute-related functions (to be obsolete soon) var forcePropNames = { innerHTML: 1, className: 1, htmlFor: has("ie"), value: 1 }, attrNames = { // original attribute names classname: "class", htmlfor: "for", // for IE tabindex: "tabIndex", readonly: "readOnly" }; function _hasAttr(node, name){ var attr = node.getAttributeNode && node.getAttributeNode(name); return attr && attr.specified; // Boolean } // There is a difference in the presence of certain properties and their default values // between browsers. For example, on IE "disabled" is present on all elements, // but it is value is "false"; "tabIndex" of
returns 0 by default on IE, yet other browsers // can return -1. exports.has = function hasAttr(/*DOMNode|String*/ node, /*String*/ name){ // summary: // Returns true if the requested attribute is specified on the // given element, and false otherwise. // node: DOMNode|String // id or reference to the element to check // name: String // the name of the attribute // returns: Boolean // true if the requested attribute is specified on the // given element, and false otherwise var lc = name.toLowerCase(); return forcePropNames[prop.names[lc] || name] || _hasAttr(dom.byId(node), attrNames[lc] || name); // Boolean }; exports.get = function getAttr(/*DOMNode|String*/ node, /*String*/ name){ // summary: // Gets an attribute on an HTML element. // description: // Handles normalized getting of attributes on DOM Nodes. // node: DOMNode|String // id or reference to the element to get the attribute on // name: String // the name of the attribute to get. // returns: // the value of the requested attribute or null if that attribute does not have a specified or // default value; // // example: // | // get the current value of the "foo" attribute on a node // | dojo.getAttr(dojo.byId("nodeId"), "foo"); // | // or we can just pass the id: // | dojo.getAttr("nodeId", "foo"); node = dom.byId(node); var lc = name.toLowerCase(), propName = prop.names[lc] || name, forceProp = forcePropNames[propName], value = node[propName]; // should we access this attribute via a property or via getAttribute()? if(forceProp && typeof value != "undefined"){ // node's property return value; // Anything } if(propName != "href" && (typeof value == "boolean" || lang.isFunction(value))){ // node's property return value; // Anything } // node's attribute // we need _hasAttr() here to guard against IE returning a default value var attrName = attrNames[lc] || name; return _hasAttr(node, attrName) ? node.getAttribute(attrName) : null; // Anything }; exports.set = function setAttr(/*DOMNode|String*/ node, /*String|Object*/ name, /*String?*/ value){ // summary: // Sets an attribute on an HTML element. // description: // Handles normalized setting of attributes on DOM Nodes. // // When passing functions as values, note that they will not be // directly assigned to slots on the node, but rather the default // behavior will be removed and the new behavior will be added // using `dojo.connect()`, meaning that event handler properties // will be normalized and that some caveats with regards to // non-standard behaviors for onsubmit apply. Namely that you // should cancel form submission using `dojo.stopEvent()` on the // passed event object instead of returning a boolean value from // the handler itself. // node: DOMNode|String // id or reference to the element to set the attribute on // name: String|Object // the name of the attribute to set, or a hash of key-value pairs to set. // value: String? // the value to set for the attribute, if the name is a string. // returns: // the DOM node // // example: // | // use attr() to set the tab index // | dojo.setAttr("nodeId", "tabIndex", 3); // // example: // Set multiple values at once, including event handlers: // | dojo.setAttr("formId", { // | "foo": "bar", // | "tabIndex": -1, // | "method": "POST", // | "onsubmit": function(e){ // | // stop submitting the form. Note that the IE behavior // | // of returning true or false will have no effect here // | // since our handler is connect()ed to the built-in // | // onsubmit behavior and so we need to use // | // dojo.stopEvent() to ensure that the submission // | // doesn't proceed. // | dojo.stopEvent(e); // | // | // submit the form with Ajax // | dojo.xhrPost({ form: "formId" }); // | } // | }); // // example: // Style is s special case: Only set with an object hash of styles // | dojo.setAttr("someNode",{ // | id:"bar", // | style:{ // | width:"200px", height:"100px", color:"#000" // | } // | }); // // example: // Again, only set style as an object hash of styles: // | var obj = { color:"#fff", backgroundColor:"#000" }; // | dojo.setAttr("someNode", "style", obj); // | // | // though shorter to use `dojo.style()` in this case: // | dojo.setStyle("someNode", obj); node = dom.byId(node); if(arguments.length == 2){ // inline'd type check // the object form of setter: the 2nd argument is a dictionary for(var x in name){ exports.set(node, x, name[x]); } return node; // DomNode } var lc = name.toLowerCase(), propName = prop.names[lc] || name, forceProp = forcePropNames[propName]; if(propName == "style" && typeof value != "string"){ // inline'd type check // special case: setting a style style.set(node, value); return node; // DomNode } if(forceProp || typeof value == "boolean" || lang.isFunction(value)){ return prop.set(node, name, value); } // node's attribute node.setAttribute(attrNames[lc] || name, value); return node; // DomNode }; exports.remove = function removeAttr(/*DOMNode|String*/ node, /*String*/ name){ // summary: // Removes an attribute from an HTML element. // node: DOMNode|String // id or reference to the element to remove the attribute from // name: String // the name of the attribute to remove dom.byId(node).removeAttribute(attrNames[name.toLowerCase()] || name); }; exports.getNodeProp = function getNodeProp(/*DomNode|String*/ node, /*String*/ name){ // summary: // Returns an effective value of a property or an attribute. // node: DOMNode|String // id or reference to the element to remove the attribute from // name: String // the name of the attribute // returns: // the value of the attribute node = dom.byId(node); var lc = name.toLowerCase(), propName = prop.names[lc] || name; if((propName in node) && propName != "href"){ // node's property return node[propName]; // Anything } // node's attribute var attrName = attrNames[lc] || name; return _hasAttr(node, attrName) ? node.getAttribute(attrName) : null; // Anything }; }); }, 'dojo/dom-construct':function(){ define(["exports", "./_base/kernel", "./sniff", "./_base/window", "./dom", "./dom-attr", "./on"], function(exports, dojo, has, win, dom, attr, on){ // module: // dojo/dom-construct // summary: // This module defines the core dojo DOM construction API. // TODOC: summary not showing up in output, see https://github.com/csnover/js-doc-parse/issues/42 // support stuff for toDom() var tagWrap = { option: ["select"], tbody: ["table"], thead: ["table"], tfoot: ["table"], tr: ["table", "tbody"], td: ["table", "tbody", "tr"], th: ["table", "thead", "tr"], legend: ["fieldset"], caption: ["table"], colgroup: ["table"], col: ["table", "colgroup"], li: ["ul"] }, reTag = /<\s*([\w\:]+)/, masterNode = {}, masterNum = 0, masterName = "__" + dojo._scopeName + "ToDomId"; // generate start/end tag strings to use // for the injection for each special tag wrap case. for(var param in tagWrap){ if(tagWrap.hasOwnProperty(param)){ var tw = tagWrap[param]; tw.pre = param == "option" ? '"; all = div.getElementsByTagName( "*" ); a = div.getElementsByTagName( "a" )[ 0 ]; // Can't get basic test support if ( !all || !all.length || !a ) { return {}; } // First batch of supports tests select = document.createElement( "select" ); opt = select.appendChild( document.createElement("option") ); input = div.getElementsByTagName( "input" )[ 0 ]; support = { // IE strips leading whitespace when .innerHTML is used leadingWhitespace: ( div.firstChild.nodeType === 3 ), // Make sure that tbody elements aren't automatically inserted // IE will insert them into empty tables tbody: !div.getElementsByTagName("tbody").length, // Make sure that link elements get serialized correctly by innerHTML // This requires a wrapper element in IE htmlSerialize: !!div.getElementsByTagName("link").length, // Get the style information from getAttribute // (IE uses .cssText instead) style: /top/.test( a.getAttribute("style") ), // Make sure that URLs aren't manipulated // (IE normalizes it by default) 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 opacity: /^0.55/.test( a.style.opacity ), // Verify style float existence // (IE uses styleFloat instead of cssFloat) cssFloat: !!a.style.cssFloat, // Make sure that if no value is specified for a checkbox // that it defaults to "on". // (WebKit defaults to "" instead) checkOn: ( input.value === "on" ), // 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) optSelected: opt.selected, // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7) getSetAttribute: div.className !== "t", // Tests for enctype support on a form(#6743) enctype: !!document.createElement("form").enctype, // Makes sure cloning an html5 element does not cause problems // Where outerHTML is undefined, this still works html5Clone: document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav>", // Will be defined later submitBubbles: true, changeBubbles: true, focusinBubbles: false, deleteExpando: true, noCloneEvent: true, inlineBlockNeedsLayout: false, shrinkWrapBlocks: false, reliableMarginRight: true, pixelMargin: true }; // jQuery.boxModel DEPRECATED in 1.3, use jQuery.support.boxModel instead jQuery.boxModel = support.boxModel = (document.compatMode === "CSS1Compat"); // 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; // Test to see if it's possible to delete an expando from an element // Fails in Internet Explorer try { delete div.test; } catch( e ) { support.deleteExpando = false; } if ( !div.addEventListener && div.attachEvent && div.fireEvent ) { div.attachEvent( "onclick", function() { // Cloning a node shouldn't copy over any // bound event handlers (IE does this) support.noCloneEvent = false; }); div.cloneNode( true ).fireEvent( "onclick" ); } // Check if a radio maintains its value // after being appended to the DOM input = document.createElement("input"); input.value = "t"; input.setAttribute("type", "radio"); support.radioValue = input.value === "t"; input.setAttribute("checked", "checked"); // #11217 - WebKit loses check when the name is after the checked attribute input.setAttribute( "name", "t" ); div.appendChild( input ); fragment = document.createDocumentFragment(); fragment.appendChild( div.lastChild ); // WebKit doesn't clone checked state correctly in fragments support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked; // Check if a disconnected checkbox will retain its checked // value of true after appended to the DOM (IE6/7) support.appendChecked = input.checked; fragment.removeChild( input ); fragment.appendChild( div ); // Technique from Juriy Zaytsev // http://perfectionkills.com/detecting-event-support-without-browser-sniffing/ // We only care about the case where non-standard event systems // are used, namely in IE. Short-circuiting here helps us to // avoid an eval call (in setAttribute) which can cause CSP // to go haywire. See: https://developer.mozilla.org/en/Security/CSP if ( div.attachEvent ) { for ( i in { submit: 1, change: 1, focusin: 1 }) { eventName = "on" + i; isSupported = ( eventName in div ); if ( !isSupported ) { div.setAttribute( eventName, "return;" ); isSupported = ( typeof div[ eventName ] === "function" ); } support[ i + "Bubbles" ] = isSupported; } } fragment.removeChild( div ); // Null elements to avoid leaks in IE fragment = select = opt = div = input = null; // Run tests that need a body at doc ready jQuery(function() { var container, outer, inner, table, td, offsetSupport, marginDiv, conMarginTop, style, html, positionTopLeftWidthHeight, paddingMarginBorderVisibility, paddingMarginBorder, body = document.getElementsByTagName("body")[0]; if ( !body ) { // Return for frameset docs that don't have a body return; } conMarginTop = 1; paddingMarginBorder = "padding:0;margin:0;border:"; positionTopLeftWidthHeight = "position:absolute;top:0;left:0;width:1px;height:1px;"; paddingMarginBorderVisibility = paddingMarginBorder + "0;visibility:hidden;"; style = "style='" + positionTopLeftWidthHeight + paddingMarginBorder + "5px solid #000;"; html = "
" + "" + "
"; container = document.createElement("div"); container.style.cssText = paddingMarginBorderVisibility + "width:0;height:0;position:static;top:0;margin-top:" + conMarginTop + "px"; body.insertBefore( container, body.firstChild ); // Construct the test element div = document.createElement("div"); container.appendChild( div ); // 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). // (only IE 8 fails this test) div.innerHTML = "
t
"; tds = div.getElementsByTagName( "td" ); isSupported = ( tds[ 0 ].offsetHeight === 0 ); tds[ 0 ].style.display = ""; tds[ 1 ].style.display = "none"; // Check if empty table cells still have offsetWidth/Height // (IE <= 8 fail this test) support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 ); // Check if div with explicit width and no margin-right incorrectly // gets computed margin-right based on width of container. For more // info see bug #3333 // Fails in WebKit before Feb 2011 nightlies // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right if ( window.getComputedStyle ) { div.innerHTML = ""; marginDiv = document.createElement( "div" ); marginDiv.style.width = "0"; marginDiv.style.marginRight = "0"; div.style.width = "2px"; div.appendChild( marginDiv ); support.reliableMarginRight = ( parseInt( ( window.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0; } if ( typeof div.style.zoom !== "undefined" ) { // Check if natively block-level elements act like inline-block // elements when setting their display to 'inline' and giving // them layout // (IE < 8 does this) div.innerHTML = ""; div.style.width = div.style.padding = "1px"; div.style.border = 0; div.style.overflow = "hidden"; div.style.display = "inline"; div.style.zoom = 1; support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 ); // Check if elements with layout shrink-wrap their children // (IE 6 does this) div.style.display = "block"; div.style.overflow = "visible"; div.innerHTML = "
"; support.shrinkWrapBlocks = ( div.offsetWidth !== 3 ); } div.style.cssText = positionTopLeftWidthHeight + paddingMarginBorderVisibility; div.innerHTML = html; outer = div.firstChild; inner = outer.firstChild; td = outer.nextSibling.firstChild.firstChild; offsetSupport = { doesNotAddBorder: ( inner.offsetTop !== 5 ), doesAddBorderForTableAndCells: ( td.offsetTop === 5 ) }; inner.style.position = "fixed"; inner.style.top = "20px"; // safari subtracts parent border width here which is 5px offsetSupport.fixedPosition = ( inner.offsetTop === 20 || inner.offsetTop === 15 ); inner.style.position = inner.style.top = ""; outer.style.overflow = "hidden"; outer.style.position = "relative"; offsetSupport.subtractsBorderForOverflowNotVisible = ( inner.offsetTop === -5 ); offsetSupport.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== conMarginTop ); if ( window.getComputedStyle ) { div.style.marginTop = "1%"; support.pixelMargin = ( window.getComputedStyle( div, null ) || { marginTop: 0 } ).marginTop !== "1%"; } if ( typeof container.style.zoom !== "undefined" ) { container.style.zoom = 1; } body.removeChild( container ); marginDiv = div = container = null; jQuery.extend( support, offsetSupport ); }); return support; })(); var rbrace = /^(?:\{.*\}|\[.*\])$/, rmultiDash = /([A-Z])/g; jQuery.extend({ cache: {}, // Please use with caution uuid: 0, // Unique for each copy of jQuery on the page // Non-digits removed to match rinlinejQuery expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ), // The following elements throw uncatchable exceptions if you // attempt to add expando properties to them. noData: { "embed": true, // Ban all objects except for Flash (which handle expandos) "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000", "applet": true }, hasData: function( elem ) { elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; return !!elem && !isEmptyDataObject( elem ); }, data: function( elem, name, data, pvt /* Internal Use Only */ ) { if ( !jQuery.acceptData( elem ) ) { return; } var privateCache, thisCache, ret, internalKey = jQuery.expando, getByName = typeof name === "string", // 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, isEvents = name === "events"; // 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] || (!isEvents && !pvt && !cache[id].data)) && getByName && data === undefined ) { 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 ) { elem[ internalKey ] = id = ++jQuery.uuid; } else { id = internalKey; } } if ( !cache[ id ] ) { cache[ id ] = {}; // Avoids exposing jQuery metadata on plain JS objects when the object // is serialized using JSON.stringify if ( !isNode ) { cache[ id ].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 ); } } privateCache = 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; } // Users should not attempt to inspect the internal events object using jQuery.data, // it is undocumented and subject to change. But does anyone listen? No. if ( isEvents && !thisCache[ name ] ) { return privateCache.events; } // Check for both converted-to-camel and non-converted data property names // If a data property was specified if ( getByName ) { // 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; }, removeData: function( elem, name, pvt /* Internal Use Only */ ) { if ( !jQuery.acceptData( elem ) ) { return; } var thisCache, i, l, // Reference to internal data cache key internalKey = jQuery.expando, isNode = elem.nodeType, // See jQuery.data for more information cache = isNode ? jQuery.cache : elem, // See jQuery.data for more information id = isNode ? elem[ internalKey ] : internalKey; // 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( " " ); } } } for ( i = 0, l = name.length; i < l; 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 : 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; } } // Browsers that fail expando deletion also refuse to delete expandos on // the window, but it will allow it on all other JS objects; other browsers // don't care // Ensure that `cache` is not a window object #10080 if ( jQuery.support.deleteExpando || !cache.setInterval ) { delete cache[ id ]; } else { cache[ id ] = null; } // We destroyed the cache and need to eliminate the expando on the node to avoid // false lookups in the cache for entries that no longer exist if ( isNode ) { // 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 ( jQuery.support.deleteExpando ) { delete elem[ internalKey ]; } else if ( elem.removeAttribute ) { elem.removeAttribute( internalKey ); } else { elem[ internalKey ] = null; } } }, // For internal use only. _data: function( elem, name, data ) { return jQuery.data( elem, name, data, true ); }, // A method for determining if a DOM node can handle the data expando acceptData: function( elem ) { if ( elem.nodeName ) { var match = jQuery.noData[ elem.nodeName.toLowerCase() ]; if ( match ) { return !(match === true || elem.getAttribute("classid") !== match); } } return true; } }); jQuery.fn.extend({ data: function( key, value ) { var parts, part, attr, name, l, elem = this[0], i = 0, data = null; // Gets all values if ( key === undefined ) { if ( this.length ) { data = jQuery.data( elem ); if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) { attr = elem.attributes; for ( l = attr.length; i < l; i++ ) { name = attr[i].name; if ( name.indexOf( "data-" ) === 0 ) { name = jQuery.camelCase( name.substring(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 ); }); } parts = key.split( ".", 2 ); parts[1] = parts[1] ? "." + parts[1] : ""; part = parts[1] + "!"; return jQuery.access( this, function( value ) { if ( value === undefined ) { data = this.triggerHandler( "getData" + part, [ parts[0] ] ); // Try to fetch any internally stored data first if ( data === undefined && elem ) { data = jQuery.data( elem, key ); data = dataAttr( elem, key, data ); } return data === undefined && parts[1] ? this.data( parts[0] ) : data; } parts[1] = value; this.each(function() { var self = jQuery( this ); self.triggerHandler( "setData" + part, parts ); jQuery.data( this, key, value ); self.triggerHandler( "changeData" + part, parts ); }); }, null, value, arguments.length > 1, null, false ); }, 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 : jQuery.isNumeric( 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 ) { for ( var 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; } function handleQueueMarkDefer( elem, type, src ) { var deferDataKey = type + "defer", queueDataKey = type + "queue", markDataKey = type + "mark", defer = jQuery._data( elem, deferDataKey ); if ( defer && ( src === "queue" || !jQuery._data(elem, queueDataKey) ) && ( src === "mark" || !jQuery._data(elem, markDataKey) ) ) { // Give room for hard-coded callbacks to fire first // and eventually mark/queue something else on the element setTimeout( function() { if ( !jQuery._data( elem, queueDataKey ) && !jQuery._data( elem, markDataKey ) ) { jQuery.removeData( elem, deferDataKey, true ); defer.fire(); } }, 0 ); } } jQuery.extend({ _mark: function( elem, type ) { if ( elem ) { type = ( type || "fx" ) + "mark"; jQuery._data( elem, type, (jQuery._data( elem, type ) || 0) + 1 ); } }, _unmark: function( force, elem, type ) { if ( force !== true ) { type = elem; elem = force; force = false; } if ( elem ) { type = type || "fx"; var key = type + "mark", count = force ? 0 : ( (jQuery._data( elem, key ) || 1) - 1 ); if ( count ) { jQuery._data( elem, key, count ); } else { jQuery.removeData( elem, key, true ); handleQueueMarkDefer( elem, type, "mark" ); } } }, queue: function( elem, type, data ) { var q; if ( elem ) { type = ( type || "fx" ) + "queue"; q = jQuery._data( elem, type ); // Speed up dequeue by getting out quickly if this is just a lookup if ( data ) { if ( !q || jQuery.isArray(data) ) { q = jQuery._data( elem, type, jQuery.makeArray(data) ); } else { q.push( data ); } } return q || []; } }, dequeue: function( elem, type ) { type = type || "fx"; var queue = jQuery.queue( elem, type ), fn = queue.shift(), hooks = {}; // If the fx queue is dequeued, always remove the progress sentinel if ( fn === "inprogress" ) { fn = queue.shift(); } if ( fn ) { // Add a progress sentinel to prevent the fx queue from being // automatically dequeued if ( type === "fx" ) { queue.unshift( "inprogress" ); } jQuery._data( elem, type + ".run", hooks ); fn.call( elem, function() { jQuery.dequeue( elem, type ); }, hooks ); } if ( !queue.length ) { jQuery.removeData( elem, type + "queue " + type + ".run", true ); handleQueueMarkDefer( elem, type, "queue" ); } } }); 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 ); 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, object ) { if ( typeof type !== "string" ) { object = type; type = undefined; } type = type || "fx"; var defer = jQuery.Deferred(), elements = this, i = elements.length, count = 1, deferDataKey = type + "defer", queueDataKey = type + "queue", markDataKey = type + "mark", tmp; function resolve() { if ( !( --count ) ) { defer.resolveWith( elements, [ elements ] ); } } while( i-- ) { if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) || ( jQuery.data( elements[ i ], queueDataKey, undefined, true ) || jQuery.data( elements[ i ], markDataKey, undefined, true ) ) && jQuery.data( elements[ i ], deferDataKey, jQuery.Callbacks( "once memory" ), true ) )) { count++; tmp.add( resolve ); } } resolve(); return defer.promise( object ); } }); var rclass = /[\n\t\r]/g, rspace = /\s+/, rreturn = /\r/g, rtype = /^(?:button|input)$/i, rfocusable = /^(?:button|input|object|select|textarea)$/i, rclickable = /^a(?:rea)?$/i, rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i, getSetAttribute = jQuery.support.getSetAttribute, nodeHook, boolHook, fixSpecified; 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 classNames, i, l, elem, setClass, c, cl; if ( jQuery.isFunction( value ) ) { return this.each(function( j ) { jQuery( this ).addClass( value.call(this, j, this.className) ); }); } if ( value && typeof value === "string" ) { classNames = value.split( rspace ); for ( i = 0, l = this.length; i < l; i++ ) { elem = this[ i ]; if ( elem.nodeType === 1 ) { if ( !elem.className && classNames.length === 1 ) { elem.className = value; } else { setClass = " " + elem.className + " "; for ( c = 0, cl = classNames.length; c < cl; c++ ) { if ( !~setClass.indexOf( " " + classNames[ c ] + " " ) ) { setClass += classNames[ c ] + " "; } } elem.className = jQuery.trim( setClass ); } } } } return this; }, removeClass: function( value ) { var classNames, i, l, elem, className, c, cl; if ( jQuery.isFunction( value ) ) { return this.each(function( j ) { jQuery( this ).removeClass( value.call(this, j, this.className) ); }); } if ( (value && typeof value === "string") || value === undefined ) { classNames = ( value || "" ).split( rspace ); for ( i = 0, l = this.length; i < l; i++ ) { elem = this[ i ]; if ( elem.nodeType === 1 && elem.className ) { if ( value ) { className = (" " + elem.className + " ").replace( rclass, " " ); for ( c = 0, cl = classNames.length; c < cl; c++ ) { className = className.replace(" " + classNames[ c ] + " ", " "); } elem.className = jQuery.trim( className ); } else { elem.className = ""; } } } } return this; }, toggleClass: function( value, stateVal ) { var type = typeof value, isBool = typeof stateVal === "boolean"; 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 ), state = stateVal, classNames = value.split( rspace ); while ( (className = classNames[ i++ ]) ) { // check each className given, space seperated list state = isBool ? state : !self.hasClass( className ); self[ state ? "addClass" : "removeClass" ]( className ); } } else if ( type === "undefined" || type === "boolean" ) { if ( this.className ) { // store className if set jQuery._data( this, "__className__", this.className ); } // toggle whole className 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 ) > -1 ) { return true; } } return false; }, val: function( value ) { var hooks, ret, 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 self = jQuery(this), val; if ( this.nodeType !== 1 ) { return; } if ( isFunction ) { val = value.call( this, i, self.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 ) { // attributes.value is undefined in Blackberry 4.7 but // uses .value. See #6932 var val = elem.attributes.value; return !val || val.specified ? elem.value : elem.text; } }, select: { get: function( elem ) { var value, i, max, option, index = elem.selectedIndex, values = [], options = elem.options, one = elem.type === "select-one"; // Nothing was selected if ( index < 0 ) { return null; } // Loop through all the selected options i = one ? index : 0; max = one ? index + 1 : options.length; for ( ; i < max; i++ ) { option = options[ i ]; // Don't return options that are disabled or in a disabled optgroup if ( option.selected && (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 ); } } // Fixes Bug #2551 -- select.val() broken in IE after form.reset() if ( one && !values.length && options.length ) { return jQuery( options[ index ] ).val(); } return values; }, set: function( elem, value ) { var values = jQuery.makeArray( value ); jQuery(elem).find("option").each(function() { this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0; }); if ( !values.length ) { elem.selectedIndex = -1; } return values; } } }, attrFn: { val: true, css: true, html: true, text: true, data: true, width: true, height: true, offset: true }, attr: function( elem, name, value, pass ) { var ret, hooks, notxml, nType = elem.nodeType; // don't get/set attributes on text, comment and attribute nodes if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { return; } if ( pass && name in jQuery.attrFn ) { return jQuery( elem )[ name ]( value ); } // Fallback to prop when attributes are not supported if ( typeof elem.getAttribute === "undefined" ) { return jQuery.prop( elem, name, value ); } notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); // All attributes are lowercase // Grab necessary hook if one is defined if ( notxml ) { name = name.toLowerCase(); hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook ); } if ( value !== undefined ) { if ( value === null ) { jQuery.removeAttr( elem, name ); return; } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) { return ret; } else { elem.setAttribute( name, "" + value ); return value; } } else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) { return ret; } else { ret = elem.getAttribute( name ); // Non-existent attributes return null, we normalize to undefined return ret === null ? undefined : ret; } }, removeAttr: function( elem, value ) { var propName, attrNames, name, l, isBool, i = 0; if ( value && elem.nodeType === 1 ) { attrNames = value.toLowerCase().split( rspace ); l = attrNames.length; for ( ; i < l; i++ ) { name = attrNames[ i ]; if ( name ) { propName = jQuery.propFix[ name ] || name; isBool = rboolean.test( name ); // See #9699 for explanation of this approach (setting first, then removal) // Do not do this for boolean attributes (see #10870) if ( !isBool ) { jQuery.attr( elem, name, "" ); } elem.removeAttribute( getSetAttribute ? name : propName ); // Set corresponding property to false for boolean attributes if ( isBool && propName in elem ) { elem[ propName ] = false; } } } } }, attrHooks: { type: { set: function( elem, value ) { // We can't allow the type property to be changed (since it causes problems in IE) if ( rtype.test( elem.nodeName ) && elem.parentNode ) { jQuery.error( "type property can't be changed" ); } else 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 it's default in case type is set after value // This is for element creation var val = elem.value; elem.setAttribute( "type", value ); if ( val ) { elem.value = val; } return value; } } }, // Use the value property for back compat // Use the nodeHook for button elements in IE6/7 (#1954) value: { get: function( elem, name ) { if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { return nodeHook.get( elem, name ); } return name in elem ? elem.value : null; }, set: function( elem, value, name ) { if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { return nodeHook.set( elem, value, name ); } // Does not return so that setAttribute is also used elem.value = value; } } }, propFix: { tabindex: "tabIndex", readonly: "readOnly", "for": "htmlFor", "class": "className", maxlength: "maxLength", cellspacing: "cellSpacing", cellpadding: "cellPadding", rowspan: "rowSpan", colspan: "colSpan", usemap: "useMap", frameborder: "frameBorder", contenteditable: "contentEditable" }, 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 ) { if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { return ret; } else { return ( elem[ name ] = value ); } } else { if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { return ret; } else { return 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/ var attributeNode = elem.getAttributeNode("tabindex"); return attributeNode && attributeNode.specified ? parseInt( attributeNode.value, 10 ) : rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? 0 : undefined; } } } }); // Add the tabIndex propHook to attrHooks for back-compat (different case is intentional) jQuery.attrHooks.tabindex = jQuery.propHooks.tabIndex; // Hook for boolean attributes boolHook = { get: function( elem, name ) { // Align boolean attributes with corresponding properties // Fall back to attribute presence where some booleans are not supported var attrNode, property = jQuery.prop( elem, name ); return property === true || typeof property !== "boolean" && ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ? name.toLowerCase() : undefined; }, set: function( elem, value, name ) { var propName; if ( value === false ) { // Remove boolean attributes when set to false jQuery.removeAttr( elem, name ); } else { // value is true since we know at this point it's type boolean and not false // Set boolean attributes to the same name and set the DOM property propName = jQuery.propFix[ name ] || name; if ( propName in elem ) { // Only set the IDL specifically if it already exists on the element elem[ propName ] = true; } elem.setAttribute( name, name.toLowerCase() ); } return name; } }; // IE6/7 do not support getting/setting some attributes with get/setAttribute if ( !getSetAttribute ) { fixSpecified = { name: true, id: true, coords: true }; // Use this for any attribute in IE6/7 // This fixes almost every IE6/7 issue nodeHook = jQuery.valHooks.button = { get: function( elem, name ) { var ret; ret = elem.getAttributeNode( name ); return ret && ( fixSpecified[ name ] ? ret.nodeValue !== "" : ret.specified ) ? ret.nodeValue : undefined; }, set: function( elem, value, name ) { // Set the existing or create a new attribute node var ret = elem.getAttributeNode( name ); if ( !ret ) { ret = document.createAttribute( name ); elem.setAttributeNode( ret ); } return ( ret.nodeValue = value + "" ); } }; // Apply the nodeHook to tabindex jQuery.attrHooks.tabindex.set = nodeHook.set; // 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 ] = jQuery.extend( jQuery.attrHooks[ name ], { set: function( elem, value ) { if ( value === "" ) { elem.setAttribute( name, "auto" ); return value; } } }); }); // Set contenteditable to false on removals(#10429) // Setting to empty string throws an error as an invalid value jQuery.attrHooks.contenteditable = { get: nodeHook.get, set: function( elem, value, name ) { if ( value === "" ) { value = "false"; } nodeHook.set( elem, value, name ); } }; } // Some attributes require a special call on IE if ( !jQuery.support.hrefNormalized ) { jQuery.each([ "href", "src", "width", "height" ], function( i, name ) { jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { get: function( elem ) { var ret = elem.getAttribute( name, 2 ); return ret === null ? undefined : ret; } }); }); } if ( !jQuery.support.style ) { jQuery.attrHooks.style = { get: function( elem ) { // Return undefined in the case of empty string // Normalize to lowercase since IE uppercases css property names return elem.style.cssText.toLowerCase() || 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 = jQuery.extend( 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; } }); } // IE6/7 call enctype encoding if ( !jQuery.support.enctype ) { jQuery.propFix.enctype = "encoding"; } // Radios and checkboxes getter/setter if ( !jQuery.support.checkOn ) { jQuery.each([ "radio", "checkbox" ], function() { jQuery.valHooks[ this ] = { get: function( elem ) { // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified return elem.getAttribute("value") === null ? "on" : elem.value; } }; }); } jQuery.each([ "radio", "checkbox" ], function() { jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], { set: function( elem, value ) { if ( jQuery.isArray( value ) ) { return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 ); } } }); }); var rformElems = /^(?:textarea|input|select)$/i, rtypenamespace = /^([^\.]*)?(?:\.(.+))?$/, rhoverHack = /(?:^|\s)hover(\.\S+)?\b/, rkeyEvent = /^key/, rmouseEvent = /^(?:mouse|contextmenu)|click/, rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, rquickIs = /^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/, quickParse = function( selector ) { var quick = rquickIs.exec( selector ); if ( quick ) { // 0 1 2 3 // [ _, tag, id, class ] quick[1] = ( quick[1] || "" ).toLowerCase(); quick[3] = quick[3] && new RegExp( "(?:^|\\s)" + quick[3] + "(?:\\s|$)" ); } return quick; }, quickIs = function( elem, m ) { var attrs = elem.attributes || {}; return ( (!m[1] || elem.nodeName.toLowerCase() === m[1]) && (!m[2] || (attrs.id || {}).value === m[2]) && (!m[3] || m[3].test( (attrs[ "class" ] || {}).value )) ); }, hoverHack = function( events ) { return jQuery.event.special.hover ? events : events.replace( rhoverHack, "mouseenter$1 mouseleave$1" ); }; /* * Helper functions for managing events -- not part of the public interface. * Props to Dean Edwards' addEvent library for many of the ideas. */ jQuery.event = { add: function( elem, types, handler, data, selector ) { var elemData, eventHandle, events, t, tns, type, namespaces, handleObj, handleObjIn, quick, handlers, special; // Don't attach events to noData or text/comment nodes (allow plain objects tho) if ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = jQuery._data( elem )) ) { 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 events = elemData.events; if ( !events ) { elemData.events = events = {}; } eventHandle = elemData.handle; if ( !eventHandle ) { elemData.handle = eventHandle = 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 !== "undefined" && (!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 // jQuery(...).bind("mouseover mouseout", fn); types = jQuery.trim( hoverHack(types) ).split( " " ); for ( t = 0; t < types.length; t++ ) { tns = rtypenamespace.exec( types[t] ) || []; type = tns[1]; namespaces = ( tns[2] || "" ).split( "." ).sort(); // 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: tns[1], data: data, handler: handler, guid: handler.guid, selector: selector, quick: selector && quickParse( selector ), namespace: namespaces.join(".") }, handleObjIn ); // Init the event handler queue if we're the first handlers = events[ type ]; if ( !handlers ) { 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; }, global: {}, // Detach an event or set of events from an element remove: function( elem, types, handler, selector, mappedTypes ) { var elemData = jQuery.hasData( elem ) && jQuery._data( elem ), t, tns, type, origType, namespaces, origCount, j, events, special, handle, eventType, handleObj; if ( !elemData || !(events = elemData.events) ) { return; } // Once for each type.namespace in types; type may be omitted types = jQuery.trim( hoverHack( types || "" ) ).split(" "); for ( t = 0; t < types.length; t++ ) { tns = rtypenamespace.exec( types[t] ) || []; type = origType = tns[1]; namespaces = tns[2]; // 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; eventType = events[ type ] || []; origCount = eventType.length; namespaces = namespaces ? new RegExp("(^|\\.)" + namespaces.split(".").sort().join("\\.(?:.*\\.)?") + "(\\.|$)") : null; // Remove matching events for ( j = 0; j < eventType.length; j++ ) { handleObj = eventType[ j ]; if ( ( mappedTypes || origType === handleObj.origType ) && ( !handler || handler.guid === handleObj.guid ) && ( !namespaces || namespaces.test( handleObj.namespace ) ) && ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { eventType.splice( j--, 1 ); if ( handleObj.selector ) { eventType.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 ( eventType.length === 0 && origCount !== eventType.length ) { if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) { jQuery.removeEvent( elem, type, elemData.handle ); } delete events[ type ]; } } // Remove the expando if it's no longer used if ( jQuery.isEmptyObject( events ) ) { handle = elemData.handle; if ( handle ) { handle.elem = null; } // removeData also checks for emptiness and clears the expando if empty // so use it instead of delete jQuery.removeData( elem, [ "events", "handle" ], true ); } }, // Events that are safe to short-circuit if no handlers are attached. // Native DOM events should not be added, they may have inline handlers. customEvent: { "getData": true, "setData": true, "changeData": true }, trigger: function( event, data, elem, onlyHandlers ) { // Don't do events on text and comment nodes if ( elem && (elem.nodeType === 3 || elem.nodeType === 8) ) { return; } // Event object or event type var type = event.type || event, namespaces = [], cache, exclusive, i, cur, old, ontype, special, handle, eventPath, bubbleType; // 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 ) { // Exclusive events trigger only for the exact event (no namespaces) type = type.slice(0, -1); exclusive = true; } if ( type.indexOf( "." ) >= 0 ) { // Namespaced trigger; create a regexp to match event type in handle() namespaces = type.split("."); type = namespaces.shift(); namespaces.sort(); } if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) { // No jQuery handlers for this event type, and it can't have inline handlers return; } // Caller can pass in an Event, Object, or just an event type string event = typeof event === "object" ? // jQuery.Event object event[ jQuery.expando ] ? event : // Object literal new jQuery.Event( type, event ) : // Just the event type (string) new jQuery.Event( type ); event.type = type; event.isTrigger = true; event.exclusive = exclusive; event.namespace = namespaces.join( "." ); event.namespace_re = event.namespace? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)") : null; ontype = type.indexOf( ":" ) < 0 ? "on" + type : ""; // Handle a global trigger if ( !elem ) { // TODO: Stop taunting the data cache; remove global events and always attach to document cache = jQuery.cache; for ( i in cache ) { if ( cache[ i ].events && cache[ i ].events[ type ] ) { jQuery.event.trigger( event, data, cache[ i ].handle.elem, true ); } } return; } // 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 ? jQuery.makeArray( data ) : []; data.unshift( event ); // Allow special events to draw outside the lines special = jQuery.event.special[ type ] || {}; if ( 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) eventPath = [[ elem, special.bindType || type ]]; if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { bubbleType = special.delegateType || type; cur = rfocusMorph.test( bubbleType + type ) ? elem : elem.parentNode; old = null; for ( ; cur; cur = cur.parentNode ) { eventPath.push([ cur, bubbleType ]); old = cur; } // Only add window if we got to document (e.g., not plain obj or detached DOM) if ( old && old === elem.ownerDocument ) { eventPath.push([ old.defaultView || old.parentWindow || window, bubbleType ]); } } // Fire handlers on the event path for ( i = 0; i < eventPath.length && !event.isPropagationStopped(); i++ ) { cur = eventPath[i][0]; event.type = eventPath[i][1]; handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" ); if ( handle ) { handle.apply( cur, data ); } // Note that this is a bare JS function and not a jQuery handler handle = ontype && cur[ ontype ]; if ( handle && jQuery.acceptData( cur ) && 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( elem.ownerDocument, data ) === false) && !(type === "click" && jQuery.nodeName( elem, "a" )) && 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) // IE<9 dies on focus/blur to hidden element (#1486) if ( ontype && elem[ type ] && ((type !== "focus" && type !== "blur") || event.target.offsetWidth !== 0) && !jQuery.isWindow( elem ) ) { // Don't re-trigger an onFOO event when we call its FOO() method old = elem[ ontype ]; if ( old ) { elem[ ontype ] = null; } // Prevent re-triggering of the same event, since we already bubbled it above jQuery.event.triggered = type; elem[ type ](); jQuery.event.triggered = undefined; if ( old ) { elem[ ontype ] = old; } } } } return event.result; }, dispatch: function( event ) { // Make a writable jQuery.Event from the native event object event = jQuery.event.fix( event || window.event ); var handlers = ( (jQuery._data( this, "events" ) || {} )[ event.type ] || []), delegateCount = handlers.delegateCount, args = [].slice.call( arguments, 0 ), run_all = !event.exclusive && !event.namespace, special = jQuery.event.special[ event.type ] || {}, handlerQueue = [], i, j, cur, jqcur, ret, selMatch, matched, matches, handleObj, sel, related; // 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 that should run if there are delegated events // Avoid non-left-click bubbling in Firefox (#3861) if ( delegateCount && !(event.button && event.type === "click") ) { // Pregenerate a single jQuery object for reuse with .is() jqcur = jQuery(this); jqcur.context = this.ownerDocument || this; for ( cur = event.target; cur != this; cur = cur.parentNode || this ) { // Don't process events on disabled elements (#6911, #8165) if ( cur.disabled !== true ) { selMatch = {}; matches = []; jqcur[0] = cur; for ( i = 0; i < delegateCount; i++ ) { handleObj = handlers[ i ]; sel = handleObj.selector; if ( selMatch[ sel ] === undefined ) { selMatch[ sel ] = ( handleObj.quick ? quickIs( cur, handleObj.quick ) : jqcur.is( sel ) ); } if ( selMatch[ sel ] ) { matches.push( handleObj ); } } if ( matches.length ) { handlerQueue.push({ elem: cur, matches: matches }); } } } } // Add the remaining (directly-bound) handlers if ( handlers.length > delegateCount ) { handlerQueue.push({ elem: this, matches: handlers.slice( delegateCount ) }); } // Run delegates first; they may want to stop propagation beneath us for ( i = 0; i < handlerQueue.length && !event.isPropagationStopped(); i++ ) { matched = handlerQueue[ i ]; event.currentTarget = matched.elem; for ( j = 0; j < matched.matches.length && !event.isImmediatePropagationStopped(); j++ ) { handleObj = matched.matches[ j ]; // Triggered event must either 1) be non-exclusive and have no namespace, or // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). if ( run_all || (!event.namespace && !handleObj.namespace) || event.namespace_re && event.namespace_re.test( handleObj.namespace ) ) { event.data = handleObj.data; event.handleObj = handleObj; ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) .apply( matched.elem, args ); if ( ret !== undefined ) { event.result = ret; if ( 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; }, // Includes some event props shared by KeyEvent and MouseEvent // *** attrChange attrName relatedNode srcElement are not normalized, non-W3C, deprecated, will be removed in 1.8 *** props: "attrChange attrName relatedNode srcElement 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 eventDoc, doc, body, 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; } }, fix: function( event ) { if ( event[ jQuery.expando ] ) { return event; } // Create a writable copy of the event object and normalize some properties var i, prop, originalEvent = event, fixHook = jQuery.event.fixHooks[ event.type ] || {}, copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; event = jQuery.Event( originalEvent ); for ( i = copy.length; i; ) { prop = copy[ --i ]; event[ prop ] = originalEvent[ prop ]; } // Fix target property, if necessary (#1925, IE 6/7/8 & Safari2) if ( !event.target ) { event.target = originalEvent.srcElement || document; } // Target should not be a text node (#504, Safari) if ( event.target.nodeType === 3 ) { event.target = event.target.parentNode; } // For mouse/key events; add metaKey if it's not there (#3368, IE6/7/8) if ( event.metaKey === undefined ) { event.metaKey = event.ctrlKey; } return fixHook.filter? fixHook.filter( event, originalEvent ) : event; }, special: { ready: { // Make sure the ready event is setup setup: jQuery.bindReady }, load: { // Prevent triggered image.load events from bubbling to window.load noBubble: true }, focus: { delegateType: "focusin" }, blur: { delegateType: "focusout" }, beforeunload: { setup: function( data, namespaces, eventHandle ) { // We only want to do this special case on windows if ( jQuery.isWindow( this ) ) { this.onbeforeunload = eventHandle; } }, teardown: function( namespaces, eventHandle ) { if ( this.onbeforeunload === eventHandle ) { this.onbeforeunload = null; } } } }, 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(); } } }; // Some plugins are using, but it's undocumented/deprecated and will be removed. // The 1.7 special event interface should provide all the hooks needed now. jQuery.event.handle = jQuery.event.dispatch; jQuery.removeEvent = document.removeEventListener ? function( elem, type, handle ) { if ( elem.removeEventListener ) { elem.removeEventListener( type, handle, false ); } } : function( elem, type, handle ) { if ( elem.detachEvent ) { elem.detachEvent( "on" + type, 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; }; function returnFalse() { return false; } function returnTrue() { return 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 = { preventDefault: function() { this.isDefaultPrevented = returnTrue; var e = this.originalEvent; if ( !e ) { return; } // if preventDefault exists run it on the original event if ( e.preventDefault ) { e.preventDefault(); // otherwise set the returnValue property of the original event to false (IE) } else { e.returnValue = false; } }, stopPropagation: function() { this.isPropagationStopped = returnTrue; var e = this.originalEvent; if ( !e ) { return; } // if stopPropagation exists run it on the original event if ( e.stopPropagation ) { e.stopPropagation(); } // otherwise set the cancelBubble property of the original event to true (IE) e.cancelBubble = true; }, stopImmediatePropagation: function() { this.isImmediatePropagationStopped = returnTrue; this.stopPropagation(); }, isDefaultPrevented: returnFalse, isPropagationStopped: returnFalse, isImmediatePropagationStopped: returnFalse }; // 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 target = this, related = event.relatedTarget, handleObj = event.handleObj, selector = handleObj.selector, ret; // 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 && !form._submit_attached ) { jQuery.event.add( form, "submit._submit", function( event ) { event._submit_bubble = true; }); form._submit_attached = 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; 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 ) && !elem._change_attached ) { jQuery.event.add( elem, "change._change", function( event ) { if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { jQuery.event.simulate( "change", this.parentNode, event, true ); } }); elem._change_attached = 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 origFn, type; // Types can be a map of types/handlers if ( typeof types === "object" ) { // ( types-Object, selector, data ) if ( typeof selector !== "string" ) { // && selector != null // ( 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 ) { if ( types && types.preventDefault && types.handleObj ) { // ( event ) dispatched jQuery.Event var 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 ( var 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 ); }); }, bind: function( types, data, fn ) { return this.on( types, null, data, fn ); }, unbind: function( types, fn ) { return this.off( types, null, fn ); }, live: function( types, data, fn ) { jQuery( this.context ).on( types, this.selector, data, fn ); return this; }, die: function( types, fn ) { jQuery( this.context ).off( types, this.selector || "**", fn ); return this; }, delegate: function( selector, types, data, fn ) { return this.on( types, selector, data, fn ); }, undelegate: function( selector, types, fn ) { // ( namespace ) or ( selector, types [, fn] ) return arguments.length == 1? this.off( selector, "**" ) : this.off( types, selector, fn ); }, trigger: function( type, data ) { return this.each(function() { jQuery.event.trigger( type, data, this ); }); }, triggerHandler: function( type, data ) { if ( this[0] ) { return jQuery.event.trigger( type, data, this[0], true ); } }, toggle: function( fn ) { // Save reference to arguments for access in closure var args = arguments, guid = fn.guid || jQuery.guid++, i = 0, toggler = function( event ) { // Figure out which function to execute var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i; jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 ); // Make sure that clicks stop event.preventDefault(); // and execute the function return args[ lastToggle ].apply( this, arguments ) || false; }; // link all the functions, so any of them can unbind this click handler toggler.guid = guid; while ( i < args.length ) { args[ i++ ].guid = guid; } return this.click( toggler ); }, hover: function( fnOver, fnOut ) { return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); } }); jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " + "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) { // Handle event binding jQuery.fn[ name ] = function( data, fn ) { if ( fn == null ) { fn = data; data = null; } return arguments.length > 0 ? this.on( name, null, data, fn ) : this.trigger( name ); }; if ( jQuery.attrFn ) { jQuery.attrFn[ name ] = true; } if ( rkeyEvent.test( name ) ) { jQuery.event.fixHooks[ name ] = jQuery.event.keyHooks; } if ( rmouseEvent.test( name ) ) { jQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks; } }); /*! * Sizzle CSS Selector Engine * Copyright 2011, The Dojo Foundation * Released under the MIT, BSD, and GPL Licenses. * More information: http://sizzlejs.com/ */ (function(){ var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, expando = "sizcache" + (Math.random() + '').replace('.', ''), done = 0, toString = Object.prototype.toString, hasDuplicate = false, baseHasDuplicate = true, rBackslash = /\\/g, rReturn = /\r\n/g, rNonWord = /\W/; // Here we check if the JavaScript engine is using some sort of // optimization where it does not always call our comparision // function. If that is the case, discard the hasDuplicate value. // Thus far that includes Google Chrome. [0, 0].sort(function() { baseHasDuplicate = false; return 0; }); var Sizzle = function( selector, context, results, seed ) { results = results || []; context = context || document; var origContext = context; if ( context.nodeType !== 1 && context.nodeType !== 9 ) { return []; } if ( !selector || typeof selector !== "string" ) { return results; } var m, set, checkSet, extra, ret, cur, pop, i, prune = true, contextXML = Sizzle.isXML( context ), parts = [], soFar = selector; // Reset the position of the chunker regexp (start from head) do { chunker.exec( "" ); m = chunker.exec( soFar ); if ( m ) { soFar = m[3]; parts.push( m[1] ); if ( m[2] ) { extra = m[3]; break; } } } while ( m ); if ( parts.length > 1 && origPOS.exec( selector ) ) { if ( parts.length === 2 && Expr.relative[ parts[0] ] ) { set = posProcess( parts[0] + parts[1], context, seed ); } else { set = Expr.relative[ parts[0] ] ? [ context ] : Sizzle( parts.shift(), context ); while ( parts.length ) { selector = parts.shift(); if ( Expr.relative[ selector ] ) { selector += parts.shift(); } set = posProcess( selector, set, seed ); } } } else { // Take a shortcut and set the context if the root selector is an ID // (but not if it'll be faster if the inner selector is an ID) if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML && Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) { ret = Sizzle.find( parts.shift(), context, contextXML ); context = ret.expr ? Sizzle.filter( ret.expr, ret.set )[0] : ret.set[0]; } if ( context ) { ret = seed ? { expr: parts.pop(), set: makeArray(seed) } : Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML ); set = ret.expr ? Sizzle.filter( ret.expr, ret.set ) : ret.set; if ( parts.length > 0 ) { checkSet = makeArray( set ); } else { prune = false; } while ( parts.length ) { cur = parts.pop(); pop = cur; if ( !Expr.relative[ cur ] ) { cur = ""; } else { pop = parts.pop(); } if ( pop == null ) { pop = context; } Expr.relative[ cur ]( checkSet, pop, contextXML ); } } else { checkSet = parts = []; } } if ( !checkSet ) { checkSet = set; } if ( !checkSet ) { Sizzle.error( cur || selector ); } if ( toString.call(checkSet) === "[object Array]" ) { if ( !prune ) { results.push.apply( results, checkSet ); } else if ( context && context.nodeType === 1 ) { for ( i = 0; checkSet[i] != null; i++ ) { if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) { results.push( set[i] ); } } } else { for ( i = 0; checkSet[i] != null; i++ ) { if ( checkSet[i] && checkSet[i].nodeType === 1 ) { results.push( set[i] ); } } } } else { makeArray( checkSet, results ); } if ( extra ) { Sizzle( extra, origContext, results, seed ); Sizzle.uniqueSort( results ); } return results; }; Sizzle.uniqueSort = function( results ) { if ( sortOrder ) { hasDuplicate = baseHasDuplicate; results.sort( sortOrder ); if ( hasDuplicate ) { for ( var i = 1; i < results.length; i++ ) { if ( results[i] === results[ i - 1 ] ) { results.splice( i--, 1 ); } } } } return results; }; Sizzle.matches = function( expr, set ) { return Sizzle( expr, null, null, set ); }; Sizzle.matchesSelector = function( node, expr ) { return Sizzle( expr, null, null, [node] ).length > 0; }; Sizzle.find = function( expr, context, isXML ) { var set, i, len, match, type, left; if ( !expr ) { return []; } for ( i = 0, len = Expr.order.length; i < len; i++ ) { type = Expr.order[i]; if ( (match = Expr.leftMatch[ type ].exec( expr )) ) { left = match[1]; match.splice( 1, 1 ); if ( left.substr( left.length - 1 ) !== "\\" ) { match[1] = (match[1] || "").replace( rBackslash, "" ); set = Expr.find[ type ]( match, context, isXML ); if ( set != null ) { expr = expr.replace( Expr.match[ type ], "" ); break; } } } } if ( !set ) { set = typeof context.getElementsByTagName !== "undefined" ? context.getElementsByTagName( "*" ) : []; } return { set: set, expr: expr }; }; Sizzle.filter = function( expr, set, inplace, not ) { var match, anyFound, type, found, item, filter, left, i, pass, old = expr, result = [], curLoop = set, isXMLFilter = set && set[0] && Sizzle.isXML( set[0] ); while ( expr && set.length ) { for ( type in Expr.filter ) { if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) { filter = Expr.filter[ type ]; left = match[1]; anyFound = false; match.splice(1,1); if ( left.substr( left.length - 1 ) === "\\" ) { continue; } if ( curLoop === result ) { result = []; } if ( Expr.preFilter[ type ] ) { match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter ); if ( !match ) { anyFound = found = true; } else if ( match === true ) { continue; } } if ( match ) { for ( i = 0; (item = curLoop[i]) != null; i++ ) { if ( item ) { found = filter( item, match, i, curLoop ); pass = not ^ found; if ( inplace && found != null ) { if ( pass ) { anyFound = true; } else { curLoop[i] = false; } } else if ( pass ) { result.push( item ); anyFound = true; } } } } if ( found !== undefined ) { if ( !inplace ) { curLoop = result; } expr = expr.replace( Expr.match[ type ], "" ); if ( !anyFound ) { return []; } break; } } } // Improper expression if ( expr === old ) { if ( anyFound == null ) { Sizzle.error( expr ); } else { break; } } old = expr; } return curLoop; }; Sizzle.error = function( msg ) { throw new Error( "Syntax error, unrecognized expression: " + msg ); }; /** * Utility function for retreiving the text value of an array of DOM nodes * @param {Array|Element} elem */ var getText = Sizzle.getText = function( elem ) { var i, node, nodeType = elem.nodeType, ret = ""; if ( nodeType ) { if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { // Use textContent || innerText for elements if ( typeof elem.textContent === 'string' ) { return elem.textContent; } else if ( typeof elem.innerText === 'string' ) { // Replace IE's carriage returns return elem.innerText.replace( rReturn, '' ); } else { // Traverse it's children for ( elem = elem.firstChild; elem; elem = elem.nextSibling) { ret += getText( elem ); } } } else if ( nodeType === 3 || nodeType === 4 ) { return elem.nodeValue; } } else { // If no nodeType, this is expected to be an array for ( i = 0; (node = elem[i]); i++ ) { // Do not traverse comment nodes if ( node.nodeType !== 8 ) { ret += getText( node ); } } } return ret; }; var Expr = Sizzle.selectors = { order: [ "ID", "NAME", "TAG" ], match: { ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/, ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/, TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/, CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/, POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/, PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/ }, leftMatch: {}, attrMap: { "class": "className", "for": "htmlFor" }, attrHandle: { href: function( elem ) { return elem.getAttribute( "href" ); }, type: function( elem ) { return elem.getAttribute( "type" ); } }, relative: { "+": function(checkSet, part){ var isPartStr = typeof part === "string", isTag = isPartStr && !rNonWord.test( part ), isPartStrNotTag = isPartStr && !isTag; if ( isTag ) { part = part.toLowerCase(); } for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) { if ( (elem = checkSet[i]) ) { while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {} checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ? elem || false : elem === part; } } if ( isPartStrNotTag ) { Sizzle.filter( part, checkSet, true ); } }, ">": function( checkSet, part ) { var elem, isPartStr = typeof part === "string", i = 0, l = checkSet.length; if ( isPartStr && !rNonWord.test( part ) ) { part = part.toLowerCase(); for ( ; i < l; i++ ) { elem = checkSet[i]; if ( elem ) { var parent = elem.parentNode; checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false; } } } else { for ( ; i < l; i++ ) { elem = checkSet[i]; if ( elem ) { checkSet[i] = isPartStr ? elem.parentNode : elem.parentNode === part; } } if ( isPartStr ) { Sizzle.filter( part, checkSet, true ); } } }, "": function(checkSet, part, isXML){ var nodeCheck, doneName = done++, checkFn = dirCheck; if ( typeof part === "string" && !rNonWord.test( part ) ) { part = part.toLowerCase(); nodeCheck = part; checkFn = dirNodeCheck; } checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML ); }, "~": function( checkSet, part, isXML ) { var nodeCheck, doneName = done++, checkFn = dirCheck; if ( typeof part === "string" && !rNonWord.test( part ) ) { part = part.toLowerCase(); nodeCheck = part; checkFn = dirNodeCheck; } checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML ); } }, find: { ID: function( match, context, isXML ) { if ( typeof context.getElementById !== "undefined" && !isXML ) { var m = context.getElementById(match[1]); // Check parentNode to catch when Blackberry 4.6 returns // nodes that are no longer in the document #6963 return m && m.parentNode ? [m] : []; } }, NAME: function( match, context ) { if ( typeof context.getElementsByName !== "undefined" ) { var ret = [], results = context.getElementsByName( match[1] ); for ( var i = 0, l = results.length; i < l; i++ ) { if ( results[i].getAttribute("name") === match[1] ) { ret.push( results[i] ); } } return ret.length === 0 ? null : ret; } }, TAG: function( match, context ) { if ( typeof context.getElementsByTagName !== "undefined" ) { return context.getElementsByTagName( match[1] ); } } }, preFilter: { CLASS: function( match, curLoop, inplace, result, not, isXML ) { match = " " + match[1].replace( rBackslash, "" ) + " "; if ( isXML ) { return match; } for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) { if ( elem ) { if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) { if ( !inplace ) { result.push( elem ); } } else if ( inplace ) { curLoop[i] = false; } } } return false; }, ID: function( match ) { return match[1].replace( rBackslash, "" ); }, TAG: function( match, curLoop ) { return match[1].replace( rBackslash, "" ).toLowerCase(); }, CHILD: function( match ) { if ( match[1] === "nth" ) { if ( !match[2] ) { Sizzle.error( match[0] ); } match[2] = match[2].replace(/^\+|\s*/g, ''); // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6' var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec( match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" || !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]); // calculate the numbers (first)n+(last) including if they are negative match[2] = (test[1] + (test[2] || 1)) - 0; match[3] = test[3] - 0; } else if ( match[2] ) { Sizzle.error( match[0] ); } // TODO: Move to normal caching system match[0] = done++; return match; }, ATTR: function( match, curLoop, inplace, result, not, isXML ) { var name = match[1] = match[1].replace( rBackslash, "" ); if ( !isXML && Expr.attrMap[name] ) { match[1] = Expr.attrMap[name]; } // Handle if an un-quoted value was used match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" ); if ( match[2] === "~=" ) { match[4] = " " + match[4] + " "; } return match; }, PSEUDO: function( match, curLoop, inplace, result, not ) { if ( match[1] === "not" ) { // If we're dealing with a complex expression, or a simple one if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) { match[3] = Sizzle(match[3], null, null, curLoop); } else { var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not); if ( !inplace ) { result.push.apply( result, ret ); } return false; } } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) { return true; } return match; }, POS: function( match ) { match.unshift( true ); return match; } }, filters: { enabled: function( elem ) { return elem.disabled === false && elem.type !== "hidden"; }, disabled: function( elem ) { return elem.disabled === true; }, checked: function( elem ) { return elem.checked === true; }, 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; }, parent: function( elem ) { return !!elem.firstChild; }, empty: function( elem ) { return !elem.firstChild; }, has: function( elem, i, match ) { return !!Sizzle( match[3], elem ).length; }, header: function( elem ) { return (/h\d/i).test( elem.nodeName ); }, text: function( elem ) { var attr = elem.getAttribute( "type" ), type = elem.type; // 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" && "text" === type && ( attr === type || attr === null ); }, radio: function( elem ) { return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type; }, checkbox: function( elem ) { return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type; }, file: function( elem ) { return elem.nodeName.toLowerCase() === "input" && "file" === elem.type; }, password: function( elem ) { return elem.nodeName.toLowerCase() === "input" && "password" === elem.type; }, submit: function( elem ) { var name = elem.nodeName.toLowerCase(); return (name === "input" || name === "button") && "submit" === elem.type; }, image: function( elem ) { return elem.nodeName.toLowerCase() === "input" && "image" === elem.type; }, reset: function( elem ) { var name = elem.nodeName.toLowerCase(); return (name === "input" || name === "button") && "reset" === elem.type; }, button: function( elem ) { var name = elem.nodeName.toLowerCase(); return name === "input" && "button" === elem.type || name === "button"; }, input: function( elem ) { return (/input|select|textarea|button/i).test( elem.nodeName ); }, focus: function( elem ) { return elem === elem.ownerDocument.activeElement; } }, setFilters: { first: function( elem, i ) { return i === 0; }, last: function( elem, i, match, array ) { return i === array.length - 1; }, even: function( elem, i ) { return i % 2 === 0; }, odd: function( elem, i ) { return i % 2 === 1; }, lt: function( elem, i, match ) { return i < match[3] - 0; }, gt: function( elem, i, match ) { return i > match[3] - 0; }, nth: function( elem, i, match ) { return match[3] - 0 === i; }, eq: function( elem, i, match ) { return match[3] - 0 === i; } }, filter: { PSEUDO: function( elem, match, i, array ) { var name = match[1], filter = Expr.filters[ name ]; if ( filter ) { return filter( elem, i, match, array ); } else if ( name === "contains" ) { return (elem.textContent || elem.innerText || getText([ elem ]) || "").indexOf(match[3]) >= 0; } else if ( name === "not" ) { var not = match[3]; for ( var j = 0, l = not.length; j < l; j++ ) { if ( not[j] === elem ) { return false; } } return true; } else { Sizzle.error( name ); } }, CHILD: function( elem, match ) { var first, last, doneName, parent, cache, count, diff, type = match[1], node = elem; switch ( type ) { case "only": case "first": while ( (node = node.previousSibling) ) { if ( node.nodeType === 1 ) { return false; } } if ( type === "first" ) { return true; } node = elem; /* falls through */ case "last": while ( (node = node.nextSibling) ) { if ( node.nodeType === 1 ) { return false; } } return true; case "nth": first = match[2]; last = match[3]; if ( first === 1 && last === 0 ) { return true; } doneName = match[0]; parent = elem.parentNode; if ( parent && (parent[ expando ] !== doneName || !elem.nodeIndex) ) { count = 0; for ( node = parent.firstChild; node; node = node.nextSibling ) { if ( node.nodeType === 1 ) { node.nodeIndex = ++count; } } parent[ expando ] = doneName; } diff = elem.nodeIndex - last; if ( first === 0 ) { return diff === 0; } else { return ( diff % first === 0 && diff / first >= 0 ); } } }, ID: function( elem, match ) { return elem.nodeType === 1 && elem.getAttribute("id") === match; }, TAG: function( elem, match ) { return (match === "*" && elem.nodeType === 1) || !!elem.nodeName && elem.nodeName.toLowerCase() === match; }, CLASS: function( elem, match ) { return (" " + (elem.className || elem.getAttribute("class")) + " ") .indexOf( match ) > -1; }, ATTR: function( elem, match ) { var name = match[1], result = Sizzle.attr ? Sizzle.attr( elem, name ) : Expr.attrHandle[ name ] ? Expr.attrHandle[ name ]( elem ) : elem[ name ] != null ? elem[ name ] : elem.getAttribute( name ), value = result + "", type = match[2], check = match[4]; return result == null ? type === "!=" : !type && Sizzle.attr ? result != null : type === "=" ? value === check : type === "*=" ? value.indexOf(check) >= 0 : type === "~=" ? (" " + value + " ").indexOf(check) >= 0 : !check ? value && result !== false : type === "!=" ? value !== check : type === "^=" ? value.indexOf(check) === 0 : type === "$=" ? value.substr(value.length - check.length) === check : type === "|=" ? value === check || value.substr(0, check.length + 1) === check + "-" : false; }, POS: function( elem, match, i, array ) { var name = match[2], filter = Expr.setFilters[ name ]; if ( filter ) { return filter( elem, i, match, array ); } } } }; var origPOS = Expr.match.POS, fescape = function(all, num){ return "\\" + (num - 0 + 1); }; for ( var type in Expr.match ) { Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) ); Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) ); } // Expose origPOS // "global" as in regardless of relation to brackets/parens Expr.match.globalPOS = origPOS; var makeArray = function( array, results ) { array = Array.prototype.slice.call( array, 0 ); if ( results ) { results.push.apply( results, array ); return results; } return array; }; // Perform a simple check to determine if the browser is capable of // converting a NodeList to an array using builtin methods. // Also verifies that the returned array holds DOM nodes // (which is not the case in the Blackberry browser) try { Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType; // Provide a fallback method if it does not work } catch( e ) { makeArray = function( array, results ) { var i = 0, ret = results || []; if ( toString.call(array) === "[object Array]" ) { Array.prototype.push.apply( ret, array ); } else { if ( typeof array.length === "number" ) { for ( var l = array.length; i < l; i++ ) { ret.push( array[i] ); } } else { for ( ; array[i]; i++ ) { ret.push( array[i] ); } } } return ret; }; } var sortOrder, siblingCheck; if ( document.documentElement.compareDocumentPosition ) { sortOrder = function( a, b ) { if ( a === b ) { hasDuplicate = true; return 0; } if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) { return a.compareDocumentPosition ? -1 : 1; } return a.compareDocumentPosition(b) & 4 ? -1 : 1; }; } else { sortOrder = function( a, b ) { // The nodes are identical, we can exit early if ( a === b ) { hasDuplicate = true; return 0; // Fallback to using sourceIndex (in IE) if it's available on both nodes } else if ( a.sourceIndex && b.sourceIndex ) { return a.sourceIndex - b.sourceIndex; } var al, bl, ap = [], bp = [], aup = a.parentNode, bup = b.parentNode, cur = aup; // If the nodes are siblings (or identical) we can do a quick check if ( aup === bup ) { return siblingCheck( a, b ); // If no parents were found then the nodes are disconnected } else if ( !aup ) { return -1; } else if ( !bup ) { return 1; } // Otherwise they're somewhere else in the tree so we need // to build up a full list of the parentNodes for comparison while ( cur ) { ap.unshift( cur ); cur = cur.parentNode; } cur = bup; while ( cur ) { bp.unshift( cur ); cur = cur.parentNode; } al = ap.length; bl = bp.length; // Start walking down the tree looking for a discrepancy for ( var i = 0; i < al && i < bl; i++ ) { if ( ap[i] !== bp[i] ) { return siblingCheck( ap[i], bp[i] ); } } // We ended someplace up the tree so do a sibling check return i === al ? siblingCheck( a, bp[i], -1 ) : siblingCheck( ap[i], b, 1 ); }; siblingCheck = function( a, b, ret ) { if ( a === b ) { return ret; } var cur = a.nextSibling; while ( cur ) { if ( cur === b ) { return -1; } cur = cur.nextSibling; } return 1; }; } // Check to see if the browser returns elements by name when // querying by getElementById (and provide a workaround) (function(){ // We're going to inject a fake input element with a specified name var form = document.createElement("div"), id = "script" + (new Date()).getTime(), root = document.documentElement; form.innerHTML = ""; // Inject it into the root element, check its status, and remove it quickly root.insertBefore( form, root.firstChild ); // The workaround has to do additional checks after a getElementById // Which slows things down for other browsers (hence the branching) if ( document.getElementById( id ) ) { Expr.find.ID = function( match, context, isXML ) { if ( typeof context.getElementById !== "undefined" && !isXML ) { var m = context.getElementById(match[1]); return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : []; } }; Expr.filter.ID = function( elem, match ) { var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); return elem.nodeType === 1 && node && node.nodeValue === match; }; } root.removeChild( form ); // release memory in IE root = form = null; })(); (function(){ // Check to see if the browser returns only elements // when doing getElementsByTagName("*") // Create a fake element var div = document.createElement("div"); div.appendChild( document.createComment("") ); // Make sure no comments are found if ( div.getElementsByTagName("*").length > 0 ) { Expr.find.TAG = function( match, context ) { var results = context.getElementsByTagName( match[1] ); // Filter out possible comments if ( match[1] === "*" ) { var tmp = []; for ( var i = 0; results[i]; i++ ) { if ( results[i].nodeType === 1 ) { tmp.push( results[i] ); } } results = tmp; } return results; }; } // Check to see if an attribute returns normalized href attributes div.innerHTML = ""; if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" && div.firstChild.getAttribute("href") !== "#" ) { Expr.attrHandle.href = function( elem ) { return elem.getAttribute( "href", 2 ); }; } // release memory in IE div = null; })(); if ( document.querySelectorAll ) { (function(){ var oldSizzle = Sizzle, div = document.createElement("div"), id = "__sizzle__"; div.innerHTML = "

"; // Safari can't handle uppercase or unicode characters when // in quirks mode. if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) { return; } Sizzle = function( query, context, extra, seed ) { context = context || document; // Only use querySelectorAll on non-XML documents // (ID selectors don't work in non-HTML documents) if ( !seed && !Sizzle.isXML(context) ) { // See if we find a selector to speed up var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query ); if ( match && (context.nodeType === 1 || context.nodeType === 9) ) { // Speed-up: Sizzle("TAG") if ( match[1] ) { return makeArray( context.getElementsByTagName( query ), extra ); // Speed-up: Sizzle(".CLASS") } else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) { return makeArray( context.getElementsByClassName( match[2] ), extra ); } } if ( context.nodeType === 9 ) { // Speed-up: Sizzle("body") // The body element only exists once, optimize finding it if ( query === "body" && context.body ) { return makeArray( [ context.body ], extra ); // Speed-up: Sizzle("#ID") } else if ( match && match[3] ) { var elem = context.getElementById( match[3] ); // 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[3] ) { return makeArray( [ elem ], extra ); } } else { return makeArray( [], extra ); } } try { return makeArray( context.querySelectorAll(query), extra ); } catch(qsaError) {} // 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 } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { var oldContext = context, old = context.getAttribute( "id" ), nid = old || id, hasParent = context.parentNode, relativeHierarchySelector = /^\s*[+~]/.test( query ); if ( !old ) { context.setAttribute( "id", nid ); } else { nid = nid.replace( /'/g, "\\$&" ); } if ( relativeHierarchySelector && hasParent ) { context = context.parentNode; } try { if ( !relativeHierarchySelector || hasParent ) { return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra ); } } catch(pseudoError) { } finally { if ( !old ) { oldContext.removeAttribute( "id" ); } } } } return oldSizzle(query, context, extra, seed); }; for ( var prop in oldSizzle ) { Sizzle[ prop ] = oldSizzle[ prop ]; } // release memory in IE div = null; })(); } (function(){ var html = document.documentElement, matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector; if ( matches ) { // Check to see if it's possible to do matchesSelector // on a disconnected node (IE 9 fails this) var disconnectedMatch = !matches.call( document.createElement( "div" ), "div" ), pseudoWorks = false; try { // This should fail with an exception // Gecko does not error, returns false instead matches.call( document.documentElement, "[test!='']:sizzle" ); } catch( pseudoError ) { pseudoWorks = true; } Sizzle.matchesSelector = function( node, expr ) { // Make sure that attribute selectors are quoted expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']"); if ( !Sizzle.isXML( node ) ) { try { if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) { var ret = matches.call( node, expr ); // IE 9's matchesSelector returns false on disconnected nodes if ( ret || !disconnectedMatch || // As well, disconnected nodes are said to be in a document // fragment in IE 9, so check for that node.document && node.document.nodeType !== 11 ) { return ret; } } } catch(e) {} } return Sizzle(expr, null, null, [node]).length > 0; }; } })(); (function(){ var div = document.createElement("div"); div.innerHTML = "
"; // Opera can't find a second classname (in 9.6) // Also, make sure that getElementsByClassName actually exists if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) { return; } // Safari caches class attributes, doesn't catch changes (in 3.2) div.lastChild.className = "e"; if ( div.getElementsByClassName("e").length === 1 ) { return; } Expr.order.splice(1, 0, "CLASS"); Expr.find.CLASS = function( match, context, isXML ) { if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) { return context.getElementsByClassName(match[1]); } }; // release memory in IE div = null; })(); function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { for ( var i = 0, l = checkSet.length; i < l; i++ ) { var elem = checkSet[i]; if ( elem ) { var match = false; elem = elem[dir]; while ( elem ) { if ( elem[ expando ] === doneName ) { match = checkSet[elem.sizset]; break; } if ( elem.nodeType === 1 && !isXML ){ elem[ expando ] = doneName; elem.sizset = i; } if ( elem.nodeName.toLowerCase() === cur ) { match = elem; break; } elem = elem[dir]; } checkSet[i] = match; } } } function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { for ( var i = 0, l = checkSet.length; i < l; i++ ) { var elem = checkSet[i]; if ( elem ) { var match = false; elem = elem[dir]; while ( elem ) { if ( elem[ expando ] === doneName ) { match = checkSet[elem.sizset]; break; } if ( elem.nodeType === 1 ) { if ( !isXML ) { elem[ expando ] = doneName; elem.sizset = i; } if ( typeof cur !== "string" ) { if ( elem === cur ) { match = true; break; } } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) { match = elem; break; } } elem = elem[dir]; } checkSet[i] = match; } } } if ( document.documentElement.contains ) { Sizzle.contains = function( a, b ) { return a !== b && (a.contains ? a.contains(b) : true); }; } else if ( document.documentElement.compareDocumentPosition ) { Sizzle.contains = function( a, b ) { return !!(a.compareDocumentPosition(b) & 16); }; } else { Sizzle.contains = function() { return false; }; } 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 : 0).documentElement; return documentElement ? documentElement.nodeName !== "HTML" : false; }; var posProcess = function( selector, context, seed ) { var match, tmpSet = [], later = "", root = context.nodeType ? [context] : context; // Position selectors must be done after the filter // And so must :not(positional) so we move all PSEUDOs to the end while ( (match = Expr.match.PSEUDO.exec( selector )) ) { later += match[0]; selector = selector.replace( Expr.match.PSEUDO, "" ); } selector = Expr.relative[selector] ? selector + "*" : selector; for ( var i = 0, l = root.length; i < l; i++ ) { Sizzle( selector, root[i], tmpSet, seed ); } return Sizzle.filter( later, tmpSet ); }; // EXPOSE // Override sizzle attribute retrieval Sizzle.attr = jQuery.attr; Sizzle.selectors.attrMap = {}; jQuery.find = Sizzle; jQuery.expr = Sizzle.selectors; jQuery.expr[":"] = jQuery.expr.filters; jQuery.unique = Sizzle.uniqueSort; jQuery.text = Sizzle.getText; jQuery.isXMLDoc = Sizzle.isXML; jQuery.contains = Sizzle.contains; })(); var runtil = /Until$/, rparentsprev = /^(?:parents|prevUntil|prevAll)/, // Note: This RegExp should be improved, or likely pulled from Sizzle rmultiselector = /,/, isSimple = /^.[^:#\[\.,]*$/, slice = Array.prototype.slice, POS = jQuery.expr.match.globalPOS, // 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 self = this, i, l; if ( typeof selector !== "string" ) { return jQuery( selector ).filter(function() { for ( i = 0, l = self.length; i < l; i++ ) { if ( jQuery.contains( self[ i ], this ) ) { return true; } } }); } var ret = this.pushStack( "", "find", selector ), length, n, r; for ( i = 0, l = this.length; i < l; i++ ) { length = ret.length; jQuery.find( selector, this[i], ret ); if ( i > 0 ) { // Make sure that the results are unique for ( n = length; n < ret.length; n++ ) { for ( r = 0; r < length; r++ ) { if ( ret[r] === ret[n] ) { ret.splice(n--, 1); break; } } } } } return ret; }, has: function( target ) { var targets = jQuery( target ); return this.filter(function() { for ( var i = 0, l = targets.length; i < l; i++ ) { if ( jQuery.contains( this, targets[i] ) ) { return true; } } }); }, not: function( selector ) { return this.pushStack( winnow(this, selector, false), "not", selector); }, filter: function( selector ) { return this.pushStack( winnow(this, selector, true), "filter", selector ); }, is: function( selector ) { return !!selector && ( typeof selector === "string" ? // If this is a positional selector, check membership in the returned set // so $("p:first").is("p:last") won't return true for a doc with two "p". POS.test( selector ) ? jQuery( selector, this.context ).index( this[0] ) >= 0 : jQuery.filter( selector, this ).length > 0 : this.filter( selector ).length > 0 ); }, closest: function( selectors, context ) { var ret = [], i, l, cur = this[0]; // Array (deprecated as of jQuery 1.7) if ( jQuery.isArray( selectors ) ) { var level = 1; while ( cur && cur.ownerDocument && cur !== context ) { for ( i = 0; i < selectors.length; i++ ) { if ( jQuery( cur ).is( selectors[ i ] ) ) { ret.push({ selector: selectors[ i ], elem: cur, level: level }); } } cur = cur.parentNode; level++; } return ret; } // String var pos = POS.test( selectors ) || typeof selectors !== "string" ? jQuery( selectors, context || this.context ) : 0; for ( i = 0, l = this.length; i < l; i++ ) { cur = this[i]; while ( cur ) { if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) { ret.push( cur ); break; } else { cur = cur.parentNode; if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) { break; } } } } ret = ret.length > 1 ? jQuery.unique( ret ) : ret; return this.pushStack( ret, "closest", selectors ); }, // 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.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( isDisconnected( set[0] ) || isDisconnected( all[0] ) ? all : jQuery.unique( all ) ); }, andSelf: function() { return this.add( this.prevObject ); } }); // A painfully simple check to see if an element is disconnected // from a document (should be improved, where feasible). function isDisconnected( node ) { return !node || !node.parentNode || node.parentNode.nodeType === 11; } 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 jQuery.nth( elem, 2, "nextSibling" ); }, prev: function( elem ) { return jQuery.nth( elem, 2, "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.makeArray( elem.childNodes ); } }, function( name, fn ) { jQuery.fn[ name ] = function( until, selector ) { var ret = jQuery.map( this, fn, until ); if ( !runtil.test( name ) ) { selector = until; } if ( selector && typeof selector === "string" ) { ret = jQuery.filter( selector, ret ); } ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret; if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) { ret = ret.reverse(); } return this.pushStack( ret, name, slice.call( arguments ).join(",") ); }; }); jQuery.extend({ filter: function( expr, elems, not ) { if ( not ) { expr = ":not(" + expr + ")"; } return elems.length === 1 ? jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] : jQuery.find.matches(expr, elems); }, 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; }, nth: function( cur, result, dir, elem ) { result = result || 1; var num = 0; for ( ; cur; cur = cur[dir] ) { if ( cur.nodeType === 1 && ++num === result ) { break; } } return cur; }, 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, keep ) { // Can't pass null or undefined to indexOf in Firefox 4 // Set to 0 to skip string check qualifier = qualifier || 0; if ( jQuery.isFunction( qualifier ) ) { return jQuery.grep(elements, function( elem, i ) { var retVal = !!qualifier.call( elem, i, elem ); return retVal === keep; }); } else if ( qualifier.nodeType ) { return jQuery.grep(elements, function( elem, i ) { return ( elem === qualifier ) === keep; }); } else if ( typeof qualifier === "string" ) { var filtered = jQuery.grep(elements, function( elem ) { return elem.nodeType === 1; }); if ( isSimple.test( qualifier ) ) { return jQuery.filter(qualifier, filtered, !keep); } else { qualifier = jQuery.filter( qualifier, filtered ); } } return jQuery.grep(elements, function( elem, i ) { return ( jQuery.inArray( elem, qualifier ) >= 0 ) === keep; }); } 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+="(?:\d+|null)"/g, rleadingWhitespace = /^\s+/, rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig, rtagName = /<([\w:]+)/, rtbody = /]", "i"), // checked="checked" or checked rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, rscriptType = /\/(java|ecma)script/i, rcleanScript = /^\s*", "" ], legend: [ 1, "
", "
" ], thead: [ 1, "", "
" ], tr: [ 2, "", "
" ], td: [ 3, "", "
" ], col: [ 2, "", "
" ], area: [ 1, "", "" ], _default: [ 0, "", "" ] }, safeFragment = createSafeFragment( document ); wrapMap.optgroup = wrapMap.option; wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; wrapMap.th = wrapMap.td; // IE can't serialize and sizzle-1.10.17/speed/libs/000077500000000000000000000000001226755370700152505ustar00rootroot00000000000000sizzle-1.10.17/speed/libs/benchmark/000077500000000000000000000000001226755370700172025ustar00rootroot00000000000000sizzle-1.10.17/speed/libs/benchmark/benchmark.js000066400000000000000000003362621226755370700215060ustar00rootroot00000000000000/*! * Benchmark.js v1.0.0 * Copyright 2010-2012 Mathias Bynens * Based on JSLitmus.js, copyright Robert Kieffer * Modified by John-David Dalton * Available under MIT license */ ;(function(window, undefined) { 'use strict'; /** Used to assign each benchmark an incrimented id */ var counter = 0; /** Detect DOM document object */ var doc = isHostType(window, 'document') && document; /** Detect free variable `define` */ var freeDefine = typeof define == 'function' && typeof define.amd == 'object' && define.amd && define; /** Detect free variable `exports` */ var freeExports = typeof exports == 'object' && exports && (typeof global == 'object' && global && global == global.global && (window = global), exports); /** Detect free variable `require` */ var freeRequire = typeof require == 'function' && require; /** Used to crawl all properties regardless of enumerability */ var getAllKeys = Object.getOwnPropertyNames; /** Used to get property descriptors */ var getDescriptor = Object.getOwnPropertyDescriptor; /** Used in case an object doesn't have its own method */ var hasOwnProperty = {}.hasOwnProperty; /** Used to check if an object is extensible */ var isExtensible = Object.isExtensible || function() { return true; }; /** Used to access Wade Simmons' Node microtime module */ var microtimeObject = req('microtime'); /** Used to access the browser's high resolution timer */ var perfObject = isHostType(window, 'performance') && performance; /** Used to call the browser's high resolution timer */ var perfName = perfObject && ( perfObject.now && 'now' || perfObject.webkitNow && 'webkitNow' ); /** Used to access Node's high resolution timer */ var processObject = isHostType(window, 'process') && process; /** Used to check if an own property is enumerable */ var propertyIsEnumerable = {}.propertyIsEnumerable; /** Used to set property descriptors */ var setDescriptor = Object.defineProperty; /** Used to resolve a value's internal [[Class]] */ var toString = {}.toString; /** Used to prevent a `removeChild` memory leak in IE < 9 */ var trash = doc && doc.createElement('div'); /** Used to integrity check compiled tests */ var uid = 'uid' + (+new Date); /** Used to avoid infinite recursion when methods call each other */ var calledBy = {}; /** Used to avoid hz of Infinity */ var divisors = { '1': 4096, '2': 512, '3': 64, '4': 8, '5': 0 }; /** * T-Distribution two-tailed critical values for 95% confidence * http://www.itl.nist.gov/div898/handbook/eda/section3/eda3672.htm */ var tTable = { '1': 12.706,'2': 4.303, '3': 3.182, '4': 2.776, '5': 2.571, '6': 2.447, '7': 2.365, '8': 2.306, '9': 2.262, '10': 2.228, '11': 2.201, '12': 2.179, '13': 2.16, '14': 2.145, '15': 2.131, '16': 2.12, '17': 2.11, '18': 2.101, '19': 2.093, '20': 2.086, '21': 2.08, '22': 2.074, '23': 2.069, '24': 2.064, '25': 2.06, '26': 2.056, '27': 2.052, '28': 2.048, '29': 2.045, '30': 2.042, 'infinity': 1.96 }; /** * Critical Mann-Whitney U-values for 95% confidence * http://www.saburchill.com/IBbiology/stats/003.html */ var uTable = { '5': [0, 1, 2], '6': [1, 2, 3, 5], '7': [1, 3, 5, 6, 8], '8': [2, 4, 6, 8, 10, 13], '9': [2, 4, 7, 10, 12, 15, 17], '10': [3, 5, 8, 11, 14, 17, 20, 23], '11': [3, 6, 9, 13, 16, 19, 23, 26, 30], '12': [4, 7, 11, 14, 18, 22, 26, 29, 33, 37], '13': [4, 8, 12, 16, 20, 24, 28, 33, 37, 41, 45], '14': [5, 9, 13, 17, 22, 26, 31, 36, 40, 45, 50, 55], '15': [5, 10, 14, 19, 24, 29, 34, 39, 44, 49, 54, 59, 64], '16': [6, 11, 15, 21, 26, 31, 37, 42, 47, 53, 59, 64, 70, 75], '17': [6, 11, 17, 22, 28, 34, 39, 45, 51, 57, 63, 67, 75, 81, 87], '18': [7, 12, 18, 24, 30, 36, 42, 48, 55, 61, 67, 74, 80, 86, 93, 99], '19': [7, 13, 19, 25, 32, 38, 45, 52, 58, 65, 72, 78, 85, 92, 99, 106, 113], '20': [8, 14, 20, 27, 34, 41, 48, 55, 62, 69, 76, 83, 90, 98, 105, 112, 119, 127], '21': [8, 15, 22, 29, 36, 43, 50, 58, 65, 73, 80, 88, 96, 103, 111, 119, 126, 134, 142], '22': [9, 16, 23, 30, 38, 45, 53, 61, 69, 77, 85, 93, 101, 109, 117, 125, 133, 141, 150, 158], '23': [9, 17, 24, 32, 40, 48, 56, 64, 73, 81, 89, 98, 106, 115, 123, 132, 140, 149, 157, 166, 175], '24': [10, 17, 25, 33, 42, 50, 59, 67, 76, 85, 94, 102, 111, 120, 129, 138, 147, 156, 165, 174, 183, 192], '25': [10, 18, 27, 35, 44, 53, 62, 71, 80, 89, 98, 107, 117, 126, 135, 145, 154, 163, 173, 182, 192, 201, 211], '26': [11, 19, 28, 37, 46, 55, 64, 74, 83, 93, 102, 112, 122, 132, 141, 151, 161, 171, 181, 191, 200, 210, 220, 230], '27': [11, 20, 29, 38, 48, 57, 67, 77, 87, 97, 107, 118, 125, 138, 147, 158, 168, 178, 188, 199, 209, 219, 230, 240, 250], '28': [12, 21, 30, 40, 50, 60, 70, 80, 90, 101, 111, 122, 132, 143, 154, 164, 175, 186, 196, 207, 218, 228, 239, 250, 261, 272], '29': [13, 22, 32, 42, 52, 62, 73, 83, 94, 105, 116, 127, 138, 149, 160, 171, 182, 193, 204, 215, 226, 238, 249, 260, 271, 282, 294], '30': [13, 23, 33, 43, 54, 65, 76, 87, 98, 109, 120, 131, 143, 154, 166, 177, 189, 200, 212, 223, 235, 247, 258, 270, 282, 293, 305, 317] }; /** * An object used to flag environments/features. * * @static * @memberOf Benchmark * @type Object */ var support = {}; (function() { /** * Detect Adobe AIR. * * @memberOf Benchmark.support * @type Boolean */ support.air = isClassOf(window.runtime, 'ScriptBridgingProxyObject'); /** * Detect if `arguments` objects have the correct internal [[Class]] value. * * @memberOf Benchmark.support * @type Boolean */ support.argumentsClass = isClassOf(arguments, 'Arguments'); /** * Detect if in a browser environment. * * @memberOf Benchmark.support * @type Boolean */ support.browser = doc && isHostType(window, 'navigator'); /** * Detect if strings support accessing characters by index. * * @memberOf Benchmark.support * @type Boolean */ support.charByIndex = // IE 8 supports indexes on string literals but not string objects ('x'[0] + Object('x')[0]) == 'xx'; /** * Detect if strings have indexes as own properties. * * @memberOf Benchmark.support * @type Boolean */ support.charByOwnIndex = // Narwhal, Rhino, RingoJS, IE 8, and Opera < 10.52 support indexes on // strings but don't detect them as own properties support.charByIndex && hasKey('x', '0'); /** * Detect if Java is enabled/exposed. * * @memberOf Benchmark.support * @type Boolean */ support.java = isClassOf(window.java, 'JavaPackage'); /** * Detect if the Timers API exists. * * @memberOf Benchmark.support * @type Boolean */ support.timeout = isHostType(window, 'setTimeout') && isHostType(window, 'clearTimeout'); /** * Detect if functions support decompilation. * * @name decompilation * @memberOf Benchmark.support * @type Boolean */ try { // Safari 2.x removes commas in object literals // from Function#toString results // http://webk.it/11609 // Firefox 3.6 and Opera 9.25 strip grouping // parentheses from Function#toString results // http://bugzil.la/559438 support.decompilation = Function( 'return (' + (function(x) { return { 'x': '' + (1 + x) + '', 'y': 0 }; }) + ')' )()(0).x === '1'; } catch(e) { support.decompilation = false; } /** * Detect ES5+ property descriptor API. * * @name descriptors * @memberOf Benchmark.support * @type Boolean */ try { var o = {}; support.descriptors = (setDescriptor(o, o, o), 'value' in getDescriptor(o, o)); } catch(e) { support.descriptors = false; } /** * Detect ES5+ Object.getOwnPropertyNames(). * * @name getAllKeys * @memberOf Benchmark.support * @type Boolean */ try { support.getAllKeys = /\bvalueOf\b/.test(getAllKeys(Object.prototype)); } catch(e) { support.getAllKeys = false; } /** * Detect if own properties are iterated before inherited properties (all but IE < 9). * * @name iteratesOwnLast * @memberOf Benchmark.support * @type Boolean */ support.iteratesOwnFirst = (function() { var props = []; function ctor() { this.x = 1; } ctor.prototype = { 'y': 1 }; for (var prop in new ctor) { props.push(prop); } return props[0] == 'x'; }()); /** * Detect if a node's [[Class]] is resolvable (all but IE < 9) * and that the JS engine errors when attempting to coerce an object to a * string without a `toString` property value of `typeof` "function". * * @name nodeClass * @memberOf Benchmark.support * @type Boolean */ try { support.nodeClass = ({ 'toString': 0 } + '', toString.call(doc || 0) != '[object Object]'); } catch(e) { support.nodeClass = true; } }()); /** * Timer object used by `clock()` and `Deferred#resolve`. * * @private * @type Object */ var timer = { /** * The timer namespace object or constructor. * * @private * @memberOf timer * @type Function|Object */ 'ns': Date, /** * Starts the deferred timer. * * @private * @memberOf timer * @param {Object} deferred The deferred instance. */ 'start': null, // lazy defined in `clock()` /** * Stops the deferred timer. * * @private * @memberOf timer * @param {Object} deferred The deferred instance. */ 'stop': null // lazy defined in `clock()` }; /** Shortcut for inverse results */ var noArgumentsClass = !support.argumentsClass, noCharByIndex = !support.charByIndex, noCharByOwnIndex = !support.charByOwnIndex; /** Math shortcuts */ var abs = Math.abs, floor = Math.floor, max = Math.max, min = Math.min, pow = Math.pow, sqrt = Math.sqrt; /*--------------------------------------------------------------------------*/ /** * The Benchmark constructor. * * @constructor * @param {String} name A name to identify the benchmark. * @param {Function|String} fn The test to benchmark. * @param {Object} [options={}] Options object. * @example * * // basic usage (the `new` operator is optional) * var bench = new Benchmark(fn); * * // or using a name first * var bench = new Benchmark('foo', fn); * * // or with options * var bench = new Benchmark('foo', fn, { * * // displayed by Benchmark#toString if `name` is not available * 'id': 'xyz', * * // called when the benchmark starts running * 'onStart': onStart, * * // called after each run cycle * 'onCycle': onCycle, * * // called when aborted * 'onAbort': onAbort, * * // called when a test errors * 'onError': onError, * * // called when reset * 'onReset': onReset, * * // called when the benchmark completes running * 'onComplete': onComplete, * * // compiled/called before the test loop * 'setup': setup, * * // compiled/called after the test loop * 'teardown': teardown * }); * * // or name and options * var bench = new Benchmark('foo', { * * // a flag to indicate the benchmark is deferred * 'defer': true, * * // benchmark test function * 'fn': function(deferred) { * // call resolve() when the deferred test is finished * deferred.resolve(); * } * }); * * // or options only * var bench = new Benchmark({ * * // benchmark name * 'name': 'foo', * * // benchmark test as a string * 'fn': '[1,2,3,4].sort()' * }); * * // a test's `this` binding is set to the benchmark instance * var bench = new Benchmark('foo', function() { * 'My name is '.concat(this.name); // My name is foo * }); */ function Benchmark(name, fn, options) { var me = this; // allow instance creation without the `new` operator if (me == null || me.constructor != Benchmark) { return new Benchmark(name, fn, options); } // juggle arguments if (isClassOf(name, 'Object')) { // 1 argument (options) options = name; } else if (isClassOf(name, 'Function')) { // 2 arguments (fn, options) options = fn; fn = name; } else if (isClassOf(fn, 'Object')) { // 2 arguments (name, options) options = fn; fn = null; me.name = name; } else { // 3 arguments (name, fn [, options]) me.name = name; } setOptions(me, options); me.id || (me.id = ++counter); me.fn == null && (me.fn = fn); me.stats = deepClone(me.stats); me.times = deepClone(me.times); } /** * The Deferred constructor. * * @constructor * @memberOf Benchmark * @param {Object} clone The cloned benchmark instance. */ function Deferred(clone) { var me = this; if (me == null || me.constructor != Deferred) { return new Deferred(clone); } me.benchmark = clone; clock(me); } /** * The Event constructor. * * @constructor * @memberOf Benchmark * @param {String|Object} type The event type. */ function Event(type) { var me = this; return (me == null || me.constructor != Event) ? new Event(type) : (type instanceof Event) ? type : extend(me, { 'timeStamp': +new Date }, typeof type == 'string' ? { 'type': type } : type); } /** * The Suite constructor. * * @constructor * @memberOf Benchmark * @param {String} name A name to identify the suite. * @param {Object} [options={}] Options object. * @example * * // basic usage (the `new` operator is optional) * var suite = new Benchmark.Suite; * * // or using a name first * var suite = new Benchmark.Suite('foo'); * * // or with options * var suite = new Benchmark.Suite('foo', { * * // called when the suite starts running * 'onStart': onStart, * * // called between running benchmarks * 'onCycle': onCycle, * * // called when aborted * 'onAbort': onAbort, * * // called when a test errors * 'onError': onError, * * // called when reset * 'onReset': onReset, * * // called when the suite completes running * 'onComplete': onComplete * }); */ function Suite(name, options) { var me = this; // allow instance creation without the `new` operator if (me == null || me.constructor != Suite) { return new Suite(name, options); } // juggle arguments if (isClassOf(name, 'Object')) { // 1 argument (options) options = name; } else { // 2 arguments (name [, options]) me.name = name; } setOptions(me, options); } /*--------------------------------------------------------------------------*/ /** * Note: Some array methods have been implemented in plain JavaScript to avoid * bugs in IE, Opera, Rhino, and Mobile Safari. * * IE compatibility mode and IE < 9 have buggy Array `shift()` and `splice()` * functions that fail to remove the last element, `object[0]`, of * array-like-objects even though the `length` property is set to `0`. * The `shift()` method is buggy in IE 8 compatibility mode, while `splice()` * is buggy regardless of mode in IE < 9 and buggy in compatibility mode in IE 9. * * In Opera < 9.50 and some older/beta Mobile Safari versions using `unshift()` * generically to augment the `arguments` object will pave the value at index 0 * without incrimenting the other values's indexes. * https://github.com/documentcloud/underscore/issues/9 * * Rhino and environments it powers, like Narwhal and RingoJS, may have * buggy Array `concat()`, `reverse()`, `shift()`, `slice()`, `splice()` and * `unshift()` functions that make sparse arrays non-sparse by assigning the * undefined indexes a value of undefined. * https://github.com/mozilla/rhino/commit/702abfed3f8ca043b2636efd31c14ba7552603dd */ /** * Creates an array containing the elements of the host array followed by the * elements of each argument in order. * * @memberOf Benchmark.Suite * @returns {Array} The new array. */ function concat() { var value, j = -1, length = arguments.length, result = slice.call(this), index = result.length; while (++j < length) { value = arguments[j]; if (isClassOf(value, 'Array')) { for (var k = 0, l = value.length; k < l; k++, index++) { if (k in value) { result[index] = value[k]; } } } else { result[index++] = value; } } return result; } /** * Utility function used by `shift()`, `splice()`, and `unshift()`. * * @private * @param {Number} start The index to start inserting elements. * @param {Number} deleteCount The number of elements to delete from the insert point. * @param {Array} elements The elements to insert. * @returns {Array} An array of deleted elements. */ function insert(start, deleteCount, elements) { // `result` should have its length set to the `deleteCount` // see https://bugs.ecmascript.org/show_bug.cgi?id=332 var deleteEnd = start + deleteCount, elementCount = elements ? elements.length : 0, index = start - 1, length = start + elementCount, object = this, result = Array(deleteCount), tail = slice.call(object, deleteEnd); // delete elements from the array while (++index < deleteEnd) { if (index in object) { result[index - start] = object[index]; delete object[index]; } } // insert elements index = start - 1; while (++index < length) { object[index] = elements[index - start]; } // append tail elements start = index--; length = max(0, (object.length >>> 0) - deleteCount + elementCount); while (++index < length) { if ((index - start) in tail) { object[index] = tail[index - start]; } else if (index in object) { delete object[index]; } } // delete excess elements deleteCount = deleteCount > elementCount ? deleteCount - elementCount : 0; while (deleteCount--) { index = length + deleteCount; if (index in object) { delete object[index]; } } object.length = length; return result; } /** * Rearrange the host array's elements in reverse order. * * @memberOf Benchmark.Suite * @returns {Array} The reversed array. */ function reverse() { var upperIndex, value, index = -1, object = Object(this), length = object.length >>> 0, middle = floor(length / 2); if (length > 1) { while (++index < middle) { upperIndex = length - index - 1; value = upperIndex in object ? object[upperIndex] : uid; if (index in object) { object[upperIndex] = object[index]; } else { delete object[upperIndex]; } if (value != uid) { object[index] = value; } else { delete object[index]; } } } return object; } /** * Removes the first element of the host array and returns it. * * @memberOf Benchmark.Suite * @returns {Mixed} The first element of the array. */ function shift() { return insert.call(this, 0, 1)[0]; } /** * Creates an array of the host array's elements from the start index up to, * but not including, the end index. * * @memberOf Benchmark.Suite * @param {Number} start The starting index. * @param {Number} end The end index. * @returns {Array} The new array. */ function slice(start, end) { var index = -1, object = Object(this), length = object.length >>> 0, result = []; start = toInteger(start); start = start < 0 ? max(length + start, 0) : min(start, length); start--; end = end == null ? length : toInteger(end); end = end < 0 ? max(length + end, 0) : min(end, length); while ((++index, ++start) < end) { if (start in object) { result[index] = object[start]; } } return result; } /** * Allows removing a range of elements and/or inserting elements into the * host array. * * @memberOf Benchmark.Suite * @param {Number} start The start index. * @param {Number} deleteCount The number of elements to delete. * @param {Mixed} [val1, val2, ...] values to insert at the `start` index. * @returns {Array} An array of removed elements. */ function splice(start, deleteCount) { var object = Object(this), length = object.length >>> 0; start = toInteger(start); start = start < 0 ? max(length + start, 0) : min(start, length); // support the de-facto SpiderMonkey extension // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/splice#Parameters // https://bugs.ecmascript.org/show_bug.cgi?id=429 deleteCount = arguments.length == 1 ? length - start : min(max(toInteger(deleteCount), 0), length - start); return insert.call(object, start, deleteCount, slice.call(arguments, 2)); } /** * Converts the specified `value` to an integer. * * @private * @param {Mixed} value The value to convert. * @returns {Number} The resulting integer. */ function toInteger(value) { value = +value; return value === 0 || !isFinite(value) ? value || 0 : value - (value % 1); } /** * Appends arguments to the host array. * * @memberOf Benchmark.Suite * @returns {Number} The new length. */ function unshift() { var object = Object(this); insert.call(object, 0, 0, arguments); return object.length; } /*--------------------------------------------------------------------------*/ /** * A generic `Function#bind` like method. * * @private * @param {Function} fn The function to be bound to `thisArg`. * @param {Mixed} thisArg The `this` binding for the given function. * @returns {Function} The bound function. */ function bind(fn, thisArg) { return function() { fn.apply(thisArg, arguments); }; } /** * Creates a function from the given arguments string and body. * * @private * @param {String} args The comma separated function arguments. * @param {String} body The function body. * @returns {Function} The new function. */ function createFunction() { // lazy define createFunction = function(args, body) { var result, anchor = freeDefine ? define.amd : Benchmark, prop = uid + 'createFunction'; runScript((freeDefine ? 'define.amd.' : 'Benchmark.') + prop + '=function(' + args + '){' + body + '}'); result = anchor[prop]; delete anchor[prop]; return result; }; // fix JaegerMonkey bug // http://bugzil.la/639720 createFunction = support.browser && (createFunction('', 'return"' + uid + '"') || noop)() == uid ? createFunction : Function; return createFunction.apply(null, arguments); } /** * Delay the execution of a function based on the benchmark's `delay` property. * * @private * @param {Object} bench The benchmark instance. * @param {Object} fn The function to execute. */ function delay(bench, fn) { bench._timerId = setTimeout(fn, bench.delay * 1e3); } /** * Destroys the given element. * * @private * @param {Element} element The element to destroy. */ function destroyElement(element) { trash.appendChild(element); trash.innerHTML = ''; } /** * Iterates over an object's properties, executing the `callback` for each. * Callbacks may terminate the loop by explicitly returning `false`. * * @private * @param {Object} object The object to iterate over. * @param {Function} callback The function executed per own property. * @param {Object} options The options object. * @returns {Object} Returns the object iterated over. */ function forProps() { var forShadowed, skipSeen, forArgs = true, shadowed = ['constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'toLocaleString', 'toString', 'valueOf']; (function(enumFlag, key) { // must use a non-native constructor to catch the Safari 2 issue function Klass() { this.valueOf = 0; }; Klass.prototype.valueOf = 0; // check various for-in bugs for (key in new Klass) { enumFlag += key == 'valueOf' ? 1 : 0; } // check if `arguments` objects have non-enumerable indexes for (key in arguments) { key == '0' && (forArgs = false); } // Safari 2 iterates over shadowed properties twice // http://replay.waybackmachine.org/20090428222941/http://tobielangel.com/2007/1/29/for-in-loop-broken-in-safari/ skipSeen = enumFlag == 2; // IE < 9 incorrectly makes an object's properties non-enumerable if they have // the same name as other non-enumerable properties in its prototype chain. forShadowed = !enumFlag; }(0)); // lazy define forProps = function(object, callback, options) { options || (options = {}); var result = object; object = Object(object); var ctor, key, keys, skipCtor, done = !result, which = options.which, allFlag = which == 'all', index = -1, iteratee = object, length = object.length, ownFlag = allFlag || which == 'own', seen = {}, skipProto = isClassOf(object, 'Function'), thisArg = options.bind; if (thisArg !== undefined) { callback = bind(callback, thisArg); } // iterate all properties if (allFlag && support.getAllKeys) { for (index = 0, keys = getAllKeys(object), length = keys.length; index < length; index++) { key = keys[index]; if (callback(object[key], key, object) === false) { break; } } } // else iterate only enumerable properties else { for (key in object) { // Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1 // (if the prototype or a property on the prototype has been set) // incorrectly set a function's `prototype` property [[Enumerable]] value // to `true`. Because of this we standardize on skipping the `prototype` // property of functions regardless of their [[Enumerable]] value. if ((done = !(skipProto && key == 'prototype') && !(skipSeen && (hasKey(seen, key) || !(seen[key] = true))) && (!ownFlag || ownFlag && hasKey(object, key)) && callback(object[key], key, object) === false)) { break; } } // in IE < 9 strings don't support accessing characters by index if (!done && (forArgs && isArguments(object) || ((noCharByIndex || noCharByOwnIndex) && isClassOf(object, 'String') && (iteratee = noCharByIndex ? object.split('') : object)))) { while (++index < length) { if ((done = callback(iteratee[index], String(index), object) === false)) { break; } } } if (!done && forShadowed) { // Because IE < 9 can't set the `[[Enumerable]]` attribute of an existing // property and the `constructor` property of a prototype defaults to // non-enumerable, we manually skip the `constructor` property when we // think we are iterating over a `prototype` object. ctor = object.constructor; skipCtor = ctor && ctor.prototype && ctor.prototype.constructor === ctor; for (index = 0; index < 7; index++) { key = shadowed[index]; if (!(skipCtor && key == 'constructor') && hasKey(object, key) && callback(object[key], key, object) === false) { break; } } } } return result; }; return forProps.apply(null, arguments); } /** * Gets the name of the first argument from a function's source. * * @private * @param {Function} fn The function. * @returns {String} The argument name. */ function getFirstArgument(fn) { return (!hasKey(fn, 'toString') && (/^[\s(]*function[^(]*\(([^\s,)]+)/.exec(fn) || 0)[1]) || ''; } /** * Computes the arithmetic mean of a sample. * * @private * @param {Array} sample The sample. * @returns {Number} The mean. */ function getMean(sample) { return reduce(sample, function(sum, x) { return sum + x; }) / sample.length || 0; } /** * Gets the source code of a function. * * @private * @param {Function} fn The function. * @param {String} altSource A string used when a function's source code is unretrievable. * @returns {String} The function's source code. */ function getSource(fn, altSource) { var result = altSource; if (isStringable(fn)) { result = String(fn); } else if (support.decompilation) { // escape the `{` for Firefox 1 result = (/^[^{]+\{([\s\S]*)}\s*$/.exec(fn) || 0)[1]; } // trim string result = (result || '').replace(/^\s+|\s+$/g, ''); // detect strings containing only the "use strict" directive return /^(?:\/\*+[\w|\W]*?\*\/|\/\/.*?[\n\r\u2028\u2029]|\s)*(["'])use strict\1;?$/.test(result) ? '' : result; } /** * Checks if a value is an `arguments` object. * * @private * @param {Mixed} value The value to check. * @returns {Boolean} Returns `true` if the value is an `arguments` object, else `false`. */ function isArguments() { // lazy define isArguments = function(value) { return toString.call(value) == '[object Arguments]'; }; if (noArgumentsClass) { isArguments = function(value) { return hasKey(value, 'callee') && !(propertyIsEnumerable && propertyIsEnumerable.call(value, 'callee')); }; } return isArguments(arguments[0]); } /** * Checks if an object is of the specified class. * * @private * @param {Mixed} value The value to check. * @param {String} name The name of the class. * @returns {Boolean} Returns `true` if the value is of the specified class, else `false`. */ function isClassOf(value, name) { return value != null && toString.call(value) == '[object ' + name + ']'; } /** * Host objects can return type values that are different from their actual * data type. The objects we are concerned with usually return non-primitive * types of object, function, or unknown. * * @private * @param {Mixed} object The owner of the property. * @param {String} property The property to check. * @returns {Boolean} Returns `true` if the property value is a non-primitive, else `false`. */ function isHostType(object, property) { var type = object != null ? typeof object[property] : 'number'; return !/^(?:boolean|number|string|undefined)$/.test(type) && (type == 'object' ? !!object[property] : true); } /** * Checks if a given `value` is an object created by the `Object` constructor * assuming objects created by the `Object` constructor have no inherited * enumerable properties and that there are no `Object.prototype` extensions. * * @private * @param {Mixed} value The value to check. * @returns {Boolean} Returns `true` if the `value` is a plain `Object` object, else `false`. */ function isPlainObject(value) { // avoid non-objects and false positives for `arguments` objects in IE < 9 var result = false; if (!(value && typeof value == 'object') || isArguments(value)) { return result; } // IE < 9 presents DOM nodes as `Object` objects except they have `toString` // methods that are `typeof` "string" and still can coerce nodes to strings. // Also check that the constructor is `Object` (i.e. `Object instanceof Object`) var ctor = value.constructor; if ((support.nodeClass || !(typeof value.toString != 'function' && typeof (value + '') == 'string')) && (!isClassOf(ctor, 'Function') || ctor instanceof ctor)) { // In most environments an object's own properties are iterated before // its inherited properties. If the last iterated property is an object's // own property then there are no inherited enumerable properties. if (support.iteratesOwnFirst) { forProps(value, function(subValue, subKey) { result = subKey; }); return result === false || hasKey(value, result); } // IE < 9 iterates inherited properties before own properties. If the first // iterated property is an object's own property then there are no inherited // enumerable properties. forProps(value, function(subValue, subKey) { result = !hasKey(value, subKey); return false; }); return result === false; } return result; } /** * Checks if a value can be safely coerced to a string. * * @private * @param {Mixed} value The value to check. * @returns {Boolean} Returns `true` if the value can be coerced, else `false`. */ function isStringable(value) { return hasKey(value, 'toString') || isClassOf(value, 'String'); } /** * Wraps a function and passes `this` to the original function as the * first argument. * * @private * @param {Function} fn The function to be wrapped. * @returns {Function} The new function. */ function methodize(fn) { return function() { var args = [this]; args.push.apply(args, arguments); return fn.apply(null, args); }; } /** * A no-operation function. * * @private */ function noop() { // no operation performed } /** * A wrapper around require() to suppress `module missing` errors. * * @private * @param {String} id The module id. * @returns {Mixed} The exported module or `null`. */ function req(id) { try { var result = freeExports && freeRequire(id); } catch(e) { } return result || null; } /** * Runs a snippet of JavaScript via script injection. * * @private * @param {String} code The code to run. */ function runScript(code) { var anchor = freeDefine ? define.amd : Benchmark, script = doc.createElement('script'), sibling = doc.getElementsByTagName('script')[0], parent = sibling.parentNode, prop = uid + 'runScript', prefix = '(' + (freeDefine ? 'define.amd.' : 'Benchmark.') + prop + '||function(){})();'; // Firefox 2.0.0.2 cannot use script injection as intended because it executes // asynchronously, but that's OK because script injection is only used to avoid // the previously commented JaegerMonkey bug. try { // remove the inserted script *before* running the code to avoid differences // in the expected script element count/order of the document. script.appendChild(doc.createTextNode(prefix + code)); anchor[prop] = function() { destroyElement(script); }; } catch(e) { parent = parent.cloneNode(false); sibling = null; script.text = code; } parent.insertBefore(script, sibling); delete anchor[prop]; } /** * A helper function for setting options/event handlers. * * @private * @param {Object} bench The benchmark instance. * @param {Object} [options={}] Options object. */ function setOptions(bench, options) { options = extend({}, bench.constructor.options, options); bench.options = forOwn(options, function(value, key) { if (value != null) { // add event listeners if (/^on[A-Z]/.test(key)) { forEach(key.split(' '), function(key) { bench.on(key.slice(2).toLowerCase(), value); }); } else if (!hasKey(bench, key)) { bench[key] = deepClone(value); } } }); } /*--------------------------------------------------------------------------*/ /** * Handles cycling/completing the deferred benchmark. * * @memberOf Benchmark.Deferred */ function resolve() { var me = this, clone = me.benchmark, bench = clone._original; if (bench.aborted) { // cycle() -> clone cycle/complete event -> compute()'s invoked bench.run() cycle/complete me.teardown(); clone.running = false; cycle(me); } else if (++me.cycles < clone.count) { // continue the test loop if (support.timeout) { // use setTimeout to avoid a call stack overflow if called recursively setTimeout(function() { clone.compiled.call(me, timer); }, 0); } else { clone.compiled.call(me, timer); } } else { timer.stop(me); me.teardown(); delay(clone, function() { cycle(me); }); } } /*--------------------------------------------------------------------------*/ /** * A deep clone utility. * * @static * @memberOf Benchmark * @param {Mixed} value The value to clone. * @returns {Mixed} The cloned value. */ function deepClone(value) { var accessor, circular, clone, ctor, descriptor, extensible, key, length, markerKey, parent, result, source, subIndex, data = { 'value': value }, index = 0, marked = [], queue = { 'length': 0 }, unmarked = []; /** * An easily detectable decorator for cloned values. */ function Marker(object) { this.raw = object; } /** * The callback used by `forProps()`. */ function forPropsCallback(subValue, subKey) { // exit early to avoid cloning the marker if (subValue && subValue.constructor == Marker) { return; } // add objects to the queue if (subValue === Object(subValue)) { queue[queue.length++] = { 'key': subKey, 'parent': clone, 'source': value }; } // assign non-objects else { try { // will throw an error in strict mode if the property is read-only clone[subKey] = subValue; } catch(e) { } } } /** * Gets an available marker key for the given object. */ function getMarkerKey(object) { // avoid collisions with existing keys var result = uid; while (object[result] && object[result].constructor != Marker) { result += 1; } return result; } do { key = data.key; parent = data.parent; source = data.source; clone = value = source ? source[key] : data.value; accessor = circular = descriptor = false; // create a basic clone to filter out functions, DOM elements, and // other non `Object` objects if (value === Object(value)) { // use custom deep clone function if available if (isClassOf(value.deepClone, 'Function')) { clone = value.deepClone(); } else { ctor = value.constructor; switch (toString.call(value)) { case '[object Array]': clone = new ctor(value.length); break; case '[object Boolean]': clone = new ctor(value == true); break; case '[object Date]': clone = new ctor(+value); break; case '[object Object]': isPlainObject(value) && (clone = {}); break; case '[object Number]': case '[object String]': clone = new ctor(value); break; case '[object RegExp]': clone = ctor(value.source, (value.global ? 'g' : '') + (value.ignoreCase ? 'i' : '') + (value.multiline ? 'm' : '')); } } // continue clone if `value` doesn't have an accessor descriptor // http://es5.github.com/#x8.10.1 if (clone && clone != value && !(descriptor = source && support.descriptors && getDescriptor(source, key), accessor = descriptor && (descriptor.get || descriptor.set))) { // use an existing clone (circular reference) if ((extensible = isExtensible(value))) { markerKey = getMarkerKey(value); if (value[markerKey]) { circular = clone = value[markerKey].raw; } } else { // for frozen/sealed objects for (subIndex = 0, length = unmarked.length; subIndex < length; subIndex++) { data = unmarked[subIndex]; if (data.object === value) { circular = clone = data.clone; break; } } } if (!circular) { // mark object to allow quickly detecting circular references and tie it to its clone if (extensible) { value[markerKey] = new Marker(clone); marked.push({ 'key': markerKey, 'object': value }); } else { // for frozen/sealed objects unmarked.push({ 'clone': clone, 'object': value }); } // iterate over object properties forProps(value, forPropsCallback, { 'which': 'all' }); } } } if (parent) { // for custom property descriptors if (accessor || (descriptor && !(descriptor.configurable && descriptor.enumerable && descriptor.writable))) { if ('value' in descriptor) { descriptor.value = clone; } setDescriptor(parent, key, descriptor); } // for default property descriptors else { parent[key] = clone; } } else { result = clone; } } while ((data = queue[index++])); // remove markers for (index = 0, length = marked.length; index < length; index++) { data = marked[index]; delete data.object[data.key]; } return result; } /** * An iteration utility for arrays and objects. * Callbacks may terminate the loop by explicitly returning `false`. * * @static * @memberOf Benchmark * @param {Array|Object} object The object to iterate over. * @param {Function} callback The function called per iteration. * @param {Mixed} thisArg The `this` binding for the callback. * @returns {Array|Object} Returns the object iterated over. */ function each(object, callback, thisArg) { var result = object; object = Object(object); var fn = callback, index = -1, length = object.length, isSnapshot = !!(object.snapshotItem && (length = object.snapshotLength)), isSplittable = (noCharByIndex || noCharByOwnIndex) && isClassOf(object, 'String'), isConvertable = isSnapshot || isSplittable || 'item' in object, origObject = object; // in Opera < 10.5 `hasKey(object, 'length')` returns `false` for NodeLists if (length === length >>> 0) { if (isConvertable) { // the third argument of the callback is the original non-array object callback = function(value, index) { return fn.call(this, value, index, origObject); }; // in IE < 9 strings don't support accessing characters by index if (isSplittable) { object = object.split(''); } else { object = []; while (++index < length) { // in Safari 2 `index in object` is always `false` for NodeLists object[index] = isSnapshot ? result.snapshotItem(index) : result[index]; } } } forEach(object, callback, thisArg); } else { forOwn(object, callback, thisArg); } return result; } /** * Copies enumerable properties from the source(s) object to the destination object. * * @static * @memberOf Benchmark * @param {Object} destination The destination object. * @param {Object} [source={}] The source object. * @returns {Object} The destination object. */ function extend(destination, source) { // Chrome < 14 incorrectly sets `destination` to `undefined` when we `delete arguments[0]` // http://code.google.com/p/v8/issues/detail?id=839 var result = destination; delete arguments[0]; forEach(arguments, function(source) { forProps(source, function(value, key) { result[key] = value; }); }); return result; } /** * A generic `Array#filter` like method. * * @static * @memberOf Benchmark * @param {Array} array The array to iterate over. * @param {Function|String} callback The function/alias called per iteration. * @param {Mixed} thisArg The `this` binding for the callback. * @returns {Array} A new array of values that passed callback filter. * @example * * // get odd numbers * Benchmark.filter([1, 2, 3, 4, 5], function(n) { * return n % 2; * }); // -> [1, 3, 5]; * * // get fastest benchmarks * Benchmark.filter(benches, 'fastest'); * * // get slowest benchmarks * Benchmark.filter(benches, 'slowest'); * * // get benchmarks that completed without erroring * Benchmark.filter(benches, 'successful'); */ function filter(array, callback, thisArg) { var result; if (callback == 'successful') { // callback to exclude those that are errored, unrun, or have hz of Infinity callback = function(bench) { return bench.cycles && isFinite(bench.hz); }; } else if (callback == 'fastest' || callback == 'slowest') { // get successful, sort by period + margin of error, and filter fastest/slowest result = filter(array, 'successful').sort(function(a, b) { a = a.stats; b = b.stats; return (a.mean + a.moe > b.mean + b.moe ? 1 : -1) * (callback == 'fastest' ? 1 : -1); }); result = filter(result, function(bench) { return result[0].compare(bench) == 0; }); } return result || reduce(array, function(result, value, index) { return callback.call(thisArg, value, index, array) ? (result.push(value), result) : result; }, []); } /** * A generic `Array#forEach` like method. * Callbacks may terminate the loop by explicitly returning `false`. * * @static * @memberOf Benchmark * @param {Array} array The array to iterate over. * @param {Function} callback The function called per iteration. * @param {Mixed} thisArg The `this` binding for the callback. * @returns {Array} Returns the array iterated over. */ function forEach(array, callback, thisArg) { var index = -1, length = (array = Object(array)).length >>> 0; if (thisArg !== undefined) { callback = bind(callback, thisArg); } while (++index < length) { if (index in array && callback(array[index], index, array) === false) { break; } } return array; } /** * Iterates over an object's own properties, executing the `callback` for each. * Callbacks may terminate the loop by explicitly returning `false`. * * @static * @memberOf Benchmark * @param {Object} object The object to iterate over. * @param {Function} callback The function executed per own property. * @param {Mixed} thisArg The `this` binding for the callback. * @returns {Object} Returns the object iterated over. */ function forOwn(object, callback, thisArg) { return forProps(object, callback, { 'bind': thisArg, 'which': 'own' }); } /** * Converts a number to a more readable comma-separated string representation. * * @static * @memberOf Benchmark * @param {Number} number The number to convert. * @returns {String} The more readable string representation. */ function formatNumber(number) { number = String(number).split('.'); return number[0].replace(/(?=(?:\d{3})+$)(?!\b)/g, ',') + (number[1] ? '.' + number[1] : ''); } /** * Checks if an object has the specified key as a direct property. * * @static * @memberOf Benchmark * @param {Object} object The object to check. * @param {String} key The key to check for. * @returns {Boolean} Returns `true` if key is a direct property, else `false`. */ function hasKey() { // lazy define for worst case fallback (not as accurate) hasKey = function(object, key) { var parent = object != null && (object.constructor || Object).prototype; return !!parent && key in Object(object) && !(key in parent && object[key] === parent[key]); }; // for modern browsers if (isClassOf(hasOwnProperty, 'Function')) { hasKey = function(object, key) { return object != null && hasOwnProperty.call(object, key); }; } // for Safari 2 else if ({}.__proto__ == Object.prototype) { hasKey = function(object, key) { var result = false; if (object != null) { object = Object(object); object.__proto__ = [object.__proto__, object.__proto__ = null, result = key in object][0]; } return result; }; } return hasKey.apply(this, arguments); } /** * A generic `Array#indexOf` like method. * * @static * @memberOf Benchmark * @param {Array} array The array to iterate over. * @param {Mixed} value The value to search for. * @param {Number} [fromIndex=0] The index to start searching from. * @returns {Number} The index of the matched value or `-1`. */ function indexOf(array, value, fromIndex) { var index = toInteger(fromIndex), length = (array = Object(array)).length >>> 0; index = (index < 0 ? max(0, length + index) : index) - 1; while (++index < length) { if (index in array && value === array[index]) { return index; } } return -1; } /** * Modify a string by replacing named tokens with matching object property values. * * @static * @memberOf Benchmark * @param {String} string The string to modify. * @param {Object} object The template object. * @returns {String} The modified string. */ function interpolate(string, object) { forOwn(object, function(value, key) { // escape regexp special characters in `key` string = string.replace(RegExp('#\\{' + key.replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1') + '\\}', 'g'), value); }); return string; } /** * Invokes a method on all items in an array. * * @static * @memberOf Benchmark * @param {Array} benches Array of benchmarks to iterate over. * @param {String|Object} name The name of the method to invoke OR options object. * @param {Mixed} [arg1, arg2, ...] Arguments to invoke the method with. * @returns {Array} A new array of values returned from each method invoked. * @example * * // invoke `reset` on all benchmarks * Benchmark.invoke(benches, 'reset'); * * // invoke `emit` with arguments * Benchmark.invoke(benches, 'emit', 'complete', listener); * * // invoke `run(true)`, treat benchmarks as a queue, and register invoke callbacks * Benchmark.invoke(benches, { * * // invoke the `run` method * 'name': 'run', * * // pass a single argument * 'args': true, * * // treat as queue, removing benchmarks from front of `benches` until empty * 'queued': true, * * // called before any benchmarks have been invoked. * 'onStart': onStart, * * // called between invoking benchmarks * 'onCycle': onCycle, * * // called after all benchmarks have been invoked. * 'onComplete': onComplete * }); */ function invoke(benches, name) { var args, bench, queued, index = -1, eventProps = { 'currentTarget': benches }, options = { 'onStart': noop, 'onCycle': noop, 'onComplete': noop }, result = map(benches, function(bench) { return bench; }); /** * Invokes the method of the current object and if synchronous, fetches the next. */ function execute() { var listeners, async = isAsync(bench); if (async) { // use `getNext` as the first listener bench.on('complete', getNext); listeners = bench.events.complete; listeners.splice(0, 0, listeners.pop()); } // execute method result[index] = isClassOf(bench && bench[name], 'Function') ? bench[name].apply(bench, args) : undefined; // if synchronous return true until finished return !async && getNext(); } /** * Fetches the next bench or executes `onComplete` callback. */ function getNext(event) { var cycleEvent, last = bench, async = isAsync(last); if (async) { last.off('complete', getNext); last.emit('complete'); } // emit "cycle" event eventProps.type = 'cycle'; eventProps.target = last; cycleEvent = Event(eventProps); options.onCycle.call(benches, cycleEvent); // choose next benchmark if not exiting early if (!cycleEvent.aborted && raiseIndex() !== false) { bench = queued ? benches[0] : result[index]; if (isAsync(bench)) { delay(bench, execute); } else if (async) { // resume execution if previously asynchronous but now synchronous while (execute()) { } } else { // continue synchronous execution return true; } } else { // emit "complete" event eventProps.type = 'complete'; options.onComplete.call(benches, Event(eventProps)); } // When used as a listener `event.aborted = true` will cancel the rest of // the "complete" listeners because they were already called above and when // used as part of `getNext` the `return false` will exit the execution while-loop. if (event) { event.aborted = true; } else { return false; } } /** * Checks if invoking `Benchmark#run` with asynchronous cycles. */ function isAsync(object) { // avoid using `instanceof` here because of IE memory leak issues with host objects var async = args[0] && args[0].async; return Object(object).constructor == Benchmark && name == 'run' && ((async == null ? object.options.async : async) && support.timeout || object.defer); } /** * Raises `index` to the next defined index or returns `false`. */ function raiseIndex() { var length = result.length; if (queued) { // if queued remove the previous bench and subsequent skipped non-entries do { ++index > 0 && shift.call(benches); } while ((length = benches.length) && !('0' in benches)); } else { while (++index < length && !(index in result)) { } } // if we reached the last index then return `false` return (queued ? length : index < length) ? index : (index = false); } // juggle arguments if (isClassOf(name, 'String')) { // 2 arguments (array, name) args = slice.call(arguments, 2); } else { // 2 arguments (array, options) options = extend(options, name); name = options.name; args = isClassOf(args = 'args' in options ? options.args : [], 'Array') ? args : [args]; queued = options.queued; } // start iterating over the array if (raiseIndex() !== false) { // emit "start" event bench = result[index]; eventProps.type = 'start'; eventProps.target = bench; options.onStart.call(benches, Event(eventProps)); // end early if the suite was aborted in an "onStart" listener if (benches.aborted && benches.constructor == Suite && name == 'run') { // emit "cycle" event eventProps.type = 'cycle'; options.onCycle.call(benches, Event(eventProps)); // emit "complete" event eventProps.type = 'complete'; options.onComplete.call(benches, Event(eventProps)); } // else start else { if (isAsync(bench)) { delay(bench, execute); } else { while (execute()) { } } } } return result; } /** * Creates a string of joined array values or object key-value pairs. * * @static * @memberOf Benchmark * @param {Array|Object} object The object to operate on. * @param {String} [separator1=','] The separator used between key-value pairs. * @param {String} [separator2=': '] The separator used between keys and values. * @returns {String} The joined result. */ function join(object, separator1, separator2) { var result = [], length = (object = Object(object)).length, arrayLike = length === length >>> 0; separator2 || (separator2 = ': '); each(object, function(value, key) { result.push(arrayLike ? value : key + separator2 + value); }); return result.join(separator1 || ','); } /** * A generic `Array#map` like method. * * @static * @memberOf Benchmark * @param {Array} array The array to iterate over. * @param {Function} callback The function called per iteration. * @param {Mixed} thisArg The `this` binding for the callback. * @returns {Array} A new array of values returned by the callback. */ function map(array, callback, thisArg) { return reduce(array, function(result, value, index) { result[index] = callback.call(thisArg, value, index, array); return result; }, Array(Object(array).length >>> 0)); } /** * Retrieves the value of a specified property from all items in an array. * * @static * @memberOf Benchmark * @param {Array} array The array to iterate over. * @param {String} property The property to pluck. * @returns {Array} A new array of property values. */ function pluck(array, property) { return map(array, function(object) { return object == null ? undefined : object[property]; }); } /** * A generic `Array#reduce` like method. * * @static * @memberOf Benchmark * @param {Array} array The array to iterate over. * @param {Function} callback The function called per iteration. * @param {Mixed} accumulator Initial value of the accumulator. * @returns {Mixed} The accumulator. */ function reduce(array, callback, accumulator) { var noaccum = arguments.length < 3; forEach(array, function(value, index) { accumulator = noaccum ? (noaccum = false, value) : callback(accumulator, value, index, array); }); return accumulator; } /*--------------------------------------------------------------------------*/ /** * Aborts all benchmarks in the suite. * * @name abort * @memberOf Benchmark.Suite * @returns {Object} The suite instance. */ function abortSuite() { var event, me = this, resetting = calledBy.resetSuite; if (me.running) { event = Event('abort'); me.emit(event); if (!event.cancelled || resetting) { // avoid infinite recursion calledBy.abortSuite = true; me.reset(); delete calledBy.abortSuite; if (!resetting) { me.aborted = true; invoke(me, 'abort'); } } } return me; } /** * Adds a test to the benchmark suite. * * @memberOf Benchmark.Suite * @param {String} name A name to identify the benchmark. * @param {Function|String} fn The test to benchmark. * @param {Object} [options={}] Options object. * @returns {Object} The benchmark instance. * @example * * // basic usage * suite.add(fn); * * // or using a name first * suite.add('foo', fn); * * // or with options * suite.add('foo', fn, { * 'onCycle': onCycle, * 'onComplete': onComplete * }); * * // or name and options * suite.add('foo', { * 'fn': fn, * 'onCycle': onCycle, * 'onComplete': onComplete * }); * * // or options only * suite.add({ * 'name': 'foo', * 'fn': fn, * 'onCycle': onCycle, * 'onComplete': onComplete * }); */ function add(name, fn, options) { var me = this, bench = Benchmark(name, fn, options), event = Event({ 'type': 'add', 'target': bench }); if (me.emit(event), !event.cancelled) { me.push(bench); } return me; } /** * Creates a new suite with cloned benchmarks. * * @name clone * @memberOf Benchmark.Suite * @param {Object} options Options object to overwrite cloned options. * @returns {Object} The new suite instance. */ function cloneSuite(options) { var me = this, result = new me.constructor(extend({}, me.options, options)); // copy own properties forOwn(me, function(value, key) { if (!hasKey(result, key)) { result[key] = value && isClassOf(value.clone, 'Function') ? value.clone() : deepClone(value); } }); return result; } /** * An `Array#filter` like method. * * @name filter * @memberOf Benchmark.Suite * @param {Function|String} callback The function/alias called per iteration. * @returns {Object} A new suite of benchmarks that passed callback filter. */ function filterSuite(callback) { var me = this, result = new me.constructor; result.push.apply(result, filter(me, callback)); return result; } /** * Resets all benchmarks in the suite. * * @name reset * @memberOf Benchmark.Suite * @returns {Object} The suite instance. */ function resetSuite() { var event, me = this, aborting = calledBy.abortSuite; if (me.running && !aborting) { // no worries, `resetSuite()` is called within `abortSuite()` calledBy.resetSuite = true; me.abort(); delete calledBy.resetSuite; } // reset if the state has changed else if ((me.aborted || me.running) && (me.emit(event = Event('reset')), !event.cancelled)) { me.running = false; if (!aborting) { invoke(me, 'reset'); } } return me; } /** * Runs the suite. * * @name run * @memberOf Benchmark.Suite * @param {Object} [options={}] Options object. * @returns {Object} The suite instance. * @example * * // basic usage * suite.run(); * * // or with options * suite.run({ 'async': true, 'queued': true }); */ function runSuite(options) { var me = this; me.reset(); me.running = true; options || (options = {}); invoke(me, { 'name': 'run', 'args': options, 'queued': options.queued, 'onStart': function(event) { me.emit(event); }, 'onCycle': function(event) { var bench = event.target; if (bench.error) { me.emit({ 'type': 'error', 'target': bench }); } me.emit(event); event.aborted = me.aborted; }, 'onComplete': function(event) { me.running = false; me.emit(event); } }); return me; } /*--------------------------------------------------------------------------*/ /** * Executes all registered listeners of the specified event type. * * @memberOf Benchmark, Benchmark.Suite * @param {String|Object} type The event type or object. * @returns {Mixed} Returns the return value of the last listener executed. */ function emit(type) { var listeners, me = this, event = Event(type), events = me.events, args = (arguments[0] = event, arguments); event.currentTarget || (event.currentTarget = me); event.target || (event.target = me); delete event.result; if (events && (listeners = hasKey(events, event.type) && events[event.type])) { forEach(listeners.slice(), function(listener) { if ((event.result = listener.apply(me, args)) === false) { event.cancelled = true; } return !event.aborted; }); } return event.result; } /** * Returns an array of event listeners for a given type that can be manipulated * to add or remove listeners. * * @memberOf Benchmark, Benchmark.Suite * @param {String} type The event type. * @returns {Array} The listeners array. */ function listeners(type) { var me = this, events = me.events || (me.events = {}); return hasKey(events, type) ? events[type] : (events[type] = []); } /** * Unregisters a listener for the specified event type(s), * or unregisters all listeners for the specified event type(s), * or unregisters all listeners for all event types. * * @memberOf Benchmark, Benchmark.Suite * @param {String} [type] The event type. * @param {Function} [listener] The function to unregister. * @returns {Object} The benchmark instance. * @example * * // unregister a listener for an event type * bench.off('cycle', listener); * * // unregister a listener for multiple event types * bench.off('start cycle', listener); * * // unregister all listeners for an event type * bench.off('cycle'); * * // unregister all listeners for multiple event types * bench.off('start cycle complete'); * * // unregister all listeners for all event types * bench.off(); */ function off(type, listener) { var me = this, events = me.events; events && each(type ? type.split(' ') : events, function(listeners, type) { var index; if (typeof listeners == 'string') { type = listeners; listeners = hasKey(events, type) && events[type]; } if (listeners) { if (listener) { index = indexOf(listeners, listener); if (index > -1) { listeners.splice(index, 1); } } else { listeners.length = 0; } } }); return me; } /** * Registers a listener for the specified event type(s). * * @memberOf Benchmark, Benchmark.Suite * @param {String} type The event type. * @param {Function} listener The function to register. * @returns {Object} The benchmark instance. * @example * * // register a listener for an event type * bench.on('cycle', listener); * * // register a listener for multiple event types * bench.on('start cycle', listener); */ function on(type, listener) { var me = this, events = me.events || (me.events = {}); forEach(type.split(' '), function(type) { (hasKey(events, type) ? events[type] : (events[type] = []) ).push(listener); }); return me; } /*--------------------------------------------------------------------------*/ /** * Aborts the benchmark without recording times. * * @memberOf Benchmark * @returns {Object} The benchmark instance. */ function abort() { var event, me = this, resetting = calledBy.reset; if (me.running) { event = Event('abort'); me.emit(event); if (!event.cancelled || resetting) { // avoid infinite recursion calledBy.abort = true; me.reset(); delete calledBy.abort; if (support.timeout) { clearTimeout(me._timerId); delete me._timerId; } if (!resetting) { me.aborted = true; me.running = false; } } } return me; } /** * Creates a new benchmark using the same test and options. * * @memberOf Benchmark * @param {Object} options Options object to overwrite cloned options. * @returns {Object} The new benchmark instance. * @example * * var bizarro = bench.clone({ * 'name': 'doppelganger' * }); */ function clone(options) { var me = this, result = new me.constructor(extend({}, me, options)); // correct the `options` object result.options = extend({}, me.options, options); // copy own custom properties forOwn(me, function(value, key) { if (!hasKey(result, key)) { result[key] = deepClone(value); } }); return result; } /** * Determines if a benchmark is faster than another. * * @memberOf Benchmark * @param {Object} other The benchmark to compare. * @returns {Number} Returns `-1` if slower, `1` if faster, and `0` if indeterminate. */ function compare(other) { var critical, zStat, me = this, sample1 = me.stats.sample, sample2 = other.stats.sample, size1 = sample1.length, size2 = sample2.length, maxSize = max(size1, size2), minSize = min(size1, size2), u1 = getU(sample1, sample2), u2 = getU(sample2, sample1), u = min(u1, u2); function getScore(xA, sampleB) { return reduce(sampleB, function(total, xB) { return total + (xB > xA ? 0 : xB < xA ? 1 : 0.5); }, 0); } function getU(sampleA, sampleB) { return reduce(sampleA, function(total, xA) { return total + getScore(xA, sampleB); }, 0); } function getZ(u) { return (u - ((size1 * size2) / 2)) / sqrt((size1 * size2 * (size1 + size2 + 1)) / 12); } // exit early if comparing the same benchmark if (me == other) { return 0; } // reject the null hyphothesis the two samples come from the // same population (i.e. have the same median) if... if (size1 + size2 > 30) { // ...the z-stat is greater than 1.96 or less than -1.96 // http://www.statisticslectures.com/topics/mannwhitneyu/ zStat = getZ(u); return abs(zStat) > 1.96 ? (zStat > 0 ? -1 : 1) : 0; } // ...the U value is less than or equal the critical U value // http://www.geoib.com/mann-whitney-u-test.html critical = maxSize < 5 || minSize < 3 ? 0 : uTable[maxSize][minSize - 3]; return u <= critical ? (u == u1 ? 1 : -1) : 0; } /** * Reset properties and abort if running. * * @memberOf Benchmark * @returns {Object} The benchmark instance. */ function reset() { var data, event, me = this, index = 0, changes = { 'length': 0 }, queue = { 'length': 0 }; if (me.running && !calledBy.abort) { // no worries, `reset()` is called within `abort()` calledBy.reset = true; me.abort(); delete calledBy.reset; } else { // a non-recursive solution to check if properties have changed // http://www.jslab.dk/articles/non.recursive.preorder.traversal.part4 data = { 'destination': me, 'source': extend({}, me.constructor.prototype, me.options) }; do { forOwn(data.source, function(value, key) { var changed, destination = data.destination, currValue = destination[key]; if (value && typeof value == 'object') { if (isClassOf(value, 'Array')) { // check if an array value has changed to a non-array value if (!isClassOf(currValue, 'Array')) { changed = currValue = []; } // or has changed its length if (currValue.length != value.length) { changed = currValue = currValue.slice(0, value.length); currValue.length = value.length; } } // check if an object has changed to a non-object value else if (!currValue || typeof currValue != 'object') { changed = currValue = {}; } // register a changed object if (changed) { changes[changes.length++] = { 'destination': destination, 'key': key, 'value': currValue }; } queue[queue.length++] = { 'destination': currValue, 'source': value }; } // register a changed primitive else if (value !== currValue && !(value == null || isClassOf(value, 'Function'))) { changes[changes.length++] = { 'destination': destination, 'key': key, 'value': value }; } }); } while ((data = queue[index++])); // if changed emit the `reset` event and if it isn't cancelled reset the benchmark if (changes.length && (me.emit(event = Event('reset')), !event.cancelled)) { forEach(changes, function(data) { data.destination[data.key] = data.value; }); } } return me; } /** * Displays relevant benchmark information when coerced to a string. * * @name toString * @memberOf Benchmark * @returns {String} A string representation of the benchmark instance. */ function toStringBench() { var me = this, error = me.error, hz = me.hz, id = me.id, stats = me.stats, size = stats.sample.length, pm = support.java ? '+/-' : '\xb1', result = me.name || (isNaN(id) ? id : ''); if (error) { result += ': ' + join(error); } else { result += ' x ' + formatNumber(hz.toFixed(hz < 100 ? 2 : 0)) + ' ops/sec ' + pm + stats.rme.toFixed(2) + '% (' + size + ' run' + (size == 1 ? '' : 's') + ' sampled)'; } return result; } /*--------------------------------------------------------------------------*/ /** * Clocks the time taken to execute a test per cycle (secs). * * @private * @param {Object} bench The benchmark instance. * @returns {Number} The time taken. */ function clock() { var applet, options = Benchmark.options, template = { 'begin': 's$=new n$', 'end': 'r$=(new n$-s$)/1e3', 'uid': uid }, timers = [{ 'ns': timer.ns, 'res': max(0.0015, getRes('ms')), 'unit': 'ms' }]; // lazy define for hi-res timers clock = function(clone) { var deferred; if (clone instanceof Deferred) { deferred = clone; clone = deferred.benchmark; } var bench = clone._original, fn = bench.fn, fnArg = deferred ? getFirstArgument(fn) || 'deferred' : '', stringable = isStringable(fn); var source = { 'setup': getSource(bench.setup, preprocess('m$.setup()')), 'fn': getSource(fn, preprocess('m$.fn(' + fnArg + ')')), 'fnArg': fnArg, 'teardown': getSource(bench.teardown, preprocess('m$.teardown()')) }; var count = bench.count = clone.count, decompilable = support.decompilation || stringable, id = bench.id, isEmpty = !(source.fn || stringable), name = bench.name || (typeof id == 'number' ? '' : id), ns = timer.ns, result = 0; // init `minTime` if needed clone.minTime = bench.minTime || (bench.minTime = bench.options.minTime = options.minTime); // repair nanosecond timer // (some Chrome builds erase the `ns` variable after millions of executions) if (applet) { try { ns.nanoTime(); } catch(e) { // use non-element to avoid issues with libs that augment them ns = timer.ns = new applet.Packages.nano; } } // Compile in setup/teardown functions and the test loop. // Create a new compiled test, instead of using the cached `bench.compiled`, // to avoid potential engine optimizations enabled over the life of the test. var compiled = bench.compiled = createFunction(preprocess('t$'), interpolate( preprocess(deferred ? 'var d$=this,#{fnArg}=d$,m$=d$.benchmark._original,f$=m$.fn,su$=m$.setup,td$=m$.teardown;' + // when `deferred.cycles` is `0` then... 'if(!d$.cycles){' + // set `deferred.fn` 'd$.fn=function(){var #{fnArg}=d$;if(typeof f$=="function"){try{#{fn}\n}catch(e$){f$(d$)}}else{#{fn}\n}};' + // set `deferred.teardown` 'd$.teardown=function(){d$.cycles=0;if(typeof td$=="function"){try{#{teardown}\n}catch(e$){td$()}}else{#{teardown}\n}};' + // execute the benchmark's `setup` 'if(typeof su$=="function"){try{#{setup}\n}catch(e$){su$()}}else{#{setup}\n};' + // start timer 't$.start(d$);' + // execute `deferred.fn` and return a dummy object '}d$.fn();return{}' : 'var r$,s$,m$=this,f$=m$.fn,i$=m$.count,n$=t$.ns;#{setup}\n#{begin};' + 'while(i$--){#{fn}\n}#{end};#{teardown}\nreturn{elapsed:r$,uid:"#{uid}"}'), source )); try { if (isEmpty) { // Firefox may remove dead code from Function#toString results // http://bugzil.la/536085 throw new Error('The test "' + name + '" is empty. This may be the result of dead code removal.'); } else if (!deferred) { // pretest to determine if compiled code is exits early, usually by a // rogue `return` statement, by checking for a return object with the uid bench.count = 1; compiled = (compiled.call(bench, timer) || {}).uid == uid && compiled; bench.count = count; } } catch(e) { compiled = null; clone.error = e || new Error(String(e)); bench.count = count; } // fallback when a test exits early or errors during pretest if (decompilable && !compiled && !deferred && !isEmpty) { compiled = createFunction(preprocess('t$'), interpolate( preprocess( (clone.error && !stringable ? 'var r$,s$,m$=this,f$=m$.fn,i$=m$.count' : 'function f$(){#{fn}\n}var r$,s$,m$=this,i$=m$.count' ) + ',n$=t$.ns;#{setup}\n#{begin};m$.f$=f$;while(i$--){m$.f$()}#{end};' + 'delete m$.f$;#{teardown}\nreturn{elapsed:r$}' ), source )); try { // pretest one more time to check for errors bench.count = 1; compiled.call(bench, timer); bench.compiled = compiled; bench.count = count; delete clone.error; } catch(e) { bench.count = count; if (clone.error) { compiled = null; } else { bench.compiled = compiled; clone.error = e || new Error(String(e)); } } } // assign `compiled` to `clone` before calling in case a deferred benchmark // immediately calls `deferred.resolve()` clone.compiled = compiled; // if no errors run the full test loop if (!clone.error) { result = compiled.call(deferred || bench, timer).elapsed; } return result; }; /*------------------------------------------------------------------------*/ /** * Gets the current timer's minimum resolution (secs). */ function getRes(unit) { var measured, begin, count = 30, divisor = 1e3, ns = timer.ns, sample = []; // get average smallest measurable time while (count--) { if (unit == 'us') { divisor = 1e6; if (ns.stop) { ns.start(); while (!(measured = ns.microseconds())) { } } else if (ns[perfName]) { divisor = 1e3; measured = Function('n', 'var r,s=n.' + perfName + '();while(!(r=n.' + perfName + '()-s)){};return r')(ns); } else { begin = ns(); while (!(measured = ns() - begin)) { } } } else if (unit == 'ns') { divisor = 1e9; if (ns.nanoTime) { begin = ns.nanoTime(); while (!(measured = ns.nanoTime() - begin)) { } } else { begin = (begin = ns())[0] + (begin[1] / divisor); while (!(measured = ((measured = ns())[0] + (measured[1] / divisor)) - begin)) { } divisor = 1; } } else { begin = new ns; while (!(measured = new ns - begin)) { } } // check for broken timers (nanoTime may have issues) // http://alivebutsleepy.srnet.cz/unreliable-system-nanotime/ if (measured > 0) { sample.push(measured); } else { sample.push(Infinity); break; } } // convert to seconds return getMean(sample) / divisor; } /** * Replaces all occurrences of `$` with a unique number and * template tokens with content. */ function preprocess(code) { return interpolate(code, template).replace(/\$/g, /\d+/.exec(uid)); } /*------------------------------------------------------------------------*/ // detect nanosecond support from a Java applet each(doc && doc.applets || [], function(element) { return !(timer.ns = applet = 'nanoTime' in element && element); }); // check type in case Safari returns an object instead of a number try { if (typeof timer.ns.nanoTime() == 'number') { timers.push({ 'ns': timer.ns, 'res': getRes('ns'), 'unit': 'ns' }); } } catch(e) { } // detect Chrome's microsecond timer: // enable benchmarking via the --enable-benchmarking command // line switch in at least Chrome 7 to use chrome.Interval try { if ((timer.ns = new (window.chrome || window.chromium).Interval)) { timers.push({ 'ns': timer.ns, 'res': getRes('us'), 'unit': 'us' }); } } catch(e) { } // detect `performance.now` microsecond resolution timer if ((timer.ns = perfName && perfObject)) { timers.push({ 'ns': timer.ns, 'res': getRes('us'), 'unit': 'us' }); } // detect Node's nanosecond resolution timer available in Node >= 0.8 if (processObject && typeof (timer.ns = processObject.hrtime) == 'function') { timers.push({ 'ns': timer.ns, 'res': getRes('ns'), 'unit': 'ns' }); } // detect Wade Simmons' Node microtime module if (microtimeObject && typeof (timer.ns = microtimeObject.now) == 'function') { timers.push({ 'ns': timer.ns, 'res': getRes('us'), 'unit': 'us' }); } // pick timer with highest resolution timer = reduce(timers, function(timer, other) { return other.res < timer.res ? other : timer; }); // remove unused applet if (timer.unit != 'ns' && applet) { applet = destroyElement(applet); } // error if there are no working timers if (timer.res == Infinity) { throw new Error('Benchmark.js was unable to find a working timer.'); } // use API of chosen timer if (timer.unit == 'ns') { if (timer.ns.nanoTime) { extend(template, { 'begin': 's$=n$.nanoTime()', 'end': 'r$=(n$.nanoTime()-s$)/1e9' }); } else { extend(template, { 'begin': 's$=n$()', 'end': 'r$=n$(s$);r$=r$[0]+(r$[1]/1e9)' }); } } else if (timer.unit == 'us') { if (timer.ns.stop) { extend(template, { 'begin': 's$=n$.start()', 'end': 'r$=n$.microseconds()/1e6' }); } else if (perfName) { extend(template, { 'begin': 's$=n$.' + perfName + '()', 'end': 'r$=(n$.' + perfName + '()-s$)/1e3' }); } else { extend(template, { 'begin': 's$=n$()', 'end': 'r$=(n$()-s$)/1e6' }); } } // define `timer` methods timer.start = createFunction(preprocess('o$'), preprocess('var n$=this.ns,#{begin};o$.elapsed=0;o$.timeStamp=s$')); timer.stop = createFunction(preprocess('o$'), preprocess('var n$=this.ns,s$=o$.timeStamp,#{end};o$.elapsed=r$')); // resolve time span required to achieve a percent uncertainty of at most 1% // http://spiff.rit.edu/classes/phys273/uncert/uncert.html options.minTime || (options.minTime = max(timer.res / 2 / 0.01, 0.05)); return clock.apply(null, arguments); } /*--------------------------------------------------------------------------*/ /** * Computes stats on benchmark results. * * @private * @param {Object} bench The benchmark instance. * @param {Object} options The options object. */ function compute(bench, options) { options || (options = {}); var async = options.async, elapsed = 0, initCount = bench.initCount, minSamples = bench.minSamples, queue = [], sample = bench.stats.sample; /** * Adds a clone to the queue. */ function enqueue() { queue.push(bench.clone({ '_original': bench, 'events': { 'abort': [update], 'cycle': [update], 'error': [update], 'start': [update] } })); } /** * Updates the clone/original benchmarks to keep their data in sync. */ function update(event) { var clone = this, type = event.type; if (bench.running) { if (type == 'start') { // Note: `clone.minTime` prop is inited in `clock()` clone.count = bench.initCount; } else { if (type == 'error') { bench.error = clone.error; } if (type == 'abort') { bench.abort(); bench.emit('cycle'); } else { event.currentTarget = event.target = bench; bench.emit(event); } } } else if (bench.aborted) { // clear abort listeners to avoid triggering bench's abort/cycle again clone.events.abort.length = 0; clone.abort(); } } /** * Determines if more clones should be queued or if cycling should stop. */ function evaluate(event) { var critical, df, mean, moe, rme, sd, sem, variance, clone = event.target, done = bench.aborted, now = +new Date, size = sample.push(clone.times.period), maxedOut = size >= minSamples && (elapsed += now - clone.times.timeStamp) / 1e3 > bench.maxTime, times = bench.times, varOf = function(sum, x) { return sum + pow(x - mean, 2); }; // exit early for aborted or unclockable tests if (done || clone.hz == Infinity) { maxedOut = !(size = sample.length = queue.length = 0); } if (!done) { // sample mean (estimate of the population mean) mean = getMean(sample); // sample variance (estimate of the population variance) variance = reduce(sample, varOf, 0) / (size - 1) || 0; // sample standard deviation (estimate of the population standard deviation) sd = sqrt(variance); // standard error of the mean (a.k.a. the standard deviation of the sampling distribution of the sample mean) sem = sd / sqrt(size); // degrees of freedom df = size - 1; // critical value critical = tTable[Math.round(df) || 1] || tTable.infinity; // margin of error moe = sem * critical; // relative margin of error rme = (moe / mean) * 100 || 0; extend(bench.stats, { 'deviation': sd, 'mean': mean, 'moe': moe, 'rme': rme, 'sem': sem, 'variance': variance }); // Abort the cycle loop when the minimum sample size has been collected // and the elapsed time exceeds the maximum time allowed per benchmark. // We don't count cycle delays toward the max time because delays may be // increased by browsers that clamp timeouts for inactive tabs. // https://developer.mozilla.org/en/window.setTimeout#Inactive_tabs if (maxedOut) { // reset the `initCount` in case the benchmark is rerun bench.initCount = initCount; bench.running = false; done = true; times.elapsed = (now - times.timeStamp) / 1e3; } if (bench.hz != Infinity) { bench.hz = 1 / mean; times.cycle = mean * bench.count; times.period = mean; } } // if time permits, increase sample size to reduce the margin of error if (queue.length < 2 && !maxedOut) { enqueue(); } // abort the invoke cycle when done event.aborted = done; } // init queue and begin enqueue(); invoke(queue, { 'name': 'run', 'args': { 'async': async }, 'queued': true, 'onCycle': evaluate, 'onComplete': function() { bench.emit('complete'); } }); } /*--------------------------------------------------------------------------*/ /** * Cycles a benchmark until a run `count` can be established. * * @private * @param {Object} clone The cloned benchmark instance. * @param {Object} options The options object. */ function cycle(clone, options) { options || (options = {}); var deferred; if (clone instanceof Deferred) { deferred = clone; clone = clone.benchmark; } var clocked, cycles, divisor, event, minTime, period, async = options.async, bench = clone._original, count = clone.count, times = clone.times; // continue, if not aborted between cycles if (clone.running) { // `minTime` is set to `Benchmark.options.minTime` in `clock()` cycles = ++clone.cycles; clocked = deferred ? deferred.elapsed : clock(clone); minTime = clone.minTime; if (cycles > bench.cycles) { bench.cycles = cycles; } if (clone.error) { event = Event('error'); event.message = clone.error; clone.emit(event); if (!event.cancelled) { clone.abort(); } } } // continue, if not errored if (clone.running) { // time taken to complete last test cycle bench.times.cycle = times.cycle = clocked; // seconds per operation period = bench.times.period = times.period = clocked / count; // ops per second bench.hz = clone.hz = 1 / period; // avoid working our way up to this next time bench.initCount = clone.initCount = count; // do we need to do another cycle? clone.running = clocked < minTime; if (clone.running) { // tests may clock at `0` when `initCount` is a small number, // to avoid that we set its count to something a bit higher if (!clocked && (divisor = divisors[clone.cycles]) != null) { count = floor(4e6 / divisor); } // calculate how many more iterations it will take to achive the `minTime` if (count <= clone.count) { count += Math.ceil((minTime - clocked) / period); } clone.running = count != Infinity; } } // should we exit early? event = Event('cycle'); clone.emit(event); if (event.aborted) { clone.abort(); } // figure out what to do next if (clone.running) { // start a new cycle clone.count = count; if (deferred) { clone.compiled.call(deferred, timer); } else if (async) { delay(clone, function() { cycle(clone, options); }); } else { cycle(clone); } } else { // fix TraceMonkey bug associated with clock fallbacks // http://bugzil.la/509069 if (support.browser) { runScript(uid + '=1;delete ' + uid); } // done clone.emit('complete'); } } /*--------------------------------------------------------------------------*/ /** * Runs the benchmark. * * @memberOf Benchmark * @param {Object} [options={}] Options object. * @returns {Object} The benchmark instance. * @example * * // basic usage * bench.run(); * * // or with options * bench.run({ 'async': true }); */ function run(options) { var me = this, event = Event('start'); // set `running` to `false` so `reset()` won't call `abort()` me.running = false; me.reset(); me.running = true; me.count = me.initCount; me.times.timeStamp = +new Date; me.emit(event); if (!event.cancelled) { options = { 'async': ((options = options && options.async) == null ? me.async : options) && support.timeout }; // for clones created within `compute()` if (me._original) { if (me.defer) { Deferred(me); } else { cycle(me, options); } } // for original benchmarks else { compute(me, options); } } return me; } /*--------------------------------------------------------------------------*/ // Firefox 1 erroneously defines variable and argument names of functions on // the function itself as non-configurable properties with `undefined` values. // The bugginess continues as the `Benchmark` constructor has an argument // named `options` and Firefox 1 will not assign a value to `Benchmark.options`, // making it non-writable in the process, unless it is the first property // assigned by for-in loop of `extend()`. extend(Benchmark, { /** * The default options copied by benchmark instances. * * @static * @memberOf Benchmark * @type Object */ 'options': { /** * A flag to indicate that benchmark cycles will execute asynchronously * by default. * * @memberOf Benchmark.options * @type Boolean */ 'async': false, /** * A flag to indicate that the benchmark clock is deferred. * * @memberOf Benchmark.options * @type Boolean */ 'defer': false, /** * The delay between test cycles (secs). * @memberOf Benchmark.options * @type Number */ 'delay': 0.005, /** * Displayed by Benchmark#toString when a `name` is not available * (auto-generated if absent). * * @memberOf Benchmark.options * @type String */ 'id': undefined, /** * The default number of times to execute a test on a benchmark's first cycle. * * @memberOf Benchmark.options * @type Number */ 'initCount': 1, /** * The maximum time a benchmark is allowed to run before finishing (secs). * * Note: Cycle delays aren't counted toward the maximum time. * * @memberOf Benchmark.options * @type Number */ 'maxTime': 5, /** * The minimum sample size required to perform statistical analysis. * * @memberOf Benchmark.options * @type Number */ 'minSamples': 5, /** * The time needed to reduce the percent uncertainty of measurement to 1% (secs). * * @memberOf Benchmark.options * @type Number */ 'minTime': 0, /** * The name of the benchmark. * * @memberOf Benchmark.options * @type String */ 'name': undefined, /** * An event listener called when the benchmark is aborted. * * @memberOf Benchmark.options * @type Function */ 'onAbort': undefined, /** * An event listener called when the benchmark completes running. * * @memberOf Benchmark.options * @type Function */ 'onComplete': undefined, /** * An event listener called after each run cycle. * * @memberOf Benchmark.options * @type Function */ 'onCycle': undefined, /** * An event listener called when a test errors. * * @memberOf Benchmark.options * @type Function */ 'onError': undefined, /** * An event listener called when the benchmark is reset. * * @memberOf Benchmark.options * @type Function */ 'onReset': undefined, /** * An event listener called when the benchmark starts running. * * @memberOf Benchmark.options * @type Function */ 'onStart': undefined }, /** * Platform object with properties describing things like browser name, * version, and operating system. * * @static * @memberOf Benchmark * @type Object */ 'platform': req('platform') || window.platform || { /** * The platform description. * * @memberOf Benchmark.platform * @type String */ 'description': window.navigator && navigator.userAgent || null, /** * The name of the browser layout engine. * * @memberOf Benchmark.platform * @type String|Null */ 'layout': null, /** * The name of the product hosting the browser. * * @memberOf Benchmark.platform * @type String|Null */ 'product': null, /** * The name of the browser/environment. * * @memberOf Benchmark.platform * @type String|Null */ 'name': null, /** * The name of the product's manufacturer. * * @memberOf Benchmark.platform * @type String|Null */ 'manufacturer': null, /** * The name of the operating system. * * @memberOf Benchmark.platform * @type String|Null */ 'os': null, /** * The alpha/beta release indicator. * * @memberOf Benchmark.platform * @type String|Null */ 'prerelease': null, /** * The browser/environment version. * * @memberOf Benchmark.platform * @type String|Null */ 'version': null, /** * Return platform description when the platform object is coerced to a string. * * @memberOf Benchmark.platform * @type Function * @returns {String} The platform description. */ 'toString': function() { return this.description || ''; } }, /** * The semantic version number. * * @static * @memberOf Benchmark * @type String */ 'version': '1.0.0', // an object of environment/feature detection flags 'support': support, // clone objects 'deepClone': deepClone, // iteration utility 'each': each, // augment objects 'extend': extend, // generic Array#filter 'filter': filter, // generic Array#forEach 'forEach': forEach, // generic own property iteration utility 'forOwn': forOwn, // converts a number to a comma-separated string 'formatNumber': formatNumber, // generic Object#hasOwnProperty // (trigger hasKey's lazy define before assigning it to Benchmark) 'hasKey': (hasKey(Benchmark, ''), hasKey), // generic Array#indexOf 'indexOf': indexOf, // template utility 'interpolate': interpolate, // invokes a method on each item in an array 'invoke': invoke, // generic Array#join for arrays and objects 'join': join, // generic Array#map 'map': map, // retrieves a property value from each item in an array 'pluck': pluck, // generic Array#reduce 'reduce': reduce }); /*--------------------------------------------------------------------------*/ extend(Benchmark.prototype, { /** * The number of times a test was executed. * * @memberOf Benchmark * @type Number */ 'count': 0, /** * The number of cycles performed while benchmarking. * * @memberOf Benchmark * @type Number */ 'cycles': 0, /** * The number of executions per second. * * @memberOf Benchmark * @type Number */ 'hz': 0, /** * The compiled test function. * * @memberOf Benchmark * @type Function|String */ 'compiled': undefined, /** * The error object if the test failed. * * @memberOf Benchmark * @type Object */ 'error': undefined, /** * The test to benchmark. * * @memberOf Benchmark * @type Function|String */ 'fn': undefined, /** * A flag to indicate if the benchmark is aborted. * * @memberOf Benchmark * @type Boolean */ 'aborted': false, /** * A flag to indicate if the benchmark is running. * * @memberOf Benchmark * @type Boolean */ 'running': false, /** * Compiled into the test and executed immediately **before** the test loop. * * @memberOf Benchmark * @type Function|String * @example * * // basic usage * var bench = Benchmark({ * 'setup': function() { * var c = this.count, * element = document.getElementById('container'); * while (c--) { * element.appendChild(document.createElement('div')); * } * }, * 'fn': function() { * element.removeChild(element.lastChild); * } * }); * * // compiles to something like: * var c = this.count, * element = document.getElementById('container'); * while (c--) { * element.appendChild(document.createElement('div')); * } * var start = new Date; * while (count--) { * element.removeChild(element.lastChild); * } * var end = new Date - start; * * // or using strings * var bench = Benchmark({ * 'setup': '\ * var a = 0;\n\ * (function() {\n\ * (function() {\n\ * (function() {', * 'fn': 'a += 1;', * 'teardown': '\ * }())\n\ * }())\n\ * }())' * }); * * // compiles to something like: * var a = 0; * (function() { * (function() { * (function() { * var start = new Date; * while (count--) { * a += 1; * } * var end = new Date - start; * }()) * }()) * }()) */ 'setup': noop, /** * Compiled into the test and executed immediately **after** the test loop. * * @memberOf Benchmark * @type Function|String */ 'teardown': noop, /** * An object of stats including mean, margin or error, and standard deviation. * * @memberOf Benchmark * @type Object */ 'stats': { /** * The margin of error. * * @memberOf Benchmark#stats * @type Number */ 'moe': 0, /** * The relative margin of error (expressed as a percentage of the mean). * * @memberOf Benchmark#stats * @type Number */ 'rme': 0, /** * The standard error of the mean. * * @memberOf Benchmark#stats * @type Number */ 'sem': 0, /** * The sample standard deviation. * * @memberOf Benchmark#stats * @type Number */ 'deviation': 0, /** * The sample arithmetic mean. * * @memberOf Benchmark#stats * @type Number */ 'mean': 0, /** * The array of sampled periods. * * @memberOf Benchmark#stats * @type Array */ 'sample': [], /** * The sample variance. * * @memberOf Benchmark#stats * @type Number */ 'variance': 0 }, /** * An object of timing data including cycle, elapsed, period, start, and stop. * * @memberOf Benchmark * @type Object */ 'times': { /** * The time taken to complete the last cycle (secs). * * @memberOf Benchmark#times * @type Number */ 'cycle': 0, /** * The time taken to complete the benchmark (secs). * * @memberOf Benchmark#times * @type Number */ 'elapsed': 0, /** * The time taken to execute the test once (secs). * * @memberOf Benchmark#times * @type Number */ 'period': 0, /** * A timestamp of when the benchmark started (ms). * * @memberOf Benchmark#times * @type Number */ 'timeStamp': 0 }, // aborts benchmark (does not record times) 'abort': abort, // creates a new benchmark using the same test and options 'clone': clone, // compares benchmark's hertz with another 'compare': compare, // executes listeners 'emit': emit, // get listeners 'listeners': listeners, // unregister listeners 'off': off, // register listeners 'on': on, // reset benchmark properties 'reset': reset, // runs the benchmark 'run': run, // pretty print benchmark info 'toString': toStringBench }); /*--------------------------------------------------------------------------*/ extend(Deferred.prototype, { /** * The deferred benchmark instance. * * @memberOf Benchmark.Deferred * @type Object */ 'benchmark': null, /** * The number of deferred cycles performed while benchmarking. * * @memberOf Benchmark.Deferred * @type Number */ 'cycles': 0, /** * The time taken to complete the deferred benchmark (secs). * * @memberOf Benchmark.Deferred * @type Number */ 'elapsed': 0, /** * A timestamp of when the deferred benchmark started (ms). * * @memberOf Benchmark.Deferred * @type Number */ 'timeStamp': 0, // cycles/completes the deferred benchmark 'resolve': resolve }); /*--------------------------------------------------------------------------*/ extend(Event.prototype, { /** * A flag to indicate if the emitters listener iteration is aborted. * * @memberOf Benchmark.Event * @type Boolean */ 'aborted': false, /** * A flag to indicate if the default action is cancelled. * * @memberOf Benchmark.Event * @type Boolean */ 'cancelled': false, /** * The object whose listeners are currently being processed. * * @memberOf Benchmark.Event * @type Object */ 'currentTarget': undefined, /** * The return value of the last executed listener. * * @memberOf Benchmark.Event * @type Mixed */ 'result': undefined, /** * The object to which the event was originally emitted. * * @memberOf Benchmark.Event * @type Object */ 'target': undefined, /** * A timestamp of when the event was created (ms). * * @memberOf Benchmark.Event * @type Number */ 'timeStamp': 0, /** * The event type. * * @memberOf Benchmark.Event * @type String */ 'type': '' }); /*--------------------------------------------------------------------------*/ /** * The default options copied by suite instances. * * @static * @memberOf Benchmark.Suite * @type Object */ Suite.options = { /** * The name of the suite. * * @memberOf Benchmark.Suite.options * @type String */ 'name': undefined }; /*--------------------------------------------------------------------------*/ extend(Suite.prototype, { /** * The number of benchmarks in the suite. * * @memberOf Benchmark.Suite * @type Number */ 'length': 0, /** * A flag to indicate if the suite is aborted. * * @memberOf Benchmark.Suite * @type Boolean */ 'aborted': false, /** * A flag to indicate if the suite is running. * * @memberOf Benchmark.Suite * @type Boolean */ 'running': false, /** * An `Array#forEach` like method. * Callbacks may terminate the loop by explicitly returning `false`. * * @memberOf Benchmark.Suite * @param {Function} callback The function called per iteration. * @returns {Object} The suite iterated over. */ 'forEach': methodize(forEach), /** * An `Array#indexOf` like method. * * @memberOf Benchmark.Suite * @param {Mixed} value The value to search for. * @returns {Number} The index of the matched value or `-1`. */ 'indexOf': methodize(indexOf), /** * Invokes a method on all benchmarks in the suite. * * @memberOf Benchmark.Suite * @param {String|Object} name The name of the method to invoke OR options object. * @param {Mixed} [arg1, arg2, ...] Arguments to invoke the method with. * @returns {Array} A new array of values returned from each method invoked. */ 'invoke': methodize(invoke), /** * Converts the suite of benchmarks to a string. * * @memberOf Benchmark.Suite * @param {String} [separator=','] A string to separate each element of the array. * @returns {String} The string. */ 'join': [].join, /** * An `Array#map` like method. * * @memberOf Benchmark.Suite * @param {Function} callback The function called per iteration. * @returns {Array} A new array of values returned by the callback. */ 'map': methodize(map), /** * Retrieves the value of a specified property from all benchmarks in the suite. * * @memberOf Benchmark.Suite * @param {String} property The property to pluck. * @returns {Array} A new array of property values. */ 'pluck': methodize(pluck), /** * Removes the last benchmark from the suite and returns it. * * @memberOf Benchmark.Suite * @returns {Mixed} The removed benchmark. */ 'pop': [].pop, /** * Appends benchmarks to the suite. * * @memberOf Benchmark.Suite * @returns {Number} The suite's new length. */ 'push': [].push, /** * Sorts the benchmarks of the suite. * * @memberOf Benchmark.Suite * @param {Function} [compareFn=null] A function that defines the sort order. * @returns {Object} The sorted suite. */ 'sort': [].sort, /** * An `Array#reduce` like method. * * @memberOf Benchmark.Suite * @param {Function} callback The function called per iteration. * @param {Mixed} accumulator Initial value of the accumulator. * @returns {Mixed} The accumulator. */ 'reduce': methodize(reduce), // aborts all benchmarks in the suite 'abort': abortSuite, // adds a benchmark to the suite 'add': add, // creates a new suite with cloned benchmarks 'clone': cloneSuite, // executes listeners of a specified type 'emit': emit, // creates a new suite of filtered benchmarks 'filter': filterSuite, // get listeners 'listeners': listeners, // unregister listeners 'off': off, // register listeners 'on': on, // resets all benchmarks in the suite 'reset': resetSuite, // runs all benchmarks in the suite 'run': runSuite, // array methods 'concat': concat, 'reverse': reverse, 'shift': shift, 'slice': slice, 'splice': splice, 'unshift': unshift }); /*--------------------------------------------------------------------------*/ // expose Deferred, Event and Suite extend(Benchmark, { 'Deferred': Deferred, 'Event': Event, 'Suite': Suite }); // expose Benchmark // some AMD build optimizers, like r.js, check for specific condition patterns like the following: if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) { // define as an anonymous module so, through path mapping, it can be aliased define(function() { return Benchmark; }); } // check for `exports` after `define` in case a build optimizer adds an `exports` object else if (freeExports) { // in Node.js or RingoJS v0.8.0+ if (typeof module == 'object' && module && module.exports == freeExports) { (module.exports = Benchmark).Benchmark = Benchmark; } // in Narwhal or RingoJS v0.7.0- else { freeExports.Benchmark = Benchmark; } } // in a browser or Rhino else { // use square bracket notation so Closure Compiler won't munge `Benchmark` // http://code.google.com/closure/compiler/docs/api-tutorial3.html#export window['Benchmark'] = Benchmark; } // trigger clock's lazy define early to avoid a security error if (support.air) { clock({ '_original': { 'fn': noop, 'count': 1, 'options': {} } }); } }(this)); sizzle-1.10.17/speed/libs/requirejs-domready/000077500000000000000000000000001226755370700210635ustar00rootroot00000000000000sizzle-1.10.17/speed/libs/requirejs-domready/domReady.js000066400000000000000000000077031226755370700231740ustar00rootroot00000000000000/** * @license RequireJS domReady 2.0.1 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved. * Available via the MIT or new BSD license. * see: http://github.com/requirejs/domReady for details */ /*jslint */ /*global require: false, define: false, requirejs: false, window: false, clearInterval: false, document: false, self: false, setInterval: false */ define(function () { 'use strict'; var isTop, testDiv, scrollIntervalId, isBrowser = typeof window !== "undefined" && window.document, isPageLoaded = !isBrowser, doc = isBrowser ? document : null, readyCalls = []; function runCallbacks(callbacks) { var i; for (i = 0; i < callbacks.length; i += 1) { callbacks[i](doc); } } function callReady() { var callbacks = readyCalls; if (isPageLoaded) { //Call the DOM ready callbacks if (callbacks.length) { readyCalls = []; runCallbacks(callbacks); } } } /** * Sets the page as loaded. */ function pageLoaded() { if (!isPageLoaded) { isPageLoaded = true; if (scrollIntervalId) { clearInterval(scrollIntervalId); } callReady(); } } if (isBrowser) { if (document.addEventListener) { //Standards. Hooray! Assumption here that if standards based, //it knows about DOMContentLoaded. document.addEventListener("DOMContentLoaded", pageLoaded, false); window.addEventListener("load", pageLoaded, false); } else if (window.attachEvent) { window.attachEvent("onload", pageLoaded); testDiv = document.createElement('div'); try { isTop = window.frameElement === null; } catch (e) {} //DOMContentLoaded approximation that uses a doScroll, as found by //Diego Perini: http://javascript.nwbox.com/IEContentLoaded/, //but modified by other contributors, including jdalton if (testDiv.doScroll && isTop && window.external) { scrollIntervalId = setInterval(function () { try { testDiv.doScroll(); pageLoaded(); } catch (e) {} }, 30); } } //Check if document already complete, and if so, just trigger page load //listeners. Latest webkit browsers also use "interactive", and //will fire the onDOMContentLoaded before "interactive" but not after //entering "interactive" or "complete". More details: //http://dev.w3.org/html5/spec/the-end.html#the-end //http://stackoverflow.com/questions/3665561/document-readystate-of-interactive-vs-ondomcontentloaded //Hmm, this is more complicated on further use, see "firing too early" //bug: https://github.com/requirejs/domReady/issues/1 //so removing the || document.readyState === "interactive" test. //There is still a window.onload binding that should get fired if //DOMContentLoaded is missed. if (document.readyState === "complete") { pageLoaded(); } } /** START OF PUBLIC API **/ /** * Registers a callback for DOM ready. If DOM is already ready, the * callback is called immediately. * @param {Function} callback */ function domReady(callback) { if (isPageLoaded) { callback(doc); } else { readyCalls.push(callback); } return domReady; } domReady.version = '2.0.1'; /** * Loader Plugin API method */ domReady.load = function (name, req, onLoad, config) { if (config.isBuild) { onLoad(null); } else { domReady(onLoad); } }; /** END OF PUBLIC API **/ return domReady; }); sizzle-1.10.17/speed/libs/requirejs-text/000077500000000000000000000000001226755370700202435ustar00rootroot00000000000000sizzle-1.10.17/speed/libs/requirejs-text/text.js000066400000000000000000000361501226755370700215720ustar00rootroot00000000000000/** * @license RequireJS text 2.0.10 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved. * Available via the MIT or new BSD license. * see: http://github.com/requirejs/text for details */ /*jslint regexp: true */ /*global require, XMLHttpRequest, ActiveXObject, define, window, process, Packages, java, location, Components, FileUtils */ define(['module'], function (module) { 'use strict'; var text, fs, Cc, Ci, xpcIsWindows, progIds = ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0'], xmlRegExp = /^\s*<\?xml(\s)+version=[\'\"](\d)*.(\d)*[\'\"](\s)*\?>/im, bodyRegExp = /]*>\s*([\s\S]+)\s*<\/body>/im, hasLocation = typeof location !== 'undefined' && location.href, defaultProtocol = hasLocation && location.protocol && location.protocol.replace(/\:/, ''), defaultHostName = hasLocation && location.hostname, defaultPort = hasLocation && (location.port || undefined), buildMap = {}, masterConfig = (module.config && module.config()) || {}; text = { version: '2.0.10', strip: function (content) { //Strips declarations so that external SVG and XML //documents can be added to a document without worry. Also, if the string //is an HTML document, only the part inside the body tag is returned. if (content) { content = content.replace(xmlRegExp, ""); var matches = content.match(bodyRegExp); if (matches) { content = matches[1]; } } else { content = ""; } return content; }, jsEscape: function (content) { return content.replace(/(['\\])/g, '\\$1') .replace(/[\f]/g, "\\f") .replace(/[\b]/g, "\\b") .replace(/[\n]/g, "\\n") .replace(/[\t]/g, "\\t") .replace(/[\r]/g, "\\r") .replace(/[\u2028]/g, "\\u2028") .replace(/[\u2029]/g, "\\u2029"); }, createXhr: masterConfig.createXhr || function () { //Would love to dump the ActiveX crap in here. Need IE 6 to die first. var xhr, i, progId; if (typeof XMLHttpRequest !== "undefined") { return new XMLHttpRequest(); } else if (typeof ActiveXObject !== "undefined") { for (i = 0; i < 3; i += 1) { progId = progIds[i]; try { xhr = new ActiveXObject(progId); } catch (e) {} if (xhr) { progIds = [progId]; // so faster next time break; } } } return xhr; }, /** * Parses a resource name into its component parts. Resource names * look like: module/name.ext!strip, where the !strip part is * optional. * @param {String} name the resource name * @returns {Object} with properties "moduleName", "ext" and "strip" * where strip is a boolean. */ parseName: function (name) { var modName, ext, temp, strip = false, index = name.indexOf("."), isRelative = name.indexOf('./') === 0 || name.indexOf('../') === 0; if (index !== -1 && (!isRelative || index > 1)) { modName = name.substring(0, index); ext = name.substring(index + 1, name.length); } else { modName = name; } temp = ext || modName; index = temp.indexOf("!"); if (index !== -1) { //Pull off the strip arg. strip = temp.substring(index + 1) === "strip"; temp = temp.substring(0, index); if (ext) { ext = temp; } else { modName = temp; } } return { moduleName: modName, ext: ext, strip: strip }; }, xdRegExp: /^((\w+)\:)?\/\/([^\/\\]+)/, /** * Is an URL on another domain. Only works for browser use, returns * false in non-browser environments. Only used to know if an * optimized .js version of a text resource should be loaded * instead. * @param {String} url * @returns Boolean */ useXhr: function (url, protocol, hostname, port) { var uProtocol, uHostName, uPort, match = text.xdRegExp.exec(url); if (!match) { return true; } uProtocol = match[2]; uHostName = match[3]; uHostName = uHostName.split(':'); uPort = uHostName[1]; uHostName = uHostName[0]; return (!uProtocol || uProtocol === protocol) && (!uHostName || uHostName.toLowerCase() === hostname.toLowerCase()) && ((!uPort && !uHostName) || uPort === port); }, finishLoad: function (name, strip, content, onLoad) { content = strip ? text.strip(content) : content; if (masterConfig.isBuild) { buildMap[name] = content; } onLoad(content); }, load: function (name, req, onLoad, config) { //Name has format: some.module.filext!strip //The strip part is optional. //if strip is present, then that means only get the string contents //inside a body tag in an HTML string. For XML/SVG content it means //removing the declarations so the content can be inserted //into the current doc without problems. // Do not bother with the work if a build and text will // not be inlined. if (config.isBuild && !config.inlineText) { onLoad(); return; } masterConfig.isBuild = config.isBuild; var parsed = text.parseName(name), nonStripName = parsed.moduleName + (parsed.ext ? '.' + parsed.ext : ''), url = req.toUrl(nonStripName), useXhr = (masterConfig.useXhr) || text.useXhr; // Do not load if it is an empty: url if (url.indexOf('empty:') === 0) { onLoad(); return; } //Load the text. Use XHR if possible and in a browser. if (!hasLocation || useXhr(url, defaultProtocol, defaultHostName, defaultPort)) { text.get(url, function (content) { text.finishLoad(name, parsed.strip, content, onLoad); }, function (err) { if (onLoad.error) { onLoad.error(err); } }); } else { //Need to fetch the resource across domains. Assume //the resource has been optimized into a JS module. Fetch //by the module name + extension, but do not include the //!strip part to avoid file system issues. req([nonStripName], function (content) { text.finishLoad(parsed.moduleName + '.' + parsed.ext, parsed.strip, content, onLoad); }); } }, write: function (pluginName, moduleName, write, config) { if (buildMap.hasOwnProperty(moduleName)) { var content = text.jsEscape(buildMap[moduleName]); write.asModule(pluginName + "!" + moduleName, "define(function () { return '" + content + "';});\n"); } }, writeFile: function (pluginName, moduleName, req, write, config) { var parsed = text.parseName(moduleName), extPart = parsed.ext ? '.' + parsed.ext : '', nonStripName = parsed.moduleName + extPart, //Use a '.js' file name so that it indicates it is a //script that can be loaded across domains. fileName = req.toUrl(parsed.moduleName + extPart) + '.js'; //Leverage own load() method to load plugin value, but only //write out values that do not have the strip argument, //to avoid any potential issues with ! in file names. text.load(nonStripName, req, function (value) { //Use own write() method to construct full module value. //But need to create shell that translates writeFile's //write() to the right interface. var textWrite = function (contents) { return write(fileName, contents); }; textWrite.asModule = function (moduleName, contents) { return write.asModule(moduleName, fileName, contents); }; text.write(pluginName, nonStripName, textWrite, config); }, config); } }; if (masterConfig.env === 'node' || (!masterConfig.env && typeof process !== "undefined" && process.versions && !!process.versions.node && !process.versions['node-webkit'])) { //Using special require.nodeRequire, something added by r.js. fs = require.nodeRequire('fs'); text.get = function (url, callback, errback) { try { var file = fs.readFileSync(url, 'utf8'); //Remove BOM (Byte Mark Order) from utf8 files if it is there. if (file.indexOf('\uFEFF') === 0) { file = file.substring(1); } callback(file); } catch (e) { errback(e); } }; } else if (masterConfig.env === 'xhr' || (!masterConfig.env && text.createXhr())) { text.get = function (url, callback, errback, headers) { var xhr = text.createXhr(), header; xhr.open('GET', url, true); //Allow plugins direct access to xhr headers if (headers) { for (header in headers) { if (headers.hasOwnProperty(header)) { xhr.setRequestHeader(header.toLowerCase(), headers[header]); } } } //Allow overrides specified in config if (masterConfig.onXhr) { masterConfig.onXhr(xhr, url); } xhr.onreadystatechange = function (evt) { var status, err; //Do not explicitly handle errors, those should be //visible via console output in the browser. if (xhr.readyState === 4) { status = xhr.status; if (status > 399 && status < 600) { //An http 4xx or 5xx error. Signal an error. err = new Error(url + ' HTTP status: ' + status); err.xhr = xhr; errback(err); } else { callback(xhr.responseText); } if (masterConfig.onXhrComplete) { masterConfig.onXhrComplete(xhr, url); } } }; xhr.send(null); }; } else if (masterConfig.env === 'rhino' || (!masterConfig.env && typeof Packages !== 'undefined' && typeof java !== 'undefined')) { //Why Java, why is this so awkward? text.get = function (url, callback) { var stringBuffer, line, encoding = "utf-8", file = new java.io.File(url), lineSeparator = java.lang.System.getProperty("line.separator"), input = new java.io.BufferedReader(new java.io.InputStreamReader(new java.io.FileInputStream(file), encoding)), content = ''; try { stringBuffer = new java.lang.StringBuffer(); line = input.readLine(); // Byte Order Mark (BOM) - The Unicode Standard, version 3.0, page 324 // http://www.unicode.org/faq/utf_bom.html // Note that when we use utf-8, the BOM should appear as "EF BB BF", but it doesn't due to this bug in the JDK: // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4508058 if (line && line.length() && line.charAt(0) === 0xfeff) { // Eat the BOM, since we've already found the encoding on this file, // and we plan to concatenating this buffer with others; the BOM should // only appear at the top of a file. line = line.substring(1); } if (line !== null) { stringBuffer.append(line); } while ((line = input.readLine()) !== null) { stringBuffer.append(lineSeparator); stringBuffer.append(line); } //Make sure we return a JavaScript string and not a Java string. content = String(stringBuffer.toString()); //String } finally { input.close(); } callback(content); }; } else if (masterConfig.env === 'xpconnect' || (!masterConfig.env && typeof Components !== 'undefined' && Components.classes && Components.interfaces)) { //Avert your gaze! Cc = Components.classes, Ci = Components.interfaces; Components.utils['import']('resource://gre/modules/FileUtils.jsm'); xpcIsWindows = ('@mozilla.org/windows-registry-key;1' in Cc); text.get = function (url, callback) { var inStream, convertStream, fileObj, readData = {}; if (xpcIsWindows) { url = url.replace(/\//g, '\\'); } fileObj = new FileUtils.File(url); //XPCOM, you so crazy try { inStream = Cc['@mozilla.org/network/file-input-stream;1'] .createInstance(Ci.nsIFileInputStream); inStream.init(fileObj, 1, 0, false); convertStream = Cc['@mozilla.org/intl/converter-input-stream;1'] .createInstance(Ci.nsIConverterInputStream); convertStream.init(inStream, "utf-8", inStream.available(), Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER); convertStream.readString(inStream.available(), readData); convertStream.close(); inStream.close(); callback(readData.value); } catch (e) { throw new Error((fileObj && fileObj.path || '') + ': ' + e); } }; } return text; }); sizzle-1.10.17/speed/libs/requirejs/000077500000000000000000000000001226755370700172615ustar00rootroot00000000000000sizzle-1.10.17/speed/libs/requirejs/require.js000066400000000000000000002413771226755370700213110ustar00rootroot00000000000000/** vim: et:ts=4:sw=4:sts=4 * @license RequireJS 2.1.9 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved. * Available via the MIT or new BSD license. * see: http://github.com/jrburke/requirejs for details */ //Not using strict: uneven strict support in browsers, #392, and causes //problems with requirejs.exec()/transpiler plugins that may not be strict. /*jslint regexp: true, nomen: true, sloppy: true */ /*global window, navigator, document, importScripts, setTimeout, opera */ var requirejs, require, define; (function (global) { var req, s, head, baseElement, dataMain, src, interactiveScript, currentlyAddingScript, mainScript, subPath, version = '2.1.9', commentRegExp = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg, cjsRequireRegExp = /[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g, jsSuffixRegExp = /\.js$/, currDirRegExp = /^\.\//, op = Object.prototype, ostring = op.toString, hasOwn = op.hasOwnProperty, ap = Array.prototype, apsp = ap.splice, isBrowser = !!(typeof window !== 'undefined' && typeof navigator !== 'undefined' && window.document), isWebWorker = !isBrowser && typeof importScripts !== 'undefined', //PS3 indicates loaded and complete, but need to wait for complete //specifically. Sequence is 'loading', 'loaded', execution, // then 'complete'. The UA check is unfortunate, but not sure how //to feature test w/o causing perf issues. readyRegExp = isBrowser && navigator.platform === 'PLAYSTATION 3' ? /^complete$/ : /^(complete|loaded)$/, defContextName = '_', //Oh the tragedy, detecting opera. See the usage of isOpera for reason. isOpera = typeof opera !== 'undefined' && opera.toString() === '[object Opera]', contexts = {}, cfg = {}, globalDefQueue = [], useInteractive = false; function isFunction(it) { return ostring.call(it) === '[object Function]'; } function isArray(it) { return ostring.call(it) === '[object Array]'; } /** * Helper function for iterating over an array. If the func returns * a true value, it will break out of the loop. */ function each(ary, func) { if (ary) { var i; for (i = 0; i < ary.length; i += 1) { if (ary[i] && func(ary[i], i, ary)) { break; } } } } /** * Helper function for iterating over an array backwards. If the func * returns a true value, it will break out of the loop. */ function eachReverse(ary, func) { if (ary) { var i; for (i = ary.length - 1; i > -1; i -= 1) { if (ary[i] && func(ary[i], i, ary)) { break; } } } } function hasProp(obj, prop) { return hasOwn.call(obj, prop); } function getOwn(obj, prop) { return hasProp(obj, prop) && obj[prop]; } /** * Cycles over properties in an object and calls a function for each * property value. If the function returns a truthy value, then the * iteration is stopped. */ function eachProp(obj, func) { var prop; for (prop in obj) { if (hasProp(obj, prop)) { if (func(obj[prop], prop)) { break; } } } } /** * Simple function to mix in properties from source into target, * but only if target does not already have a property of the same name. */ function mixin(target, source, force, deepStringMixin) { if (source) { eachProp(source, function (value, prop) { if (force || !hasProp(target, prop)) { if (deepStringMixin && typeof value !== 'string') { if (!target[prop]) { target[prop] = {}; } mixin(target[prop], value, force, deepStringMixin); } else { target[prop] = value; } } }); } return target; } //Similar to Function.prototype.bind, but the 'this' object is specified //first, since it is easier to read/figure out what 'this' will be. function bind(obj, fn) { return function () { return fn.apply(obj, arguments); }; } function scripts() { return document.getElementsByTagName('script'); } function defaultOnError(err) { throw err; } //Allow getting a global that expressed in //dot notation, like 'a.b.c'. function getGlobal(value) { if (!value) { return value; } var g = global; each(value.split('.'), function (part) { g = g[part]; }); return g; } /** * Constructs an error with a pointer to an URL with more information. * @param {String} id the error ID that maps to an ID on a web page. * @param {String} message human readable error. * @param {Error} [err] the original error, if there is one. * * @returns {Error} */ function makeError(id, msg, err, requireModules) { var e = new Error(msg + '\nhttp://requirejs.org/docs/errors.html#' + id); e.requireType = id; e.requireModules = requireModules; if (err) { e.originalError = err; } return e; } if (typeof define !== 'undefined') { //If a define is already in play via another AMD loader, //do not overwrite. return; } if (typeof requirejs !== 'undefined') { if (isFunction(requirejs)) { //Do not overwrite and existing requirejs instance. return; } cfg = requirejs; requirejs = undefined; } //Allow for a require config object if (typeof require !== 'undefined' && !isFunction(require)) { //assume it is a config object. cfg = require; require = undefined; } function newContext(contextName) { var inCheckLoaded, Module, context, handlers, checkLoadedTimeoutId, config = { //Defaults. Do not set a default for map //config to speed up normalize(), which //will run faster if there is no default. waitSeconds: 7, baseUrl: './', paths: {}, pkgs: {}, shim: {}, config: {} }, registry = {}, //registry of just enabled modules, to speed //cycle breaking code when lots of modules //are registered, but not activated. enabledRegistry = {}, undefEvents = {}, defQueue = [], defined = {}, urlFetched = {}, requireCounter = 1, unnormalizedCounter = 1; /** * Trims the . and .. from an array of path segments. * It will keep a leading path segment if a .. will become * the first path segment, to help with module name lookups, * which act like paths, but can be remapped. But the end result, * all paths that use this function should look normalized. * NOTE: this method MODIFIES the input array. * @param {Array} ary the array of path segments. */ function trimDots(ary) { var i, part; for (i = 0; ary[i]; i += 1) { part = ary[i]; if (part === '.') { ary.splice(i, 1); i -= 1; } else if (part === '..') { if (i === 1 && (ary[2] === '..' || ary[0] === '..')) { //End of the line. Keep at least one non-dot //path segment at the front so it can be mapped //correctly to disk. Otherwise, there is likely //no path mapping for a path starting with '..'. //This can still fail, but catches the most reasonable //uses of .. break; } else if (i > 0) { ary.splice(i - 1, 2); i -= 2; } } } } /** * Given a relative module name, like ./something, normalize it to * a real name that can be mapped to a path. * @param {String} name the relative name * @param {String} baseName a real name that the name arg is relative * to. * @param {Boolean} applyMap apply the map config to the value. Should * only be done if this normalization is for a dependency ID. * @returns {String} normalized name */ function normalize(name, baseName, applyMap) { var pkgName, pkgConfig, mapValue, nameParts, i, j, nameSegment, foundMap, foundI, foundStarMap, starI, baseParts = baseName && baseName.split('/'), normalizedBaseParts = baseParts, map = config.map, starMap = map && map['*']; //Adjust any relative paths. if (name && name.charAt(0) === '.') { //If have a base name, try to normalize against it, //otherwise, assume it is a top-level require that will //be relative to baseUrl in the end. if (baseName) { if (getOwn(config.pkgs, baseName)) { //If the baseName is a package name, then just treat it as one //name to concat the name with. normalizedBaseParts = baseParts = [baseName]; } else { //Convert baseName to array, and lop off the last part, //so that . matches that 'directory' and not name of the baseName's //module. For instance, baseName of 'one/two/three', maps to //'one/two/three.js', but we want the directory, 'one/two' for //this normalization. normalizedBaseParts = baseParts.slice(0, baseParts.length - 1); } name = normalizedBaseParts.concat(name.split('/')); trimDots(name); //Some use of packages may use a . path to reference the //'main' module name, so normalize for that. pkgConfig = getOwn(config.pkgs, (pkgName = name[0])); name = name.join('/'); if (pkgConfig && name === pkgName + '/' + pkgConfig.main) { name = pkgName; } } else if (name.indexOf('./') === 0) { // No baseName, so this is ID is resolved relative // to baseUrl, pull off the leading dot. name = name.substring(2); } } //Apply map config if available. if (applyMap && map && (baseParts || starMap)) { nameParts = name.split('/'); for (i = nameParts.length; i > 0; i -= 1) { nameSegment = nameParts.slice(0, i).join('/'); if (baseParts) { //Find the longest baseName segment match in the config. //So, do joins on the biggest to smallest lengths of baseParts. for (j = baseParts.length; j > 0; j -= 1) { mapValue = getOwn(map, baseParts.slice(0, j).join('/')); //baseName segment has config, find if it has one for //this name. if (mapValue) { mapValue = getOwn(mapValue, nameSegment); if (mapValue) { //Match, update name to the new value. foundMap = mapValue; foundI = i; break; } } } } if (foundMap) { break; } //Check for a star map match, but just hold on to it, //if there is a shorter segment match later in a matching //config, then favor over this star map. if (!foundStarMap && starMap && getOwn(starMap, nameSegment)) { foundStarMap = getOwn(starMap, nameSegment); starI = i; } } if (!foundMap && foundStarMap) { foundMap = foundStarMap; foundI = starI; } if (foundMap) { nameParts.splice(0, foundI, foundMap); name = nameParts.join('/'); } } return name; } function removeScript(name) { if (isBrowser) { each(scripts(), function (scriptNode) { if (scriptNode.getAttribute('data-requiremodule') === name && scriptNode.getAttribute('data-requirecontext') === context.contextName) { scriptNode.parentNode.removeChild(scriptNode); return true; } }); } } function hasPathFallback(id) { var pathConfig = getOwn(config.paths, id); if (pathConfig && isArray(pathConfig) && pathConfig.length > 1) { //Pop off the first array value, since it failed, and //retry pathConfig.shift(); context.require.undef(id); context.require([id]); return true; } } //Turns a plugin!resource to [plugin, resource] //with the plugin being undefined if the name //did not have a plugin prefix. function splitPrefix(name) { var prefix, index = name ? name.indexOf('!') : -1; if (index > -1) { prefix = name.substring(0, index); name = name.substring(index + 1, name.length); } return [prefix, name]; } /** * Creates a module mapping that includes plugin prefix, module * name, and path. If parentModuleMap is provided it will * also normalize the name via require.normalize() * * @param {String} name the module name * @param {String} [parentModuleMap] parent module map * for the module name, used to resolve relative names. * @param {Boolean} isNormalized: is the ID already normalized. * This is true if this call is done for a define() module ID. * @param {Boolean} applyMap: apply the map config to the ID. * Should only be true if this map is for a dependency. * * @returns {Object} */ function makeModuleMap(name, parentModuleMap, isNormalized, applyMap) { var url, pluginModule, suffix, nameParts, prefix = null, parentName = parentModuleMap ? parentModuleMap.name : null, originalName = name, isDefine = true, normalizedName = ''; //If no name, then it means it is a require call, generate an //internal name. if (!name) { isDefine = false; name = '_@r' + (requireCounter += 1); } nameParts = splitPrefix(name); prefix = nameParts[0]; name = nameParts[1]; if (prefix) { prefix = normalize(prefix, parentName, applyMap); pluginModule = getOwn(defined, prefix); } //Account for relative paths if there is a base name. if (name) { if (prefix) { if (pluginModule && pluginModule.normalize) { //Plugin is loaded, use its normalize method. normalizedName = pluginModule.normalize(name, function (name) { return normalize(name, parentName, applyMap); }); } else { normalizedName = normalize(name, parentName, applyMap); } } else { //A regular module. normalizedName = normalize(name, parentName, applyMap); //Normalized name may be a plugin ID due to map config //application in normalize. The map config values must //already be normalized, so do not need to redo that part. nameParts = splitPrefix(normalizedName); prefix = nameParts[0]; normalizedName = nameParts[1]; isNormalized = true; url = context.nameToUrl(normalizedName); } } //If the id is a plugin id that cannot be determined if it needs //normalization, stamp it with a unique ID so two matching relative //ids that may conflict can be separate. suffix = prefix && !pluginModule && !isNormalized ? '_unnormalized' + (unnormalizedCounter += 1) : ''; return { prefix: prefix, name: normalizedName, parentMap: parentModuleMap, unnormalized: !!suffix, url: url, originalName: originalName, isDefine: isDefine, id: (prefix ? prefix + '!' + normalizedName : normalizedName) + suffix }; } function getModule(depMap) { var id = depMap.id, mod = getOwn(registry, id); if (!mod) { mod = registry[id] = new context.Module(depMap); } return mod; } function on(depMap, name, fn) { var id = depMap.id, mod = getOwn(registry, id); if (hasProp(defined, id) && (!mod || mod.defineEmitComplete)) { if (name === 'defined') { fn(defined[id]); } } else { mod = getModule(depMap); if (mod.error && name === 'error') { fn(mod.error); } else { mod.on(name, fn); } } } function onError(err, errback) { var ids = err.requireModules, notified = false; if (errback) { errback(err); } else { each(ids, function (id) { var mod = getOwn(registry, id); if (mod) { //Set error on module, so it skips timeout checks. mod.error = err; if (mod.events.error) { notified = true; mod.emit('error', err); } } }); if (!notified) { req.onError(err); } } } /** * Internal method to transfer globalQueue items to this context's * defQueue. */ function takeGlobalQueue() { //Push all the globalDefQueue items into the context's defQueue if (globalDefQueue.length) { //Array splice in the values since the context code has a //local var ref to defQueue, so cannot just reassign the one //on context. apsp.apply(defQueue, [defQueue.length - 1, 0].concat(globalDefQueue)); globalDefQueue = []; } } handlers = { 'require': function (mod) { if (mod.require) { return mod.require; } else { return (mod.require = context.makeRequire(mod.map)); } }, 'exports': function (mod) { mod.usingExports = true; if (mod.map.isDefine) { if (mod.exports) { return mod.exports; } else { return (mod.exports = defined[mod.map.id] = {}); } } }, 'module': function (mod) { if (mod.module) { return mod.module; } else { return (mod.module = { id: mod.map.id, uri: mod.map.url, config: function () { var c, pkg = getOwn(config.pkgs, mod.map.id); // For packages, only support config targeted // at the main module. c = pkg ? getOwn(config.config, mod.map.id + '/' + pkg.main) : getOwn(config.config, mod.map.id); return c || {}; }, exports: defined[mod.map.id] }); } } }; function cleanRegistry(id) { //Clean up machinery used for waiting modules. delete registry[id]; delete enabledRegistry[id]; } function breakCycle(mod, traced, processed) { var id = mod.map.id; if (mod.error) { mod.emit('error', mod.error); } else { traced[id] = true; each(mod.depMaps, function (depMap, i) { var depId = depMap.id, dep = getOwn(registry, depId); //Only force things that have not completed //being defined, so still in the registry, //and only if it has not been matched up //in the module already. if (dep && !mod.depMatched[i] && !processed[depId]) { if (getOwn(traced, depId)) { mod.defineDep(i, defined[depId]); mod.check(); //pass false? } else { breakCycle(dep, traced, processed); } } }); processed[id] = true; } } function checkLoaded() { var map, modId, err, usingPathFallback, waitInterval = config.waitSeconds * 1000, //It is possible to disable the wait interval by using waitSeconds of 0. expired = waitInterval && (context.startTime + waitInterval) < new Date().getTime(), noLoads = [], reqCalls = [], stillLoading = false, needCycleCheck = true; //Do not bother if this call was a result of a cycle break. if (inCheckLoaded) { return; } inCheckLoaded = true; //Figure out the state of all the modules. eachProp(enabledRegistry, function (mod) { map = mod.map; modId = map.id; //Skip things that are not enabled or in error state. if (!mod.enabled) { return; } if (!map.isDefine) { reqCalls.push(mod); } if (!mod.error) { //If the module should be executed, and it has not //been inited and time is up, remember it. if (!mod.inited && expired) { if (hasPathFallback(modId)) { usingPathFallback = true; stillLoading = true; } else { noLoads.push(modId); removeScript(modId); } } else if (!mod.inited && mod.fetched && map.isDefine) { stillLoading = true; if (!map.prefix) { //No reason to keep looking for unfinished //loading. If the only stillLoading is a //plugin resource though, keep going, //because it may be that a plugin resource //is waiting on a non-plugin cycle. return (needCycleCheck = false); } } } }); if (expired && noLoads.length) { //If wait time expired, throw error of unloaded modules. err = makeError('timeout', 'Load timeout for modules: ' + noLoads, null, noLoads); err.contextName = context.contextName; return onError(err); } //Not expired, check for a cycle. if (needCycleCheck) { each(reqCalls, function (mod) { breakCycle(mod, {}, {}); }); } //If still waiting on loads, and the waiting load is something //other than a plugin resource, or there are still outstanding //scripts, then just try back later. if ((!expired || usingPathFallback) && stillLoading) { //Something is still waiting to load. Wait for it, but only //if a timeout is not already in effect. if ((isBrowser || isWebWorker) && !checkLoadedTimeoutId) { checkLoadedTimeoutId = setTimeout(function () { checkLoadedTimeoutId = 0; checkLoaded(); }, 50); } } inCheckLoaded = false; } Module = function (map) { this.events = getOwn(undefEvents, map.id) || {}; this.map = map; this.shim = getOwn(config.shim, map.id); this.depExports = []; this.depMaps = []; this.depMatched = []; this.pluginMaps = {}; this.depCount = 0; /* this.exports this.factory this.depMaps = [], this.enabled, this.fetched */ }; Module.prototype = { init: function (depMaps, factory, errback, options) { options = options || {}; //Do not do more inits if already done. Can happen if there //are multiple define calls for the same module. That is not //a normal, common case, but it is also not unexpected. if (this.inited) { return; } this.factory = factory; if (errback) { //Register for errors on this module. this.on('error', errback); } else if (this.events.error) { //If no errback already, but there are error listeners //on this module, set up an errback to pass to the deps. errback = bind(this, function (err) { this.emit('error', err); }); } //Do a copy of the dependency array, so that //source inputs are not modified. For example //"shim" deps are passed in here directly, and //doing a direct modification of the depMaps array //would affect that config. this.depMaps = depMaps && depMaps.slice(0); this.errback = errback; //Indicate this module has be initialized this.inited = true; this.ignore = options.ignore; //Could have option to init this module in enabled mode, //or could have been previously marked as enabled. However, //the dependencies are not known until init is called. So //if enabled previously, now trigger dependencies as enabled. if (options.enabled || this.enabled) { //Enable this module and dependencies. //Will call this.check() this.enable(); } else { this.check(); } }, defineDep: function (i, depExports) { //Because of cycles, defined callback for a given //export can be called more than once. if (!this.depMatched[i]) { this.depMatched[i] = true; this.depCount -= 1; this.depExports[i] = depExports; } }, fetch: function () { if (this.fetched) { return; } this.fetched = true; context.startTime = (new Date()).getTime(); var map = this.map; //If the manager is for a plugin managed resource, //ask the plugin to load it now. if (this.shim) { context.makeRequire(this.map, { enableBuildCallback: true })(this.shim.deps || [], bind(this, function () { return map.prefix ? this.callPlugin() : this.load(); })); } else { //Regular dependency. return map.prefix ? this.callPlugin() : this.load(); } }, load: function () { var url = this.map.url; //Regular dependency. if (!urlFetched[url]) { urlFetched[url] = true; context.load(this.map.id, url); } }, /** * Checks if the module is ready to define itself, and if so, * define it. */ check: function () { if (!this.enabled || this.enabling) { return; } var err, cjsModule, id = this.map.id, depExports = this.depExports, exports = this.exports, factory = this.factory; if (!this.inited) { this.fetch(); } else if (this.error) { this.emit('error', this.error); } else if (!this.defining) { //The factory could trigger another require call //that would result in checking this module to //define itself again. If already in the process //of doing that, skip this work. this.defining = true; if (this.depCount < 1 && !this.defined) { if (isFunction(factory)) { //If there is an error listener, favor passing //to that instead of throwing an error. However, //only do it for define()'d modules. require //errbacks should not be called for failures in //their callbacks (#699). However if a global //onError is set, use that. if ((this.events.error && this.map.isDefine) || req.onError !== defaultOnError) { try { exports = context.execCb(id, factory, depExports, exports); } catch (e) { err = e; } } else { exports = context.execCb(id, factory, depExports, exports); } if (this.map.isDefine) { //If setting exports via 'module' is in play, //favor that over return value and exports. After that, //favor a non-undefined return value over exports use. cjsModule = this.module; if (cjsModule && cjsModule.exports !== undefined && //Make sure it is not already the exports value cjsModule.exports !== this.exports) { exports = cjsModule.exports; } else if (exports === undefined && this.usingExports) { //exports already set the defined value. exports = this.exports; } } if (err) { err.requireMap = this.map; err.requireModules = this.map.isDefine ? [this.map.id] : null; err.requireType = this.map.isDefine ? 'define' : 'require'; return onError((this.error = err)); } } else { //Just a literal value exports = factory; } this.exports = exports; if (this.map.isDefine && !this.ignore) { defined[id] = exports; if (req.onResourceLoad) { req.onResourceLoad(context, this.map, this.depMaps); } } //Clean up cleanRegistry(id); this.defined = true; } //Finished the define stage. Allow calling check again //to allow define notifications below in the case of a //cycle. this.defining = false; if (this.defined && !this.defineEmitted) { this.defineEmitted = true; this.emit('defined', this.exports); this.defineEmitComplete = true; } } }, callPlugin: function () { var map = this.map, id = map.id, //Map already normalized the prefix. pluginMap = makeModuleMap(map.prefix); //Mark this as a dependency for this plugin, so it //can be traced for cycles. this.depMaps.push(pluginMap); on(pluginMap, 'defined', bind(this, function (plugin) { var load, normalizedMap, normalizedMod, name = this.map.name, parentName = this.map.parentMap ? this.map.parentMap.name : null, localRequire = context.makeRequire(map.parentMap, { enableBuildCallback: true }); //If current map is not normalized, wait for that //normalized name to load instead of continuing. if (this.map.unnormalized) { //Normalize the ID if the plugin allows it. if (plugin.normalize) { name = plugin.normalize(name, function (name) { return normalize(name, parentName, true); }) || ''; } //prefix and name should already be normalized, no need //for applying map config again either. normalizedMap = makeModuleMap(map.prefix + '!' + name, this.map.parentMap); on(normalizedMap, 'defined', bind(this, function (value) { this.init([], function () { return value; }, null, { enabled: true, ignore: true }); })); normalizedMod = getOwn(registry, normalizedMap.id); if (normalizedMod) { //Mark this as a dependency for this plugin, so it //can be traced for cycles. this.depMaps.push(normalizedMap); if (this.events.error) { normalizedMod.on('error', bind(this, function (err) { this.emit('error', err); })); } normalizedMod.enable(); } return; } load = bind(this, function (value) { this.init([], function () { return value; }, null, { enabled: true }); }); load.error = bind(this, function (err) { this.inited = true; this.error = err; err.requireModules = [id]; //Remove temp unnormalized modules for this module, //since they will never be resolved otherwise now. eachProp(registry, function (mod) { if (mod.map.id.indexOf(id + '_unnormalized') === 0) { cleanRegistry(mod.map.id); } }); onError(err); }); //Allow plugins to load other code without having to know the //context or how to 'complete' the load. load.fromText = bind(this, function (text, textAlt) { /*jslint evil: true */ var moduleName = map.name, moduleMap = makeModuleMap(moduleName), hasInteractive = useInteractive; //As of 2.1.0, support just passing the text, to reinforce //fromText only being called once per resource. Still //support old style of passing moduleName but discard //that moduleName in favor of the internal ref. if (textAlt) { text = textAlt; } //Turn off interactive script matching for IE for any define //calls in the text, then turn it back on at the end. if (hasInteractive) { useInteractive = false; } //Prime the system by creating a module instance for //it. getModule(moduleMap); //Transfer any config to this other module. if (hasProp(config.config, id)) { config.config[moduleName] = config.config[id]; } try { req.exec(text); } catch (e) { return onError(makeError('fromtexteval', 'fromText eval for ' + id + ' failed: ' + e, e, [id])); } if (hasInteractive) { useInteractive = true; } //Mark this as a dependency for the plugin //resource this.depMaps.push(moduleMap); //Support anonymous modules. context.completeLoad(moduleName); //Bind the value of that module to the value for this //resource ID. localRequire([moduleName], load); }); //Use parentName here since the plugin's name is not reliable, //could be some weird string with no path that actually wants to //reference the parentName's path. plugin.load(map.name, localRequire, load, config); })); context.enable(pluginMap, this); this.pluginMaps[pluginMap.id] = pluginMap; }, enable: function () { enabledRegistry[this.map.id] = this; this.enabled = true; //Set flag mentioning that the module is enabling, //so that immediate calls to the defined callbacks //for dependencies do not trigger inadvertent load //with the depCount still being zero. this.enabling = true; //Enable each dependency each(this.depMaps, bind(this, function (depMap, i) { var id, mod, handler; if (typeof depMap === 'string') { //Dependency needs to be converted to a depMap //and wired up to this module. depMap = makeModuleMap(depMap, (this.map.isDefine ? this.map : this.map.parentMap), false, !this.skipMap); this.depMaps[i] = depMap; handler = getOwn(handlers, depMap.id); if (handler) { this.depExports[i] = handler(this); return; } this.depCount += 1; on(depMap, 'defined', bind(this, function (depExports) { this.defineDep(i, depExports); this.check(); })); if (this.errback) { on(depMap, 'error', bind(this, this.errback)); } } id = depMap.id; mod = registry[id]; //Skip special modules like 'require', 'exports', 'module' //Also, don't call enable if it is already enabled, //important in circular dependency cases. if (!hasProp(handlers, id) && mod && !mod.enabled) { context.enable(depMap, this); } })); //Enable each plugin that is used in //a dependency eachProp(this.pluginMaps, bind(this, function (pluginMap) { var mod = getOwn(registry, pluginMap.id); if (mod && !mod.enabled) { context.enable(pluginMap, this); } })); this.enabling = false; this.check(); }, on: function (name, cb) { var cbs = this.events[name]; if (!cbs) { cbs = this.events[name] = []; } cbs.push(cb); }, emit: function (name, evt) { each(this.events[name], function (cb) { cb(evt); }); if (name === 'error') { //Now that the error handler was triggered, remove //the listeners, since this broken Module instance //can stay around for a while in the registry. delete this.events[name]; } } }; function callGetModule(args) { //Skip modules already defined. if (!hasProp(defined, args[0])) { getModule(makeModuleMap(args[0], null, true)).init(args[1], args[2]); } } function removeListener(node, func, name, ieName) { //Favor detachEvent because of IE9 //issue, see attachEvent/addEventListener comment elsewhere //in this file. if (node.detachEvent && !isOpera) { //Probably IE. If not it will throw an error, which will be //useful to know. if (ieName) { node.detachEvent(ieName, func); } } else { node.removeEventListener(name, func, false); } } /** * Given an event from a script node, get the requirejs info from it, * and then removes the event listeners on the node. * @param {Event} evt * @returns {Object} */ function getScriptData(evt) { //Using currentTarget instead of target for Firefox 2.0's sake. Not //all old browsers will be supported, but this one was easy enough //to support and still makes sense. var node = evt.currentTarget || evt.srcElement; //Remove the listeners once here. removeListener(node, context.onScriptLoad, 'load', 'onreadystatechange'); removeListener(node, context.onScriptError, 'error'); return { node: node, id: node && node.getAttribute('data-requiremodule') }; } function intakeDefines() { var args; //Any defined modules in the global queue, intake them now. takeGlobalQueue(); //Make sure any remaining defQueue items get properly processed. while (defQueue.length) { args = defQueue.shift(); if (args[0] === null) { return onError(makeError('mismatch', 'Mismatched anonymous define() module: ' + args[args.length - 1])); } else { //args are id, deps, factory. Should be normalized by the //define() function. callGetModule(args); } } } context = { config: config, contextName: contextName, registry: registry, defined: defined, urlFetched: urlFetched, defQueue: defQueue, Module: Module, makeModuleMap: makeModuleMap, nextTick: req.nextTick, onError: onError, /** * Set a configuration for the context. * @param {Object} cfg config object to integrate. */ configure: function (cfg) { //Make sure the baseUrl ends in a slash. if (cfg.baseUrl) { if (cfg.baseUrl.charAt(cfg.baseUrl.length - 1) !== '/') { cfg.baseUrl += '/'; } } //Save off the paths and packages since they require special processing, //they are additive. var pkgs = config.pkgs, shim = config.shim, objs = { paths: true, config: true, map: true }; eachProp(cfg, function (value, prop) { if (objs[prop]) { if (prop === 'map') { if (!config.map) { config.map = {}; } mixin(config[prop], value, true, true); } else { mixin(config[prop], value, true); } } else { config[prop] = value; } }); //Merge shim if (cfg.shim) { eachProp(cfg.shim, function (value, id) { //Normalize the structure if (isArray(value)) { value = { deps: value }; } if ((value.exports || value.init) && !value.exportsFn) { value.exportsFn = context.makeShimExports(value); } shim[id] = value; }); config.shim = shim; } //Adjust packages if necessary. if (cfg.packages) { each(cfg.packages, function (pkgObj) { var location; pkgObj = typeof pkgObj === 'string' ? { name: pkgObj } : pkgObj; location = pkgObj.location; //Create a brand new object on pkgs, since currentPackages can //be passed in again, and config.pkgs is the internal transformed //state for all package configs. pkgs[pkgObj.name] = { name: pkgObj.name, location: location || pkgObj.name, //Remove leading dot in main, so main paths are normalized, //and remove any trailing .js, since different package //envs have different conventions: some use a module name, //some use a file name. main: (pkgObj.main || 'main') .replace(currDirRegExp, '') .replace(jsSuffixRegExp, '') }; }); //Done with modifications, assing packages back to context config config.pkgs = pkgs; } //If there are any "waiting to execute" modules in the registry, //update the maps for them, since their info, like URLs to load, //may have changed. eachProp(registry, function (mod, id) { //If module already has init called, since it is too //late to modify them, and ignore unnormalized ones //since they are transient. if (!mod.inited && !mod.map.unnormalized) { mod.map = makeModuleMap(id); } }); //If a deps array or a config callback is specified, then call //require with those args. This is useful when require is defined as a //config object before require.js is loaded. if (cfg.deps || cfg.callback) { context.require(cfg.deps || [], cfg.callback); } }, makeShimExports: function (value) { function fn() { var ret; if (value.init) { ret = value.init.apply(global, arguments); } return ret || (value.exports && getGlobal(value.exports)); } return fn; }, makeRequire: function (relMap, options) { options = options || {}; function localRequire(deps, callback, errback) { var id, map, requireMod; if (options.enableBuildCallback && callback && isFunction(callback)) { callback.__requireJsBuild = true; } if (typeof deps === 'string') { if (isFunction(callback)) { //Invalid call return onError(makeError('requireargs', 'Invalid require call'), errback); } //If require|exports|module are requested, get the //value for them from the special handlers. Caveat: //this only works while module is being defined. if (relMap && hasProp(handlers, deps)) { return handlers[deps](registry[relMap.id]); } //Synchronous access to one module. If require.get is //available (as in the Node adapter), prefer that. if (req.get) { return req.get(context, deps, relMap, localRequire); } //Normalize module name, if it contains . or .. map = makeModuleMap(deps, relMap, false, true); id = map.id; if (!hasProp(defined, id)) { return onError(makeError('notloaded', 'Module name "' + id + '" has not been loaded yet for context: ' + contextName + (relMap ? '' : '. Use require([])'))); } return defined[id]; } //Grab defines waiting in the global queue. intakeDefines(); //Mark all the dependencies as needing to be loaded. context.nextTick(function () { //Some defines could have been added since the //require call, collect them. intakeDefines(); requireMod = getModule(makeModuleMap(null, relMap)); //Store if map config should be applied to this require //call for dependencies. requireMod.skipMap = options.skipMap; requireMod.init(deps, callback, errback, { enabled: true }); checkLoaded(); }); return localRequire; } mixin(localRequire, { isBrowser: isBrowser, /** * Converts a module name + .extension into an URL path. * *Requires* the use of a module name. It does not support using * plain URLs like nameToUrl. */ toUrl: function (moduleNamePlusExt) { var ext, index = moduleNamePlusExt.lastIndexOf('.'), segment = moduleNamePlusExt.split('/')[0], isRelative = segment === '.' || segment === '..'; //Have a file extension alias, and it is not the //dots from a relative path. if (index !== -1 && (!isRelative || index > 1)) { ext = moduleNamePlusExt.substring(index, moduleNamePlusExt.length); moduleNamePlusExt = moduleNamePlusExt.substring(0, index); } return context.nameToUrl(normalize(moduleNamePlusExt, relMap && relMap.id, true), ext, true); }, defined: function (id) { return hasProp(defined, makeModuleMap(id, relMap, false, true).id); }, specified: function (id) { id = makeModuleMap(id, relMap, false, true).id; return hasProp(defined, id) || hasProp(registry, id); } }); //Only allow undef on top level require calls if (!relMap) { localRequire.undef = function (id) { //Bind any waiting define() calls to this context, //fix for #408 takeGlobalQueue(); var map = makeModuleMap(id, relMap, true), mod = getOwn(registry, id); removeScript(id); delete defined[id]; delete urlFetched[map.url]; delete undefEvents[id]; if (mod) { //Hold on to listeners in case the //module will be attempted to be reloaded //using a different config. if (mod.events.defined) { undefEvents[id] = mod.events; } cleanRegistry(id); } }; } return localRequire; }, /** * Called to enable a module if it is still in the registry * awaiting enablement. A second arg, parent, the parent module, * is passed in for context, when this method is overriden by * the optimizer. Not shown here to keep code compact. */ enable: function (depMap) { var mod = getOwn(registry, depMap.id); if (mod) { getModule(depMap).enable(); } }, /** * Internal method used by environment adapters to complete a load event. * A load event could be a script load or just a load pass from a synchronous * load call. * @param {String} moduleName the name of the module to potentially complete. */ completeLoad: function (moduleName) { var found, args, mod, shim = getOwn(config.shim, moduleName) || {}, shExports = shim.exports; takeGlobalQueue(); while (defQueue.length) { args = defQueue.shift(); if (args[0] === null) { args[0] = moduleName; //If already found an anonymous module and bound it //to this name, then this is some other anon module //waiting for its completeLoad to fire. if (found) { break; } found = true; } else if (args[0] === moduleName) { //Found matching define call for this script! found = true; } callGetModule(args); } //Do this after the cycle of callGetModule in case the result //of those calls/init calls changes the registry. mod = getOwn(registry, moduleName); if (!found && !hasProp(defined, moduleName) && mod && !mod.inited) { if (config.enforceDefine && (!shExports || !getGlobal(shExports))) { if (hasPathFallback(moduleName)) { return; } else { return onError(makeError('nodefine', 'No define call for ' + moduleName, null, [moduleName])); } } else { //A script that does not call define(), so just simulate //the call for it. callGetModule([moduleName, (shim.deps || []), shim.exportsFn]); } } checkLoaded(); }, /** * Converts a module name to a file path. Supports cases where * moduleName may actually be just an URL. * Note that it **does not** call normalize on the moduleName, * it is assumed to have already been normalized. This is an * internal API, not a public one. Use toUrl for the public API. */ nameToUrl: function (moduleName, ext, skipExt) { var paths, pkgs, pkg, pkgPath, syms, i, parentModule, url, parentPath; //If a colon is in the URL, it indicates a protocol is used and it is just //an URL to a file, or if it starts with a slash, contains a query arg (i.e. ?) //or ends with .js, then assume the user meant to use an url and not a module id. //The slash is important for protocol-less URLs as well as full paths. if (req.jsExtRegExp.test(moduleName)) { //Just a plain path, not module name lookup, so just return it. //Add extension if it is included. This is a bit wonky, only non-.js things pass //an extension, this method probably needs to be reworked. url = moduleName + (ext || ''); } else { //A module that needs to be converted to a path. paths = config.paths; pkgs = config.pkgs; syms = moduleName.split('/'); //For each module name segment, see if there is a path //registered for it. Start with most specific name //and work up from it. for (i = syms.length; i > 0; i -= 1) { parentModule = syms.slice(0, i).join('/'); pkg = getOwn(pkgs, parentModule); parentPath = getOwn(paths, parentModule); if (parentPath) { //If an array, it means there are a few choices, //Choose the one that is desired if (isArray(parentPath)) { parentPath = parentPath[0]; } syms.splice(0, i, parentPath); break; } else if (pkg) { //If module name is just the package name, then looking //for the main module. if (moduleName === pkg.name) { pkgPath = pkg.location + '/' + pkg.main; } else { pkgPath = pkg.location; } syms.splice(0, i, pkgPath); break; } } //Join the path parts together, then figure out if baseUrl is needed. url = syms.join('/'); url += (ext || (/^data\:|\?/.test(url) || skipExt ? '' : '.js')); url = (url.charAt(0) === '/' || url.match(/^[\w\+\.\-]+:/) ? '' : config.baseUrl) + url; } return config.urlArgs ? url + ((url.indexOf('?') === -1 ? '?' : '&') + config.urlArgs) : url; }, //Delegates to req.load. Broken out as a separate function to //allow overriding in the optimizer. load: function (id, url) { req.load(context, id, url); }, /** * Executes a module callback function. Broken out as a separate function * solely to allow the build system to sequence the files in the built * layer in the right sequence. * * @private */ execCb: function (name, callback, args, exports) { return callback.apply(exports, args); }, /** * callback for script loads, used to check status of loading. * * @param {Event} evt the event from the browser for the script * that was loaded. */ onScriptLoad: function (evt) { //Using currentTarget instead of target for Firefox 2.0's sake. Not //all old browsers will be supported, but this one was easy enough //to support and still makes sense. if (evt.type === 'load' || (readyRegExp.test((evt.currentTarget || evt.srcElement).readyState))) { //Reset interactive script so a script node is not held onto for //to long. interactiveScript = null; //Pull out the name of the module and the context. var data = getScriptData(evt); context.completeLoad(data.id); } }, /** * Callback for script errors. */ onScriptError: function (evt) { var data = getScriptData(evt); if (!hasPathFallback(data.id)) { return onError(makeError('scripterror', 'Script error for: ' + data.id, evt, [data.id])); } } }; context.require = context.makeRequire(); return context; } /** * Main entry point. * * If the only argument to require is a string, then the module that * is represented by that string is fetched for the appropriate context. * * If the first argument is an array, then it will be treated as an array * of dependency string names to fetch. An optional function callback can * be specified to execute when all of those dependencies are available. * * Make a local req variable to help Caja compliance (it assumes things * on a require that are not standardized), and to give a short * name for minification/local scope use. */ req = requirejs = function (deps, callback, errback, optional) { //Find the right context, use default var context, config, contextName = defContextName; // Determine if have config object in the call. if (!isArray(deps) && typeof deps !== 'string') { // deps is a config object config = deps; if (isArray(callback)) { // Adjust args if there are dependencies deps = callback; callback = errback; errback = optional; } else { deps = []; } } if (config && config.context) { contextName = config.context; } context = getOwn(contexts, contextName); if (!context) { context = contexts[contextName] = req.s.newContext(contextName); } if (config) { context.configure(config); } return context.require(deps, callback, errback); }; /** * Support require.config() to make it easier to cooperate with other * AMD loaders on globally agreed names. */ req.config = function (config) { return req(config); }; /** * Execute something after the current tick * of the event loop. Override for other envs * that have a better solution than setTimeout. * @param {Function} fn function to execute later. */ req.nextTick = typeof setTimeout !== 'undefined' ? function (fn) { setTimeout(fn, 4); } : function (fn) { fn(); }; /** * Export require as a global, but only if it does not already exist. */ if (!require) { require = req; } req.version = version; //Used to filter out dependencies that are already paths. req.jsExtRegExp = /^\/|:|\?|\.js$/; req.isBrowser = isBrowser; s = req.s = { contexts: contexts, newContext: newContext }; //Create default context. req({}); //Exports some context-sensitive methods on global require. each([ 'toUrl', 'undef', 'defined', 'specified' ], function (prop) { //Reference from contexts instead of early binding to default context, //so that during builds, the latest instance of the default context //with its config gets used. req[prop] = function () { var ctx = contexts[defContextName]; return ctx.require[prop].apply(ctx, arguments); }; }); if (isBrowser) { head = s.head = document.getElementsByTagName('head')[0]; //If BASE tag is in play, using appendChild is a problem for IE6. //When that browser dies, this can be removed. Details in this jQuery bug: //http://dev.jquery.com/ticket/2709 baseElement = document.getElementsByTagName('base')[0]; if (baseElement) { head = s.head = baseElement.parentNode; } } /** * Any errors that require explicitly generates will be passed to this * function. Intercept/override it if you want custom error handling. * @param {Error} err the error object. */ req.onError = defaultOnError; /** * Creates the node for the load command. Only used in browser envs. */ req.createNode = function (config, moduleName, url) { var node = config.xhtml ? document.createElementNS('http://www.w3.org/1999/xhtml', 'html:script') : document.createElement('script'); node.type = config.scriptType || 'text/javascript'; node.charset = 'utf-8'; node.async = true; return node; }; /** * Does the request to load a module for the browser case. * Make this a separate function to allow other environments * to override it. * * @param {Object} context the require context to find state. * @param {String} moduleName the name of the module. * @param {Object} url the URL to the module. */ req.load = function (context, moduleName, url) { var config = (context && context.config) || {}, node; if (isBrowser) { //In the browser so use a script tag node = req.createNode(config, moduleName, url); node.setAttribute('data-requirecontext', context.contextName); node.setAttribute('data-requiremodule', moduleName); //Set up load listener. Test attachEvent first because IE9 has //a subtle issue in its addEventListener and script onload firings //that do not match the behavior of all other browsers with //addEventListener support, which fire the onload event for a //script right after the script execution. See: //https://connect.microsoft.com/IE/feedback/details/648057/script-onload-event-is-not-fired-immediately-after-script-execution //UNFORTUNATELY Opera implements attachEvent but does not follow the script //script execution mode. if (node.attachEvent && //Check if node.attachEvent is artificially added by custom script or //natively supported by browser //read https://github.com/jrburke/requirejs/issues/187 //if we can NOT find [native code] then it must NOT natively supported. //in IE8, node.attachEvent does not have toString() //Note the test for "[native code" with no closing brace, see: //https://github.com/jrburke/requirejs/issues/273 !(node.attachEvent.toString && node.attachEvent.toString().indexOf('[native code') < 0) && !isOpera) { //Probably IE. IE (at least 6-8) do not fire //script onload right after executing the script, so //we cannot tie the anonymous define call to a name. //However, IE reports the script as being in 'interactive' //readyState at the time of the define call. useInteractive = true; node.attachEvent('onreadystatechange', context.onScriptLoad); //It would be great to add an error handler here to catch //404s in IE9+. However, onreadystatechange will fire before //the error handler, so that does not help. If addEventListener //is used, then IE will fire error before load, but we cannot //use that pathway given the connect.microsoft.com issue //mentioned above about not doing the 'script execute, //then fire the script load event listener before execute //next script' that other browsers do. //Best hope: IE10 fixes the issues, //and then destroys all installs of IE 6-9. //node.attachEvent('onerror', context.onScriptError); } else { node.addEventListener('load', context.onScriptLoad, false); node.addEventListener('error', context.onScriptError, false); } node.src = url; //For some cache cases in IE 6-8, the script executes before the end //of the appendChild execution, so to tie an anonymous define //call to the module name (which is stored on the node), hold on //to a reference to this node, but clear after the DOM insertion. currentlyAddingScript = node; if (baseElement) { head.insertBefore(node, baseElement); } else { head.appendChild(node); } currentlyAddingScript = null; return node; } else if (isWebWorker) { try { //In a web worker, use importScripts. This is not a very //efficient use of importScripts, importScripts will block until //its script is downloaded and evaluated. However, if web workers //are in play, the expectation that a build has been done so that //only one script needs to be loaded anyway. This may need to be //reevaluated if other use cases become common. importScripts(url); //Account for anonymous modules context.completeLoad(moduleName); } catch (e) { context.onError(makeError('importscripts', 'importScripts failed for ' + moduleName + ' at ' + url, e, [moduleName])); } } }; function getInteractiveScript() { if (interactiveScript && interactiveScript.readyState === 'interactive') { return interactiveScript; } eachReverse(scripts(), function (script) { if (script.readyState === 'interactive') { return (interactiveScript = script); } }); return interactiveScript; } //Look for a data-main script attribute, which could also adjust the baseUrl. if (isBrowser && !cfg.skipDataMain) { //Figure out baseUrl. Get it from the script tag with require.js in it. eachReverse(scripts(), function (script) { //Set the 'head' where we can append children by //using the script's parent. if (!head) { head = script.parentNode; } //Look for a data-main attribute to set main script for the page //to load. If it is there, the path to data main becomes the //baseUrl, if it is not already set. dataMain = script.getAttribute('data-main'); if (dataMain) { //Preserve dataMain in case it is a path (i.e. contains '?') mainScript = dataMain; //Set final baseUrl if there is not already an explicit one. if (!cfg.baseUrl) { //Pull off the directory of data-main for use as the //baseUrl. src = mainScript.split('/'); mainScript = src.pop(); subPath = src.length ? src.join('/') + '/' : './'; cfg.baseUrl = subPath; } //Strip off any trailing .js since mainScript is now //like a module name. mainScript = mainScript.replace(jsSuffixRegExp, ''); //If mainScript is still a path, fall back to dataMain if (req.jsExtRegExp.test(mainScript)) { mainScript = dataMain; } //Put the data-main script in the files to load. cfg.deps = cfg.deps ? cfg.deps.concat(mainScript) : [mainScript]; return true; } }); } /** * The function that handles definitions of modules. Differs from * require() in that a string for the module should be the first argument, * and the function to execute after dependencies are loaded should * return a value to define the module corresponding to the first argument's * name. */ define = function (name, deps, callback) { var node, context; //Allow for anonymous modules if (typeof name !== 'string') { //Adjust args appropriately callback = deps; deps = name; name = null; } //This module may not have dependencies if (!isArray(deps)) { callback = deps; deps = null; } //If no name, and callback is a function, then figure out if it a //CommonJS thing with dependencies. if (!deps && isFunction(callback)) { deps = []; //Remove comments from the callback string, //look for require calls, and pull them into the dependencies, //but only if there are function args. if (callback.length) { callback .toString() .replace(commentRegExp, '') .replace(cjsRequireRegExp, function (match, dep) { deps.push(dep); }); //May be a CommonJS thing even without require calls, but still //could use exports, and module. Avoid doing exports and module //work though if it just needs require. //REQUIRES the function to expect the CommonJS variables in the //order listed below. deps = (callback.length === 1 ? ['require'] : ['require', 'exports', 'module']).concat(deps); } } //If in IE 6-8 and hit an anonymous define() call, do the interactive //work. if (useInteractive) { node = currentlyAddingScript || getInteractiveScript(); if (node) { if (!name) { name = node.getAttribute('data-requiremodule'); } context = contexts[node.getAttribute('data-requirecontext')]; } } //Always save off evaluating the def call until the script onload handler. //This allows multiple modules to be in a file without prematurely //tracing dependencies, and allows for anonymous module support, //where the module name is not known until the script onload event //occurs. If no context, use the global queue, and get it processed //in the onscript load callback. (context ? context.defQueue : globalDefQueue).push([name, deps, callback]); }; define.amd = { jQuery: true }; /** * Executes the text. Normally just uses eval, but can be modified * to use a better, environment-specific call. Only used for transpiling * loader plugins, not for plain JS modules. * @param {String} text the text to execute/evaluate. */ req.exec = function (text) { /*jslint evil: true */ return eval(text); }; //Set up with config info. req(cfg); }(this)); sizzle-1.10.17/speed/selectors.css000066400000000000000000000012701226755370700170340ustar00rootroot00000000000000.note #title h1#title div #title div.example ul .tocline2 .title .toc .toc .tocline2 .tocline2, .tocline3, .tocline4 div.example, div.note body div body div div p div > p div + p div ~ p div[class^=exa][class$=mple] div p a div > p > a div.example > p > a div + p + a div ~ p ~ p div, p, a ul.toc li.tocline2 ul.toc > li.tocline2 h1#title + div > p h1[id]:contains(Selectors) a[href][lang][class] div[class] div[class=example] div[class^=exa] div[class$=mple] div[class*=e] div[class|=dialog] div[class!=made_up] div[class~=example] div:not(.example) p:contains(selectors) p:nth-child(even) p:nth-child(2n) p:nth-child(odd) p:nth-child(2n+1) p:nth-child(n) p:only-child p:last-child p:first-childsizzle-1.10.17/speed/selectors.large.css000066400000000000000000000175051226755370700201350ustar00rootroot00000000000000.note #title h1#title div #title div.example ul .tocline2 .title .toc .toc .tocline2 .tocline2, .tocline3, .tocline4 div.example, div.note body div body div div p div > p div + p div ~ p div[class^=exa][class$=mple] div p a div, p, a ul.toc li.tocline2 ul.toc > li.tocline2 h1#title + div > p h1[id]:contains(Selectors) a[href][lang][class] div[class] div[class=example] div[class^=exa] div[class$=mple] div[class*=e] div[class|=dialog] div[class!=made_up] div[class~=example] div:not(.example) p:contains(selectors) p:nth-child(even) p:nth-child(2n) p:nth-child(odd) p:nth-child(2n+1) p:nth-child(n) p:only-child p:last-child p:first-child * A [foo] [foo="bar"] [foo~="bar"] [hreflang|="en"] [foo^="bar"] [foo$="bar"] [foo*="bar"] :first-child :root :nth-child(n) :nth-last-child(n) :nth-of-type(n) :nth-last-of-type(n) :last-child :first-of-type :last-of-type :only-child :only-of-type :empty :link :visited :active :hover :focus :lang(fr) :target :disabled :enabled :checked .warning #myid #myid * B * > B * + B * ~ B :not(B) :not(*) :not([foo]) :not([foo="bar"]) :not([foo~="bar"]) :not([hreflang|="en"]) :not([foo^="bar"]) :not([foo$="bar"]) :not([foo*="bar"]) :not(:first-child) :not(:root) :not(:nth-child(n)) :not(:nth-last-child(n)) :not(:nth-of-type(n)) :not(:nth-last-of-type(n)) :not(:last-child) :not(:first-of-type) :not(:last-of-type) :not(:only-child) :not(:only-of-type) :not(:empty) :not(:link) :not(:visited) :not(:active) :not(:hover) :not(:focus) :not(:lang(fr)) :not(:target) :not(:disabled) :not(:enabled) :not(:checked) :not(.warning) :not(#myid) li,p address * ul, p *.t1 * ul, p *.t1 #foo p p p[title] address address[title="foo"] span[title="a"] p p[class~="b"] address address[title~="foo"] span[class~="b"] p [title~="hello world"] p p[lang|="en"] address address[lang="fi"] span[lang|="fr"] p p[title^="foo"] p p[title$="bar"] p p[title*="bar"] li .t1 li.t2 .t3 p p.t1 p.t2 div div.teST div.te div.st div.te.st p .t1.fail .fail.t1 .t2.fail .fail.t2 p p.t1.t2 div div.t1 address address.t5.t5 p .t1:not(.t2) :not(.t2).t1 .t2:not(.t1) :not(.t1).t2 p p:not(.t1):not(.t2) div div:not(.t1) address address:not(.t5):not(.t5) li #t1 li#t2 li#t3 #t4 p #test#fail #fail#test #fail div #pass#pass .warning div #Aone#Atwo, #Aone#Athree, #Atwo#Athree p #Bone#Btwo, #Bone#Bthree, #Btwo#Bthree #Cone#Ctwo, #Cone#Cthree, #Ctwo#Cthree #Done#Dtwo, #Done#Dthree, #Dtwo#Dthree p.test a p.test *:link p.test a p.test *:visited p:hover a:hover tr:hover td:hover table p .a a:hover .b a:hover .b a:link .c :link .c :visited:hover div:hover > p:first-child :link, :visited :link:hover span a:active button:active a:focus p:target p p:target :root :target ul > li li:lang(en-GB) button input button:enabled input:enabled button input button:disabled input:disabled input, span input:checked, input:checked + span html *:root :root:first-child :root:last-child :root:only-child :root:nth-child(1) :root:nth-child(n) :root:nth-last-child(1) :root:nth-last-child(n) :root:first-of-type :root:last-of-type :root:only-of-type :root:nth-of-type(1) :root:nth-of-type(n) :root:nth-last-of-type(1) :root:nth-last-of-type(n) p * html * :root p .red ul > li:nth-child(odd) ol > li:nth-child(even) table.t1 tr:nth-child(-n+4) table.t2 td:nth-child(3n+1) .green ul > li:nth-child(odd) ol > li:nth-child(even) table.t1 tr:nth-child(-n+4) table.t2 td:nth-child(3n+1) .red ul > li:nth-last-child(odd) ol > li:nth-last-child(even) table.t1 tr:nth-last-child(-n+4) table.t2 td:nth-last-child(3n+1) .green ul > li:nth-last-child(odd) ol > li:nth-last-child(even) table.t1 tr:nth-last-child(-n+4) table.t2 td:nth-last-child(3n+1) .red p:nth-of-type(3) dl > :nth-of-type(3n+1) .red p:nth-last-of-type(3) dl > :nth-last-of-type(3n+1) .red .t1 td:first-child p > *:first-child .red .t1 td:last-child p > *:last-child .red address address:first-of-type .red address address:last-of-type .red p:only-child div.testText > div > p .red .t1 :only-of-type .white .red div.t1 p .white .green div.t1 p .white .red div > p.test .white .green div > p.test .fail > div .control #fail > div p .red div.stub > p + p .green .white div.stub > p + p .fail + div .control .red div.stub > p ~ p .green div.stub > p ~ p div.stub > * div.stub *:not(.foo) div.stub > * div.stub *:not(#foo) div.stub > * div.stub *:not(:link) div.stub > * div.stub *:not(:visited) div.stub * div.stub > * > *:not(:hover) div.stub * div.stub > * > *:not(:active) a:not(:focus) a p p:not(:target) p p:not(:target) div.stub * div.stub *:not(:lang(fr)) button input button:not(:enabled) input:not(:enabled) button input button:not(:disabled) input:not(:disabled) input, span input:not(:checked), input:not(:checked) + span p:not(:root) div * html:not(:root), test:not(:root) p .red ul > li:not(:nth-child(odd)) ol > li:not(:nth-child(even)) table.t1 tr:not(:nth-child(-n+4)) table.t2 td:not(:nth-child(3n+1)) table.t1 td, table.t2 td .green ul > li:not(:nth-child(odd)) ol > li:not(:nth-child(even)) table.t1 tr:not(:nth-child(-n+4)) table.t2 td:not(:nth-child(3n+1)) table.t1 td, table.t2 td .red ul > li:not(:nth-last-child(odd)) ol > li:not(:nth-last-child(even)) table.t1 tr:not(:nth-last-child(-n+4)) table.t2 td:not(:nth-last-child(3n+1)) table.t1 td, table.t2 td .green ul > li:not(:nth-last-child(odd)) ol > li:not(:nth-last-child(even)) table.t1 tr:not(:nth-last-child(-n+4)) table.t2 td:not(:nth-last-child(3n+1)) table.t1 td, table.t2 td .red p:not(:nth-of-type(3)) dl > *:not(:nth-of-type(3n+1)) .green p:not(:nth-of-type(3)) dl > *:not(:nth-of-type(3n+1)) .red p:not(:nth-last-of-type(3)) dl > *:not(:nth-last-of-type(3n+1)) .green p:not(:nth-last-of-type(3)) dl > *:not(:nth-last-of-type(3n+1)) .red .t1 td:not(:first-child) p > *:not(:first-child) table.t1 td .green .t1 td:not(:first-child) p > *:not(:first-child) table.t1 td .red .t1 td:not(:last-child) p > *:not(:last-child) table.t1 td .green .t1 td:not(:last-child) p > *:not(:last-child) table.t1 td .red address address:not(:first-of-type) .red address address:not(:last-of-type) .red p:not(:only-child) div.testText > div > p .green p:not(:only-child) div.testText > div > p .red .t1 *:not(:only-of-type) .green .t1 *:not(:only-of-type) p p:not(:not(p)) p blockquote > div p p blockquote + div ~ p p blockquote + div ~ p p blockquote + div p p blockquote + div p p blockquote div > p p blockquote ~ div + p p blockquote ~ div + p div :not(:enabled):not(:disabled) p line [type~=odd] line:nth-of-type(odd) [hidden] line [type~=odd] line:nth-of-type(odd) [hidden] line [type~=match] line:nth-child(3n-1) [hidden] line [type~=match] line:nth-child(3n-1) [hidden] line [type~=match] line:nth-last-of-type(3n-1) [hidden] line [type~=match] line:nth-last-of-type(3n-1) [hidden] p p:empty address:empty address .text address:empty address .text address:empty address .text address address:empty .text address address:empty .text address address:empty .text p p, p .5cm p .\5cm p .two\ words p .one.word .one\.word p p foo & address, p foo & address, p p foo & address, p p p [*=test] p p:subject p p * p > * p + * p ~ * td > div td > div > span .test strong p .fail p .13 p .\13 p .\31 \33 div p::first-child .cs .cs P .cs .a .cs .span1 span .cs .span2 .cs .span2 SPAN .cs .span2 span .ci .ci P .ci .a .ci .span1 span .ci .span2 SPAN p foo\:bar p ..test .foo..quux .bar. #test #test:not(:empty) #test1 #test1:empty #test2 #test2:empty #test #stub ~ div div + div > div [test] stub ~ [|attribute^=start]:not([|attribute~=mid])[|attribute*=dle][|attribute$=end] ~ t #two:first-child #three:last-child input, span input:indeterminate, input:indeterminate + span input, span input:checked, input:checked + span input, span input:not(:checked), input:not(:checked) + span p[example=publicclass] p[example="public"]sizzle-1.10.17/speed/selectors.small.css000066400000000000000000000000551226755370700201430ustar00rootroot00000000000000.note #title div[class=example] p:first-childsizzle-1.10.17/speed/speed.css000066400000000000000000000233011226755370700161300ustar00rootroot00000000000000/** * speed.css * * Styles for SizzleSpeed */ /*! normalize.css v1.0.1 | MIT License | git.io/normalize */ article,aside,details,figcaption,figure,footer,header,hgroup,nav,section,summary { display: block; } audio,canvas,video { display: inline-block; *display: inline; *zoom: 1; } audio:not([controls]) { display: none; height: 0; } [hidden] { display: none; } html { font-size: 100%; /* 1 */ -webkit-text-size-adjust: 100%; /* 2 */ -ms-text-size-adjust: 100%; /* 2 */ } html,button,input,select,textarea { font-family: sans-serif; } body { margin: 0; } a:focus { outline: thin dotted; } a:active,a:hover { outline: 0; } h1 { font-size: 2em; margin: 0.67em 0; } h2 { font-size: 1.5em; margin: 0.83em 0; } h3 { font-size: 1.17em; margin: 1em 0; } h4 { font-size: 1em; margin: 1.33em 0; } h5 { font-size: 0.83em; margin: 1.67em 0; } h6 { font-size: 0.75em; margin: 2.33em 0; } abbr[title] { border-bottom: 1px dotted; } b,strong { font-weight: bold; } blockquote { margin: 1em 40px; } dfn { font-style: italic; } mark { background: #ff0; color: #000; } p,pre { margin: 1em 0; } code,kbd,pre,samp { font-family: monospace, serif; _font-family: 'courier new', monospace; font-size: 1em; } pre { white-space: pre; white-space: pre-wrap; word-wrap: break-word; } q { quotes: none; } q:before,q:after { content: ''; content: none; } small { font-size: 80%; } sub,sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; } sup { top: -0.5em; } sub { bottom: -0.25em; } dl,menu,ol,ul { margin: 1em 0;} dd { margin: 0 0 0 40px; } menu,ol,ul { padding: 0 0 0 40px; } nav ul,nav ol { list-style: none; list-style-image: none; } img { border: 0; /* 1 */ -ms-interpolation-mode: bicubic; /* 2 */ } svg:not(:root) { overflow: hidden; } figure { margin: 0; } form { margin: 0; } fieldset { border: 1px solid #c0c0c0; margin: 0 2px; padding: 0.35em 0.625em 0.75em; } legend { border: 0; /* 1 */ padding: 0; white-space: normal; /* 2 */ *margin-left: -7px; /* 3 */ } button,input,select,textarea { font-size: 100%; /* 1 */ margin: 0; /* 2 */ vertical-align: baseline; /* 3 */ *vertical-align: middle; /* 3 */ } button,input { line-height: normal; } button,html input[type="button"], /* 1 */input[type="reset"],input[type="submit"] { -webkit-appearance: button; /* 2 */ cursor: pointer; /* 3 */ *overflow: visible; /* 4 */ } button[disabled],input[disabled] { cursor: default; } input[type="checkbox"],input[type="radio"] { box-sizing: border-box; /* 1 */ padding: 0; /* 2 */ *height: 13px; /* 3 */ *width: 13px; /* 3 */ } input[type="search"] { -webkit-appearance: textfield; /* 1 */ -moz-box-sizing: content-box; -webkit-box-sizing: content-box; /* 2 */ box-sizing: content-box; } input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration { -webkit-appearance: none; } button::-moz-focus-inner,input::-moz-focus-inner { border: 0; padding: 0; } textarea { overflow: auto; /* 1 */ vertical-align: top; /* 2 */ } table { border-collapse: collapse; border-spacing: 0; } /* ==|== animations ======================================== */ @-webkit-keyframes shake { from { -webkit-transform: translate3d(0, 0, 0); } 40% { -webkit-transform: translate3d(0, 0, 0); } 50% { -webkit-transform: translate3d(-4px, 0, 0); } 75% { -webkit-transform: translate3d(4px, 0, 0); } 90% { -webkit-transform: translate3d(-2px, 0, 0); } 95% { -webkit-transform: translate3d(1px, 0, 0); } to { -webkit-transform: translate3d(0, 0, 0); } } @-moz-keyframes shake { from { -moz-transform: translate(0, 0); } 40% { -moz-transform: translate(0, 0); } 50% { -moz-transform: translate(-4px, 0); } 75% { -moz-transform: translate(4px, 0); } 90% { -moz-transform: translate(-2px, 0); } 95% { -moz-transform: translate(1px, 0); } to { -moz-transform: translate(0, 0); } } @-o-keyframes shake { from { -o-transform: translate(0, 0); } 40% { -o-transform: translate(0, 0); } 50% { -o-transform: translate(-4px, 0); } 75% { -o-transform: translate(4px, 0); } 90% { -o-transform: translate(-2px, 0); } 95% { -o-transform: translate(1px, 0); } to { -o-transform: translate(0, 0); } } @-ms-keyframes shake { from { -ms-transform: translate(0, 0); } 40% { -ms-transform: translate(0, 0); } 50% { -ms-transform: translate(-4px, 0); } 75% { -ms-transform: translate(4px, 0); } 90% { -ms-transform: translate(-2px, 0); } 95% { -ms-transform: translate(1px, 0); } to { -ms-transform: translate(0, 0); } } @keyframes shake { from { transform: translate(0, 0); } 40% { transform: translate(0, 0); } 50% { transform: translate(-4px, 0); } 75% { transform: translate(4px, 0); } 90% { transform: translate(-2px, 0); } 95% { transform: translate(1px, 0); } to { transform: translate(0, 0); } } /* ==|== Performance suite styles ======================================== */ body { padding: 40px; font: 14px/1.4 "Helvetica Neue", Helvetica, Arial, sans-serif; } body.complete { background: rgb(230, 255, 230); } small, .small { font-size: 0.85em; } a { color: #730E00; } a:hover { color: #EE1E00; } a:active { color: black; } #logo { padding: 10px; display: block; margin-bottom: 10px; background: #8C0000; -moz-box-shadow: rgba(0, 0, 0, 0.5) 0px 3px 3px; -webkit-box-shadow: rgba(0, 0, 0, 0.5) 0px 3px 3px; box-shadow: rgba(0, 0, 0, 0.5) 0px 3px 3px; -webkit-border-radius: 10px; -moz-border-radius: 10px; border-radius: 10px; } /* ==|== table styles ======================================== */ .table { width: 100%; margin: 1.2em 0 3em; } .table th, .table td { padding: 5px 10px; width: 150px; line-height: 1.4; text-align: left; vertical-align: middle; } .table th.text-right, .table td.text-right { text-align: right; } .table th { color: #9F0000; text-shadow: rgba(0, 0, 0, 0.2) 0 1px; background: rgb(240, 240, 240); font-weight: 600; } .table td { font-size: 12px; } .table thead th { vertical-align: bottom; } .table caption + thead tr:first-child th, .table caption + thead tr:first-child td, .table colgroup + thead tr:first-child th, .table colgroup + thead tr:first-child td, .table thead:first-child tr:first-child th, .table thead:first-child tr:first-child td { border-top: 0; } .table tbody + tbody { border-top: 2px solid #dddddd; } .table-dark td { color: #31373c; } .table-condensed th, .table-condensed td { padding: 4px 5px; } .table-semi-bordered td { border-right: 1px solid #dddddd; border-top: 1px solid #dddddd; } .table-semi-bordered td:first-child { border-left: 1px solid #dddddd; } .table-bordered { border: 2px solid #dddddd; border-bottom: 0; border-collapse: separate; *border-collapse: collapse; border-left: 0; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; } .table-bordered th, .table-bordered td { border-left: 2px solid #dddddd; border-bottom: 2px solid #dddddd; } .table-bordered caption + thead tr:first-child th, .table-bordered caption + tbody tr:first-child th, .table-bordered caption + tbody tr:first-child td, .table-bordered colgroup + thead tr:first-child th, .table-bordered colgroup + tbody tr:first-child th, .table-bordered colgroup + tbody tr:first-child td, .table-bordered thead:first-child tr:first-child th, .table-bordered tbody:first-child tr:first-child th, .table-bordered tbody:first-child tr:first-child td { border-top: 0; } .table-bordered thead:first-child tr:first-child th:first-child, .table-bordered tbody:first-child tr:first-child td:first-child { -webkit-border-top-left-radius: 4px; -moz-border-radius-topleft: 4px; border-top-left-radius: 4px; } .table-bordered thead:first-child tr:first-child th:last-child, .table-bordered tbody:first-child tr:first-child td:last-child { -webkit-border-top-right-radius: 4px; -moz-border-radius-topright: 4px; border-top-right-radius: 4px; } .table-bordered thead:last-child tr:last-child th:first-child, .table-bordered tbody:last-child tr:last-child td:first-child { -webkit-border-radius: 0 0 0 4px; -moz-border-radius: 0 0 0 4px; border-radius: 0 0 0 4px; } .table-bordered thead:last-child tr:last-child th:last-child, .table-bordered tbody:last-child tr:last-child td:last-child { -webkit-border-bottom-right-radius: 4px; -moz-border-radius-bottomright: 4px; border-bottom-right-radius: 4px; } .table-striped tbody tr:nth-child(even) td, .table-striped tbody tr:nth-child(even) th { background-color: #f9f9f9; } .table tbody tr:hover td, .table tbody tr:hover th, .table tbody tr .table-hover-background { background-color: #f0f6fa; } .table tbody tr td.red { background: #FF5E5E; } .table tbody tr td.green { background: #19EB4B; } .table tbody tr td.black { background: #41464D; color: #F3F1F1; } .table tbody tr td.yellow { background: hsl(60, 108%, 65%); } .table tbody tr td.pending { background: hsl(215, 100%, 80%); } .selector { background: hsl(215, 100%, 95%); } .pending span { display: inline-block; *display: inline; -webkit-animation-name: shake; -moz-animation-name: shake; -o-animation-name: shake; -ms-animation-name: shake; animation-name: shake; -webkit-animation-duration: 0.7s; -moz-animation-duration: 0.7s; -o-animation-duration: 0.7s; -ms-animation-duration: 0.7s; animation-duration: 0.7s; -webkit-animation-iteration-count: infinite; -moz-animation-iteration-count: infinite; -o-animation-iteration-count: infinite; -ms-animation-iteration-count: infinite; animation-iteration-count: infinite; } /* ==|== helper classes ======================================== */ .clear { clear: both; } .bold { font-weight: bold; } sizzle-1.10.17/speed/speed.js000066400000000000000000000360251226755370700157630ustar00rootroot00000000000000/* * Performance test suite using benchmark.js */ require([ "libs/benchmark/benchmark", "libs/requirejs-domready/domReady!", "libs/requirejs-text/text!selectors.css", "data/checkJava" ], function( Benchmark, document, selectors ) { // Convert selectors to an array selectors = selectors.split("\n"); var // Used to indicate whether console profiling is begin run profiling, trim, // Class manipulation // IE doesn't match non-breaking spaces with \s rtrim = /\S/.test("\xA0") ? (/^[\s\xA0]+|[\s\xA0]+$/g) : /^\s+|\s+$/g, rspaces = /\s+/, ptrim = String.prototype.trim, // Test HTML file name in the data folder testHtml = "selector", // Construct search parameters object urlParams = (function() { var parts, value, params = {}, search = location.search.substring(1).split("&"), i = 0, len = search.length; for ( ; i < len; i++ ) { parts = search[i].split("="); value = parts[1]; // Cast booleans and treat no value as true params[ decodeURIComponent(parts[0]) ] = value && value !== "true" ? value === "false" ? false : decodeURIComponent( value ) : true; } return params; })(), // Whether to allow the use of QSA by the selector engines useQSA = urlParams.qsa || false, // Benchmark options maxTime = 0.5, minSamples = 3, // Keep track of all iframes iframes = {}, // Keeps track of which benches had errors errors = {}, // Selector engines engines = { // "qsa": "d.querySelectorAll( s )", "jquery-1.7.2": "jQuery.find( s, d )", // "jquery-1.8.1": "jQuery.find( s, d )", "oldSizzle": "Sizzle( s, d )", "sizzle": "Sizzle( s, d )", // "dojo": "dojo.query( s, d )", "mootools-slick": "Slick.search( d, s )", "nwmatcher": "NW.Dom.select( s, d )" }, // Keeps track of overall scores scores = (function() { var engine, scores = {}; for ( engine in engines ) { scores[ engine ] = 0; } return scores; })(), // Keeps track of the number of elements returned returned = (function() { var engine, returned = {}; for ( engine in engines ) { returned[ engine ] = {}; } return returned; })(), // Just counts the engines numEngines = (function() { var engine, count = 0; for ( engine in engines ) { count++; } return count; })(), selectorIndex = 0; // Expose iframeCallbacks window.iframeCallbacks = {}; /** * Trim leading and trailing whitespace * * @private * @param {String} str The string to trim */ trim = ptrim ? function( str ) { return ptrim.call( str ); } : function( str ) { return str.replace( rtrim, "" ); }; /** * A shortcut for getElementById * * @private * @param {String} id The ID with which to query the DOM */ function get( id ) { return document.getElementById( id ); } /** * Adds the given class to the element if it does not exist * * @private * @param {Element} elem The element on which to add the class * @param {String} classStr The class to add */ function addClass( elem, classStr ) { classStr = classStr.split( rspaces ); var c, cls = " " + elem.className + " ", i = 0, len = classStr.length; for ( ; i < len; ++i ) { c = classStr[ i ]; if ( c && cls.indexOf(" " + c + " ") < 0 ) { cls += c + " "; } } elem.className = trim( cls ); } /** * Removes a given class on the element * * @private * @param {Element} elem The element from which to remove the class * @param {String} classStr The class to remove */ function removeClass( elem, classStr ) { var cls, len, i; if ( classStr !== undefined ) { classStr = classStr.split( rspaces ); cls = " " + elem.className + " "; i = 0; len = classStr.length; for ( ; i < len; ++i ) { cls = cls.replace(" " + classStr[ i ] + " ", " "); } cls = trim( cls ); } else { // Remove all classes cls = ""; } if ( elem.className !== cls ) { elem.className = cls; } } /** * Runs the console profiler if available * * @param {String} name The name of the profile */ function profile( name ) { if ( window.console && typeof console.profile !== "undefined" && !profiling ) { profiling = true; console.profile( name ); } } /** * Stops console profiling if available * * @param {String} name The name of the profile */ function profileEnd( name ) { if ( profiling ) { profiling = false; console.profileEnd( name ); } } /** * Retrieves the position of the first column * of the row that has just been tested */ function firstTestedColumn() { return selectorIndex * (numEngines + 1) + 1; } /** * Add random number to the url to stop caching * * @private * @param {String} value The url to which to add cache control * @returns {String} Returns the new url * * @example url("data/test.html") * // => "data/test.html?10538358428943" * * @example url("data/test.php?foo=bar") * // => "data/test.php?foo=bar&10538358345554" */ function url( value ) { return value + (/\?/.test( value ) ? "&" : "?") + new Date().getTime() + "" + parseInt( Math.random() * 100000, 10 ); } /** * Gets the Hz, i.e. operations per second, of `bench` adjusted for the * margin of error. * * @private * @param {Object} bench The benchmark object. * @returns {Number} Returns the adjusted Hz. */ function getHz( bench ) { return 1 / ( bench.stats.mean + bench.stats.moe ); } /** * Determines the common number of elements found by the engines. * If there are only 2 engines, this will just return the first one. * * @private * @param {String} selector The selector for which to check returned elements */ function getCommonReturn( selector ) { var engine, count, common, max = 0, counts = {}; for ( engine in returned ) { count = returned[ engine ][ selector ]; if ( count ) { count = count.length; counts[ count ] = (counts[ count ] || 0) + 1; } } for ( count in counts ) { if ( counts[ count ] > max ) { max = counts[ count ]; common = count; } } return +common; } /** * Adds all of the necessary headers and rows * for all selector engines * * @private */ function buildTable() { var engine, i = 0, len = selectors.length, headers = "selectors", emptyColumns = "", rows = ""; // Build out headers for ( engine in engines ) { headers += "" + engine + ""; emptyColumns += " "; } // Build out initial rows for ( ; i < len; i++ ) { rows += "" + selectors[i] + "" + emptyColumns + ""; } rows += "Total (more is better)" + emptyColumns + ""; get("perf-table-headers").innerHTML = headers; get("perf-table-body").innerHTML = rows; } /** * Creates an iframe for use in testing a selector engine * * @private * @param {String} engine Indicates which selector engine to load in the fixture * @param {String} suite Name of the Benchmark Suite to use * @param {Number} callbackIndex Index of the iframe callback for this iframe * @returns {Element} Returns the iframe */ function createIframe( engine, suite, callbackIndex ) { var src = url( "./data/" + testHtml + ".html?engine=" + encodeURIComponent( engine ) + "&suite=" + encodeURIComponent( suite ) + "&callback=" + callbackIndex + "&qsa=" + useQSA ), iframe = document.createElement("iframe"); iframe.setAttribute( "src", src ); iframe.style.cssText = "width: 500px; height: 500px; position: absolute; top: -600px; left: -600px; visibility: hidden;"; document.body.appendChild( iframe ); iframes[ suite ].push( iframe ); return iframe; } /** * Runs a Benchmark suite from within an iframe * then destroys the iframe * Each selector is tested in a fresh iframe * * @private * @param {Object} suite Benchmark Suite to which to add tests * @param {String} selector The selector being tested * @param {String} engine The selector engine begin tested * @param {Function} iframeLoaded Callback to call when the iframe has loaded */ function addTestToSuite( suite, selector, engine, iframeLoaded ) { /** * Run selector tests with a particular engine in an iframe * * @param {Function} r Require in the context of the iframe * @param {Object} document The document of the iframe */ function test( document ) { var win = this, select = new Function( "w", "s", "d", "return " + (engine !== "qsa" ? "w." : "") + engines[ engine ] ); suite.add( engine, function() { returned[ engine ][ selector ] = select( win, selector, document ); }); if ( typeof iframeLoaded !== "undefined" ) { iframeLoaded(); } } // Called by the iframe var index, name = suite.name, callbacks = window.iframeCallbacks[ name ]; index = callbacks.push(function() { var self = this, args = arguments; setTimeout(function() { test.apply( self, args ); }, 0 ); }) - 1; // Load fixture in iframe and add it to the list createIframe( engine, name, index ); } /** * Tests a selector in all selector engines * * @private * @param {String} selector Selector to test */ function testSelector( selector ) { var engine, suite = Benchmark.Suite( selector ), name = suite.name, count = numEngines; /** * Called when an iframe has loaded for a test. * Need to wait until all iframes * have loaded to run the suite */ function loaded() { // Run the suite if ( --count === 0 ) { suite.run(); } } // Add spots for iframe callbacks and iframes window.iframeCallbacks[ name ] = []; iframes[ name ] = []; // Add the tests to the new suite for ( engine in engines ) { addTestToSuite( suite, selector, engine, loaded ); } } /** * Adds the bench to the list of failures to indicate * failure on cycle. Aborts and returns false. * * @param {Object} event Benchmark.Event instance */ function onError() { errors[ this.id ] = true; this.abort(); return false; } /** * Callback for the start of each test * Adds the `pending` class to the selector column */ function onStart() { profile( selectors[selectorIndex] ); var selectorElem = get( "selector" + selectorIndex ); addClass( selectorElem, "pending" ); } /** * Adds the Hz result or "FAILURE" to the corresponding column for the engine */ function onCycle( event ) { var i = firstTestedColumn(), len = i + numEngines, tableBody = get("perf-table-body"), tds = tableBody.getElementsByTagName("td"), bench = event.target, hasError = errors[ bench.id ], textNode = document.createTextNode( hasError ? "FAILED" : Benchmark.formatNumber(getHz( bench ).toFixed( 2 )) + "o/s | " + returned[ bench.name ][ selectors[selectorIndex] ].length + " found" ); // Add the result to the row for ( ; i < len; i++ ) { if ( tds[i].getAttribute("data-engine") === bench.name ) { tds[i].appendChild( textNode ); if ( hasError ) { addClass( tds[i], "black" ); } break; } } } /** * Called after each test * - Removes the `pending` class from the row * - Adds the totals to the `scores` object * - Highlights the corresponding row appropriately * - Removes all iframes and their callbacks from memory * - Calls the next test OR finishes up by: * * adding the `complete` class to body * * adding the totals to the table * * determining the fastest overall and slowest overall */ function onComplete() { profileEnd( selectors[selectorIndex] ); var fastestHz, slowestHz, elem, attr, j, jlen, td, ret, i = firstTestedColumn(), // Determine different elements returned selector = selectors[ selectorIndex ], common = getCommonReturn( selector ), len = i + numEngines, selectorElem = get( "selector" + selectorIndex ), tableBody = get("perf-table-body"), tds = tableBody.getElementsByTagName("td"), fastest = this.filter("fastest"), slowest = this.filter("slowest"); removeClass( selectorElem, "pending" ); // Add up the scores this.forEach(function( bench ) { if ( errors[ bench.id ] ) { // No need to store this error anymore delete errors[ bench.id ]; } else { scores[ bench.name ] += getHz( bench ); } }); // Highlight different returned yellow, fastest green, and slowest red for ( ; i < len; i++ ) { td = tds[i]; attr = td.getAttribute("data-engine"); ret = returned[ attr ][ selector ]; if ( ret && ret.length !== common ) { addClass( td, "yellow" ); continue; } for ( j = 0, jlen = slowest.length; j < jlen; j++ ) { if ( slowest[j].name === attr ) { addClass( td, "red" ); } } for ( j = 0, jlen = fastest.length; j < jlen; j++ ) { if ( fastest[j].name === attr ) { addClass( td, "green" ); } } } // Remove all added iframes for this suite for ( i = 0, len = iframes[ this.name ].length; i < len; i++ ) { document.body.removeChild( iframes[ this.name ].pop() ); } delete iframes[ this.name ]; // Remove all callbacks on the window for this suite window.iframeCallbacks[ this.name ] = null; try { // Errors in IE delete window.iframeCallbacks[ this.name ]; } catch( e ) {} if ( ++selectorIndex < selectors.length ) { testSelector( selectors[selectorIndex] ); } else { addClass( document.body, "complete" ); // Get the fastest and slowest slowest = fastest = undefined; fastestHz = 0; slowestHz = Infinity; for ( i in scores ) { if ( scores[i] > fastestHz ) { fastestHz = scores[i]; fastest = i; } else if ( scores[i] < slowestHz ) { slowestHz = scores[i]; slowest = i; } // Format scores for display scores[i] = Benchmark.formatNumber( scores[i].toFixed(2) ) + "o/s"; } // Add conclusion to the header elem = document.createElement("h3"); elem.innerHTML = "The fastest is " + fastest + " (" + scores[ fastest ] + "). " + "The slowest is " + slowest + " (" + scores[ slowest ] + ")."; get("header").appendChild( elem ); // Add totals to table i = firstTestedColumn(); while ( (elem = tds[ i++ ]) ) { attr = elem.getAttribute("data-engine"); if ( attr === fastest ) { addClass( elem, "green" ); } else if ( attr === slowest ) { addClass( elem, "red" ); } elem.appendChild( document.createTextNode( scores[ attr ] ) ); } } } /* Benchmark Options ---------------------------------------------------------------------- */ Benchmark.options.async = true; Benchmark.options.maxTime = maxTime; Benchmark.options.minSamples = minSamples; Benchmark.options.onError = onError; /* Benchmark Suite Options ---------------------------------------------------------------------- */ Benchmark.Suite.options.onStart = onStart; Benchmark.Suite.options.onCycle = onCycle; Benchmark.Suite.options.onComplete = onComplete; // Kick it off buildTable(); testSelector( selectors[selectorIndex] ); }); sizzle-1.10.17/src/000077500000000000000000000000001226755370700140065ustar00rootroot00000000000000sizzle-1.10.17/src/.jshintrc000066400000000000000000000006021226755370700156310ustar00rootroot00000000000000{ "boss": true, "curly": true, "eqeqeq": true, "eqnull": true, "expr": true, "immed": true, "noarg": true, "onevar": true, "quotmark": "double", "smarttabs": true, "trailing": true, "undef": true, "unused": true, "regexdash": true, "sub": true, "browser": true, "wsh": true, "globals": { "define": true, "module": true, "require": true, "jQuery": true } } sizzle-1.10.17/src/sizzle.js000066400000000000000000001615661226755370700157030ustar00rootroot00000000000000/*! * Sizzle CSS Selector Engine v@VERSION * http://sizzlejs.com/ * * Copyright 2013 jQuery Foundation, Inc. and other contributors * Released under the MIT license * http://jquery.org/license * * Date: @DATE */ (function( window ) { var i, support, Expr, getText, isXML, compile, select, outermostContext, sortInput, hasDuplicate, // 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(), sortOrder = function( a, b ) { if ( a === b ) { hasDuplicate = true; } 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 + "*" ), 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" ) }, rinputs = /^(?:input|select|textarea|button)$/i, rheader = /^h\d$/i, rnative = /^[^{]+\{\s*\[native \w/, // Easily-parseable/retrievable ID or TAG or CLASS selectors rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, rsibling = /[+~]/, 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 : high < 0 ? // BMP codepoint 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 (jQuery #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 ) && testContext( 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]); } } }); }); } /** * Checks a node for validity as a Sizzle context * @param {Element|Object=} context * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value */ function testContext( context ) { return context && typeof context.getElementsByTagName !== strundefined && context; } // Expose support vars for convenience support = Sizzle.support = {}; /** * Detects XML nodes * @param {Element|Object} elem An element or a document * @returns {Boolean} True iff elem is a non-HTML XML node */ 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; }; /** * 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 hasCompare, 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 !== parent.top ) { // IE11 does not have attachEvent, so all must suffer if ( parent.addEventListener ) { parent.addEventListener( "unload", function() { setDocument(); }, false ); } else if ( parent.attachEvent ) { parent.attachEvent( "onunload", 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 = rnative.test( doc.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, Opera 10-12 // Nothing should be selected when empty strings follow ^= or $= or *= if ( div.querySelectorAll("[t^='']").length ) { rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); } // 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: Windows 8 Native Apps // The type and name attributes are restricted during .innerHTML assignment var input = doc.createElement("input"); input.setAttribute( "type", "hidden" ); div.appendChild( input ).setAttribute( "name", "D" ); // Support: IE8 // Enforce case-sensitivity of name attribute if ( div.querySelectorAll("[name=d]").length ) { rbuggyQSA.push( "name" + 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 ---------------------------------------------------------------------- */ hasCompare = rnative.test( docElem.compareDocumentPosition ); // Element contains another // Purposefully does not implement inclusive descendent // As in, an element does not contain itself contains = hasCompare || rnative.test( docElem.contains ) ? 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 = hasCompare ? function( a, b ) { // Flag for duplicate removal if ( a === b ) { hasDuplicate = true; return 0; } // Sort on method existence if only one input has compareDocumentPosition var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; if ( compare ) { return compare; } // Calculate position if both inputs belong to the same document compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ? a.compareDocumentPosition( b ) : // Otherwise we know they are disconnected 1; // 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 || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { return -1; } if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { return 1; } // Maintain original order return sortInput ? ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : 0; } return compare & 4 ? -1 : 1; } : function( a, b ) { // Exit early if the nodes are identical if ( a === b ) { hasDuplicate = true; return 0; } var cur, i = 0, aup = a.parentNode, bup = b.parentNode, ap = [ a ], bp = [ b ]; // Parentless nodes are either documents or disconnected 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 ? val : support.attributes || !documentIsHTML ? elem.getAttribute( name ) : (val = elem.getAttributeNode(name)) && val.specified ? val.value : null; }; 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 ); } } // Clear input after sorting to release objects // See https://github.com/jquery/sizzle/pull/225 sortInput = null; 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 while ( (node = elem[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 (jQuery #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 negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), // but not by others (comment: 8; processing instruction: 7; etc.) // nodeType < 6 works because attributes (2) do not appear as children for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { if ( elem.nodeType < 6 ) { 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; return elem.nodeName.toLowerCase() === "input" && elem.type === "text" && // Support: IE<8 // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" ); }, // 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 oldCache, outerCache, newCache = [ 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 ( (oldCache = outerCache[ dir ]) && oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { // Assign to newCache so results back-propagate to previous elements return (newCache[ 2 ] = oldCache[ 2 ]); } else { // Reuse newcache so results back-propagate to previous elements outerCache[ dir ] = newCache; // A match means we're done; a fail means we have to keep checking if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { 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 multipleContexts( selector, contexts, results ) { var i = 0, len = contexts.length; for ( ; i < len; i++ ) { Sizzle( selector, contexts[i], results ); } return results; } 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 ) { var bySet = setMatchers.length > 0, byElement = elementMatchers.length > 0, superMatcher = function( seed, context, xml, results, outermost ) { var elem, j, matcher, matchedCount = 0, i = "0", unmatched = seed && [], setMatched = [], contextBackup = outermostContext, // We must always have either seed elements or outermost context elems = seed || byElement && Expr.find["TAG"]( "*", outermost ), // Use integer dirruns iff this is the outermost matcher dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), len = elems.length; if ( outermost ) { outermostContext = context !== document && context; } // Add elements passing elementMatchers directly to results // Keep `i` a string if there are no elements so `matchedCount` will be "00" below // Support: IE<9, Safari // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id for ( ; i !== len && (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; } } // 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, match /* 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 ( !match ) { match = tokenize( selector ); } i = match.length; while ( i-- ) { cached = matcherFromTokens( match[i] ); if ( cached[ expando ] ) { setMatchers.push( cached ); } else { elementMatchers.push( cached ); } } // Cache the compiled function cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); // Save selector and tokenization cached.selector = selector; cached.match = match; } return cached; }; /** * A low-level selection function that works with Sizzle's compiled * selector functions * @param {String|Function} selector A selector or a pre-compiled * selector function built with Sizzle.compile * @param {Element} context * @param {Array} [results] * @param {Array} [seed] A set of elements to match against */ select = Sizzle.select = function( selector, context, results, seed ) { var i, tokens, token, type, find, match, compiled; results = results || []; if ( typeof selector === "function" ) { compiled = selector; match = compiled.match; selector = compiled.selector; } else { 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 ( !compiled && 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 ) && testContext( 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 if one is not provided // Provide `match` to avoid retokenization if we modified the selector above ( compiled || compile( selector, match ) )( seed, context, !documentIsHTML, results, rsibling.test( selector ) && testContext( context.parentNode ) || context ); 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 elem[ name ] === true ? name.toLowerCase() : (val = elem.getAttributeNode( name )) && val.specified ? val.value : null; } }); } // EXPOSE if ( typeof define === "function" && define.amd ) { define(function() { return Sizzle; }); // Sizzle requires that there be a global window in Common-JS like environments } else if ( typeof module !== "undefined" && module.exports ) { module.exports = Sizzle; } else { window.Sizzle = Sizzle; } // EXPOSE })( window ); sizzle-1.10.17/tasks/000077500000000000000000000000001226755370700143445ustar00rootroot00000000000000sizzle-1.10.17/tasks/commit.js000066400000000000000000000004331226755370700161720ustar00rootroot00000000000000"use strict"; var exec = require( "child_process" ).exec; module.exports = function( grunt ) { grunt.registerTask( "commit", "Add and commit changes", function( message ) { // Always add dist directory exec( "git add dist && git commit -m " + message, this.async() ); }); }; sizzle-1.10.17/tasks/compile.js000066400000000000000000000014221226755370700163310ustar00rootroot00000000000000"use strict"; module.exports = function( grunt ) { grunt.registerMultiTask( "compile", "Compile sizzle.js to the dist directory. Embed date/version.", function() { var data = this.data, dest = data.dest, src = data.src, version = grunt.config( "pkg.version" ), compiled = grunt.file.read( src ); // Embed version and date compiled = compiled .replace( /@VERSION/g, version ) .replace( "@DATE", function() { var date = new Date(); // YYYY-MM-DD return [ date.getFullYear(), ( "0" + ( date.getMonth() + 1 ) ).slice( -2 ), ( "0" + date.getDate() ).slice( -2 ) ].join( "-" ); }); // Write source to file grunt.file.write( dest, compiled ); grunt.log.ok( "File written to " + dest ); } ); }; sizzle-1.10.17/tasks/dist.js000066400000000000000000000021361226755370700156470ustar00rootroot00000000000000"use strict"; var fs = require( "fs" ); module.exports = function( grunt ) { grunt.registerTask( "dist", "Process files for distribution", function() { var files = grunt.file.expand( { filter: "isFile" }, "dist/*" ); files.forEach(function( filename ) { var map, text = fs.readFileSync( filename, "utf8" ); // Modify map/min so that it points to files in the same folder; // see https://github.com/mishoo/UglifyJS2/issues/47 if ( /\.map$/.test( filename ) ) { text = text.replace( /"dist\//g, "\"" ); fs.writeFileSync( filename, text, "utf-8" ); } else if ( /\.min\.js$/.test( filename ) ) { // Wrap sourceMap directive in multiline comments (#13274) text = text.replace( /\n?(\/\/@\s*sourceMappingURL=)(.*)/, function( _, directive, path ) { map = "\n" + directive + path.replace( /^dist\//, "" ); return ""; }); if ( map ) { text = text.replace( /(^\/\*[\w\W]*?)\s*\*\/|$/, function( _, comment ) { return ( comment || "\n/*" ) + map + "\n*/"; }); } fs.writeFileSync( filename, text, "utf-8" ); } }); }); }; sizzle-1.10.17/tasks/release.js000066400000000000000000000021741226755370700163260ustar00rootroot00000000000000"use strict"; var exec = require( "child_process" ).exec; module.exports = function( grunt ) { var rpreversion = /(\d\.\d+\.\d+)-pre/; grunt.registerTask( "release", "Release a version of sizzle, updates a pre version to released, " + "inserts `next` as the new pre version", function( next ) { if ( !rpreversion.test( next ) ) { grunt.fatal( "Next version should be a -pre version (x.x.x-pre): " + next ); return; } var done, version = grunt.config( "pkg.version" ); if ( !rpreversion.test( version ) ) { grunt.fatal( "Existing version is not a pre version: " + version ); return; } version = version.replace( rpreversion, "$1" ); done = this.async(); exec( "git diff --quiet HEAD", function( err ) { if ( err ) { grunt.fatal( "The working directory should be clean when releasing. Commit or stash changes." ); return; } // Build to dist directories along with a map and tag the release grunt.task.run([ // Commit new version "version:" + version, // Tag new version "tag:" + version, // Commit next version "version:" + next ]); done(); }); }); }; sizzle-1.10.17/tasks/tag.js000066400000000000000000000003461226755370700154600ustar00rootroot00000000000000"use strict"; var exec = require( "child_process" ).exec; module.exports = function( grunt ) { grunt.registerTask( "tag", "Tag the specified version", function( version ) { exec( "git tag " + version, this.async() ); }); }; sizzle-1.10.17/tasks/version.js000066400000000000000000000017071226755370700163740ustar00rootroot00000000000000"use strict"; var exec = require( "child_process" ).exec; module.exports = function( grunt ) { grunt.registerTask( "version", "Commit a new version", function( version ) { if ( !/\d\.\d+\.\d+(?:-pre)?/.test( version ) ) { grunt.fatal( "Version must follow semver release format: " + version ); return; } var done = this.async(), files = grunt.config( "version.files" ), rversion = /("version":\s*")[^"]+/; // Update version in specified files files.forEach(function( filename ) { var text = grunt.file.read( filename ); text = text.replace( rversion, "$1" + version ); grunt.file.write( filename, text ); }); // Add files to git index exec( "git add -A", function( err ) { if ( err ) { grunt.fatal( err ); return; } // Commit next pre version grunt.config( "pkg.version", version ); grunt.task.run([ "build", "uglify", "dist", "commit:'Update version to " + version + "'" ]); done(); }); }); }; sizzle-1.10.17/test/000077500000000000000000000000001226755370700141765ustar00rootroot00000000000000sizzle-1.10.17/test/.jshintrc000066400000000000000000000014331226755370700160240ustar00rootroot00000000000000{ "boss": true, "curly": true, "eqeqeq": true, "eqnull": true, "expr": true, "immed": true, "noarg": true, "onevar": true, "quotmark": "double", "smarttabs": true, "trailing": true, "undef": true, "unused": true, "sub": true, "browser": true, "wsh": true, "globals": { "QUnit": false, "module": false, "test": false, "asyncTest": false, "expect": false, "stop": false, "start": false, "ok": false, "equal": false, "notEqual": false, "deepEqual": false, "notDeepEqual": false, "strictEqual": false, "notStrictEqual": false, "raises": false, "createWithFriesXML": false, "fireNative": false, "moduleTeardown": false, "q": false, "t": false, "testIframeWithCallback": false, "url": false, "jQuery": false, "Sizzle": false } } sizzle-1.10.17/test/data/000077500000000000000000000000001226755370700151075ustar00rootroot00000000000000sizzle-1.10.17/test/data/empty.js000066400000000000000000000000001226755370700165710ustar00rootroot00000000000000sizzle-1.10.17/test/data/mixed_sort.html000066400000000000000000000011301226755370700201450ustar00rootroot00000000000000 sizzle-1.10.17/test/data/testinit.js000066400000000000000000000073721226755370700173210ustar00rootroot00000000000000var fireNative, jQuery = this.jQuery || "jQuery", // For testing .noConflict() $ = this.$ || "$", originaljQuery = jQuery, original$ = $; (function() { // Config parameter to force basic code paths QUnit.config.urlConfig.push({ id: "basic", label: "Bypass optimizations", tooltip: "Force use of the most basic code by disabling native querySelectorAll; contains; compareDocumentPosition" }); if ( QUnit.urlParams.basic ) { document.querySelectorAll = null; document.documentElement.contains = null; document.documentElement.compareDocumentPosition = null; // Return array of length two to pass assertion // But support should be false as its not native document.getElementsByClassName = function() { return [ 0, 1 ]; }; } })(); /** * Returns an array of elements with the given IDs * @example q("main", "foo", "bar") * @result [
, , ] */ function q() { var r = [], i = 0; for ( ; i < arguments.length; i++ ) { r.push( document.getElementById( arguments[i] ) ); } return r; } /** * Asserts that a select matches the given IDs * @param {String} a - Assertion name * @param {String} b - Sizzle selector * @param {String} c - Array of ids to construct what is expected * @example t("Check for something", "//[a]", ["foo", "baar"]); * @result returns true if "//[a]" return two elements with the IDs 'foo' and 'baar' */ function t( a, b, c ) { var f = Sizzle(b), s = "", i = 0; for ( ; i < f.length; i++ ) { s += ( s && "," ) + '"' + f[ i ].id + '"'; } deepEqual(f, q.apply( q, c ), a + " (" + b + ")"); } /** * Add random number to url to stop caching * * @example url("data/test.html") * @result "data/test.html?10538358428943" * * @example url("data/test.php?foo=bar") * @result "data/test.php?foo=bar&10538358345554" */ function url( value ) { return value + (/\?/.test(value) ? "&" : "?") + new Date().getTime() + "" + parseInt(Math.random()*100000); } var createWithFriesXML = function() { var string = ' \ \ \ \ \ \ \ \ \ \ 1 \ \ \ \ \ foo \ \ \ \ \ \ \ '; return jQuery.parseXML( string ); }; fireNative = document.createEvent ? function( node, type ) { var event = document.createEvent("HTMLEvents"); event.initEvent( type, true, true ); node.dispatchEvent( event ); } : function( node, type ) { var event = document.createEventObject(); node.fireEvent( "on" + type, event ); }; function testIframeWithCallback( title, fileName, func ) { test( title, function() { var iframe; stop(); window.iframeCallback = function() { var self = this, args = arguments; setTimeout(function() { window.iframeCallback = undefined; iframe.remove(); func.apply( self, args ); func = function() {}; start(); }, 0 ); }; iframe = jQuery( "
" ).css({ position: "absolute", width: "500px", left: "-600px" }) .append( jQuery( "
hi there
C
  1. Rice
  2. Beans
  3. Blinis
  4. Tofu
I'm hungry. I should...
...Eat lots of food... | ...Eat a little food... | ...Eat no food... ...Eat a burger... ...Eat some funyuns... ...Eat some funyuns...
1 2

sizzle-1.10.17/test/jquery.js000066400000000000000000010141341226755370700160570ustar00rootroot00000000000000/*! * jQuery JavaScript Library v1.9.1 * http://jquery.com/ * * Includes Sizzle.js * http://sizzlejs.com/ * * Copyright 2005, 2012 jQuery Foundation, Inc. and other contributors * Released under the MIT license * http://jquery.org/license * * Date: 2013-2-4 */ (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<9 // For `typeof node.method` instead of `node.method !== undefined` core_strundefined = typeof undefined, // Use the correct document accordingly with window argument (sandbox) document = window.document, location = window.location, // 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.9.1", // 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 = /^(?:(<[\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, // The number of elements contained in the matched element set size: function() { return this.length; }, 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({ 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 ) { 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 ) { // 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; } // Own properties are enumerated firstly, so to speed up, // if last one is own, then all properties are own. var key; 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(); } }); 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); // 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 = []; 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 ) { args = args || []; args = [ context, args.slice ? args.slice() : args ]; if ( list && ( !fired || stack ) ) { 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() { var support, all, a, input, select, fragment, opt, eventName, isSupported, i, div = document.createElement("div"); // Setup div.setAttribute( "className", "t" ); div.innerHTML = "
a"; // Support tests won't run in some limited or non-browser environments all = div.getElementsByTagName("*"); a = div.getElementsByTagName("a")[ 0 ]; if ( !all || !a || !all.length ) { return {}; } // 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"; support = { // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7) getSetAttribute: div.className !== "t", // IE strips leading whitespace when .innerHTML is used leadingWhitespace: div.firstChild.nodeType === 3, // Make sure that tbody elements aren't automatically inserted // IE will insert them into empty tables tbody: !div.getElementsByTagName("tbody").length, // Make sure that link elements get serialized correctly by innerHTML // This requires a wrapper element in IE htmlSerialize: !!div.getElementsByTagName("link").length, // Get the style information from getAttribute // (IE uses .cssText instead) style: /top/.test( a.getAttribute("style") ), // Make sure that URLs aren't manipulated // (IE normalizes it by default) 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 opacity: /^0.5/.test( a.style.opacity ), // Verify style float existence // (IE uses styleFloat instead of cssFloat) cssFloat: !!a.style.cssFloat, // Check the default checkbox/radio value ("" on WebKit; "on" elsewhere) 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) optSelected: opt.selected, // Tests for enctype support on a form (#6743) enctype: !!document.createElement("form").enctype, // Makes sure cloning an html5 element does not cause problems // Where outerHTML is undefined, this still works html5Clone: document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav>", // jQuery.support.boxModel DEPRECATED in 1.8 since we don't support Quirks Mode boxModel: document.compatMode === "CSS1Compat", // Will be defined later deleteExpando: true, noCloneEvent: true, inlineBlockNeedsLayout: false, shrinkWrapBlocks: false, reliableMarginRight: true, boxSizingReliable: true, pixelPosition: false }; // 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), test/csp.php 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"; // 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%;"; support.boxSizing = ( div.offsetWidth === 4 ); support.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== 1 ); // 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 thisCache, ret, internalKey = jQuery.expando, getByName = typeof name === "string", // 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)) && getByName && data === undefined ) { 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 ) { elem[ internalKey ] = id = core_deletedIds.pop() || jQuery.guid++; } else { id = internalKey; } } if ( !cache[ id ] ) { cache[ id ] = {}; // Avoids exposing jQuery metadata on plain JS objects when the object // is serialized using JSON.stringify if ( !isNode ) { cache[ id ].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 ( getByName ) { // 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 i, l, thisCache, 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 ) ); } for ( i = 0, l = name.length; i < l; 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 : 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) } else if ( jQuery.support.deleteExpando || cache != cache.window ) { delete cache[ id ]; // When all else fails, null } else { cache[ id ] = null; } } jQuery.extend({ cache: {}, // Unique for each copy of jQuery on the page // Non-digits removed to match rinlinejQuery expando: "jQuery" + ( core_version + Math.random() ).replace( /\D/g, "" ), // The following elements throw uncatchable exceptions if you // attempt to add expando properties to them. noData: { "embed": true, // Ban all objects except for Flash (which handle expandos) "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000", "applet": true }, 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, elem = this[0], i = 0, data = null; // 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-" ) ) { 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 jQuery.access( this, function( value ) { if ( value === undefined ) { // Try to fetch any internally stored data first return elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : null; } this.each(function() { jQuery.data( this, key, value ); }); }, null, value, arguments.length > 1, null, true ); }, 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--; } hooks.cur = fn; 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]/g, rreturn = /\r/g, rfocusable = /^(?:input|select|textarea|button|object)$/i, rclickable = /^(?:a|area)$/i, rboolean = /^(?:checked|selected|autofocus|autoplay|async|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped)$/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, isBool = typeof stateVal === "boolean"; 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 ), state = stateVal, classNames = value.match( core_rnotwhite ) || []; while ( (className = classNames[ i++ ]) ) { // check each className given, space separated list state = isBool ? state : !self.hasClass( className ); self[ state ? "addClass" : "removeClass" ]( 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, self = jQuery(this); if ( this.nodeType !== 1 ) { return; } if ( isFunction ) { val = value.call( this, i, self.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 ) { // attributes.value is undefined in Blackberry 4.7 but // uses .value. See #6932 var val = elem.attributes.value; return !val || val.specified ? elem.value : 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 values = jQuery.makeArray( value ); jQuery(elem).find("option").each(function() { this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0; }); if ( !values.length ) { elem.selectedIndex = -1; } return values; } } }, attr: function( elem, name, value ) { var hooks, notxml, 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 ); } notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); // All attributes are lowercase // Grab necessary hook if one is defined if ( notxml ) { name = name.toLowerCase(); hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook ); } if ( value !== undefined ) { if ( value === null ) { jQuery.removeAttr( elem, name ); } else if ( hooks && notxml && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { return ret; } else { elem.setAttribute( name, value + "" ); return value; } } else if ( hooks && notxml && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { return ret; } else { // In IE9+, Flash objects don't have .getAttribute (#12945) // Support: IE9+ if ( typeof elem.getAttribute !== core_strundefined ) { ret = elem.getAttribute( 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 ( rboolean.test( name ) ) { // Set corresponding property to false for boolean attributes // Also clear defaultChecked/defaultSelected (if appropriate) for IE<8 if ( !getSetAttribute && ruseDefault.test( name ) ) { elem[ jQuery.camelCase( "default-" + name ) ] = elem[ propName ] = false; } else { 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: { tabindex: "tabIndex", readonly: "readOnly", "for": "htmlFor", "class": "className", maxlength: "maxLength", cellspacing: "cellSpacing", cellpadding: "cellPadding", rowspan: "rowSpan", colspan: "colSpan", usemap: "useMap", frameborder: "frameBorder", contenteditable: "contentEditable" }, 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 ) { if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { return ret; } else { return ( elem[ name ] = value ); } } else { if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { return ret; } else { return 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/ var attributeNode = elem.getAttributeNode("tabindex"); return attributeNode && attributeNode.specified ? parseInt( attributeNode.value, 10 ) : rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? 0 : undefined; } } } }); // Hook for boolean attributes boolHook = { get: function( elem, name ) { var // Use .prop to determine if this attribute is understood as boolean prop = jQuery.prop( elem, name ), // Fetch it accordingly attr = typeof prop === "boolean" && elem.getAttribute( name ), detail = typeof prop === "boolean" ? getSetInput && getSetAttribute ? attr != null : // oldIE fabricates an empty string for missing boolean attributes // and conflates checked/selected into attroperties ruseDefault.test( name ) ? elem[ jQuery.camelCase( "default-" + name ) ] : !!attr : // fetch an attribute node for properties not recognized as boolean elem.getAttributeNode( name ); return detail && detail.value !== false ? name.toLowerCase() : undefined; }, 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; } }; // fix oldIE value attroperty if ( !getSetInput || !getSetAttribute ) { jQuery.attrHooks.value = { get: function( elem, name ) { var ret = elem.getAttributeNode( name ); return jQuery.nodeName( elem, "input" ) ? // Ignore the value *property* by using defaultValue elem.defaultValue : ret && ret.specified ? ret.value : undefined; }, 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 = jQuery.valHooks.button = { get: function( elem, name ) { var ret = elem.getAttributeNode( name ); return ret && ( name === "id" || name === "name" || name === "coords" ? ret.value !== "" : ret.specified ) ? ret.value : undefined; }, 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; } }; // Set contenteditable to false on removals(#10429) // Setting to empty string throws an error as an invalid value jQuery.attrHooks.contenteditable = { get: nodeHook.get, 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 ] = jQuery.extend( 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 ) { jQuery.each([ "href", "src", "width", "height" ], function( i, name ) { jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { get: function( elem ) { var ret = elem.getAttribute( name, 2 ); return ret == null ? undefined : ret; } }); }); // 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 = jQuery.extend( 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; } }); } // IE6/7 call enctype encoding if ( !jQuery.support.enctype ) { jQuery.propFix.enctype = "encoding"; } // Radios and checkboxes getter/setter if ( !jQuery.support.checkOn ) { jQuery.each([ "radio", "checkbox" ], function() { jQuery.valHooks[ this ] = { get: function( elem ) { // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified return elem.getAttribute("value") === null ? "on" : elem.value; } }; }); } jQuery.each([ "radio", "checkbox" ], function() { jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], { set: function( elem, value ) { if ( jQuery.isArray( value ) ) { return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 ); } } }); }); var rformElems = /^(?:input|select|textarea)$/i, rkeyEvent = /^key/, rmouseEvent = /^(?:mouse|contextmenu)|click/, rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, rtypenamespace = /^([^.]*)(?:\.(.+)|)$/; function returnTrue() { return true; } function returnFalse() { return false; } /* * 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 // jQuery(...).bind("mouseover mouseout", fn); types = ( types || "" ).match( core_rnotwhite ) || [""]; t = types.length; while ( t-- ) { tmp = rtypenamespace.exec( types[t] ) || []; type = origType = tmp[1]; namespaces = ( tmp[2] || "" ).split( "." ).sort(); // 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 ); event.isTrigger = true; 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( elem.ownerDocument, data ) === false) && !(type === "click" && jQuery.nodeName( elem, "a" )) && 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") ) { for ( ; cur != this; cur = cur.parentNode || this ) { // 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 }, 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; } } }, focus: { // Fire native event if possible so blur/focus sequence is correct trigger: function() { if ( this !== document.activeElement && 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 === document.activeElement && this.blur ) { this.blur(); return false; } }, delegateType: "focusout" }, 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 ); }); }, bind: function( types, data, fn ) { return this.on( types, null, data, fn ); }, unbind: function( types, fn ) { return this.off( types, null, fn ); }, delegate: function( selector, types, data, fn ) { return this.on( types, selector, data, fn ); }, undelegate: function( selector, types, fn ) { // ( namespace ) or ( selector, types [, fn] ) return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn ); }, 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 ); } } }); /*! * Sizzle CSS Selector Engine * Copyright 2012 jQuery Foundation and other contributors * Released under the MIT license * http://sizzlejs.com/ */ (function( window, undefined ) { var i, cachedruns, Expr, getText, isXML, compile, hasDuplicate, outermostContext, // Local document vars setDocument, document, docElem, documentIsXML, rbuggyQSA, rbuggyMatches, matches, contains, sortOrder, // Instance-specific data expando = "sizzle" + -(new Date()), preferredDoc = window.document, support = {}, dirruns = 0, done = 0, classCache = createCache(), tokenCache = createCache(), compilerCache = createCache(), // General-purpose constants strundefined = typeof undefined, MAX_NEGATIVE = 1 << 31, // Array methods arr = [], pop = arr.pop, 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; }, // 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 operators = "([*^$|!~]?=)", attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace + "*(?:" + operators + 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 + "*([\\x20\\t\\r\\n\\f>+~])" + whitespace + "*" ), rpseudo = new RegExp( pseudos ), ridentifier = new RegExp( "^" + identifier + "$" ), matchExpr = { "ID": new RegExp( "^#(" + characterEncoding + ")" ), "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ), "NAME": new RegExp( "^\\[name=['\"]?(" + 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" ), // 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" ) }, rsibling = /[\x20\t\r\n\f]*[+~]/, rnative = /^[^{]+\{\s*\[native code/, // 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, rattributeQuotes = /\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g, // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters runescape = /\\([\da-fA-F]{1,6}[\x20\t\r\n\f]?|.)/g, funescape = function( _, escaped ) { var high = "0x" + escaped - 0x10000; // NaN means non-codepoint return high !== high ? escaped : // BMP codepoint high < 0 ? String.fromCharCode( high + 0x10000 ) : // Supplemental Plane codepoint (surrogate pair) String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); }; // Use a stripped-down slice if we can't use a native one try { slice.call( preferredDoc.documentElement.childNodes, 0 )[0].nodeType; } catch ( e ) { slice = function( i ) { var elem, results = []; while ( (elem = this[i++]) ) { results.push( elem ); } return results; }; } /** * For feature detection * @param {Function} fn The function to test for native support */ function isNative( fn ) { return rnative.test( fn + "" ); } /** * 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 cache, keys = []; return (cache = function( 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); }); } /** * 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 { // release memory in IE div = null; } } 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 ( !documentIsXML && !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, slice.call(context.getElementsByTagName( selector ), 0) ); return results; // Speed-up: Sizzle(".CLASS") } else if ( (m = match[3]) && support.getByClassName && context.getElementsByClassName ) { push.apply( results, slice.call(context.getElementsByClassName( m ), 0) ); return results; } } // QSA path if ( support.qsa && !rbuggyQSA.test(selector) ) { old = true; nid = 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, slice.call( newContext.querySelectorAll( newSelector ), 0 ) ); return results; } catch(qsaError) { } finally { if ( !old ) { context.removeAttribute("id"); } } } } } // All others return select( selector.replace( rtrim, "$1" ), context, results, seed ); } /** * 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; }; /** * 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; // 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 documentIsXML = isXML( doc ); // Check if getElementsByTagName("*") returns only elements support.tagNameNoComments = assert(function( div ) { div.appendChild( doc.createComment("") ); return !div.getElementsByTagName("*").length; }); // Check if attributes should be retrieved by attribute nodes support.attributes = assert(function( div ) { div.innerHTML = ""; var type = typeof div.lastChild.getAttribute("multiple"); // IE8 returns a string for some attributes even when not present return type !== "boolean" && type !== "string"; }); // Check if getElementsByClassName can be trusted support.getByClassName = assert(function( div ) { // Opera can't find a second classname (in 9.6) div.innerHTML = ""; if ( !div.getElementsByClassName || !div.getElementsByClassName("e").length ) { return false; } // Safari 3.2 caches class attributes and doesn't catch changes div.lastChild.className = "e"; return div.getElementsByClassName("e").length === 2; }); // Check if getElementById returns elements by name // Check if getElementsByName privileges form controls or returns elements by ID support.getByName = assert(function( div ) { // Inject content div.id = expando + 0; div.innerHTML = "
"; docElem.insertBefore( div, docElem.firstChild ); // Test var pass = doc.getElementsByName && // buggy browsers will return fewer than the correct 2 doc.getElementsByName( expando ).length === 2 + // buggy browsers will return more than the correct 0 doc.getElementsByName( expando + 0 ).length; support.getIdNotName = !doc.getElementById( expando ); // Cleanup docElem.removeChild( div ); return pass; }); // IE6/7 return modified attributes Expr.attrHandle = assert(function( div ) { div.innerHTML = ""; return div.firstChild && typeof div.firstChild.getAttribute !== strundefined && div.firstChild.getAttribute("href") === "#"; }) ? {} : { "href": function( elem ) { return elem.getAttribute( "href", 2 ); }, "type": function( elem ) { return elem.getAttribute("type"); } }; // ID find and filter if ( support.getIdNotName ) { Expr.find["ID"] = function( id, context ) { if ( typeof context.getElementById !== strundefined && !documentIsXML ) { 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 { Expr.find["ID"] = function( id, context ) { if ( typeof context.getElementById !== strundefined && !documentIsXML ) { var m = context.getElementById( id ); return m ? m.id === id || typeof m.getAttributeNode !== strundefined && m.getAttributeNode("id").value === id ? [m] : undefined : []; } }; 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.tagNameNoComments ? 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; }; // Name Expr.find["NAME"] = support.getByName && function( tag, context ) { if ( typeof context.getElementsByName !== strundefined ) { return context.getElementsByName( name ); } }; // Class Expr.find["CLASS"] = support.getByClassName && function( className, context ) { if ( typeof context.getElementsByClassName !== strundefined && !documentIsXML ) { return context.getElementsByClassName( className ); } }; // QSA and matchesSelector support // matchesSelector(:active) reports false when true (IE9/Opera 11.5) rbuggyMatches = []; // qSa(:focus) reports false when true (Chrome 21), // no need to also add to buggyMatches since matches checks buggyQSA // A support test would require too much code (would include document ready) rbuggyQSA = [ ":focus" ]; if ( (support.qsa = isNative(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 explictly // setting a boolean content attribute, // since its presence should be enough // http://bugs.jquery.com/ticket/12359 div.innerHTML = ""; // IE8 - Some boolean attributes are not treated correctly if ( !div.querySelectorAll("[selected]").length ) { rbuggyQSA.push( "\\[" + whitespace + "*(?:checked|disabled|ismap|multiple|readonly|selected|value)" ); } // 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 ) { // Opera 10-12/IE8 - ^= $= *= and empty values // Should not select anything div.innerHTML = ""; if ( div.querySelectorAll("[i^='']").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 = isNative( (matches = docElem.matchesSelector || docElem.mozMatchesSelector || docElem.webkitMatchesSelector || 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 = new RegExp( rbuggyQSA.join("|") ); rbuggyMatches = new RegExp( rbuggyMatches.join("|") ); // Element contains another // Purposefully does not implement inclusive descendent // As in, an element does not contain itself contains = isNative(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; }; // Document order sorting sortOrder = docElem.compareDocumentPosition ? function( a, b ) { var compare; if ( a === b ) { hasDuplicate = true; return 0; } if ( (compare = b.compareDocumentPosition && a.compareDocumentPosition && a.compareDocumentPosition( b )) ) { if ( compare & 1 || a.parentNode && a.parentNode.nodeType === 11 ) { if ( a === doc || contains( preferredDoc, a ) ) { return -1; } if ( b === doc || contains( preferredDoc, b ) ) { return 1; } return 0; } return compare & 4 ? -1 : 1; } 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 : 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; }; // Always assume the presence of duplicates if sort doesn't // pass them to our comparison function (as in Google Chrome). hasDuplicate = false; [0, 0].sort( sortOrder ); support.detectDuplicates = hasDuplicate; return document; }; 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']" ); // rbuggyQSA always contains :focus, so no need for an existence check if ( support.matchesSelector && !documentIsXML && (!rbuggyMatches || !rbuggyMatches.test(expr)) && !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 ) { var val; // Set document vars if needed if ( ( elem.ownerDocument || elem ) !== document ) { setDocument( elem ); } if ( !documentIsXML ) { name = name.toLowerCase(); } if ( (val = Expr.attrHandle[ name ]) ) { return val( elem ); } if ( documentIsXML || support.attributes ) { return elem.getAttribute( name ); } return ( (val = elem.getAttributeNode( name )) || elem.getAttribute( name ) ) && elem[ name ] === true ? name : val && val.specified ? val.value : null; }; Sizzle.error = function( msg ) { throw new Error( "Syntax error, unrecognized expression: " + msg ); }; // Document sorting and removing duplicates Sizzle.uniqueSort = function( results ) { var elem, duplicates = [], i = 1, j = 0; // Unless we *know* we can detect duplicates, assume their presence hasDuplicate = !support.detectDuplicates; results.sort( sortOrder ); if ( hasDuplicate ) { for ( ; (elem = results[i]); i++ ) { if ( elem === results[ i - 1 ] ) { j = duplicates.push( i ); } } while ( j-- ) { results.splice( duplicates[ j ], 1 ); } } return results; }; function siblingCheck( a, b ) { var cur = b && a, diff = cur && ( ~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 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 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 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]); } } }); }); } /** * 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, 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[4] ) { 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( nodeName ) { if ( nodeName === "*" ) { return function() { return true; }; } nodeName = nodeName.replace( runescape, funescape ).toLowerCase(); return 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( 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 identifider if ( !ridentifier.test(lang || "") ) { Sizzle.error( "unsupported lang: " + lang ); } lang = lang.replace( runescape, funescape ).toLowerCase(); return function( elem ) { var elemLang; do { if ( (elemLang = documentIsXML ? elem.getAttribute("xml:lang") || elem.getAttribute("lang") : elem.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; }) } }; // 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 ); } 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( tokens.slice( 0, i - 1 ) ).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" && context.nodeType === 9 && !documentIsXML && 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, slice.call( seed, 0 ) ); 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, documentIsXML, results, rsibling.test( selector ) ); return results; } // Deprecated Expr.pseudos["nth"] = Expr.pseudos["eq"]; // Easy API for creating new setFilters function setFilters() {} Expr.filters = setFilters.prototype = Expr.pseudos; Expr.setFilters = new setFilters(); // Initialize with the default document setDocument(); // Override sizzle attribute retrieval Sizzle.attr = jQuery.attr; 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 ); var runtil = /Until$/, rparentsprev = /^(?:parents|prev(?:Until|All))/, isSimple = /^.[^:#\[\.,]*$/, 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, len = this.length; if ( typeof selector !== "string" ) { self = this; return this.pushStack( jQuery( selector ).filter(function() { for ( i = 0; i < len; i++ ) { if ( jQuery.contains( self[ i ], this ) ) { return true; } } }) ); } ret = []; for ( i = 0; i < len; i++ ) { jQuery.find( selector, this[ 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; 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, false) ); }, filter: function( selector ) { return this.pushStack( winnow(this, selector, true) ); }, is: function( selector ) { return !!selector && ( typeof selector === "string" ? // 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". rneedsContext.test( selector ) ? jQuery( selector, this.context ).index( this[0] ) >= 0 : jQuery.filter( selector, this ).length > 0 : this.filter( selector ).length > 0 ); }, 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++ ) { cur = this[i]; while ( cur && cur.ownerDocument && cur !== context && cur.nodeType !== 11 ) { if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) { ret.push( cur ); break; } cur = cur.parentNode; } } 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) ); } }); jQuery.fn.andSelf = jQuery.fn.addBack; 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 ( !runtil.test( name ) ) { selector = until; } if ( selector && typeof selector === "string" ) { ret = jQuery.filter( selector, ret ); } ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret; if ( this.length > 1 && rparentsprev.test( name ) ) { ret = ret.reverse(); } return this.pushStack( ret ); }; }); jQuery.extend({ filter: function( expr, elems, not ) { if ( not ) { expr = ":not(" + expr + ")"; } return elems.length === 1 ? jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] : jQuery.find.matches(expr, elems); }, 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, keep ) { // Can't pass null or undefined to indexOf in Firefox 4 // Set to 0 to skip string check qualifier = qualifier || 0; if ( jQuery.isFunction( qualifier ) ) { return jQuery.grep(elements, function( elem, i ) { var retVal = !!qualifier.call( elem, i, elem ); return retVal === keep; }); } else if ( qualifier.nodeType ) { return jQuery.grep(elements, function( elem ) { return ( elem === qualifier ) === keep; }); } else if ( typeof qualifier === "string" ) { var filtered = jQuery.grep(elements, function( elem ) { return elem.nodeType === 1; }); if ( isSimple.test( qualifier ) ) { return jQuery.filter(qualifier, filtered, !keep); } else { qualifier = jQuery.filter( qualifier, filtered ); } } return jQuery.grep(elements, function( elem ) { return ( jQuery.inArray( elem, qualifier ) >= 0 ) === keep; }); } 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 ); }, 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(); }, append: function() { return this.domManip(arguments, true, function( elem ) { if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { this.appendChild( elem ); } }); }, prepend: function() { return this.domManip(arguments, true, function( elem ) { if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { this.insertBefore( elem, this.firstChild ); } }); }, before: function() { return this.domManip( arguments, false, function( elem ) { if ( this.parentNode ) { this.parentNode.insertBefore( elem, this ); } }); }, after: function() { return this.domManip( arguments, false, 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, i = 0; for ( ; (elem = this[i]) != null; i++ ) { if ( !selector || jQuery.filter( selector, [ elem ] ).length > 0 ) { 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( value ) { var isFunc = jQuery.isFunction( value ); // Make sure that the elements are removed from the DOM before they are inserted // this can help fix replacing a parent with child elements if ( !isFunc && typeof value !== "string" ) { value = jQuery( value ).not( this ).detach(); } return this.domManip( [ value ], true, function( elem ) { var next = this.nextSibling, parent = this.parentNode; if ( parent ) { jQuery( this ).remove(); parent.insertBefore( elem, next ); } }); }, detach: function( selector ) { return this.remove( selector, true ); }, domManip: function( args, table, callback ) { // 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, table ? self.html() : undefined ); } self.domManip( args, table, callback ); }); } if ( l ) { fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this ); first = fragment.firstChild; if ( fragment.childNodes.length === 1 ) { fragment = first; } if ( first ) { table = table && jQuery.nodeName( first, "tr" ); 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( table && jQuery.nodeName( this[i], "table" ) ? findOrAppend( this[i], "tbody" ) : 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.ajax({ url: node.src, type: "GET", dataType: "script", async: false, global: false, "throws": true }); } else { jQuery.globalEval( ( node.text || node.textContent || node.innerHTML || "" ).replace( rcleanScript, "" ) ); } } } } // Fix #11809: Avoid leaking memory fragment = first = null; } } return this; } }); function findOrAppend( elem, tag ) { return elem.getElementsByTagName( tag )[0] || elem.appendChild( elem.ownerDocument.createElement( tag ) ); } // Replace/restore the type attribute of script elements for safe DOM manipulation function disableScript( elem ) { var attr = elem.getAttributeNode("type"); elem.type = ( attr && attr.specified ) + "/" + 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 ); } } } } } }); 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 ) { var bool = typeof state === "boolean"; return this.each(function() { if ( bool ? state : 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; } } } }, // Exclude the following css properties to add px cssNumber: { "columnCount": true, "fillOpacity": true, "fontWeight": true, "lineHeight": true, "opacity": 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; }, // A method for quickly swapping in/out CSS properties to get correct calculations 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; } }); // 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("