From 0510c9b111aed03d0d3680db63614d50f231745c Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Wed, 10 Sep 2014 14:22:26 +1200 Subject: Client-side framework for web application --- web/src/benchmark.html | 22 + web/src/css/bootstrap.css | 6296 ++++++ web/src/css/mitmproxy.less | 7 + web/src/js/certinstall.jsx | 27 + web/src/js/certinstall_jsx.js | 27 + web/src/js/mitmproxy.js | 10 + web/src/js/router.jsx | 10 + web/src/js/router_jsx.js | 10 + web/src/js/tests.js | 5 + web/src/test.html | 25 + web/src/vendor/benchmark/.bower.json | 14 + web/src/vendor/benchmark/.gitattributes | 1 + web/src/vendor/benchmark/.gitignore | 4 + web/src/vendor/benchmark/.npmignore | 8 + web/src/vendor/benchmark/LICENSE.txt | 22 + web/src/vendor/benchmark/README.md | 135 + web/src/vendor/benchmark/benchmark.js | 3919 ++++ web/src/vendor/benchmark/doc/README.md | 2629 +++ web/src/vendor/benchmark/doc/parse.php | 35 + web/src/vendor/benchmark/example/jsperf/index.html | 287 + web/src/vendor/benchmark/example/jsperf/main.css | 588 + web/src/vendor/benchmark/example/jsperf/ui.js | 745 + web/src/vendor/benchmark/nano.jar | Bin 0 -> 293 bytes web/src/vendor/benchmark/nano.java | 23 + web/src/vendor/benchmark/package.json | 54 + web/src/vendor/benchmark/plugin/ui.browserscope.js | 1052 + .../test/benchmark.air/.actionScriptProperties | 24 + .../benchmark/test/benchmark.air/.flexProperties | 2 + .../vendor/benchmark/test/benchmark.air/.project | 24 + .../vendor/benchmark/test/benchmark.air/README.md | 6 + .../benchmark/test/benchmark.air/bin-debug/air.swf | Bin 0 -> 965966 bytes .../benchmark/test/benchmark.air/src/air-app.xml | 16 + .../benchmark/test/benchmark.air/src/air.mxml | 7 + .../benchmark/test/benchmark.air/src/index.html | 37 + web/src/vendor/benchmark/test/index.html | 85 + web/src/vendor/benchmark/test/run-test.sh | 9 + web/src/vendor/benchmark/test/test.js | 2074 ++ .../vendor/benchmark/vendor/docdown/LICENSE.txt | 20 + web/src/vendor/benchmark/vendor/docdown/README.md | 33 + .../vendor/benchmark/vendor/docdown/docdown.php | 38 + .../benchmark/vendor/docdown/src/DocDown/Entry.php | 304 + .../vendor/docdown/src/DocDown/Generator.php | 416 + .../benchmark/vendor/platform.js/LICENSE.txt | 20 + .../vendor/benchmark/vendor/platform.js/README.md | 98 + .../benchmark/vendor/platform.js/platform.js | 996 + .../vendor/benchmark/vendor/qunit-clib/LICENSE.txt | 20 + .../vendor/benchmark/vendor/qunit-clib/README.md | 57 + .../benchmark/vendor/qunit-clib/qunit-clib.js | 319 + web/src/vendor/benchmark/vendor/qunit/README.md | 49 + .../benchmark/vendor/qunit/qunit/qunit-1.8.0.js | 1863 ++ .../vendor/benchmark/vendor/qunit/qunit/qunit.css | 231 + .../vendor/benchmark/vendor/qunit/qunit/qunit.js | 1932 ++ web/src/vendor/benchmark/vendor/requirejs/LICENSE | 58 + .../vendor/benchmark/vendor/requirejs/README.md | 51 + .../vendor/benchmark/vendor/requirejs/require.js | 2053 ++ web/src/vendor/benchmarkjs-runner/.bower.json | 30 + web/src/vendor/benchmarkjs-runner/History.md | 7 + web/src/vendor/benchmarkjs-runner/Makefile | 12 + web/src/vendor/benchmarkjs-runner/Readme.md | 64 + web/src/vendor/benchmarkjs-runner/bower.json | 21 + web/src/vendor/benchmarkjs-runner/example.html | 44 + web/src/vendor/benchmarkjs-runner/runner.js | 13019 ++++++++++++ web/src/vendor/benchmarkjs-runner/src/runner.js | 271 + .../benchmarkjs-runner/support/screenshot.png | Bin 0 -> 39700 bytes web/src/vendor/fontawesome/.bower.json | 36 + web/src/vendor/fontawesome/.gitignore | 32 + web/src/vendor/fontawesome/.npmignore | 42 + web/src/vendor/fontawesome/bower.json | 23 + web/src/vendor/fontawesome/css/font-awesome.css | 1672 ++ .../vendor/fontawesome/css/font-awesome.min.css | 4 + web/src/vendor/fontawesome/fonts/FontAwesome.otf | Bin 0 -> 85908 bytes .../fontawesome/fonts/fontawesome-webfont.eot | Bin 0 -> 56006 bytes .../fontawesome/fonts/fontawesome-webfont.svg | 520 + .../fontawesome/fonts/fontawesome-webfont.ttf | Bin 0 -> 112160 bytes .../fontawesome/fonts/fontawesome-webfont.woff | Bin 0 -> 65452 bytes .../vendor/fontawesome/less/bordered-pulled.less | 16 + web/src/vendor/fontawesome/less/core.less | 11 + web/src/vendor/fontawesome/less/extras.less | 2 + web/src/vendor/fontawesome/less/fixed-width.less | 6 + web/src/vendor/fontawesome/less/font-awesome.less | 17 + web/src/vendor/fontawesome/less/icons.less | 552 + web/src/vendor/fontawesome/less/larger.less | 13 + web/src/vendor/fontawesome/less/list.less | 19 + web/src/vendor/fontawesome/less/mixins.less | 25 + web/src/vendor/fontawesome/less/path.less | 14 + .../vendor/fontawesome/less/rotated-flipped.less | 20 + web/src/vendor/fontawesome/less/spinning.less | 29 + web/src/vendor/fontawesome/less/stacked.less | 20 + web/src/vendor/fontawesome/less/variables.less | 561 + .../vendor/fontawesome/scss/_bordered-pulled.scss | 16 + web/src/vendor/fontawesome/scss/_core.scss | 11 + web/src/vendor/fontawesome/scss/_extras.scss | 44 + web/src/vendor/fontawesome/scss/_fixed-width.scss | 6 + web/src/vendor/fontawesome/scss/_icons.scss | 552 + web/src/vendor/fontawesome/scss/_larger.scss | 13 + web/src/vendor/fontawesome/scss/_list.scss | 19 + web/src/vendor/fontawesome/scss/_mixins.scss | 25 + web/src/vendor/fontawesome/scss/_path.scss | 14 + .../vendor/fontawesome/scss/_rotated-flipped.scss | 20 + web/src/vendor/fontawesome/scss/_spinning.scss | 29 + web/src/vendor/fontawesome/scss/_stacked.scss | 20 + web/src/vendor/fontawesome/scss/_variables.scss | 561 + web/src/vendor/fontawesome/scss/font-awesome.scss | 17 + web/src/vendor/jquery/.bower.json | 21 + web/src/vendor/jquery/.gitignore | 1 + web/src/vendor/jquery/README.md | 12 + web/src/vendor/jquery/bower.json | 11 + web/src/vendor/jquery/component.json | 15 + web/src/vendor/jquery/composer.json | 36 + web/src/vendor/jquery/jquery-migrate.js | 521 + web/src/vendor/jquery/jquery-migrate.min.js | 2 + web/src/vendor/jquery/jquery.js | 9190 +++++++++ web/src/vendor/jquery/jquery.min.js | 4 + web/src/vendor/jquery/package.json | 33 + web/src/vendor/lodash/.bower.json | 33 + web/src/vendor/lodash/LICENSE.txt | 22 + web/src/vendor/lodash/bower.json | 23 + web/src/vendor/lodash/dist/lodash.compat.js | 7157 +++++++ web/src/vendor/lodash/dist/lodash.compat.min.js | 61 + web/src/vendor/lodash/dist/lodash.js | 6785 +++++++ web/src/vendor/lodash/dist/lodash.min.js | 56 + web/src/vendor/lodash/dist/lodash.underscore.js | 4979 +++++ .../vendor/lodash/dist/lodash.underscore.min.js | 39 + web/src/vendor/qunit/.bower.json | 28 + web/src/vendor/qunit/AUTHORS.txt | 90 + web/src/vendor/qunit/CONTRIBUTING.md | 5 + web/src/vendor/qunit/History.md | 570 + web/src/vendor/qunit/LICENSE.txt | 37 + web/src/vendor/qunit/README.md | 56 + web/src/vendor/qunit/bower.json | 18 + web/src/vendor/qunit/browserstack.json | 27 + web/src/vendor/qunit/build/release.js | 28 + web/src/vendor/qunit/external/jsdiff/jsdiff.js | 146 + web/src/vendor/qunit/qunit/qunit.css | 237 + web/src/vendor/qunit/qunit/qunit.js | 2495 +++ web/src/vendor/qunit/reporter/html.js | 682 + web/src/vendor/qunit/src/assert.js | 180 + web/src/vendor/qunit/src/core.js | 695 + web/src/vendor/qunit/src/dump.js | 240 + web/src/vendor/qunit/src/equiv.js | 218 + web/src/vendor/qunit/src/export.js | 54 + web/src/vendor/qunit/src/intro.js | 12 + web/src/vendor/qunit/src/outro.js | 4 + web/src/vendor/qunit/src/qunit.css | 237 + web/src/vendor/qunit/src/test.js | 254 + web/src/vendor/react-router/.bower.json | 38 + web/src/vendor/react-router/CHANGELOG.md | 169 + web/src/vendor/react-router/LICENSE | 19 + web/src/vendor/react-router/README.md | 135 + web/src/vendor/react-router/UPGRADE_GUIDE.md | 215 + web/src/vendor/react-router/bower.json | 29 + web/src/vendor/react-router/dist/react-router.js | 4635 +++++ .../vendor/react-router/dist/react-router.min.js | 2 + web/src/vendor/react-router/docs/api/README.md | 32 + web/src/vendor/react-router/docs/api/Router.md | 65 + .../docs/api/components/DefaultRoute.md | 55 + .../react-router/docs/api/components/Link.md | 71 + .../docs/api/components/NotFoundRoute.md | 36 + .../react-router/docs/api/components/Redirect.md | 59 + .../react-router/docs/api/components/Route.md | 105 + .../docs/api/components/RouteHandler.md | 108 + .../react-router/docs/api/components/Routes.md | 69 + .../vendor/react-router/docs/api/misc/Location.md | 66 + .../react-router/docs/api/misc/transition.md | 24 + .../react-router/docs/api/mixins/ActiveState.md | 58 + .../react-router/docs/api/mixins/AsyncState.md | 115 + .../vendor/react-router/docs/guides/overview.md | 373 + .../react-router/docs/guides/path-matching.md | 83 + web/src/vendor/react-router/eslint.json | 18 + web/src/vendor/react-router/scripts/build | 4 + web/src/vendor/react-router/scripts/build-examples | 18 + .../vendor/react-router/scripts/preview-release | 2 + web/src/vendor/react-router/scripts/release | 3 + web/src/vendor/react-router/scripts/test | 2 + web/src/vendor/react/.bower.json | 15 + web/src/vendor/react/JSXTransformer.js | 13446 ++++++++++++ web/src/vendor/react/bower.json | 5 + web/src/vendor/react/react-with-addons.js | 20251 +++++++++++++++++++ web/src/vendor/react/react-with-addons.min.js | 22 + web/src/vendor/react/react.js | 18459 +++++++++++++++++ web/src/vendor/react/react.min.js | 21 + 181 files changed, 139387 insertions(+) create mode 100644 web/src/benchmark.html create mode 100644 web/src/css/bootstrap.css create mode 100644 web/src/css/mitmproxy.less create mode 100644 web/src/js/certinstall.jsx create mode 100644 web/src/js/certinstall_jsx.js create mode 100644 web/src/js/mitmproxy.js create mode 100644 web/src/js/router.jsx create mode 100644 web/src/js/router_jsx.js create mode 100644 web/src/js/tests.js create mode 100644 web/src/test.html create mode 100644 web/src/vendor/benchmark/.bower.json create mode 100644 web/src/vendor/benchmark/.gitattributes create mode 100644 web/src/vendor/benchmark/.gitignore create mode 100644 web/src/vendor/benchmark/.npmignore create mode 100644 web/src/vendor/benchmark/LICENSE.txt create mode 100644 web/src/vendor/benchmark/README.md create mode 100644 web/src/vendor/benchmark/benchmark.js create mode 100644 web/src/vendor/benchmark/doc/README.md create mode 100644 web/src/vendor/benchmark/doc/parse.php create mode 100644 web/src/vendor/benchmark/example/jsperf/index.html create mode 100644 web/src/vendor/benchmark/example/jsperf/main.css create mode 100644 web/src/vendor/benchmark/example/jsperf/ui.js create mode 100644 web/src/vendor/benchmark/nano.jar create mode 100644 web/src/vendor/benchmark/nano.java create mode 100644 web/src/vendor/benchmark/package.json create mode 100644 web/src/vendor/benchmark/plugin/ui.browserscope.js create mode 100644 web/src/vendor/benchmark/test/benchmark.air/.actionScriptProperties create mode 100644 web/src/vendor/benchmark/test/benchmark.air/.flexProperties create mode 100644 web/src/vendor/benchmark/test/benchmark.air/.project create mode 100644 web/src/vendor/benchmark/test/benchmark.air/README.md create mode 100644 web/src/vendor/benchmark/test/benchmark.air/bin-debug/air.swf create mode 100644 web/src/vendor/benchmark/test/benchmark.air/src/air-app.xml create mode 100644 web/src/vendor/benchmark/test/benchmark.air/src/air.mxml create mode 100644 web/src/vendor/benchmark/test/benchmark.air/src/index.html create mode 100644 web/src/vendor/benchmark/test/index.html create mode 100755 web/src/vendor/benchmark/test/run-test.sh create mode 100644 web/src/vendor/benchmark/test/test.js create mode 100644 web/src/vendor/benchmark/vendor/docdown/LICENSE.txt create mode 100644 web/src/vendor/benchmark/vendor/docdown/README.md create mode 100644 web/src/vendor/benchmark/vendor/docdown/docdown.php create mode 100644 web/src/vendor/benchmark/vendor/docdown/src/DocDown/Entry.php create mode 100644 web/src/vendor/benchmark/vendor/docdown/src/DocDown/Generator.php create mode 100644 web/src/vendor/benchmark/vendor/platform.js/LICENSE.txt create mode 100644 web/src/vendor/benchmark/vendor/platform.js/README.md create mode 100644 web/src/vendor/benchmark/vendor/platform.js/platform.js create mode 100644 web/src/vendor/benchmark/vendor/qunit-clib/LICENSE.txt create mode 100644 web/src/vendor/benchmark/vendor/qunit-clib/README.md create mode 100644 web/src/vendor/benchmark/vendor/qunit-clib/qunit-clib.js create mode 100644 web/src/vendor/benchmark/vendor/qunit/README.md create mode 100644 web/src/vendor/benchmark/vendor/qunit/qunit/qunit-1.8.0.js create mode 100644 web/src/vendor/benchmark/vendor/qunit/qunit/qunit.css create mode 100644 web/src/vendor/benchmark/vendor/qunit/qunit/qunit.js create mode 100644 web/src/vendor/benchmark/vendor/requirejs/LICENSE create mode 100644 web/src/vendor/benchmark/vendor/requirejs/README.md create mode 100644 web/src/vendor/benchmark/vendor/requirejs/require.js create mode 100644 web/src/vendor/benchmarkjs-runner/.bower.json create mode 100644 web/src/vendor/benchmarkjs-runner/History.md create mode 100644 web/src/vendor/benchmarkjs-runner/Makefile create mode 100644 web/src/vendor/benchmarkjs-runner/Readme.md create mode 100644 web/src/vendor/benchmarkjs-runner/bower.json create mode 100644 web/src/vendor/benchmarkjs-runner/example.html create mode 100644 web/src/vendor/benchmarkjs-runner/runner.js create mode 100644 web/src/vendor/benchmarkjs-runner/src/runner.js create mode 100644 web/src/vendor/benchmarkjs-runner/support/screenshot.png create mode 100644 web/src/vendor/fontawesome/.bower.json create mode 100644 web/src/vendor/fontawesome/.gitignore create mode 100644 web/src/vendor/fontawesome/.npmignore create mode 100644 web/src/vendor/fontawesome/bower.json create mode 100644 web/src/vendor/fontawesome/css/font-awesome.css create mode 100644 web/src/vendor/fontawesome/css/font-awesome.min.css create mode 100644 web/src/vendor/fontawesome/fonts/FontAwesome.otf create mode 100644 web/src/vendor/fontawesome/fonts/fontawesome-webfont.eot create mode 100644 web/src/vendor/fontawesome/fonts/fontawesome-webfont.svg create mode 100644 web/src/vendor/fontawesome/fonts/fontawesome-webfont.ttf create mode 100644 web/src/vendor/fontawesome/fonts/fontawesome-webfont.woff create mode 100644 web/src/vendor/fontawesome/less/bordered-pulled.less create mode 100644 web/src/vendor/fontawesome/less/core.less create mode 100644 web/src/vendor/fontawesome/less/extras.less create mode 100644 web/src/vendor/fontawesome/less/fixed-width.less create mode 100644 web/src/vendor/fontawesome/less/font-awesome.less create mode 100644 web/src/vendor/fontawesome/less/icons.less create mode 100644 web/src/vendor/fontawesome/less/larger.less create mode 100644 web/src/vendor/fontawesome/less/list.less create mode 100644 web/src/vendor/fontawesome/less/mixins.less create mode 100644 web/src/vendor/fontawesome/less/path.less create mode 100644 web/src/vendor/fontawesome/less/rotated-flipped.less create mode 100644 web/src/vendor/fontawesome/less/spinning.less create mode 100644 web/src/vendor/fontawesome/less/stacked.less create mode 100644 web/src/vendor/fontawesome/less/variables.less create mode 100644 web/src/vendor/fontawesome/scss/_bordered-pulled.scss create mode 100644 web/src/vendor/fontawesome/scss/_core.scss create mode 100644 web/src/vendor/fontawesome/scss/_extras.scss create mode 100644 web/src/vendor/fontawesome/scss/_fixed-width.scss create mode 100644 web/src/vendor/fontawesome/scss/_icons.scss create mode 100644 web/src/vendor/fontawesome/scss/_larger.scss create mode 100644 web/src/vendor/fontawesome/scss/_list.scss create mode 100644 web/src/vendor/fontawesome/scss/_mixins.scss create mode 100644 web/src/vendor/fontawesome/scss/_path.scss create mode 100644 web/src/vendor/fontawesome/scss/_rotated-flipped.scss create mode 100644 web/src/vendor/fontawesome/scss/_spinning.scss create mode 100644 web/src/vendor/fontawesome/scss/_stacked.scss create mode 100644 web/src/vendor/fontawesome/scss/_variables.scss create mode 100644 web/src/vendor/fontawesome/scss/font-awesome.scss create mode 100644 web/src/vendor/jquery/.bower.json create mode 100644 web/src/vendor/jquery/.gitignore create mode 100644 web/src/vendor/jquery/README.md create mode 100644 web/src/vendor/jquery/bower.json create mode 100644 web/src/vendor/jquery/component.json create mode 100644 web/src/vendor/jquery/composer.json create mode 100644 web/src/vendor/jquery/jquery-migrate.js create mode 100644 web/src/vendor/jquery/jquery-migrate.min.js create mode 100644 web/src/vendor/jquery/jquery.js create mode 100644 web/src/vendor/jquery/jquery.min.js create mode 100644 web/src/vendor/jquery/package.json create mode 100644 web/src/vendor/lodash/.bower.json create mode 100644 web/src/vendor/lodash/LICENSE.txt create mode 100644 web/src/vendor/lodash/bower.json create mode 100644 web/src/vendor/lodash/dist/lodash.compat.js create mode 100644 web/src/vendor/lodash/dist/lodash.compat.min.js create mode 100644 web/src/vendor/lodash/dist/lodash.js create mode 100644 web/src/vendor/lodash/dist/lodash.min.js create mode 100644 web/src/vendor/lodash/dist/lodash.underscore.js create mode 100644 web/src/vendor/lodash/dist/lodash.underscore.min.js create mode 100644 web/src/vendor/qunit/.bower.json create mode 100644 web/src/vendor/qunit/AUTHORS.txt create mode 100644 web/src/vendor/qunit/CONTRIBUTING.md create mode 100644 web/src/vendor/qunit/History.md create mode 100644 web/src/vendor/qunit/LICENSE.txt create mode 100644 web/src/vendor/qunit/README.md create mode 100644 web/src/vendor/qunit/bower.json create mode 100644 web/src/vendor/qunit/browserstack.json create mode 100644 web/src/vendor/qunit/build/release.js create mode 100644 web/src/vendor/qunit/external/jsdiff/jsdiff.js create mode 100644 web/src/vendor/qunit/qunit/qunit.css create mode 100644 web/src/vendor/qunit/qunit/qunit.js create mode 100644 web/src/vendor/qunit/reporter/html.js create mode 100644 web/src/vendor/qunit/src/assert.js create mode 100644 web/src/vendor/qunit/src/core.js create mode 100644 web/src/vendor/qunit/src/dump.js create mode 100644 web/src/vendor/qunit/src/equiv.js create mode 100644 web/src/vendor/qunit/src/export.js create mode 100644 web/src/vendor/qunit/src/intro.js create mode 100644 web/src/vendor/qunit/src/outro.js create mode 100644 web/src/vendor/qunit/src/qunit.css create mode 100644 web/src/vendor/qunit/src/test.js create mode 100644 web/src/vendor/react-router/.bower.json create mode 100644 web/src/vendor/react-router/CHANGELOG.md create mode 100644 web/src/vendor/react-router/LICENSE create mode 100644 web/src/vendor/react-router/README.md create mode 100644 web/src/vendor/react-router/UPGRADE_GUIDE.md create mode 100644 web/src/vendor/react-router/bower.json create mode 100644 web/src/vendor/react-router/dist/react-router.js create mode 100644 web/src/vendor/react-router/dist/react-router.min.js create mode 100644 web/src/vendor/react-router/docs/api/README.md create mode 100644 web/src/vendor/react-router/docs/api/Router.md create mode 100644 web/src/vendor/react-router/docs/api/components/DefaultRoute.md create mode 100644 web/src/vendor/react-router/docs/api/components/Link.md create mode 100644 web/src/vendor/react-router/docs/api/components/NotFoundRoute.md create mode 100644 web/src/vendor/react-router/docs/api/components/Redirect.md create mode 100644 web/src/vendor/react-router/docs/api/components/Route.md create mode 100644 web/src/vendor/react-router/docs/api/components/RouteHandler.md create mode 100644 web/src/vendor/react-router/docs/api/components/Routes.md create mode 100644 web/src/vendor/react-router/docs/api/misc/Location.md create mode 100644 web/src/vendor/react-router/docs/api/misc/transition.md create mode 100644 web/src/vendor/react-router/docs/api/mixins/ActiveState.md create mode 100644 web/src/vendor/react-router/docs/api/mixins/AsyncState.md create mode 100644 web/src/vendor/react-router/docs/guides/overview.md create mode 100644 web/src/vendor/react-router/docs/guides/path-matching.md create mode 100644 web/src/vendor/react-router/eslint.json create mode 100755 web/src/vendor/react-router/scripts/build create mode 100755 web/src/vendor/react-router/scripts/build-examples create mode 100755 web/src/vendor/react-router/scripts/preview-release create mode 100755 web/src/vendor/react-router/scripts/release create mode 100755 web/src/vendor/react-router/scripts/test create mode 100644 web/src/vendor/react/.bower.json create mode 100644 web/src/vendor/react/JSXTransformer.js create mode 100644 web/src/vendor/react/bower.json create mode 100644 web/src/vendor/react/react-with-addons.js create mode 100644 web/src/vendor/react/react-with-addons.min.js create mode 100644 web/src/vendor/react/react.js create mode 100644 web/src/vendor/react/react.min.js (limited to 'web/src') diff --git a/web/src/benchmark.html b/web/src/benchmark.html new file mode 100644 index 00000000..56b7f362 --- /dev/null +++ b/web/src/benchmark.html @@ -0,0 +1,22 @@ + + + + + Benchmarks + + + + + + + + + + + + + \ No newline at end of file diff --git a/web/src/css/bootstrap.css b/web/src/css/bootstrap.css new file mode 100644 index 00000000..75266cca --- /dev/null +++ b/web/src/css/bootstrap.css @@ -0,0 +1,6296 @@ +/*! + * bootswatch v3.2.0 + * Homepage: http://bootswatch.com + * Copyright 2012-2014 Thomas Park + * Licensed under MIT + * Based on Bootstrap +*/ +/*! normalize.css v3.0.1 | MIT License | git.io/normalize */ +html { + font-family: sans-serif; + -ms-text-size-adjust: 100%; + -webkit-text-size-adjust: 100%; +} +body { + margin: 0; +} +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +main, +nav, +section, +summary { + display: block; +} +audio, +canvas, +progress, +video { + display: inline-block; + vertical-align: baseline; +} +audio:not([controls]) { + display: none; + height: 0; +} +[hidden], +template { + display: none; +} +a { + background: transparent; +} +a:active, +a:hover { + outline: 0; +} +abbr[title] { + border-bottom: 1px dotted; +} +b, +strong { + font-weight: bold; +} +dfn { + font-style: italic; +} +h1 { + font-size: 2em; + margin: 0.67em 0; +} +mark { + background: #ff0; + color: #000; +} +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; +} +img { + border: 0; +} +svg:not(:root) { + overflow: hidden; +} +figure { + margin: 1em 40px; +} +hr { + -moz-box-sizing: content-box; + box-sizing: content-box; + height: 0; +} +pre { + overflow: auto; +} +code, +kbd, +pre, +samp { + font-family: monospace, monospace; + font-size: 1em; +} +button, +input, +optgroup, +select, +textarea { + color: inherit; + font: inherit; + margin: 0; +} +button { + overflow: visible; +} +button, +select { + text-transform: none; +} +button, +html input[type="button"], +input[type="reset"], +input[type="submit"] { + -webkit-appearance: button; + cursor: pointer; +} +button[disabled], +html input[disabled] { + cursor: default; +} +button::-moz-focus-inner, +input::-moz-focus-inner { + border: 0; + padding: 0; +} +input { + line-height: normal; +} +input[type="checkbox"], +input[type="radio"] { + box-sizing: border-box; + padding: 0; +} +input[type="number"]::-webkit-inner-spin-button, +input[type="number"]::-webkit-outer-spin-button { + height: auto; +} +input[type="search"] { + -webkit-appearance: textfield; + -moz-box-sizing: content-box; + -webkit-box-sizing: content-box; + box-sizing: content-box; +} +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} +fieldset { + border: 1px solid #c0c0c0; + margin: 0 2px; + padding: 0.35em 0.625em 0.75em; +} +legend { + border: 0; + padding: 0; +} +textarea { + overflow: auto; +} +optgroup { + font-weight: bold; +} +table { + border-collapse: collapse; + border-spacing: 0; +} +td, +th { + padding: 0; +} +@media print { + * { + text-shadow: none !important; + color: #000 !important; + background: transparent !important; + box-shadow: none !important; + } + a, + a:visited { + text-decoration: underline; + } + a[href]:after { + content: " (" attr(href) ")"; + } + abbr[title]:after { + content: " (" attr(title) ")"; + } + a[href^="javascript:"]:after, + a[href^="#"]:after { + content: ""; + } + pre, + blockquote { + border: 1px solid #999; + page-break-inside: avoid; + } + thead { + display: table-header-group; + } + tr, + img { + page-break-inside: avoid; + } + img { + max-width: 100% !important; + } + p, + h2, + h3 { + orphans: 3; + widows: 3; + } + h2, + h3 { + page-break-after: avoid; + } + select { + background: #fff !important; + } + .navbar { + display: none; + } + .table td, + .table th { + background-color: #fff !important; + } + .btn > .caret, + .dropup > .btn > .caret { + border-top-color: #000 !important; + } + .label { + border: 1px solid #000; + } + .table { + border-collapse: collapse !important; + } + .table-bordered th, + .table-bordered td { + border: 1px solid #ddd !important; + } +} +@font-face { + font-family: 'Glyphicons Halflings'; + src: url('../fonts/glyphicons-halflings-regular.eot'); + src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg'); +} +.glyphicon { + position: relative; + top: 1px; + display: inline-block; + font-family: 'Glyphicons Halflings'; + font-style: normal; + font-weight: normal; + line-height: 1; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} +.glyphicon-asterisk:before { + content: "\2a"; +} +.glyphicon-plus:before { + content: "\2b"; +} +.glyphicon-euro:before { + content: "\20ac"; +} +.glyphicon-minus:before { + content: "\2212"; +} +.glyphicon-cloud:before { + content: "\2601"; +} +.glyphicon-envelope:before { + content: "\2709"; +} +.glyphicon-pencil:before { + content: "\270f"; +} +.glyphicon-glass:before { + content: "\e001"; +} +.glyphicon-music:before { + content: "\e002"; +} +.glyphicon-search:before { + content: "\e003"; +} +.glyphicon-heart:before { + content: "\e005"; +} +.glyphicon-star:before { + content: "\e006"; +} +.glyphicon-star-empty:before { + content: "\e007"; +} +.glyphicon-user:before { + content: "\e008"; +} +.glyphicon-film:before { + content: "\e009"; +} +.glyphicon-th-large:before { + content: "\e010"; +} +.glyphicon-th:before { + content: "\e011"; +} +.glyphicon-th-list:before { + content: "\e012"; +} +.glyphicon-ok:before { + content: "\e013"; +} +.glyphicon-remove:before { + content: "\e014"; +} +.glyphicon-zoom-in:before { + content: "\e015"; +} +.glyphicon-zoom-out:before { + content: "\e016"; +} +.glyphicon-off:before { + content: "\e017"; +} +.glyphicon-signal:before { + content: "\e018"; +} +.glyphicon-cog:before { + content: "\e019"; +} +.glyphicon-trash:before { + content: "\e020"; +} +.glyphicon-home:before { + content: "\e021"; +} +.glyphicon-file:before { + content: "\e022"; +} +.glyphicon-time:before { + content: "\e023"; +} +.glyphicon-road:before { + content: "\e024"; +} +.glyphicon-download-alt:before { + content: "\e025"; +} +.glyphicon-download:before { + content: "\e026"; +} +.glyphicon-upload:before { + content: "\e027"; +} +.glyphicon-inbox:before { + content: "\e028"; +} +.glyphicon-play-circle:before { + content: "\e029"; +} +.glyphicon-repeat:before { + content: "\e030"; +} +.glyphicon-refresh:before { + content: "\e031"; +} +.glyphicon-list-alt:before { + content: "\e032"; +} +.glyphicon-lock:before { + content: "\e033"; +} +.glyphicon-flag:before { + content: "\e034"; +} +.glyphicon-headphones:before { + content: "\e035"; +} +.glyphicon-volume-off:before { + content: "\e036"; +} +.glyphicon-volume-down:before { + content: "\e037"; +} +.glyphicon-volume-up:before { + content: "\e038"; +} +.glyphicon-qrcode:before { + content: "\e039"; +} +.glyphicon-barcode:before { + content: "\e040"; +} +.glyphicon-tag:before { + content: "\e041"; +} +.glyphicon-tags:before { + content: "\e042"; +} +.glyphicon-book:before { + content: "\e043"; +} +.glyphicon-bookmark:before { + content: "\e044"; +} +.glyphicon-print:before { + content: "\e045"; +} +.glyphicon-camera:before { + content: "\e046"; +} +.glyphicon-font:before { + content: "\e047"; +} +.glyphicon-bold:before { + content: "\e048"; +} +.glyphicon-italic:before { + content: "\e049"; +} +.glyphicon-text-height:before { + content: "\e050"; +} +.glyphicon-text-width:before { + content: "\e051"; +} +.glyphicon-align-left:before { + content: "\e052"; +} +.glyphicon-align-center:before { + content: "\e053"; +} +.glyphicon-align-right:before { + content: "\e054"; +} +.glyphicon-align-justify:before { + content: "\e055"; +} +.glyphicon-list:before { + content: "\e056"; +} +.glyphicon-indent-left:before { + content: "\e057"; +} +.glyphicon-indent-right:before { + content: "\e058"; +} +.glyphicon-facetime-video:before { + content: "\e059"; +} +.glyphicon-picture:before { + content: "\e060"; +} +.glyphicon-map-marker:before { + content: "\e062"; +} +.glyphicon-adjust:before { + content: "\e063"; +} +.glyphicon-tint:before { + content: "\e064"; +} +.glyphicon-edit:before { + content: "\e065"; +} +.glyphicon-share:before { + content: "\e066"; +} +.glyphicon-check:before { + content: "\e067"; +} +.glyphicon-move:before { + content: "\e068"; +} +.glyphicon-step-backward:before { + content: "\e069"; +} +.glyphicon-fast-backward:before { + content: "\e070"; +} +.glyphicon-backward:before { + content: "\e071"; +} +.glyphicon-play:before { + content: "\e072"; +} +.glyphicon-pause:before { + content: "\e073"; +} +.glyphicon-stop:before { + content: "\e074"; +} +.glyphicon-forward:before { + content: "\e075"; +} +.glyphicon-fast-forward:before { + content: "\e076"; +} +.glyphicon-step-forward:before { + content: "\e077"; +} +.glyphicon-eject:before { + content: "\e078"; +} +.glyphicon-chevron-left:before { + content: "\e079"; +} +.glyphicon-chevron-right:before { + content: "\e080"; +} +.glyphicon-plus-sign:before { + content: "\e081"; +} +.glyphicon-minus-sign:before { + content: "\e082"; +} +.glyphicon-remove-sign:before { + content: "\e083"; +} +.glyphicon-ok-sign:before { + content: "\e084"; +} +.glyphicon-question-sign:before { + content: "\e085"; +} +.glyphicon-info-sign:before { + content: "\e086"; +} +.glyphicon-screenshot:before { + content: "\e087"; +} +.glyphicon-remove-circle:before { + content: "\e088"; +} +.glyphicon-ok-circle:before { + content: "\e089"; +} +.glyphicon-ban-circle:before { + content: "\e090"; +} +.glyphicon-arrow-left:before { + content: "\e091"; +} +.glyphicon-arrow-right:before { + content: "\e092"; +} +.glyphicon-arrow-up:before { + content: "\e093"; +} +.glyphicon-arrow-down:before { + content: "\e094"; +} +.glyphicon-share-alt:before { + content: "\e095"; +} +.glyphicon-resize-full:before { + content: "\e096"; +} +.glyphicon-resize-small:before { + content: "\e097"; +} +.glyphicon-exclamation-sign:before { + content: "\e101"; +} +.glyphicon-gift:before { + content: "\e102"; +} +.glyphicon-leaf:before { + content: "\e103"; +} +.glyphicon-fire:before { + content: "\e104"; +} +.glyphicon-eye-open:before { + content: "\e105"; +} +.glyphicon-eye-close:before { + content: "\e106"; +} +.glyphicon-warning-sign:before { + content: "\e107"; +} +.glyphicon-plane:before { + content: "\e108"; +} +.glyphicon-calendar:before { + content: "\e109"; +} +.glyphicon-random:before { + content: "\e110"; +} +.glyphicon-comment:before { + content: "\e111"; +} +.glyphicon-magnet:before { + content: "\e112"; +} +.glyphicon-chevron-up:before { + content: "\e113"; +} +.glyphicon-chevron-down:before { + content: "\e114"; +} +.glyphicon-retweet:before { + content: "\e115"; +} +.glyphicon-shopping-cart:before { + content: "\e116"; +} +.glyphicon-folder-close:before { + content: "\e117"; +} +.glyphicon-folder-open:before { + content: "\e118"; +} +.glyphicon-resize-vertical:before { + content: "\e119"; +} +.glyphicon-resize-horizontal:before { + content: "\e120"; +} +.glyphicon-hdd:before { + content: "\e121"; +} +.glyphicon-bullhorn:before { + content: "\e122"; +} +.glyphicon-bell:before { + content: "\e123"; +} +.glyphicon-certificate:before { + content: "\e124"; +} +.glyphicon-thumbs-up:before { + content: "\e125"; +} +.glyphicon-thumbs-down:before { + content: "\e126"; +} +.glyphicon-hand-right:before { + content: "\e127"; +} +.glyphicon-hand-left:before { + content: "\e128"; +} +.glyphicon-hand-up:before { + content: "\e129"; +} +.glyphicon-hand-down:before { + content: "\e130"; +} +.glyphicon-circle-arrow-right:before { + content: "\e131"; +} +.glyphicon-circle-arrow-left:before { + content: "\e132"; +} +.glyphicon-circle-arrow-up:before { + content: "\e133"; +} +.glyphicon-circle-arrow-down:before { + content: "\e134"; +} +.glyphicon-globe:before { + content: "\e135"; +} +.glyphicon-wrench:before { + content: "\e136"; +} +.glyphicon-tasks:before { + content: "\e137"; +} +.glyphicon-filter:before { + content: "\e138"; +} +.glyphicon-briefcase:before { + content: "\e139"; +} +.glyphicon-fullscreen:before { + content: "\e140"; +} +.glyphicon-dashboard:before { + content: "\e141"; +} +.glyphicon-paperclip:before { + content: "\e142"; +} +.glyphicon-heart-empty:before { + content: "\e143"; +} +.glyphicon-link:before { + content: "\e144"; +} +.glyphicon-phone:before { + content: "\e145"; +} +.glyphicon-pushpin:before { + content: "\e146"; +} +.glyphicon-usd:before { + content: "\e148"; +} +.glyphicon-gbp:before { + content: "\e149"; +} +.glyphicon-sort:before { + content: "\e150"; +} +.glyphicon-sort-by-alphabet:before { + content: "\e151"; +} +.glyphicon-sort-by-alphabet-alt:before { + content: "\e152"; +} +.glyphicon-sort-by-order:before { + content: "\e153"; +} +.glyphicon-sort-by-order-alt:before { + content: "\e154"; +} +.glyphicon-sort-by-attributes:before { + content: "\e155"; +} +.glyphicon-sort-by-attributes-alt:before { + content: "\e156"; +} +.glyphicon-unchecked:before { + content: "\e157"; +} +.glyphicon-expand:before { + content: "\e158"; +} +.glyphicon-collapse-down:before { + content: "\e159"; +} +.glyphicon-collapse-up:before { + content: "\e160"; +} +.glyphicon-log-in:before { + content: "\e161"; +} +.glyphicon-flash:before { + content: "\e162"; +} +.glyphicon-log-out:before { + content: "\e163"; +} +.glyphicon-new-window:before { + content: "\e164"; +} +.glyphicon-record:before { + content: "\e165"; +} +.glyphicon-save:before { + content: "\e166"; +} +.glyphicon-open:before { + content: "\e167"; +} +.glyphicon-saved:before { + content: "\e168"; +} +.glyphicon-import:before { + content: "\e169"; +} +.glyphicon-export:before { + content: "\e170"; +} +.glyphicon-send:before { + content: "\e171"; +} +.glyphicon-floppy-disk:before { + content: "\e172"; +} +.glyphicon-floppy-saved:before { + content: "\e173"; +} +.glyphicon-floppy-remove:before { + content: "\e174"; +} +.glyphicon-floppy-save:before { + content: "\e175"; +} +.glyphicon-floppy-open:before { + content: "\e176"; +} +.glyphicon-credit-card:before { + content: "\e177"; +} +.glyphicon-transfer:before { + content: "\e178"; +} +.glyphicon-cutlery:before { + content: "\e179"; +} +.glyphicon-header:before { + content: "\e180"; +} +.glyphicon-compressed:before { + content: "\e181"; +} +.glyphicon-earphone:before { + content: "\e182"; +} +.glyphicon-phone-alt:before { + content: "\e183"; +} +.glyphicon-tower:before { + content: "\e184"; +} +.glyphicon-stats:before { + content: "\e185"; +} +.glyphicon-sd-video:before { + content: "\e186"; +} +.glyphicon-hd-video:before { + content: "\e187"; +} +.glyphicon-subtitles:before { + content: "\e188"; +} +.glyphicon-sound-stereo:before { + content: "\e189"; +} +.glyphicon-sound-dolby:before { + content: "\e190"; +} +.glyphicon-sound-5-1:before { + content: "\e191"; +} +.glyphicon-sound-6-1:before { + content: "\e192"; +} +.glyphicon-sound-7-1:before { + content: "\e193"; +} +.glyphicon-copyright-mark:before { + content: "\e194"; +} +.glyphicon-registration-mark:before { + content: "\e195"; +} +.glyphicon-cloud-download:before { + content: "\e197"; +} +.glyphicon-cloud-upload:before { + content: "\e198"; +} +.glyphicon-tree-conifer:before { + content: "\e199"; +} +.glyphicon-tree-deciduous:before { + content: "\e200"; +} +* { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +*:before, +*:after { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +html { + font-size: 10px; + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); +} +body { + font-family: Georgia, "Times New Roman", Times, serif; + font-size: 16px; + line-height: 1.42857143; + color: #333333; + background-color: #ffffff; +} +input, +button, +select, +textarea { + font-family: inherit; + font-size: inherit; + line-height: inherit; +} +a { + color: #4582ec; + text-decoration: none; +} +a:hover, +a:focus { + color: #134fb8; + text-decoration: underline; +} +a:focus { + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +figure { + margin: 0; +} +img { + vertical-align: middle; +} +.img-responsive, +.thumbnail > img, +.thumbnail a > img, +.carousel-inner > .item > img, +.carousel-inner > .item > a > img { + display: block; + width: 100% \9; + max-width: 100%; + height: auto; +} +.img-rounded { + border-radius: 6px; +} +.img-thumbnail { + padding: 4px; + line-height: 1.42857143; + background-color: #ffffff; + border: 1px solid #dddddd; + border-radius: 4px; + -webkit-transition: all 0.2s ease-in-out; + -o-transition: all 0.2s ease-in-out; + transition: all 0.2s ease-in-out; + display: inline-block; + width: 100% \9; + max-width: 100%; + height: auto; +} +.img-circle { + border-radius: 50%; +} +hr { + margin-top: 22px; + margin-bottom: 22px; + border: 0; + border-top: 1px solid #eeeeee; +} +.sr-only { + position: absolute; + width: 1px; + height: 1px; + margin: -1px; + padding: 0; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0; +} +.sr-only-focusable:active, +.sr-only-focusable:focus { + position: static; + width: auto; + height: auto; + margin: 0; + overflow: visible; + clip: auto; +} +h1, +h2, +h3, +h4, +h5, +h6, +.h1, +.h2, +.h3, +.h4, +.h5, +.h6 { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-weight: bold; + line-height: 1.1; + color: inherit; +} +h1 small, +h2 small, +h3 small, +h4 small, +h5 small, +h6 small, +.h1 small, +.h2 small, +.h3 small, +.h4 small, +.h5 small, +.h6 small, +h1 .small, +h2 .small, +h3 .small, +h4 .small, +h5 .small, +h6 .small, +.h1 .small, +.h2 .small, +.h3 .small, +.h4 .small, +.h5 .small, +.h6 .small { + font-weight: normal; + line-height: 1; + color: #b3b3b3; +} +h1, +.h1, +h2, +.h2, +h3, +.h3 { + margin-top: 22px; + margin-bottom: 11px; +} +h1 small, +.h1 small, +h2 small, +.h2 small, +h3 small, +.h3 small, +h1 .small, +.h1 .small, +h2 .small, +.h2 .small, +h3 .small, +.h3 .small { + font-size: 65%; +} +h4, +.h4, +h5, +.h5, +h6, +.h6 { + margin-top: 11px; + margin-bottom: 11px; +} +h4 small, +.h4 small, +h5 small, +.h5 small, +h6 small, +.h6 small, +h4 .small, +.h4 .small, +h5 .small, +.h5 .small, +h6 .small, +.h6 .small { + font-size: 75%; +} +h1, +.h1 { + font-size: 41px; +} +h2, +.h2 { + font-size: 34px; +} +h3, +.h3 { + font-size: 28px; +} +h4, +.h4 { + font-size: 20px; +} +h5, +.h5 { + font-size: 16px; +} +h6, +.h6 { + font-size: 14px; +} +p { + margin: 0 0 11px; +} +.lead { + margin-bottom: 22px; + font-size: 18px; + font-weight: 300; + line-height: 1.4; +} +@media (min-width: 768px) { + .lead { + font-size: 24px; + } +} +small, +.small { + font-size: 87%; +} +cite { + font-style: normal; +} +mark, +.mark { + background-color: #fcf8e3; + padding: .2em; +} +.text-left { + text-align: left; +} +.text-right { + text-align: right; +} +.text-center { + text-align: center; +} +.text-justify { + text-align: justify; +} +.text-nowrap { + white-space: nowrap; +} +.text-lowercase { + text-transform: lowercase; +} +.text-uppercase { + text-transform: uppercase; +} +.text-capitalize { + text-transform: capitalize; +} +.text-muted { + color: #b3b3b3; +} +.text-primary { + color: #4582ec; +} +a.text-primary:hover { + color: #1863e6; +} +.text-success { + color: #3fad46; +} +a.text-success:hover { + color: #318837; +} +.text-info { + color: #5bc0de; +} +a.text-info:hover { + color: #31b0d5; +} +.text-warning { + color: #f0ad4e; +} +a.text-warning:hover { + color: #ec971f; +} +.text-danger { + color: #d9534f; +} +a.text-danger:hover { + color: #c9302c; +} +.bg-primary { + color: #fff; + background-color: #4582ec; +} +a.bg-primary:hover { + background-color: #1863e6; +} +.bg-success { + background-color: #dff0d8; +} +a.bg-success:hover { + background-color: #c1e2b3; +} +.bg-info { + background-color: #d9edf7; +} +a.bg-info:hover { + background-color: #afd9ee; +} +.bg-warning { + background-color: #fcf8e3; +} +a.bg-warning:hover { + background-color: #f7ecb5; +} +.bg-danger { + background-color: #f2dede; +} +a.bg-danger:hover { + background-color: #e4b9b9; +} +.page-header { + padding-bottom: 10px; + margin: 44px 0 22px; + border-bottom: 1px solid #dddddd; +} +ul, +ol { + margin-top: 0; + margin-bottom: 11px; +} +ul ul, +ol ul, +ul ol, +ol ol { + margin-bottom: 0; +} +.list-unstyled { + padding-left: 0; + list-style: none; +} +.list-inline { + padding-left: 0; + list-style: none; + margin-left: -5px; +} +.list-inline > li { + display: inline-block; + padding-left: 5px; + padding-right: 5px; +} +dl { + margin-top: 0; + margin-bottom: 22px; +} +dt, +dd { + line-height: 1.42857143; +} +dt { + font-weight: bold; +} +dd { + margin-left: 0; +} +@media (min-width: 768px) { + .dl-horizontal dt { + float: left; + width: 160px; + clear: left; + text-align: right; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + .dl-horizontal dd { + margin-left: 180px; + } +} +abbr[title], +abbr[data-original-title] { + cursor: help; + border-bottom: 1px dotted #b3b3b3; +} +.initialism { + font-size: 90%; + text-transform: uppercase; +} +blockquote { + padding: 11px 22px; + margin: 0 0 22px; + font-size: 20px; + border-left: 5px solid #4582ec; +} +blockquote p:last-child, +blockquote ul:last-child, +blockquote ol:last-child { + margin-bottom: 0; +} +blockquote footer, +blockquote small, +blockquote .small { + display: block; + font-size: 80%; + line-height: 1.42857143; + color: #333333; +} +blockquote footer:before, +blockquote small:before, +blockquote .small:before { + content: '\2014 \00A0'; +} +.blockquote-reverse, +blockquote.pull-right { + padding-right: 15px; + padding-left: 0; + border-right: 5px solid #4582ec; + border-left: 0; + text-align: right; +} +.blockquote-reverse footer:before, +blockquote.pull-right footer:before, +.blockquote-reverse small:before, +blockquote.pull-right small:before, +.blockquote-reverse .small:before, +blockquote.pull-right .small:before { + content: ''; +} +.blockquote-reverse footer:after, +blockquote.pull-right footer:after, +.blockquote-reverse small:after, +blockquote.pull-right small:after, +.blockquote-reverse .small:after, +blockquote.pull-right .small:after { + content: '\00A0 \2014'; +} +blockquote:before, +blockquote:after { + content: ""; +} +address { + margin-bottom: 22px; + font-style: normal; + line-height: 1.42857143; +} +code, +kbd, +pre, +samp { + font-family: Menlo, Monaco, Consolas, "Courier New", monospace; +} +code { + padding: 2px 4px; + font-size: 90%; + color: #c7254e; + background-color: #f9f2f4; + border-radius: 4px; +} +kbd { + padding: 2px 4px; + font-size: 90%; + color: #ffffff; + background-color: #333333; + border-radius: 3px; + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25); +} +kbd kbd { + padding: 0; + font-size: 100%; + box-shadow: none; +} +pre { + display: block; + padding: 10.5px; + margin: 0 0 11px; + font-size: 15px; + line-height: 1.42857143; + word-break: break-all; + word-wrap: break-word; + color: #333333; + background-color: #f5f5f5; + border: 1px solid #cccccc; + border-radius: 4px; +} +pre code { + padding: 0; + font-size: inherit; + color: inherit; + white-space: pre-wrap; + background-color: transparent; + border-radius: 0; +} +.pre-scrollable { + max-height: 340px; + overflow-y: scroll; +} +.container { + margin-right: auto; + margin-left: auto; + padding-left: 15px; + padding-right: 15px; +} +@media (min-width: 768px) { + .container { + width: 750px; + } +} +@media (min-width: 992px) { + .container { + width: 970px; + } +} +@media (min-width: 1200px) { + .container { + width: 1170px; + } +} +.container-fluid { + margin-right: auto; + margin-left: auto; + padding-left: 15px; + padding-right: 15px; +} +.row { + margin-left: -15px; + margin-right: -15px; +} +.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 { + position: relative; + min-height: 1px; + padding-left: 15px; + padding-right: 15px; +} +.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 { + float: left; +} +.col-xs-12 { + width: 100%; +} +.col-xs-11 { + width: 91.66666667%; +} +.col-xs-10 { + width: 83.33333333%; +} +.col-xs-9 { + width: 75%; +} +.col-xs-8 { + width: 66.66666667%; +} +.col-xs-7 { + width: 58.33333333%; +} +.col-xs-6 { + width: 50%; +} +.col-xs-5 { + width: 41.66666667%; +} +.col-xs-4 { + width: 33.33333333%; +} +.col-xs-3 { + width: 25%; +} +.col-xs-2 { + width: 16.66666667%; +} +.col-xs-1 { + width: 8.33333333%; +} +.col-xs-pull-12 { + right: 100%; +} +.col-xs-pull-11 { + right: 91.66666667%; +} +.col-xs-pull-10 { + right: 83.33333333%; +} +.col-xs-pull-9 { + right: 75%; +} +.col-xs-pull-8 { + right: 66.66666667%; +} +.col-xs-pull-7 { + right: 58.33333333%; +} +.col-xs-pull-6 { + right: 50%; +} +.col-xs-pull-5 { + right: 41.66666667%; +} +.col-xs-pull-4 { + right: 33.33333333%; +} +.col-xs-pull-3 { + right: 25%; +} +.col-xs-pull-2 { + right: 16.66666667%; +} +.col-xs-pull-1 { + right: 8.33333333%; +} +.col-xs-pull-0 { + right: auto; +} +.col-xs-push-12 { + left: 100%; +} +.col-xs-push-11 { + left: 91.66666667%; +} +.col-xs-push-10 { + left: 83.33333333%; +} +.col-xs-push-9 { + left: 75%; +} +.col-xs-push-8 { + left: 66.66666667%; +} +.col-xs-push-7 { + left: 58.33333333%; +} +.col-xs-push-6 { + left: 50%; +} +.col-xs-push-5 { + left: 41.66666667%; +} +.col-xs-push-4 { + left: 33.33333333%; +} +.col-xs-push-3 { + left: 25%; +} +.col-xs-push-2 { + left: 16.66666667%; +} +.col-xs-push-1 { + left: 8.33333333%; +} +.col-xs-push-0 { + left: auto; +} +.col-xs-offset-12 { + margin-left: 100%; +} +.col-xs-offset-11 { + margin-left: 91.66666667%; +} +.col-xs-offset-10 { + margin-left: 83.33333333%; +} +.col-xs-offset-9 { + margin-left: 75%; +} +.col-xs-offset-8 { + margin-left: 66.66666667%; +} +.col-xs-offset-7 { + margin-left: 58.33333333%; +} +.col-xs-offset-6 { + margin-left: 50%; +} +.col-xs-offset-5 { + margin-left: 41.66666667%; +} +.col-xs-offset-4 { + margin-left: 33.33333333%; +} +.col-xs-offset-3 { + margin-left: 25%; +} +.col-xs-offset-2 { + margin-left: 16.66666667%; +} +.col-xs-offset-1 { + margin-left: 8.33333333%; +} +.col-xs-offset-0 { + margin-left: 0%; +} +@media (min-width: 768px) { + .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 { + float: left; + } + .col-sm-12 { + width: 100%; + } + .col-sm-11 { + width: 91.66666667%; + } + .col-sm-10 { + width: 83.33333333%; + } + .col-sm-9 { + width: 75%; + } + .col-sm-8 { + width: 66.66666667%; + } + .col-sm-7 { + width: 58.33333333%; + } + .col-sm-6 { + width: 50%; + } + .col-sm-5 { + width: 41.66666667%; + } + .col-sm-4 { + width: 33.33333333%; + } + .col-sm-3 { + width: 25%; + } + .col-sm-2 { + width: 16.66666667%; + } + .col-sm-1 { + width: 8.33333333%; + } + .col-sm-pull-12 { + right: 100%; + } + .col-sm-pull-11 { + right: 91.66666667%; + } + .col-sm-pull-10 { + right: 83.33333333%; + } + .col-sm-pull-9 { + right: 75%; + } + .col-sm-pull-8 { + right: 66.66666667%; + } + .col-sm-pull-7 { + right: 58.33333333%; + } + .col-sm-pull-6 { + right: 50%; + } + .col-sm-pull-5 { + right: 41.66666667%; + } + .col-sm-pull-4 { + right: 33.33333333%; + } + .col-sm-pull-3 { + right: 25%; + } + .col-sm-pull-2 { + right: 16.66666667%; + } + .col-sm-pull-1 { + right: 8.33333333%; + } + .col-sm-pull-0 { + right: auto; + } + .col-sm-push-12 { + left: 100%; + } + .col-sm-push-11 { + left: 91.66666667%; + } + .col-sm-push-10 { + left: 83.33333333%; + } + .col-sm-push-9 { + left: 75%; + } + .col-sm-push-8 { + left: 66.66666667%; + } + .col-sm-push-7 { + left: 58.33333333%; + } + .col-sm-push-6 { + left: 50%; + } + .col-sm-push-5 { + left: 41.66666667%; + } + .col-sm-push-4 { + left: 33.33333333%; + } + .col-sm-push-3 { + left: 25%; + } + .col-sm-push-2 { + left: 16.66666667%; + } + .col-sm-push-1 { + left: 8.33333333%; + } + .col-sm-push-0 { + left: auto; + } + .col-sm-offset-12 { + margin-left: 100%; + } + .col-sm-offset-11 { + margin-left: 91.66666667%; + } + .col-sm-offset-10 { + margin-left: 83.33333333%; + } + .col-sm-offset-9 { + margin-left: 75%; + } + .col-sm-offset-8 { + margin-left: 66.66666667%; + } + .col-sm-offset-7 { + margin-left: 58.33333333%; + } + .col-sm-offset-6 { + margin-left: 50%; + } + .col-sm-offset-5 { + margin-left: 41.66666667%; + } + .col-sm-offset-4 { + margin-left: 33.33333333%; + } + .col-sm-offset-3 { + margin-left: 25%; + } + .col-sm-offset-2 { + margin-left: 16.66666667%; + } + .col-sm-offset-1 { + margin-left: 8.33333333%; + } + .col-sm-offset-0 { + margin-left: 0%; + } +} +@media (min-width: 992px) { + .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 { + float: left; + } + .col-md-12 { + width: 100%; + } + .col-md-11 { + width: 91.66666667%; + } + .col-md-10 { + width: 83.33333333%; + } + .col-md-9 { + width: 75%; + } + .col-md-8 { + width: 66.66666667%; + } + .col-md-7 { + width: 58.33333333%; + } + .col-md-6 { + width: 50%; + } + .col-md-5 { + width: 41.66666667%; + } + .col-md-4 { + width: 33.33333333%; + } + .col-md-3 { + width: 25%; + } + .col-md-2 { + width: 16.66666667%; + } + .col-md-1 { + width: 8.33333333%; + } + .col-md-pull-12 { + right: 100%; + } + .col-md-pull-11 { + right: 91.66666667%; + } + .col-md-pull-10 { + right: 83.33333333%; + } + .col-md-pull-9 { + right: 75%; + } + .col-md-pull-8 { + right: 66.66666667%; + } + .col-md-pull-7 { + right: 58.33333333%; + } + .col-md-pull-6 { + right: 50%; + } + .col-md-pull-5 { + right: 41.66666667%; + } + .col-md-pull-4 { + right: 33.33333333%; + } + .col-md-pull-3 { + right: 25%; + } + .col-md-pull-2 { + right: 16.66666667%; + } + .col-md-pull-1 { + right: 8.33333333%; + } + .col-md-pull-0 { + right: auto; + } + .col-md-push-12 { + left: 100%; + } + .col-md-push-11 { + left: 91.66666667%; + } + .col-md-push-10 { + left: 83.33333333%; + } + .col-md-push-9 { + left: 75%; + } + .col-md-push-8 { + left: 66.66666667%; + } + .col-md-push-7 { + left: 58.33333333%; + } + .col-md-push-6 { + left: 50%; + } + .col-md-push-5 { + left: 41.66666667%; + } + .col-md-push-4 { + left: 33.33333333%; + } + .col-md-push-3 { + left: 25%; + } + .col-md-push-2 { + left: 16.66666667%; + } + .col-md-push-1 { + left: 8.33333333%; + } + .col-md-push-0 { + left: auto; + } + .col-md-offset-12 { + margin-left: 100%; + } + .col-md-offset-11 { + margin-left: 91.66666667%; + } + .col-md-offset-10 { + margin-left: 83.33333333%; + } + .col-md-offset-9 { + margin-left: 75%; + } + .col-md-offset-8 { + margin-left: 66.66666667%; + } + .col-md-offset-7 { + margin-left: 58.33333333%; + } + .col-md-offset-6 { + margin-left: 50%; + } + .col-md-offset-5 { + margin-left: 41.66666667%; + } + .col-md-offset-4 { + margin-left: 33.33333333%; + } + .col-md-offset-3 { + margin-left: 25%; + } + .col-md-offset-2 { + margin-left: 16.66666667%; + } + .col-md-offset-1 { + margin-left: 8.33333333%; + } + .col-md-offset-0 { + margin-left: 0%; + } +} +@media (min-width: 1200px) { + .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 { + float: left; + } + .col-lg-12 { + width: 100%; + } + .col-lg-11 { + width: 91.66666667%; + } + .col-lg-10 { + width: 83.33333333%; + } + .col-lg-9 { + width: 75%; + } + .col-lg-8 { + width: 66.66666667%; + } + .col-lg-7 { + width: 58.33333333%; + } + .col-lg-6 { + width: 50%; + } + .col-lg-5 { + width: 41.66666667%; + } + .col-lg-4 { + width: 33.33333333%; + } + .col-lg-3 { + width: 25%; + } + .col-lg-2 { + width: 16.66666667%; + } + .col-lg-1 { + width: 8.33333333%; + } + .col-lg-pull-12 { + right: 100%; + } + .col-lg-pull-11 { + right: 91.66666667%; + } + .col-lg-pull-10 { + right: 83.33333333%; + } + .col-lg-pull-9 { + right: 75%; + } + .col-lg-pull-8 { + right: 66.66666667%; + } + .col-lg-pull-7 { + right: 58.33333333%; + } + .col-lg-pull-6 { + right: 50%; + } + .col-lg-pull-5 { + right: 41.66666667%; + } + .col-lg-pull-4 { + right: 33.33333333%; + } + .col-lg-pull-3 { + right: 25%; + } + .col-lg-pull-2 { + right: 16.66666667%; + } + .col-lg-pull-1 { + right: 8.33333333%; + } + .col-lg-pull-0 { + right: auto; + } + .col-lg-push-12 { + left: 100%; + } + .col-lg-push-11 { + left: 91.66666667%; + } + .col-lg-push-10 { + left: 83.33333333%; + } + .col-lg-push-9 { + left: 75%; + } + .col-lg-push-8 { + left: 66.66666667%; + } + .col-lg-push-7 { + left: 58.33333333%; + } + .col-lg-push-6 { + left: 50%; + } + .col-lg-push-5 { + left: 41.66666667%; + } + .col-lg-push-4 { + left: 33.33333333%; + } + .col-lg-push-3 { + left: 25%; + } + .col-lg-push-2 { + left: 16.66666667%; + } + .col-lg-push-1 { + left: 8.33333333%; + } + .col-lg-push-0 { + left: auto; + } + .col-lg-offset-12 { + margin-left: 100%; + } + .col-lg-offset-11 { + margin-left: 91.66666667%; + } + .col-lg-offset-10 { + margin-left: 83.33333333%; + } + .col-lg-offset-9 { + margin-left: 75%; + } + .col-lg-offset-8 { + margin-left: 66.66666667%; + } + .col-lg-offset-7 { + margin-left: 58.33333333%; + } + .col-lg-offset-6 { + margin-left: 50%; + } + .col-lg-offset-5 { + margin-left: 41.66666667%; + } + .col-lg-offset-4 { + margin-left: 33.33333333%; + } + .col-lg-offset-3 { + margin-left: 25%; + } + .col-lg-offset-2 { + margin-left: 16.66666667%; + } + .col-lg-offset-1 { + margin-left: 8.33333333%; + } + .col-lg-offset-0 { + margin-left: 0%; + } +} +table { + background-color: transparent; +} +th { + text-align: left; +} +.table { + width: 100%; + max-width: 100%; + margin-bottom: 22px; +} +.table > thead > tr > th, +.table > tbody > tr > th, +.table > tfoot > tr > th, +.table > thead > tr > td, +.table > tbody > tr > td, +.table > tfoot > tr > td { + padding: 8px; + line-height: 1.42857143; + vertical-align: top; + border-top: 1px solid #dddddd; +} +.table > thead > tr > th { + vertical-align: bottom; + border-bottom: 2px solid #dddddd; +} +.table > caption + thead > tr:first-child > th, +.table > colgroup + thead > tr:first-child > th, +.table > thead:first-child > tr:first-child > th, +.table > caption + thead > tr:first-child > td, +.table > colgroup + thead > tr:first-child > td, +.table > thead:first-child > tr:first-child > td { + border-top: 0; +} +.table > tbody + tbody { + border-top: 2px solid #dddddd; +} +.table .table { + background-color: #ffffff; +} +.table-condensed > thead > tr > th, +.table-condensed > tbody > tr > th, +.table-condensed > tfoot > tr > th, +.table-condensed > thead > tr > td, +.table-condensed > tbody > tr > td, +.table-condensed > tfoot > tr > td { + padding: 5px; +} +.table-bordered { + border: 1px solid #dddddd; +} +.table-bordered > thead > tr > th, +.table-bordered > tbody > tr > th, +.table-bordered > tfoot > tr > th, +.table-bordered > thead > tr > td, +.table-bordered > tbody > tr > td, +.table-bordered > tfoot > tr > td { + border: 1px solid #dddddd; +} +.table-bordered > thead > tr > th, +.table-bordered > thead > tr > td { + border-bottom-width: 2px; +} +.table-striped > tbody > tr:nth-child(odd) > td, +.table-striped > tbody > tr:nth-child(odd) > th { + background-color: #f9f9f9; +} +.table-hover > tbody > tr:hover > td, +.table-hover > tbody > tr:hover > th { + background-color: #f5f5f5; +} +table col[class*="col-"] { + position: static; + float: none; + display: table-column; +} +table td[class*="col-"], +table th[class*="col-"] { + position: static; + float: none; + display: table-cell; +} +.table > thead > tr > td.active, +.table > tbody > tr > td.active, +.table > tfoot > tr > td.active, +.table > thead > tr > th.active, +.table > tbody > tr > th.active, +.table > tfoot > tr > th.active, +.table > thead > tr.active > td, +.table > tbody > tr.active > td, +.table > tfoot > tr.active > td, +.table > thead > tr.active > th, +.table > tbody > tr.active > th, +.table > tfoot > tr.active > th { + background-color: #f5f5f5; +} +.table-hover > tbody > tr > td.active:hover, +.table-hover > tbody > tr > th.active:hover, +.table-hover > tbody > tr.active:hover > td, +.table-hover > tbody > tr:hover > .active, +.table-hover > tbody > tr.active:hover > th { + background-color: #e8e8e8; +} +.table > thead > tr > td.success, +.table > tbody > tr > td.success, +.table > tfoot > tr > td.success, +.table > thead > tr > th.success, +.table > tbody > tr > th.success, +.table > tfoot > tr > th.success, +.table > thead > tr.success > td, +.table > tbody > tr.success > td, +.table > tfoot > tr.success > td, +.table > thead > tr.success > th, +.table > tbody > tr.success > th, +.table > tfoot > tr.success > th { + background-color: #dff0d8; +} +.table-hover > tbody > tr > td.success:hover, +.table-hover > tbody > tr > th.success:hover, +.table-hover > tbody > tr.success:hover > td, +.table-hover > tbody > tr:hover > .success, +.table-hover > tbody > tr.success:hover > th { + background-color: #d0e9c6; +} +.table > thead > tr > td.info, +.table > tbody > tr > td.info, +.table > tfoot > tr > td.info, +.table > thead > tr > th.info, +.table > tbody > tr > th.info, +.table > tfoot > tr > th.info, +.table > thead > tr.info > td, +.table > tbody > tr.info > td, +.table > tfoot > tr.info > td, +.table > thead > tr.info > th, +.table > tbody > tr.info > th, +.table > tfoot > tr.info > th { + background-color: #d9edf7; +} +.table-hover > tbody > tr > td.info:hover, +.table-hover > tbody > tr > th.info:hover, +.table-hover > tbody > tr.info:hover > td, +.table-hover > tbody > tr:hover > .info, +.table-hover > tbody > tr.info:hover > th { + background-color: #c4e3f3; +} +.table > thead > tr > td.warning, +.table > tbody > tr > td.warning, +.table > tfoot > tr > td.warning, +.table > thead > tr > th.warning, +.table > tbody > tr > th.warning, +.table > tfoot > tr > th.warning, +.table > thead > tr.warning > td, +.table > tbody > tr.warning > td, +.table > tfoot > tr.warning > td, +.table > thead > tr.warning > th, +.table > tbody > tr.warning > th, +.table > tfoot > tr.warning > th { + background-color: #fcf8e3; +} +.table-hover > tbody > tr > td.warning:hover, +.table-hover > tbody > tr > th.warning:hover, +.table-hover > tbody > tr.warning:hover > td, +.table-hover > tbody > tr:hover > .warning, +.table-hover > tbody > tr.warning:hover > th { + background-color: #faf2cc; +} +.table > thead > tr > td.danger, +.table > tbody > tr > td.danger, +.table > tfoot > tr > td.danger, +.table > thead > tr > th.danger, +.table > tbody > tr > th.danger, +.table > tfoot > tr > th.danger, +.table > thead > tr.danger > td, +.table > tbody > tr.danger > td, +.table > tfoot > tr.danger > td, +.table > thead > tr.danger > th, +.table > tbody > tr.danger > th, +.table > tfoot > tr.danger > th { + background-color: #f2dede; +} +.table-hover > tbody > tr > td.danger:hover, +.table-hover > tbody > tr > th.danger:hover, +.table-hover > tbody > tr.danger:hover > td, +.table-hover > tbody > tr:hover > .danger, +.table-hover > tbody > tr.danger:hover > th { + background-color: #ebcccc; +} +@media screen and (max-width: 767px) { + .table-responsive { + width: 100%; + margin-bottom: 16.5px; + overflow-y: hidden; + overflow-x: auto; + -ms-overflow-style: -ms-autohiding-scrollbar; + border: 1px solid #dddddd; + -webkit-overflow-scrolling: touch; + } + .table-responsive > .table { + margin-bottom: 0; + } + .table-responsive > .table > thead > tr > th, + .table-responsive > .table > tbody > tr > th, + .table-responsive > .table > tfoot > tr > th, + .table-responsive > .table > thead > tr > td, + .table-responsive > .table > tbody > tr > td, + .table-responsive > .table > tfoot > tr > td { + white-space: nowrap; + } + .table-responsive > .table-bordered { + border: 0; + } + .table-responsive > .table-bordered > thead > tr > th:first-child, + .table-responsive > .table-bordered > tbody > tr > th:first-child, + .table-responsive > .table-bordered > tfoot > tr > th:first-child, + .table-responsive > .table-bordered > thead > tr > td:first-child, + .table-responsive > .table-bordered > tbody > tr > td:first-child, + .table-responsive > .table-bordered > tfoot > tr > td:first-child { + border-left: 0; + } + .table-responsive > .table-bordered > thead > tr > th:last-child, + .table-responsive > .table-bordered > tbody > tr > th:last-child, + .table-responsive > .table-bordered > tfoot > tr > th:last-child, + .table-responsive > .table-bordered > thead > tr > td:last-child, + .table-responsive > .table-bordered > tbody > tr > td:last-child, + .table-responsive > .table-bordered > tfoot > tr > td:last-child { + border-right: 0; + } + .table-responsive > .table-bordered > tbody > tr:last-child > th, + .table-responsive > .table-bordered > tfoot > tr:last-child > th, + .table-responsive > .table-bordered > tbody > tr:last-child > td, + .table-responsive > .table-bordered > tfoot > tr:last-child > td { + border-bottom: 0; + } +} +fieldset { + padding: 0; + margin: 0; + border: 0; + min-width: 0; +} +legend { + display: block; + width: 100%; + padding: 0; + margin-bottom: 22px; + font-size: 24px; + line-height: inherit; + color: #333333; + border: 0; + border-bottom: 1px solid #e5e5e5; +} +label { + display: inline-block; + max-width: 100%; + margin-bottom: 5px; + font-weight: bold; +} +input[type="search"] { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +input[type="radio"], +input[type="checkbox"] { + margin: 4px 0 0; + margin-top: 1px \9; + line-height: normal; +} +input[type="file"] { + display: block; +} +input[type="range"] { + display: block; + width: 100%; +} +select[multiple], +select[size] { + height: auto; +} +input[type="file"]:focus, +input[type="radio"]:focus, +input[type="checkbox"]:focus { + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +output { + display: block; + padding-top: 9px; + font-size: 16px; + line-height: 1.42857143; + color: #333333; +} +.form-control { + display: block; + width: 100%; + height: 40px; + padding: 8px 12px; + font-size: 16px; + line-height: 1.42857143; + color: #333333; + background-color: #ffffff; + background-image: none; + border: 1px solid #dddddd; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; + -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; + transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; +} +.form-control:focus { + border-color: #66afe9; + outline: 0; + -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6); + box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6); +} +.form-control::-moz-placeholder { + color: #b3b3b3; + opacity: 1; +} +.form-control:-ms-input-placeholder { + color: #b3b3b3; +} +.form-control::-webkit-input-placeholder { + color: #b3b3b3; +} +.form-control[disabled], +.form-control[readonly], +fieldset[disabled] .form-control { + cursor: not-allowed; + background-color: #eeeeee; + opacity: 1; +} +textarea.form-control { + height: auto; +} +input[type="search"] { + -webkit-appearance: none; +} +input[type="date"], +input[type="time"], +input[type="datetime-local"], +input[type="month"] { + line-height: 40px; + line-height: 1.42857143 \0; +} +input[type="date"].input-sm, +input[type="time"].input-sm, +input[type="datetime-local"].input-sm, +input[type="month"].input-sm { + line-height: 33px; +} +input[type="date"].input-lg, +input[type="time"].input-lg, +input[type="datetime-local"].input-lg, +input[type="month"].input-lg { + line-height: 57px; +} +.form-group { + margin-bottom: 15px; +} +.radio, +.checkbox { + position: relative; + display: block; + min-height: 22px; + margin-top: 10px; + margin-bottom: 10px; +} +.radio label, +.checkbox label { + padding-left: 20px; + margin-bottom: 0; + font-weight: normal; + cursor: pointer; +} +.radio input[type="radio"], +.radio-inline input[type="radio"], +.checkbox input[type="checkbox"], +.checkbox-inline input[type="checkbox"] { + position: absolute; + margin-left: -20px; + margin-top: 4px \9; +} +.radio + .radio, +.checkbox + .checkbox { + margin-top: -5px; +} +.radio-inline, +.checkbox-inline { + display: inline-block; + padding-left: 20px; + margin-bottom: 0; + vertical-align: middle; + font-weight: normal; + cursor: pointer; +} +.radio-inline + .radio-inline, +.checkbox-inline + .checkbox-inline { + margin-top: 0; + margin-left: 10px; +} +input[type="radio"][disabled], +input[type="checkbox"][disabled], +input[type="radio"].disabled, +input[type="checkbox"].disabled, +fieldset[disabled] input[type="radio"], +fieldset[disabled] input[type="checkbox"] { + cursor: not-allowed; +} +.radio-inline.disabled, +.checkbox-inline.disabled, +fieldset[disabled] .radio-inline, +fieldset[disabled] .checkbox-inline { + cursor: not-allowed; +} +.radio.disabled label, +.checkbox.disabled label, +fieldset[disabled] .radio label, +fieldset[disabled] .checkbox label { + cursor: not-allowed; +} +.form-control-static { + padding-top: 9px; + padding-bottom: 9px; + margin-bottom: 0; +} +.form-control-static.input-lg, +.form-control-static.input-sm { + padding-left: 0; + padding-right: 0; +} +.input-sm, +.form-horizontal .form-group-sm .form-control { + height: 33px; + padding: 5px 10px; + font-size: 14px; + line-height: 1.5; + border-radius: 3px; +} +select.input-sm { + height: 33px; + line-height: 33px; +} +textarea.input-sm, +select[multiple].input-sm { + height: auto; +} +.input-lg, +.form-horizontal .form-group-lg .form-control { + height: 57px; + padding: 14px 16px; + font-size: 20px; + line-height: 1.33; + border-radius: 6px; +} +select.input-lg { + height: 57px; + line-height: 57px; +} +textarea.input-lg, +select[multiple].input-lg { + height: auto; +} +.has-feedback { + position: relative; +} +.has-feedback .form-control { + padding-right: 50px; +} +.form-control-feedback { + position: absolute; + top: 27px; + right: 0; + z-index: 2; + display: block; + width: 40px; + height: 40px; + line-height: 40px; + text-align: center; +} +.input-lg + .form-control-feedback { + width: 57px; + height: 57px; + line-height: 57px; +} +.input-sm + .form-control-feedback { + width: 33px; + height: 33px; + line-height: 33px; +} +.has-success .help-block, +.has-success .control-label, +.has-success .radio, +.has-success .checkbox, +.has-success .radio-inline, +.has-success .checkbox-inline { + color: #3fad46; +} +.has-success .form-control { + border-color: #3fad46; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} +.has-success .form-control:focus { + border-color: #318837; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #81d186; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #81d186; +} +.has-success .input-group-addon { + color: #3fad46; + border-color: #3fad46; + background-color: #dff0d8; +} +.has-success .form-control-feedback { + color: #3fad46; +} +.has-warning .help-block, +.has-warning .control-label, +.has-warning .radio, +.has-warning .checkbox, +.has-warning .radio-inline, +.has-warning .checkbox-inline { + color: #f0ad4e; +} +.has-warning .form-control { + border-color: #f0ad4e; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} +.has-warning .form-control:focus { + border-color: #ec971f; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #f8d9ac; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #f8d9ac; +} +.has-warning .input-group-addon { + color: #f0ad4e; + border-color: #f0ad4e; + background-color: #fcf8e3; +} +.has-warning .form-control-feedback { + color: #f0ad4e; +} +.has-error .help-block, +.has-error .control-label, +.has-error .radio, +.has-error .checkbox, +.has-error .radio-inline, +.has-error .checkbox-inline { + color: #d9534f; +} +.has-error .form-control { + border-color: #d9534f; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} +.has-error .form-control:focus { + border-color: #c9302c; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #eba5a3; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #eba5a3; +} +.has-error .input-group-addon { + color: #d9534f; + border-color: #d9534f; + background-color: #f2dede; +} +.has-error .form-control-feedback { + color: #d9534f; +} +.has-feedback label.sr-only ~ .form-control-feedback { + top: 0; +} +.help-block { + display: block; + margin-top: 5px; + margin-bottom: 10px; + color: #737373; +} +@media (min-width: 768px) { + .form-inline .form-group { + display: inline-block; + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .form-control { + display: inline-block; + width: auto; + vertical-align: middle; + } + .form-inline .input-group { + display: inline-table; + vertical-align: middle; + } + .form-inline .input-group .input-group-addon, + .form-inline .input-group .input-group-btn, + .form-inline .input-group .form-control { + width: auto; + } + .form-inline .input-group > .form-control { + width: 100%; + } + .form-inline .control-label { + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .radio, + .form-inline .checkbox { + display: inline-block; + margin-top: 0; + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .radio label, + .form-inline .checkbox label { + padding-left: 0; + } + .form-inline .radio input[type="radio"], + .form-inline .checkbox input[type="checkbox"] { + position: relative; + margin-left: 0; + } + .form-inline .has-feedback .form-control-feedback { + top: 0; + } +} +.form-horizontal .radio, +.form-horizontal .checkbox, +.form-horizontal .radio-inline, +.form-horizontal .checkbox-inline { + margin-top: 0; + margin-bottom: 0; + padding-top: 9px; +} +.form-horizontal .radio, +.form-horizontal .checkbox { + min-height: 31px; +} +.form-horizontal .form-group { + margin-left: -15px; + margin-right: -15px; +} +@media (min-width: 768px) { + .form-horizontal .control-label { + text-align: right; + margin-bottom: 0; + padding-top: 9px; + } +} +.form-horizontal .has-feedback .form-control-feedback { + top: 0; + right: 15px; +} +@media (min-width: 768px) { + .form-horizontal .form-group-lg .control-label { + padding-top: 19.62px; + } +} +@media (min-width: 768px) { + .form-horizontal .form-group-sm .control-label { + padding-top: 6px; + } +} +.btn { + display: inline-block; + margin-bottom: 0; + font-weight: normal; + text-align: center; + vertical-align: middle; + cursor: pointer; + background-image: none; + border: 1px solid transparent; + white-space: nowrap; + padding: 8px 12px; + font-size: 16px; + line-height: 1.42857143; + border-radius: 4px; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} +.btn:focus, +.btn:active:focus, +.btn.active:focus { + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +.btn:hover, +.btn:focus { + color: #333333; + text-decoration: none; +} +.btn:active, +.btn.active { + outline: 0; + background-image: none; + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); +} +.btn.disabled, +.btn[disabled], +fieldset[disabled] .btn { + cursor: not-allowed; + pointer-events: none; + opacity: 0.65; + filter: alpha(opacity=65); + -webkit-box-shadow: none; + box-shadow: none; +} +.btn-default { + color: #333333; + background-color: #ffffff; + border-color: #dddddd; +} +.btn-default:hover, +.btn-default:focus, +.btn-default:active, +.btn-default.active, +.open > .dropdown-toggle.btn-default { + color: #333333; + background-color: #e6e6e6; + border-color: #bebebe; +} +.btn-default:active, +.btn-default.active, +.open > .dropdown-toggle.btn-default { + background-image: none; +} +.btn-default.disabled, +.btn-default[disabled], +fieldset[disabled] .btn-default, +.btn-default.disabled:hover, +.btn-default[disabled]:hover, +fieldset[disabled] .btn-default:hover, +.btn-default.disabled:focus, +.btn-default[disabled]:focus, +fieldset[disabled] .btn-default:focus, +.btn-default.disabled:active, +.btn-default[disabled]:active, +fieldset[disabled] .btn-default:active, +.btn-default.disabled.active, +.btn-default[disabled].active, +fieldset[disabled] .btn-default.active { + background-color: #ffffff; + border-color: #dddddd; +} +.btn-default .badge { + color: #ffffff; + background-color: #333333; +} +.btn-primary { + color: #ffffff; + background-color: #4582ec; + border-color: #4582ec; +} +.btn-primary:hover, +.btn-primary:focus, +.btn-primary:active, +.btn-primary.active, +.open > .dropdown-toggle.btn-primary { + color: #ffffff; + background-color: #1863e6; + border-color: #175fdd; +} +.btn-primary:active, +.btn-primary.active, +.open > .dropdown-toggle.btn-primary { + background-image: none; +} +.btn-primary.disabled, +.btn-primary[disabled], +fieldset[disabled] .btn-primary, +.btn-primary.disabled:hover, +.btn-primary[disabled]:hover, +fieldset[disabled] .btn-primary:hover, +.btn-primary.disabled:focus, +.btn-primary[disabled]:focus, +fieldset[disabled] .btn-primary:focus, +.btn-primary.disabled:active, +.btn-primary[disabled]:active, +fieldset[disabled] .btn-primary:active, +.btn-primary.disabled.active, +.btn-primary[disabled].active, +fieldset[disabled] .btn-primary.active { + background-color: #4582ec; + border-color: #4582ec; +} +.btn-primary .badge { + color: #4582ec; + background-color: #ffffff; +} +.btn-success { + color: #ffffff; + background-color: #3fad46; + border-color: #3fad46; +} +.btn-success:hover, +.btn-success:focus, +.btn-success:active, +.btn-success.active, +.open > .dropdown-toggle.btn-success { + color: #ffffff; + background-color: #318837; + border-color: #2f8034; +} +.btn-success:active, +.btn-success.active, +.open > .dropdown-toggle.btn-success { + background-image: none; +} +.btn-success.disabled, +.btn-success[disabled], +fieldset[disabled] .btn-success, +.btn-success.disabled:hover, +.btn-success[disabled]:hover, +fieldset[disabled] .btn-success:hover, +.btn-success.disabled:focus, +.btn-success[disabled]:focus, +fieldset[disabled] .btn-success:focus, +.btn-success.disabled:active, +.btn-success[disabled]:active, +fieldset[disabled] .btn-success:active, +.btn-success.disabled.active, +.btn-success[disabled].active, +fieldset[disabled] .btn-success.active { + background-color: #3fad46; + border-color: #3fad46; +} +.btn-success .badge { + color: #3fad46; + background-color: #ffffff; +} +.btn-info { + color: #ffffff; + background-color: #5bc0de; + border-color: #5bc0de; +} +.btn-info:hover, +.btn-info:focus, +.btn-info:active, +.btn-info.active, +.open > .dropdown-toggle.btn-info { + color: #ffffff; + background-color: #31b0d5; + border-color: #2aabd2; +} +.btn-info:active, +.btn-info.active, +.open > .dropdown-toggle.btn-info { + background-image: none; +} +.btn-info.disabled, +.btn-info[disabled], +fieldset[disabled] .btn-info, +.btn-info.disabled:hover, +.btn-info[disabled]:hover, +fieldset[disabled] .btn-info:hover, +.btn-info.disabled:focus, +.btn-info[disabled]:focus, +fieldset[disabled] .btn-info:focus, +.btn-info.disabled:active, +.btn-info[disabled]:active, +fieldset[disabled] .btn-info:active, +.btn-info.disabled.active, +.btn-info[disabled].active, +fieldset[disabled] .btn-info.active { + background-color: #5bc0de; + border-color: #5bc0de; +} +.btn-info .badge { + color: #5bc0de; + background-color: #ffffff; +} +.btn-warning { + color: #ffffff; + background-color: #f0ad4e; + border-color: #f0ad4e; +} +.btn-warning:hover, +.btn-warning:focus, +.btn-warning:active, +.btn-warning.active, +.open > .dropdown-toggle.btn-warning { + color: #ffffff; + background-color: #ec971f; + border-color: #eb9316; +} +.btn-warning:active, +.btn-warning.active, +.open > .dropdown-toggle.btn-warning { + background-image: none; +} +.btn-warning.disabled, +.btn-warning[disabled], +fieldset[disabled] .btn-warning, +.btn-warning.disabled:hover, +.btn-warning[disabled]:hover, +fieldset[disabled] .btn-warning:hover, +.btn-warning.disabled:focus, +.btn-warning[disabled]:focus, +fieldset[disabled] .btn-warning:focus, +.btn-warning.disabled:active, +.btn-warning[disabled]:active, +fieldset[disabled] .btn-warning:active, +.btn-warning.disabled.active, +.btn-warning[disabled].active, +fieldset[disabled] .btn-warning.active { + background-color: #f0ad4e; + border-color: #f0ad4e; +} +.btn-warning .badge { + color: #f0ad4e; + background-color: #ffffff; +} +.btn-danger { + color: #ffffff; + background-color: #d9534f; + border-color: #d9534f; +} +.btn-danger:hover, +.btn-danger:focus, +.btn-danger:active, +.btn-danger.active, +.open > .dropdown-toggle.btn-danger { + color: #ffffff; + background-color: #c9302c; + border-color: #c12e2a; +} +.btn-danger:active, +.btn-danger.active, +.open > .dropdown-toggle.btn-danger { + background-image: none; +} +.btn-danger.disabled, +.btn-danger[disabled], +fieldset[disabled] .btn-danger, +.btn-danger.disabled:hover, +.btn-danger[disabled]:hover, +fieldset[disabled] .btn-danger:hover, +.btn-danger.disabled:focus, +.btn-danger[disabled]:focus, +fieldset[disabled] .btn-danger:focus, +.btn-danger.disabled:active, +.btn-danger[disabled]:active, +fieldset[disabled] .btn-danger:active, +.btn-danger.disabled.active, +.btn-danger[disabled].active, +fieldset[disabled] .btn-danger.active { + background-color: #d9534f; + border-color: #d9534f; +} +.btn-danger .badge { + color: #d9534f; + background-color: #ffffff; +} +.btn-link { + color: #4582ec; + font-weight: normal; + cursor: pointer; + border-radius: 0; +} +.btn-link, +.btn-link:active, +.btn-link[disabled], +fieldset[disabled] .btn-link { + background-color: transparent; + -webkit-box-shadow: none; + box-shadow: none; +} +.btn-link, +.btn-link:hover, +.btn-link:focus, +.btn-link:active { + border-color: transparent; +} +.btn-link:hover, +.btn-link:focus { + color: #134fb8; + text-decoration: underline; + background-color: transparent; +} +.btn-link[disabled]:hover, +fieldset[disabled] .btn-link:hover, +.btn-link[disabled]:focus, +fieldset[disabled] .btn-link:focus { + color: #b3b3b3; + text-decoration: none; +} +.btn-lg, +.btn-group-lg > .btn { + padding: 14px 16px; + font-size: 20px; + line-height: 1.33; + border-radius: 6px; +} +.btn-sm, +.btn-group-sm > .btn { + padding: 5px 10px; + font-size: 14px; + line-height: 1.5; + border-radius: 3px; +} +.btn-xs, +.btn-group-xs > .btn { + padding: 1px 5px; + font-size: 14px; + line-height: 1.5; + border-radius: 3px; +} +.btn-block { + display: block; + width: 100%; +} +.btn-block + .btn-block { + margin-top: 5px; +} +input[type="submit"].btn-block, +input[type="reset"].btn-block, +input[type="button"].btn-block { + width: 100%; +} +.fade { + opacity: 0; + -webkit-transition: opacity 0.15s linear; + -o-transition: opacity 0.15s linear; + transition: opacity 0.15s linear; +} +.fade.in { + opacity: 1; +} +.collapse { + display: none; +} +.collapse.in { + display: block; +} +tr.collapse.in { + display: table-row; +} +tbody.collapse.in { + display: table-row-group; +} +.collapsing { + position: relative; + height: 0; + overflow: hidden; + -webkit-transition: height 0.35s ease; + -o-transition: height 0.35s ease; + transition: height 0.35s ease; +} +.caret { + display: inline-block; + width: 0; + height: 0; + margin-left: 2px; + vertical-align: middle; + border-top: 4px solid; + border-right: 4px solid transparent; + border-left: 4px solid transparent; +} +.dropdown { + position: relative; +} +.dropdown-toggle:focus { + outline: 0; +} +.dropdown-menu { + position: absolute; + top: 100%; + left: 0; + z-index: 1000; + display: none; + float: left; + min-width: 160px; + padding: 5px 0; + margin: 2px 0 0; + list-style: none; + font-size: 16px; + text-align: left; + background-color: #ffffff; + border: 1px solid #cccccc; + border: 1px solid rgba(0, 0, 0, 0.15); + border-radius: 4px; + -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); + box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); + background-clip: padding-box; +} +.dropdown-menu.pull-right { + right: 0; + left: auto; +} +.dropdown-menu .divider { + height: 1px; + margin: 10px 0; + overflow: hidden; + background-color: #e5e5e5; +} +.dropdown-menu > li > a { + display: block; + padding: 3px 20px; + clear: both; + font-weight: normal; + line-height: 1.42857143; + color: #333333; + white-space: nowrap; +} +.dropdown-menu > li > a:hover, +.dropdown-menu > li > a:focus { + text-decoration: none; + color: #ffffff; + background-color: #4582ec; +} +.dropdown-menu > .active > a, +.dropdown-menu > .active > a:hover, +.dropdown-menu > .active > a:focus { + color: #ffffff; + text-decoration: none; + outline: 0; + background-color: #4582ec; +} +.dropdown-menu > .disabled > a, +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + color: #b3b3b3; +} +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + text-decoration: none; + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + cursor: not-allowed; +} +.open > .dropdown-menu { + display: block; +} +.open > a { + outline: 0; +} +.dropdown-menu-right { + left: auto; + right: 0; +} +.dropdown-menu-left { + left: 0; + right: auto; +} +.dropdown-header { + display: block; + padding: 3px 20px; + font-size: 14px; + line-height: 1.42857143; + color: #b3b3b3; + white-space: nowrap; +} +.dropdown-backdrop { + position: fixed; + left: 0; + right: 0; + bottom: 0; + top: 0; + z-index: 990; +} +.pull-right > .dropdown-menu { + right: 0; + left: auto; +} +.dropup .caret, +.navbar-fixed-bottom .dropdown .caret { + border-top: 0; + border-bottom: 4px solid; + content: ""; +} +.dropup .dropdown-menu, +.navbar-fixed-bottom .dropdown .dropdown-menu { + top: auto; + bottom: 100%; + margin-bottom: 1px; +} +@media (min-width: 768px) { + .navbar-right .dropdown-menu { + left: auto; + right: 0; + } + .navbar-right .dropdown-menu-left { + left: 0; + right: auto; + } +} +.btn-group, +.btn-group-vertical { + position: relative; + display: inline-block; + vertical-align: middle; +} +.btn-group > .btn, +.btn-group-vertical > .btn { + position: relative; + float: left; +} +.btn-group > .btn:hover, +.btn-group-vertical > .btn:hover, +.btn-group > .btn:focus, +.btn-group-vertical > .btn:focus, +.btn-group > .btn:active, +.btn-group-vertical > .btn:active, +.btn-group > .btn.active, +.btn-group-vertical > .btn.active { + z-index: 2; +} +.btn-group > .btn:focus, +.btn-group-vertical > .btn:focus { + outline: 0; +} +.btn-group .btn + .btn, +.btn-group .btn + .btn-group, +.btn-group .btn-group + .btn, +.btn-group .btn-group + .btn-group { + margin-left: -1px; +} +.btn-toolbar { + margin-left: -5px; +} +.btn-toolbar .btn-group, +.btn-toolbar .input-group { + float: left; +} +.btn-toolbar > .btn, +.btn-toolbar > .btn-group, +.btn-toolbar > .input-group { + margin-left: 5px; +} +.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) { + border-radius: 0; +} +.btn-group > .btn:first-child { + margin-left: 0; +} +.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) { + border-bottom-right-radius: 0; + border-top-right-radius: 0; +} +.btn-group > .btn:last-child:not(:first-child), +.btn-group > .dropdown-toggle:not(:first-child) { + border-bottom-left-radius: 0; + border-top-left-radius: 0; +} +.btn-group > .btn-group { + float: left; +} +.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn { + border-radius: 0; +} +.btn-group > .btn-group:first-child > .btn:last-child, +.btn-group > .btn-group:first-child > .dropdown-toggle { + border-bottom-right-radius: 0; + border-top-right-radius: 0; +} +.btn-group > .btn-group:last-child > .btn:first-child { + border-bottom-left-radius: 0; + border-top-left-radius: 0; +} +.btn-group .dropdown-toggle:active, +.btn-group.open .dropdown-toggle { + outline: 0; +} +.btn-group > .btn + .dropdown-toggle { + padding-left: 8px; + padding-right: 8px; +} +.btn-group > .btn-lg + .dropdown-toggle { + padding-left: 12px; + padding-right: 12px; +} +.btn-group.open .dropdown-toggle { + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); +} +.btn-group.open .dropdown-toggle.btn-link { + -webkit-box-shadow: none; + box-shadow: none; +} +.btn .caret { + margin-left: 0; +} +.btn-lg .caret { + border-width: 5px 5px 0; + border-bottom-width: 0; +} +.dropup .btn-lg .caret { + border-width: 0 5px 5px; +} +.btn-group-vertical > .btn, +.btn-group-vertical > .btn-group, +.btn-group-vertical > .btn-group > .btn { + display: block; + float: none; + width: 100%; + max-width: 100%; +} +.btn-group-vertical > .btn-group > .btn { + float: none; +} +.btn-group-vertical > .btn + .btn, +.btn-group-vertical > .btn + .btn-group, +.btn-group-vertical > .btn-group + .btn, +.btn-group-vertical > .btn-group + .btn-group { + margin-top: -1px; + margin-left: 0; +} +.btn-group-vertical > .btn:not(:first-child):not(:last-child) { + border-radius: 0; +} +.btn-group-vertical > .btn:first-child:not(:last-child) { + border-top-right-radius: 4px; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group-vertical > .btn:last-child:not(:first-child) { + border-bottom-left-radius: 4px; + border-top-right-radius: 0; + border-top-left-radius: 0; +} +.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn { + border-radius: 0; +} +.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child, +.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child { + border-top-right-radius: 0; + border-top-left-radius: 0; +} +.btn-group-justified { + display: table; + width: 100%; + table-layout: fixed; + border-collapse: separate; +} +.btn-group-justified > .btn, +.btn-group-justified > .btn-group { + float: none; + display: table-cell; + width: 1%; +} +.btn-group-justified > .btn-group .btn { + width: 100%; +} +.btn-group-justified > .btn-group .dropdown-menu { + left: auto; +} +[data-toggle="buttons"] > .btn > input[type="radio"], +[data-toggle="buttons"] > .btn > input[type="checkbox"] { + position: absolute; + z-index: -1; + opacity: 0; + filter: alpha(opacity=0); +} +.input-group { + position: relative; + display: table; + border-collapse: separate; +} +.input-group[class*="col-"] { + float: none; + padding-left: 0; + padding-right: 0; +} +.input-group .form-control { + position: relative; + z-index: 2; + float: left; + width: 100%; + margin-bottom: 0; +} +.input-group-lg > .form-control, +.input-group-lg > .input-group-addon, +.input-group-lg > .input-group-btn > .btn { + height: 57px; + padding: 14px 16px; + font-size: 20px; + line-height: 1.33; + border-radius: 6px; +} +select.input-group-lg > .form-control, +select.input-group-lg > .input-group-addon, +select.input-group-lg > .input-group-btn > .btn { + height: 57px; + line-height: 57px; +} +textarea.input-group-lg > .form-control, +textarea.input-group-lg > .input-group-addon, +textarea.input-group-lg > .input-group-btn > .btn, +select[multiple].input-group-lg > .form-control, +select[multiple].input-group-lg > .input-group-addon, +select[multiple].input-group-lg > .input-group-btn > .btn { + height: auto; +} +.input-group-sm > .form-control, +.input-group-sm > .input-group-addon, +.input-group-sm > .input-group-btn > .btn { + height: 33px; + padding: 5px 10px; + font-size: 14px; + line-height: 1.5; + border-radius: 3px; +} +select.input-group-sm > .form-control, +select.input-group-sm > .input-group-addon, +select.input-group-sm > .input-group-btn > .btn { + height: 33px; + line-height: 33px; +} +textarea.input-group-sm > .form-control, +textarea.input-group-sm > .input-group-addon, +textarea.input-group-sm > .input-group-btn > .btn, +select[multiple].input-group-sm > .form-control, +select[multiple].input-group-sm > .input-group-addon, +select[multiple].input-group-sm > .input-group-btn > .btn { + height: auto; +} +.input-group-addon, +.input-group-btn, +.input-group .form-control { + display: table-cell; +} +.input-group-addon:not(:first-child):not(:last-child), +.input-group-btn:not(:first-child):not(:last-child), +.input-group .form-control:not(:first-child):not(:last-child) { + border-radius: 0; +} +.input-group-addon, +.input-group-btn { + width: 1%; + white-space: nowrap; + vertical-align: middle; +} +.input-group-addon { + padding: 8px 12px; + font-size: 16px; + font-weight: normal; + line-height: 1; + color: #333333; + text-align: center; + background-color: #eeeeee; + border: 1px solid #dddddd; + border-radius: 4px; +} +.input-group-addon.input-sm { + padding: 5px 10px; + font-size: 14px; + border-radius: 3px; +} +.input-group-addon.input-lg { + padding: 14px 16px; + font-size: 20px; + border-radius: 6px; +} +.input-group-addon input[type="radio"], +.input-group-addon input[type="checkbox"] { + margin-top: 0; +} +.input-group .form-control:first-child, +.input-group-addon:first-child, +.input-group-btn:first-child > .btn, +.input-group-btn:first-child > .btn-group > .btn, +.input-group-btn:first-child > .dropdown-toggle, +.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle), +.input-group-btn:last-child > .btn-group:not(:last-child) > .btn { + border-bottom-right-radius: 0; + border-top-right-radius: 0; +} +.input-group-addon:first-child { + border-right: 0; +} +.input-group .form-control:last-child, +.input-group-addon:last-child, +.input-group-btn:last-child > .btn, +.input-group-btn:last-child > .btn-group > .btn, +.input-group-btn:last-child > .dropdown-toggle, +.input-group-btn:first-child > .btn:not(:first-child), +.input-group-btn:first-child > .btn-group:not(:first-child) > .btn { + border-bottom-left-radius: 0; + border-top-left-radius: 0; +} +.input-group-addon:last-child { + border-left: 0; +} +.input-group-btn { + position: relative; + font-size: 0; + white-space: nowrap; +} +.input-group-btn > .btn { + position: relative; +} +.input-group-btn > .btn + .btn { + margin-left: -1px; +} +.input-group-btn > .btn:hover, +.input-group-btn > .btn:focus, +.input-group-btn > .btn:active { + z-index: 2; +} +.input-group-btn:first-child > .btn, +.input-group-btn:first-child > .btn-group { + margin-right: -1px; +} +.input-group-btn:last-child > .btn, +.input-group-btn:last-child > .btn-group { + margin-left: -1px; +} +.nav { + margin-bottom: 0; + padding-left: 0; + list-style: none; +} +.nav > li { + position: relative; + display: block; +} +.nav > li > a { + position: relative; + display: block; + padding: 10px 15px; +} +.nav > li > a:hover, +.nav > li > a:focus { + text-decoration: none; + background-color: #eeeeee; +} +.nav > li.disabled > a { + color: #b3b3b3; +} +.nav > li.disabled > a:hover, +.nav > li.disabled > a:focus { + color: #b3b3b3; + text-decoration: none; + background-color: transparent; + cursor: not-allowed; +} +.nav .open > a, +.nav .open > a:hover, +.nav .open > a:focus { + background-color: #eeeeee; + border-color: #4582ec; +} +.nav .nav-divider { + height: 1px; + margin: 10px 0; + overflow: hidden; + background-color: #e5e5e5; +} +.nav > li > a > img { + max-width: none; +} +.nav-tabs { + border-bottom: 1px solid #dddddd; +} +.nav-tabs > li { + float: left; + margin-bottom: -1px; +} +.nav-tabs > li > a { + margin-right: 2px; + line-height: 1.42857143; + border: 1px solid transparent; + border-radius: 4px 4px 0 0; +} +.nav-tabs > li > a:hover { + border-color: #eeeeee #eeeeee #dddddd; +} +.nav-tabs > li.active > a, +.nav-tabs > li.active > a:hover, +.nav-tabs > li.active > a:focus { + color: #555555; + background-color: #ffffff; + border: 1px solid #dddddd; + border-bottom-color: transparent; + cursor: default; +} +.nav-tabs.nav-justified { + width: 100%; + border-bottom: 0; +} +.nav-tabs.nav-justified > li { + float: none; +} +.nav-tabs.nav-justified > li > a { + text-align: center; + margin-bottom: 5px; +} +.nav-tabs.nav-justified > .dropdown .dropdown-menu { + top: auto; + left: auto; +} +@media (min-width: 768px) { + .nav-tabs.nav-justified > li { + display: table-cell; + width: 1%; + } + .nav-tabs.nav-justified > li > a { + margin-bottom: 0; + } +} +.nav-tabs.nav-justified > li > a { + margin-right: 0; + border-radius: 4px; +} +.nav-tabs.nav-justified > .active > a, +.nav-tabs.nav-justified > .active > a:hover, +.nav-tabs.nav-justified > .active > a:focus { + border: 1px solid #dddddd; +} +@media (min-width: 768px) { + .nav-tabs.nav-justified > li > a { + border-bottom: 1px solid #dddddd; + border-radius: 4px 4px 0 0; + } + .nav-tabs.nav-justified > .active > a, + .nav-tabs.nav-justified > .active > a:hover, + .nav-tabs.nav-justified > .active > a:focus { + border-bottom-color: #ffffff; + } +} +.nav-pills > li { + float: left; +} +.nav-pills > li > a { + border-radius: 4px; +} +.nav-pills > li + li { + margin-left: 2px; +} +.nav-pills > li.active > a, +.nav-pills > li.active > a:hover, +.nav-pills > li.active > a:focus { + color: #ffffff; + background-color: #4582ec; +} +.nav-stacked > li { + float: none; +} +.nav-stacked > li + li { + margin-top: 2px; + margin-left: 0; +} +.nav-justified { + width: 100%; +} +.nav-justified > li { + float: none; +} +.nav-justified > li > a { + text-align: center; + margin-bottom: 5px; +} +.nav-justified > .dropdown .dropdown-menu { + top: auto; + left: auto; +} +@media (min-width: 768px) { + .nav-justified > li { + display: table-cell; + width: 1%; + } + .nav-justified > li > a { + margin-bottom: 0; + } +} +.nav-tabs-justified { + border-bottom: 0; +} +.nav-tabs-justified > li > a { + margin-right: 0; + border-radius: 4px; +} +.nav-tabs-justified > .active > a, +.nav-tabs-justified > .active > a:hover, +.nav-tabs-justified > .active > a:focus { + border: 1px solid #dddddd; +} +@media (min-width: 768px) { + .nav-tabs-justified > li > a { + border-bottom: 1px solid #dddddd; + border-radius: 4px 4px 0 0; + } + .nav-tabs-justified > .active > a, + .nav-tabs-justified > .active > a:hover, + .nav-tabs-justified > .active > a:focus { + border-bottom-color: #ffffff; + } +} +.tab-content > .tab-pane { + display: none; +} +.tab-content > .active { + display: block; +} +.nav-tabs .dropdown-menu { + margin-top: -1px; + border-top-right-radius: 0; + border-top-left-radius: 0; +} +.navbar { + position: relative; + min-height: 65px; + margin-bottom: 22px; + border: 1px solid transparent; +} +@media (min-width: 768px) { + .navbar { + border-radius: 4px; + } +} +@media (min-width: 768px) { + .navbar-header { + float: left; + } +} +.navbar-collapse { + overflow-x: visible; + padding-right: 15px; + padding-left: 15px; + border-top: 1px solid transparent; + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1); + -webkit-overflow-scrolling: touch; +} +.navbar-collapse.in { + overflow-y: auto; +} +@media (min-width: 768px) { + .navbar-collapse { + width: auto; + border-top: 0; + box-shadow: none; + } + .navbar-collapse.collapse { + display: block !important; + height: auto !important; + padding-bottom: 0; + overflow: visible !important; + } + .navbar-collapse.in { + overflow-y: visible; + } + .navbar-fixed-top .navbar-collapse, + .navbar-static-top .navbar-collapse, + .navbar-fixed-bottom .navbar-collapse { + padding-left: 0; + padding-right: 0; + } +} +.navbar-fixed-top .navbar-collapse, +.navbar-fixed-bottom .navbar-collapse { + max-height: 340px; +} +@media (max-width: 480px) and (orientation: landscape) { + .navbar-fixed-top .navbar-collapse, + .navbar-fixed-bottom .navbar-collapse { + max-height: 200px; + } +} +.container > .navbar-header, +.container-fluid > .navbar-header, +.container > .navbar-collapse, +.container-fluid > .navbar-collapse { + margin-right: -15px; + margin-left: -15px; +} +@media (min-width: 768px) { + .container > .navbar-header, + .container-fluid > .navbar-header, + .container > .navbar-collapse, + .container-fluid > .navbar-collapse { + margin-right: 0; + margin-left: 0; + } +} +.navbar-static-top { + z-index: 1000; + border-width: 0 0 1px; +} +@media (min-width: 768px) { + .navbar-static-top { + border-radius: 0; + } +} +.navbar-fixed-top, +.navbar-fixed-bottom { + position: fixed; + right: 0; + left: 0; + z-index: 1030; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); +} +@media (min-width: 768px) { + .navbar-fixed-top, + .navbar-fixed-bottom { + border-radius: 0; + } +} +.navbar-fixed-top { + top: 0; + border-width: 0 0 1px; +} +.navbar-fixed-bottom { + bottom: 0; + margin-bottom: 0; + border-width: 1px 0 0; +} +.navbar-brand { + float: left; + padding: 21.5px 15px; + font-size: 20px; + line-height: 22px; + height: 65px; +} +.navbar-brand:hover, +.navbar-brand:focus { + text-decoration: none; +} +@media (min-width: 768px) { + .navbar > .container .navbar-brand, + .navbar > .container-fluid .navbar-brand { + margin-left: -15px; + } +} +.navbar-toggle { + position: relative; + float: right; + margin-right: 15px; + padding: 9px 10px; + margin-top: 15.5px; + margin-bottom: 15.5px; + background-color: transparent; + background-image: none; + border: 1px solid transparent; + border-radius: 4px; +} +.navbar-toggle:focus { + outline: 0; +} +.navbar-toggle .icon-bar { + display: block; + width: 22px; + height: 2px; + border-radius: 1px; +} +.navbar-toggle .icon-bar + .icon-bar { + margin-top: 4px; +} +@media (min-width: 768px) { + .navbar-toggle { + display: none; + } +} +.navbar-nav { + margin: 10.75px -15px; +} +.navbar-nav > li > a { + padding-top: 10px; + padding-bottom: 10px; + line-height: 22px; +} +@media (max-width: 767px) { + .navbar-nav .open .dropdown-menu { + position: static; + float: none; + width: auto; + margin-top: 0; + background-color: transparent; + border: 0; + box-shadow: none; + } + .navbar-nav .open .dropdown-menu > li > a, + .navbar-nav .open .dropdown-menu .dropdown-header { + padding: 5px 15px 5px 25px; + } + .navbar-nav .open .dropdown-menu > li > a { + line-height: 22px; + } + .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-nav .open .dropdown-menu > li > a:focus { + background-image: none; + } +} +@media (min-width: 768px) { + .navbar-nav { + float: left; + margin: 0; + } + .navbar-nav > li { + float: left; + } + .navbar-nav > li > a { + padding-top: 21.5px; + padding-bottom: 21.5px; + } + .navbar-nav.navbar-right:last-child { + margin-right: -15px; + } +} +@media (min-width: 768px) { + .navbar-left { + float: left !important; + } + .navbar-right { + float: right !important; + } +} +.navbar-form { + margin-left: -15px; + margin-right: -15px; + padding: 10px 15px; + border-top: 1px solid transparent; + border-bottom: 1px solid transparent; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); + margin-top: 12.5px; + margin-bottom: 12.5px; +} +@media (min-width: 768px) { + .navbar-form .form-group { + display: inline-block; + margin-bottom: 0; + vertical-align: middle; + } + .navbar-form .form-control { + display: inline-block; + width: auto; + vertical-align: middle; + } + .navbar-form .input-group { + display: inline-table; + vertical-align: middle; + } + .navbar-form .input-group .input-group-addon, + .navbar-form .input-group .input-group-btn, + .navbar-form .input-group .form-control { + width: auto; + } + .navbar-form .input-group > .form-control { + width: 100%; + } + .navbar-form .control-label { + margin-bottom: 0; + vertical-align: middle; + } + .navbar-form .radio, + .navbar-form .checkbox { + display: inline-block; + margin-top: 0; + margin-bottom: 0; + vertical-align: middle; + } + .navbar-form .radio label, + .navbar-form .checkbox label { + padding-left: 0; + } + .navbar-form .radio input[type="radio"], + .navbar-form .checkbox input[type="checkbox"] { + position: relative; + margin-left: 0; + } + .navbar-form .has-feedback .form-control-feedback { + top: 0; + } +} +@media (max-width: 767px) { + .navbar-form .form-group { + margin-bottom: 5px; + } +} +@media (min-width: 768px) { + .navbar-form { + width: auto; + border: 0; + margin-left: 0; + margin-right: 0; + padding-top: 0; + padding-bottom: 0; + -webkit-box-shadow: none; + box-shadow: none; + } + .navbar-form.navbar-right:last-child { + margin-right: -15px; + } +} +.navbar-nav > li > .dropdown-menu { + margin-top: 0; + border-top-right-radius: 0; + border-top-left-radius: 0; +} +.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.navbar-btn { + margin-top: 12.5px; + margin-bottom: 12.5px; +} +.navbar-btn.btn-sm { + margin-top: 16px; + margin-bottom: 16px; +} +.navbar-btn.btn-xs { + margin-top: 21.5px; + margin-bottom: 21.5px; +} +.navbar-text { + margin-top: 21.5px; + margin-bottom: 21.5px; +} +@media (min-width: 768px) { + .navbar-text { + float: left; + margin-left: 15px; + margin-right: 15px; + } + .navbar-text.navbar-right:last-child { + margin-right: 0; + } +} +.navbar-default { + background-color: #ffffff; + border-color: #dddddd; +} +.navbar-default .navbar-brand { + color: #4582ec; +} +.navbar-default .navbar-brand:hover, +.navbar-default .navbar-brand:focus { + color: #4582ec; + background-color: transparent; +} +.navbar-default .navbar-text { + color: #333333; +} +.navbar-default .navbar-nav > li > a { + color: #4582ec; +} +.navbar-default .navbar-nav > li > a:hover, +.navbar-default .navbar-nav > li > a:focus { + color: #4582ec; + background-color: transparent; +} +.navbar-default .navbar-nav > .active > a, +.navbar-default .navbar-nav > .active > a:hover, +.navbar-default .navbar-nav > .active > a:focus { + color: #4582ec; + background-color: transparent; +} +.navbar-default .navbar-nav > .disabled > a, +.navbar-default .navbar-nav > .disabled > a:hover, +.navbar-default .navbar-nav > .disabled > a:focus { + color: #333333; + background-color: transparent; +} +.navbar-default .navbar-toggle { + border-color: #dddddd; +} +.navbar-default .navbar-toggle:hover, +.navbar-default .navbar-toggle:focus { + background-color: #dddddd; +} +.navbar-default .navbar-toggle .icon-bar { + background-color: #cccccc; +} +.navbar-default .navbar-collapse, +.navbar-default .navbar-form { + border-color: #dddddd; +} +.navbar-default .navbar-nav > .open > a, +.navbar-default .navbar-nav > .open > a:hover, +.navbar-default .navbar-nav > .open > a:focus { + background-color: transparent; + color: #4582ec; +} +@media (max-width: 767px) { + .navbar-default .navbar-nav .open .dropdown-menu > li > a { + color: #4582ec; + } + .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus { + color: #4582ec; + background-color: transparent; + } + .navbar-default .navbar-nav .open .dropdown-menu > .active > a, + .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus { + color: #4582ec; + background-color: transparent; + } + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a, + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus { + color: #333333; + background-color: transparent; + } +} +.navbar-default .navbar-link { + color: #4582ec; +} +.navbar-default .navbar-link:hover { + color: #4582ec; +} +.navbar-default .btn-link { + color: #4582ec; +} +.navbar-default .btn-link:hover, +.navbar-default .btn-link:focus { + color: #4582ec; +} +.navbar-default .btn-link[disabled]:hover, +fieldset[disabled] .navbar-default .btn-link:hover, +.navbar-default .btn-link[disabled]:focus, +fieldset[disabled] .navbar-default .btn-link:focus { + color: #333333; +} +.navbar-inverse { + background-color: #ffffff; + border-color: #dddddd; +} +.navbar-inverse .navbar-brand { + color: #333333; +} +.navbar-inverse .navbar-brand:hover, +.navbar-inverse .navbar-brand:focus { + color: #333333; + background-color: transparent; +} +.navbar-inverse .navbar-text { + color: #333333; +} +.navbar-inverse .navbar-nav > li > a { + color: #333333; +} +.navbar-inverse .navbar-nav > li > a:hover, +.navbar-inverse .navbar-nav > li > a:focus { + color: #333333; + background-color: transparent; +} +.navbar-inverse .navbar-nav > .active > a, +.navbar-inverse .navbar-nav > .active > a:hover, +.navbar-inverse .navbar-nav > .active > a:focus { + color: #333333; + background-color: transparent; +} +.navbar-inverse .navbar-nav > .disabled > a, +.navbar-inverse .navbar-nav > .disabled > a:hover, +.navbar-inverse .navbar-nav > .disabled > a:focus { + color: #cccccc; + background-color: transparent; +} +.navbar-inverse .navbar-toggle { + border-color: #dddddd; +} +.navbar-inverse .navbar-toggle:hover, +.navbar-inverse .navbar-toggle:focus { + background-color: #dddddd; +} +.navbar-inverse .navbar-toggle .icon-bar { + background-color: #cccccc; +} +.navbar-inverse .navbar-collapse, +.navbar-inverse .navbar-form { + border-color: #ededed; +} +.navbar-inverse .navbar-nav > .open > a, +.navbar-inverse .navbar-nav > .open > a:hover, +.navbar-inverse .navbar-nav > .open > a:focus { + background-color: transparent; + color: #333333; +} +@media (max-width: 767px) { + .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header { + border-color: #dddddd; + } + .navbar-inverse .navbar-nav .open .dropdown-menu .divider { + background-color: #dddddd; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a { + color: #333333; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus { + color: #333333; + background-color: transparent; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a, + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus { + color: #333333; + background-color: transparent; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a, + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus { + color: #cccccc; + background-color: transparent; + } +} +.navbar-inverse .navbar-link { + color: #333333; +} +.navbar-inverse .navbar-link:hover { + color: #333333; +} +.navbar-inverse .btn-link { + color: #333333; +} +.navbar-inverse .btn-link:hover, +.navbar-inverse .btn-link:focus { + color: #333333; +} +.navbar-inverse .btn-link[disabled]:hover, +fieldset[disabled] .navbar-inverse .btn-link:hover, +.navbar-inverse .btn-link[disabled]:focus, +fieldset[disabled] .navbar-inverse .btn-link:focus { + color: #cccccc; +} +.breadcrumb { + padding: 8px 15px; + margin-bottom: 22px; + list-style: none; + background-color: #f5f5f5; + border-radius: 4px; +} +.breadcrumb > li { + display: inline-block; +} +.breadcrumb > li + li:before { + content: "/\00a0"; + padding: 0 5px; + color: #cccccc; +} +.breadcrumb > .active { + color: #b3b3b3; +} +.pagination { + display: inline-block; + padding-left: 0; + margin: 22px 0; + border-radius: 4px; +} +.pagination > li { + display: inline; +} +.pagination > li > a, +.pagination > li > span { + position: relative; + float: left; + padding: 8px 12px; + line-height: 1.42857143; + text-decoration: none; + color: #333333; + background-color: #ffffff; + border: 1px solid #dddddd; + margin-left: -1px; +} +.pagination > li:first-child > a, +.pagination > li:first-child > span { + margin-left: 0; + border-bottom-left-radius: 4px; + border-top-left-radius: 4px; +} +.pagination > li:last-child > a, +.pagination > li:last-child > span { + border-bottom-right-radius: 4px; + border-top-right-radius: 4px; +} +.pagination > li > a:hover, +.pagination > li > span:hover, +.pagination > li > a:focus, +.pagination > li > span:focus { + color: #ffffff; + background-color: #4582ec; + border-color: #4582ec; +} +.pagination > .active > a, +.pagination > .active > span, +.pagination > .active > a:hover, +.pagination > .active > span:hover, +.pagination > .active > a:focus, +.pagination > .active > span:focus { + z-index: 2; + color: #ffffff; + background-color: #4582ec; + border-color: #4582ec; + cursor: default; +} +.pagination > .disabled > span, +.pagination > .disabled > span:hover, +.pagination > .disabled > span:focus, +.pagination > .disabled > a, +.pagination > .disabled > a:hover, +.pagination > .disabled > a:focus { + color: #b3b3b3; + background-color: #ffffff; + border-color: #dddddd; + cursor: not-allowed; +} +.pagination-lg > li > a, +.pagination-lg > li > span { + padding: 14px 16px; + font-size: 20px; +} +.pagination-lg > li:first-child > a, +.pagination-lg > li:first-child > span { + border-bottom-left-radius: 6px; + border-top-left-radius: 6px; +} +.pagination-lg > li:last-child > a, +.pagination-lg > li:last-child > span { + border-bottom-right-radius: 6px; + border-top-right-radius: 6px; +} +.pagination-sm > li > a, +.pagination-sm > li > span { + padding: 5px 10px; + font-size: 14px; +} +.pagination-sm > li:first-child > a, +.pagination-sm > li:first-child > span { + border-bottom-left-radius: 3px; + border-top-left-radius: 3px; +} +.pagination-sm > li:last-child > a, +.pagination-sm > li:last-child > span { + border-bottom-right-radius: 3px; + border-top-right-radius: 3px; +} +.pager { + padding-left: 0; + margin: 22px 0; + list-style: none; + text-align: center; +} +.pager li { + display: inline; +} +.pager li > a, +.pager li > span { + display: inline-block; + padding: 5px 14px; + background-color: #ffffff; + border: 1px solid #dddddd; + border-radius: 15px; +} +.pager li > a:hover, +.pager li > a:focus { + text-decoration: none; + background-color: #4582ec; +} +.pager .next > a, +.pager .next > span { + float: right; +} +.pager .previous > a, +.pager .previous > span { + float: left; +} +.pager .disabled > a, +.pager .disabled > a:hover, +.pager .disabled > a:focus, +.pager .disabled > span { + color: #b3b3b3; + background-color: #ffffff; + cursor: not-allowed; +} +.label { + display: inline; + padding: .2em .6em .3em; + font-size: 75%; + font-weight: bold; + line-height: 1; + color: #ffffff; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + border-radius: .25em; +} +a.label:hover, +a.label:focus { + color: #ffffff; + text-decoration: none; + cursor: pointer; +} +.label:empty { + display: none; +} +.btn .label { + position: relative; + top: -1px; +} +.label-default { + background-color: #ffffff; +} +.label-default[href]:hover, +.label-default[href]:focus { + background-color: #e6e6e6; +} +.label-primary { + background-color: #4582ec; +} +.label-primary[href]:hover, +.label-primary[href]:focus { + background-color: #1863e6; +} +.label-success { + background-color: #3fad46; +} +.label-success[href]:hover, +.label-success[href]:focus { + background-color: #318837; +} +.label-info { + background-color: #5bc0de; +} +.label-info[href]:hover, +.label-info[href]:focus { + background-color: #31b0d5; +} +.label-warning { + background-color: #f0ad4e; +} +.label-warning[href]:hover, +.label-warning[href]:focus { + background-color: #ec971f; +} +.label-danger { + background-color: #d9534f; +} +.label-danger[href]:hover, +.label-danger[href]:focus { + background-color: #c9302c; +} +.badge { + display: inline-block; + min-width: 10px; + padding: 3px 7px; + font-size: 14px; + font-weight: bold; + color: #ffffff; + line-height: 1; + vertical-align: baseline; + white-space: nowrap; + text-align: center; + background-color: #4582ec; + border-radius: 10px; +} +.badge:empty { + display: none; +} +.btn .badge { + position: relative; + top: -1px; +} +.btn-xs .badge { + top: 0; + padding: 1px 5px; +} +a.badge:hover, +a.badge:focus { + color: #ffffff; + text-decoration: none; + cursor: pointer; +} +a.list-group-item.active > .badge, +.nav-pills > .active > a > .badge { + color: #4582ec; + background-color: #ffffff; +} +.nav-pills > li > a > .badge { + margin-left: 3px; +} +.jumbotron { + padding: 30px; + margin-bottom: 30px; + color: inherit; + background-color: #f7f7f7; +} +.jumbotron h1, +.jumbotron .h1 { + color: inherit; +} +.jumbotron p { + margin-bottom: 15px; + font-size: 24px; + font-weight: 200; +} +.jumbotron > hr { + border-top-color: #dedede; +} +.container .jumbotron { + border-radius: 6px; +} +.jumbotron .container { + max-width: 100%; +} +@media screen and (min-width: 768px) { + .jumbotron { + padding-top: 48px; + padding-bottom: 48px; + } + .container .jumbotron { + padding-left: 60px; + padding-right: 60px; + } + .jumbotron h1, + .jumbotron .h1 { + font-size: 72px; + } +} +.thumbnail { + display: block; + padding: 4px; + margin-bottom: 22px; + line-height: 1.42857143; + background-color: #ffffff; + border: 1px solid #dddddd; + border-radius: 4px; + -webkit-transition: all 0.2s ease-in-out; + -o-transition: all 0.2s ease-in-out; + transition: all 0.2s ease-in-out; +} +.thumbnail > img, +.thumbnail a > img { + margin-left: auto; + margin-right: auto; +} +a.thumbnail:hover, +a.thumbnail:focus, +a.thumbnail.active { + border-color: #4582ec; +} +.thumbnail .caption { + padding: 9px; + color: #333333; +} +.alert { + padding: 15px; + margin-bottom: 22px; + border: 1px solid transparent; + border-radius: 4px; +} +.alert h4 { + margin-top: 0; + color: inherit; +} +.alert .alert-link { + font-weight: bold; +} +.alert > p, +.alert > ul { + margin-bottom: 0; +} +.alert > p + p { + margin-top: 5px; +} +.alert-dismissable, +.alert-dismissible { + padding-right: 35px; +} +.alert-dismissable .close, +.alert-dismissible .close { + position: relative; + top: -2px; + right: -21px; + color: inherit; +} +.alert-success { + background-color: #3fad46; + border-color: #3fad46; + color: #ffffff; +} +.alert-success hr { + border-top-color: #389a3e; +} +.alert-success .alert-link { + color: #e6e6e6; +} +.alert-info { + background-color: #5bc0de; + border-color: #5bc0de; + color: #ffffff; +} +.alert-info hr { + border-top-color: #46b8da; +} +.alert-info .alert-link { + color: #e6e6e6; +} +.alert-warning { + background-color: #f0ad4e; + border-color: #f0ad4e; + color: #ffffff; +} +.alert-warning hr { + border-top-color: #eea236; +} +.alert-warning .alert-link { + color: #e6e6e6; +} +.alert-danger { + background-color: #d9534f; + border-color: #d9534f; + color: #ffffff; +} +.alert-danger hr { + border-top-color: #d43f3a; +} +.alert-danger .alert-link { + color: #e6e6e6; +} +@-webkit-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +@keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +.progress { + overflow: hidden; + height: 22px; + margin-bottom: 22px; + background-color: #f5f5f5; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); +} +.progress-bar { + float: left; + width: 0%; + height: 100%; + font-size: 14px; + line-height: 22px; + color: #ffffff; + text-align: center; + background-color: #4582ec; + -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + -webkit-transition: width 0.6s ease; + -o-transition: width 0.6s ease; + transition: width 0.6s ease; +} +.progress-striped .progress-bar, +.progress-bar-striped { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-size: 40px 40px; +} +.progress.active .progress-bar, +.progress-bar.active { + -webkit-animation: progress-bar-stripes 2s linear infinite; + -o-animation: progress-bar-stripes 2s linear infinite; + animation: progress-bar-stripes 2s linear infinite; +} +.progress-bar[aria-valuenow="1"], +.progress-bar[aria-valuenow="2"] { + min-width: 30px; +} +.progress-bar[aria-valuenow="0"] { + color: #b3b3b3; + min-width: 30px; + background-color: transparent; + background-image: none; + box-shadow: none; +} +.progress-bar-success { + background-color: #3fad46; +} +.progress-striped .progress-bar-success { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} +.progress-bar-info { + background-color: #5bc0de; +} +.progress-striped .progress-bar-info { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} +.progress-bar-warning { + background-color: #f0ad4e; +} +.progress-striped .progress-bar-warning { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} +.progress-bar-danger { + background-color: #d9534f; +} +.progress-striped .progress-bar-danger { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} +.media, +.media-body { + overflow: hidden; + zoom: 1; +} +.media, +.media .media { + margin-top: 15px; +} +.media:first-child { + margin-top: 0; +} +.media-object { + display: block; +} +.media-heading { + margin: 0 0 5px; +} +.media > .pull-left { + margin-right: 10px; +} +.media > .pull-right { + margin-left: 10px; +} +.media-list { + padding-left: 0; + list-style: none; +} +.list-group { + margin-bottom: 20px; + padding-left: 0; +} +.list-group-item { + position: relative; + display: block; + padding: 10px 15px; + margin-bottom: -1px; + background-color: #ffffff; + border: 1px solid #dddddd; +} +.list-group-item:first-child { + border-top-right-radius: 4px; + border-top-left-radius: 4px; +} +.list-group-item:last-child { + margin-bottom: 0; + border-bottom-right-radius: 4px; + border-bottom-left-radius: 4px; +} +.list-group-item > .badge { + float: right; +} +.list-group-item > .badge + .badge { + margin-right: 5px; +} +a.list-group-item { + color: #555555; +} +a.list-group-item .list-group-item-heading { + color: #333333; +} +a.list-group-item:hover, +a.list-group-item:focus { + text-decoration: none; + color: #555555; + background-color: #f5f5f5; +} +.list-group-item.disabled, +.list-group-item.disabled:hover, +.list-group-item.disabled:focus { + background-color: #eeeeee; + color: #b3b3b3; +} +.list-group-item.disabled .list-group-item-heading, +.list-group-item.disabled:hover .list-group-item-heading, +.list-group-item.disabled:focus .list-group-item-heading { + color: inherit; +} +.list-group-item.disabled .list-group-item-text, +.list-group-item.disabled:hover .list-group-item-text, +.list-group-item.disabled:focus .list-group-item-text { + color: #b3b3b3; +} +.list-group-item.active, +.list-group-item.active:hover, +.list-group-item.active:focus { + z-index: 2; + color: #ffffff; + background-color: #4582ec; + border-color: #4582ec; +} +.list-group-item.active .list-group-item-heading, +.list-group-item.active:hover .list-group-item-heading, +.list-group-item.active:focus .list-group-item-heading, +.list-group-item.active .list-group-item-heading > small, +.list-group-item.active:hover .list-group-item-heading > small, +.list-group-item.active:focus .list-group-item-heading > small, +.list-group-item.active .list-group-item-heading > .small, +.list-group-item.active:hover .list-group-item-heading > .small, +.list-group-item.active:focus .list-group-item-heading > .small { + color: inherit; +} +.list-group-item.active .list-group-item-text, +.list-group-item.active:hover .list-group-item-text, +.list-group-item.active:focus .list-group-item-text { + color: #fefeff; +} +.list-group-item-success { + color: #3fad46; + background-color: #dff0d8; +} +a.list-group-item-success { + color: #3fad46; +} +a.list-group-item-success .list-group-item-heading { + color: inherit; +} +a.list-group-item-success:hover, +a.list-group-item-success:focus { + color: #3fad46; + background-color: #d0e9c6; +} +a.list-group-item-success.active, +a.list-group-item-success.active:hover, +a.list-group-item-success.active:focus { + color: #fff; + background-color: #3fad46; + border-color: #3fad46; +} +.list-group-item-info { + color: #5bc0de; + background-color: #d9edf7; +} +a.list-group-item-info { + color: #5bc0de; +} +a.list-group-item-info .list-group-item-heading { + color: inherit; +} +a.list-group-item-info:hover, +a.list-group-item-info:focus { + color: #5bc0de; + background-color: #c4e3f3; +} +a.list-group-item-info.active, +a.list-group-item-info.active:hover, +a.list-group-item-info.active:focus { + color: #fff; + background-color: #5bc0de; + border-color: #5bc0de; +} +.list-group-item-warning { + color: #f0ad4e; + background-color: #fcf8e3; +} +a.list-group-item-warning { + color: #f0ad4e; +} +a.list-group-item-warning .list-group-item-heading { + color: inherit; +} +a.list-group-item-warning:hover, +a.list-group-item-warning:focus { + color: #f0ad4e; + background-color: #faf2cc; +} +a.list-group-item-warning.active, +a.list-group-item-warning.active:hover, +a.list-group-item-warning.active:focus { + color: #fff; + background-color: #f0ad4e; + border-color: #f0ad4e; +} +.list-group-item-danger { + color: #d9534f; + background-color: #f2dede; +} +a.list-group-item-danger { + color: #d9534f; +} +a.list-group-item-danger .list-group-item-heading { + color: inherit; +} +a.list-group-item-danger:hover, +a.list-group-item-danger:focus { + color: #d9534f; + background-color: #ebcccc; +} +a.list-group-item-danger.active, +a.list-group-item-danger.active:hover, +a.list-group-item-danger.active:focus { + color: #fff; + background-color: #d9534f; + border-color: #d9534f; +} +.list-group-item-heading { + margin-top: 0; + margin-bottom: 5px; +} +.list-group-item-text { + margin-bottom: 0; + line-height: 1.3; +} +.panel { + margin-bottom: 22px; + background-color: #ffffff; + border: 1px solid transparent; + border-radius: 4px; + -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05); + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05); +} +.panel-body { + padding: 15px; +} +.panel-heading { + padding: 10px 15px; + border-bottom: 1px solid transparent; + border-top-right-radius: 3px; + border-top-left-radius: 3px; +} +.panel-heading > .dropdown .dropdown-toggle { + color: inherit; +} +.panel-title { + margin-top: 0; + margin-bottom: 0; + font-size: 18px; + color: inherit; +} +.panel-title > a { + color: inherit; +} +.panel-footer { + padding: 10px 15px; + background-color: #ffffff; + border-top: 1px solid #dddddd; + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; +} +.panel > .list-group { + margin-bottom: 0; +} +.panel > .list-group .list-group-item { + border-width: 1px 0; + border-radius: 0; +} +.panel > .list-group:first-child .list-group-item:first-child { + border-top: 0; + border-top-right-radius: 3px; + border-top-left-radius: 3px; +} +.panel > .list-group:last-child .list-group-item:last-child { + border-bottom: 0; + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; +} +.panel-heading + .list-group .list-group-item:first-child { + border-top-width: 0; +} +.list-group + .panel-footer { + border-top-width: 0; +} +.panel > .table, +.panel > .table-responsive > .table, +.panel > .panel-collapse > .table { + margin-bottom: 0; +} +.panel > .table:first-child, +.panel > .table-responsive:first-child > .table:first-child { + border-top-right-radius: 3px; + border-top-left-radius: 3px; +} +.panel > .table:first-child > thead:first-child > tr:first-child td:first-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child, +.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child, +.panel > .table:first-child > thead:first-child > tr:first-child th:first-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child, +.panel > .table:first-child > tbody:first-child > tr:first-child th:first-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child { + border-top-left-radius: 3px; +} +.panel > .table:first-child > thead:first-child > tr:first-child td:last-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child, +.panel > .table:first-child > tbody:first-child > tr:first-child td:last-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child, +.panel > .table:first-child > thead:first-child > tr:first-child th:last-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child, +.panel > .table:first-child > tbody:first-child > tr:first-child th:last-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child { + border-top-right-radius: 3px; +} +.panel > .table:last-child, +.panel > .table-responsive:last-child > .table:last-child { + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; +} +.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child, +.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child { + border-bottom-left-radius: 3px; +} +.panel > .table:last-child > tbody:last-child > tr:last-child td:last-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child, +.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child { + border-bottom-right-radius: 3px; +} +.panel > .panel-body + .table, +.panel > .panel-body + .table-responsive { + border-top: 1px solid #dddddd; +} +.panel > .table > tbody:first-child > tr:first-child th, +.panel > .table > tbody:first-child > tr:first-child td { + border-top: 0; +} +.panel > .table-bordered, +.panel > .table-responsive > .table-bordered { + border: 0; +} +.panel > .table-bordered > thead > tr > th:first-child, +.panel > .table-responsive > .table-bordered > thead > tr > th:first-child, +.panel > .table-bordered > tbody > tr > th:first-child, +.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child, +.panel > .table-bordered > tfoot > tr > th:first-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child, +.panel > .table-bordered > thead > tr > td:first-child, +.panel > .table-responsive > .table-bordered > thead > tr > td:first-child, +.panel > .table-bordered > tbody > tr > td:first-child, +.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child, +.panel > .table-bordered > tfoot > tr > td:first-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child { + border-left: 0; +} +.panel > .table-bordered > thead > tr > th:last-child, +.panel > .table-responsive > .table-bordered > thead > tr > th:last-child, +.panel > .table-bordered > tbody > tr > th:last-child, +.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child, +.panel > .table-bordered > tfoot > tr > th:last-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child, +.panel > .table-bordered > thead > tr > td:last-child, +.panel > .table-responsive > .table-bordered > thead > tr > td:last-child, +.panel > .table-bordered > tbody > tr > td:last-child, +.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child, +.panel > .table-bordered > tfoot > tr > td:last-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child { + border-right: 0; +} +.panel > .table-bordered > thead > tr:first-child > td, +.panel > .table-responsive > .table-bordered > thead > tr:first-child > td, +.panel > .table-bordered > tbody > tr:first-child > td, +.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td, +.panel > .table-bordered > thead > tr:first-child > th, +.panel > .table-responsive > .table-bordered > thead > tr:first-child > th, +.panel > .table-bordered > tbody > tr:first-child > th, +.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th { + border-bottom: 0; +} +.panel > .table-bordered > tbody > tr:last-child > td, +.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td, +.panel > .table-bordered > tfoot > tr:last-child > td, +.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td, +.panel > .table-bordered > tbody > tr:last-child > th, +.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th, +.panel > .table-bordered > tfoot > tr:last-child > th, +.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th { + border-bottom: 0; +} +.panel > .table-responsive { + border: 0; + margin-bottom: 0; +} +.panel-group { + margin-bottom: 22px; +} +.panel-group .panel { + margin-bottom: 0; + border-radius: 4px; +} +.panel-group .panel + .panel { + margin-top: 5px; +} +.panel-group .panel-heading { + border-bottom: 0; +} +.panel-group .panel-heading + .panel-collapse > .panel-body { + border-top: 1px solid #dddddd; +} +.panel-group .panel-footer { + border-top: 0; +} +.panel-group .panel-footer + .panel-collapse .panel-body { + border-bottom: 1px solid #dddddd; +} +.panel-default { + border-color: #dddddd; +} +.panel-default > .panel-heading { + color: #333333; + background-color: #f5f5f5; + border-color: #dddddd; +} +.panel-default > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #dddddd; +} +.panel-default > .panel-heading .badge { + color: #f5f5f5; + background-color: #333333; +} +.panel-default > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #dddddd; +} +.panel-primary { + border-color: transparent; +} +.panel-primary > .panel-heading { + color: #ffffff; + background-color: #4582ec; + border-color: transparent; +} +.panel-primary > .panel-heading + .panel-collapse > .panel-body { + border-top-color: transparent; +} +.panel-primary > .panel-heading .badge { + color: #4582ec; + background-color: #ffffff; +} +.panel-primary > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: transparent; +} +.panel-success { + border-color: transparent; +} +.panel-success > .panel-heading { + color: #3fad46; + background-color: #3fad46; + border-color: transparent; +} +.panel-success > .panel-heading + .panel-collapse > .panel-body { + border-top-color: transparent; +} +.panel-success > .panel-heading .badge { + color: #3fad46; + background-color: #3fad46; +} +.panel-success > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: transparent; +} +.panel-info { + border-color: transparent; +} +.panel-info > .panel-heading { + color: #5bc0de; + background-color: #5bc0de; + border-color: transparent; +} +.panel-info > .panel-heading + .panel-collapse > .panel-body { + border-top-color: transparent; +} +.panel-info > .panel-heading .badge { + color: #5bc0de; + background-color: #5bc0de; +} +.panel-info > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: transparent; +} +.panel-warning { + border-color: transparent; +} +.panel-warning > .panel-heading { + color: #f0ad4e; + background-color: #f0ad4e; + border-color: transparent; +} +.panel-warning > .panel-heading + .panel-collapse > .panel-body { + border-top-color: transparent; +} +.panel-warning > .panel-heading .badge { + color: #f0ad4e; + background-color: #f0ad4e; +} +.panel-warning > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: transparent; +} +.panel-danger { + border-color: transparent; +} +.panel-danger > .panel-heading { + color: #d9534f; + background-color: #d9534f; + border-color: transparent; +} +.panel-danger > .panel-heading + .panel-collapse > .panel-body { + border-top-color: transparent; +} +.panel-danger > .panel-heading .badge { + color: #d9534f; + background-color: #d9534f; +} +.panel-danger > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: transparent; +} +.embed-responsive { + position: relative; + display: block; + height: 0; + padding: 0; + overflow: hidden; +} +.embed-responsive .embed-responsive-item, +.embed-responsive iframe, +.embed-responsive embed, +.embed-responsive object { + position: absolute; + top: 0; + left: 0; + bottom: 0; + height: 100%; + width: 100%; + border: 0; +} +.embed-responsive.embed-responsive-16by9 { + padding-bottom: 56.25%; +} +.embed-responsive.embed-responsive-4by3 { + padding-bottom: 75%; +} +.well { + min-height: 20px; + padding: 19px; + margin-bottom: 20px; + background-color: #f7f7f7; + border: 1px solid #e5e5e5; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); +} +.well blockquote { + border-color: #ddd; + border-color: rgba(0, 0, 0, 0.15); +} +.well-lg { + padding: 24px; + border-radius: 6px; +} +.well-sm { + padding: 9px; + border-radius: 3px; +} +.close { + float: right; + font-size: 24px; + font-weight: bold; + line-height: 1; + color: #ffffff; + text-shadow: 0 1px 0 #ffffff; + opacity: 0.2; + filter: alpha(opacity=20); +} +.close:hover, +.close:focus { + color: #ffffff; + text-decoration: none; + cursor: pointer; + opacity: 0.5; + filter: alpha(opacity=50); +} +button.close { + padding: 0; + cursor: pointer; + background: transparent; + border: 0; + -webkit-appearance: none; +} +.modal-open { + overflow: hidden; +} +.modal { + display: none; + overflow: hidden; + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1050; + -webkit-overflow-scrolling: touch; + outline: 0; +} +.modal.fade .modal-dialog { + -webkit-transform: translate3d(0, -25%, 0); + transform: translate3d(0, -25%, 0); + -webkit-transition: -webkit-transform 0.3s ease-out; + -moz-transition: -moz-transform 0.3s ease-out; + -o-transition: -o-transform 0.3s ease-out; + transition: transform 0.3s ease-out; +} +.modal.in .modal-dialog { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); +} +.modal-open .modal { + overflow-x: hidden; + overflow-y: auto; +} +.modal-dialog { + position: relative; + width: auto; + margin: 10px; +} +.modal-content { + position: relative; + background-color: #ffffff; + border: 1px solid #999999; + border: 1px solid rgba(0, 0, 0, 0.2); + border-radius: 6px; + -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5); + box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5); + background-clip: padding-box; + outline: 0; +} +.modal-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1040; + background-color: #000000; +} +.modal-backdrop.fade { + opacity: 0; + filter: alpha(opacity=0); +} +.modal-backdrop.in { + opacity: 0.5; + filter: alpha(opacity=50); +} +.modal-header { + padding: 15px; + border-bottom: 1px solid #e5e5e5; + min-height: 16.42857143px; +} +.modal-header .close { + margin-top: -2px; +} +.modal-title { + margin: 0; + line-height: 1.42857143; +} +.modal-body { + position: relative; + padding: 20px; +} +.modal-footer { + padding: 20px; + text-align: right; + border-top: 1px solid #e5e5e5; +} +.modal-footer .btn + .btn { + margin-left: 5px; + margin-bottom: 0; +} +.modal-footer .btn-group .btn + .btn { + margin-left: -1px; +} +.modal-footer .btn-block + .btn-block { + margin-left: 0; +} +.modal-scrollbar-measure { + position: absolute; + top: -9999px; + width: 50px; + height: 50px; + overflow: scroll; +} +@media (min-width: 768px) { + .modal-dialog { + width: 600px; + margin: 30px auto; + } + .modal-content { + -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5); + box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5); + } + .modal-sm { + width: 300px; + } +} +@media (min-width: 992px) { + .modal-lg { + width: 900px; + } +} +.tooltip { + position: absolute; + z-index: 1070; + display: block; + visibility: visible; + font-size: 14px; + line-height: 1.4; + opacity: 0; + filter: alpha(opacity=0); +} +.tooltip.in { + opacity: 0.9; + filter: alpha(opacity=90); +} +.tooltip.top { + margin-top: -3px; + padding: 5px 0; +} +.tooltip.right { + margin-left: 3px; + padding: 0 5px; +} +.tooltip.bottom { + margin-top: 3px; + padding: 5px 0; +} +.tooltip.left { + margin-left: -3px; + padding: 0 5px; +} +.tooltip-inner { + max-width: 200px; + padding: 3px 8px; + color: #ffffff; + text-align: center; + text-decoration: none; + background-color: rgba(0, 0, 0, 0.9); + border-radius: 4px; +} +.tooltip-arrow { + position: absolute; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} +.tooltip.top .tooltip-arrow { + bottom: 0; + left: 50%; + margin-left: -5px; + border-width: 5px 5px 0; + border-top-color: rgba(0, 0, 0, 0.9); +} +.tooltip.top-left .tooltip-arrow { + bottom: 0; + left: 5px; + border-width: 5px 5px 0; + border-top-color: rgba(0, 0, 0, 0.9); +} +.tooltip.top-right .tooltip-arrow { + bottom: 0; + right: 5px; + border-width: 5px 5px 0; + border-top-color: rgba(0, 0, 0, 0.9); +} +.tooltip.right .tooltip-arrow { + top: 50%; + left: 0; + margin-top: -5px; + border-width: 5px 5px 5px 0; + border-right-color: rgba(0, 0, 0, 0.9); +} +.tooltip.left .tooltip-arrow { + top: 50%; + right: 0; + margin-top: -5px; + border-width: 5px 0 5px 5px; + border-left-color: rgba(0, 0, 0, 0.9); +} +.tooltip.bottom .tooltip-arrow { + top: 0; + left: 50%; + margin-left: -5px; + border-width: 0 5px 5px; + border-bottom-color: rgba(0, 0, 0, 0.9); +} +.tooltip.bottom-left .tooltip-arrow { + top: 0; + left: 5px; + border-width: 0 5px 5px; + border-bottom-color: rgba(0, 0, 0, 0.9); +} +.tooltip.bottom-right .tooltip-arrow { + top: 0; + right: 5px; + border-width: 0 5px 5px; + border-bottom-color: rgba(0, 0, 0, 0.9); +} +.popover { + position: absolute; + top: 0; + left: 0; + z-index: 1060; + display: none; + max-width: 276px; + padding: 1px; + text-align: left; + background-color: #ffffff; + background-clip: padding-box; + border: 1px solid #cccccc; + border: 1px solid rgba(0, 0, 0, 0.2); + border-radius: 6px; + -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + white-space: normal; +} +.popover.top { + margin-top: -10px; +} +.popover.right { + margin-left: 10px; +} +.popover.bottom { + margin-top: 10px; +} +.popover.left { + margin-left: -10px; +} +.popover-title { + margin: 0; + padding: 8px 14px; + font-size: 16px; + font-weight: normal; + line-height: 18px; + background-color: #f7f7f7; + border-bottom: 1px solid #ebebeb; + border-radius: 5px 5px 0 0; +} +.popover-content { + padding: 9px 14px; +} +.popover > .arrow, +.popover > .arrow:after { + position: absolute; + display: block; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} +.popover > .arrow { + border-width: 11px; +} +.popover > .arrow:after { + border-width: 10px; + content: ""; +} +.popover.top > .arrow { + left: 50%; + margin-left: -11px; + border-bottom-width: 0; + border-top-color: #999999; + border-top-color: rgba(0, 0, 0, 0.25); + bottom: -11px; +} +.popover.top > .arrow:after { + content: " "; + bottom: 1px; + margin-left: -10px; + border-bottom-width: 0; + border-top-color: #ffffff; +} +.popover.right > .arrow { + top: 50%; + left: -11px; + margin-top: -11px; + border-left-width: 0; + border-right-color: #999999; + border-right-color: rgba(0, 0, 0, 0.25); +} +.popover.right > .arrow:after { + content: " "; + left: 1px; + bottom: -10px; + border-left-width: 0; + border-right-color: #ffffff; +} +.popover.bottom > .arrow { + left: 50%; + margin-left: -11px; + border-top-width: 0; + border-bottom-color: #999999; + border-bottom-color: rgba(0, 0, 0, 0.25); + top: -11px; +} +.popover.bottom > .arrow:after { + content: " "; + top: 1px; + margin-left: -10px; + border-top-width: 0; + border-bottom-color: #ffffff; +} +.popover.left > .arrow { + top: 50%; + right: -11px; + margin-top: -11px; + border-right-width: 0; + border-left-color: #999999; + border-left-color: rgba(0, 0, 0, 0.25); +} +.popover.left > .arrow:after { + content: " "; + right: 1px; + border-right-width: 0; + border-left-color: #ffffff; + bottom: -10px; +} +.carousel { + position: relative; +} +.carousel-inner { + position: relative; + overflow: hidden; + width: 100%; +} +.carousel-inner > .item { + display: none; + position: relative; + -webkit-transition: 0.6s ease-in-out left; + -o-transition: 0.6s ease-in-out left; + transition: 0.6s ease-in-out left; +} +.carousel-inner > .item > img, +.carousel-inner > .item > a > img { + line-height: 1; +} +.carousel-inner > .active, +.carousel-inner > .next, +.carousel-inner > .prev { + display: block; +} +.carousel-inner > .active { + left: 0; +} +.carousel-inner > .next, +.carousel-inner > .prev { + position: absolute; + top: 0; + width: 100%; +} +.carousel-inner > .next { + left: 100%; +} +.carousel-inner > .prev { + left: -100%; +} +.carousel-inner > .next.left, +.carousel-inner > .prev.right { + left: 0; +} +.carousel-inner > .active.left { + left: -100%; +} +.carousel-inner > .active.right { + left: 100%; +} +.carousel-control { + position: absolute; + top: 0; + left: 0; + bottom: 0; + width: 15%; + opacity: 0.5; + filter: alpha(opacity=50); + font-size: 20px; + color: #ffffff; + text-align: center; + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6); +} +.carousel-control.left { + background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%); + background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%); + background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1); +} +.carousel-control.right { + left: auto; + right: 0; + background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%); + background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%); + background-image: linear-gradient(to right, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1); +} +.carousel-control:hover, +.carousel-control:focus { + outline: 0; + color: #ffffff; + text-decoration: none; + opacity: 0.9; + filter: alpha(opacity=90); +} +.carousel-control .icon-prev, +.carousel-control .icon-next, +.carousel-control .glyphicon-chevron-left, +.carousel-control .glyphicon-chevron-right { + position: absolute; + top: 50%; + z-index: 5; + display: inline-block; +} +.carousel-control .icon-prev, +.carousel-control .glyphicon-chevron-left { + left: 50%; + margin-left: -10px; +} +.carousel-control .icon-next, +.carousel-control .glyphicon-chevron-right { + right: 50%; + margin-right: -10px; +} +.carousel-control .icon-prev, +.carousel-control .icon-next { + width: 20px; + height: 20px; + margin-top: -10px; + font-family: serif; +} +.carousel-control .icon-prev:before { + content: '\2039'; +} +.carousel-control .icon-next:before { + content: '\203a'; +} +.carousel-indicators { + position: absolute; + bottom: 10px; + left: 50%; + z-index: 15; + width: 60%; + margin-left: -30%; + padding-left: 0; + list-style: none; + text-align: center; +} +.carousel-indicators li { + display: inline-block; + width: 10px; + height: 10px; + margin: 1px; + text-indent: -999px; + border: 1px solid #ffffff; + border-radius: 10px; + cursor: pointer; + background-color: #000 \9; + background-color: rgba(0, 0, 0, 0); +} +.carousel-indicators .active { + margin: 0; + width: 12px; + height: 12px; + background-color: #ffffff; +} +.carousel-caption { + position: absolute; + left: 15%; + right: 15%; + bottom: 20px; + z-index: 10; + padding-top: 20px; + padding-bottom: 20px; + color: #ffffff; + text-align: center; + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6); +} +.carousel-caption .btn { + text-shadow: none; +} +@media screen and (min-width: 768px) { + .carousel-control .glyphicon-chevron-left, + .carousel-control .glyphicon-chevron-right, + .carousel-control .icon-prev, + .carousel-control .icon-next { + width: 30px; + height: 30px; + margin-top: -15px; + font-size: 30px; + } + .carousel-control .glyphicon-chevron-left, + .carousel-control .icon-prev { + margin-left: -15px; + } + .carousel-control .glyphicon-chevron-right, + .carousel-control .icon-next { + margin-right: -15px; + } + .carousel-caption { + left: 20%; + right: 20%; + padding-bottom: 30px; + } + .carousel-indicators { + bottom: 20px; + } +} +.clearfix:before, +.clearfix:after, +.dl-horizontal dd:before, +.dl-horizontal dd:after, +.container:before, +.container:after, +.container-fluid:before, +.container-fluid:after, +.row:before, +.row:after, +.form-horizontal .form-group:before, +.form-horizontal .form-group:after, +.btn-toolbar:before, +.btn-toolbar:after, +.btn-group-vertical > .btn-group:before, +.btn-group-vertical > .btn-group:after, +.nav:before, +.nav:after, +.navbar:before, +.navbar:after, +.navbar-header:before, +.navbar-header:after, +.navbar-collapse:before, +.navbar-collapse:after, +.pager:before, +.pager:after, +.panel-body:before, +.panel-body:after, +.modal-footer:before, +.modal-footer:after { + content: " "; + display: table; +} +.clearfix:after, +.dl-horizontal dd:after, +.container:after, +.container-fluid:after, +.row:after, +.form-horizontal .form-group:after, +.btn-toolbar:after, +.btn-group-vertical > .btn-group:after, +.nav:after, +.navbar:after, +.navbar-header:after, +.navbar-collapse:after, +.pager:after, +.panel-body:after, +.modal-footer:after { + clear: both; +} +.center-block { + display: block; + margin-left: auto; + margin-right: auto; +} +.pull-right { + float: right !important; +} +.pull-left { + float: left !important; +} +.hide { + display: none !important; +} +.show { + display: block !important; +} +.invisible { + visibility: hidden; +} +.text-hide { + font: 0/0 a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; +} +.hidden { + display: none !important; + visibility: hidden !important; +} +.affix { + position: fixed; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); +} +@-ms-viewport { + width: device-width; +} +.visible-xs, +.visible-sm, +.visible-md, +.visible-lg { + display: none !important; +} +.visible-xs-block, +.visible-xs-inline, +.visible-xs-inline-block, +.visible-sm-block, +.visible-sm-inline, +.visible-sm-inline-block, +.visible-md-block, +.visible-md-inline, +.visible-md-inline-block, +.visible-lg-block, +.visible-lg-inline, +.visible-lg-inline-block { + display: none !important; +} +@media (max-width: 767px) { + .visible-xs { + display: block !important; + } + table.visible-xs { + display: table; + } + tr.visible-xs { + display: table-row !important; + } + th.visible-xs, + td.visible-xs { + display: table-cell !important; + } +} +@media (max-width: 767px) { + .visible-xs-block { + display: block !important; + } +} +@media (max-width: 767px) { + .visible-xs-inline { + display: inline !important; + } +} +@media (max-width: 767px) { + .visible-xs-inline-block { + display: inline-block !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm { + display: block !important; + } + table.visible-sm { + display: table; + } + tr.visible-sm { + display: table-row !important; + } + th.visible-sm, + td.visible-sm { + display: table-cell !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm-block { + display: block !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm-inline { + display: inline !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm-inline-block { + display: inline-block !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md { + display: block !important; + } + table.visible-md { + display: table; + } + tr.visible-md { + display: table-row !important; + } + th.visible-md, + td.visible-md { + display: table-cell !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md-block { + display: block !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md-inline { + display: inline !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md-inline-block { + display: inline-block !important; + } +} +@media (min-width: 1200px) { + .visible-lg { + display: block !important; + } + table.visible-lg { + display: table; + } + tr.visible-lg { + display: table-row !important; + } + th.visible-lg, + td.visible-lg { + display: table-cell !important; + } +} +@media (min-width: 1200px) { + .visible-lg-block { + display: block !important; + } +} +@media (min-width: 1200px) { + .visible-lg-inline { + display: inline !important; + } +} +@media (min-width: 1200px) { + .visible-lg-inline-block { + display: inline-block !important; + } +} +@media (max-width: 767px) { + .hidden-xs { + display: none !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .hidden-sm { + display: none !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .hidden-md { + display: none !important; + } +} +@media (min-width: 1200px) { + .hidden-lg { + display: none !important; + } +} +.visible-print { + display: none !important; +} +@media print { + .visible-print { + display: block !important; + } + table.visible-print { + display: table; + } + tr.visible-print { + display: table-row !important; + } + th.visible-print, + td.visible-print { + display: table-cell !important; + } +} +.visible-print-block { + display: none !important; +} +@media print { + .visible-print-block { + display: block !important; + } +} +.visible-print-inline { + display: none !important; +} +@media print { + .visible-print-inline { + display: inline !important; + } +} +.visible-print-inline-block { + display: none !important; +} +@media print { + .visible-print-inline-block { + display: inline-block !important; + } +} +@media print { + .hidden-print { + display: none !important; + } +} +.navbar { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; +} +.navbar-nav, +.navbar-form { + margin-left: 0; + margin-right: 0; +} +.navbar-nav > li > a { + padding: 8px 12px; + margin: 12px 6px; + border: 1px solid transparent; + border-radius: 4px; +} +.navbar-nav > li > a:hover { + border: 1px solid #ddd; +} +.navbar-nav > .active > a, +.navbar-nav > .active > a:hover { + border: 1px solid #ddd; +} +.navbar-default .navbar-nav > .active > a:hover { + color: #4582ec; +} +.navbar-inverse .navbar-nav > .active > a:hover { + color: #333333; +} +.navbar-brand { + padding-top: 20px; +} +@media (max-width: 768px) { + .navbar .navbar-nav > li > a { + margin: 0; + } +} +.btn { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; +} +legend { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; +} +.input-group-addon { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; +} +.nav .open > a, +.nav .open > a:hover, +.nav .open > a:focus { + border: 1px solid #ddd; +} +.pagination { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; +} +.pagination-lg > li > a, +.pagination-lg > li > span { + padding: 14px 24px; +} +.pager { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; +} +.pager a { + color: #333333; +} +.pager a:hover { + border-color: transparent; + color: #fff; +} +.pager .disabled a { + border-color: #dddddd; +} +.close { + color: #fff; + text-decoration: none; + text-shadow: none; + opacity: 0.4; +} +.close:hover, +.close:focus { + color: #fff; + opacity: 1; +} +.alert .alert-link { + color: #ffffff; + text-decoration: underline; +} +.label { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-weight: normal; +} +.label-default { + border: 1px solid #ddd; + color: #333333; +} +.badge { + padding: 1px 7px 5px; + vertical-align: 2px; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-weight: normal; +} +.panel { + -webkit-box-shadow: none; + box-shadow: none; +} +.panel-default .close { + color: #333333; +} +.panel-primary .panel-heading, +.panel-success .panel-heading, +.panel-warning .panel-heading, +.panel-danger .panel-heading, +.panel-info .panel-heading { + color: #fff; +} +.panel-primary .panel-body, +.panel-success .panel-body, +.panel-warning .panel-body, +.panel-danger .panel-body, +.panel-info .panel-body { + border: 1px solid #ddd; + border-top-width: 0; + border-radius: 0 0 4px 4px; +} +.modal .close { + color: #333333; +} diff --git a/web/src/css/mitmproxy.less b/web/src/css/mitmproxy.less new file mode 100644 index 00000000..a64f7f90 --- /dev/null +++ b/web/src/css/mitmproxy.less @@ -0,0 +1,7 @@ +@import (less) 'bootstrap.css'; +@import (less) '../vendor/fontawesome/css/font-awesome.css'; + +.certinstall { + +} + diff --git a/web/src/js/certinstall.jsx b/web/src/js/certinstall.jsx new file mode 100644 index 00000000..2e681ac2 --- /dev/null +++ b/web/src/js/certinstall.jsx @@ -0,0 +1,27 @@ +/** @jsx React.DOM */ + +var CertInstallView = React.createClass({ + render: function () { + return
+

Click to install the mitmproxy certificate:

+
+
+ +

Apple

+
+
+ +

Windows

+
+
+ +

Android

+
+
+ +

Other

+
+
+
; + } +}); diff --git a/web/src/js/certinstall_jsx.js b/web/src/js/certinstall_jsx.js new file mode 100644 index 00000000..17f9f807 --- /dev/null +++ b/web/src/js/certinstall_jsx.js @@ -0,0 +1,27 @@ +/** @jsx React.DOM */ + +var CertInstallView = React.createClass({displayName: 'CertInstallView', + render: function () { + return React.DOM.div({className: "certinstall"}, + React.DOM.h2(null, " Click to install the mitmproxy certificate: "), + React.DOM.div({id: "certbank", className: "row"}, + React.DOM.div({className: "col-md-3"}, + React.DOM.a({href: "/cert/pem"}, React.DOM.i({className: "fa fa-apple fa-5x"})), + React.DOM.p(null, "Apple") + ), + React.DOM.div({className: "col-md-3"}, + React.DOM.a({href: "/cert/p12"}, React.DOM.i({className: "fa fa-windows fa-5x"})), + React.DOM.p(null, "Windows") + ), + React.DOM.div({className: "col-md-3"}, + React.DOM.a({href: "/cert/pem"}, React.DOM.i({className: "fa fa-android fa-5x"})), + React.DOM.p(null, "Android") + ), + React.DOM.div({className: "col-md-3"}, + React.DOM.a({href: "/cert/pem"}, React.DOM.i({className: "fa fa-asterisk fa-5x"})), + React.DOM.p(null, "Other") + ) + ) + ); + } +}); diff --git a/web/src/js/mitmproxy.js b/web/src/js/mitmproxy.js new file mode 100644 index 00000000..87c45b34 --- /dev/null +++ b/web/src/js/mitmproxy.js @@ -0,0 +1,10 @@ + +mitmproxy = function () { + function init() { + React.renderComponent(Router(), $("#mitmproxy")[0]); + } + var exports = { + init: init, + }; + return exports; +}(); \ No newline at end of file diff --git a/web/src/js/router.jsx b/web/src/js/router.jsx new file mode 100644 index 00000000..dc3e729b --- /dev/null +++ b/web/src/js/router.jsx @@ -0,0 +1,10 @@ +/** @jsx React.DOM */ + +var Router = React.createClass({ + render: function(){ + return + + + ; + } +}); diff --git a/web/src/js/router_jsx.js b/web/src/js/router_jsx.js new file mode 100644 index 00000000..707715de --- /dev/null +++ b/web/src/js/router_jsx.js @@ -0,0 +1,10 @@ +/** @jsx React.DOM */ + +var Router = React.createClass({displayName: 'Router', + render: function(){ + return ReactRouter.Routes({location: "hash"}, + ReactRouter.Route({name: "certs", path: "/", handler: CertInstallView}), + ReactRouter.Route({name: "other", path: "/other", handler: CertInstallView}) + ); + } +}); diff --git a/web/src/js/tests.js b/web/src/js/tests.js new file mode 100644 index 00000000..254bad72 --- /dev/null +++ b/web/src/js/tests.js @@ -0,0 +1,5 @@ + + +QUnit.test("example test", function (assert) { + assert.ok(true); +}); \ No newline at end of file diff --git a/web/src/test.html b/web/src/test.html new file mode 100644 index 00000000..9de604e4 --- /dev/null +++ b/web/src/test.html @@ -0,0 +1,25 @@ + + + + + Unit Tests + + + + + + + + + + + + + + + +
+
+ + + \ No newline at end of file diff --git a/web/src/vendor/benchmark/.bower.json b/web/src/vendor/benchmark/.bower.json new file mode 100644 index 00000000..83417220 --- /dev/null +++ b/web/src/vendor/benchmark/.bower.json @@ -0,0 +1,14 @@ +{ + "name": "benchmark", + "homepage": "https://github.com/bestiejs/benchmark.js", + "version": "1.0.0", + "_release": "1.0.0", + "_resolution": { + "type": "version", + "tag": "v1.0.0", + "commit": "f3c1476cfac950b186b167843077f2cf7014f080" + }, + "_source": "git://github.com/bestiejs/benchmark.js.git", + "_target": "*", + "_originalSource": "benchmark" +} \ No newline at end of file diff --git a/web/src/vendor/benchmark/.gitattributes b/web/src/vendor/benchmark/.gitattributes new file mode 100644 index 00000000..176a458f --- /dev/null +++ b/web/src/vendor/benchmark/.gitattributes @@ -0,0 +1 @@ +* text=auto diff --git a/web/src/vendor/benchmark/.gitignore b/web/src/vendor/benchmark/.gitignore new file mode 100644 index 00000000..cdecb6ae --- /dev/null +++ b/web/src/vendor/benchmark/.gitignore @@ -0,0 +1,4 @@ +.DS_Store +node_modules/ +tests/benchmark.air/src/*.js +tests/benchmark.air/bin-debug/ diff --git a/web/src/vendor/benchmark/.npmignore b/web/src/vendor/benchmark/.npmignore new file mode 100644 index 00000000..b9acbef5 --- /dev/null +++ b/web/src/vendor/benchmark/.npmignore @@ -0,0 +1,8 @@ +.* +nano.* +example/ +plugin/ +vendor/ +doc/*.php +test/*.air +test/*.html diff --git a/web/src/vendor/benchmark/LICENSE.txt b/web/src/vendor/benchmark/LICENSE.txt new file mode 100644 index 00000000..e33e63f7 --- /dev/null +++ b/web/src/vendor/benchmark/LICENSE.txt @@ -0,0 +1,22 @@ +Copyright 2010-2012 Mathias Bynens +Based on JSLitmus.js, copyright Robert Kieffer +Modified by John-David Dalton + +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. diff --git a/web/src/vendor/benchmark/README.md b/web/src/vendor/benchmark/README.md new file mode 100644 index 00000000..62a2d1ae --- /dev/null +++ b/web/src/vendor/benchmark/README.md @@ -0,0 +1,135 @@ +# Benchmark.js v1.0.0 + +A [robust](http://calendar.perfplanet.com/2010/bulletproof-javascript-benchmarks/ "Bulletproof JavaScript benchmarks") benchmarking library that works on nearly all JavaScript platforms1, supports high-resolution timers, and returns statistically significant results. As seen on [jsPerf](http://jsperf.com/). + +## Download + + * [Development source](https://raw.github.com/bestiejs/benchmark.js/v1.0.0/benchmark.js) + +## Dive in + +We’ve got [API docs](http://benchmarkjs.com/docs) and [unit tests](http://benchmarkjs.com/tests). + +For a list of upcoming features, check out our [roadmap](https://github.com/bestiejs/benchmark.js/wiki/Roadmap). + +## Support + +Benchmark.js has been tested in at least Adobe AIR 3.1, Chrome 5-21, Firefox 1.5-13, IE 6-9, Opera 9.25-12.01, Safari 3-6, Node.js 0.8.6, Narwhal 0.3.2, RingoJS 0.8, and Rhino 1.7RC5. + +## Installation and usage + +In a browser or Adobe AIR: + +```html + +``` + +Optionally, expose Java’s nanosecond timer by adding the `nano` applet to the ``: + +```html + +``` + +Or enable Chrome’s microsecond timer by using the [command line switch](http://peter.sh/experiments/chromium-command-line-switches/#enable-benchmarking): + + --enable-benchmarking + +Via [npm](http://npmjs.org/): + +```bash +npm install benchmark +``` + +In [Node.js](http://nodejs.org/) and [RingoJS v0.8.0+](http://ringojs.org/): + +```js +var Benchmark = require('benchmark'); +``` + +Optionally, use the [microtime module](https://github.com/wadey/node-microtime) by Wade Simmons: + +```bash +npm install microtime +``` + +In [RingoJS v0.7.0-](http://ringojs.org/): + +```js +var Benchmark = require('benchmark').Benchmark; +``` + +In [Rhino](http://www.mozilla.org/rhino/): + +```js +load('benchmark.js'); +``` + +In an AMD loader like [RequireJS](http://requirejs.org/): + +```js +require({ + 'paths': { + 'benchmark': 'path/to/benchmark' + } +}, +['benchmark'], function(Benchmark) { + console.log(Benchmark.version); +}); + +// or with platform.js +// https://github.com/bestiejs/platform.js +require({ + 'paths': { + 'benchmark': 'path/to/benchmark', + 'platform': 'path/to/platform' + } +}, +['benchmark', 'platform'], function(Benchmark, platform) { + Benchmark.platform = platform; + console.log(Benchmark.platform.name); +}); +``` + +Usage example: + +```js +var suite = new Benchmark.Suite; + +// add tests +suite.add('RegExp#test', function() { + /o/.test('Hello World!'); +}) +.add('String#indexOf', function() { + 'Hello World!'.indexOf('o') > -1; +}) +// add listeners +.on('cycle', function(event) { + console.log(String(event.target)); +}) +.on('complete', function() { + console.log('Fastest is ' + this.filter('fastest').pluck('name')); +}) +// run async +.run({ 'async': true }); + +// logs: +// > RegExp#test x 4,161,532 +-0.99% (59 cycles) +// > String#indexOf x 6,139,623 +-1.00% (131 cycles) +// > Fastest is String#indexOf +``` + +## BestieJS + +Benchmark.js is part of the BestieJS *"Best in Class"* module collection. This means we promote solid browser/environment support, ES5 precedents, unit testing, and plenty of documentation. + +## Authors + +* [Mathias Bynens](http://mathiasbynens.be/) + [![twitter/mathias](http://gravatar.com/avatar/24e08a9ea84deb17ae121074d0f17125?s=70)](https://twitter.com/mathias "Follow @mathias on Twitter") +* [John-David Dalton](http://allyoucanleet.com/) + [![twitter/jdalton](http://gravatar.com/avatar/299a3d891ff1920b69c364d061007043?s=70)](https://twitter.com/jdalton "Follow @jdalton on Twitter") + +## Contributors + +* [Kit Cambridge](http://kitcambridge.github.com/) + [![twitter/kitcambridge](http://gravatar.com/avatar/6662a1d02f351b5ef2f8b4d815804661?s=70)](https://twitter.com/kitcambridge "Follow @kitcambridge on Twitter") diff --git a/web/src/vendor/benchmark/benchmark.js b/web/src/vendor/benchmark/benchmark.js new file mode 100644 index 00000000..db2c9958 --- /dev/null +++ b/web/src/vendor/benchmark/benchmark.js @@ -0,0 +1,3919 @@ +/*! + * 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)); diff --git a/web/src/vendor/benchmark/doc/README.md b/web/src/vendor/benchmark/doc/README.md new file mode 100644 index 00000000..5ac99e37 --- /dev/null +++ b/web/src/vendor/benchmark/doc/README.md @@ -0,0 +1,2629 @@ +# Benchmark.js v1.0.0 + + + + + + +## `Benchmark` +* [`Benchmark`](#benchmarkname-fn--options) +* [`Benchmark.version`](#benchmarkversion) +* [`Benchmark.deepClone`](#benchmarkdeepclonevalue) +* [`Benchmark.each`](#benchmarkeachobject-callback-thisarg) +* [`Benchmark.extend`](#benchmarkextenddestination--source) +* [`Benchmark.filter`](#benchmarkfilterarray-callback-thisarg) +* [`Benchmark.forEach`](#benchmarkforeacharray-callback-thisarg) +* [`Benchmark.formatNumber`](#benchmarkformatnumbernumber) +* [`Benchmark.forOwn`](#benchmarkforownobject-callback-thisarg) +* [`Benchmark.hasKey`](#benchmarkhaskeyobject-key) +* [`Benchmark.indexOf`](#benchmarkindexofarray-value--fromindex0) +* [`Benchmark.interpolate`](#benchmarkinterpolatestring-object) +* [`Benchmark.invoke`](#benchmarkinvokebenches-name--arg1-arg2-) +* [`Benchmark.join`](#benchmarkjoinobject--separator1--separator2:) +* [`Benchmark.map`](#benchmarkmaparray-callback-thisarg) +* [`Benchmark.pluck`](#benchmarkpluckarray-property) +* [`Benchmark.reduce`](#benchmarkreducearray-callback-accumulator) + + + + + + +## `Benchmark.prototype` +* [`Benchmark.prototype.aborted`](#benchmarkprototypeaborted) +* [`Benchmark.prototype.compiled`](#benchmarkprototypecompiled) +* [`Benchmark.prototype.count`](#benchmarkprototypecount) +* [`Benchmark.prototype.cycles`](#benchmarkprototypecycles) +* [`Benchmark.prototype.fn`](#benchmarkprototypefn) +* [`Benchmark.prototype.hz`](#benchmarkprototypehz) +* [`Benchmark.prototype.running`](#benchmarkprototyperunning) +* [`Benchmark.prototype.setup`](#benchmarkprototypesetup) +* [`Benchmark.prototype.teardown`](#benchmarkprototypeteardown) +* [`Benchmark.prototype.abort`](#benchmarkprototypeabort) +* [`Benchmark.prototype.clone`](#benchmarkprototypecloneoptions) +* [`Benchmark.prototype.compare`](#benchmarkprototypecompareother) +* [`Benchmark.prototype.emit`](#benchmarkprototypeemittype) +* [`Benchmark.prototype.listeners`](#benchmarkprototypelistenerstype) +* [`Benchmark.prototype.off`](#benchmarkprototypeofftype-listener) +* [`Benchmark.prototype.on`](#benchmarkprototypeontype-listener) +* [`Benchmark.prototype.reset`](#benchmarkprototypereset) +* [`Benchmark.prototype.run`](#benchmarkprototyperunoptions) +* [`Benchmark.prototype.toString`](#benchmarkprototypetostring) + + + + + + +## `Benchmark.options` +* [`Benchmark.options`](#benchmarkoptions) +* [`Benchmark.options.async`](#benchmarkoptionsasync) +* [`Benchmark.options.defer`](#benchmarkoptionsdefer) +* [`Benchmark.options.delay`](#benchmarkoptionsdelay) +* [`Benchmark.options.id`](#benchmarkoptionsid) +* [`Benchmark.options.initCount`](#benchmarkoptionsinitcount) +* [`Benchmark.options.maxTime`](#benchmarkoptionsmaxtime) +* [`Benchmark.options.minSamples`](#benchmarkoptionsminsamples) +* [`Benchmark.options.minTime`](#benchmarkoptionsmintime) +* [`Benchmark.options.name`](#benchmarkoptionsname) +* [`Benchmark.options.onAbort`](#benchmarkoptionsonabort) +* [`Benchmark.options.onComplete`](#benchmarkoptionsoncomplete) +* [`Benchmark.options.onCycle`](#benchmarkoptionsoncycle) +* [`Benchmark.options.onError`](#benchmarkoptionsonerror) +* [`Benchmark.options.onReset`](#benchmarkoptionsonreset) +* [`Benchmark.options.onStart`](#benchmarkoptionsonstart) + + + + + + +## `Benchmark.platform` +* [`Benchmark.platform`](#benchmarkplatform) +* [`Benchmark.platform.description`](#benchmarkplatformdescription) +* [`Benchmark.platform.layout`](#benchmarkplatformlayout) +* [`Benchmark.platform.manufacturer`](#benchmarkplatformmanufacturer) +* [`Benchmark.platform.name`](#benchmarkplatformname) +* [`Benchmark.platform.os`](#benchmarkplatformos) +* [`Benchmark.platform.prerelease`](#benchmarkplatformprerelease) +* [`Benchmark.platform.product`](#benchmarkplatformproduct) +* [`Benchmark.platform.version`](#benchmarkplatformversion) +* [`Benchmark.platform.toString`](#benchmarkplatformtostring) + + + + + + +## `Benchmark.support` +* [`Benchmark.support`](#benchmarksupport) +* [`Benchmark.support.air`](#benchmarksupportair) +* [`Benchmark.support.argumentsClass`](#benchmarksupportargumentsclass) +* [`Benchmark.support.browser`](#benchmarksupportbrowser) +* [`Benchmark.support.charByIndex`](#benchmarksupportcharbyindex) +* [`Benchmark.support.charByOwnIndex`](#benchmarksupportcharbyownindex) +* [`Benchmark.support.decompilation`](#benchmarksupportdecompilation) +* [`Benchmark.support.descriptors`](#benchmarksupportdescriptors) +* [`Benchmark.support.getAllKeys`](#benchmarksupportgetallkeys) +* [`Benchmark.support.iteratesOwnLast`](#benchmarksupportiteratesownfirst) +* [`Benchmark.support.java`](#benchmarksupportjava) +* [`Benchmark.support.nodeClass`](#benchmarksupportnodeclass) +* [`Benchmark.support.timeout`](#benchmarksupporttimeout) + + + + + + +## `Benchmark.prototype.error` +* [`Benchmark.prototype.error`](#benchmarkprototypeerror) + + + + + + +## `Benchmark.prototype.stats` +* [`Benchmark.prototype.stats`](#benchmarkprototypestats) +* [`Benchmark.prototype.stats.deviation`](#benchmark-statsdeviation) +* [`Benchmark.prototype.stats.mean`](#benchmark-statsmean) +* [`Benchmark.prototype.stats.moe`](#benchmark-statsmoe) +* [`Benchmark.prototype.stats.rme`](#benchmark-statsrme) +* [`Benchmark.prototype.stats.sample`](#benchmark-statssample) +* [`Benchmark.prototype.stats.sem`](#benchmark-statssem) +* [`Benchmark.prototype.stats.variance`](#benchmark-statsvariance) + + + + + + +## `Benchmark.prototype.times` +* [`Benchmark.prototype.times`](#benchmarkprototypetimes) +* [`Benchmark.prototype.times.cycle`](#benchmark-timescycle) +* [`Benchmark.prototype.times.elapsed`](#benchmark-timeselapsed) +* [`Benchmark.prototype.times.period`](#benchmark-timesperiod) +* [`Benchmark.prototype.times.timeStamp`](#benchmark-timestimestamp) + + + + + + +## `Benchmark.Deferred` +* [`Benchmark.Deferred`](#benchmarkdeferredclone) + + + + + + +## `Benchmark.Deferred.prototype` +* [`Benchmark.Deferred.prototype.benchmark`](#benchmarkdeferredprototypebenchmark) +* [`Benchmark.Deferred.prototype.cycles`](#benchmarkdeferredprototypecycles) +* [`Benchmark.Deferred.prototype.elapsed`](#benchmarkdeferredprototypeelapsed) +* [`Benchmark.Deferred.prototype.resolve`](#benchmarkdeferredprototyperesolve) +* [`Benchmark.Deferred.prototype.timeStamp`](#benchmarkdeferredprototypetimestamp) + + + + + + +## `Benchmark.Event` +* [`Benchmark.Event`](#benchmarkeventtype) + + + + + + +## `Benchmark.Event.prototype` +* [`Benchmark.Event.prototype.aborted`](#benchmarkeventprototypeaborted) +* [`Benchmark.Event.prototype.cancelled`](#benchmarkeventprototypecancelled) +* [`Benchmark.Event.prototype.result`](#benchmarkeventprototyperesult) +* [`Benchmark.Event.prototype.timeStamp`](#benchmarkeventprototypetimestamp) +* [`Benchmark.Event.prototype.type`](#benchmarkeventprototypetype) + + + + + + +## `Benchmark.Event.prototype.currentTarget` +* [`Benchmark.Event.prototype.currentTarget`](#benchmarkeventprototypecurrenttarget) + + + + + + +## `Benchmark.Event.prototype.target` +* [`Benchmark.Event.prototype.target`](#benchmarkeventprototypetarget) + + + + + + +## `Benchmark.Suite` +* [`Benchmark.Suite`](#benchmarksuitename--options) + + + + + + +## `Benchmark.Suite.prototype` +* [`Benchmark.Suite.prototype.aborted`](#benchmarksuiteprototypeaborted) +* [`Benchmark.Suite.prototype.length`](#benchmarksuiteprototypelength) +* [`Benchmark.Suite.prototype.running`](#benchmarksuiteprototyperunning) +* [`Benchmark.Suite.prototype.abort`](#benchmarksuiteprototypeabort) +* [`Benchmark.Suite.prototype.add`](#benchmarksuiteprototypeaddname-fn--options) +* [`Benchmark.Suite.prototype.clone`](#benchmarksuiteprototypecloneoptions) +* [`Benchmark.Suite.prototype.emit`](#benchmarkprototypeemittype) +* [`Benchmark.Suite.prototype.filter`](#benchmarksuiteprototypefiltercallback) +* [`Benchmark.Suite.prototype.forEach`](#benchmarksuiteprototypeforeachcallback) +* [`Benchmark.Suite.prototype.indexOf`](#benchmarksuiteprototypeindexofvalue) +* [`Benchmark.Suite.prototype.invoke`](#benchmarksuiteprototypeinvokename--arg1-arg2-) +* [`Benchmark.Suite.prototype.join`](#benchmarksuiteprototypejoinseparator-) +* [`Benchmark.Suite.prototype.listeners`](#benchmarkprototypelistenerstype) +* [`Benchmark.Suite.prototype.map`](#benchmarksuiteprototypemapcallback) +* [`Benchmark.Suite.prototype.off`](#benchmarkprototypeofftype-listener) +* [`Benchmark.Suite.prototype.on`](#benchmarkprototypeontype-listener) +* [`Benchmark.Suite.prototype.pluck`](#benchmarksuiteprototypepluckproperty) +* [`Benchmark.Suite.prototype.pop`](#benchmarksuiteprototypepop) +* [`Benchmark.Suite.prototype.push`](#benchmarksuiteprototypepush) +* [`Benchmark.Suite.prototype.reduce`](#benchmarksuiteprototypereducecallback-accumulator) +* [`Benchmark.Suite.prototype.reset`](#benchmarksuiteprototypereset) +* [`Benchmark.Suite.prototype.reverse`](#benchmarksuiteprototypereverse) +* [`Benchmark.Suite.prototype.run`](#benchmarksuiteprototyperunoptions) +* [`Benchmark.Suite.prototype.shift`](#benchmarksuiteprototypeshift) +* [`Benchmark.Suite.prototype.slice`](#benchmarksuiteprototypeslicestart-end) +* [`Benchmark.Suite.prototype.sort`](#benchmarksuiteprototypesortcomparefnnull) +* [`Benchmark.Suite.prototype.splice`](#benchmarksuiteprototypesplicestart-deletecount--val1-val2-) +* [`Benchmark.Suite.prototype.unshift`](#benchmarksuiteprototypeunshift) + + + + + + +## `Benchmark.Suite.options` +* [`Benchmark.Suite.options`](#benchmarksuiteoptions) +* [`Benchmark.Suite.options.name`](#benchmarksuiteoptionsname) + + + + + + + + + + + + +## `Benchmark` + + + +### `Benchmark(name, fn [, options={}])` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L404 "View in source") [Ⓣ][1] + +The Benchmark constructor. + +#### Arguments +1. `name` *(String)*: A name to identify the benchmark. +2. `fn` *(Function|String)*: The test to benchmark. +3. `[options={}]` *(Object)*: Options object. + +#### Example +```js +// 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 +}); +``` + +* * * + + + + + + +### `Benchmark.version` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3268 "View in source") [Ⓣ][1] + +*(String)*: The semantic version number. + +* * * + + + + + + +### `Benchmark.deepClone(value)` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L1225 "View in source") [Ⓣ][1] + +A deep clone utility. + +#### Arguments +1. `value` *(Mixed)*: The value to clone. + +#### Returns +*(Mixed)*: The cloned value. + +* * * + + + + + + +### `Benchmark.each(object, callback, thisArg)` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L1400 "View in source") [Ⓣ][1] + +An iteration utility for arrays and objects. Callbacks may terminate the loop by explicitly returning `false`. + +#### Arguments +1. `object` *(Array|Object)*: The object to iterate over. +2. `callback` *(Function)*: The function called per iteration. +3. `thisArg` *(Mixed)*: The `this` binding for the callback. + +#### Returns +*(Array, Object)*: Returns the object iterated over. + +* * * + + + + + + +### `Benchmark.extend(destination [, source={}])` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L1446 "View in source") [Ⓣ][1] + +Copies enumerable properties from the source(s) object to the destination object. + +#### Arguments +1. `destination` *(Object)*: The destination object. +2. `[source={}]` *(Object)*: The source object. + +#### Returns +*(Object)*: The destination object. + +* * * + + + + + + +### `Benchmark.filter(array, callback, thisArg)` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L1485 "View in source") [Ⓣ][1] + +A generic `Array#filter` like method. + +#### Arguments +1. `array` *(Array)*: The array to iterate over. +2. `callback` *(Function|String)*: The function/alias called per iteration. +3. `thisArg` *(Mixed)*: The `this` binding for the callback. + +#### Returns +*(Array)*: A new array of values that passed callback filter. + +#### Example +```js +// 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'); +``` + +* * * + + + + + + +### `Benchmark.forEach(array, callback, thisArg)` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L1518 "View in source") [Ⓣ][1] + +A generic `Array#forEach` like method. Callbacks may terminate the loop by explicitly returning `false`. + +#### Arguments +1. `array` *(Array)*: The array to iterate over. +2. `callback` *(Function)*: The function called per iteration. +3. `thisArg` *(Mixed)*: The `this` binding for the callback. + +#### Returns +*(Array)*: Returns the array iterated over. + +* * * + + + + + + +### `Benchmark.formatNumber(number)` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L1557 "View in source") [Ⓣ][1] + +Converts a number to a more readable comma-separated string representation. + +#### Arguments +1. `number` *(Number)*: The number to convert. + +#### Returns +*(String)*: The more readable string representation. + +* * * + + + + + + +### `Benchmark.forOwn(object, callback, thisArg)` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L1545 "View in source") [Ⓣ][1] + +Iterates over an object's own properties, executing the `callback` for each. Callbacks may terminate the loop by explicitly returning `false`. + +#### Arguments +1. `object` *(Object)*: The object to iterate over. +2. `callback` *(Function)*: The function executed per own property. +3. `thisArg` *(Mixed)*: The `this` binding for the callback. + +#### Returns +*(Object)*: Returns the object iterated over. + +* * * + + + + + + +### `Benchmark.hasKey(object, key)` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L1572 "View in source") [Ⓣ][1] + +Checks if an object has the specified key as a direct property. + +#### Arguments +1. `object` *(Object)*: The object to check. +2. `key` *(String)*: The key to check for. + +#### Returns +*(Boolean)*: Returns `true` if key is a direct property, else `false`. + +* * * + + + + + + +### `Benchmark.indexOf(array, value [, fromIndex=0])` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L1608 "View in source") [Ⓣ][1] + +A generic `Array#indexOf` like method. + +#### Arguments +1. `array` *(Array)*: The array to iterate over. +2. `value` *(Mixed)*: The value to search for. +3. `[fromIndex=0]` *(Number)*: The index to start searching from. + +#### Returns +*(Number)*: The index of the matched value or `-1`. + +* * * + + + + + + +### `Benchmark.interpolate(string, object)` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L1630 "View in source") [Ⓣ][1] + +Modify a string by replacing named tokens with matching object property values. + +#### Arguments +1. `string` *(String)*: The string to modify. +2. `object` *(Object)*: The template object. + +#### Returns +*(String)*: The modified string. + +* * * + + + + + + +### `Benchmark.invoke(benches, name [, arg1, arg2, ...])` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L1677 "View in source") [Ⓣ][1] + +Invokes a method on all items in an array. + +#### Arguments +1. `benches` *(Array)*: Array of benchmarks to iterate over. +2. `name` *(String|Object)*: The name of the method to invoke OR options object. +3. `[arg1, arg2, ...]` *(Mixed)*: Arguments to invoke the method with. + +#### Returns +*(Array)*: A new array of values returned from each method invoked. + +#### Example +```js +// 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 +}); +``` + +* * * + + + + + + +### `Benchmark.join(object [, separator1=',', separator2=': '])` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L1831 "View in source") [Ⓣ][1] + +Creates a string of joined array values or object key-value pairs. + +#### Arguments +1. `object` *(Array|Object)*: The object to operate on. +2. `[separator1=',']` *(String)*: The separator used between key-value pairs. +3. `[separator2=': ']` *(String)*: The separator used between keys and values. + +#### Returns +*(String)*: The joined result. + +* * * + + + + + + +### `Benchmark.map(array, callback, thisArg)` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L1853 "View in source") [Ⓣ][1] + +A generic `Array#map` like method. + +#### Arguments +1. `array` *(Array)*: The array to iterate over. +2. `callback` *(Function)*: The function called per iteration. +3. `thisArg` *(Mixed)*: The `this` binding for the callback. + +#### Returns +*(Array)*: A new array of values returned by the callback. + +* * * + + + + + + +### `Benchmark.pluck(array, property)` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L1869 "View in source") [Ⓣ][1] + +Retrieves the value of a specified property from all items in an array. + +#### Arguments +1. `array` *(Array)*: The array to iterate over. +2. `property` *(String)*: The property to pluck. + +#### Returns +*(Array)*: A new array of property values. + +* * * + + + + + + +### `Benchmark.reduce(array, callback, accumulator)` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L1885 "View in source") [Ⓣ][1] + +A generic `Array#reduce` like method. + +#### Arguments +1. `array` *(Array)*: The array to iterate over. +2. `callback` *(Function)*: The function called per iteration. +3. `accumulator` *(Mixed)*: Initial value of the accumulator. + +#### Returns +*(Mixed)*: The accumulator. + +* * * + + + + + + + + + +## `Benchmark.prototype` + + + +### `Benchmark.prototype.aborted` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3378 "View in source") [Ⓣ][1] + +*(Boolean)*: A flag to indicate if the benchmark is aborted. + +* * * + + + + + + +### `Benchmark.prototype.compiled` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3354 "View in source") [Ⓣ][1] + +*(Function, String)*: The compiled test function. + +* * * + + + + + + +### `Benchmark.prototype.count` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3330 "View in source") [Ⓣ][1] + +*(Number)*: The number of times a test was executed. + +* * * + + + + + + +### `Benchmark.prototype.cycles` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3338 "View in source") [Ⓣ][1] + +*(Number)*: The number of cycles performed while benchmarking. + +* * * + + + + + + +### `Benchmark.prototype.fn` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3370 "View in source") [Ⓣ][1] + +*(Function, String)*: The test to benchmark. + +* * * + + + + + + +### `Benchmark.prototype.hz` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3346 "View in source") [Ⓣ][1] + +*(Number)*: The number of executions per second. + +* * * + + + + + + +### `Benchmark.prototype.running` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3386 "View in source") [Ⓣ][1] + +*(Boolean)*: A flag to indicate if the benchmark is running. + +* * * + + + + + + +### `Benchmark.prototype.setup` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3449 "View in source") [Ⓣ][1] + +*(Function, String)*: Compiled into the test and executed immediately **before** the test loop. + +#### Example +```js +// 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; + }()) + }()) +}()) +``` + +* * * + + + + + + +### `Benchmark.prototype.teardown` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3457 "View in source") [Ⓣ][1] + +*(Function, String)*: Compiled into the test and executed immediately **after** the test loop. + +* * * + + + + + + +### `Benchmark.prototype.abort()` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L2218 "View in source") [Ⓣ][1] + +Aborts the benchmark without recording times. + +#### Returns +*(Object)*: The benchmark instance. + +* * * + + + + + + +### `Benchmark.prototype.clone(options)` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L2257 "View in source") [Ⓣ][1] + +Creates a new benchmark using the same test and options. + +#### Arguments +1. `options` *(Object)*: Options object to overwrite cloned options. + +#### Returns +*(Object)*: The new benchmark instance. + +#### Example +```js +var bizarro = bench.clone({ + 'name': 'doppelganger' +}); +``` + +* * * + + + + + + +### `Benchmark.prototype.compare(other)` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L2280 "View in source") [Ⓣ][1] + +Determines if a benchmark is faster than another. + +#### Arguments +1. `other` *(Object)*: The benchmark to compare. + +#### Returns +*(Number)*: Returns `-1` if slower, `1` if faster, and `0` if indeterminate. + +* * * + + + + + + +### `Benchmark.Suite.prototype.emit(type)` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L2095 "View in source") [Ⓣ][1] + +Executes all registered listeners of the specified event type. + +#### Arguments +1. `type` *(String|Object)*: The event type or object. + +#### Returns +*(Mixed)*: Returns the return value of the last listener executed. + +* * * + + + + + + +### `Benchmark.Suite.prototype.listeners(type)` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L2125 "View in source") [Ⓣ][1] + +Returns an array of event listeners for a given type that can be manipulated to add or remove listeners. + +#### Arguments +1. `type` *(String)*: The event type. + +#### Returns +*(Array)*: The listeners array. + +* * * + + + + + + +### `Benchmark.Suite.prototype.off([type, listener])` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L2158 "View in source") [Ⓣ][1] + +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. + +#### Arguments +1. `[type]` *(String)*: The event type. +2. `[listener]` *(Function)*: The function to unregister. + +#### Returns +*(Object)*: The benchmark instance. + +#### Example +```js +// 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(); +``` + +* * * + + + + + + +### `Benchmark.Suite.prototype.on(type, listener)` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L2197 "View in source") [Ⓣ][1] + +Registers a listener for the specified event type(s). + +#### Arguments +1. `type` *(String)*: The event type. +2. `listener` *(Function)*: The function to register. + +#### Returns +*(Object)*: The benchmark instance. + +#### Example +```js +// register a listener for an event type +bench.on('cycle', listener); + +// register a listener for multiple event types +bench.on('start cycle', listener); +``` + +* * * + + + + + + +### `Benchmark.prototype.reset()` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L2334 "View in source") [Ⓣ][1] + +Reset properties and abort if running. + +#### Returns +*(Object)*: The benchmark instance. + +* * * + + + + + + +### `Benchmark.prototype.run([options={}])` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3000 "View in source") [Ⓣ][1] + +Runs the benchmark. + +#### Arguments +1. `[options={}]` *(Object)*: Options object. + +#### Returns +*(Object)*: The benchmark instance. + +#### Example +```js +// basic usage +bench.run(); + +// or with options +bench.run({ 'async': true }); +``` + +* * * + + + + + + +### `Benchmark.prototype.toString()` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L2405 "View in source") [Ⓣ][1] + +Displays relevant benchmark information when coerced to a string. + +#### Returns +*(String)*: A string representation of the benchmark instance. + +* * * + + + + + + + + + +## `Benchmark.options` + + + +### `Benchmark.options` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3049 "View in source") [Ⓣ][1] + +*(Object)*: The default options copied by benchmark instances. + +* * * + + + + + + +### `Benchmark.options.async` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3058 "View in source") [Ⓣ][1] + +*(Boolean)*: A flag to indicate that benchmark cycles will execute asynchronously by default. + +* * * + + + + + + +### `Benchmark.options.defer` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3066 "View in source") [Ⓣ][1] + +*(Boolean)*: A flag to indicate that the benchmark clock is deferred. + +* * * + + + + + + +### `Benchmark.options.delay` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3073 "View in source") [Ⓣ][1] + +*(Number)*: The delay between test cycles *(secs)*. + +* * * + + + + + + +### `Benchmark.options.id` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3082 "View in source") [Ⓣ][1] + +*(String)*: Displayed by Benchmark#toString when a `name` is not available *(auto-generated if absent)*. + +* * * + + + + + + +### `Benchmark.options.initCount` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3090 "View in source") [Ⓣ][1] + +*(Number)*: The default number of times to execute a test on a benchmark's first cycle. + +* * * + + + + + + +### `Benchmark.options.maxTime` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3100 "View in source") [Ⓣ][1] + +*(Number)*: The maximum time a benchmark is allowed to run before finishing *(secs)*. Note: Cycle delays aren't counted toward the maximum time. + +* * * + + + + + + +### `Benchmark.options.minSamples` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3108 "View in source") [Ⓣ][1] + +*(Number)*: The minimum sample size required to perform statistical analysis. + +* * * + + + + + + +### `Benchmark.options.minTime` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3116 "View in source") [Ⓣ][1] + +*(Number)*: The time needed to reduce the percent uncertainty of measurement to `1`% *(secs)*. + +* * * + + + + + + +### `Benchmark.options.name` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3124 "View in source") [Ⓣ][1] + +*(String)*: The name of the benchmark. + +* * * + + + + + + +### `Benchmark.options.onAbort` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3132 "View in source") [Ⓣ][1] + +An event listener called when the benchmark is aborted. + +* * * + + + + + + +### `Benchmark.options.onComplete` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3140 "View in source") [Ⓣ][1] + +An event listener called when the benchmark completes running. + +* * * + + + + + + +### `Benchmark.options.onCycle` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3148 "View in source") [Ⓣ][1] + +An event listener called after each run cycle. + +* * * + + + + + + +### `Benchmark.options.onError` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3156 "View in source") [Ⓣ][1] + +An event listener called when a test errors. + +* * * + + + + + + +### `Benchmark.options.onReset` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3164 "View in source") [Ⓣ][1] + +An event listener called when the benchmark is reset. + +* * * + + + + + + +### `Benchmark.options.onStart` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3172 "View in source") [Ⓣ][1] + +An event listener called when the benchmark starts running. + +* * * + + + + + + + + + +## `Benchmark.platform` + + + +### `Benchmark.platform` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3183 "View in source") [Ⓣ][1] + +*(Object)*: Platform object with properties describing things like browser name, version, and operating system. + +* * * + + + + + + +### `Benchmark.platform.description` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3191 "View in source") [Ⓣ][1] + +*(String)*: The platform description. + +* * * + + + + + + +### `Benchmark.platform.layout` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3199 "View in source") [Ⓣ][1] + +*(String, Null)*: The name of the browser layout engine. + +* * * + + + + + + +### `Benchmark.platform.manufacturer` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3223 "View in source") [Ⓣ][1] + +*(String, Null)*: The name of the product's manufacturer. + +* * * + + + + + + +### `Benchmark.platform.name` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3215 "View in source") [Ⓣ][1] + +*(String, Null)*: The name of the browser/environment. + +* * * + + + + + + +### `Benchmark.platform.os` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3231 "View in source") [Ⓣ][1] + +*(String, Null)*: The name of the operating system. + +* * * + + + + + + +### `Benchmark.platform.prerelease` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3239 "View in source") [Ⓣ][1] + +*(String, Null)*: The alpha/beta release indicator. + +* * * + + + + + + +### `Benchmark.platform.product` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3207 "View in source") [Ⓣ][1] + +*(String, Null)*: The name of the product hosting the browser. + +* * * + + + + + + +### `Benchmark.platform.version` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3247 "View in source") [Ⓣ][1] + +*(String, Null)*: The browser/environment version. + +* * * + + + + + + +### `Benchmark.platform.toString()` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3256 "View in source") [Ⓣ][1] + +Return platform description when the platform object is coerced to a string. + +#### Returns +*(String)*: The platform description. + +* * * + + + + + + + + + +## `Benchmark.support` + + + +### `Benchmark.support` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L135 "View in source") [Ⓣ][1] + +*(Object)*: An object used to flag environments/features. + +* * * + + + + + + +### `Benchmark.support.air` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L145 "View in source") [Ⓣ][1] + +*(Boolean)*: Detect Adobe AIR. + +* * * + + + + + + +### `Benchmark.support.argumentsClass` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L153 "View in source") [Ⓣ][1] + +*(Boolean)*: Detect if `arguments` objects have the correct internal [[Class]] value. + +* * * + + + + + + +### `Benchmark.support.browser` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L161 "View in source") [Ⓣ][1] + +*(Boolean)*: Detect if in a browser environment. + +* * * + + + + + + +### `Benchmark.support.charByIndex` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L169 "View in source") [Ⓣ][1] + +*(Boolean)*: Detect if strings support accessing characters by index. + +* * * + + + + + + +### `Benchmark.support.charByOwnIndex` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L179 "View in source") [Ⓣ][1] + +*(Boolean)*: Detect if strings have indexes as own properties. + +* * * + + + + + + +### `Benchmark.support.decompilation` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L207 "View in source") [Ⓣ][1] + +*(Boolean)*: Detect if functions support decompilation. + +* * * + + + + + + +### `Benchmark.support.descriptors` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L228 "View in source") [Ⓣ][1] + +*(Boolean)*: Detect ES5+ property descriptor API. + +* * * + + + + + + +### `Benchmark.support.getAllKeys` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L242 "View in source") [Ⓣ][1] + +*(Boolean)*: Detect ES5+ Object.getOwnPropertyNames(). + +* * * + + + + + + +### `Benchmark.support.iteratesOwnFirst` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L255 "View in source") [Ⓣ][1] + +*(Boolean)*: Detect if own properties are iterated before inherited properties *(all but IE < `9`)*. + +* * * + + + + + + +### `Benchmark.support.java` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L190 "View in source") [Ⓣ][1] + +*(Boolean)*: Detect if Java is enabled/exposed. + +* * * + + + + + + +### `Benchmark.support.nodeClass` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L272 "View in source") [Ⓣ][1] + +*(Boolean)*: 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". + +* * * + + + + + + +### `Benchmark.support.timeout` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L198 "View in source") [Ⓣ][1] + +*(Boolean)*: Detect if the Timers API exists. + +* * * + + + + + + + + + +## `Benchmark.prototype.error` + + + +### `Benchmark.prototype.error` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3362 "View in source") [Ⓣ][1] + +*(Object)*: The error object if the test failed. + +* * * + + + + + + + + + +## `Benchmark.prototype.stats` + + + +### `Benchmark.prototype.stats` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3465 "View in source") [Ⓣ][1] + +*(Object)*: An object of stats including mean, margin or error, and standard deviation. + +* * * + + + + + + +### `Benchmark.prototype.stats.deviation` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3497 "View in source") [Ⓣ][1] + +*(Number)*: The sample standard deviation. + +* * * + + + + + + +### `Benchmark.prototype.stats.mean` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3505 "View in source") [Ⓣ][1] + +*(Number)*: The sample arithmetic mean. + +* * * + + + + + + +### `Benchmark.prototype.stats.moe` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3473 "View in source") [Ⓣ][1] + +*(Number)*: The margin of error. + +* * * + + + + + + +### `Benchmark.prototype.stats.rme` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3481 "View in source") [Ⓣ][1] + +*(Number)*: The relative margin of error *(expressed as a percentage of the mean)*. + +* * * + + + + + + +### `Benchmark.prototype.stats.sample` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3513 "View in source") [Ⓣ][1] + +*(Array)*: The array of sampled periods. + +* * * + + + + + + +### `Benchmark.prototype.stats.sem` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3489 "View in source") [Ⓣ][1] + +*(Number)*: The standard error of the mean. + +* * * + + + + + + +### `Benchmark.prototype.stats.variance` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3521 "View in source") [Ⓣ][1] + +*(Number)*: The sample variance. + +* * * + + + + + + + + + +## `Benchmark.prototype.times` + + + +### `Benchmark.prototype.times` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3530 "View in source") [Ⓣ][1] + +*(Object)*: An object of timing data including cycle, elapsed, period, start, and stop. + +* * * + + + + + + +### `Benchmark.prototype.times.cycle` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3538 "View in source") [Ⓣ][1] + +*(Number)*: The time taken to complete the last cycle *(secs)*. + +* * * + + + + + + +### `Benchmark.prototype.times.elapsed` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3546 "View in source") [Ⓣ][1] + +*(Number)*: The time taken to complete the benchmark *(secs)*. + +* * * + + + + + + +### `Benchmark.prototype.times.period` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3554 "View in source") [Ⓣ][1] + +*(Number)*: The time taken to execute the test once *(secs)*. + +* * * + + + + + + +### `Benchmark.prototype.times.timeStamp` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3562 "View in source") [Ⓣ][1] + +*(Number)*: A timestamp of when the benchmark started *(ms)*. + +* * * + + + + + + + + + +## `Benchmark.Deferred` + + + +### `Benchmark.Deferred(clone)` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L445 "View in source") [Ⓣ][1] + +The Deferred constructor. + +#### Arguments +1. `clone` *(Object)*: The cloned benchmark instance. + +* * * + + + + + + + + + +## `Benchmark.Deferred.prototype` + + + +### `Benchmark.Deferred.prototype.benchmark` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3606 "View in source") [Ⓣ][1] + +*(Object)*: The deferred benchmark instance. + +* * * + + + + + + +### `Benchmark.Deferred.prototype.cycles` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3614 "View in source") [Ⓣ][1] + +*(Number)*: The number of deferred cycles performed while benchmarking. + +* * * + + + + + + +### `Benchmark.Deferred.prototype.elapsed` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3622 "View in source") [Ⓣ][1] + +*(Number)*: The time taken to complete the deferred benchmark *(secs)*. + +* * * + + + + + + +### `Benchmark.Deferred.prototype.resolve` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L1188 "View in source") [Ⓣ][1] + +*(Unknown)*: Handles cycling/completing the deferred benchmark. + +* * * + + + + + + +### `Benchmark.Deferred.prototype.timeStamp` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3630 "View in source") [Ⓣ][1] + +*(Number)*: A timestamp of when the deferred benchmark started *(ms)*. + +* * * + + + + + + + + + +## `Benchmark.Event` + + + +### `Benchmark.Event(type)` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L461 "View in source") [Ⓣ][1] + +The Event constructor. + +#### Arguments +1. `type` *(String|Object)*: The event type. + +* * * + + + + + + + + + +## `Benchmark.Event.prototype` + + + +### `Benchmark.Event.prototype.aborted` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3646 "View in source") [Ⓣ][1] + +*(Boolean)*: A flag to indicate if the emitters listener iteration is aborted. + +* * * + + + + + + +### `Benchmark.Event.prototype.cancelled` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3654 "View in source") [Ⓣ][1] + +*(Boolean)*: A flag to indicate if the default action is cancelled. + +* * * + + + + + + +### `Benchmark.Event.prototype.result` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3670 "View in source") [Ⓣ][1] + +*(Mixed)*: The return value of the last executed listener. + +* * * + + + + + + +### `Benchmark.Event.prototype.timeStamp` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3686 "View in source") [Ⓣ][1] + +*(Number)*: A timestamp of when the event was created *(ms)*. + +* * * + + + + + + +### `Benchmark.Event.prototype.type` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3694 "View in source") [Ⓣ][1] + +*(String)*: The event type. + +* * * + + + + + + + + + +## `Benchmark.Event.prototype.currentTarget` + + + +### `Benchmark.Event.prototype.currentTarget` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3662 "View in source") [Ⓣ][1] + +*(Object)*: The object whose listeners are currently being processed. + +* * * + + + + + + + + + +## `Benchmark.Event.prototype.target` + + + +### `Benchmark.Event.prototype.target` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3678 "View in source") [Ⓣ][1] + +*(Object)*: The object to which the event was originally emitted. + +* * * + + + + + + + + + +## `Benchmark.Suite` + + + +### `Benchmark.Suite(name [, options={}])` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L507 "View in source") [Ⓣ][1] + +The Suite constructor. + +#### Arguments +1. `name` *(String)*: A name to identify the suite. +2. `[options={}]` *(Object)*: Options object. + +#### Example +```js +// 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 +}); +``` + +* * * + + + + + + + + + +## `Benchmark.Suite.prototype` + + + +### `Benchmark.Suite.prototype.aborted` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3735 "View in source") [Ⓣ][1] + +*(Boolean)*: A flag to indicate if the suite is aborted. + +* * * + + + + + + +### `Benchmark.Suite.prototype.length` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3727 "View in source") [Ⓣ][1] + +*(Number)*: The number of benchmarks in the suite. + +* * * + + + + + + +### `Benchmark.Suite.prototype.running` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3743 "View in source") [Ⓣ][1] + +*(Boolean)*: A flag to indicate if the suite is running. + +* * * + + + + + + +### `Benchmark.Suite.prototype.abort()` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L1902 "View in source") [Ⓣ][1] + +Aborts all benchmarks in the suite. + +#### Returns +*(Object)*: The suite instance. + +* * * + + + + + + +### `Benchmark.Suite.prototype.add(name, fn [, options={}])` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L1962 "View in source") [Ⓣ][1] + +Adds a test to the benchmark suite. + +#### Arguments +1. `name` *(String)*: A name to identify the benchmark. +2. `fn` *(Function|String)*: The test to benchmark. +3. `[options={}]` *(Object)*: Options object. + +#### Returns +*(Object)*: The benchmark instance. + +#### Example +```js +// 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 +}); +``` + +* * * + + + + + + +### `Benchmark.Suite.prototype.clone(options)` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L1981 "View in source") [Ⓣ][1] + +Creates a new suite with cloned benchmarks. + +#### Arguments +1. `options` *(Object)*: Options object to overwrite cloned options. + +#### Returns +*(Object)*: The new suite instance. + +* * * + + + + + + +### `Benchmark.Suite.prototype.emit(type)` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L2095 "View in source") [Ⓣ][1] + +Executes all registered listeners of the specified event type. + +#### Arguments +1. `type` *(String|Object)*: The event type or object. + +#### Returns +*(Mixed)*: Returns the return value of the last listener executed. + +* * * + + + + + + +### `Benchmark.Suite.prototype.filter(callback)` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L2004 "View in source") [Ⓣ][1] + +An `Array#filter` like method. + +#### Arguments +1. `callback` *(Function|String)*: The function/alias called per iteration. + +#### Returns +*(Object)*: A new suite of benchmarks that passed callback filter. + +* * * + + + + + + +### `Benchmark.Suite.prototype.forEach(callback)` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3753 "View in source") [Ⓣ][1] + +An `Array#forEach` like method. Callbacks may terminate the loop by explicitly returning `false`. + +#### Arguments +1. `callback` *(Function)*: The function called per iteration. + +#### Returns +*(Object)*: The suite iterated over. + +* * * + + + + + + +### `Benchmark.Suite.prototype.indexOf(value)` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3762 "View in source") [Ⓣ][1] + +An `Array#indexOf` like method. + +#### Arguments +1. `value` *(Mixed)*: The value to search for. + +#### Returns +*(Number)*: The index of the matched value or `-1`. + +* * * + + + + + + +### `Benchmark.Suite.prototype.invoke(name [, arg1, arg2, ...])` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3772 "View in source") [Ⓣ][1] + +Invokes a method on all benchmarks in the suite. + +#### Arguments +1. `name` *(String|Object)*: The name of the method to invoke OR options object. +2. `[arg1, arg2, ...]` *(Mixed)*: Arguments to invoke the method with. + +#### Returns +*(Array)*: A new array of values returned from each method invoked. + +* * * + + + + + + +### `Benchmark.Suite.prototype.join([separator=','])` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3781 "View in source") [Ⓣ][1] + +Converts the suite of benchmarks to a string. + +#### Arguments +1. `[separator=',']` *(String)*: A string to separate each element of the array. + +#### Returns +*(String)*: The string. + +* * * + + + + + + +### `Benchmark.Suite.prototype.listeners(type)` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L2125 "View in source") [Ⓣ][1] + +Returns an array of event listeners for a given type that can be manipulated to add or remove listeners. + +#### Arguments +1. `type` *(String)*: The event type. + +#### Returns +*(Array)*: The listeners array. + +* * * + + + + + + +### `Benchmark.Suite.prototype.map(callback)` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3790 "View in source") [Ⓣ][1] + +An `Array#map` like method. + +#### Arguments +1. `callback` *(Function)*: The function called per iteration. + +#### Returns +*(Array)*: A new array of values returned by the callback. + +* * * + + + + + + +### `Benchmark.Suite.prototype.off([type, listener])` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L2158 "View in source") [Ⓣ][1] + +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. + +#### Arguments +1. `[type]` *(String)*: The event type. +2. `[listener]` *(Function)*: The function to unregister. + +#### Returns +*(Object)*: The benchmark instance. + +#### Example +```js +// 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(); +``` + +* * * + + + + + + +### `Benchmark.Suite.prototype.on(type, listener)` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L2197 "View in source") [Ⓣ][1] + +Registers a listener for the specified event type(s). + +#### Arguments +1. `type` *(String)*: The event type. +2. `listener` *(Function)*: The function to register. + +#### Returns +*(Object)*: The benchmark instance. + +#### Example +```js +// register a listener for an event type +bench.on('cycle', listener); + +// register a listener for multiple event types +bench.on('start cycle', listener); +``` + +* * * + + + + + + +### `Benchmark.Suite.prototype.pluck(property)` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3799 "View in source") [Ⓣ][1] + +Retrieves the value of a specified property from all benchmarks in the suite. + +#### Arguments +1. `property` *(String)*: The property to pluck. + +#### Returns +*(Array)*: A new array of property values. + +* * * + + + + + + +### `Benchmark.Suite.prototype.pop()` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3807 "View in source") [Ⓣ][1] + +Removes the last benchmark from the suite and returns it. + +#### Returns +*(Mixed)*: The removed benchmark. + +* * * + + + + + + +### `Benchmark.Suite.prototype.push()` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3815 "View in source") [Ⓣ][1] + +Appends benchmarks to the suite. + +#### Returns +*(Number)*: The suite's new length. + +* * * + + + + + + +### `Benchmark.Suite.prototype.reduce(callback, accumulator)` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3834 "View in source") [Ⓣ][1] + +An `Array#reduce` like method. + +#### Arguments +1. `callback` *(Function)*: The function called per iteration. +2. `accumulator` *(Mixed)*: Initial value of the accumulator. + +#### Returns +*(Mixed)*: The accumulator. + +* * * + + + + + + +### `Benchmark.Suite.prototype.reset()` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L2019 "View in source") [Ⓣ][1] + +Resets all benchmarks in the suite. + +#### Returns +*(Object)*: The suite instance. + +* * * + + + + + + +### `Benchmark.Suite.prototype.reverse()` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L638 "View in source") [Ⓣ][1] + +Rearrange the host array's elements in reverse order. + +#### Returns +*(Array)*: The reversed array. + +* * * + + + + + + +### `Benchmark.Suite.prototype.run([options={}])` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L2056 "View in source") [Ⓣ][1] + +Runs the suite. + +#### Arguments +1. `[options={}]` *(Object)*: Options object. + +#### Returns +*(Object)*: The suite instance. + +#### Example +```js +// basic usage +suite.run(); + +// or with options +suite.run({ 'async': true, 'queued': true }); +``` + +* * * + + + + + + +### `Benchmark.Suite.prototype.shift()` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L671 "View in source") [Ⓣ][1] + +Removes the first element of the host array and returns it. + +#### Returns +*(Mixed)*: The first element of the array. + +* * * + + + + + + +### `Benchmark.Suite.prototype.slice(start, end)` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L684 "View in source") [Ⓣ][1] + +Creates an array of the host array's elements from the start index up to, but not including, the end index. + +#### Arguments +1. `start` *(Number)*: The starting index. +2. `end` *(Number)*: The end index. + +#### Returns +*(Array)*: The new array. + +* * * + + + + + + +### `Benchmark.Suite.prototype.sort([compareFn=null])` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3824 "View in source") [Ⓣ][1] + +Sorts the benchmarks of the suite. + +#### Arguments +1. `[compareFn=null]` *(Function)*: A function that defines the sort order. + +#### Returns +*(Object)*: The sorted suite. + +* * * + + + + + + +### `Benchmark.Suite.prototype.splice(start, deleteCount [, val1, val2, ...])` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L714 "View in source") [Ⓣ][1] + +Allows removing a range of elements and/or inserting elements into the host array. + +#### Arguments +1. `start` *(Number)*: The start index. +2. `deleteCount` *(Number)*: The number of elements to delete. +3. `[val1, val2, ...]` *(Mixed)*: values to insert at the `start` index. + +#### Returns +*(Array)*: An array of removed elements. + +* * * + + + + + + +### `Benchmark.Suite.prototype.unshift()` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L749 "View in source") [Ⓣ][1] + +Appends arguments to the host array. + +#### Returns +*(Number)*: The new length. + +* * * + + + + + + + + + +## `Benchmark.Suite.options` + + + +### `Benchmark.Suite.options` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3706 "View in source") [Ⓣ][1] + +*(Object)*: The default options copied by suite instances. + +* * * + + + + + + +### `Benchmark.Suite.options.name` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3714 "View in source") [Ⓣ][1] + +*(String)*: The name of the suite. + +* * * + + + + + + + + + + + [1]: #Benchmark "Jump back to the TOC." \ No newline at end of file diff --git a/web/src/vendor/benchmark/doc/parse.php b/web/src/vendor/benchmark/doc/parse.php new file mode 100644 index 00000000..565b78fb --- /dev/null +++ b/web/src/vendor/benchmark/doc/parse.php @@ -0,0 +1,35 @@ + '../' . $file, + 'title' => 'Benchmark.js v1.0.0', + 'url' => 'https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js' + )); + + // save to a .md file + file_put_contents($output . '.md', $markdown); + + // print + header('Content-Type: text/plain;charset=utf-8'); + echo $markdown . PHP_EOL; + +?> diff --git a/web/src/vendor/benchmark/example/jsperf/index.html b/web/src/vendor/benchmark/example/jsperf/index.html new file mode 100644 index 00000000..040ddb63 --- /dev/null +++ b/web/src/vendor/benchmark/example/jsperf/index.html @@ -0,0 +1,287 @@ + + + + + + Benchmark.js test page | jsPerf + + + + + + +
+
+

Benchmark.js test page

+

JavaScript performance comparison

+
+ +

+ Test case created by Mathias + + and last updated +

+ +
+

Info

+

+ This is just a test document for Benchmark.js. +

+
+ +
+

Preparation code

+
<div>Lorem ipsum</div>
<script>
  var arr = [1, 5, 4, 2, 3];

  function init() {
    window.console && console.log('init called');
  }
</script>
<script>
Benchmark.prototype.setup = function() {
  window.foo = 42;
  var x = arr;
};

Benchmark.prototype.teardown = function() {
  window.foo = 24;
};
</script>
+
+ +
+

Preparation code output

+
+
Lorem ipsum
+
+
+ +
+

Test runner

+

+ Warning! For accurate results, please disable Firebug before running the tests. (Why?) +

+

+ Java applet disabled. +

+

+ +

+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Testing in
TestOps/sec
+
Normal
+
+
x.sort(function(a, b) {
  return a - b;
});
+
+
Exit Early
+
+
x.sort(function(a, b) {
  return a - b;
});
return;
+
+
Async
+
+
// async test
setTimeout(function() {
  deferred.resolve();
}, 10);
+
+
Error
+
+
x.foo(); // unknown method
+
+
Comments
+
+
// comments at start
x.reverse().sort(function(a, b) {
  return a - b;
});
// comments at end
+
+ +

+ You can edit these tests or add even more tests to this page + by appending /edit to the URL. +

+
+ +
+

Compare results of other browsers

+
+
+ +
+

0 comments

+
+
+
+

Add a comment

+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+
+
+
+
+
+ + + + + + + + + + + diff --git a/web/src/vendor/benchmark/example/jsperf/main.css b/web/src/vendor/benchmark/example/jsperf/main.css new file mode 100644 index 00000000..52d42ef9 --- /dev/null +++ b/web/src/vendor/benchmark/example/jsperf/main.css @@ -0,0 +1,588 @@ +html, body, h1, h2, h3, fieldset, #faq, #faq dt, #faq dd { + margin: 0; + padding: 0; + border: 0; +} + +table, p, ul, h1, h2, h3, #error-info, form div, #faq, .bs-rt { + margin-bottom: 1em; +} + +button, input, textarea, a, .bs-rt { + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + border-radius: 4px; +} + +html, input, textarea, button { + font: 1em/1.5 sans-serif; +} + +html { + background: #c4c4c4; + height: 100%; +} + +body { + background: #fff; + border: solid #aaa; + border-width: 0 1px; + width: 60em; + padding: 0 2.5em; + margin: 0 auto; + min-height: 100%; +} + +a { + color: #357ab0; + padding: .2em; +} + +a:hover, a:focus { + text-decoration: none; +} + +blockquote { + margin: 0 0 1em; + border-left: 5px solid #b4b4b4; + padding-left: .5em; +} + +table { + width: 100%; + border-collapse: collapse; +} + +thead th, button:hover, button:focus, .submit:hover, .submit:focus, a:hover, a:focus, #comments .meta a:hover, #comments .meta a:focus, li.current a:hover, li.current a:focus, form h3, #comments .owner .meta { + background: #1a6ab9; + background-image: -moz-linear-gradient(top, #6ca5dd, #1a6ab9); + background-image: -o-linear-gradient(top, #6ca5dd, #1a6ab9); + background-image: -webkit-gradient(linear, left top, left bottom, from(#6ca5dd), to(#1a6ab9)); + background-image: -webkit-linear-gradient(#6ca5dd, #1a6ab9); + background-image: linear-gradient(top, #6ca5dd, #1a6ab9); + filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#6ca5dd', EndColorStr='#1a6ab9'); + color: #fff; +} + +caption, #comments .meta { + background: #bcbcbc; + background-image: -moz-linear-gradient(top, #d0d0d0, #a7a7a7); + background-image: -o-linear-gradient(top, #d0d0d0, #a7a7a7); + background-image: -webkit-gradient(linear, left top, left bottom, from(#d0d0d0), to(#a7a7a7)); + background-image: -webkit-linear-gradient(#d0d0d0, #a7a7a7); + background-image: linear-gradient(top, #d0d0d0, #a7a7a7); + filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#d0d0d0', EndColorStr='#a7a7a7'); + color: #555; +} + +thead th, caption { + font-weight: bold; +} + +.js tbody th:hover, .js tbody th:focus { + text-decoration: underline; + cursor: pointer; +} + +tbody th, td { + border: solid #b4b4b4; + border-width: 0 1px 1px 0; +} + +tbody th { + background: #dde4ea; + min-width: 100px; +} + +tbody th div { + max-width: 200px; + word-wrap: break-word; + overflow: auto; +} + +td.results { + text-align: center; + border-right: 0; +} + +.results span, small { + display: block; + font-size: .8em; +} + +td, th, caption { + padding: .2em .5em; +} + +td.fastest { + background: #9cee82; +} + +tr:last-child td, tr:last-child th { + border-bottom: 0; +} + +td.slowest, td.error, .invalid { + background: pink; +} + +/* needs its own rule because of buggy IE */ +:focus:invalid { + background: pink; +} + +td.error { + text-transform: uppercase; + font-weight: bold; +} + +button, .submit { + padding: .35em .5em; + cursor: pointer; + color: #000; + border: 1px solid #999; + background: #dadada; + background-image: -moz-linear-gradient(top, #ebebeb, #b8b8b8); + background-image: -o-linear-gradient(top, #ebebeb, #b8b8b8); + background-image: -webkit-gradient(linear, left top, left bottom, from(#ebebeb), to(#b8b8b8)); + background-image: -webkit-linear-gradient(top, #ebebeb, #b8b8b8); + background-image: linear-gradient(top, #ebebeb, #b8b8b8); + filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#ebebeb', EndColorStr='#b8b8b8'); +} + +a:hover span, a:focus span, #comments .owner .meta a { + color: #fff; +} + +#controls, #run, .buttons { + float: right; +} + +button:hover, button:focus, .submit:hover, .submit:focus { + border-color: #357ab0 +} + +#add-buttons button { + padding: .15em .4em; + font-size: 11px; + font-weight: bold; +} + +form label { + float: left; + width: 14em; + cursor: pointer; + text-align: right; + margin-right: 1em; + padding: .4em; +} + +label.inline { + float: none; + padding: 0; + margin: 0; +} + +label[for="visible"], label[for$="][defer]"] { + position: relative; + top: -.37em; +} + +label span { + display: block; + font-size: 90%; + color: #b4b4b4; +} + +label em { + color: red; + font-style: normal; +} + +.js #advanced { + display: none; +} + +#show-advanced { + display: none; +} + +.js #show-advanced { + display: block; +} + +section { + display: block; + border-top: 1px solid #ccc; + padding-top: 2em; + margin: 2em 0; +} + +textarea { + resize: vertical; + height: 15em; + width: 42.6em; + *width: 42.4em; /* IE < 8 */ +} + +input, textarea { + border: 1px solid #b4b4b4; + padding: .4em; +} + +#visible, #calibrate { /* checkboxes, for IE */ + border: 0; + padding: 0; +} + +form h2, form h3, form h4, p.error, .preview, #add-libraries, #add-buttons { + padding-left: 250px; + display: block; +} + +.js .question, hgroup h2, #controls, #firebug, #java { + display: none; +} + +pre { + width: 100%; + overflow: auto; +} + +table #results-1 { + width: 100px; +} + +table pre { + *padding: 1.5em 0; /* IE < 8 */ + *overflow-y: hidden; /* IE < 8 */ +} + +table pre, table td.code { + width: 650px; +} + +mark { + background: #ff9; + padding: .2em .1em; +} + +h1, h2, h3, h4 { + font-weight: bold; + font-size: 1em; +} + +h1 { + padding-top: 1em; + font-size: 1.4em; +} + +form h3 { + padding-top: .2em; + padding-bottom: .2em; +} + +h1 em { + font-style: normal; +} + +h1 strong { + font-style: italic; + font-family: Monaco, 'Lucida Console', monospace; +} + +li.current a { + background: #90ee85; +} + +#donate { + display: block; + background: #ffffdc; + border: 1px solid #faa700; + padding: 1em; +} + +#donate h1 { + padding-top: 0; + font-size: 16px; +} + +#paypal { + text-align: center; +} + +footer { + display: block; + margin-top: 2em; + padding: .5em 0 1.5em; + border-top: 2px solid #c4c4c4; +} + +#add-test { + margin-right: .3em; +} + +#bs-chart { + overflow: auto; +} + +#bs-logo { + margin: 0; +} + +#bs-logo span, applet { + position: absolute; + left: -9999em; +} + +#bs-logo a { + display: block; + width: 232px; + height: 39px; + filter: none; + background: url(//www.browserscope.org/static/img/logo.png) 0 0 no-repeat; +} + +#bs-ua { + padding: .5em .5em 0; + color: #555; +} + +#bs-results .bs-rt { + font-size: 10pt; + padding: .5em; + background: #ddd; +} + +#bs-results td { + border: 1px solid #ddd; + padding: .4em; + white-space: nowrap; +} + +#bs-results .rt-ua-cur { + font-style: italic; + font-weight: bold; +} + +#bs-results .bs-rt-message { + padding: 3em; + text-align: center; + font-weight: bold; + color: #555; +} + +#bs-results .google-visualization-table-tr-head td { + white-space: normal; +} + +#controls { + margin-top: -3.35em; +} + +#comments h1 { + padding: 0; +} + +#comments .meta img { + position: absolute; + left: 0; + top: 0; + margin: 0; +} + +#comments .meta img { + top: 2px; + left: 2px; +} + +#comments .meta { + padding-left: 35px; + margin-top: 0; + width: 923px; + line-height: 30px; +} + +#comments .meta a { + font-weight: bold; + color: #555; +} + +#comments article div { + padding: 0 1em 0; +} + +#comments article { + display: block; + border: 1px solid #b4b4b4; + position: relative; + margin-bottom: 1em; +} + +/* needs its own rule (cannot be grouped with `tbody th`) because of buggy IE */ +#comments article:target { + background: #dde4ea; +} + +#error-info.show, .meta strong, #firebug strong, #java strong, #status strong { + background: pink; + border: 1px solid #b00b00; + padding: .4em; +} + +#error-info.show { + padding: .5em 1em; +} + +#error-info, code, samp, var, textarea, #slug { + font-family: Monaco, monospace; + font-size: .9em; +} + +#java strong { + background: #ffffdc; + border: 1px solid #faa700; +} + +#slug { + font-size: 1em; +} + +#faq dt { + margin-top: 1em; + font-weight: bold; +} + +#faq dt a { + display: none; +} + +#faq dt:hover a { + display: inline; +} + +#faq dt:target, #faq dt:target + dd { + background: #90ee85; + margin: 0 -.8em; + padding: 0 .8em; +} + +#faq dt:target + dd { + padding-bottom: .5em; + margin-bottom: -.5em; +} + +#faq dt:target { + margin-top: .5em; + padding-top: .5em; +} + +#firebug, #java, #status { + margin: 0 0 1em; + padding: .3em 0; +} + +#prep-code pre { + max-height: 500px; + overflow: auto; +} + +#controls.show, #firebug.show, #java.show { + display: block; +} + +.co1, .co2, .coMULTI { + font-style: italic; +} + +.error { + color: #b00b00; +} + +.imp { + color: red; +} + +.kw1, .kw3 { + color: #006; +} + +.kw2 { + color: #036; +} + +.co1, .coMULTI { + color: #060; +} + +.co2 { + color: #096; +} + +.es0 { + color: #009; +} + +.br0 { + color: #090; +} + +.sy0 { + color: #393; +} + +.st0 { + color: #36c; +} + +.nu0 { + color: #c00; +} + +.me1 { + color: #606; +} + +/* < 1051px */ +@media (max-width: 1050px) { + table pre, table td.code { + width: 550px; + } +} + +/* < 1041px */ +@media (max-width: 1040px) { + body { + margin: 0; + border: 0; + } + + body, #comments .meta { + width: 100%; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + } + +} + +/* < 801px */ +@media (max-width: 800px) { + table pre, table td.code { + width: 450px; + } +} + +/* < 681px */ +@media (max-width: 680px) { + table pre, table td.code { + width: 350px; + } +} + +/* < 651px */ +@media (max-width: 650px) { + table pre, table td.code { + width: 200px; + } +} diff --git a/web/src/vendor/benchmark/example/jsperf/ui.js b/web/src/vendor/benchmark/example/jsperf/ui.js new file mode 100644 index 00000000..8270cd66 --- /dev/null +++ b/web/src/vendor/benchmark/example/jsperf/ui.js @@ -0,0 +1,745 @@ +/*! + * ui.js + * Copyright Mathias Bynens + * Modified by John-David Dalton + * Available under MIT license + */ +(function(window, document) { + + /** Java applet archive path */ + var archive = '../../nano.jar'; + + /** Cache of error messages */ + var errors = []; + + /** Google Analytics account id */ + var gaId = ''; + + /** Cache of event handlers */ + var handlers = {}; + + /** A flag to indicate that the page has loaded */ + var pageLoaded = false; + + /** Benchmark results element id prefix (e.g. `results-1`) */ + var prefix = 'results-'; + + /** The element responsible for scrolling the page (assumes ui.js is just before ) */ + var scrollEl = document.body; + + /** Used to resolve a value's internal [[Class]] */ + var toString = {}.toString; + + /** Namespace */ + var ui = new Benchmark.Suite; + + /** Object containing various CSS class names */ + var classNames = { + // used for error styles + 'error': 'error', + // used to make content visible + 'show': 'show', + // used to reset result styles + 'results': 'results' + }; + + /** Used to flag environments/features */ + var has = { + // used for pre-populating form fields + 'localStorage': !!function() { + try { + return !localStorage.getItem(+new Date); + } catch(e) { } + }(), + // used to distinguish between a regular test page and an embedded chart + 'runner': !!$('runner') + }; + + /** Object containing various text messages */ + var texts = { + // inner text for the various run button states + 'run': { + 'again': 'Run again', + 'ready': 'Run tests', + 'running': 'Stop running' + }, + // common status values + 'status': { + 'again': 'Done. Ready to run again.', + 'ready': 'Ready to run.' + } + }; + + /** The options object for Benchmark.Suite#run */ + var runOptions = { + 'async': true, + 'queued': true + }; + + /** API shortcuts */ + var each = Benchmark.each, + extend = Benchmark.extend, + filter = Benchmark.filter, + forOwn = Benchmark.forOwn, + formatNumber = Benchmark.formatNumber, + indexOf = Benchmark.indexOf, + invoke = Benchmark.invoke, + join = Benchmark.join; + + /*--------------------------------------------------------------------------*/ + + handlers.benchmark = { + + /** + * The onCycle callback, used for onStart as well, assigned to new benchmarks. + * + * @private + */ + 'cycle': function() { + var bench = this, + size = bench.stats.sample.length; + + if (!bench.aborted) { + setStatus(bench.name + ' × ' + formatNumber(bench.count) + ' (' + + size + ' sample' + (size == 1 ? '' : 's') + ')'); + } + }, + + /** + * The onStart callback assigned to new benchmarks. + * + * @private + */ + 'start': function() { + // call user provided init() function + if (isFunction(window.init)) { + init(); + } + } + }; + + handlers.button = { + + /** + * The "run" button click event handler used to run or abort the benchmarks. + * + * @private + */ + 'run': function() { + var stopped = !ui.running; + ui.abort(); + ui.length = 0; + + if (stopped) { + logError({ 'clear': true }); + ui.push.apply(ui, filter(ui.benchmarks, function(bench) { + return !bench.error && bench.reset(); + })); + ui.run(runOptions); + } + } + }; + + handlers.title = { + + /** + * The title table cell click event handler used to run the corresponding benchmark. + * + * @private + * @param {Object} event The event object. + */ + 'click': function(event) { + event || (event = window.event); + + var id, + index, + target = event.target || event.srcElement; + + while (target && !(id = target.id)) { + target = target.parentNode; + } + index = id && --id.split('-')[1] || 0; + ui.push(ui.benchmarks[index].reset()); + ui.running ? ui.render(index) : ui.run(runOptions); + }, + + /** + * The title cell keyup event handler used to simulate a mouse click when hitting the ENTER key. + * + * @private + * @param {Object} event The event object. + */ + 'keyup': function(event) { + if (13 == (event || window.event).keyCode) { + handlers.title.click(event); + } + } + }; + + handlers.window = { + + /** + * The window hashchange event handler supported by Chrome 5+, Firefox 3.6+, and IE8+. + * + * @private + */ + 'hashchange': function() { + ui.parseHash(); + + var scrollTop, + params = ui.params, + chart = params.chart, + filterBy = params.filterby; + + if (pageLoaded) { + // configure posting + ui.browserscope.postable = has.runner && !('nopost' in params); + + // configure chart renderer + if (chart || filterBy) { + scrollTop = $('results').offsetTop; + ui.browserscope.render({ 'chart': chart, 'filterBy': filterBy }); + } + if (has.runner) { + // call user provided init() function + if (isFunction(window.init)) { + init(); + } + // auto-run + if ('run' in params) { + scrollTop = $('runner').offsetTop; + setTimeout(handlers.button.run, 1); + } + // scroll to the relevant section + if (scrollTop) { + scrollEl.scrollTop = scrollTop; + } + } + } + }, + + /** + * The window load event handler used to initialize the UI. + * + * @private + */ + 'load': function() { + // only for pages with a comment form + if (has.runner) { + // init the ui + addClass('controls', classNames.show); + addListener('run', 'click', handlers.button.run); + + setHTML('run', texts.run.ready); + setHTML('user-agent', Benchmark.platform); + setStatus(texts.status.ready); + + // answer spammer question + $('question').value = 'no'; + + // prefill author details + if (has.localStorage) { + each([$('author'), $('author-email'), $('author-url')], function(element) { + element.value = localStorage[element.id] || ''; + element.oninput = element.onkeydown = function(event) { + event && event.type < 'k' && (element.onkeydown = null); + localStorage[element.id] = element.value; + }; + }); + } + // show warning when Firebug is enabled (avoids showing for Firebug Lite) + try { + // Firebug 1.9 no longer has `console.firebug` + if (console.firebug || /firebug/i.test(console.table())) { + addClass('firebug', classNames.show); + } + } catch(e) { } + } + // evaluate hash values + // (delay in an attempt to ensure this is executed after all other window load handlers) + setTimeout(function() { + pageLoaded = true; + handlers.window.hashchange(); + }, 1); + } + }; + + /*--------------------------------------------------------------------------*/ + + /** + * Shortcut for document.getElementById(). + * + * @private + * @param {Element|String} id The id of the element to retrieve. + * @returns {Element} The element, if found, or null. + */ + function $(id) { + return typeof id == 'string' ? document.getElementById(id) : id; + } + + /** + * Adds a CSS class name to an element's className property. + * + * @private + * @param {Element|String} element The element or id of the element. + * @param {String} className The class name. + * @returns {Element} The element. + */ + function addClass(element, className) { + if ((element = $(element)) && !hasClass(element, className)) { + element.className += (element.className ? ' ' : '') + className; + } + return element; + } + + /** + * Registers an event listener on an element. + * + * @private + * @param {Element|String} element The element or id of the element. + * @param {String} eventName The name of the event. + * @param {Function} handler The event handler. + * @returns {Element} The element. + */ + function addListener(element, eventName, handler) { + if ((element = $(element))) { + if (typeof element.addEventListener != 'undefined') { + element.addEventListener(eventName, handler, false); + } else if (typeof element.attachEvent != 'undefined') { + element.attachEvent('on' + eventName, handler); + } + } + return element; + } + + /** + * Appends to an element's innerHTML property. + * + * @private + * @param {Element|String} element The element or id of the element. + * @param {String} html The HTML to append. + * @returns {Element} The element. + */ + function appendHTML(element, html) { + if ((element = $(element)) && html != null) { + element.innerHTML += html; + } + return element; + } + + /** + * Shortcut for document.createElement(). + * + * @private + * @param {String} tag The tag name of the element to create. + * @returns {Element} A new element of the given tag name. + */ + function createElement(tagName) { + return document.createElement(tagName); + } + + /** + * Checks if an element is assigned the given class name. + * + * @private + * @param {Element|String} element The element or id of the element. + * @param {String} className The class name. + * @returns {Boolean} If assigned the class name return true, else false. + */ + function hasClass(element, className) { + return !!(element = $(element)) && + (' ' + element.className + ' ').indexOf(' ' + className + ' ') > -1; + } + + /** + * Set an element's innerHTML property. + * + * @private + * @param {Element|String} element The element or id of the element. + * @param {String} html The HTML to set. + * @returns {Element} The element. + */ + function setHTML(element, html) { + if ((element = $(element))) { + element.innerHTML = html == null ? '' : html; + } + return element; + } + + /*--------------------------------------------------------------------------*/ + + /** + * 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); + } + + /** + * Checks if a value has an internal [[Class]] of Function. + * + * @private + * @param {Mixed} value The value to check. + * @returns {Boolean} Returns `true` if the value is a function, else `false`. + */ + function isFunction(value) { + return toString.call(value) == '[object Function]'; + } + + /** + * Appends to or clears the error log. + * + * @private + * @param {String|Object} text The text to append or options object. + */ + function logError(text) { + var table, + div = $('error-info'), + options = {}; + + // juggle arguments + if (typeof text == 'object' && text) { + options = text; + text = options.text; + } + else if (arguments.length) { + options.text = text; + } + if (!div) { + table = $('test-table'); + div = createElement('div'); + div.id = 'error-info'; + table.parentNode.insertBefore(div, table.nextSibling); + } + if (options.clear) { + div.className = div.innerHTML = ''; + errors.length = 0; + } + if ('text' in options && indexOf(errors, text) < 0) { + errors.push(text); + addClass(div, classNames.show); + appendHTML(div, text); + } + } + + /** + * Sets the status text. + * + * @private + * @param {String} text The text to write to the status. + */ + function setStatus(text) { + setHTML('status', text); + } + + /*--------------------------------------------------------------------------*/ + + /** + * Parses the window.location.hash value into an object assigned to `ui.params`. + * + * @static + * @memberOf ui + * @returns {Object} The suite instance. + */ + function parseHash() { + var me = this, + hashes = location.hash.slice(1).split('&'), + params = me.params || (me.params = {}); + + // remove old params + forOwn(params, function(value, key) { + delete params[key]; + }); + + // add new params + each(hashes[0] && hashes, function(value) { + value = value.split('='); + params[value[0].toLowerCase()] = (value[1] || '').toLowerCase(); + }); + return me; + } + + /** + * Renders the results table cell of the corresponding benchmark(s). + * + * @static + * @memberOf ui + * @param {Number} [index] The index of the benchmark to render. + * @returns {Object} The suite instance. + */ + function render(index) { + each(index == null ? (index = 0, ui.benchmarks) : [ui.benchmarks[index]], function(bench) { + var parsed, + cell = $(prefix + (++index)), + error = bench.error, + hz = bench.hz; + + // reset title and class + cell.title = ''; + cell.className = classNames.results; + + // status: error + if (error) { + setHTML(cell, 'Error'); + addClass(cell, classNames.error); + parsed = join(error, '
  • '); + logError('

    ' + error + '.

    ' + (parsed ? '
    • ' + parsed + '
    ' : '')); + } + else { + // status: running + if (bench.running) { + setHTML(cell, 'running…'); + } + // status: completed + else if (bench.cycles) { + // obscure details until the suite has completed + if (ui.running) { + setHTML(cell, 'completed'); + } + else { + cell.title = 'Ran ' + formatNumber(bench.count) + ' times in ' + + bench.times.cycle.toFixed(3) + ' seconds.'; + setHTML(cell, formatNumber(hz.toFixed(hz < 100 ? 2 : 0)) + + ' ±' + bench.stats.rme.toFixed(2) + '%'); + } + } + else { + // status: pending + if (ui.running && ui.indexOf(bench) > -1) { + setHTML(cell, 'pending…'); + } + // status: ready + else { + setHTML(cell, 'ready'); + } + } + } + }); + return ui; + } + + /*--------------------------------------------------------------------------*/ + + ui.on('add', function(event) { + var bench = event.target, + index = ui.benchmarks.length, + id = index + 1, + title = $('title-' + id); + + delete ui[--ui.length]; + ui.benchmarks.push(bench); + + if (has.runner) { + title.tabIndex = 0; + title.title = 'Click to run this test again.'; + + addListener(title, 'click', handlers.title.click); + addListener(title, 'keyup', handlers.title.keyup); + + bench.on('start', handlers.benchmark.start); + bench.on('start cycle', handlers.benchmark.cycle); + ui.render(index); + } + }) + .on('start cycle', function() { + ui.render(); + setHTML('run', texts.run.running); + }) + .on('complete', function() { + var benches = filter(ui.benchmarks, 'successful'), + fastest = filter(benches, 'fastest'), + slowest = filter(benches, 'slowest'); + + ui.render(); + setHTML('run', texts.run.again); + setStatus(texts.status.again); + + // highlight result cells + each(benches, function(bench) { + var cell = $(prefix + (indexOf(ui.benchmarks, bench) + 1)), + fastestHz = getHz(fastest[0]), + hz = getHz(bench), + percent = (1 - (hz / fastestHz)) * 100, + span = cell.getElementsByTagName('span')[0], + text = 'fastest'; + + if (indexOf(fastest, bench) > -1) { + // mark fastest + addClass(cell, text); + } + else { + text = isFinite(hz) + ? formatNumber(percent < 1 ? percent.toFixed(2) : Math.round(percent)) + '% slower' + : ''; + + // mark slowest + if (indexOf(slowest, bench) > -1) { + addClass(cell, 'slowest'); + } + } + // write ranking + if (span) { + setHTML(span, text); + } else { + appendHTML(cell, '' + text + ''); + } + }); + + ui.browserscope.post(); + }); + + /*--------------------------------------------------------------------------*/ + + /** + * An array of benchmarks created from test cases. + * + * @memberOf ui + * @type Array + */ + ui.benchmarks = []; + + /** + * The parsed query parameters of the pages url hash. + * + * @memberOf ui + * @type Object + */ + ui.params = {}; + + // parse query params into ui.params hash + ui.parseHash = parseHash; + + // (re)render the results of one or more benchmarks + ui.render = render; + + /*--------------------------------------------------------------------------*/ + + // expose + window.ui = ui; + + // don't let users alert, confirm, prompt, or open new windows + window.alert = window.confirm = window.prompt = window.open = function() { }; + + // parse hash query params when it changes + addListener(window, 'hashchange', handlers.window.hashchange); + + // bootstrap onload + addListener(window, 'load', handlers.window.load); + + // parse location hash string + ui.parseHash(); + + // provide a simple UI for toggling between chart types and filtering results + // (assumes ui.js is just before ) + (function() { + var sibling = $('bs-results'), + p = createElement('p'); + + p.innerHTML = + 'Chart type: bar, ' + + 'column, line, pie, ' + + 'table
    ' + + 'Filter: popular, ' + + 'all, desktop, family, ' + + 'major, minor, mobile, ' + + 'prerelease'; + + sibling.parentNode.insertBefore(p, sibling); + + // use DOM0 event handler to simplify canceling the default action + $('charts').onclick = + $('filters').onclick = function(event) { + event || (event = window.event); + var target = event.target || event.srcElement; + if (target.href || (target = target.parentNode).href) { + ui.browserscope.render( + target.parentNode.id == 'charts' + ? { 'chart': target.innerHTML } + : { 'filterBy': target.innerHTML } + ); + } + // cancel the default action + return false; + }; + }()); + + /*--------------------------------------------------------------------------*/ + + // fork for runner or embedded chart + if (has.runner) { + // detect the scroll element + (function() { + var scrollTop, + div = document.createElement('div'), + body = document.body, + bodyStyle = body.style, + bodyHeight = bodyStyle.height, + html = document.documentElement, + htmlStyle = html.style, + htmlHeight = htmlStyle.height; + + bodyStyle.height = htmlStyle.height = 'auto'; + div.style.cssText = 'display:block;height:9001px;'; + body.insertBefore(div, body.firstChild); + scrollTop = html.scrollTop; + + // set `scrollEl` that's used in `handlers.window.hashchange()` + if (html.clientWidth !== 0 && ++html.scrollTop && html.scrollTop == scrollTop + 1) { + scrollEl = html; + } + body.removeChild(div); + bodyStyle.height = bodyHeight; + htmlStyle.height = htmlHeight; + html.scrollTop = scrollTop; + }()); + + // catch and display errors from the "preparation code" + window.onerror = function(message, fileName, lineNumber) { + logError('

    ' + message + '.

    • ' + join({ + 'message': message, + 'fileName': fileName, + 'lineNumber': lineNumber + }, '
    • ') + '
    '); + scrollEl.scrollTop = $('error-info').offsetTop; + }; + // inject nano applet + // (assumes ui.js is just before ) + if ('nojava' in ui.params) { + addClass('java', classNames.show); + } else { + // using innerHTML avoids an alert in some versions of IE6 + document.body.insertBefore(setHTML(createElement('div'), + '').lastChild, document.body.firstChild); + } + } + else { + // short circuit unusable methods + ui.render = function() { }; + ui.off('start cycle complete'); + setTimeout(function() { + ui.off(); + ui.browserscope.post = function() { }; + invoke(ui.benchmarks, 'off'); + }, 1); + } + + /*--------------------------------------------------------------------------*/ + + // optimized asynchronous Google Analytics snippet based on + // http://mathiasbynens.be/notes/async-analytics-snippet + if (gaId) { + (function() { + var script = createElement('script'), + sibling = document.getElementsByTagName('script')[0]; + + window._gaq = [['_setAccount', gaId], ['_trackPageview']]; + script.src = '//www.google-analytics.com/ga.js'; + sibling.parentNode.insertBefore(script, sibling); + }()); + } +}(this, document)); diff --git a/web/src/vendor/benchmark/nano.jar b/web/src/vendor/benchmark/nano.jar new file mode 100644 index 00000000..b5778403 Binary files /dev/null and b/web/src/vendor/benchmark/nano.jar differ diff --git a/web/src/vendor/benchmark/nano.java b/web/src/vendor/benchmark/nano.java new file mode 100644 index 00000000..96fc2244 --- /dev/null +++ b/web/src/vendor/benchmark/nano.java @@ -0,0 +1,23 @@ +/** + * Simple class to expose nanoTime() to JavaScript. + * + * Compile using + * javac -g:none -target 1.5 nano.java + * jar cfM nano.jar nano.class + * java -jar proguard.jar @options.txt + * + * ProGuard (http://proguard.sourceforge.net) + * options.txt + * -injars nano.jar + * -outjars nano_s.jar + * -libraryjars /jre/lib/rt.jar + * -keep public class nano { + * public long nanoTime(); + * } + */ +import java.applet.Applet; +public class nano extends Applet { + public long nanoTime() { + return System.nanoTime(); + } +} diff --git a/web/src/vendor/benchmark/package.json b/web/src/vendor/benchmark/package.json new file mode 100644 index 00000000..2be940ca --- /dev/null +++ b/web/src/vendor/benchmark/package.json @@ -0,0 +1,54 @@ +{ + "name": "benchmark", + "version": "1.0.0", + "description": "A benchmarking library that works on nearly all JavaScript platforms, supports high-resolution timers, and returns statistically significant results.", + "homepage": "http://benchmarkjs.com/", + "main": "benchmark", + "keywords": [ + "benchmark", + "narwhal", + "node", + "performance", + "ringo", + "speed" + ], + "licenses": [ + { + "type": "MIT", + "url": "http://mths.be/mit" + } + ], + "author": { + "name": "Mathias Bynens", + "email": "mathias@benchmarkjs.com", + "web": "http://mathiasbynens.be/" + }, + "maintainers": [ + { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com", + "web": "http://allyoucanleet.com/" + }, + { + "name": "Mathias Bynens", + "email": "mathias@benchmarkjs.com", + "web": "http://mathiasbynens.be/" + } + ], + "bugs": { + "email": "bugs@benchmarkjs.com", + "url": "https://github.com/bestiejs/benchmark.js/issues" + }, + "repository": { + "type": "git", + "url": "https://github.com/bestiejs/benchmark.js.git" + }, + "engines": [ + "node", + "rhino" + ], + "directories": { + "doc": "./doc", + "test": "./test" + } +} diff --git a/web/src/vendor/benchmark/plugin/ui.browserscope.js b/web/src/vendor/benchmark/plugin/ui.browserscope.js new file mode 100644 index 00000000..01905bde --- /dev/null +++ b/web/src/vendor/benchmark/plugin/ui.browserscope.js @@ -0,0 +1,1052 @@ +(function(window, document) { + + /** Cache used by various methods */ + var cache = { + 'counter': 0, + 'lastAction': 'load', + 'lastChart': 'bar', + 'lastFilterBy': 'all', + 'responses': { /* 'all': null, 'desktop': null, 'major': null, ... */ }, + 'timers': { /* 'cleanup': null, 'load': null, 'post': null, ... */ }, + 'trash': createElement('div') + }; + + /** + * Used to filter Browserscope results by browser category. + * + * @see http://www.browserscope.org/user/tests/howto#urlparams + */ + var filterMap = { + 'all': 3, + 'desktop': 'top-d', + 'family': 0, + 'major': 1, + 'minor': 2, + 'mobile': 'top-m', + 'popular': 'top', + 'prerelease': 'top-d-e' + }; + + /** Used to resolve a value's internal [[Class]] */ + var toString = {}.toString; + + /** + * The `uaToken` is prepended to the value of the data cell of the Google + * visualization data table object that matches the user's browser name. After + * the chart is rendered the element containing the `uaToken` is assigned the + * `ui.browserscope.uaClass` class name to allow for the creation of a visual + * indicator to help the user more easily find their browser's results. + */ + var uaToken = '\u2028'; + + /** Math shortcuts */ + var floor = Math.floor, + max = Math.max, + min = Math.min; + + /** Utility shortcuts */ + var each = Benchmark.each, + extend = Benchmark.extend, + filter = Benchmark.filter, + forOwn = Benchmark.forOwn, + formatNumber = Benchmark.formatNumber, + hasKey = Benchmark.hasKey, + indexOf = Benchmark.indexOf, + interpolate = Benchmark.interpolate, + invoke = Benchmark.invoke, + map = Benchmark.map, + reduce = Benchmark.reduce; + + /*--------------------------------------------------------------------------*/ + + /** + * Registers an event listener. + * + * @private + * @param {Element} element The element. + * @param {String} eventName The name of the event to listen to. + * @param {Function} handler The event handler. + * @returns {Element} The element. + */ + function addListener(element, eventName, handler) { + if ((element = typeof element == 'string' ? query(element)[0] : element)) { + if (typeof element.addEventListener != 'undefined') { + element.addEventListener(eventName, handler, false); + } else if (typeof element.attachEvent != 'undefined') { + element.attachEvent('on' + eventName, handler); + } + } + return element; + } + + /** + * Shortcut for `document.createElement()`. + * + * @private + * @param {String} tagName The tag name of the element to create. + * @param {String} name A name to assign to the element. + * @param {Document|Element} context The document object used to create the element. + * @returns {Element} Returns a new element. + */ + function createElement(tagName, name, context) { + var result; + name && name.nodeType && (context = name, name = 0); + context = context ? context.ownerDocument || context : document; + name || (name = ''); + + try { + // set name attribute for IE6/7 + result = context.createElement('<' + tagName + ' name="' + name + '">'); + } catch(e) { + (result = context.createElement(tagName)).name = name; + } + return result; + } + + /** + * Creates a new style element. + * + * @private + * @param {String} cssText The css text of the style element. + * @param {Document|Element} context The document object used to create the element. + * @returns {Element} Returns the new style element. + */ + function createStyleSheet(cssText, context) { + // use a text node, "x", to work around innerHTML issues with style elements + // http://msdn.microsoft.com/en-us/library/ms533897(v=vs.85).aspx#1 + var div = createElement('div', context); + div.innerHTML = 'x'; + return div.lastChild; + } + + /** + * Gets the text content of an element. + * + * @private + * @param {Element} element The element. + * @returns {String} The text content of the element. + */ + function getText(element) { + element = query(element)[0]; + return element && (element.textContent || element.innerText) || ''; + } + + /** + * Injects a script into the document. + * + * @private + * @param {String} src The external script source. + * @param {Object} sibling The element to inject the script after. + * @param {Document} context The document object used to create the script element. + * @returns {Object} The new script element. + */ + function loadScript(src, sibling, context) { + context = sibling ? sibling.ownerDocument || [sibling, sibling = 0][0] : context; + var script = createElement('script', context), + nextSibling = sibling ? sibling.nextSibling : query('script', context).pop(); + + script.src = src; + return (sibling || nextSibling).parentNode.insertBefore(script, nextSibling); + } + + /** + * Queries the document for elements by id or tagName. + * + * @private + * @param {String} selector The css selector to match. + * @param {Document|Element} context The element whose descendants are queried. + * @returns {Array} The array of results. + */ + function query(selector, context) { + var result = []; + selector || (selector = ''); + context = typeof context == 'string' ? query(context)[0] : context || document; + + if (selector.nodeType) { + result = [selector]; + } + else if (context) { + each(selector.split(','), function(selector) { + each(/^#/.test(selector) + ? [context.getElementById(selector.slice(1))] + : context.getElementsByTagName(selector), function(node) { + result.push(node); + }); + }); + } + return result; + } + + /** + * Set an element's innerHTML property. + * + * @private + * @param {Element} element The element. + * @param {String} html The HTML to set. + * @param {Object} object The template object used to modify the html. + * @returns {Element} The element. + */ + function setHTML(element, html, object) { + if ((element = query(element)[0])) { + element.innerHTML = interpolate(html, object); + } + return element; + } + + /** + * Displays a message in the "results" element. + * + * @private + * @param {String} text The text to display. + * @param {Object} object The template object used to modify the text. + */ + function setMessage(text, object) { + var me = ui.browserscope, + cont = me.container; + + if (cont) { + cont.className = 'bs-rt-message'; + setHTML(cont, text, object); + } + } + + /*--------------------------------------------------------------------------*/ + + /** + * Adds a style sheet to the current chart and assigns the `ui.browserscope.uaClass` + * class name to the chart element containing the user's browser name. + * + * @private + * @returns {Boolean} Returns `true` if the operation succeeded, else `false`. + */ + function addChartStyle() { + var me = ui.browserscope, + cssText = [], + context = frames[query('iframe', me.container)[0].name].document, + chartNodes = query('text,textpath', context), + uaClass = me.uaClass, + result = false; + + if (chartNodes.length) { + // extract CSS rules for `uaClass` + each(query('link,style'), function(node) { + // avoid access denied errors on external style sheets + // outside the same origin policy + try { + var sheet = node.sheet || node.styleSheet; + each(sheet.cssRules || sheet.rules, function(rule) { + if ((rule.selectorText || rule.cssText).indexOf('.' + uaClass) > -1) { + cssText.push(rule.style && rule.style.cssText || /[^{}]*(?=})/.exec(rule.cssText) || ''); + } + }); + } catch(e) { } + }); + + // insert custom style sheet + query('head', context)[0].appendChild( + createStyleSheet('.' + uaClass + '{' + cssText.join(';') + '}', context)); + + // scan chart elements for a match + each(chartNodes, function(node) { + var nextSibling; + if ((node.string || getText(node)).charAt(0) == uaToken) { + // for VML + if (node.string) { + // IE requires reinserting the element to render correctly + node.className = uaClass; + nextSibling = node.nextSibling; + node.parentNode.insertBefore(node.removeNode(), nextSibling); + } + // for SVG + else { + node.setAttribute('class', uaClass); + } + result = true; + } + }); + } + return result; + } + + /** + * Periodically executed callback that removes injected script and iframe elements. + * + * @private + */ + function cleanup() { + var me = ui.browserscope, + timings = me.timings, + timers = cache.timers, + trash = cache.trash, + delay = timings.cleanup * 1e3; + + // remove injected scripts and old iframes when benchmarks aren't running + if (timers.cleanup && !ui.running) { + // if expired, destroy the element to prevent pseudo memory leaks. + // http://dl.dropbox.com/u/513327/removechild_ie_leak.html + each(query('iframe,script'), function(element) { + var expire = +(/^browserscope-\d+-(\d+)$/.exec(element.name) || 0)[1] + max(delay, timings.timeout * 1e3); + if (new Date > expire || /browserscope\.org|google\.com/.test(element.src)) { + trash.appendChild(element); + trash.innerHTML = ''; + } + }); + } + // schedule another round + timers.cleanup = setTimeout(cleanup, delay); + } + + /** + * A simple data object cloning utility. + * + * @private + * @param {Mixed} data The data object to clone. + * @returns {Mixed} The cloned data object. + */ + function cloneData(data) { + var fn, + ctor, + result = data; + + if (isArray(data)) { + result = map(data, cloneData); + } + else if (data === Object(data)) { + ctor = data.constructor; + result = ctor == Object ? {} : (fn = function(){}, fn.prototype = ctor.prototype, new fn); + forOwn(data, function(value, key) { + result[key] = cloneData(value); + }); + } + return result; + } + + /** + * Creates a Browserscope results object. + * + * @private + * @returns {Object|Null} Browserscope results object or null. + */ + function createSnapshot() { + // clone benches, exclude those that are errored, unrun, or have hz of Infinity + var benches = invoke(filter(ui.benchmarks, 'successful'), 'clone'), + fastest = filter(benches, 'fastest'), + slowest = filter(benches, 'slowest'), + neither = filter(benches, function(bench) { + return indexOf(fastest, bench) + indexOf(slowest, bench) == -2; + }); + + function merge(destination, source) { + destination.count = source.count; + destination.cycles = source.cycles; + destination.hz = source.hz; + destination.stats = extend({}, source.stats); + } + + // normalize results on slowest in each category + each(fastest.concat(slowest), function(bench) { + merge(bench, indexOf(fastest, bench) > -1 ? fastest[fastest.length - 1] : slowest[0]); + }); + + // sort slowest to fastest + // (a larger `mean` indicates a slower benchmark) + neither.sort(function(a, b) { + a = a.stats; b = b.stats; + return (a.mean + a.moe > b.mean + b.moe) ? -1 : 1; + }); + + // normalize the leftover benchmarks + reduce(neither, function(prev, bench) { + // if the previous slower benchmark is indistinguishable from + // the current then use the previous benchmark's values + if (prev.compare(bench) == 0) { + merge(bench, prev); + } + return bench; + }); + + // append benchmark ids for duplicate names or names with no alphanumeric/space characters + // and use the upper limit of the confidence interval to compute a lower hz + // to avoid recording inflated results caused by a high margin or error + return reduce(benches, function(result, bench, key) { + var stats = bench.stats; + result || (result = {}); + key = toLabel(bench.name); + result[key && !hasKey(result, key) ? key : key + bench.id ] = floor(1 / (stats.mean + stats.moe)); + return result; + }, null); + } + + /** + * Retrieves the "cells" array from a given Google visualization data row object. + * + * @private + * @param {Object} object The data row object. + * @returns {Array} An array of cell objects. + */ + function getDataCells(object) { + // resolve cells by duck typing because of munged property names + var result = []; + forOwn(object, function(value) { + return !(isArray(value) && (result = value)); + }); + // remove empty entries which occur when not all the tests are recorded + return filter(result, Boolean); + } + + /** + * Retrieves the "labels" array from a given Google visualization data table object. + * + * @private + * @param {Object} object The data table object. + * @returns {Array} An array of label objects. + */ + function getDataLabels(object) { + var result = [], + labelMap = {}; + + // resolve labels by duck typing because of munged property names + forOwn(object, function(value) { + return !(isArray(value) && 0 in value && 'type' in value[0] && (result = value)); + }); + // create a data map of labels to names + each(ui.benchmarks, function(bench) { + var key = toLabel(bench.name); + labelMap[key && !hasKey(labelMap, key) ? key : key + bench.id ] = bench.name; + }); + // replace Browserscope's basic labels with benchmark names + return each(result, function(cell) { + var name = labelMap[cell.label]; + name && (cell.label = name); + }); + } + + /** + * Retrieves the "rows" array from a given Google visualization data table object. + * + * @private + * @param {Object} object The data table object. + * @returns {Array} An array of row objects. + */ + function getDataRows(object) { + var name, + filterBy = cache.lastFilterBy, + browserName = toBrowserName(getText(query('strong', '#bs-ua')[0]), filterBy), + uaClass = ui.browserscope.uaClass, + result = []; + + // resolve rows by duck typing because of munged property names + forOwn(object, function(value, key) { + return !(isArray(value) && 0 in value && !('type' in value[0]) && (name = key, result = value)); + }); + // remove empty rows and set the `p.className` on the browser + // name cell that matches the user's browser name + if (result.length) { + result = object[name] = filter(result, function(value) { + var cells = getDataCells(value), + first = cells[0], + second = cells[1]; + + // cells[0] is the browser name cell so instead we check cells[1] + // for the presence of ops/sec data to determine if a row is empty or not + if (first && second && second.f) { + delete first.p.className; + if (browserName == toBrowserName(first.f, filterBy)) { + first.p.className = uaClass; + } + return true; + } + }); + } + return result; + } + + /** + * Checks if a value has an internal [[Class]] of Array. + * + * @private + * @param {Mixed} value The value to check. + * @returns {Boolean} Returns `true` if the value has an internal [[Class]] of + * Array, else `false`. + */ + function isArray(value) { + return toString.call(value) == '[object Array]'; + } + + /** + * Executes a callback at a given delay interval until it returns `false`. + * + * @private + * @param {Function} callback The function called every poll interval. + * @param {Number} delay The delay between callback calls (secs). + */ + function poll(callback, delay) { + function poller(init) { + if (init || callback() !== false) { + setTimeout(poller, delay * 1e3); + } + } + poller(true); + } + + /** + * Cleans up the last action and sets the current action. + * + * @private + * @param {String} action The current action. + */ + function setAction(action) { + clearTimeout(cache.timers[cache.lastAction]); + cache.lastAction = action; + } + + /** + * Converts the browser name version number to the format allowed by the + * specified filter. + * + * @private + * @param {String} name The full browser name . + * @param {String} filterBy The filter formating rules to apply. + * @returns {String} The converted browser name. + */ + function toBrowserName(name, filterBy) { + name || (name = ''); + if (filterBy == 'all') { + // truncate something like 1.0.0 to 1 + name = name.replace(/(\d+)[.0]+$/, '$1'); + } + else if (filterBy == 'family') { + // truncate something like XYZ 1.2 to XYZ + name = name.replace(/[.\d\s]+$/, ''); + } + else if (/minor|popular/.test(filterBy) && /\d+(?:\.[1-9])+$/.test(name)) { + // truncate something like 1.2.3 to 1.2 + name = name.replace(/(\d+\.[1-9])(\.[.\d]+$)/, '$1'); + } + else { + // truncate something like 1.0 to 1 or 1.2.3 to 1 but leave something like 1.2 alone + name = name.replace(/(\d+)(?:(\.[1-9]$)|(\.[.\d]+$))/, '$1$2'); + } + return name; + } + + /** + * Replaces non-alphanumeric characters with spaces because Browserscope labels + * can only contain alphanumeric characters and spaces. + * + * @private + * @param {String} text The text to be converted. + * @returns {String} The Browserscope safe label text. + * @see http://code.google.com/p/browserscope/issues/detail?id=271 + */ + function toLabel(text) { + return (text || '').replace(/[^a-z0-9]+/gi, ' '); + } + + /*--------------------------------------------------------------------------*/ + + /** + * Loads Browserscope's cumulative results table. + * + * @static + * @memberOf ui.browserscope + * @param {Object} options The options object. + */ + function load(options) { + options || (options = {}); + + var fired, + me = ui.browserscope, + cont = me.container, + filterBy = cache.lastFilterBy = options.filterBy || cache.lastFilterBy, + responses = cache.responses, + response = cache.responses[filterBy], + visualization = window.google && google.visualization; + + function onComplete(response) { + var lastResponse = responses[filterBy]; + if (!fired) { + // set the fired flag to avoid Google's own timeout + fired = true; + // render if the filter is still the same, else cache the result + if (filterBy == cache.lastFilterBy) { + me.render({ 'force': true, 'response': lastResponse || response }); + } else if(!lastResponse && response && !response.isError()) { + responses[filterBy] = response; + } + } + } + + // set last action in case the load fails and a retry is needed + setAction('load'); + + // exit early if there is no container element or the response is cached + // and retry if the visualization library hasn't loaded yet + if (!cont || !visualization || !visualization.Query || response) { + cont && onComplete(response); + } + else if (!ui.running) { + // set our own load timeout to display an error message and retry loading + cache.timers.load = setTimeout(onComplete, me.timings.timeout * 1e3); + // set "loading" message and attempt to load Browserscope data + setMessage(me.texts.loading); + // request Browserscope pass chart data to `google.visualization.Query.setResponse()` + (new visualization.Query( + '//www.browserscope.org/gviz_table_data?category=usertest_' + me.key + '&v=' + filterMap[filterBy], + { 'sendMethod': 'scriptInjection' } + )) + .send(onComplete); + } + } + + /** + * Creates a Browserscope beacon and posts the benchmark results. + * + * @static + * @memberOf ui.browserscope + */ + function post() { + var idoc, + iframe, + body = document.body, + me = ui.browserscope, + key = me.key, + timings = me.timings, + name = 'browserscope-' + (cache.counter++) + '-' + (+new Date), + snapshot = createSnapshot(); + + // set last action in case the post fails and a retry is needed + setAction('post'); + + if (key && snapshot && me.postable && !ui.running && !/Simulator/i.test(Benchmark.platform)) { + // create new beacon + // (the name contains a timestamp so `cleanup()` can determine when to remove it) + iframe = createElement('iframe', name); + body.insertBefore(iframe, body.firstChild); + idoc = frames[name].document; + iframe.style.display = 'none'; + + // expose results snapshot + me.snapshot = snapshot; + // set "posting" message and attempt to post the results snapshot + setMessage(me.texts.post); + // Note: We originally created an iframe to avoid Browerscope's old limit + // of one beacon per page load. It's currently used to implement custom + // request timeout and retry routines. + idoc.write(interpolate( + // the doctype is required so Browserscope detects the correct IE compat mode + '#{doctype} + + + + + + + diff --git a/web/src/vendor/benchmark/test/index.html b/web/src/vendor/benchmark/test/index.html new file mode 100644 index 00000000..9762fb69 --- /dev/null +++ b/web/src/vendor/benchmark/test/index.html @@ -0,0 +1,85 @@ + + + + + Benchmark.js Test Suite + + + + +
    + + + + + + + diff --git a/web/src/vendor/benchmark/test/run-test.sh b/web/src/vendor/benchmark/test/run-test.sh new file mode 100755 index 00000000..43424e43 --- /dev/null +++ b/web/src/vendor/benchmark/test/run-test.sh @@ -0,0 +1,9 @@ +cd "$(dirname "$0")" +for cmd in rhino ringo narwhal node; do + echo "" + echo "Testing in $cmd..." + $cmd test.js +done +echo "" +echo "Testing in a browser..." +open index.html diff --git a/web/src/vendor/benchmark/test/test.js b/web/src/vendor/benchmark/test/test.js new file mode 100644 index 00000000..d6944940 --- /dev/null +++ b/web/src/vendor/benchmark/test/test.js @@ -0,0 +1,2074 @@ +;(function(window, undefined) { + 'use strict'; + + /** Use a single load function */ + var load = typeof require == 'function' ? require : window.load; + + /** The `platform` object to check */ + var platform = + window.platform || + load('../vendor/platform.js/platform.js') || + window.platform; + + /** The unit testing framework */ + var QUnit = + window.QUnit || ( + window.setTimeout || (window.addEventListener = window.setTimeout = / /), + window.QUnit = load('../vendor/qunit/qunit/qunit' + (platform.name == 'Narwhal' ? '-1.8.0' : '') + '.js') || window.QUnit, + load('../vendor/qunit-clib/qunit-clib.js'), + (window.addEventListener || 0).test && delete window.addEventListener, + window.QUnit + ); + + /** The `Benchmark` constructor to test */ + var Benchmark = + window.Benchmark || ( + Benchmark = load('../benchmark.js') || window.Benchmark, + Benchmark.Benchmark || Benchmark + ); + + /** API shortcut */ + var forOwn = Benchmark.forOwn; + + /** Used to get property descriptors */ + var getDescriptor = Object.getOwnPropertyDescriptor; + + /** Used to set property descriptors */ + var setDescriptor = Object.defineProperty; + + /** Shortcut used to convert array-like objects to arrays */ + var slice = [].slice; + + /** Used to resolve a value's internal [[Class]] */ + var toString = {}.toString; + + /** Used to check problem JScript properties (a.k.a. the [[DontEnum]] bug) */ + var shadowed = { + 'constructor': 1, + 'hasOwnProperty': 2, + 'isPrototypeOf': 3, + 'propertyIsEnumerable': 4, + 'toLocaleString': 5, + 'toString': 6, + 'valueOf': 7 + }; + + /** Used to flag environments/features */ + var support = { + 'descriptors': !!function() { + try { + var o = {}; + return (setDescriptor(o, o, o), 'value' in getDescriptor(o, o)); + } catch(e) { } + }() + }; + + /*--------------------------------------------------------------------------*/ + + /** + * Skips a given number of tests with a passing result. + * + * @private + * @param {Number} [count=1] The number of tests to skip. + */ + function skipTest(count) { + count || (count = 1); + while (count--) { + ok(true, 'test skipped'); + } + } + + /*--------------------------------------------------------------------------*/ + + // init Benchmark.options.minTime + Benchmark(function() { throw 0; }).run(); + + // set a shorter max time + Benchmark.options.maxTime = Benchmark.options.minTime * 5; + + // explicitly call `QUnit.module()` instead of `module()` + // in case we are in a CLI environment + QUnit.module('Benchmark'); + + (function() { + test('has the default `Benchmark.platform` value', function() { + if (window.document) { + equal(String(Benchmark.platform), navigator.userAgent); + } else { + skipTest(1) + } + }); + + test('supports loading Benchmark.js as a module', function() { + if (window.document && window.require) { + equal((Benchmark2 || {}).version, Benchmark.version); + } else { + skipTest(1) + } + }); + + test('supports loading Platform.js as a module', function() { + if (window.document && window.require) { + var platform = (Benchmark2 || {}).platform || {}; + equal(typeof platform.name, 'string'); + } else { + skipTest(1) + } + }); + }()); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('Benchmark constructor'); + + (function() { + test('creates a new instance when called without the `new` operator', function() { + ok(Benchmark() instanceof Benchmark); + }); + + test('supports passing an options object', function() { + var bench = Benchmark({ 'name': 'foo', 'fn': function() { } }); + ok(bench.fn && bench.name == 'foo'); + }); + + test('supports passing a "name" and "fn" argument', function() { + var bench = Benchmark('foo', function() { }); + ok(bench.fn && bench.name == 'foo'); + }); + + test('supports passing a "name" argument and an options object', function() { + var bench = Benchmark('foo', { 'fn': function() { } }); + ok(bench.fn && bench.name == 'foo'); + }); + + test('supports passing a "name" argument and an options object', function() { + var bench = Benchmark('foo', function() { }, { 'id': 'bar' }); + ok(bench.fn && bench.name == 'foo' && bench.id == 'bar'); + }); + + test('supports passing an empy string for the "fn" options property', function() { + var bench = Benchmark({ 'fn': '' }).run(); + ok(!bench.error); + }); + + test('detects dead code', function() { + var bench = Benchmark(function() { }).run(); + ok(/setup\(\)/.test(bench.compiled) ? !bench.error : bench.error); + }); + }()); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('Benchmark compilation'); + + (function() { + test('compiles using the default `Function#toString`', function() { + var bench = Benchmark({ + 'setup': function() { var a = 1; }, + 'fn': function() { throw a; }, + 'teardown': function() { a = 2; } + }).run(); + + var compiled = bench.compiled; + if (/setup\(\)/.test(compiled)) { + skipTest(); + } + else { + ok(/var a\s*=\s*1/.test(compiled) && /throw a/.test(compiled) && /a\s*=\s*2/.test(compiled)); + } + }); + + test('compiles using a custom "toString" method', function() { + var bench = Benchmark({ + 'setup': function() { }, + 'fn': function() { }, + 'teardown': function() { } + }); + + bench.setup.toString = function() { return 'var a = 1;' }; + bench.fn.toString = function() { return 'throw a;' }; + bench.teardown.toString = function() { return 'a = 2;' }; + bench.run(); + + var compiled = bench.compiled; + if (/setup\(\)/.test(compiled)) { + skipTest(); + } + else { + ok(/var a\s*=\s*1/.test(compiled) && /throw a/.test(compiled) && /a\s*=\s*2/.test(compiled)); + } + }); + + test('compiles using a string value', function() { + var bench = Benchmark({ + 'setup': 'var a = 1;', + 'fn': 'throw a;', + 'teardown': 'a = 2;' + }).run(); + + var compiled = bench.compiled; + if (/setup\(\)/.test(compiled)) { + skipTest(); + } + else { + ok(/var a\s*=\s*1/.test(compiled) && /throw a/.test(compiled) && /a\s*=\s*2/.test(compiled)); + } + }); + }()); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('Benchmark test binding'); + + (function() { + var count = 0; + + var tests = { + 'inlined "setup", "fn", and "teardown"': ( + 'if(/ops/.test(this))this._fn=true;' + ), + 'called "fn" and inlined "setup"/"teardown" reached by error': function() { + count++; + if (/ops/.test(this)) { + this._fn = true; + } + }, + 'called "fn" and inlined "setup"/"teardown" reached by `return` statement': function() { + if (/ops/.test(this)) { + this._fn = true; + } + return; + } + }; + + forOwn(tests, function(fn, title) { + test('has correct binding for ' + title, function() { + var bench = Benchmark({ + 'setup': 'if(/ops/.test(this))this._setup=true;', + 'fn': fn, + 'teardown': 'if(/ops/.test(this))this._teardown=true;', + 'onCycle': function() { this.abort(); } + }).run(); + + var compiled = bench.compiled; + if (/setup\(\)/.test(compiled)) { + skipTest(3); + } + else { + ok(bench._setup, 'correct binding for "setup"'); + ok(bench._fn, 'correct binding for "fn"'); + ok(bench._teardown, 'correct binding for "teardown"'); + } + }); + }); + }()); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('Benchmark.deepClone'); + + (function() { + function createCircularObject() { + var result = { + 'foo': { 'b': { 'foo': { 'c': { } } } }, + 'bar': { } + }; + + result.foo.b.foo.c.foo = result; + result.bar.b = result.foo.b; + return result; + } + + function Klass() { + this.a = 1; + } + + Klass.prototype = { 'b': 1 }; + + var notCloneable = { + 'an arguments object': arguments, + 'an element': window.document && document.body, + 'a function': Klass, + 'a Klass instance': new Klass + }; + + var objects = { + 'an array': ['a', 'b', 'c', ''], + 'an array-like-object': { '0': 'a', '1': 'b', '2': 'c', '3': '', 'length': 5 }, + 'boolean': false, + 'boolean object': Object(false), + 'an object': { 'a': 0, 'b': 1, 'c': 3 }, + 'an object with object values': { 'a': /a/, 'b': ['B'], 'c': { 'C': 1 } }, + 'null': null, + 'a number': 3, + 'a number object': Object(3), + 'a regexp': /x/gim, + 'a string': 'x', + 'a string object': Object('x'), + 'undefined': undefined + }; + + objects['an array'].length = 5; + + forOwn(objects, function(object, key) { + test('clones ' + key + ' correctly', function() { + var kind = toString.call(object), + clone = Benchmark.deepClone(object); + + if (object == null) { + equal(clone, object); + } else { + deepEqual(clone.valueOf(), object.valueOf()); + } + if (object === Object(object)) { + ok(clone !== object); + } else { + skipTest(); + } + }); + }); + + forOwn(notCloneable, function(object, key) { + test('does not clone ' + key, function() { + ok(Benchmark.deepClone(object) === object); + }); + }); + + test('clones using Klass#deepClone', function() { + var object = new Klass; + Klass.prototype.deepClone = function() { return new Klass; }; + + var clone = Benchmark.deepClone(object); + ok(clone !== object && clone instanceof Klass); + + delete Klass.prototype.clone; + }); + + test('clones problem JScript properties', function() { + var clone = Benchmark.deepClone(shadowed); + deepEqual(clone, shadowed); + }); + + test('clones string object with custom property', function() { + var object = new String('x'); + object.x = 1; + + var clone = Benchmark.deepClone(object); + ok(clone == 'x' && typeof clone == 'object' && clone.x === 1 && toString.call(clone) == '[object String]'); + }); + + test('clones objects with circular references', function() { + var object = createCircularObject(), + clone = Benchmark.deepClone(object); + + ok(clone.bar.b === clone.foo.b && clone === clone.foo.b.foo.c.foo && clone !== object); + }); + + test('clones non-extensible objects with circular references', function() { + if (Object.preventExtensions) { + var object = Object.preventExtensions(createCircularObject()); + Object.preventExtensions(object.bar.b); + + var clone = Benchmark.deepClone(object); + ok(clone.bar.b === clone.foo.b && clone === clone.foo.b.foo.c.foo && clone !== object); + } else { + skipTest(1) + } + }); + + test('clones sealed objects with circular references', function() { + if (Object.seal) { + var object = Object.seal(createCircularObject()); + Object.seal(object.bar.b); + + var clone = Benchmark.deepClone(object); + ok(clone.bar.b === clone.foo.b && clone === clone.foo.b.foo.c.foo && clone !== object); + } else { + skipTest(1) + } + }); + + test('clones frozen objects with circular references', function() { + if (Object.freeze) { + var object = Object.freeze(createCircularObject()); + Object.freeze(object.bar.b); + + var clone = Benchmark.deepClone(object); + ok(clone.bar.b === clone.foo.b && clone === clone.foo.b.foo.c.foo && clone !== object); + } else { + skipTest(1) + } + }); + + test('clones objects with custom descriptors and circular references', function() { + var accessor, + descriptor; + + if (support.descriptors) { + var object = setDescriptor({}, 'foo', { + 'configurable': true, + 'value': setDescriptor({}, 'b', { + 'writable': true, + 'value': setDescriptor({}, 'foo', { + 'get': function() { return accessor; }, + 'set': function(value) { accessor = value; } + }) + }) + }); + + setDescriptor(object, 'bar', { 'value': {} }); + object.foo.b.foo = { 'c': object }; + object.bar.b = object.foo.b; + + var clone = Benchmark.deepClone(object); + ok(clone !== object && + clone.bar.b === clone.foo.b && + clone !== clone.foo.b.foo.c.foo && + (descriptor = getDescriptor(clone, 'foo')) && + descriptor.configurable && !(descriptor.enumerable && descriptor.writable) && + (descriptor = getDescriptor(clone.foo, 'b')) && + descriptor.writable && !(descriptor.configurable && descriptor.enumerable) && + (descriptor = getDescriptor(clone.foo.b, 'foo')) && + descriptor.get && descriptor.set && + (descriptor = getDescriptor(clone.foo.b, 'foo')) && + !(descriptor.configurable && descriptor.enumerable && descriptor.writable) && + (descriptor = getDescriptor(clone, 'bar')) && + !(descriptor.configurable && descriptor.enumerable && descriptor.writable)); + } + else { + skipTest(1) + } + }); + }()); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('Benchmark.each'); + + (function() { + var xpathResult; + + var objects = { + 'array': ['a', 'b', 'c', ''], + 'array-like-object': { '0': 'a', '1': 'b', '2': 'c', '3': '', 'length': 5 }, + 'xpath snapshot': null + }; + + if (window.document && document.evaluate) { + xpathResult = [document.documentElement, document.getElementsByTagName('head')[0], document.body]; + objects['xpath snapshot'] = document.evaluate('//*[self::html or self::head or self::body]', document, null, 7, null); + } + + objects.array.length = 5; + + forOwn(objects, function(object, key) { + test('passes the correct arguments when passing an ' + key, function() { + if (object) { + var args + Benchmark.each(object, function() { + args || (args = slice.call(arguments)); + }); + + if (key == 'xpath snapshot') { + ok(args[0] === xpathResult[0]); + } else { + equal(args[0], 'a'); + } + equal(args[1], 0); + ok(args[2] === object); + } + else { + skipTest(3); + } + }); + + test('returns the passed object when passing an ' + key, function() { + if (object) { + var actual = Benchmark.each(object, function() { }); + ok(actual === object); + } + else { + skipTest(); + } + }); + + test('iterates over all indexes when passing an ' + key, function() { + if (object) { + var values = []; + Benchmark.each(object, function(value) { + values.push(value); + }); + + deepEqual(values, key == 'xpath snapshot' ? xpathResult : ['a', 'b', 'c', '']); + } + else { + skipTest(); + } + }); + + test('exits early when returning `false` when passing an ' + key, function() { + if (object) { + var values = []; + Benchmark.each(object, function(value) { + values.push(value); + return values.length < 2; + }); + + deepEqual(values, key == 'xpath snapshot' ? xpathResult.slice(0, 2) : ['a', 'b']); + } + else { + skipTest(); + } + }); + }); + + test('passes the third callback argument as an object', function() { + var thirdArg; + Benchmark.each('hello', function(value, index, object) { + thirdArg = object; + }); + + ok(thirdArg && typeof thirdArg == 'object'); + }); + + test('iterates over strings by index', function() { + var values = []; + Benchmark.each('hello', function(value) { + values.push(value) + }); + + deepEqual(values, ['h', 'e', 'l', 'l', 'o']); + }); + }()); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('Benchmark.extend'); + + (function() { + test('allows no source argument', function() { + var object = {}; + equal(Benchmark.extend(object), object); + }); + + test('allows a single source argument', function() { + var source = { 'x': 1, 'y': 1 }, + actual = Benchmark.extend({}, source); + + deepEqual(Benchmark.extend({}, source), { 'x': 1, 'y': 1 }); + }); + + test('allows multiple source arguments', function() { + var source1 = { 'x': 1, 'y': 1 }, + source2 = { 'y': 2, 'z': 2 }, + actual = Benchmark.extend({}, source1, source2); + + deepEqual(actual, { 'x': 1, 'y': 2, 'z': 2 }); + }); + + test('will add inherited source properties', function() { + function Source() { } + Source.prototype.x = 1; + deepEqual(Benchmark.extend({}, new Source), { 'x': 1 }); + }); + + test('will add problem JScript properties', function() { + deepEqual(Benchmark.extend({}, shadowed), shadowed); + }); + }()); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('Benchmark.filter'); + + (function() { + var objects = { + 'array': ['a', 'b', 'c', ''], + 'array-like-object': { '0': 'a', '1': 'b', '2': 'c', '3': '', 'length': 5 } + }; + + objects.array.length = 5; + + forOwn(objects, function(object, key) { + test('passes the correct arguments when passing an ' + key, function() { + var args; + Benchmark.filter(object, function() { + args || (args = slice.call(arguments)); + }); + + deepEqual(args, ['a', 0, object]); + }); + + test('produces the correct result when passing an ' + key, function() { + var actual = Benchmark.filter(object, function(value, index) { + return index > 0; + }); + + deepEqual(actual, ['b', 'c', '']); + }); + + test('iterates over sparse ' + key + 's correctly', function() { + var actual = Benchmark.filter(object, function(value) { + return value === undefined; + }); + + deepEqual(actual, []); + }); + }); + }()); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('Benchmark.forOwn'); + + (function() { + function fn() { + // no-op + } + + function KlassA() { + this.a = 1; + this.b = 2; + this.c = 3; + } + + function KlassB() { + this.a = 1; + this.constructor = 2; + this.hasOwnProperty = 3; + this.isPrototypeOf = 4; + this.propertyIsEnumerable = 5; + this.toLocaleString = 6; + this.toString = 7; + this.valueOf = 8; + } + + function KlassC() { + // no-op + } + + fn.a = 1; + fn.b = 2; + fn.c = 3; + + KlassC.prototype.a = 1; + KlassC.prototype.b = 2; + KlassC.prototype.c = 3; + + var objects = { + 'an arguments object': arguments, + 'a function': fn, + 'an object': new KlassA, + 'an object shadowing properties on Object.prototype': new KlassB, + 'a prototype object': KlassC.prototype, + 'a string': 'abc' + }; + + forOwn(objects, function(object, key) { + test('passes the correct arguments when passing ' + key, function() { + var args; + Benchmark.forOwn(object, function() { + args || (args = slice.call(arguments)); + }); + + equal(typeof args[0], key == 'a string' ? 'string' : 'number'); + equal(typeof args[1], 'string'); + equal(args[2] && typeof args[2], key == 'a function' ? 'function' : 'object'); + }); + + test('returns the passed object when passing ' + key, function() { + var actual = Benchmark.forOwn(object, function() { }); + deepEqual(actual, object); + }); + + test('iterates over own properties when passing ' + key, function() { + var values = []; + Benchmark.forOwn(object, function(value) { + values.push(value); + }); + + if (object instanceof KlassB) { + deepEqual(values.sort(), [1, 2, 3, 4, 5, 6, 7, 8]); + } else if (key == 'a string') { + deepEqual(values, ['a', 'b', 'c']); + } else { + deepEqual(values.sort(), [1, 2, 3]); + } + }); + + test('exits early when returning `false` when passing ' + key, function() { + var values = []; + Benchmark.forOwn(object, function(value) { + values.push(value); + return false; + }); + + equal(values.length, 1); + }); + + if (object instanceof KlassB) { + test('exits correctly when transitioning to the JScript [[DontEnum]] fix', function() { + var values = []; + Benchmark.forOwn(object, function(value) { + values.push(value); + return values.length < 2; + }); + + equal(values.length, 2); + }); + } + }); + }(1, 2, 3)); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('Benchmark.formatNumber'); + + (function() { + test('formats a million correctly', function() { + equal(Benchmark.formatNumber(1e6), '1,000,000'); + }); + + test('formats less than 100 correctly', function() { + equal(Benchmark.formatNumber(23), '23'); + }); + + test('formats numbers with decimal values correctly', function() { + equal(Benchmark.formatNumber(1234.56), '1,234.56'); + }); + + test('formats negative numbers correctly', function() { + equal(Benchmark.formatNumber(-1234.56), '-1,234.56'); + }); + }()); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('Benchmark.hasKey'); + + (function() { + test('returns `true` for own properties', function() { + var object = { 'x': 1 }; + equal(Benchmark.hasKey(object, 'x'), true); + }); + + test('returns `false` for inherited properties', function() { + equal(Benchmark.hasKey({}, 'toString'), false); + }); + + test('doesn\'t use an object\'s `hasOwnProperty` method', function() { + var object = { 'hasOwnProperty': function() { return true; } }; + equal(Benchmark.hasKey(object, 'x'), false); + }); + }()); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('Benchmark.indexOf'); + + (function() { + var objects = { + 'array': ['a', 'b', 'c', ''], + 'array-like-object': { '0': 'a', '1': 'b', '2': 'c', '3': '', 'length': 5 } + }; + + objects.array.length = 5; + + forOwn(objects, function(object, key) { + test('produces the correct result when passing an ' + key, function() { + equal(Benchmark.indexOf(object, 'b'), 1); + }); + + test('matches values by strict equality when passing an ' + key, function() { + equal(Benchmark.indexOf(object, new String('b')), -1); + }); + + test('iterates over sparse ' + key + 's correctly', function() { + equal(Benchmark.indexOf(object, undefined), -1); + }); + }); + + test('searches from the given `fromIndex`', function() { + var array = ['a', 'b', 'c', 'a']; + equal(Benchmark.indexOf(array, 'a', 1), 3); + }); + + test('handles extreme negative `fromIndex` values correctly', function() { + var array = ['a']; + array['-1'] = 'z'; + equal(Benchmark.indexOf(array, 'z', -2), -1); + }); + + test('handles extreme positive `fromIndex` values correctly', function() { + var object = { '0': 'a', '1': 'b', '2': 'c', 'length': 2 }; + equal(Benchmark.indexOf(object, 'c', 2), -1); + }); + }()); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('Benchmark.interpolate'); + + (function() { + test('replaces tokens correctly', function() { + var actual = Benchmark.interpolate('#{greeting} #{location}.', { + 'greeting': 'Hello', + 'location': 'world' + }); + + equal(actual, 'Hello world.'); + }); + + test('ignores inherited object properties', function() { + var actual = Benchmark.interpolate('x#{toString}', {}); + equal(actual, 'x#{toString}'); + }); + + test('allows for no template object', function() { + var actual = Benchmark.interpolate('x'); + equal(actual, 'x'); + }); + + test('replaces duplicate tokens', function() { + var actual = Benchmark.interpolate('#{x}#{x}#{x}', { 'x': 'a' }); + equal(actual, 'aaa'); + }); + + test('handles keys containing RegExp special characters', function() { + var actual = Benchmark.interpolate('#{.*+?^=!:${}()|[]\\/}', { '.*+?^=!:${}()|[]\\/': 'x' }); + equal(actual, 'x'); + }); + }()); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('Benchmark.invoke'); + + (function() { + var objects = { + 'array': ['a', ['b'], 'c', null], + 'array-like-object': { '0': 'a', '1': ['b'], '2': 'c', '3': null, 'length': 5 } + }; + + objects.array.length = 5; + + forOwn(objects, function(object, key) { + test('produces the correct result when passing an ' + key, function() { + var actual = Benchmark.invoke(object, 'concat'); + deepEqual(actual, ['a', ['b'], 'c', undefined, undefined]); + equal('4' in actual, false); + }); + + test('passes the correct arguments to the invoked method when passing an ' + key, function() { + var actual = Benchmark.invoke(object, 'concat', 'x', 'y', 'z'); + deepEqual(actual, ['axyz', ['b', 'x', 'y', 'z'], 'cxyz', undefined, undefined]); + equal('4' in actual, false); + }); + + test('handles options object with callbacks correctly when passing an ' + key, function() { + function callback() { + callbacks.push(slice.call(arguments)); + } + + var callbacks = []; + var actual = Benchmark.invoke(object, { + 'name': 'concat', + 'args': ['x', 'y', 'z'], + 'onStart': callback, + 'onCycle': callback, + 'onComplete': callback + }); + + deepEqual(actual, ['axyz', ['b', 'x', 'y', 'z'], 'cxyz', undefined, undefined]); + equal('4' in actual, false); + + equal(callbacks[0].length, 1); + equal(callbacks[0][0].target, 'a'); + deepEqual(callbacks[0][0].currentTarget, object); + equal(callbacks[0][0].type, 'start'); + equal(callbacks[1][0].type, 'cycle'); + equal(callbacks[5][0].type, 'complete'); + }); + + test('supports queuing when passing an ' + key, function() { + var lengths = []; + var actual = Benchmark.invoke(object, { + 'name': 'concat', + 'queued': true, + 'args': 'x', + 'onCycle': function() { + lengths.push(object.length); + } + }); + + deepEqual(lengths, [5, 4, 3, 2]); + deepEqual(actual, ['ax', ['b', 'x'], 'cx', undefined, undefined]); + }); + }); + }()); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('Benchmark.join'); + + (function() { + var objects = { + 'array': ['a', 'b', ''], + 'array-like-object': { '0': 'a', '1': 'b', '2': '', 'length': 4 }, + 'object': { 'a': '0', 'b': '1', '': '2' } + }; + + objects.array.length = 4; + + forOwn(objects, function(object, key) { + test('joins correctly using the default separator when passing an ' + key, function() { + equal(Benchmark.join(object), key == 'object' ? 'a: 0,b: 1,: 2' : 'a,b,'); + }); + + test('joins correctly using a custom separator when passing an ' + key, function() { + equal(Benchmark.join(object, '+', '@'), key == 'object' ? 'a@0+b@1+@2' : 'a+b+'); + }); + }); + }()); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('Benchmark.map'); + + (function() { + var objects = { + 'array': ['a', 'b', 'c', ''], + 'array-like-object': { '0': 'a', '1': 'b', '2': 'c', '3': '', 'length': 5 } + }; + + objects.array.length = 5; + + forOwn(objects, function(object, key) { + test('passes the correct arguments when passing an ' + key, function() { + var args; + Benchmark.map(object, function() { + args || (args = slice.call(arguments)); + }); + + deepEqual(args, ['a', 0, object]); + }); + + test('produces the correct result when passing an ' + key, function() { + var actual = Benchmark.map(object, function(value, index) { + return value + index; + }); + + deepEqual(actual, ['a0', 'b1', 'c2', '3', undefined]); + equal('4' in actual, false); + }); + + test('produces an array of the correct length for sparse ' + key + 's', function() { + equal(Benchmark.map(object, function() { }).length, 5); + }); + }); + }()); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('Benchmark.pluck'); + + (function() { + var objects = { + 'array': [{ '_': 'a' }, { '_': 'b' }, { '_': 'c' }, null], + 'array-like-object': { '0': { '_': 'a' }, '1': { '_': 'b' }, '2': { '_': 'c' }, '3': null, 'length': 5 } + }; + + objects.array.length = 5; + + forOwn(objects, function(object, key) { + test('produces the correct result when passing an ' + key, function() { + var actual = Benchmark.pluck(object, '_'); + deepEqual(actual, ['a', 'b', 'c', undefined, undefined]); + equal('4' in actual, false); + }); + + test('produces the correct result for non-existent keys when passing an ' + key, function() { + var actual = Benchmark.pluck(object, 'non-existent'); + deepEqual(actual, [undefined, undefined, undefined, undefined, undefined]); + equal('4' in actual, false); + }); + }); + }()); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('Benchmark.reduce'); + + (function() { + var objects = { + 'array': ['b', 'c', ''], + 'array-like-object': { '0': 'b', '1': 'c', '2': '', 'length': 4 } + }; + + objects.array.length = 4; + + forOwn(objects, function(object, key) { + test('passes the correct arguments when passing an ' + key, function() { + var args; + Benchmark.reduce(object, function() { + args || (args = slice.call(arguments)); + }, 'a'); + + deepEqual(args, ['a', 'b', 0, object]); + }); + + test('accumulates correctly when passing an ' + key, function() { + var actual = Benchmark.reduce(object, function(string, value) { + return string + value; + }, 'a'); + + equal(actual, 'abc'); + }); + + test('handles arguments with no initial value correctly when passing an ' + key, function() { + var args; + Benchmark.reduce(object, function() { + args || (args = slice.call(arguments)); + }); + + deepEqual(args, ['b', 'c', 1, object]); + }); + }); + }()); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('Benchmark#clone'); + + (function() { + var bench = Benchmark(function() { this.count += 0; }).run(); + + test('produces the correct result passing no arguments', function() { + var clone = bench.clone(); + deepEqual(clone, bench); + ok(clone.stats != bench.stats && clone.times != bench.times && clone.options != bench.options); + }); + + test('produces the correct result passing a data object', function() { + var clone = bench.clone({ 'fn': '', 'name': 'foo' }); + ok(clone.fn === '' && clone.options.fn === ''); + ok(clone.name == 'foo' && clone.options.name == 'foo'); + }); + }()); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('Benchmark#run'); + + (function() { + var data = { 'onComplete': 0, 'onCycle': 0, 'onStart': 0 }; + + var bench = Benchmark({ + 'fn': function() { + this.count += 0; + }, + 'onStart': function() { + data.onStart++; + }, + 'onComplete': function() { + data.onComplete++; + } + }) + .run(); + + test('onXYZ callbacks should not be triggered by internal benchmark clones', function() { + equal(data.onStart, 1); + equal(data.onComplete, 1); + }); + }()); + + /*--------------------------------------------------------------------------*/ + + forOwn({ + 'Benchmark': Benchmark, + 'Benchmark.Suite': Benchmark.Suite + }, + function(Constructor, namespace) { + + QUnit.module(namespace + '#emit'); + + (function() { + test('emits passed arguments', function() { + var args, + object = Constructor(); + + object.on('args', function() { args = slice.call(arguments, 1); }); + object.emit('args', 'a', 'b', 'c'); + deepEqual(args, ['a', 'b', 'c']); + }); + + test('emits with no listeners', function() { + var event = Benchmark.Event('empty'), + object = Constructor(); + + object.emit(event); + equal(event.cancelled, false); + }); + + test('emits with an event type of "toString"', function() { + var event = Benchmark.Event('toString'), + object = Constructor(); + + object.emit(event); + equal(event.cancelled, false); + }); + + test('returns the last listeners returned value', function() { + var event = Benchmark.Event('result'), + object = Constructor(); + + object.on('result', function() { return 'x'; }); + object.on('result', function() { return 'y'; }); + equal(object.emit(event), 'y'); + }); + + test('aborts the emitters listener iteration when `event.aborted` is `true`', function() { + var event = Benchmark.Event('aborted'), + object = Constructor(); + + object.on('aborted', function(event) { + event.aborted = true; + return false; + }); + + object.on('aborted', function(event) { + // should not get here + event.aborted = false; + return true; + }); + + equal(object.emit(event), false); + equal(event.aborted, true); + }); + + test('cancels the event if a listener explicitly returns `false`', function() { + var event = Benchmark.Event('cancel'), + object = Constructor(); + + object.on('cancel', function() { return false; }); + object.on('cancel', function() { return true; }); + object.emit(event); + equal(event.cancelled, true); + }); + + test('uses a shallow clone of the listeners when emitting', function() { + var event, + listener2 = function(eventObject) { eventObject.listener2 = true }, + object = Constructor(); + + object.on('shallowclone', function(eventObject) { + event = eventObject; + object.off(event.type, listener2); + }) + .on('shallowclone', listener2) + .emit('shallowclone'); + + ok(event.listener2); + }); + + test('emits a custom event object', function() { + var event = Benchmark.Event('custom'), + object = Constructor(); + + object.on('custom', function(eventObject) { eventObject.touched = true; }); + object.emit(event); + ok(event.touched); + }); + + test('sets `event.result` correctly', function() { + var event = Benchmark.Event('result'), + object = Constructor(); + + object.on('result', function() { return 'x'; }); + object.emit(event); + equal(event.result, 'x'); + }); + + test('sets `event.type` correctly', function() { + var event, + object = Constructor(); + + object.on('type', function(eventObj) { + event = eventObj; + }); + + object.emit('type'); + equal(event.type, 'type'); + }); + }()); + + /*------------------------------------------------------------------------*/ + + QUnit.module(namespace + '#listeners'); + + (function() { + test('returns the correct listeners', function() { + var listener = function() { }, + object = Constructor(); + + object.on('x', listener); + deepEqual(object.listeners('x'), [listener]); + }); + + test('returns an array and initializes previously uninitialized listeners', function() { + var object = Constructor(); + deepEqual(object.listeners('x'), []); + deepEqual(object.events, { 'x': [] }); + }); + }()); + + /*------------------------------------------------------------------------*/ + + QUnit.module(namespace + '#off'); + + (function() { + test('returns the benchmark', function() { + var listener = function() { }, + object = Constructor(); + + object.on('x', listener); + equal(object.off('x', listener), object); + }); + + test('will ignore inherited properties of the event cache', function() { + var Dummy = function() { }, + listener = function() { }, + object = Constructor(); + + Dummy.prototype.x = [listener]; + object.events = new Dummy; + + object.off('x', listener); + deepEqual(object.events.x, [listener]); + }); + + test('handles an event type and listener', function() { + var listener = function() { }, + object = Constructor(); + + object.on('x', listener); + object.off('x', listener); + deepEqual(object.events.x, []); + }); + + test('handles unregistering duplicate listeners', function() { + var listener = function() { }, + object = Constructor(); + + object.on('x', listener); + object.on('x', listener); + + var events = object.events; + object.off('x', listener); + deepEqual(events.x, [listener]); + + object.off('x', listener); + deepEqual(events.x, []); + }); + + test('handles a non-registered listener', function() { + var object = Constructor(); + object.off('x', function() { }); + equal(object.events, undefined); + }); + + test('handles space separated event type and listener', function() { + var listener = function() { }, + object = Constructor(); + + object.on('x', listener); + object.on('y', listener); + + var events = object.events; + object.off('x y', listener); + deepEqual(events.x, []); + deepEqual(events.y, []); + }); + + test('handles space separated event type and no listener', function() { + var listener1 = function() { }, + listener2 = function() { }, + object = Constructor(); + + object.on('x', listener1); + object.on('y', listener2); + + var events = object.events; + object.off('x y'); + deepEqual(events.x, []); + deepEqual(events.y, []); + }); + + test('handles no arguments', function() { + var listener1 = function() { }, + listener2 = function() { }, + listener3 = function() { }, + object = Constructor(); + + object.on('x', listener1); + object.on('y', listener2); + object.on('z', listener3); + + var events = object.events; + object.off(); + deepEqual(events.x, []); + deepEqual(events.y, []); + deepEqual(events.z, []); + }); + }()); + + /*------------------------------------------------------------------------*/ + + QUnit.module(namespace + '#on'); + + (function() { + test('returns the benchmark', function() { + var listener = function() { }, + object = Constructor(); + + equal(object.on('x', listener), object); + }); + + test('will ignore inherited properties of the event cache', function() { + var Dummy = function() { }, + listener1 = function() { }, + listener2 = function() { }, + object = Constructor(); + + Dummy.prototype.x = [listener1]; + object.events = new Dummy; + + object.on('x', listener2); + deepEqual(object.events.x, [listener2]); + }); + + test('handles an event type and listener', function() { + var listener = function() { }, + object = Constructor(); + + object.on('x', listener); + deepEqual(object.events.x, [listener]); + }); + + test('handles registering duplicate listeners', function() { + var listener = function() { }, + object = Constructor(); + + object.on('x', listener); + object.on('x', listener); + deepEqual(object.events.x, [listener, listener]); + }); + + test('handles space separated event type and listener', function() { + var listener = function() { }, + object = Constructor(); + + object.on('x y', listener); + + var events = object.events; + deepEqual(events.x, [listener]); + deepEqual(events.y, [listener]); + }); + }()); + }); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('Benchmark.Suite#abort'); + + (function() { + test('igores abort calls when the suite isn\'t running', function() { + var fired = false; + var suite = Benchmark.Suite('suite', { + 'onAbort': function() { fired = true; } + }); + + suite.add('foo', function() { }); + suite.abort(); + equal(fired, false); + }); + + test('ignores abort calls from `Benchmark.Suite#reset` when the suite isn\'t running', function() { + var fired = false; + var suite = Benchmark.Suite('suite', { + 'onAbort': function() { fired = true; } + }); + + suite.add('foo', function() { }); + suite.reset(); + equal(fired, false); + }); + + asyncTest('emits an abort event when running', function() { + var fired = false; + + Benchmark.Suite({ + 'onAbort': function() { fired = true; } + }) + .on('start', function() { + this.abort(); + }) + .on('complete', function() { + ok(fired); + QUnit.start(); + }) + .add(function(){ }) + .run({ 'async': true }); + }); + + asyncTest('emits an abort event after calling `Benchmark.Suite#reset`', function() { + var fired = false; + + Benchmark.Suite({ + 'onAbort': function() { fired = true; } + }) + .on('start', function() { + this.reset(); + }) + .on('complete', function() { + ok(fired); + QUnit.start(); + }) + .add(function(){ }) + .run({ 'async': true }); + }); + + asyncTest('should abort deferred benchmark', function() { + var fired = false, + suite = Benchmark.Suite(); + + suite.on('complete', function() { + equal(fired, false); + QUnit.start(); + }) + .add('a', { + 'defer': true, + 'fn': function(deferred) { + // avoid test inlining + suite.name; + // delay resolve + setTimeout(function() { + deferred.resolve(); + suite.abort(); + }, 10); + } + }) + .add('b', { + 'defer': true, + 'fn': function(deferred) { + // avoid test inlining + suite.name; + // delay resolve + setTimeout(function() { + deferred.resolve(); + fired = true; + }, 10); + } + }) + .run(); + }); + }()); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('Benchmark.Suite#concat'); + + (function() { + var args = arguments; + + test('doesn\'t treat an arguments object like an array', function() { + var suite = Benchmark.Suite(); + deepEqual(suite.concat(args), [args]); + }); + + test('flattens array arguments', function() { + var suite = Benchmark.Suite(); + deepEqual(suite.concat([1, 2], 3, [4, 5]), [1, 2, 3, 4, 5]); + }); + + test('supports concating sparse arrays', function() { + var suite = Benchmark.Suite(); + suite[0] = 0; + suite[2] = 2; + suite.length = 3; + + var actual = suite.concat(3); + deepEqual(actual, [0, undefined, 2, 3]); + equal('1' in actual, false); + }); + + test('supports sparse arrays as arguments', function() { + var suite = Benchmark.Suite(), + sparse = []; + + sparse[0] = 0; + sparse[2] = 2; + sparse.length = 3; + + var actual = suite.concat(sparse); + deepEqual(actual, [0, undefined, 2]); + equal('1' in actual, false); + }); + + test('creates a new array', function() { + var suite = Benchmark.Suite(); + ok(suite.concat(1) !== suite); + }); + }(1, 2, 3)); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('Benchmark.Suite#reverse'); + + (function() { + test('reverses the element order', function() { + var suite = Benchmark.Suite(); + suite[0] = 0; + suite[1] = 1; + suite.length = 2; + + var actual = suite.reverse(); + equal(actual, suite); + deepEqual(slice.call(actual), [1, 0]); + }); + + test('supports reversing sparse arrays', function() { + var suite = Benchmark.Suite(); + suite[0] = 0; + suite[2] = 2; + suite.length = 3; + + var actual = suite.reverse(); + equal(actual, suite); + deepEqual(slice.call(actual), [2, undefined, 0]); + equal('1' in actual, false); + }); + }()); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('Benchmark.Suite#shift'); + + (function() { + test('removes the first element', function() { + var suite = Benchmark.Suite(); + suite[0] = 0; + suite[1] = 1; + suite.length = 2; + + var actual = suite.shift(); + equal(actual, 0); + deepEqual(slice.call(suite), [1]); + }); + + test('shifts an object with no elements', function() { + var suite = Benchmark.Suite(), + actual = suite.shift(); + + equal(actual, undefined); + deepEqual(slice.call(suite), []); + }); + + test('should have no elements when length is 0 after shift', function() { + var suite = Benchmark.Suite(); + suite[0] = 0; + suite.length = 1; + suite.shift(); + + // ensure element is removed + equal('0' in suite, false); + equal(suite.length, 0); + }); + + test('supports shifting sparse arrays', function() { + var suite = Benchmark.Suite(); + suite[1] = 1; + suite[3] = 3; + suite.length = 4; + + var actual = suite.shift(); + equal(actual, undefined); + deepEqual(slice.call(suite), [1, undefined, 3]); + equal('1' in suite, false); + }); + }()); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('Benchmark.Suite#slice'); + + (function() { + var suite = Benchmark.Suite(); + suite[0] = 0; + suite[1] = 1; + suite[2] = 2; + suite[3] = 3; + suite.length = 4; + + test('works with no arguments', function() { + var actual = suite.slice(); + deepEqual(actual, [0, 1, 2, 3]); + ok(suite !== actual); + }); + + test('works with positive `start` argument', function() { + var actual = suite.slice(2); + deepEqual(actual, [2, 3]); + ok(suite !== actual); + }); + + test('works with positive `start` and `end` arguments', function() { + var actual = suite.slice(1, 3); + deepEqual(actual, [1, 2]); + ok(suite !== actual); + }); + + test('works with `end` values exceeding length', function() { + var actual = suite.slice(1, 10); + deepEqual(actual, [1, 2, 3]); + ok(suite !== actual); + }); + + test('works with negative `start` and `end` arguments', function() { + var actual = suite.slice(-3, -1); + deepEqual(actual, [1, 2]); + ok(suite !== actual); + }); + + test('works with an extreme negative `end` value', function() { + var actual = suite.slice(1, -10); + deepEqual(actual, []); + equal('-1' in actual, false); + ok(suite !== actual); + }); + + test('supports slicing sparse arrays', function() { + var sparse = Benchmark.Suite(); + sparse[1] = 1; + sparse[3] = 3; + sparse.length = 4; + + var actual = sparse.slice(0, 2); + deepEqual(actual, [undefined, 1]); + equal('0' in actual, false); + + actual = sparse.slice(1); + deepEqual(actual, [1, undefined, 3]); + equal('1' in actual, false); + }); + }()); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('Benchmark.Suite#splice'); + + (function() { + test('works with no arguments', function() { + var suite = Benchmark.Suite(); + suite[0] = 0; + suite.length = 1; + + var actual = suite.splice(); + deepEqual(actual, []); + deepEqual(slice.call(suite), [0]); + }); + + test('works with only the `start` argument', function() { + var suite = Benchmark.Suite(); + suite[0] = 0; + suite[1] = 1; + suite.length = 2; + + var actual = suite.splice(1); + deepEqual(actual, [1]); + deepEqual(slice.call(suite), [0]); + }); + + test('should have no elements when length is 0 after splice', function() { + var suite = Benchmark.Suite(); + suite[0] = 0; + suite.length = 1 + suite.splice(0, 1); + + // ensure element is removed + equal('0' in suite, false); + equal(suite.length, 0); + }); + + test('works with positive `start` argument', function() { + var suite = Benchmark.Suite(); + suite[0] = 0; + suite[1] = 3; + suite.length = 2; + + var actual = suite.splice(1, 0, 1, 2); + deepEqual(actual, []); + deepEqual(slice.call(suite), [0, 1, 2, 3]); + }); + + test('works with positive `start` and `deleteCount` arguments', function() { + var suite = Benchmark.Suite(); + suite[0] = 0; + suite[1] = 3; + suite.length = 2; + + var actual = suite.splice(1, 1, 1, 2); + deepEqual(actual, [3]); + deepEqual(slice.call(suite), [0, 1, 2]); + }); + + test('works with `deleteCount` values exceeding length', function() { + var suite = Benchmark.Suite(); + suite[0] = 0; + suite[1] = 3; + suite.length = 2; + + var actual = suite.splice(1, 10, 1, 2); + deepEqual(actual, [3]); + deepEqual(slice.call(suite), [0, 1, 2]); + }); + + test('works with negative `start` and `deleteCount` arguments', function() { + var suite = Benchmark.Suite(); + suite[0] = 0; + suite[1] = 3; + suite.length = 2; + + var actual = suite.splice(-1, -1, 1, 2); + deepEqual(actual, []); + deepEqual(slice.call(suite), [0, 1, 2, 3]); + }); + + test('works with an extreme negative `deleteCount` value', function() { + var suite = Benchmark.Suite(); + suite[0] = 0; + suite[1] = 3; + suite.length = 2; + + var actual = suite.splice(0, -10, 1, 2); + deepEqual(actual, []); + deepEqual(slice.call(suite), [1, 2, 0, 3]); + }); + + test('supports splicing sparse arrays', function() { + var suite = Benchmark.Suite(); + suite[1] = 1; + suite[3] = 3; + suite.length = 4; + + var actual = suite.splice(1, 2, 1, 2); + deepEqual(actual, [1, undefined]); + equal(actual.length, 2); + deepEqual(slice.call(suite), [undefined, 1, 2, 3]); + equal('0' in suite, false); + }); + }()); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('Benchmark.Suite#unshift'); + + (function() { + test('adds a first element', function() { + var suite = Benchmark.Suite(); + suite[0] = 1; + suite.length = 1; + + var actual = suite.unshift(0); + equal(actual, 2); + deepEqual(slice.call(suite), [0, 1]); + }); + + test('adds multiple elements to the front', function() { + var suite = Benchmark.Suite(); + suite[0] = 3; + suite.length = 1; + + var actual = suite.unshift(0, 1, 2); + equal(actual, 4); + deepEqual(slice.call(suite), [0, 1, 2, 3]); + }); + + test('supports unshifting sparse arrays', function() { + var suite = Benchmark.Suite(); + suite[1] = 2; + suite.length = 2; + + var actual = suite.unshift(0); + equal(actual, 3); + deepEqual(slice.call(suite), [0, undefined, 2]); + equal('1' in suite, false); + }); + }()); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('Benchmark.Suite filtered results onComplete'); + + (function() { + var count = 0, + suite = Benchmark.Suite(); + + suite.add('a', function() { + count++; + }) + .add('b', function() { + for (var i = 0; i < 1e6; i++) { + count++; + } + }) + .add('c', function() { + throw new TypeError; + }); + + asyncTest('should filter by fastest', function() { + suite.on('complete', function() { + suite.off(); + deepEqual(this.filter('fastest').pluck('name'), ['a']); + QUnit.start(); + }) + .run({ 'async': true }); + }); + + asyncTest('should filter by slowest', function() { + suite.on('complete', function() { + suite.off(); + deepEqual(this.filter('slowest').pluck('name'), ['b']); + QUnit.start(); + }) + .run({ 'async': true }); + }); + + asyncTest('should filter by successful', function() { + suite.on('complete', function() { + suite.off(); + deepEqual(this.filter('successful').pluck('name'), ['a', 'b']); + QUnit.start(); + }) + .run({ 'async': true }); + }); + }()); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('Benchmark.Suite event flow'); + + (function() { + var events = [], + callback = function(event) { events.push(event); }; + + var suite = Benchmark.Suite('suite', { + 'onAdd': callback, + 'onAbort': callback, + 'onClone': callback, + 'onError': callback, + 'onStart': callback, + 'onCycle': callback, + 'onComplete': callback, + 'onReset': callback + }) + .add('bench', function() { + throw null; + }, { + 'onAbort': callback, + 'onClone': callback, + 'onError': callback, + 'onStart': callback, + 'onCycle': callback, + 'onComplete': callback, + 'onReset': callback + }) + .run({ 'async': false }); + + // first Suite#onAdd + test('should emit the suite "add" event first', function() { + var event = events[0]; + ok(event.type == 'add' && event.currentTarget.name == 'suite' && event.target.name == 'bench'); + }); + + // next we start the Suite because no reset was needed + test('should emit the suite "start" event', function() { + var event = events[1]; + ok(event.type == 'start' && event.currentTarget.name == 'suite' && event.target.name == 'bench'); + }); + + // and so start the first benchmark + test('should emit the benchmark "start" event', function() { + var event = events[2]; + ok(event.type == 'start' && event.currentTarget.name == 'bench'); + }); + + // oh no! we abort because of an error + test('should emit the benchmark "error" event', function() { + var event = events[3]; + ok(event.type == 'error' && event.currentTarget.name == 'bench'); + }); + + // benchmark error triggered + test('should emit the benchmark "abort" event', function() { + var event = events[4]; + ok(event.type == 'abort' && event.currentTarget.name == 'bench'); + }); + + // we reset the benchmark as part of the abort + test('should emit the benchmark "reset" event', function() { + var event = events[5]; + ok(event.type == 'reset' && event.currentTarget.name == 'bench'); + }); + + // benchmark is cycle is finished + test('should emit the benchmark "cycle" event', function() { + var event = events[6]; + ok(event.type == 'cycle' && event.currentTarget.name == 'bench'); + }); + + // benchmark is complete + test('should emit the benchmark "complete" event', function() { + var event = events[7]; + ok(event.type == 'complete' && event.currentTarget.name == 'bench'); + }); + + // the benchmark error triggers a Suite error + test('should emit the suite "error" event', function() { + var event = events[8]; + ok(event.type == 'error' && event.currentTarget.name == 'suite' && event.target.name == 'bench'); + }); + + // the Suite cycle finishes + test('should emit the suite "cycle" event', function() { + var event = events[9]; + ok(event.type == 'cycle' && event.currentTarget.name == 'suite' && event.target.name == 'bench'); + }); + + // the Suite completes + test('finally it should emit the suite "complete" event', function() { + var event = events[10]; + ok(event.type == 'complete' && event.currentTarget.name == 'suite' && event.target.name == 'bench'); + }); + + test('emitted all expected events', function() { + ok(events.length == 11); + }); + }()); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('Deferred benchmarks'); + + (function() { + asyncTest('should run a deferred benchmark correctly', function() { + Benchmark(function(deferred) { + setTimeout(function() { deferred.resolve(); }, 1e3); + }, { + 'defer': true, + 'onComplete': function() { + equal(this.hz.toFixed(0), 1); + QUnit.start(); + } + }) + .run(); + }); + + asyncTest('should run with string values for "fn", "setup", and "teardown"', function() { + Benchmark({ + 'defer': true, + 'setup': 'var x = [3, 2, 1];', + 'fn': 'setTimeout(function() { x.sort(); deferred.resolve(); }, 10);', + 'teardown': 'x.length = 0;', + 'onComplete': function() { + ok(true); + QUnit.start(); + } + }) + .run(); + }); + + asyncTest('should run recursively', function() { + Benchmark({ + 'defer': true, + 'setup': 'var x = [3, 2, 1];', + 'fn': 'for (var i = 0; i < 100; i++) x[ i % 2 ? "sort" : "reverse" ](); deferred.resolve();', + 'teardown': 'x.length = 0;', + 'onComplete': function() { + ok(true); + QUnit.start(); + } + }) + .run(); + }); + + asyncTest('should execute "setup", "fn", and "teardown" in correct order', function() { + var fired = []; + + Benchmark({ + 'defer': true, + 'setup': function() { + fired.push('setup'); + }, + 'fn': function(deferred) { + fired.push('fn'); + setTimeout(function() { deferred.resolve(); }, 10); + }, + 'teardown': function() { + fired.push('teardown'); + }, + 'onComplete': function() { + var actual = fired.join().replace(/(fn,)+/g, '$1').replace(/(setup,fn,teardown(?:,|$))+/, '$1'); + equal(actual, 'setup,fn,teardown'); + QUnit.start(); + } + }) + .run(); + }); + }()); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('Benchmark.deepClone'); + + (function() { + asyncTest('avoids call stack limits', function() { + var result, + count = 0, + object = {}, + recurse = function() { count++; recurse(); }; + + setTimeout(function() { + ok(result, 'avoids call stack limits (stack limit is ' + (count - 1) + ')'); + QUnit.start(); + }, 15); + + if (toString.call(window.java) == '[object JavaPackage]') { + // Java throws uncatchable errors on call stack overflows, so to avoid + // them I chose a number higher than Rhino's call stack limit without + // dynamically testing for the actual limit + count = 3e3; + } else { + try { recurse(); } catch(e) { } + } + + // exceed limit + count++; + for (var i = 0, sub = object; i <= count; i++) { + sub = sub[i] = {}; + } + + try { + for (var i = 0, sub = Benchmark.deepClone(object); sub = sub[i]; i++) { } + result = --i == count; + } catch(e) { } + }); + }()); + + /*--------------------------------------------------------------------------*/ + + // explicitly call `QUnit.start()` for Narwhal, Rhino, and RingoJS + if (!window.document) { + QUnit.start(); + } +}(typeof global == 'object' && global || this)); diff --git a/web/src/vendor/benchmark/vendor/docdown/LICENSE.txt b/web/src/vendor/benchmark/vendor/docdown/LICENSE.txt new file mode 100644 index 00000000..dadad22f --- /dev/null +++ b/web/src/vendor/benchmark/vendor/docdown/LICENSE.txt @@ -0,0 +1,20 @@ +Copyright 2011-2012 John-David Dalton + +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. \ No newline at end of file diff --git a/web/src/vendor/benchmark/vendor/docdown/README.md b/web/src/vendor/benchmark/vendor/docdown/README.md new file mode 100644 index 00000000..7e2665e3 --- /dev/null +++ b/web/src/vendor/benchmark/vendor/docdown/README.md @@ -0,0 +1,33 @@ +# Docdown v1.0.0 + +A simple JSDoc to Markdown documentation generator. + +## Documentation + +The documentation for Docdown can be viewed here: [/doc/README.md](https://github.com/jdalton/docdown/blob/master/doc/README.md#readme) + +For a list of upcoming features, check out our [roadmap](https://github.com/jdalton/docdown/wiki/Roadmap). + +## Installation and usage + +Usage example: + +```php +require("docdown.php"); + +// generate Markdown +$markdown = docdown(array( + "path" => $filepath, + "url" => "https://github.com/username/project/blob/master/my.js" +)); +``` + +## Author + +* [John-David Dalton](http://allyoucanleet.com/) + [![twitter/jdalton](http://gravatar.com/avatar/299a3d891ff1920b69c364d061007043?s=70)](https://twitter.com/jdalton "Follow @jdalton on Twitter") + +## Contributors + +* [Mathias Bynens](http://mathiasbynens.be/) + [![twitter/mathias](http://gravatar.com/avatar/24e08a9ea84deb17ae121074d0f17125?s=70)](https://twitter.com/mathias "Follow @mathias on Twitter") diff --git a/web/src/vendor/benchmark/vendor/docdown/docdown.php b/web/src/vendor/benchmark/vendor/docdown/docdown.php new file mode 100644 index 00000000..6a960d49 --- /dev/null +++ b/web/src/vendor/benchmark/vendor/docdown/docdown.php @@ -0,0 +1,38 @@ + + * Available under MIT license + */ +require(dirname(__FILE__) . '/src/DocDown/Generator.php'); + +/** + * Generates Markdown from JSDoc entries in a given file. + * + * @param {Array} [$options=array()] The options array. + * @returns {String} The generated Markdown. + * @example + * + * // specify a file path + * $markdown = docdown(array( + * // path to js file + * 'path' => $filepath, + * // url used to reference line numbers in code + * 'url' => 'https://github.com/username/project/blob/master/my.js' + * )); + * + * // or pass raw js + * $markdown = docdown(array( + * // raw JavaScript source + * 'source' => $rawJS, + * // documentation title + * 'title' => 'My API Documentation', + * // url used to reference line numbers in code + * 'url' => 'https://github.com/username/project/blob/master/my.js' + * )); + */ +function docdown( $options = array() ) { + $gen = new Generator($options); + return $gen->generate(); +} +?> \ No newline at end of file diff --git a/web/src/vendor/benchmark/vendor/docdown/src/DocDown/Entry.php b/web/src/vendor/benchmark/vendor/docdown/src/DocDown/Entry.php new file mode 100644 index 00000000..e7924c0e --- /dev/null +++ b/web/src/vendor/benchmark/vendor/docdown/src/DocDown/Entry.php @@ -0,0 +1,304 @@ +entry = $entry; + $this->lang = $lang; + $this->source = str_replace(PHP_EOL, "\n", $source); + } + + /*--------------------------------------------------------------------------*/ + + /** + * Extracts the documentation entries from source code. + * + * @static + * @memberOf Entry + * @param {String} $source The source code. + * @returns {Array} The array of entries. + */ + public static function getEntries( $source ) { + preg_match_all('#/\*\*(?![-!])[\s\S]*?\*/\s*[^\n]+#', $source, $result); + return array_pop($result); + } + + /*--------------------------------------------------------------------------*/ + + /** + * Checks if the entry is a function reference. + * + * @private + * @memberOf Entry + * @returns {Boolean} Returns `true` if the entry is a function reference, else `false`. + */ + private function isFunction() { + return !!( + $this->isCtor() || + count($this->getParams()) || + count($this->getReturns()) || + preg_match('/\*\s*@function\b/', $this->entry) + ); + } + + /*--------------------------------------------------------------------------*/ + + /** + * Extracts the function call from the entry. + * + * @memberOf Entry + * @returns {String} The function call. + */ + public function getCall() { + preg_match('#\*/\s*(?:function ([^(]*)|(.*?)(?=[:=,]|return\b))#', $this->entry, $result); + if ($result = array_pop($result)) { + $result = array_pop(explode('var ', trim(trim(array_pop(explode('.', $result))), "'"))); + } + // resolve name + // avoid $this->getName() because it calls $this->getCall() + preg_match('#\*\s*@name\s+([^\n]+)#', $this->entry, $name); + if (count($name)) { + $name = trim($name[1]); + } else { + $name = $result; + } + // compile function call syntax + if ($this->isFunction()) { + // compose parts + $result = array($result); + $params = $this->getParams(); + foreach ($params as $param) { + $result[] = $param[1]; + } + // format + $result = $name .'('. implode(array_slice($result, 1), ', ') .')'; + $result = str_replace(', [', ' [, ', str_replace('], [', ', ', $result)); + } + return $result ? $result : $name; + } + + /** + * Extracts the entry description. + * + * @memberOf Entry + * @returns {String} The entry description. + */ + public function getDesc() { + preg_match('#/\*\*(?:\s*\*)?([\s\S]*?)(?=\*\s\@[a-z]|\*/)#', $this->entry, $result); + if (count($result)) { + $type = $this->getType(); + $result = trim(preg_replace('/(?:^|\n)\s*\* ?/', ' ', $result[1])); + $result = ($type == 'Function' ? '' : '(' . str_replace('|', ', ', trim($type, '{}')) . '): ') . $result; + } + return $result; + } + + /** + * Extracts the entry `example` data. + * + * @memberOf Entry + * @returns {String} The entry `example` data. + */ + public function getExample() { + preg_match('#\*\s*@example\s+([\s\S]*?)(?=\*\s\@[a-z]|\*/)#', $this->entry, $result); + if (count($result)) { + $result = trim(preg_replace('/(?:^|\n)\s*\* ?/', "\n", $result[1])); + $result = '```' . $this->lang . "\n" . $result . "\n```"; + } + return $result; + } + + /** + * Resolves the line number of the entry. + * + * @memberOf Entry + * @returns {Number} The line number. + */ + public function getLineNumber() { + preg_match_all('/\n/', substr($this->source, 0, strrpos($this->source, $this->entry) + strlen($this->entry)), $lines); + return count(array_pop($lines)) + 1; + } + + /** + * Extracts the entry `member` data. + * + * @memberOf Entry + * @param {Number} $index The index of the array value to return. + * @returns {Array|String} The entry `member` data. + */ + public function getMembers( $index = null ) { + preg_match('#\*\s*@member(?:Of)?\s+([^\n]+)#', $this->entry, $result); + if (count($result)) { + $result = trim(preg_replace('/(?:^|\n)\s*\* ?/', ' ', $result[1])); + $result = preg_split('/,\s*/', $result); + } + return $index !== null ? @$result[$index] : $result; + } + + /** + * Extracts the entry `name` data. + * + * @memberOf Entry + * @returns {String} The entry `name` data. + */ + public function getName() { + preg_match('#\*\s*@name\s+([^\n]+)#', $this->entry, $result); + if (count($result)) { + $result = trim(preg_replace('/(?:^|\n)\s*\* ?/', ' ', $result[1])); + } else { + $result = array_shift(explode('(', $this->getCall())); + } + return $result; + } + + /** + * Extracts the entry `param` data. + * + * @memberOf Entry + * @param {Number} $index The index of the array value to return. + * @returns {Array} The entry `param` data. + */ + public function getParams( $index = null ) { + preg_match_all('#\*\s*@param\s+\{([^}]+)\}\s+(\[.+\]|[$\w]+)\s+([\s\S]*?)(?=\*\s\@[a-z]|\*/)#i', $this->entry, $result); + if (count($result = array_filter(array_slice($result, 1)))) { + // repurpose array + foreach ($result as $param) { + foreach ($param as $key => $value) { + if (!is_array($result[0][$key])) { + $result[0][$key] = array(); + } + $result[0][$key][] = trim(preg_replace('/(?:^|\n)\s*\* ?/', ' ', $value)); + } + } + $result = $result[0]; + } + return $index !== null ? @$result[$index] : $result; + } + + /** + * Extracts the entry `returns` data. + * + * @memberOf Entry + * @returns {String} The entry `returns` data. + */ + public function getReturns() { + preg_match('#\*\s*@returns\s+\{([^}]+)\}\s+([\s\S]*?)(?=\*\s\@[a-z]|\*/)#', $this->entry, $result); + if (count($result)) { + $result = array_map('trim', array_slice($result, 1)); + $result[0] = str_replace('|', ', ', $result[0]); + $result[1] = preg_replace('/(?:^|\n)\s*\* ?/', ' ', $result[1]); + } + return $result; + } + + /** + * Extracts the entry `type` data. + * + * @memberOf Entry + * @returns {String} The entry `type` data. + */ + public function getType() { + preg_match('#\*\s*@type\s+([^\n]+)#', $this->entry, $result); + if (count($result)) { + $result = trim(preg_replace('/(?:^|\n)\s*\* ?/', ' ', $result[1])); + } else { + $result = $this->isFunction() ? 'Function' : 'Unknown'; + } + return $result; + } + + /** + * Checks if an entry is a constructor. + * + * @memberOf Entry + * @returns {Boolean} Returns true if a constructor, else false. + */ + public function isCtor() { + return !!preg_match('/\*\s*@constructor\b/', $this->entry); + } + + /** + * Checks if an entry *is* assigned to a prototype. + * + * @memberOf Entry + * @returns {Boolean} Returns true if assigned to a prototype, else false. + */ + public function isPlugin() { + return !$this->isCtor() && !$this->isPrivate() && !$this->isStatic(); + } + + /** + * Checks if an entry is private. + * + * @memberOf Entry + * @returns {Boolean} Returns true if private, else false. + */ + public function isPrivate() { + return !!preg_match('/\*\s*@private\b/', $this->entry) || strrpos($this->entry, '@') === false; + } + + /** + * Checks if an entry is *not* assigned to a prototype. + * + * @memberOf Entry + * @returns {Boolean} Returns true if not assigned to a prototype, else false. + */ + public function isStatic() { + $public = !$this->isPrivate(); + $result = $public && !!preg_match('/\*\s*@static\b/', $this->entry); + + // set in cases where it isn't explicitly stated + if ($public && !$result) { + if ($parent = array_pop(preg_split('/[#.]/', $this->getMembers(0)))) { + foreach (Entry::getEntries($this->source) as $entry) { + $entry = new Entry($entry, $this->source); + if ($entry->getName() == $parent) { + $result = !$entry->isCtor(); + break; + } + } + } else { + $result = true; + } + } + return $result; + } +} +?> \ No newline at end of file diff --git a/web/src/vendor/benchmark/vendor/docdown/src/DocDown/Generator.php b/web/src/vendor/benchmark/vendor/docdown/src/DocDown/Generator.php new file mode 100644 index 00000000..6c1873d8 --- /dev/null +++ b/web/src/vendor/benchmark/vendor/docdown/src/DocDown/Generator.php @@ -0,0 +1,416 @@ +options = $options; + $this->source = str_replace(PHP_EOL, "\n", $options['source']); + $this->entries = Entry::getEntries($this->source); + + foreach ($this->entries as $index => $value) { + $this->entries[$index] = new Entry($value, $this->source, $options['lang']); + } + } + + /*--------------------------------------------------------------------------*/ + + /** + * Performs common string formatting operations. + * + * @private + * @static + * @memberOf Generator + * @param {String} $string The string to format. + * @returns {String} The formatted string. + */ + private static function format($string) { + $counter = 0; + + // tokenize inline code snippets + preg_match_all('/`[^`]+`/', $string, $tokenized); + $tokenized = $tokenized[0]; + foreach ($tokenized as $snippet) { + $string = str_replace($snippet, '__token' . ($counter++) .'__', $string); + } + + // italicize parentheses + $string = preg_replace('/(^|\s)(\([^)]+\))/', '$1*$2*', $string); + + // mark numbers as inline code + $string = preg_replace('/ (-?\d+(?:.\d+)?)(?!\.[^\n])/', ' `$1`', $string); + + // detokenize inline code snippets + $counter = 0; + foreach ($tokenized as $snippet) { + $string = str_replace('__token' . ($counter++) . '__', $snippet, $string); + } + + return trim($string); + } + + /** + * Modify a string by replacing named tokens with matching assoc. array values. + * + * @private + * @static + * @memberOf Generator + * @param {String} $string The string to modify. + * @param {Array|Object} $object The template object. + * @returns {String} The modified string. + */ + private static function interpolate($string, $object) { + preg_match_all('/#\{([^}]+)\}/', $string, $tokens); + $tokens = array_unique(array_pop($tokens)); + + foreach ($tokens as $token) { + $pattern = '/#\{' . $token . '\}/'; + $replacement = ''; + + if (is_object($object)) { + preg_match('/\(([^)]+?)\)$/', $token, $args); + $args = preg_split('/,\s*/', array_pop($args)); + $method = 'get' . ucfirst(str_replace('/\([^)]+?\)$/', '', $token)); + + if (method_exists($object, $method)) { + $replacement = (string) call_user_func_array(array($object, $method), $args); + } else if (isset($object->{$token})) { + $replacement = (string) $object->{$token}; + } + } else if (isset($object[$token])) { + $replacement = (string) $object[$token]; + } + $string = preg_replace($pattern, trim($replacement), $string); + } + return Generator::format($string); + } + + /*--------------------------------------------------------------------------*/ + + /** + * Resolves the entry's hash used to navigate the documentation. + * + * @private + * @memberOf Generator + * @param {Number|Object} $entry The entry object. + * @param {String} $member The name of the member. + * @returns {String} The url hash. + */ + private function getHash( $entry, $member = '' ) { + $entry = is_numeric($entry) ? $this->entries[$entry] : $entry; + $member = !$member ? $entry->getMembers(0) : $member; + $result = ($member ? $member . ($entry->isPlugin() ? 'prototype' : '') : '') . $entry->getCall(); + $result = preg_replace('/\(\[|\[\]/', '', $result); + $result = preg_replace('/[ =\'"{}.()\]]/', '', $result); + $result = preg_replace('/[[#,]/', '-', $result); + return strtolower($result); + } + + /** + * Resolves the entry's url for the specific line number. + * + * @private + * @memberOf Generator + * @param {Number|Object} $entry The entry object. + * @returns {String} The url. + */ + private function getLineUrl( $entry ) { + $entry = is_numeric($entry) ? $this->entries($entry) : $entry; + return $this->options['url'] . '#L' . $entry->getLineNumber(); + } + + /** + * Extracts the character used to separate the entry's name from its member. + * + * @private + * @memberOf Generator + * @param {Number|Object} $entry The entry object. + * @returns {String} The separator. + */ + private function getSeparator( $entry ) { + $entry = is_numeric($entry) ? $this->entries($entry) : $entry; + return $entry->isPlugin() ? '.prototype.' : '.'; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Generates Markdown from JSDoc entries. + * + * @memberOf Generator + * @returns {String} The rendered Markdown. + */ + public function generate() { + $api = array(); + $compiling = false; + $openTag = "\n\n"; + $closeTag = "\n\n"; + $result = array('# ' . $this->options['title']); + $toc = 'toc'; + + // initialize $api array + foreach ($this->entries as $entry) { + + if (!$entry->isPrivate()) { + $name = $entry->getName(); + $members = $entry->getMembers(); + $members = count($members) ? $members : array(''); + + foreach ($members as $member) { + // create api category arrays + if (!isset($api[$member]) && $member) { + $api[$member] = new Entry('', '', $entry->lang); + $api[$member]->static = array(); + $api[$member]->plugin = array(); + } + // append entry to api category + if (!$member || $entry->isCtor() || ($entry->getType() == 'Object' && + !preg_match('/[=:]\s*null\s*[,;]?$/', $entry->entry))) { + $member = ($member ? $member . ($entry->isPlugin() ? '#' : '.') : '') . $name; + $entry->static = @$api[$member] ? $api[$member]->static : array(); + $entry->plugin = @$api[$member] ? $api[$member]->plugin : array(); + $api[$member] = $entry; + } + else if ($entry->isStatic()) { + $api[$member]->static[] = $entry; + } else if (!$entry->isCtor()) { + $api[$member]->plugin[] = $entry; + } + } + } + } + + /*------------------------------------------------------------------------*/ + + // custom sort for root level entries + // TODO: see how well it handles deeper namespace traversal + function sortCompare($a, $b) { + $score = array( 'a' => 0, 'b' => 0); + foreach (array( 'a' => $a, 'b' => $b) as $key => $value) { + // capitalized keys that represent constructor properties are last + if (preg_match('/[#.][A-Z]/', $value)) { + $score[$key] = 0; + } + // lowercase keys with prototype properties are next to last + else if (preg_match('/#[a-z]/', $value)) { + $score[$key] = 1; + } + // lowercase keys with static properties next to first + else if (preg_match('/\.[a-z]/', $value)) { + $score[$key] = 2; + } + // lowercase keys with no properties are first + else if (preg_match('/^[^#.]+$/', $value)) { + $score[$key] = 3; + } + } + $score = $score['b'] - $score['a']; + return $score ? $score : strcasecmp($a, $b); + } + + uksort($api, 'sortCompare'); + + // sort static and plugin sub-entries + foreach ($api as $entry) { + foreach (array('static', 'plugin') as $kind) { + $sortBy = array( 'a' => array(), 'b' => array(), 'c' => array() ); + foreach ($entry->{$kind} as $subentry) { + $name = $subentry->getName(); + // functions w/o ALL-CAPs names are last + $sortBy['a'][] = $subentry->getType() == 'Function' && !preg_match('/^[A-Z_]+$/', $name); + // ALL-CAPs properties first + $sortBy['b'][] = preg_match('/^[A-Z_]+$/', $name); + // lowercase alphanumeric sort + $sortBy['c'][] = strtolower($name); + } + array_multisort($sortBy['a'], SORT_ASC, $sortBy['b'], SORT_DESC, $sortBy['c'], SORT_ASC, $entry->{$kind}); + } + } + + /*------------------------------------------------------------------------*/ + + // compile TOC + $result[] = $openTag; + + foreach ($api as $key => $entry) { + $entry->hash = $this->getHash($entry); + $entry->href = $this->getLineUrl($entry); + + $member = $entry->getMembers(0); + $member = ($member ? $member . ($entry->isPlugin() ? '.prototype.' : '.') : '') . $entry->getName(); + + $entry->member = preg_replace('/' . $entry->getName() . '$/', '', $member); + + $compiling = $compiling ? ($result[] = $closeTag) : true; + + // assign TOC hash + if (count($result) == 2) { + $toc = $member; + } + + // add root entry + array_push( + $result, + $openTag, '## ' . (count($result) == 2 ? '' : '') . '`' . $member . '`', + Generator::interpolate('* [`' . $member . '`](##{hash})', $entry) + ); + + // add static and plugin sub-entries + foreach (array('static', 'plugin') as $kind) { + if ($kind == 'plugin' && count($entry->plugin)) { + array_push( + $result, + $closeTag, + $openTag, + '## `' . $member . ($entry->isCtor() ? '.prototype`' : '`') + ); + } + foreach ($entry->{$kind} as $subentry) { + $subentry->hash = $this->getHash($subentry); + $subentry->href = $this->getLineUrl($subentry); + $subentry->member = $member; + $subentry->separator = $this->getSeparator($subentry); + $result[] = Generator::interpolate('* [`#{member}#{separator}#{name}`](##{hash})', $subentry); + } + } + } + + array_push($result, $closeTag, $closeTag); + + /*------------------------------------------------------------------------*/ + + // compile content + $compiling = false; + $result[] = $openTag; + + foreach ($api as $entry) { + // add root entry + $member = $entry->member . $entry->getName(); + $compiling = $compiling ? ($result[] = $closeTag) : true; + + array_push($result, $openTag, '## `' . $member . '`'); + + foreach (array($entry, 'static', 'plugin') as $kind) { + $subentries = is_string($kind) ? $entry->{$kind} : array($kind); + + // title + if ($kind != 'static' && $entry->getType() != 'Object' && + count($subentries) && $subentries[0] != $kind) { + if ($kind == 'plugin') { + $result[] = $closeTag; + } + array_push( + $result, + $openTag, + '## `' . $member . ($kind == 'plugin' ? '.prototype`' : '`') + ); + } + + // body + foreach ($subentries as $subentry) { + // description + array_push( + $result, + $openTag, + Generator::interpolate("### `#{member}#{separator}#{call}`\n# [Ⓢ](#{href} \"View in source\") [Ⓣ][1]\n\n#{desc}", $subentry) + ); + + // @param + if (count($params = $subentry->getParams())) { + array_push($result, '', '#### Arguments'); + foreach ($params as $index => $param) { + $result[] = Generator::interpolate('#{num}. `#{name}` (#{type}): #{desc}', array( + 'desc' => $param[2], + 'name' => $param[1], + 'num' => $index + 1, + 'type' => $param[0] + )); + } + } + // @returns + if (count($returns = $subentry->getReturns())) { + array_push( + $result, '', + '#### Returns', + Generator::interpolate('(#{type}): #{desc}', array('desc' => $returns[1], 'type' => $returns[0])) + ); + } + // @example + if ($example = $subentry->getExample()) { + array_push($result, '', '#### Example', $example); + } + array_push($result, "\n* * *", $closeTag); + } + } + } + + // close tags add TOC link reference + array_push($result, $closeTag, $closeTag, '', ' [1]: #' . $toc . ' "Jump back to the TOC."'); + + // cleanup whitespace + return trim(preg_replace('/ +\n/', "\n", join($result, "\n"))); + } +} +?> diff --git a/web/src/vendor/benchmark/vendor/platform.js/LICENSE.txt b/web/src/vendor/benchmark/vendor/platform.js/LICENSE.txt new file mode 100644 index 00000000..dadad22f --- /dev/null +++ b/web/src/vendor/benchmark/vendor/platform.js/LICENSE.txt @@ -0,0 +1,20 @@ +Copyright 2011-2012 John-David Dalton + +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. \ No newline at end of file diff --git a/web/src/vendor/benchmark/vendor/platform.js/README.md b/web/src/vendor/benchmark/vendor/platform.js/README.md new file mode 100644 index 00000000..b9133118 --- /dev/null +++ b/web/src/vendor/benchmark/vendor/platform.js/README.md @@ -0,0 +1,98 @@ +# Platform.js v1.0.0 + +A platform detection library that works on nearly all JavaScript platforms1. + +## Disclaimer + +Platform.js is for informational purposes only and **not** intended as a substitution for [feature detection/inference](http://allyoucanleet.com/post/18087210413/feature-testing-costs#screencast2) checks. + +## BestieJS + +Platform.js is part of the BestieJS *"Best in Class"* module collection. This means we promote solid browser/environment support, ES5 precedents, unit testing, and plenty of documentation. + +## Documentation + +The documentation for Platform.js can be viewed here: [/doc/README.md](https://github.com/bestiejs/platform.js/blob/master/doc/README.md#readme) + +For a list of upcoming features, check out our [roadmap](https://github.com/bestiejs/platform.js/wiki/Roadmap). + +## Support + +Platform.js has been tested in at least Adobe AIR 3.1, Chrome 5-21, Firefox 1.5-13, IE 6-9, Opera 9.25-12.01, Safari 3-6, Node.js 0.8.6, Narwhal 0.3.2, RingoJS 0.8, and Rhino 1.7RC5. + +## Installation and usage + +In a browser or Adobe AIR: + +```html + +``` + +Via [npm](http://npmjs.org/): + +```bash +npm install platform +``` + +In [Node.js](http://nodejs.org/) and [RingoJS](http://ringojs.org/): + +```js +var platform = require('platform'); +``` + +In [Rhino](http://www.mozilla.org/rhino/): + +```js +load('platform.js'); +``` + +In an AMD loader like [RequireJS](http://requirejs.org/): + +```js +require({ + 'paths': { + 'platform': 'path/to/platform' + } +}, +['platform'], function(platform) { + console.log(platform.name); +}); +``` + +Usage example: + +```js +// on IE10 x86 platform preview running in IE7 compatibility mode on Windows 7 64 bit edition +platform.name; // 'IE' +platform.version; // '10.0' +platform.layout; // 'Trident' +platform.os; // 'Windows Server 2008 R2 / 7 x64' +platform.description; // 'IE 10.0 x86 (platform preview; running in IE 7 mode) on Windows Server 2008 R2 / 7 x64' + +// or on an iPad +platform.name; // 'Safari' +platform.version; // '5.1' +platform.product; // 'iPad' +platform.manufacturer; // 'Apple' +platform.layout; // 'WebKit' +platform.os; // 'iOS 5.0' +platform.description; // 'Safari 5.1 on Apple iPad (iOS 5.0)' + +// or parsing a given UA string +var info = platform.parse('Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7.2; en; rv:2.0) Gecko/20100101 Firefox/4.0 Opera 11.52'); +info.name; // 'Opera' +info.version; // '11.52' +info.layout; // 'Presto' +info.os; // 'Mac OS X 10.7.2' +info.description; // 'Opera 11.52 (identifying as Firefox 4.0) on Mac OS X 10.7.2' +``` + +## Author + +* [John-David Dalton](http://allyoucanleet.com/) + [![twitter/jdalton](http://gravatar.com/avatar/299a3d891ff1920b69c364d061007043?s=70)](https://twitter.com/jdalton "Follow @jdalton on Twitter") + +## Contributors + +* [Mathias Bynens](http://mathiasbynens.be/) + [![twitter/mathias](http://gravatar.com/avatar/24e08a9ea84deb17ae121074d0f17125?s=70)](https://twitter.com/mathias "Follow @mathias on Twitter") diff --git a/web/src/vendor/benchmark/vendor/platform.js/platform.js b/web/src/vendor/benchmark/vendor/platform.js/platform.js new file mode 100644 index 00000000..a8a5482b --- /dev/null +++ b/web/src/vendor/benchmark/vendor/platform.js/platform.js @@ -0,0 +1,996 @@ +/*! + * Platform.js v1.0.0 + * Copyright 2010-2012 John-David Dalton + * Available under MIT license + */ +;(function(window) { + 'use strict'; + + /** Backup possible window/global object */ + var oldWin = window; + + /** Detect free variable `exports` */ + var freeExports = typeof exports == 'object' && exports; + + /** Detect free variable `global` */ + var freeGlobal = typeof global == 'object' && global && + (global == global.global ? (window = global) : global); + + /** Opera regexp */ + var reOpera = /Opera/; + + /** Used to resolve a value's internal [[Class]] */ + var toString = {}.toString; + + /** Detect Java environment */ + var java = /Java/.test(getClassOf(window.java)) && window.java; + + /** A character to represent alpha */ + var alpha = java ? 'a' : '\u03b1'; + + /** A character to represent beta */ + var beta = java ? 'b' : '\u03b2'; + + /** Browser document object */ + var doc = window.document || {}; + + /** Used to check for own properties of an object */ + var hasOwnProperty = {}.hasOwnProperty; + + /** Browser navigator object */ + var nav = window.navigator || {}; + + /** + * Detect Opera browser + * http://www.howtocreate.co.uk/operaStuff/operaObject.html + * http://dev.opera.com/articles/view/opera-mini-web-content-authoring-guidelines/#operamini + */ + var opera = window.operamini || window.opera; + + /** Opera [[Class]] */ + var operaClass = reOpera.test(operaClass = getClassOf(opera)) ? operaClass : (opera = null); + + /** Possible global object */ + var thisBinding = this; + + /** Browser user agent string */ + var userAgent = nav.userAgent || ''; + + /*--------------------------------------------------------------------------*/ + + /** + * Capitalizes a string value. + * + * @private + * @param {String} string The string to capitalize. + * @returns {String} The capitalized string. + */ + function capitalize(string) { + string = String(string); + return string.charAt(0).toUpperCase() + string.slice(1); + } + + /** + * An iteration utility for arrays and objects. + * + * @private + * @param {Array|Object} object The object to iterate over. + * @param {Function} callback The function called per iteration. + */ + function each(object, callback) { + var index = -1, + length = object.length; + + if (length == length >>> 0) { + while (++index < length) { + callback(object[index], index, object); + } + } else { + forOwn(object, callback); + } + } + + /** + * Trim and conditionally capitalize string values. + * + * @private + * @param {String} string The string to format. + * @returns {String} The formatted string. + */ + function format(string) { + string = trim(string); + return /^(?:webOS|i(?:OS|P))/.test(string) + ? string + : capitalize(string); + } + + /** + * Iterates over an object's own properties, executing the `callback` for each. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} callback The function executed per own property. + */ + function forOwn(object, callback) { + for (var key in object) { + hasKey(object, key) && callback(object[key], key, object); + } + } + + /** + * Gets the internal [[Class]] of a value. + * + * @private + * @param {Mixed} value The value. + * @returns {String} The [[Class]]. + */ + function getClassOf(value) { + return value == null + ? capitalize(value) + : toString.call(value).slice(8, -1); + } + + /** + * Checks if an object has the specified key as a direct property. + * + * @private + * @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 others (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 (getClassOf(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); + } + + /** + * 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); + } + + /** + * Prepares a string for use in a RegExp constructor by making hyphens and + * spaces optional. + * + * @private + * @param {String} string The string to qualify. + * @returns {String} The qualified string. + */ + function qualify(string) { + return String(string).replace(/([ -])(?!$)/g, '$1?'); + } + + /** + * A bare-bones` Array#reduce` like utility function. + * + * @private + * @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) { + var accumulator = null; + each(array, function(value, index) { + accumulator = callback(accumulator, value, index, array); + }); + return accumulator; + } + + /** + * Removes leading and trailing whitespace from a string. + * + * @private + * @param {String} string The string to trim. + * @returns {String} The trimmed string. + */ + function trim(string) { + return String(string).replace(/^ +| +$/g, ''); + } + + /*--------------------------------------------------------------------------*/ + + /** + * Creates a new platform object. + * + * @memberOf platform + * @param {String} [ua = navigator.userAgent] The user agent string. + * @returns {Object} A platform object. + */ + function parse(ua) { + + ua || (ua = userAgent); + + /** Temporary variable used over the script's lifetime */ + var data; + + /** The CPU architecture */ + var arch = ua; + + /** Platform description array */ + var description = []; + + /** Platform alpha/beta indicator */ + var prerelease = null; + + /** A flag to indicate that environment features should be used to resolve the platform */ + var useFeatures = ua == userAgent; + + /** The browser/environment version */ + var version = useFeatures && opera && typeof opera.version == 'function' && opera.version(); + + /* Detectable layout engines (order is important) */ + var layout = getLayout([ + { 'label': 'WebKit', 'pattern': 'AppleWebKit' }, + 'iCab', + 'Presto', + 'NetFront', + 'Tasman', + 'Trident', + 'KHTML', + 'Gecko' + ]); + + /* Detectable browser names (order is important) */ + var name = getName([ + 'Adobe AIR', + 'Arora', + 'Avant Browser', + 'Camino', + 'Epiphany', + 'Fennec', + 'Flock', + 'Galeon', + 'GreenBrowser', + 'iCab', + 'Iceweasel', + 'Iron', + 'K-Meleon', + 'Konqueror', + 'Lunascape', + 'Maxthon', + 'Midori', + 'Nook Browser', + 'PhantomJS', + 'Raven', + 'Rekonq', + 'RockMelt', + 'SeaMonkey', + { 'label': 'Silk', 'pattern': '(?:Cloud9|Silk-Accelerated)' }, + 'Sleipnir', + 'SlimBrowser', + 'Sunrise', + 'Swiftfox', + 'WebPositive', + 'Opera Mini', + 'Opera', + 'Chrome', + { 'label': 'Chrome Mobile', 'pattern': '(?:CriOS|CrMo)' }, + { 'label': 'Firefox', 'pattern': '(?:Firefox|Minefield)' }, + { 'label': 'IE', 'pattern': 'MSIE' }, + 'Safari' + ]); + + /* Detectable products (order is important) */ + var product = getProduct([ + 'BlackBerry', + { 'label': 'Galaxy S', 'pattern': 'GT-I9000' }, + { 'label': 'Galaxy S2', 'pattern': 'GT-I9100' }, + 'Google TV', + 'iPad', + 'iPod', + 'iPhone', + 'Kindle', + { 'label': 'Kindle Fire', 'pattern': '(?:Cloud9|Silk-Accelerated)' }, + 'Nook', + 'PlayBook', + 'PlayStation Vita', + 'TouchPad', + 'Transformer', + 'Xoom' + ]); + + /* Detectable manufacturers */ + var manufacturer = getManufacturer({ + 'Apple': { 'iPad': 1, 'iPhone': 1, 'iPod': 1 }, + 'Amazon': { 'Kindle': 1, 'Kindle Fire': 1 }, + 'Asus': { 'Transformer': 1 }, + 'Barnes & Noble': { 'Nook': 1 }, + 'BlackBerry': { 'PlayBook': 1 }, + 'Google': { 'Google TV': 1 }, + 'HP': { 'TouchPad': 1 }, + 'LG': { }, + 'Motorola': { 'Xoom': 1 }, + 'Nokia': { }, + 'Samsung': { 'Galaxy S': 1, 'Galaxy S2': 1 }, + 'Sony': { 'PlayStation Vita': 1 } + }); + + /* Detectable OSes (order is important) */ + var os = getOS([ + 'Android', + 'CentOS', + 'Debian', + 'Fedora', + 'FreeBSD', + 'Gentoo', + 'Haiku', + 'Kubuntu', + 'Linux Mint', + 'Red Hat', + 'SuSE', + 'Ubuntu', + 'Xubuntu', + 'Cygwin', + 'Symbian OS', + 'hpwOS', + 'webOS ', + 'webOS', + 'Tablet OS', + 'Linux', + 'Mac OS X', + 'Macintosh', + 'Mac', + 'Windows 98;', + 'Windows ' + ]); + + /*------------------------------------------------------------------------*/ + + /** + * Picks the layout engine from an array of guesses. + * + * @private + * @param {Array} guesses An array of guesses. + * @returns {String|Null} The detected layout engine. + */ + function getLayout(guesses) { + return reduce(guesses, function(result, guess) { + return result || RegExp('\\b' + ( + guess.pattern || qualify(guess) + ) + '\\b', 'i').exec(ua) && (guess.label || guess); + }); + } + + /** + * Picks the manufacturer from an array of guesses. + * + * @private + * @param {Array} guesses An array of guesses. + * @returns {String|Null} The detected manufacturer. + */ + function getManufacturer(guesses) { + return reduce(guesses, function(result, value, key) { + // lookup the manufacturer by product or scan the UA for the manufacturer + return result || ( + value[product] || + value[0/*Opera 9.25 fix*/, /^[a-z]+(?: +[a-z]+\b)*/i.exec(product)] || + RegExp('\\b' + (key.pattern || qualify(key)) + '(?:\\b|\\w*\\d)', 'i').exec(ua) + ) && (key.label || key); + }); + } + + /** + * Picks the browser name from an array of guesses. + * + * @private + * @param {Array} guesses An array of guesses. + * @returns {String|Null} The detected browser name. + */ + function getName(guesses) { + return reduce(guesses, function(result, guess) { + return result || RegExp('\\b' + ( + guess.pattern || qualify(guess) + ) + '\\b', 'i').exec(ua) && (guess.label || guess); + }); + } + + /** + * Picks the OS name from an array of guesses. + * + * @private + * @param {Array} guesses An array of guesses. + * @returns {String|Null} The detected OS name. + */ + function getOS(guesses) { + return reduce(guesses, function(result, guess) { + var pattern = guess.pattern || qualify(guess); + if (!result && (result = + RegExp('\\b' + pattern + '(?:/[\\d.]+|[ \\w.]*)', 'i').exec(ua))) { + // platform tokens defined at + // http://msdn.microsoft.com/en-us/library/ms537503(VS.85).aspx + // http://web.archive.org/web/20081122053950/http://msdn.microsoft.com/en-us/library/ms537503(VS.85).aspx + data = { + '6.2': '8', + '6.1': 'Server 2008 R2 / 7', + '6.0': 'Server 2008 / Vista', + '5.2': 'Server 2003 / XP 64-bit', + '5.1': 'XP', + '5.01': '2000 SP1', + '5.0': '2000', + '4.0': 'NT', + '4.90': 'ME' + }; + // detect Windows version from platform tokens + if (/^Win/i.test(result) && + (data = data[0/*Opera 9.25 fix*/, /[\d.]+$/.exec(result)])) { + result = 'Windows ' + data; + } + // correct character case and cleanup + result = format(String(result) + .replace(RegExp(pattern, 'i'), guess.label || guess) + .replace(/ ce$/i, ' CE') + .replace(/hpw/i, 'web') + .replace(/Macintosh/, 'Mac OS') + .replace(/_PowerPC/i, ' OS') + .replace(/(OS X) [^ \d]+/i, '$1') + .replace(/\/(\d)/, ' $1') + .replace(/_/g, '.') + .replace(/(?: BePC|[ .]*fc[ \d.]+)$/i, '') + .replace(/x86\.64/gi, 'x86_64') + .split(' on ')[0]); + } + return result; + }); + } + + /** + * Picks the product name from an array of guesses. + * + * @private + * @param {Array} guesses An array of guesses. + * @returns {String|Null} The detected product name. + */ + function getProduct(guesses) { + return reduce(guesses, function(result, guess) { + var pattern = guess.pattern || qualify(guess); + if (!result && (result = + RegExp('\\b' + pattern + ' *\\d+[.\\w_]*', 'i').exec(ua) || + RegExp('\\b' + pattern + '(?:; *(?:[a-z]+[_-])?[a-z]+\\d+|[^ ();-]*)', 'i').exec(ua) + )) { + // split by forward slash and append product version if needed + if ((result = String(guess.label || result).split('/'))[1] && !/[\d.]+/.test(result[0])) { + result[0] += ' ' + result[1]; + } + // correct character case and cleanup + guess = guess.label || guess; + result = format(result[0] + .replace(RegExp(pattern, 'i'), guess) + .replace(RegExp('; *(?:' + guess + '[_-])?', 'i'), ' ') + .replace(RegExp('(' + guess + ')(\\w)', 'i'), '$1 $2')); + } + return result; + }); + } + + /** + * Resolves the version using an array of UA patterns. + * + * @private + * @param {Array} patterns An array of UA patterns. + * @returns {String|Null} The detected version. + */ + function getVersion(patterns) { + return reduce(patterns, function(result, pattern) { + return result || (RegExp(pattern + + '(?:-[\\d.]+/|(?: for [\\w-]+)?[ /-])([\\d.]+[^ ();/_-]*)', 'i').exec(ua) || 0)[1] || null; + }); + } + + /*------------------------------------------------------------------------*/ + + /** + * Returns `platform.description` when the platform object is coerced to a string. + * + * @name toString + * @memberOf platform + * @returns {String} Returns `platform.description` if available, else an empty string. + */ + function toStringPlatform() { + return this.description || ''; + } + + /*------------------------------------------------------------------------*/ + + // convert layout to an array so we can add extra details + layout && (layout = [layout]); + + // detect product names that contain their manufacturer's name + if (manufacturer && !product) { + product = getProduct([manufacturer]); + } + // clean up Google TV + if ((data = /Google TV/.exec(product))) { + product = data[0]; + } + // detect simulators + if (/\bSimulator\b/i.test(ua)) { + product = (product ? product + ' ' : '') + 'Simulator'; + } + // detect iOS + if (/^iP/.test(product)) { + name || (name = 'Safari'); + os = 'iOS' + ((data = / OS ([\d_]+)/i.exec(ua)) + ? ' ' + data[1].replace(/_/g, '.') + : ''); + } + // detect Kubuntu + else if (name == 'Konqueror' && !/buntu/i.test(os)) { + os = 'Kubuntu'; + } + // detect Android browsers + else if (manufacturer && manufacturer != 'Google' && + /Chrome|Vita/.test(name + ';' + product)) { + name = 'Android Browser'; + os = /Android/.test(os) ? os : 'Android'; + } + // detect false positives for Firefox/Safari + else if (!name || (data = !/\bMinefield\b/i.test(ua) && /Firefox|Safari/.exec(name))) { + // escape the `/` for Firefox 1 + if (name && !product && /[\/,]|^[^(]+?\)/.test(ua.slice(ua.indexOf(data + '/') + 8))) { + // clear name of false positives + name = null; + } + // reassign a generic name + if ((data = product || manufacturer || os) && + (product || manufacturer || /Android|Symbian OS|Tablet OS|webOS/.test(os))) { + name = /[a-z]+(?: Hat)?/i.exec(/Android/.test(os) ? os : data) + ' Browser'; + } + } + // detect non-Opera versions (order is important) + if (!version) { + version = getVersion([ + '(?:Cloud9|CriOS|CrMo|Opera ?Mini|Raven|Silk(?!/[\\d.]+$))', + 'Version', + qualify(name), + '(?:Firefox|Minefield|NetFront)' + ]); + } + // detect stubborn layout engines + if (layout == 'iCab' && parseFloat(version) > 3) { + layout = ['WebKit']; + } else if (data = + /Opera/.test(name) && 'Presto' || + /\b(?:Midori|Nook|Safari)\b/i.test(ua) && 'WebKit' || + !layout && /\bMSIE\b/i.test(ua) && (/^Mac/.test(os) ? 'Tasman' : 'Trident')) { + layout = [data]; + } + // leverage environment features + if (useFeatures) { + // detect server-side environments + // Rhino has a global function while others have a global object + if (isHostType(window, 'global')) { + if (java) { + data = java.lang.System; + arch = data.getProperty('os.arch'); + os = os || data.getProperty('os.name') + ' ' + data.getProperty('os.version'); + } + if (typeof exports == 'object' && exports) { + // if `thisBinding` is the [ModuleScope] + if (thisBinding == oldWin && typeof system == 'object' && (data = [system])[0]) { + os || (os = data[0].os || null); + try { + data[1] = require('ringo/engine').version; + version = data[1].join('.'); + name = 'RingoJS'; + } catch(e) { + if (data[0].global == freeGlobal) { + name = 'Narwhal'; + } + } + } else if (typeof process == 'object' && (data = process)) { + name = 'Node.js'; + arch = data.arch; + os = data.platform; + version = /[\d.]+/.exec(data.version)[0]; + } + } else if (getClassOf(window.environment) == 'Environment') { + name = 'Rhino'; + } + } + // detect Adobe AIR + else if (getClassOf(data = window.runtime) == 'ScriptBridgingProxyObject') { + name = 'Adobe AIR'; + os = data.flash.system.Capabilities.os; + } + // detect PhantomJS + else if (getClassOf(data = window.phantom) == 'RuntimeObject') { + name = 'PhantomJS'; + version = (data = data.version || null) && (data.major + '.' + data.minor + '.' + data.patch); + } + // detect IE compatibility modes + else if (typeof doc.documentMode == 'number' && (data = /\bTrident\/(\d+)/i.exec(ua))) { + // we're in compatibility mode when the Trident version + 4 doesn't + // equal the document mode + version = [version, doc.documentMode]; + if ((data = +data[1] + 4) != version[1]) { + description.push('IE ' + version[1] + ' mode'); + layout[1] = ''; + version[1] = data; + } + version = name == 'IE' ? String(version[1].toFixed(1)) : version[0]; + } + os = os && format(os); + } + // detect prerelease phases + if (version && (data = + /(?:[ab]|dp|pre|[ab]\d+pre)(?:\d+\+?)?$/i.exec(version) || + /(?:alpha|beta)(?: ?\d)?/i.exec(ua + ';' + (useFeatures && nav.appMinorVersion)) || + /\bMinefield\b/i.test(ua) && 'a')) { + prerelease = /b/i.test(data) ? 'beta' : 'alpha'; + version = version.replace(RegExp(data + '\\+?$'), '') + + (prerelease == 'beta' ? beta : alpha) + (/\d+\+?/.exec(data) || ''); + } + // rename code name "Fennec" + if (name == 'Fennec') { + name = 'Firefox Mobile'; + } + // obscure Maxthon's unreliable version + else if (name == 'Maxthon' && version) { + version = version.replace(/\.[\d.]+/, '.x'); + } + // detect Silk desktop/accelerated modes + else if (name == 'Silk') { + if (!/Mobi/i.test(ua)) { + os = 'Android'; + description.unshift('desktop mode'); + } + if (/Accelerated *= *true/i.test(ua)) { + description.unshift('accelerated'); + } + } + // detect Windows Phone desktop mode + else if (name == 'IE' && (data = (/; *(?:XBLWP|ZuneWP)(\d+)/i.exec(ua) || 0)[1])) { + name += ' Mobile'; + os = 'Windows Phone OS ' + data + '.x'; + description.unshift('desktop mode'); + } + // add mobile postfix + else if ((name == 'IE' || name && !product && !/Browser|Mobi/.test(name)) && + (os == 'Windows CE' || /Mobi/i.test(ua))) { + name += ' Mobile'; + } + // detect IE platform preview + else if (name == 'IE' && useFeatures && typeof external == 'object' && !external) { + description.unshift('platform preview'); + } + // detect BlackBerry OS version + // http://docs.blackberry.com/en/developers/deliverables/18169/HTTP_headers_sent_by_BB_Browser_1234911_11.jsp + else if (/BlackBerry/.test(product) && (data = + (RegExp(product.replace(/ +/g, ' *') + '/([.\\d]+)', 'i').exec(ua) || 0)[1] || + version)) { + os = 'Device Software ' + data; + version = null; + } + // detect Opera identifying/masking itself as another browser + // http://www.opera.com/support/kb/view/843/ + else if (this != forOwn && ( + (useFeatures && opera) || + (/Opera/.test(name) && /\b(?:MSIE|Firefox)\b/i.test(ua)) || + (name == 'Firefox' && /OS X (?:\d+\.){2,}/.test(os)) || + (name == 'IE' && ( + (os && !/^Win/.test(os) && version > 5.5) || + /Windows XP/.test(os) && version > 8 || + version == 8 && !/Trident/.test(ua) + )) + ) && !reOpera.test(data = parse.call(forOwn, ua.replace(reOpera, '') + ';')) && data.name) { + + // when "indentifying", the UA contains both Opera and the other browser's name + data = 'ing as ' + data.name + ((data = data.version) ? ' ' + data : ''); + if (reOpera.test(name)) { + if (/IE/.test(data) && os == 'Mac OS') { + os = null; + } + data = 'identify' + data; + } + // when "masking", the UA contains only the other browser's name + else { + data = 'mask' + data; + if (operaClass) { + name = format(operaClass.replace(/([a-z])([A-Z])/g, '$1 $2')); + } else { + name = 'Opera'; + } + if (/IE/.test(data)) { + os = null; + } + if (!useFeatures) { + version = null; + } + } + layout = ['Presto']; + description.push(data); + } + // detect WebKit Nightly and approximate Chrome/Safari versions + if ((data = (/\bAppleWebKit\/([\d.]+\+?)/i.exec(ua) || 0)[1])) { + // correct build for numeric comparison + // (e.g. "532.5" becomes "532.05") + data = [parseFloat(data.replace(/\.(\d)$/, '.0$1')), data]; + // nightly builds are postfixed with a `+` + if (name == 'Safari' && data[1].slice(-1) == '+') { + name = 'WebKit Nightly'; + prerelease = 'alpha'; + version = data[1].slice(0, -1); + } + // clear incorrect browser versions + else if (version == data[1] || + version == (/\bSafari\/([\d.]+\+?)/i.exec(ua) || 0)[1]) { + version = null; + } + // use the full Chrome version when available + data = [data[0], (/\bChrome\/([\d.]+)/i.exec(ua) || 0)[1]]; + + // detect JavaScriptCore + // http://stackoverflow.com/questions/6768474/how-can-i-detect-which-javascript-engine-v8-or-jsc-is-used-at-runtime-in-androi + if (!useFeatures || (/internal|\n/i.test(toString.toString()) && !data[1])) { + layout[1] = 'like Safari'; + data = (data = data[0], data < 400 ? 1 : data < 500 ? 2 : data < 526 ? 3 : data < 533 ? 4 : data < 534 ? '4+' : data < 535 ? 5 : '5'); + } else { + layout[1] = 'like Chrome'; + data = data[1] || (data = data[0], data < 530 ? 1 : data < 532 ? 2 : data < 532.05 ? 3 : data < 533 ? 4 : data < 534.03 ? 5 : data < 534.07 ? 6 : data < 534.10 ? 7 : data < 534.13 ? 8 : data < 534.16 ? 9 : data < 534.24 ? 10 : data < 534.30 ? 11 : data < 535.01 ? 12 : data < 535.02 ? '13+' : data < 535.07 ? 15 : data < 535.11 ? 16 : data < 535.19 ? 17 : data < 536.05 ? 18 : data < 536.10 ? 19 : data < 537.01 ? 20 : '21'); + } + // add the postfix of ".x" or "+" for approximate versions + layout[1] += ' ' + (data += typeof data == 'number' ? '.x' : /[.+]/.test(data) ? '' : '+'); + // obscure version for some Safari 1-2 releases + if (name == 'Safari' && (!version || parseInt(version) > 45)) { + version = data; + } + } + // detect Opera desktop modes + if (name == 'Opera' && (data = /(?:zbov|zvav)$/.exec(os))) { + name += ' '; + description.unshift('desktop mode'); + if (data == 'zvav') { + name += 'Mini'; + version = null; + } else { + name += 'Mobile'; + } + } + // detect Chrome desktop mode + else if (name == 'Safari' && /Chrome/.exec(layout[1])) { + description.unshift('desktop mode'); + name = 'Chrome Mobile'; + version = null; + + if (/Mac OS X/.test(os)) { + manufacturer = 'Apple'; + os = 'iOS 4.3+'; + } else { + os = null; + } + } + // strip incorrect OS versions + if (version && version.indexOf(data = /[\d.]+$/.exec(os)) == 0 && + ua.indexOf('/' + data + '-') > -1) { + os = trim(os.replace(data, '')); + } + // add layout engine + if (layout && !/Avant|Nook/.test(name) && ( + /Browser|Lunascape|Maxthon/.test(name) || + /^(?:Adobe|Arora|Midori|Phantom|Rekonq|Rock|Sleipnir|Web)/.test(name) && layout[1])) { + // don't add layout details to description if they are falsey + (data = layout[layout.length - 1]) && description.push(data); + } + // combine contextual information + if (description.length) { + description = ['(' + description.join('; ') + ')']; + } + // append manufacturer + if (manufacturer && product && product.indexOf(manufacturer) < 0) { + description.push('on ' + manufacturer); + } + // append product + if (product) { + description.push((/^on /.test(description[description.length -1]) ? '' : 'on ') + product); + } + // parse OS into an object + if (os) { + data = / ([\d.+]+)$/.exec(os); + os = { + 'architecture': 32, + 'family': data ? os.replace(data[0], '') : os, + 'version': data ? data[1] : null, + 'toString': function() { + var version = this.version; + return this.family + (version ? ' ' + version : '') + (this.architecture == 64 ? ' 64-bit' : ''); + } + }; + } + // add browser/OS architecture + if ((data = / (?:AMD|IA|Win|WOW|x86_|x)64\b/i.exec(arch)) && !/\bi686\b/i.test(arch)) { + if (os) { + os.architecture = 64; + os.family = os.family.replace(data, ''); + } + if (name && (/WOW64/i.test(ua) || + (useFeatures && /\w(?:86|32)$/.test(nav.cpuClass || nav.platform)))) { + description.unshift('32-bit'); + } + } + + ua || (ua = null); + + /*------------------------------------------------------------------------*/ + + /** + * The platform object. + * + * @name platform + * @type Object + */ + return { + + /** + * The browser/environment version. + * + * @memberOf platform + * @type String|Null + */ + 'version': name && version && (description.unshift(version), version), + + /** + * The name of the browser/environment. + * + * @memberOf platform + * @type String|Null + */ + 'name': name && (description.unshift(name), name), + + /** + * The name of the operating system. + * + * @memberOf platform + * @type Object + */ + 'os': os + ? (name && + !(os == String(os).split(' ')[0] && (os == name.split(' ')[0] || product)) && + description.push(product ? '(' + os + ')' : 'on ' + os), os) + : { + + /** + * The CPU architecture the OS is built for. + * + * @memberOf platform.os + * @type String|Null + */ + 'architecture': null, + + /** + * The family of the OS. + * + * @memberOf platform.os + * @type String|Null + */ + 'family': null, + + /** + * The version of the OS. + * + * @memberOf platform.os + * @type String|Null + */ + 'version': null, + + /** + * Returns the OS string. + * + * @memberOf platform.os + * @returns {String} The OS string. + */ + 'toString': function() { return 'null'; } + }, + + /** + * The platform description. + * + * @memberOf platform + * @type String|Null + */ + 'description': description.length ? description.join(' ') : ua, + + /** + * The name of the browser layout engine. + * + * @memberOf platform + * @type String|Null + */ + 'layout': layout && layout[0], + + /** + * The name of the product's manufacturer. + * + * @memberOf platform + * @type String|Null + */ + 'manufacturer': manufacturer, + + /** + * The alpha/beta release indicator. + * + * @memberOf platform + * @type String|Null + */ + 'prerelease': prerelease, + + /** + * The name of the product hosting the browser. + * + * @memberOf platform + * @type String|Null + */ + 'product': product, + + /** + * The browser's user agent string. + * + * @memberOf platform + * @type String|Null + */ + 'ua': ua, + + // parses a user agent string into a platform object + 'parse': parse, + + // returns the platform description + 'toString': toStringPlatform + }; + } + + /*--------------------------------------------------------------------------*/ + + // expose platform + // 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 parse(); + }); + } + // check for `exports` after `define` in case a build optimizer adds an `exports` object + else if (freeExports) { + // in Narwhal, Node.js, or RingoJS + forOwn(parse(), function(value, key) { + freeExports[key] = value; + }); + } + // in a browser or Rhino + else { + // use square bracket notation so Closure Compiler won't munge `platform` + // http://code.google.com/closure/compiler/docs/api-tutorial3.html#export + window['platform'] = parse(); + } +}(this)); diff --git a/web/src/vendor/benchmark/vendor/qunit-clib/LICENSE.txt b/web/src/vendor/benchmark/vendor/qunit-clib/LICENSE.txt new file mode 100644 index 00000000..dadad22f --- /dev/null +++ b/web/src/vendor/benchmark/vendor/qunit-clib/LICENSE.txt @@ -0,0 +1,20 @@ +Copyright 2011-2012 John-David Dalton + +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. \ No newline at end of file diff --git a/web/src/vendor/benchmark/vendor/qunit-clib/README.md b/web/src/vendor/benchmark/vendor/qunit-clib/README.md new file mode 100644 index 00000000..b84a21c9 --- /dev/null +++ b/web/src/vendor/benchmark/vendor/qunit-clib/README.md @@ -0,0 +1,57 @@ +# QUnit CLIB v1.0.0 +## command-line interface boilerplate + +QUnit CLIB helps extend QUnit's CLI support to many common CLI environments. + +## Screenshot + +![QUnit CLIB brings QUnit to your favorite shell.](http://i.imgur.com/jpu9l.png) + +## Support + +QUnit CLIB has been tested in at least Node.js 0.4.8-0.8.6, Narwhal v0.3.2, RingoJS v0.8.0, and Rhino v1.7RC3-RC5. + +## Usage + +```js +(function(window) { + + // use a single load function + var load = typeof require == 'function' ? require : window.load; + + // load QUnit and CLIB if needed + var QUnit = + window.QUnit || ( + window.setTimeout || (window.addEventListener = window.setTimeout = / /), + window.QUnit = load('path/to/qunit.js') || window.QUnit, + load('path/to/qunit-clib.js'), + (window.addEventListener || 0).test && delete window.addEventListener, + window.QUnit + ); + + // explicitly call `QUnit.module()` instead of `module()` + // in case we are in a CLI environment + QUnit.module('A Test Module'); + + test('A Test', function() { + // ... + }); + + // must call `QUnit.start()` if using QUnit < 1.3.0 with Node.js or any + // version of QUnit with Narwhal, Rhino, or RingoJS + if (!window.document) { + QUnit.start(); + } +}(typeof global == 'object' && global || this)); +``` + +## Footnotes + + 1. QUnit v1.3.0 does not work with Narwhal or Ringo < v0.8.0 + + 2. Rhino v1.7RC4 does not support timeout fallbacks `clearTimeout` and `setTimeout` + +## Author + +* [John-David Dalton](http://allyoucanleet.com/) + [![twitter/jdalton](http://gravatar.com/avatar/299a3d891ff1920b69c364d061007043?s=70)](https://twitter.com/jdalton "Follow @jdalton on Twitter") diff --git a/web/src/vendor/benchmark/vendor/qunit-clib/qunit-clib.js b/web/src/vendor/benchmark/vendor/qunit-clib/qunit-clib.js new file mode 100644 index 00000000..e487c03e --- /dev/null +++ b/web/src/vendor/benchmark/vendor/qunit-clib/qunit-clib.js @@ -0,0 +1,319 @@ +/*! + * QUnit CLI Boilerplate v1.0.0 + * Copyright 2011-2012 John-David Dalton + * Based on a gist by Jörn Zaefferer + * Available under MIT license + */ +;(function(global) { + 'use strict'; + + /** Add `console.log()` support for Narwhal, Rhino, and RingoJS */ + global.console || (global.console = { 'log': global.print }); + + /** Reduce global.QUnit.QUnit -> global.QUnit */ + global.QUnit && (QUnit = QUnit.QUnit || QUnit); + + /*--------------------------------------------------------------------------*/ + + /** Used as a horizontal rule in console output */ + var hr = '----------------------------------------'; + + /** Shortcut used to convert array-like objects to arrays */ + var slice = [].slice; + + /** Used to resolve a value's internal [[Class]] */ + var toString = {}.toString; + + /** Used by timer methods */ + var doneCalled, + timer, + counter = 0, + ids = {}; + + /*--------------------------------------------------------------------------*/ + + /** + * An iteration utility for arrays. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} callback The function called per iteration. + */ + function each(array, callback) { + var index = -1, + length = array.length; + + while (++index < length) { + callback(array[index], index, array); + } + } + + /** + * Checks if the specified `value` is a function. + * + * @private + * @param {Mixed} value The value to check. + * @returns {Boolean} Returns `true` if `value` is a function, else `false`. + */ + function isFunction(value) { + return toString.call(value) == '[object Function]'; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Timeout fallbacks based on the work of Andrea Giammarchi and Weston C. + * https://github.com/WebReflection/wru/blob/master/src/rhinoTimers.js + * http://stackoverflow.com/questions/2261705/how-to-run-a-javascript-function-asynchronously-without-using-settimeout + */ + + /** + * Clears the delay set by `setInterval` or `setTimeout`. + * + * @memberOf global + * @param {Number} id The ID of the timeout to be cleared. + */ + function clearTimer(id) { + if (ids[id]) { + ids[id].cancel(); + timer.purge(); + delete ids[id]; + } + } + + /** + * Schedules timer-based callbacks. + * + * @private + * @param {Function} fn The function to call. + * @oaram {Number} delay The number of milliseconds to delay the `fn` call. + * @param [arg1, arg2, ...] Arguments to invoke `fn` with. + * @param {Boolean} repeated A flag to specify whether `fn` is called repeatedly. + * @returns {Number} The the ID of the timeout. + */ + function schedule(fn, delay, args, repeated) { + // Rhino 1.7RC4 will error assigning `task` below + // https://bugzilla.mozilla.org/show_bug.cgi?id=775566 + var task = ids[++counter] = new JavaAdapter(java.util.TimerTask, { + 'run': function() { + fn.apply(global, args); + } + }); + // support non-functions + if (!isFunction(fn)) { + fn = (function(code) { + code = String(code); + return function() { eval(code); }; + }(fn)); + } + // used by setInterval + if (repeated) { + timer.schedule(task, delay, delay); + } + // used by setTimeout + else { + timer.schedule(task, delay); + } + return counter; + } + + /** + * Executes a code snippet or function repeatedly, with a delay between each call. + * + * @memberOf global + * @param {Function|String} fn The function to call or string to evaluate. + * @oaram {Number} delay The number of milliseconds to delay each `fn` call. + * @param [arg1, arg2, ...] Arguments to invoke `fn` with. + * @returns {Number} The the ID of the timeout. + */ + function setInterval(fn, delay) { + return schedule(fn, delay, slice.call(arguments, 2), true); + } + + /** + * Executes a code snippet or a function after specified delay. + * + * @memberOf global + * @param {Function|String} fn The function to call or string to evaluate. + * @oaram {Number} delay The number of milliseconds to delay the `fn` call. + * @param [arg1, arg2, ...] Arguments to invoke `fn` with. + * @returns {Number} The the ID of the timeout. + */ + function setTimeout(fn, delay) { + return schedule(fn, delay, slice.call(arguments, 2)); + } + + /*--------------------------------------------------------------------------*/ + + /** + * A logging callback triggered when all testing is completed. + * + * @memberOf QUnit + * @param {Object} details An object with properties `failed`, `passed`, + * `runtime`, and `total`. + */ + function done(details) { + // stop `asyncTest()` from erroneously calling `done()` twice in + // environments w/o timeouts + if (doneCalled) { + return; + } + doneCalled = true; + console.log(hr); + console.log(' PASS: ' + details.passed + ' FAIL: ' + details.failed + ' TOTAL: ' + details.total); + console.log(' Finished in ' + details.runtime + ' milliseconds.'); + console.log(hr); + + // exit out of Rhino + try { + quit(); + } catch(e) { } + + // exit out of Node.js + try { + process.exit(); + } catch(e) { } + } + + /** + * A logging callback triggered after every assertion. + * + * @memberOf QUnit + * @param {Object} details An object with properties `actual`, `expected`, + * `message`, and `result`. + */ + function log(details) { + var expected = details.expected, + result = details.result, + type = typeof expected != 'undefined' ? 'EQ' : 'OK'; + + var assertion = [ + result ? 'PASS' : 'FAIL', + type, + details.message || 'ok' + ]; + + if (!result && type == 'EQ') { + assertion.push('Expected: ' + expected + ', Actual: ' + details.actual); + } + QUnit.config.testStats.assertions.push(assertion.join(' | ')); + } + + /** + * A logging callback triggered at the start of every test module. + * + * @memberOf QUnit + * @param {Object} details An object with property `name`. + */ + function moduleStart(details) { + console.log(hr); + console.log(details.name); + console.log(hr); + } + + /** + * Converts an object into a string representation. + * + * @memberOf QUnit + * @type Function + * @param {Object} object The object to stringify. + * @returns {String} The result string. + */ + var parseObject = (function() { + var func = QUnit.jsDump.parsers.object; + return function(object) { + // fork to support Rhino's error objects + if (typeof object.rhinoException == 'object') { + return object.name + + ' { message: "' + object.message + + '", fileName: "' + object.fileName + + '", lineNumber: ' + object.lineNumber + ' }'; + } + return func(object); + }; + }()); + + /** + * A logging callback triggered after a test is completed. + * + * @memberOf QUnit + * @param {Object} details An object with properties `failed`, `name`, + * `passed`, and `total`. + */ + function testDone(details) { + var assertions = QUnit.config.testStats.assertions, + testName = details.name; + + if (details.failed > 0) { + console.log(' FAIL - '+ testName); + each(assertions, function(value) { + console.log(' ' + value); + }); + } + else { + console.log(' PASS - ' + testName); + } + assertions.length = 0; + } + + /*--------------------------------------------------------------------------*/ + + /** + * An object used to hold information about the current running test. + * + * @memberOf QUnit.config + * @type Object + */ + QUnit.config.testStats = { + + /** + * An array of test summaries (pipe separated). + * + * @memberOf QUnit.config.testStats + * @type Array + */ + 'assertions': [] + }; + + // add shortcuts to the global + // exclude `module` because some environments have it as a built-in object + each(['asyncTest', 'deepEqual', 'equal', 'equals', 'expect', 'notDeepEqual', + 'notEqual', 'notStrictEqual', 'ok', 'raises', 'same', 'start', 'stop', + 'strictEqual', 'test', 'throws'], function(funcName) { + var func = QUnit[funcName]; + if (func) { + global[funcName] = func; + } + }); + + // expose timer methods to global + try { + timer = new java.util.Timer; + if (!isFunction(global.clearInterval)) { + global.clearInterval = clearTimer; + } + if (!isFunction(global.clearTimeout)) { + global.clearTimeout = clearTimer; + } + if (!isFunction(global.setInterval)) { + global.setInterval = setInterval; + } + if (!isFunction(global.setTimeout)) { + global.setTimeout = setTimeout; + } + } catch(e) { } + + // add callbacks + QUnit.done(done); + QUnit.log(log); + QUnit.moduleStart(moduleStart); + QUnit.testDone(testDone); + + // add wrapped function + QUnit.jsDump.parsers.object = parseObject; + + // must call `QUnit.start()` in the test file if using QUnit < 1.3.0 with + // Node.js or any version of QUnit with Narwhal, Rhino, or RingoJS + QUnit.init(); + +}(typeof global == 'object' && global || this)); diff --git a/web/src/vendor/benchmark/vendor/qunit/README.md b/web/src/vendor/benchmark/vendor/qunit/README.md new file mode 100644 index 00000000..3778a27b --- /dev/null +++ b/web/src/vendor/benchmark/vendor/qunit/README.md @@ -0,0 +1,49 @@ +[QUnit](http://docs.jquery.com/QUnit) - A JavaScript Unit Testing framework. +================================ + +QUnit is a powerful, easy-to-use, JavaScript test suite. It's used by the jQuery +project to test its code and plugins but is capable of testing any generic +JavaScript code (and even capable of testing JavaScript code on the server-side). + +QUnit is especially useful for regression testing: Whenever a bug is reported, +write a test that asserts the existence of that particular bug. Then fix it and +commit both. Every time you work on the code again, run the tests. If the bug +comes up again - a regression - you'll spot it immediately and know how to fix +it, because you know what code you just changed. + +Having good unit test coverage makes safe refactoring easy and cheap. You can +run the tests after each small refactoring step and always know what change +broke something. + +QUnit is similar to other unit testing frameworks like JUnit, but makes use of +the features JavaScript provides and helps with testing code in the browser, e.g. +with its stop/start facilities for testing asynchronous code. + +If you are interested in helping developing QUnit, you are in the right place. +For related discussions, visit the +[QUnit and Testing forum](http://forum.jquery.com/qunit-and-testing). + +Planning for a qunitjs.com site and other testing tools related work now happens +on the [jQuery Testing Team planning wiki](http://jquerytesting.pbworks.com/w/page/41556026/FrontPage). + +Development +----------- + +To submit patches, fork the repository, create a branch for the change. Then implement +the change, run `grunt` to lint and test it, then commit, push and create a pull request. + +Include some background for the change in the commit message and `Fixes #nnn`, referring +to the issue number you're addressing. + +To run `grunt`, you need `node` and `npm`, then `npm install grunt -g`. + +Releases +-------- + +Install git-extras and run `git changelog` to update History.md. +Update qunit/qunit.js|css and package.json to the release version, commit and +tag, update them again to the next version, commit and push commits and tags +(`git push --tags origin master`). + +Put the 'v' in front of the tag, e.g. `v1.8.0`. Clean up the changelog, removing merge commits +or whitespace cleanups. diff --git a/web/src/vendor/benchmark/vendor/qunit/qunit/qunit-1.8.0.js b/web/src/vendor/benchmark/vendor/qunit/qunit/qunit-1.8.0.js new file mode 100644 index 00000000..c1570c25 --- /dev/null +++ b/web/src/vendor/benchmark/vendor/qunit/qunit/qunit-1.8.0.js @@ -0,0 +1,1863 @@ +/** + * QUnit v1.8.0 - A JavaScript Unit Testing Framework + * + * http://docs.jquery.com/QUnit + * + * Copyright (c) 2012 John Resig, Jörn Zaefferer + * Dual licensed under the MIT (MIT-LICENSE.txt) + * or GPL (GPL-LICENSE.txt) licenses. + */ + +(function( window ) { + +var QUnit, + config, + onErrorFnPrev, + testId = 0, + fileName = (sourceFromStacktrace( 0 ) || "" ).replace(/(:\d+)+\)?/, "").replace(/.+\//, ""), + toString = Object.prototype.toString, + hasOwn = Object.prototype.hasOwnProperty, + defined = { + setTimeout: typeof window.setTimeout !== "undefined", + sessionStorage: (function() { + var x = "qunit-test-string"; + try { + sessionStorage.setItem( x, x ); + sessionStorage.removeItem( x ); + return true; + } catch( e ) { + return false; + } + }()) +}; + +function Test( settings ) { + extend( this, settings ); + this.assertions = []; + this.testNumber = ++Test.count; +} + +Test.count = 0; + +Test.prototype = { + init: function() { + var a, b, li, + tests = id( "qunit-tests" ); + + if ( tests ) { + b = document.createElement( "strong" ); + b.innerHTML = this.name; + + // `a` initialized at top of scope + a = document.createElement( "a" ); + a.innerHTML = "Rerun"; + a.href = QUnit.url({ testNumber: this.testNumber }); + + li = document.createElement( "li" ); + li.appendChild( b ); + li.appendChild( a ); + li.className = "running"; + li.id = this.id = "qunit-test-output" + testId++; + + tests.appendChild( li ); + } + }, + setup: function() { + if ( this.module !== config.previousModule ) { + if ( config.previousModule ) { + runLoggingCallbacks( "moduleDone", QUnit, { + name: config.previousModule, + failed: config.moduleStats.bad, + passed: config.moduleStats.all - config.moduleStats.bad, + total: config.moduleStats.all + }); + } + config.previousModule = this.module; + config.moduleStats = { all: 0, bad: 0 }; + runLoggingCallbacks( "moduleStart", QUnit, { + name: this.module + }); + } else if ( config.autorun ) { + runLoggingCallbacks( "moduleStart", QUnit, { + name: this.module + }); + } + + config.current = this; + + this.testEnvironment = extend({ + setup: function() {}, + teardown: function() {} + }, this.moduleTestEnvironment ); + + runLoggingCallbacks( "testStart", QUnit, { + name: this.testName, + module: this.module + }); + + // allow utility functions to access the current test environment + // TODO why?? + QUnit.current_testEnvironment = this.testEnvironment; + + if ( !config.pollution ) { + saveGlobal(); + } + if ( config.notrycatch ) { + this.testEnvironment.setup.call( this.testEnvironment ); + return; + } + try { + this.testEnvironment.setup.call( this.testEnvironment ); + } catch( e ) { + QUnit.pushFailure( "Setup failed on " + this.testName + ": " + e.message, extractStacktrace( e, 1 ) ); + } + }, + run: function() { + config.current = this; + + var running = id( "qunit-testresult" ); + + if ( running ) { + running.innerHTML = "Running:
    " + this.name; + } + + if ( this.async ) { + QUnit.stop(); + } + + if ( config.notrycatch ) { + this.callback.call( this.testEnvironment, QUnit.assert ); + return; + } + + try { + this.callback.call( this.testEnvironment, QUnit.assert ); + } catch( e ) { + QUnit.pushFailure( "Died on test #" + (this.assertions.length + 1) + " " + this.stack + ": " + e.message, extractStacktrace( e, 0 ) ); + // else next test will carry the responsibility + saveGlobal(); + + // Restart the tests if they're blocking + if ( config.blocking ) { + QUnit.start(); + } + } + }, + teardown: function() { + config.current = this; + if ( config.notrycatch ) { + this.testEnvironment.teardown.call( this.testEnvironment ); + return; + } else { + try { + this.testEnvironment.teardown.call( this.testEnvironment ); + } catch( e ) { + QUnit.pushFailure( "Teardown failed on " + this.testName + ": " + e.message, extractStacktrace( e, 1 ) ); + } + } + checkPollution(); + }, + finish: function() { + config.current = this; + if ( config.requireExpects && this.expected == null ) { + QUnit.pushFailure( "Expected number of assertions to be defined, but expect() was not called.", this.stack ); + } else if ( this.expected != null && this.expected != this.assertions.length ) { + QUnit.pushFailure( "Expected " + this.expected + " assertions, but " + this.assertions.length + " were run", this.stack ); + } else if ( this.expected == null && !this.assertions.length ) { + QUnit.pushFailure( "Expected at least one assertion, but none were run - call expect(0) to accept zero assertions.", this.stack ); + } + + var assertion, a, b, i, li, ol, + test = this, + good = 0, + bad = 0, + tests = id( "qunit-tests" ); + + config.stats.all += this.assertions.length; + config.moduleStats.all += this.assertions.length; + + if ( tests ) { + ol = document.createElement( "ol" ); + + for ( i = 0; i < this.assertions.length; i++ ) { + assertion = this.assertions[i]; + + li = document.createElement( "li" ); + li.className = assertion.result ? "pass" : "fail"; + li.innerHTML = assertion.message || ( assertion.result ? "okay" : "failed" ); + ol.appendChild( li ); + + if ( assertion.result ) { + good++; + } else { + bad++; + config.stats.bad++; + config.moduleStats.bad++; + } + } + + // store result when possible + if ( QUnit.config.reorder && defined.sessionStorage ) { + if ( bad ) { + sessionStorage.setItem( "qunit-test-" + this.module + "-" + this.testName, bad ); + } else { + sessionStorage.removeItem( "qunit-test-" + this.module + "-" + this.testName ); + } + } + + if ( bad === 0 ) { + ol.style.display = "none"; + } + + // `b` initialized at top of scope + b = document.createElement( "strong" ); + b.innerHTML = this.name + " (" + bad + ", " + good + ", " + this.assertions.length + ")"; + + addEvent(b, "click", function() { + var next = b.nextSibling.nextSibling, + display = next.style.display; + next.style.display = display === "none" ? "block" : "none"; + }); + + addEvent(b, "dblclick", function( e ) { + var target = e && e.target ? e.target : window.event.srcElement; + if ( target.nodeName.toLowerCase() == "span" || target.nodeName.toLowerCase() == "b" ) { + target = target.parentNode; + } + if ( window.location && target.nodeName.toLowerCase() === "strong" ) { + window.location = QUnit.url({ testNumber: test.testNumber }); + } + }); + + // `li` initialized at top of scope + li = id( this.id ); + li.className = bad ? "fail" : "pass"; + li.removeChild( li.firstChild ); + a = li.firstChild; + li.appendChild( b ); + li.appendChild ( a ); + li.appendChild( ol ); + + } else { + for ( i = 0; i < this.assertions.length; i++ ) { + if ( !this.assertions[i].result ) { + bad++; + config.stats.bad++; + config.moduleStats.bad++; + } + } + } + + runLoggingCallbacks( "testDone", QUnit, { + name: this.testName, + module: this.module, + failed: bad, + passed: this.assertions.length - bad, + total: this.assertions.length + }); + + QUnit.reset(); + + config.current = undefined; + }, + + queue: function() { + var bad, + test = this; + + synchronize(function() { + test.init(); + }); + function run() { + // each of these can by async + synchronize(function() { + test.setup(); + }); + synchronize(function() { + test.run(); + }); + synchronize(function() { + test.teardown(); + }); + synchronize(function() { + test.finish(); + }); + } + + // `bad` initialized at top of scope + // defer when previous test run passed, if storage is available + bad = QUnit.config.reorder && defined.sessionStorage && + +sessionStorage.getItem( "qunit-test-" + this.module + "-" + this.testName ); + + if ( bad ) { + run(); + } else { + synchronize( run, true ); + } + } +}; + +// Root QUnit object. +// `QUnit` initialized at top of scope +QUnit = { + + // call on start of module test to prepend name to all tests + module: function( name, testEnvironment ) { + config.currentModule = name; + config.currentModuleTestEnviroment = testEnvironment; + }, + + asyncTest: function( testName, expected, callback ) { + if ( arguments.length === 2 ) { + callback = expected; + expected = null; + } + + QUnit.test( testName, expected, callback, true ); + }, + + test: function( testName, expected, callback, async ) { + var test, + name = "" + escapeInnerText( testName ) + ""; + + if ( arguments.length === 2 ) { + callback = expected; + expected = null; + } + + if ( config.currentModule ) { + name = "" + config.currentModule + ": " + name; + } + + test = new Test({ + name: name, + testName: testName, + expected: expected, + async: async, + callback: callback, + module: config.currentModule, + moduleTestEnvironment: config.currentModuleTestEnviroment, + stack: sourceFromStacktrace( 2 ) + }); + + if ( !validTest( test ) ) { + return; + } + + test.queue(); + }, + + // Specify the number of expected assertions to gurantee that failed test (no assertions are run at all) don't slip through. + expect: function( asserts ) { + config.current.expected = asserts; + }, + + start: function( count ) { + config.semaphore -= count || 1; + // don't start until equal number of stop-calls + if ( config.semaphore > 0 ) { + return; + } + // ignore if start is called more often then stop + if ( config.semaphore < 0 ) { + config.semaphore = 0; + } + // A slight delay, to avoid any current callbacks + if ( defined.setTimeout ) { + window.setTimeout(function() { + if ( config.semaphore > 0 ) { + return; + } + if ( config.timeout ) { + clearTimeout( config.timeout ); + } + + config.blocking = false; + process( true ); + }, 13); + } else { + config.blocking = false; + process( true ); + } + }, + + stop: function( count ) { + config.semaphore += count || 1; + config.blocking = true; + + if ( config.testTimeout && defined.setTimeout ) { + clearTimeout( config.timeout ); + config.timeout = window.setTimeout(function() { + QUnit.ok( false, "Test timed out" ); + config.semaphore = 1; + QUnit.start(); + }, config.testTimeout ); + } + } +}; + +// Asssert helpers +// All of these must call either QUnit.push() or manually do: +// - runLoggingCallbacks( "log", .. ); +// - config.current.assertions.push({ .. }); +QUnit.assert = { + /** + * Asserts rough true-ish result. + * @example ok( "asdfasdf".length > 5, "There must be at least 5 chars" ); + */ + ok: function( result, msg ) { + if ( !config.current ) { + throw new Error( "ok() assertion outside test context, was " + sourceFromStacktrace(2) ); + } + result = !!result; + + var source, + details = { + result: result, + message: msg + }; + + msg = escapeInnerText( msg || (result ? "okay" : "failed" ) ); + msg = "" + msg + ""; + + if ( !result ) { + source = sourceFromStacktrace( 2 ); + if ( source ) { + details.source = source; + msg += "
    Source:
    " + escapeInnerText( source ) + "
    "; + } + } + runLoggingCallbacks( "log", QUnit, details ); + config.current.assertions.push({ + result: result, + message: msg + }); + }, + + /** + * Assert that the first two arguments are equal, with an optional message. + * Prints out both actual and expected values. + * @example equal( format( "Received {0} bytes.", 2), "Received 2 bytes.", "format() replaces {0} with next argument" ); + */ + equal: function( actual, expected, message ) { + QUnit.push( expected == actual, actual, expected, message ); + }, + + notEqual: function( actual, expected, message ) { + QUnit.push( expected != actual, actual, expected, message ); + }, + + deepEqual: function( actual, expected, message ) { + QUnit.push( QUnit.equiv(actual, expected), actual, expected, message ); + }, + + notDeepEqual: function( actual, expected, message ) { + QUnit.push( !QUnit.equiv(actual, expected), actual, expected, message ); + }, + + strictEqual: function( actual, expected, message ) { + QUnit.push( expected === actual, actual, expected, message ); + }, + + notStrictEqual: function( actual, expected, message ) { + QUnit.push( expected !== actual, actual, expected, message ); + }, + + raises: function( block, expected, message ) { + var actual, + ok = false; + + if ( typeof expected === "string" ) { + message = expected; + expected = null; + } + + config.current.ignoreGlobalErrors = true; + try { + block.call( config.current.testEnvironment ); + } catch (e) { + actual = e; + } + config.current.ignoreGlobalErrors = false; + + if ( actual ) { + // we don't want to validate thrown error + if ( !expected ) { + ok = true; + // expected is a regexp + } else if ( QUnit.objectType( expected ) === "regexp" ) { + ok = expected.test( actual ); + // expected is a constructor + } else if ( actual instanceof expected ) { + ok = true; + // expected is a validation function which returns true is validation passed + } else if ( expected.call( {}, actual ) === true ) { + ok = true; + } + } + + QUnit.push( ok, actual, null, message ); + } +}; + +// @deprecated: Kept assertion helpers in root for backwards compatibility +extend( QUnit, QUnit.assert ); + +/** + * @deprecated: Kept for backwards compatibility + * next step: remove entirely + */ +QUnit.equals = function() { + QUnit.push( false, false, false, "QUnit.equals has been deprecated since 2009 (e88049a0), use QUnit.equal instead" ); +}; +QUnit.same = function() { + QUnit.push( false, false, false, "QUnit.same has been deprecated since 2009 (e88049a0), use QUnit.deepEqual instead" ); +}; + +// We want access to the constructor's prototype +(function() { + function F() {} + F.prototype = QUnit; + QUnit = new F(); + // Make F QUnit's constructor so that we can add to the prototype later + QUnit.constructor = F; +}()); + +/** + * Config object: Maintain internal state + * Later exposed as QUnit.config + * `config` initialized at top of scope + */ +config = { + // The queue of tests to run + queue: [], + + // block until document ready + blocking: true, + + // when enabled, show only failing tests + // gets persisted through sessionStorage and can be changed in UI via checkbox + hidepassed: false, + + // by default, run previously failed tests first + // very useful in combination with "Hide passed tests" checked + reorder: true, + + // by default, modify document.title when suite is done + altertitle: true, + + // when enabled, all tests must call expect() + requireExpects: false, + + urlConfig: [ "noglobals", "notrycatch" ], + + // logging callback queues + begin: [], + done: [], + log: [], + testStart: [], + testDone: [], + moduleStart: [], + moduleDone: [] +}; + +// Initialize more QUnit.config and QUnit.urlParams +(function() { + var i, + location = window.location || { search: "", protocol: "file:" }, + params = location.search.slice( 1 ).split( "&" ), + length = params.length, + urlParams = {}, + current; + + if ( params[ 0 ] ) { + for ( i = 0; i < length; i++ ) { + current = params[ i ].split( "=" ); + current[ 0 ] = decodeURIComponent( current[ 0 ] ); + // allow just a key to turn on a flag, e.g., test.html?noglobals + current[ 1 ] = current[ 1 ] ? decodeURIComponent( current[ 1 ] ) : true; + urlParams[ current[ 0 ] ] = current[ 1 ]; + } + } + + QUnit.urlParams = urlParams; + + // String search anywhere in moduleName+testName + config.filter = urlParams.filter; + + // Exact match of the module name + config.module = urlParams.module; + + config.testNumber = parseInt( urlParams.testNumber, 10 ) || null; + + // Figure out if we're running the tests from a server or not + QUnit.isLocal = location.protocol === "file:"; +}()); + +// Export global variables, unless an 'exports' object exists, +// in that case we assume we're in CommonJS (dealt with on the bottom of the script) +if ( typeof exports === "undefined" ) { + extend( window, QUnit ); + + // Expose QUnit object + window.QUnit = QUnit; +} + +// Extend QUnit object, +// these after set here because they should not be exposed as global functions +extend( QUnit, { + config: config, + + // Initialize the configuration options + init: function() { + extend( config, { + stats: { all: 0, bad: 0 }, + moduleStats: { all: 0, bad: 0 }, + started: +new Date(), + updateRate: 1000, + blocking: false, + autostart: true, + autorun: false, + filter: "", + queue: [], + semaphore: 0 + }); + + var tests, banner, result, + qunit = id( "qunit" ); + + if ( qunit ) { + qunit.innerHTML = + "

    " + escapeInnerText( document.title ) + "

    " + + "

    " + + "
    " + + "

    " + + "
      "; + } + + tests = id( "qunit-tests" ); + banner = id( "qunit-banner" ); + result = id( "qunit-testresult" ); + + if ( tests ) { + tests.innerHTML = ""; + } + + if ( banner ) { + banner.className = ""; + } + + if ( result ) { + result.parentNode.removeChild( result ); + } + + if ( tests ) { + result = document.createElement( "p" ); + result.id = "qunit-testresult"; + result.className = "result"; + tests.parentNode.insertBefore( result, tests ); + result.innerHTML = "Running...
       "; + } + }, + + // Resets the test setup. Useful for tests that modify the DOM. + // If jQuery is available, uses jQuery's html(), otherwise just innerHTML. + reset: function() { + var fixture; + + if ( window.jQuery ) { + jQuery( "#qunit-fixture" ).html( config.fixture ); + } else { + fixture = id( "qunit-fixture" ); + if ( fixture ) { + fixture.innerHTML = config.fixture; + } + } + }, + + // Trigger an event on an element. + // @example triggerEvent( document.body, "click" ); + triggerEvent: function( elem, type, event ) { + if ( document.createEvent ) { + event = document.createEvent( "MouseEvents" ); + event.initMouseEvent(type, true, true, elem.ownerDocument.defaultView, + 0, 0, 0, 0, 0, false, false, false, false, 0, null); + + elem.dispatchEvent( event ); + } else if ( elem.fireEvent ) { + elem.fireEvent( "on" + type ); + } + }, + + // Safe object type checking + is: function( type, obj ) { + return QUnit.objectType( obj ) == type; + }, + + objectType: function( obj ) { + if ( typeof obj === "undefined" ) { + return "undefined"; + // consider: typeof null === object + } + if ( obj === null ) { + return "null"; + } + + var type = toString.call( obj ).match(/^\[object\s(.*)\]$/)[1] || ""; + + switch ( type ) { + case "Number": + if ( isNaN(obj) ) { + return "nan"; + } + return "number"; + case "String": + case "Boolean": + case "Array": + case "Date": + case "RegExp": + case "Function": + return type.toLowerCase(); + } + if ( typeof obj === "object" ) { + return "object"; + } + return undefined; + }, + + push: function( result, actual, expected, message ) { + if ( !config.current ) { + throw new Error( "assertion outside test context, was " + sourceFromStacktrace() ); + } + + var output, source, + details = { + result: result, + message: message, + actual: actual, + expected: expected + }; + + message = escapeInnerText( message ) || ( result ? "okay" : "failed" ); + message = "" + message + ""; + output = message; + + if ( !result ) { + expected = escapeInnerText( QUnit.jsDump.parse(expected) ); + actual = escapeInnerText( QUnit.jsDump.parse(actual) ); + output += ""; + + if ( actual != expected ) { + output += ""; + output += ""; + } + + source = sourceFromStacktrace(); + + if ( source ) { + details.source = source; + output += ""; + } + + output += "
      Expected:
      " + expected + "
      Result:
      " + actual + "
      Diff:
      " + QUnit.diff( expected, actual ) + "
      Source:
      " + escapeInnerText( source ) + "
      "; + } + + runLoggingCallbacks( "log", QUnit, details ); + + config.current.assertions.push({ + result: !!result, + message: output + }); + }, + + pushFailure: function( message, source ) { + if ( !config.current ) { + throw new Error( "pushFailure() assertion outside test context, was " + sourceFromStacktrace(2) ); + } + + var output, + details = { + result: false, + message: message + }; + + message = escapeInnerText(message ) || "error"; + message = "" + message + ""; + output = message; + + if ( source ) { + details.source = source; + output += "
      Source:
      " + escapeInnerText( source ) + "
      "; + } + + runLoggingCallbacks( "log", QUnit, details ); + + config.current.assertions.push({ + result: false, + message: output + }); + }, + + url: function( params ) { + params = extend( extend( {}, QUnit.urlParams ), params ); + var key, + querystring = "?"; + + for ( key in params ) { + if ( !hasOwn.call( params, key ) ) { + continue; + } + querystring += encodeURIComponent( key ) + "=" + + encodeURIComponent( params[ key ] ) + "&"; + } + return window.location.pathname + querystring.slice( 0, -1 ); + }, + + extend: extend, + id: id, + addEvent: addEvent + // load, equiv, jsDump, diff: Attached later +}); + +/** + * @deprecated: Created for backwards compatibility with test runner that set the hook function + * into QUnit.{hook}, instead of invoking it and passing the hook function. + * QUnit.constructor is set to the empty F() above so that we can add to it's prototype here. + * Doing this allows us to tell if the following methods have been overwritten on the actual + * QUnit object. + */ +extend( QUnit.constructor.prototype, { + + // Logging callbacks; all receive a single argument with the listed properties + // run test/logs.html for any related changes + begin: registerLoggingCallback( "begin" ), + + // done: { failed, passed, total, runtime } + done: registerLoggingCallback( "done" ), + + // log: { result, actual, expected, message } + log: registerLoggingCallback( "log" ), + + // testStart: { name } + testStart: registerLoggingCallback( "testStart" ), + + // testDone: { name, failed, passed, total } + testDone: registerLoggingCallback( "testDone" ), + + // moduleStart: { name } + moduleStart: registerLoggingCallback( "moduleStart" ), + + // moduleDone: { name, failed, passed, total } + moduleDone: registerLoggingCallback( "moduleDone" ) +}); + +if ( typeof document === "undefined" || document.readyState === "complete" ) { + config.autorun = true; +} + +QUnit.load = function() { + runLoggingCallbacks( "begin", QUnit, {} ); + + // Initialize the config, saving the execution queue + var banner, filter, i, label, len, main, ol, toolbar, userAgent, val, + urlConfigHtml = "", + oldconfig = extend( {}, config ); + + QUnit.init(); + extend(config, oldconfig); + + config.blocking = false; + + len = config.urlConfig.length; + + for ( i = 0; i < len; i++ ) { + val = config.urlConfig[i]; + config[val] = QUnit.urlParams[val]; + urlConfigHtml += ""; + } + + // `userAgent` initialized at top of scope + userAgent = id( "qunit-userAgent" ); + if ( userAgent ) { + userAgent.innerHTML = navigator.userAgent; + } + + // `banner` initialized at top of scope + banner = id( "qunit-header" ); + if ( banner ) { + banner.innerHTML = "" + banner.innerHTML + " " + urlConfigHtml; + addEvent( banner, "change", function( event ) { + var params = {}; + params[ event.target.name ] = event.target.checked ? true : undefined; + window.location = QUnit.url( params ); + }); + } + + // `toolbar` initialized at top of scope + toolbar = id( "qunit-testrunner-toolbar" ); + if ( toolbar ) { + // `filter` initialized at top of scope + filter = document.createElement( "input" ); + filter.type = "checkbox"; + filter.id = "qunit-filter-pass"; + + addEvent( filter, "click", function() { + var tmp, + ol = document.getElementById( "qunit-tests" ); + + if ( filter.checked ) { + ol.className = ol.className + " hidepass"; + } else { + tmp = " " + ol.className.replace( /[\n\t\r]/g, " " ) + " "; + ol.className = tmp.replace( / hidepass /, " " ); + } + if ( defined.sessionStorage ) { + if (filter.checked) { + sessionStorage.setItem( "qunit-filter-passed-tests", "true" ); + } else { + sessionStorage.removeItem( "qunit-filter-passed-tests" ); + } + } + }); + + if ( config.hidepassed || defined.sessionStorage && sessionStorage.getItem( "qunit-filter-passed-tests" ) ) { + filter.checked = true; + // `ol` initialized at top of scope + ol = document.getElementById( "qunit-tests" ); + ol.className = ol.className + " hidepass"; + } + toolbar.appendChild( filter ); + + // `label` initialized at top of scope + label = document.createElement( "label" ); + label.setAttribute( "for", "qunit-filter-pass" ); + label.innerHTML = "Hide passed tests"; + toolbar.appendChild( label ); + } + + // `main` initialized at top of scope + main = id( "qunit-fixture" ); + if ( main ) { + config.fixture = main.innerHTML; + } + + if ( config.autostart ) { + QUnit.start(); + } +}; + +addEvent( window, "load", QUnit.load ); + +// `onErrorFnPrev` initialized at top of scope +// Preserve other handlers +onErrorFnPrev = window.onerror; + +// Cover uncaught exceptions +// Returning true will surpress the default browser handler, +// returning false will let it run. +window.onerror = function ( error, filePath, linerNr ) { + var ret = false; + if ( onErrorFnPrev ) { + ret = onErrorFnPrev( error, filePath, linerNr ); + } + + // Treat return value as window.onerror itself does, + // Only do our handling if not surpressed. + if ( ret !== true ) { + if ( QUnit.config.current ) { + if ( QUnit.config.current.ignoreGlobalErrors ) { + return true; + } + QUnit.pushFailure( error, filePath + ":" + linerNr ); + } else { + QUnit.test( "global failure", function() { + QUnit.pushFailure( error, filePath + ":" + linerNr ); + }); + } + return false; + } + + return ret; +}; + +function done() { + config.autorun = true; + + // Log the last module results + if ( config.currentModule ) { + runLoggingCallbacks( "moduleDone", QUnit, { + name: config.currentModule, + failed: config.moduleStats.bad, + passed: config.moduleStats.all - config.moduleStats.bad, + total: config.moduleStats.all + }); + } + + var i, key, + banner = id( "qunit-banner" ), + tests = id( "qunit-tests" ), + runtime = +new Date() - config.started, + passed = config.stats.all - config.stats.bad, + html = [ + "Tests completed in ", + runtime, + " milliseconds.
      ", + "", + passed, + " tests of ", + config.stats.all, + " passed, ", + config.stats.bad, + " failed." + ].join( "" ); + + if ( banner ) { + banner.className = ( config.stats.bad ? "qunit-fail" : "qunit-pass" ); + } + + if ( tests ) { + id( "qunit-testresult" ).innerHTML = html; + } + + if ( config.altertitle && typeof document !== "undefined" && document.title ) { + // show ✖ for good, ✔ for bad suite result in title + // use escape sequences in case file gets loaded with non-utf-8-charset + document.title = [ + ( config.stats.bad ? "\u2716" : "\u2714" ), + document.title.replace( /^[\u2714\u2716] /i, "" ) + ].join( " " ); + } + + // clear own sessionStorage items if all tests passed + if ( config.reorder && defined.sessionStorage && config.stats.bad === 0 ) { + // `key` & `i` initialized at top of scope + for ( i = 0; i < sessionStorage.length; i++ ) { + key = sessionStorage.key( i++ ); + if ( key.indexOf( "qunit-test-" ) === 0 ) { + sessionStorage.removeItem( key ); + } + } + } + + runLoggingCallbacks( "done", QUnit, { + failed: config.stats.bad, + passed: passed, + total: config.stats.all, + runtime: runtime + }); +} + +/** @return Boolean: true if this test should be ran */ +function validTest( test ) { + var include, + filter = config.filter && config.filter.toLowerCase(), + module = config.module, + fullName = (test.module + ": " + test.testName).toLowerCase(); + + if ( config.testNumber ) { + return test.testNumber === config.testNumber; + } + + if ( module && test.module !== module ) { + return false; + } + + if ( !filter ) { + return true; + } + + include = filter.charAt( 0 ) !== "!"; + if ( !include ) { + filter = filter.slice( 1 ); + } + + // If the filter matches, we need to honour include + if ( fullName.indexOf( filter ) !== -1 ) { + return include; + } + + // Otherwise, do the opposite + return !include; +} + +// so far supports only Firefox, Chrome and Opera (buggy), Safari (for real exceptions) +// Later Safari and IE10 are supposed to support error.stack as well +// See also https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error/Stack +function extractStacktrace( e, offset ) { + offset = offset === undefined ? 3 : offset; + + var stack, include, i, regex; + + if ( e.stacktrace ) { + // Opera + return e.stacktrace.split( "\n" )[ offset + 3 ]; + } else if ( e.stack ) { + // Firefox, Chrome + stack = e.stack.split( "\n" ); + if (/^error$/i.test( stack[0] ) ) { + stack.shift(); + } + if ( fileName ) { + include = []; + for ( i = offset; i < stack.length; i++ ) { + if ( stack[ i ].indexOf( fileName ) != -1 ) { + break; + } + include.push( stack[ i ] ); + } + if ( include.length ) { + return include.join( "\n" ); + } + } + return stack[ offset ]; + } else if ( e.sourceURL ) { + // Safari, PhantomJS + // hopefully one day Safari provides actual stacktraces + // exclude useless self-reference for generated Error objects + if ( /qunit.js$/.test( e.sourceURL ) ) { + return; + } + // for actual exceptions, this is useful + return e.sourceURL + ":" + e.line; + } +} +function sourceFromStacktrace( offset ) { + try { + throw new Error(); + } catch ( e ) { + return extractStacktrace( e, offset ); + } +} + +function escapeInnerText( s ) { + if ( !s ) { + return ""; + } + s = s + ""; + return s.replace( /[\&<>]/g, function( s ) { + switch( s ) { + case "&": return "&"; + case "<": return "<"; + case ">": return ">"; + default: return s; + } + }); +} + +function synchronize( callback, last ) { + config.queue.push( callback ); + + if ( config.autorun && !config.blocking ) { + process( last ); + } +} + +function process( last ) { + function next() { + process( last ); + } + var start = new Date().getTime(); + config.depth = config.depth ? config.depth + 1 : 1; + + while ( config.queue.length && !config.blocking ) { + if ( !defined.setTimeout || config.updateRate <= 0 || ( ( new Date().getTime() - start ) < config.updateRate ) ) { + config.queue.shift()(); + } else { + window.setTimeout( next, 13 ); + break; + } + } + config.depth--; + if ( last && !config.blocking && !config.queue.length && config.depth === 0 ) { + done(); + } +} + +function saveGlobal() { + config.pollution = []; + + if ( config.noglobals ) { + for ( var key in window ) { + // in Opera sometimes DOM element ids show up here, ignore them + if ( !hasOwn.call( window, key ) || /^qunit-test-output/.test( key ) ) { + continue; + } + config.pollution.push( key ); + } + } +} + +function checkPollution( name ) { + var newGlobals, + deletedGlobals, + old = config.pollution; + + saveGlobal(); + + newGlobals = diff( config.pollution, old ); + if ( newGlobals.length > 0 ) { + QUnit.pushFailure( "Introduced global variable(s): " + newGlobals.join(", ") ); + } + + deletedGlobals = diff( old, config.pollution ); + if ( deletedGlobals.length > 0 ) { + QUnit.pushFailure( "Deleted global variable(s): " + deletedGlobals.join(", ") ); + } +} + +// returns a new Array with the elements that are in a but not in b +function diff( a, b ) { + var i, j, + result = a.slice(); + + for ( i = 0; i < result.length; i++ ) { + for ( j = 0; j < b.length; j++ ) { + if ( result[i] === b[j] ) { + result.splice( i, 1 ); + i--; + break; + } + } + } + return result; +} + +function extend( a, b ) { + for ( var prop in b ) { + if ( b[ prop ] === undefined ) { + delete a[ prop ]; + + // Avoid "Member not found" error in IE8 caused by setting window.constructor + } else if ( prop !== "constructor" || a !== window ) { + a[ prop ] = b[ prop ]; + } + } + + return a; +} + +function addEvent( elem, type, fn ) { + if ( elem.addEventListener ) { + elem.addEventListener( type, fn, false ); + } else if ( elem.attachEvent ) { + elem.attachEvent( "on" + type, fn ); + } else { + fn(); + } +} + +function id( name ) { + return !!( typeof document !== "undefined" && document && document.getElementById ) && + document.getElementById( name ); +} + +function registerLoggingCallback( key ) { + return function( callback ) { + config[key].push( callback ); + }; +} + +// Supports deprecated method of completely overwriting logging callbacks +function runLoggingCallbacks( key, scope, args ) { + //debugger; + var i, callbacks; + if ( QUnit.hasOwnProperty( key ) ) { + QUnit[ key ].call(scope, args ); + } else { + callbacks = config[ key ]; + for ( i = 0; i < callbacks.length; i++ ) { + callbacks[ i ].call( scope, args ); + } + } +} + +// Test for equality any JavaScript type. +// Author: Philippe Rathé +QUnit.equiv = (function() { + + // Call the o related callback with the given arguments. + function bindCallbacks( o, callbacks, args ) { + var prop = QUnit.objectType( o ); + if ( prop ) { + if ( QUnit.objectType( callbacks[ prop ] ) === "function" ) { + return callbacks[ prop ].apply( callbacks, args ); + } else { + return callbacks[ prop ]; // or undefined + } + } + } + + // the real equiv function + var innerEquiv, + // stack to decide between skip/abort functions + callers = [], + // stack to avoiding loops from circular referencing + parents = [], + + getProto = Object.getPrototypeOf || function ( obj ) { + return obj.__proto__; + }, + callbacks = (function () { + + // for string, boolean, number and null + function useStrictEquality( b, a ) { + if ( b instanceof a.constructor || a instanceof b.constructor ) { + // to catch short annotaion VS 'new' annotation of a + // declaration + // e.g. var i = 1; + // var j = new Number(1); + return a == b; + } else { + return a === b; + } + } + + return { + "string": useStrictEquality, + "boolean": useStrictEquality, + "number": useStrictEquality, + "null": useStrictEquality, + "undefined": useStrictEquality, + + "nan": function( b ) { + return isNaN( b ); + }, + + "date": function( b, a ) { + return QUnit.objectType( b ) === "date" && a.valueOf() === b.valueOf(); + }, + + "regexp": function( b, a ) { + return QUnit.objectType( b ) === "regexp" && + // the regex itself + a.source === b.source && + // and its modifers + a.global === b.global && + // (gmi) ... + a.ignoreCase === b.ignoreCase && + a.multiline === b.multiline; + }, + + // - skip when the property is a method of an instance (OOP) + // - abort otherwise, + // initial === would have catch identical references anyway + "function": function() { + var caller = callers[callers.length - 1]; + return caller !== Object && typeof caller !== "undefined"; + }, + + "array": function( b, a ) { + var i, j, len, loop; + + // b could be an object literal here + if ( QUnit.objectType( b ) !== "array" ) { + return false; + } + + len = a.length; + if ( len !== b.length ) { + // safe and faster + return false; + } + + // track reference to avoid circular references + parents.push( a ); + for ( i = 0; i < len; i++ ) { + loop = false; + for ( j = 0; j < parents.length; j++ ) { + if ( parents[j] === a[i] ) { + loop = true;// dont rewalk array + } + } + if ( !loop && !innerEquiv(a[i], b[i]) ) { + parents.pop(); + return false; + } + } + parents.pop(); + return true; + }, + + "object": function( b, a ) { + var i, j, loop, + // Default to true + eq = true, + aProperties = [], + bProperties = []; + + // comparing constructors is more strict than using + // instanceof + if ( a.constructor !== b.constructor ) { + // Allow objects with no prototype to be equivalent to + // objects with Object as their constructor. + if ( !(( getProto(a) === null && getProto(b) === Object.prototype ) || + ( getProto(b) === null && getProto(a) === Object.prototype ) ) ) { + return false; + } + } + + // stack constructor before traversing properties + callers.push( a.constructor ); + // track reference to avoid circular references + parents.push( a ); + + for ( i in a ) { // be strict: don't ensures hasOwnProperty + // and go deep + loop = false; + for ( j = 0; j < parents.length; j++ ) { + if ( parents[j] === a[i] ) { + // don't go down the same path twice + loop = true; + } + } + aProperties.push(i); // collect a's properties + + if (!loop && !innerEquiv( a[i], b[i] ) ) { + eq = false; + break; + } + } + + callers.pop(); // unstack, we are done + parents.pop(); + + for ( i in b ) { + bProperties.push( i ); // collect b's properties + } + + // Ensures identical properties name + return eq && innerEquiv( aProperties.sort(), bProperties.sort() ); + } + }; + }()); + + innerEquiv = function() { // can take multiple arguments + var args = [].slice.apply( arguments ); + if ( args.length < 2 ) { + return true; // end transition + } + + return (function( a, b ) { + if ( a === b ) { + return true; // catch the most you can + } else if ( a === null || b === null || typeof a === "undefined" || + typeof b === "undefined" || + QUnit.objectType(a) !== QUnit.objectType(b) ) { + return false; // don't lose time with error prone cases + } else { + return bindCallbacks(a, callbacks, [ b, a ]); + } + + // apply transition with (1..n) arguments + }( args[0], args[1] ) && arguments.callee.apply( this, args.splice(1, args.length - 1 )) ); + }; + + return innerEquiv; +}()); + +/** + * jsDump Copyright (c) 2008 Ariel Flesler - aflesler(at)gmail(dot)com | + * http://flesler.blogspot.com Licensed under BSD + * (http://www.opensource.org/licenses/bsd-license.php) Date: 5/15/2008 + * + * @projectDescription Advanced and extensible data dumping for Javascript. + * @version 1.0.0 + * @author Ariel Flesler + * @link {http://flesler.blogspot.com/2008/05/jsdump-pretty-dump-of-any-javascript.html} + */ +QUnit.jsDump = (function() { + function quote( str ) { + return '"' + str.toString().replace( /"/g, '\\"' ) + '"'; + } + function literal( o ) { + return o + ""; + } + function join( pre, arr, post ) { + var s = jsDump.separator(), + base = jsDump.indent(), + inner = jsDump.indent(1); + if ( arr.join ) { + arr = arr.join( "," + s + inner ); + } + if ( !arr ) { + return pre + post; + } + return [ pre, inner + arr, base + post ].join(s); + } + function array( arr, stack ) { + var i = arr.length, ret = new Array(i); + this.up(); + while ( i-- ) { + ret[i] = this.parse( arr[i] , undefined , stack); + } + this.down(); + return join( "[", ret, "]" ); + } + + var reName = /^function (\w+)/, + jsDump = { + parse: function( obj, type, stack ) { //type is used mostly internally, you can fix a (custom)type in advance + stack = stack || [ ]; + var inStack, res, + parser = this.parsers[ type || this.typeOf(obj) ]; + + type = typeof parser; + inStack = inArray( obj, stack ); + + if ( inStack != -1 ) { + return "recursion(" + (inStack - stack.length) + ")"; + } + //else + if ( type == "function" ) { + stack.push( obj ); + res = parser.call( this, obj, stack ); + stack.pop(); + return res; + } + // else + return ( type == "string" ) ? parser : this.parsers.error; + }, + typeOf: function( obj ) { + var type; + if ( obj === null ) { + type = "null"; + } else if ( typeof obj === "undefined" ) { + type = "undefined"; + } else if ( QUnit.is( "regexp", obj) ) { + type = "regexp"; + } else if ( QUnit.is( "date", obj) ) { + type = "date"; + } else if ( QUnit.is( "function", obj) ) { + type = "function"; + } else if ( typeof obj.setInterval !== undefined && typeof obj.document !== "undefined" && typeof obj.nodeType === "undefined" ) { + type = "window"; + } else if ( obj.nodeType === 9 ) { + type = "document"; + } else if ( obj.nodeType ) { + type = "node"; + } else if ( + // native arrays + toString.call( obj ) === "[object Array]" || + // NodeList objects + ( typeof obj.length === "number" && typeof obj.item !== "undefined" && ( obj.length ? obj.item(0) === obj[0] : ( obj.item( 0 ) === null && typeof obj[0] === "undefined" ) ) ) + ) { + type = "array"; + } else { + type = typeof obj; + } + return type; + }, + separator: function() { + return this.multiline ? this.HTML ? "
      " : "\n" : this.HTML ? " " : " "; + }, + indent: function( extra ) {// extra can be a number, shortcut for increasing-calling-decreasing + if ( !this.multiline ) { + return ""; + } + var chr = this.indentChar; + if ( this.HTML ) { + chr = chr.replace( /\t/g, " " ).replace( / /g, " " ); + } + return new Array( this._depth_ + (extra||0) ).join(chr); + }, + up: function( a ) { + this._depth_ += a || 1; + }, + down: function( a ) { + this._depth_ -= a || 1; + }, + setParser: function( name, parser ) { + this.parsers[name] = parser; + }, + // The next 3 are exposed so you can use them + quote: quote, + literal: literal, + join: join, + // + _depth_: 1, + // This is the list of parsers, to modify them, use jsDump.setParser + parsers: { + window: "[Window]", + document: "[Document]", + error: "[ERROR]", //when no parser is found, shouldn"t happen + unknown: "[Unknown]", + "null": "null", + "undefined": "undefined", + "function": function( fn ) { + var ret = "function", + name = "name" in fn ? fn.name : (reName.exec(fn) || [])[1];//functions never have name in IE + + if ( name ) { + ret += " " + name; + } + ret += "( "; + + ret = [ ret, QUnit.jsDump.parse( fn, "functionArgs" ), "){" ].join( "" ); + return join( ret, QUnit.jsDump.parse(fn,"functionCode" ), "}" ); + }, + array: array, + nodelist: array, + "arguments": array, + object: function( map, stack ) { + var ret = [ ], keys, key, val, i; + QUnit.jsDump.up(); + if ( Object.keys ) { + keys = Object.keys( map ); + } else { + keys = []; + for ( key in map ) { + keys.push( key ); + } + } + keys.sort(); + for ( i = 0; i < keys.length; i++ ) { + key = keys[ i ]; + val = map[ key ]; + ret.push( QUnit.jsDump.parse( key, "key" ) + ": " + QUnit.jsDump.parse( val, undefined, stack ) ); + } + QUnit.jsDump.down(); + return join( "{", ret, "}" ); + }, + node: function( node ) { + var a, val, + open = QUnit.jsDump.HTML ? "<" : "<", + close = QUnit.jsDump.HTML ? ">" : ">", + tag = node.nodeName.toLowerCase(), + ret = open + tag; + + for ( a in QUnit.jsDump.DOMAttrs ) { + val = node[ QUnit.jsDump.DOMAttrs[a] ]; + if ( val ) { + ret += " " + a + "=" + QUnit.jsDump.parse( val, "attribute" ); + } + } + return ret + close + open + "/" + tag + close; + }, + functionArgs: function( fn ) {//function calls it internally, it's the arguments part of the function + var args, + l = fn.length; + + if ( !l ) { + return ""; + } + + args = new Array(l); + while ( l-- ) { + args[l] = String.fromCharCode(97+l);//97 is 'a' + } + return " " + args.join( ", " ) + " "; + }, + key: quote, //object calls it internally, the key part of an item in a map + functionCode: "[code]", //function calls it internally, it's the content of the function + attribute: quote, //node calls it internally, it's an html attribute value + string: quote, + date: quote, + regexp: literal, //regex + number: literal, + "boolean": literal + }, + DOMAttrs: { + //attributes to dump from nodes, name=>realName + id: "id", + name: "name", + "class": "className" + }, + HTML: false,//if true, entities are escaped ( <, >, \t, space and \n ) + indentChar: " ",//indentation unit + multiline: true //if true, items in a collection, are separated by a \n, else just a space. + }; + + return jsDump; +}()); + +// from Sizzle.js +function getText( elems ) { + var i, elem, + ret = ""; + + for ( i = 0; elems[i]; i++ ) { + elem = elems[i]; + + // Get the text from text nodes and CDATA nodes + if ( elem.nodeType === 3 || elem.nodeType === 4 ) { + ret += elem.nodeValue; + + // Traverse everything else, except comment nodes + } else if ( elem.nodeType !== 8 ) { + ret += getText( elem.childNodes ); + } + } + + return ret; +} + +// from jquery.js +function inArray( elem, array ) { + if ( array.indexOf ) { + return array.indexOf( elem ); + } + + for ( var i = 0, length = array.length; i < length; i++ ) { + if ( array[ i ] === elem ) { + return i; + } + } + + return -1; +} + +/* + * Javascript Diff Algorithm + * By John Resig (http://ejohn.org/) + * Modified by Chu Alan "sprite" + * + * Released under the MIT license. + * + * More Info: + * http://ejohn.org/projects/javascript-diff-algorithm/ + * + * Usage: QUnit.diff(expected, actual) + * + * QUnit.diff( "the quick brown fox jumped over", "the quick fox jumps over" ) == "the quick brown fox jumped jumps over" + */ +QUnit.diff = (function() { + function diff( o, n ) { + var i, + ns = {}, + os = {}; + + for ( i = 0; i < n.length; i++ ) { + if ( ns[ n[i] ] == null ) { + ns[ n[i] ] = { + rows: [], + o: null + }; + } + ns[ n[i] ].rows.push( i ); + } + + for ( i = 0; i < o.length; i++ ) { + if ( os[ o[i] ] == null ) { + os[ o[i] ] = { + rows: [], + n: null + }; + } + os[ o[i] ].rows.push( i ); + } + + for ( i in ns ) { + if ( !hasOwn.call( ns, i ) ) { + continue; + } + if ( ns[i].rows.length == 1 && typeof os[i] != "undefined" && os[i].rows.length == 1 ) { + n[ ns[i].rows[0] ] = { + text: n[ ns[i].rows[0] ], + row: os[i].rows[0] + }; + o[ os[i].rows[0] ] = { + text: o[ os[i].rows[0] ], + row: ns[i].rows[0] + }; + } + } + + for ( i = 0; i < n.length - 1; i++ ) { + if ( n[i].text != null && n[ i + 1 ].text == null && n[i].row + 1 < o.length && o[ n[i].row + 1 ].text == null && + n[ i + 1 ] == o[ n[i].row + 1 ] ) { + + n[ i + 1 ] = { + text: n[ i + 1 ], + row: n[i].row + 1 + }; + o[ n[i].row + 1 ] = { + text: o[ n[i].row + 1 ], + row: i + 1 + }; + } + } + + for ( i = n.length - 1; i > 0; i-- ) { + if ( n[i].text != null && n[ i - 1 ].text == null && n[i].row > 0 && o[ n[i].row - 1 ].text == null && + n[ i - 1 ] == o[ n[i].row - 1 ]) { + + n[ i - 1 ] = { + text: n[ i - 1 ], + row: n[i].row - 1 + }; + o[ n[i].row - 1 ] = { + text: o[ n[i].row - 1 ], + row: i - 1 + }; + } + } + + return { + o: o, + n: n + }; + } + + return function( o, n ) { + o = o.replace( /\s+$/, "" ); + n = n.replace( /\s+$/, "" ); + + var i, pre, + str = "", + out = diff( o === "" ? [] : o.split(/\s+/), n === "" ? [] : n.split(/\s+/) ), + oSpace = o.match(/\s+/g), + nSpace = n.match(/\s+/g); + + if ( oSpace == null ) { + oSpace = [ " " ]; + } + else { + oSpace.push( " " ); + } + + if ( nSpace == null ) { + nSpace = [ " " ]; + } + else { + nSpace.push( " " ); + } + + if ( out.n.length === 0 ) { + for ( i = 0; i < out.o.length; i++ ) { + str += "" + out.o[i] + oSpace[i] + ""; + } + } + else { + if ( out.n[0].text == null ) { + for ( n = 0; n < out.o.length && out.o[n].text == null; n++ ) { + str += "" + out.o[n] + oSpace[n] + ""; + } + } + + for ( i = 0; i < out.n.length; i++ ) { + if (out.n[i].text == null) { + str += "" + out.n[i] + nSpace[i] + ""; + } + else { + // `pre` initialized at top of scope + pre = ""; + + for ( n = out.n[i].row + 1; n < out.o.length && out.o[n].text == null; n++ ) { + pre += "" + out.o[n] + oSpace[n] + ""; + } + str += " " + out.n[i].text + nSpace[i] + pre; + } + } + } + + return str; + }; +}()); + +// for CommonJS enviroments, export everything +if ( typeof exports !== "undefined" ) { + extend(exports, QUnit); +} + +// get at whatever the global object is, like window in browsers +}( (function() {return this;}.call()) )); diff --git a/web/src/vendor/benchmark/vendor/qunit/qunit/qunit.css b/web/src/vendor/benchmark/vendor/qunit/qunit/qunit.css new file mode 100644 index 00000000..257b224f --- /dev/null +++ b/web/src/vendor/benchmark/vendor/qunit/qunit/qunit.css @@ -0,0 +1,231 @@ +/** + * QUnit v1.9.0 - A JavaScript Unit Testing Framework + * + * http://docs.jquery.com/QUnit + * + * Copyright (c) 2012 John Resig, Jörn Zaefferer + * Dual licensed under the MIT (MIT-LICENSE.txt) + * or GPL (GPL-LICENSE.txt) licenses. + */ + +/** Font Family and Sizes */ + +#qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult { + font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif; +} + +#qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; } +#qunit-tests { font-size: smaller; } + + +/** Resets */ + +#qunit-tests, #qunit-tests ol, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult { + margin: 0; + padding: 0; +} + + +/** Header */ + +#qunit-header { + padding: 0.5em 0 0.5em 1em; + + color: #8699a4; + background-color: #0d3349; + + font-size: 1.5em; + line-height: 1em; + font-weight: normal; + + border-radius: 5px 5px 0 0; + -moz-border-radius: 5px 5px 0 0; + -webkit-border-top-right-radius: 5px; + -webkit-border-top-left-radius: 5px; +} + +#qunit-header a { + text-decoration: none; + color: #c2ccd1; +} + +#qunit-header a:hover, +#qunit-header a:focus { + color: #fff; +} + +#qunit-testrunner-toolbar label { + display: inline-block; + padding: 0 .5em 0 .1em; +} + +#qunit-banner { + height: 5px; +} + +#qunit-testrunner-toolbar { + padding: 0.5em 0 0.5em 2em; + color: #5E740B; + background-color: #eee; +} + +#qunit-userAgent { + padding: 0.5em 0 0.5em 2.5em; + background-color: #2b81af; + color: #fff; + text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px; +} + + +/** Tests: Pass/Fail */ + +#qunit-tests { + list-style-position: inside; +} + +#qunit-tests li { + padding: 0.4em 0.5em 0.4em 2.5em; + border-bottom: 1px solid #fff; + list-style-position: inside; +} + +#qunit-tests.hidepass li.pass, #qunit-tests.hidepass li.running { + display: none; +} + +#qunit-tests li strong { + cursor: pointer; +} + +#qunit-tests li a { + padding: 0.5em; + color: #c2ccd1; + text-decoration: none; +} +#qunit-tests li a:hover, +#qunit-tests li a:focus { + color: #000; +} + +#qunit-tests ol { + margin-top: 0.5em; + padding: 0.5em; + + background-color: #fff; + + border-radius: 5px; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; +} + +#qunit-tests table { + border-collapse: collapse; + margin-top: .2em; +} + +#qunit-tests th { + text-align: right; + vertical-align: top; + padding: 0 .5em 0 0; +} + +#qunit-tests td { + vertical-align: top; +} + +#qunit-tests pre { + margin: 0; + white-space: pre-wrap; + word-wrap: break-word; +} + +#qunit-tests del { + background-color: #e0f2be; + color: #374e0c; + text-decoration: none; +} + +#qunit-tests ins { + background-color: #ffcaca; + color: #500; + text-decoration: none; +} + +/*** Test Counts */ + +#qunit-tests b.counts { color: black; } +#qunit-tests b.passed { color: #5E740B; } +#qunit-tests b.failed { color: #710909; } + +#qunit-tests li li { + padding: 5px; + background-color: #fff; + border-bottom: none; + list-style-position: inside; +} + +/*** Passing Styles */ + +#qunit-tests li li.pass { + color: #3c510c; + background-color: #fff; + border-left: 10px solid #C6E746; +} + +#qunit-tests .pass { color: #528CE0; background-color: #D2E0E6; } +#qunit-tests .pass .test-name { color: #366097; } + +#qunit-tests .pass .test-actual, +#qunit-tests .pass .test-expected { color: #999999; } + +#qunit-banner.qunit-pass { background-color: #C6E746; } + +/*** Failing Styles */ + +#qunit-tests li li.fail { + color: #710909; + background-color: #fff; + border-left: 10px solid #EE5757; + white-space: pre; +} + +#qunit-tests > li:last-child { + border-radius: 0 0 5px 5px; + -moz-border-radius: 0 0 5px 5px; + -webkit-border-bottom-right-radius: 5px; + -webkit-border-bottom-left-radius: 5px; +} + +#qunit-tests .fail { color: #000000; background-color: #EE5757; } +#qunit-tests .fail .test-name, +#qunit-tests .fail .module-name { color: #000000; } + +#qunit-tests .fail .test-actual { color: #EE5757; } +#qunit-tests .fail .test-expected { color: green; } + +#qunit-banner.qunit-fail { background-color: #EE5757; } + + +/** Result */ + +#qunit-testresult { + padding: 0.5em 0.5em 0.5em 2.5em; + + color: #2b81af; + background-color: #D2E0E6; + + border-bottom: 1px solid white; +} +#qunit-testresult .module-name { + font-weight: bold; +} + +/** Fixture */ + +#qunit-fixture { + position: absolute; + top: -10000px; + left: -10000px; + width: 1000px; + height: 1000px; +} diff --git a/web/src/vendor/benchmark/vendor/qunit/qunit/qunit.js b/web/src/vendor/benchmark/vendor/qunit/qunit/qunit.js new file mode 100644 index 00000000..9efedcb4 --- /dev/null +++ b/web/src/vendor/benchmark/vendor/qunit/qunit/qunit.js @@ -0,0 +1,1932 @@ +/** + * QUnit v1.9.0 - A JavaScript Unit Testing Framework + * + * http://docs.jquery.com/QUnit + * + * Copyright (c) 2012 John Resig, Jörn Zaefferer + * Dual licensed under the MIT (MIT-LICENSE.txt) + * or GPL (GPL-LICENSE.txt) licenses. + */ + +(function( window ) { + +var QUnit, + config, + onErrorFnPrev, + testId = 0, + fileName = (sourceFromStacktrace( 0 ) || "" ).replace(/(:\d+)+\)?/, "").replace(/.+\//, ""), + toString = Object.prototype.toString, + hasOwn = Object.prototype.hasOwnProperty, + defined = { + setTimeout: typeof window.setTimeout !== "undefined", + sessionStorage: (function() { + var x = "qunit-test-string"; + try { + sessionStorage.setItem( x, x ); + sessionStorage.removeItem( x ); + return true; + } catch( e ) { + return false; + } + }()) +}; + +function Test( settings ) { + extend( this, settings ); + this.assertions = []; + this.testNumber = ++Test.count; +} + +Test.count = 0; + +Test.prototype = { + init: function() { + var a, b, li, + tests = id( "qunit-tests" ); + + if ( tests ) { + b = document.createElement( "strong" ); + b.innerHTML = this.name; + + // `a` initialized at top of scope + a = document.createElement( "a" ); + a.innerHTML = "Rerun"; + a.href = QUnit.url({ testNumber: this.testNumber }); + + li = document.createElement( "li" ); + li.appendChild( b ); + li.appendChild( a ); + li.className = "running"; + li.id = this.id = "qunit-test-output" + testId++; + + tests.appendChild( li ); + } + }, + setup: function() { + if ( this.module !== config.previousModule ) { + if ( config.previousModule ) { + runLoggingCallbacks( "moduleDone", QUnit, { + name: config.previousModule, + failed: config.moduleStats.bad, + passed: config.moduleStats.all - config.moduleStats.bad, + total: config.moduleStats.all + }); + } + config.previousModule = this.module; + config.moduleStats = { all: 0, bad: 0 }; + runLoggingCallbacks( "moduleStart", QUnit, { + name: this.module + }); + } else if ( config.autorun ) { + runLoggingCallbacks( "moduleStart", QUnit, { + name: this.module + }); + } + + config.current = this; + + this.testEnvironment = extend({ + setup: function() {}, + teardown: function() {} + }, this.moduleTestEnvironment ); + + runLoggingCallbacks( "testStart", QUnit, { + name: this.testName, + module: this.module + }); + + // allow utility functions to access the current test environment + // TODO why?? + QUnit.current_testEnvironment = this.testEnvironment; + + if ( !config.pollution ) { + saveGlobal(); + } + if ( config.notrycatch ) { + this.testEnvironment.setup.call( this.testEnvironment ); + return; + } + try { + this.testEnvironment.setup.call( this.testEnvironment ); + } catch( e ) { + QUnit.pushFailure( "Setup failed on " + this.testName + ": " + e.message, extractStacktrace( e, 1 ) ); + } + }, + run: function() { + config.current = this; + + var running = id( "qunit-testresult" ); + + if ( running ) { + running.innerHTML = "Running:
      " + this.name; + } + + if ( this.async ) { + QUnit.stop(); + } + + if ( config.notrycatch ) { + this.callback.call( this.testEnvironment, QUnit.assert ); + return; + } + + try { + this.callback.call( this.testEnvironment, QUnit.assert ); + } catch( e ) { + QUnit.pushFailure( "Died on test #" + (this.assertions.length + 1) + " " + this.stack + ": " + e.message, extractStacktrace( e, 0 ) ); + // else next test will carry the responsibility + saveGlobal(); + + // Restart the tests if they're blocking + if ( config.blocking ) { + QUnit.start(); + } + } + }, + teardown: function() { + config.current = this; + if ( config.notrycatch ) { + this.testEnvironment.teardown.call( this.testEnvironment ); + return; + } else { + try { + this.testEnvironment.teardown.call( this.testEnvironment ); + } catch( e ) { + QUnit.pushFailure( "Teardown failed on " + this.testName + ": " + e.message, extractStacktrace( e, 1 ) ); + } + } + checkPollution(); + }, + finish: function() { + config.current = this; + if ( config.requireExpects && this.expected == null ) { + QUnit.pushFailure( "Expected number of assertions to be defined, but expect() was not called.", this.stack ); + } else if ( this.expected != null && this.expected != this.assertions.length ) { + QUnit.pushFailure( "Expected " + this.expected + " assertions, but " + this.assertions.length + " were run", this.stack ); + } else if ( this.expected == null && !this.assertions.length ) { + QUnit.pushFailure( "Expected at least one assertion, but none were run - call expect(0) to accept zero assertions.", this.stack ); + } + + var assertion, a, b, i, li, ol, + test = this, + good = 0, + bad = 0, + tests = id( "qunit-tests" ); + + config.stats.all += this.assertions.length; + config.moduleStats.all += this.assertions.length; + + if ( tests ) { + ol = document.createElement( "ol" ); + + for ( i = 0; i < this.assertions.length; i++ ) { + assertion = this.assertions[i]; + + li = document.createElement( "li" ); + li.className = assertion.result ? "pass" : "fail"; + li.innerHTML = assertion.message || ( assertion.result ? "okay" : "failed" ); + ol.appendChild( li ); + + if ( assertion.result ) { + good++; + } else { + bad++; + config.stats.bad++; + config.moduleStats.bad++; + } + } + + // store result when possible + if ( QUnit.config.reorder && defined.sessionStorage ) { + if ( bad ) { + sessionStorage.setItem( "qunit-test-" + this.module + "-" + this.testName, bad ); + } else { + sessionStorage.removeItem( "qunit-test-" + this.module + "-" + this.testName ); + } + } + + if ( bad === 0 ) { + ol.style.display = "none"; + } + + // `b` initialized at top of scope + b = document.createElement( "strong" ); + b.innerHTML = this.name + " (" + bad + ", " + good + ", " + this.assertions.length + ")"; + + addEvent(b, "click", function() { + var next = b.nextSibling.nextSibling, + display = next.style.display; + next.style.display = display === "none" ? "block" : "none"; + }); + + addEvent(b, "dblclick", function( e ) { + var target = e && e.target ? e.target : window.event.srcElement; + if ( target.nodeName.toLowerCase() == "span" || target.nodeName.toLowerCase() == "b" ) { + target = target.parentNode; + } + if ( window.location && target.nodeName.toLowerCase() === "strong" ) { + window.location = QUnit.url({ testNumber: test.testNumber }); + } + }); + + // `li` initialized at top of scope + li = id( this.id ); + li.className = bad ? "fail" : "pass"; + li.removeChild( li.firstChild ); + a = li.firstChild; + li.appendChild( b ); + li.appendChild ( a ); + li.appendChild( ol ); + + } else { + for ( i = 0; i < this.assertions.length; i++ ) { + if ( !this.assertions[i].result ) { + bad++; + config.stats.bad++; + config.moduleStats.bad++; + } + } + } + + runLoggingCallbacks( "testDone", QUnit, { + name: this.testName, + module: this.module, + failed: bad, + passed: this.assertions.length - bad, + total: this.assertions.length + }); + + QUnit.reset(); + + config.current = undefined; + }, + + queue: function() { + var bad, + test = this; + + synchronize(function() { + test.init(); + }); + function run() { + // each of these can by async + synchronize(function() { + test.setup(); + }); + synchronize(function() { + test.run(); + }); + synchronize(function() { + test.teardown(); + }); + synchronize(function() { + test.finish(); + }); + } + + // `bad` initialized at top of scope + // defer when previous test run passed, if storage is available + bad = QUnit.config.reorder && defined.sessionStorage && + +sessionStorage.getItem( "qunit-test-" + this.module + "-" + this.testName ); + + if ( bad ) { + run(); + } else { + synchronize( run, true ); + } + } +}; + +// Root QUnit object. +// `QUnit` initialized at top of scope +QUnit = { + + // call on start of module test to prepend name to all tests + module: function( name, testEnvironment ) { + config.currentModule = name; + config.currentModuleTestEnviroment = testEnvironment; + }, + + asyncTest: function( testName, expected, callback ) { + if ( arguments.length === 2 ) { + callback = expected; + expected = null; + } + + QUnit.test( testName, expected, callback, true ); + }, + + test: function( testName, expected, callback, async ) { + var test, + name = "" + escapeInnerText( testName ) + ""; + + if ( arguments.length === 2 ) { + callback = expected; + expected = null; + } + + if ( config.currentModule ) { + name = "" + config.currentModule + ": " + name; + } + + test = new Test({ + name: name, + testName: testName, + expected: expected, + async: async, + callback: callback, + module: config.currentModule, + moduleTestEnvironment: config.currentModuleTestEnviroment, + stack: sourceFromStacktrace( 2 ) + }); + + if ( !validTest( test ) ) { + return; + } + + test.queue(); + }, + + // Specify the number of expected assertions to gurantee that failed test (no assertions are run at all) don't slip through. + expect: function( asserts ) { + config.current.expected = asserts; + }, + + start: function( count ) { + config.semaphore -= count || 1; + // don't start until equal number of stop-calls + if ( config.semaphore > 0 ) { + return; + } + // ignore if start is called more often then stop + if ( config.semaphore < 0 ) { + config.semaphore = 0; + } + // A slight delay, to avoid any current callbacks + if ( defined.setTimeout ) { + window.setTimeout(function() { + if ( config.semaphore > 0 ) { + return; + } + if ( config.timeout ) { + clearTimeout( config.timeout ); + } + + config.blocking = false; + process( true ); + }, 13); + } else { + config.blocking = false; + process( true ); + } + }, + + stop: function( count ) { + config.semaphore += count || 1; + config.blocking = true; + + if ( config.testTimeout && defined.setTimeout ) { + clearTimeout( config.timeout ); + config.timeout = window.setTimeout(function() { + QUnit.ok( false, "Test timed out" ); + config.semaphore = 1; + QUnit.start(); + }, config.testTimeout ); + } + } +}; + +// Asssert helpers +// All of these must call either QUnit.push() or manually do: +// - runLoggingCallbacks( "log", .. ); +// - config.current.assertions.push({ .. }); +QUnit.assert = { + /** + * Asserts rough true-ish result. + * @name ok + * @function + * @example ok( "asdfasdf".length > 5, "There must be at least 5 chars" ); + */ + ok: function( result, msg ) { + if ( !config.current ) { + throw new Error( "ok() assertion outside test context, was " + sourceFromStacktrace(2) ); + } + result = !!result; + + var source, + details = { + result: result, + message: msg + }; + + msg = escapeInnerText( msg || (result ? "okay" : "failed" ) ); + msg = "" + msg + ""; + + if ( !result ) { + source = sourceFromStacktrace( 2 ); + if ( source ) { + details.source = source; + msg += "
      Source:
      " + escapeInnerText( source ) + "
      "; + } + } + runLoggingCallbacks( "log", QUnit, details ); + config.current.assertions.push({ + result: result, + message: msg + }); + }, + + /** + * Assert that the first two arguments are equal, with an optional message. + * Prints out both actual and expected values. + * @name equal + * @function + * @example equal( format( "Received {0} bytes.", 2), "Received 2 bytes.", "format() replaces {0} with next argument" ); + */ + equal: function( actual, expected, message ) { + QUnit.push( expected == actual, actual, expected, message ); + }, + + /** + * @name notEqual + * @function + */ + notEqual: function( actual, expected, message ) { + QUnit.push( expected != actual, actual, expected, message ); + }, + + /** + * @name deepEqual + * @function + */ + deepEqual: function( actual, expected, message ) { + QUnit.push( QUnit.equiv(actual, expected), actual, expected, message ); + }, + + /** + * @name notDeepEqual + * @function + */ + notDeepEqual: function( actual, expected, message ) { + QUnit.push( !QUnit.equiv(actual, expected), actual, expected, message ); + }, + + /** + * @name strictEqual + * @function + */ + strictEqual: function( actual, expected, message ) { + QUnit.push( expected === actual, actual, expected, message ); + }, + + /** + * @name notStrictEqual + * @function + */ + notStrictEqual: function( actual, expected, message ) { + QUnit.push( expected !== actual, actual, expected, message ); + }, + + throws: function( block, expected, message ) { + var actual, + ok = false; + + // 'expected' is optional + if ( typeof expected === "string" ) { + message = expected; + expected = null; + } + + config.current.ignoreGlobalErrors = true; + try { + block.call( config.current.testEnvironment ); + } catch (e) { + actual = e; + } + config.current.ignoreGlobalErrors = false; + + if ( actual ) { + // we don't want to validate thrown error + if ( !expected ) { + ok = true; + // expected is a regexp + } else if ( QUnit.objectType( expected ) === "regexp" ) { + ok = expected.test( actual ); + // expected is a constructor + } else if ( actual instanceof expected ) { + ok = true; + // expected is a validation function which returns true is validation passed + } else if ( expected.call( {}, actual ) === true ) { + ok = true; + } + + QUnit.push( ok, actual, null, message ); + } else { + QUnit.pushFailure( message, null, 'No exception was thrown.' ); + } + } +}; + +/** + * @deprecate since 1.8.0 + * Kept assertion helpers in root for backwards compatibility + */ +extend( QUnit, QUnit.assert ); + +/** + * @deprecated since 1.9.0 + * Kept global "raises()" for backwards compatibility + */ +QUnit.raises = QUnit.assert.throws; + +/** + * @deprecated since 1.0.0, replaced with error pushes since 1.3.0 + * Kept to avoid TypeErrors for undefined methods. + */ +QUnit.equals = function() { + QUnit.push( false, false, false, "QUnit.equals has been deprecated since 2009 (e88049a0), use QUnit.equal instead" ); +}; +QUnit.same = function() { + QUnit.push( false, false, false, "QUnit.same has been deprecated since 2009 (e88049a0), use QUnit.deepEqual instead" ); +}; + +// We want access to the constructor's prototype +(function() { + function F() {} + F.prototype = QUnit; + QUnit = new F(); + // Make F QUnit's constructor so that we can add to the prototype later + QUnit.constructor = F; +}()); + +/** + * Config object: Maintain internal state + * Later exposed as QUnit.config + * `config` initialized at top of scope + */ +config = { + // The queue of tests to run + queue: [], + + // block until document ready + blocking: true, + + // when enabled, show only failing tests + // gets persisted through sessionStorage and can be changed in UI via checkbox + hidepassed: false, + + // by default, run previously failed tests first + // very useful in combination with "Hide passed tests" checked + reorder: true, + + // by default, modify document.title when suite is done + altertitle: true, + + // when enabled, all tests must call expect() + requireExpects: false, + + // add checkboxes that are persisted in the query-string + // when enabled, the id is set to `true` as a `QUnit.config` property + urlConfig: [ + { + id: "noglobals", + label: "Check for Globals", + tooltip: "Enabling this will test if any test introduces new properties on the `window` object. Stored as query-strings." + }, + { + id: "notrycatch", + label: "No try-catch", + tooltip: "Enabling this will run tests outside of a try-catch block. Makes debugging exceptions in IE reasonable. Stored as query-strings." + } + ], + + // logging callback queues + begin: [], + done: [], + log: [], + testStart: [], + testDone: [], + moduleStart: [], + moduleDone: [] +}; + +// Initialize more QUnit.config and QUnit.urlParams +(function() { + var i, + location = window.location || { search: "", protocol: "file:" }, + params = location.search.slice( 1 ).split( "&" ), + length = params.length, + urlParams = {}, + current; + + if ( params[ 0 ] ) { + for ( i = 0; i < length; i++ ) { + current = params[ i ].split( "=" ); + current[ 0 ] = decodeURIComponent( current[ 0 ] ); + // allow just a key to turn on a flag, e.g., test.html?noglobals + current[ 1 ] = current[ 1 ] ? decodeURIComponent( current[ 1 ] ) : true; + urlParams[ current[ 0 ] ] = current[ 1 ]; + } + } + + QUnit.urlParams = urlParams; + + // String search anywhere in moduleName+testName + config.filter = urlParams.filter; + + // Exact match of the module name + config.module = urlParams.module; + + config.testNumber = parseInt( urlParams.testNumber, 10 ) || null; + + // Figure out if we're running the tests from a server or not + QUnit.isLocal = location.protocol === "file:"; +}()); + +// Export global variables, unless an 'exports' object exists, +// in that case we assume we're in CommonJS (dealt with on the bottom of the script) +if ( typeof exports === "undefined" ) { + extend( window, QUnit ); + + // Expose QUnit object + window.QUnit = QUnit; +} + +// Extend QUnit object, +// these after set here because they should not be exposed as global functions +extend( QUnit, { + config: config, + + // Initialize the configuration options + init: function() { + extend( config, { + stats: { all: 0, bad: 0 }, + moduleStats: { all: 0, bad: 0 }, + started: +new Date(), + updateRate: 1000, + blocking: false, + autostart: true, + autorun: false, + filter: "", + queue: [], + semaphore: 0 + }); + + var tests, banner, result, + qunit = id( "qunit" ); + + if ( qunit ) { + qunit.innerHTML = + "

      " + escapeInnerText( document.title ) + "

      " + + "

      " + + "
      " + + "

      " + + "
        "; + } + + tests = id( "qunit-tests" ); + banner = id( "qunit-banner" ); + result = id( "qunit-testresult" ); + + if ( tests ) { + tests.innerHTML = ""; + } + + if ( banner ) { + banner.className = ""; + } + + if ( result ) { + result.parentNode.removeChild( result ); + } + + if ( tests ) { + result = document.createElement( "p" ); + result.id = "qunit-testresult"; + result.className = "result"; + tests.parentNode.insertBefore( result, tests ); + result.innerHTML = "Running...
         "; + } + }, + + // Resets the test setup. Useful for tests that modify the DOM. + // If jQuery is available, uses jQuery's html(), otherwise just innerHTML. + reset: function() { + var fixture; + + if ( window.jQuery ) { + jQuery( "#qunit-fixture" ).html( config.fixture ); + } else { + fixture = id( "qunit-fixture" ); + if ( fixture ) { + fixture.innerHTML = config.fixture; + } + } + }, + + // Trigger an event on an element. + // @example triggerEvent( document.body, "click" ); + triggerEvent: function( elem, type, event ) { + if ( document.createEvent ) { + event = document.createEvent( "MouseEvents" ); + event.initMouseEvent(type, true, true, elem.ownerDocument.defaultView, + 0, 0, 0, 0, 0, false, false, false, false, 0, null); + + elem.dispatchEvent( event ); + } else if ( elem.fireEvent ) { + elem.fireEvent( "on" + type ); + } + }, + + // Safe object type checking + is: function( type, obj ) { + return QUnit.objectType( obj ) == type; + }, + + objectType: function( obj ) { + if ( typeof obj === "undefined" ) { + return "undefined"; + // consider: typeof null === object + } + if ( obj === null ) { + return "null"; + } + + var type = toString.call( obj ).match(/^\[object\s(.*)\]$/)[1] || ""; + + switch ( type ) { + case "Number": + if ( isNaN(obj) ) { + return "nan"; + } + return "number"; + case "String": + case "Boolean": + case "Array": + case "Date": + case "RegExp": + case "Function": + return type.toLowerCase(); + } + if ( typeof obj === "object" ) { + return "object"; + } + return undefined; + }, + + push: function( result, actual, expected, message ) { + if ( !config.current ) { + throw new Error( "assertion outside test context, was " + sourceFromStacktrace() ); + } + + var output, source, + details = { + result: result, + message: message, + actual: actual, + expected: expected + }; + + message = escapeInnerText( message ) || ( result ? "okay" : "failed" ); + message = "" + message + ""; + output = message; + + if ( !result ) { + expected = escapeInnerText( QUnit.jsDump.parse(expected) ); + actual = escapeInnerText( QUnit.jsDump.parse(actual) ); + output += ""; + + if ( actual != expected ) { + output += ""; + output += ""; + } + + source = sourceFromStacktrace(); + + if ( source ) { + details.source = source; + output += ""; + } + + output += "
        Expected:
        " + expected + "
        Result:
        " + actual + "
        Diff:
        " + QUnit.diff( expected, actual ) + "
        Source:
        " + escapeInnerText( source ) + "
        "; + } + + runLoggingCallbacks( "log", QUnit, details ); + + config.current.assertions.push({ + result: !!result, + message: output + }); + }, + + pushFailure: function( message, source, actual ) { + if ( !config.current ) { + throw new Error( "pushFailure() assertion outside test context, was " + sourceFromStacktrace(2) ); + } + + var output, + details = { + result: false, + message: message + }; + + message = escapeInnerText( message ) || "error"; + message = "" + message + ""; + output = message; + + output += ""; + + if ( actual ) { + output += ""; + } + + if ( source ) { + details.source = source; + output += ""; + } + + output += "
        Result:
        " + escapeInnerText( actual ) + "
        Source:
        " + escapeInnerText( source ) + "
        "; + + runLoggingCallbacks( "log", QUnit, details ); + + config.current.assertions.push({ + result: false, + message: output + }); + }, + + url: function( params ) { + params = extend( extend( {}, QUnit.urlParams ), params ); + var key, + querystring = "?"; + + for ( key in params ) { + if ( !hasOwn.call( params, key ) ) { + continue; + } + querystring += encodeURIComponent( key ) + "=" + + encodeURIComponent( params[ key ] ) + "&"; + } + return window.location.pathname + querystring.slice( 0, -1 ); + }, + + extend: extend, + id: id, + addEvent: addEvent + // load, equiv, jsDump, diff: Attached later +}); + +/** + * @deprecated: Created for backwards compatibility with test runner that set the hook function + * into QUnit.{hook}, instead of invoking it and passing the hook function. + * QUnit.constructor is set to the empty F() above so that we can add to it's prototype here. + * Doing this allows us to tell if the following methods have been overwritten on the actual + * QUnit object. + */ +extend( QUnit.constructor.prototype, { + + // Logging callbacks; all receive a single argument with the listed properties + // run test/logs.html for any related changes + begin: registerLoggingCallback( "begin" ), + + // done: { failed, passed, total, runtime } + done: registerLoggingCallback( "done" ), + + // log: { result, actual, expected, message } + log: registerLoggingCallback( "log" ), + + // testStart: { name } + testStart: registerLoggingCallback( "testStart" ), + + // testDone: { name, failed, passed, total } + testDone: registerLoggingCallback( "testDone" ), + + // moduleStart: { name } + moduleStart: registerLoggingCallback( "moduleStart" ), + + // moduleDone: { name, failed, passed, total } + moduleDone: registerLoggingCallback( "moduleDone" ) +}); + +if ( typeof document === "undefined" || document.readyState === "complete" ) { + config.autorun = true; +} + +QUnit.load = function() { + runLoggingCallbacks( "begin", QUnit, {} ); + + // Initialize the config, saving the execution queue + var banner, filter, i, label, len, main, ol, toolbar, userAgent, val, urlConfigCheckboxes, + urlConfigHtml = "", + oldconfig = extend( {}, config ); + + QUnit.init(); + extend(config, oldconfig); + + config.blocking = false; + + len = config.urlConfig.length; + + for ( i = 0; i < len; i++ ) { + val = config.urlConfig[i]; + if ( typeof val === "string" ) { + val = { + id: val, + label: val, + tooltip: "[no tooltip available]" + }; + } + config[ val.id ] = QUnit.urlParams[ val.id ]; + urlConfigHtml += ""; + } + + // `userAgent` initialized at top of scope + userAgent = id( "qunit-userAgent" ); + if ( userAgent ) { + userAgent.innerHTML = navigator.userAgent; + } + + // `banner` initialized at top of scope + banner = id( "qunit-header" ); + if ( banner ) { + banner.innerHTML = "" + banner.innerHTML + " "; + } + + // `toolbar` initialized at top of scope + toolbar = id( "qunit-testrunner-toolbar" ); + if ( toolbar ) { + // `filter` initialized at top of scope + filter = document.createElement( "input" ); + filter.type = "checkbox"; + filter.id = "qunit-filter-pass"; + + addEvent( filter, "click", function() { + var tmp, + ol = document.getElementById( "qunit-tests" ); + + if ( filter.checked ) { + ol.className = ol.className + " hidepass"; + } else { + tmp = " " + ol.className.replace( /[\n\t\r]/g, " " ) + " "; + ol.className = tmp.replace( / hidepass /, " " ); + } + if ( defined.sessionStorage ) { + if (filter.checked) { + sessionStorage.setItem( "qunit-filter-passed-tests", "true" ); + } else { + sessionStorage.removeItem( "qunit-filter-passed-tests" ); + } + } + }); + + if ( config.hidepassed || defined.sessionStorage && sessionStorage.getItem( "qunit-filter-passed-tests" ) ) { + filter.checked = true; + // `ol` initialized at top of scope + ol = document.getElementById( "qunit-tests" ); + ol.className = ol.className + " hidepass"; + } + toolbar.appendChild( filter ); + + // `label` initialized at top of scope + label = document.createElement( "label" ); + label.setAttribute( "for", "qunit-filter-pass" ); + label.setAttribute( "title", "Only show tests and assertons that fail. Stored in sessionStorage." ); + label.innerHTML = "Hide passed tests"; + toolbar.appendChild( label ); + + urlConfigCheckboxes = document.createElement( 'span' ); + urlConfigCheckboxes.innerHTML = urlConfigHtml; + addEvent( urlConfigCheckboxes, "change", function( event ) { + var params = {}; + params[ event.target.name ] = event.target.checked ? true : undefined; + window.location = QUnit.url( params ); + }); + toolbar.appendChild( urlConfigCheckboxes ); + } + + // `main` initialized at top of scope + main = id( "qunit-fixture" ); + if ( main ) { + config.fixture = main.innerHTML; + } + + if ( config.autostart ) { + QUnit.start(); + } +}; + +addEvent( window, "load", QUnit.load ); + +// `onErrorFnPrev` initialized at top of scope +// Preserve other handlers +onErrorFnPrev = window.onerror; + +// Cover uncaught exceptions +// Returning true will surpress the default browser handler, +// returning false will let it run. +window.onerror = function ( error, filePath, linerNr ) { + var ret = false; + if ( onErrorFnPrev ) { + ret = onErrorFnPrev( error, filePath, linerNr ); + } + + // Treat return value as window.onerror itself does, + // Only do our handling if not surpressed. + if ( ret !== true ) { + if ( QUnit.config.current ) { + if ( QUnit.config.current.ignoreGlobalErrors ) { + return true; + } + QUnit.pushFailure( error, filePath + ":" + linerNr ); + } else { + QUnit.test( "global failure", function() { + QUnit.pushFailure( error, filePath + ":" + linerNr ); + }); + } + return false; + } + + return ret; +}; + +function done() { + config.autorun = true; + + // Log the last module results + if ( config.currentModule ) { + runLoggingCallbacks( "moduleDone", QUnit, { + name: config.currentModule, + failed: config.moduleStats.bad, + passed: config.moduleStats.all - config.moduleStats.bad, + total: config.moduleStats.all + }); + } + + var i, key, + banner = id( "qunit-banner" ), + tests = id( "qunit-tests" ), + runtime = +new Date() - config.started, + passed = config.stats.all - config.stats.bad, + html = [ + "Tests completed in ", + runtime, + " milliseconds.
        ", + "", + passed, + " tests of ", + config.stats.all, + " passed, ", + config.stats.bad, + " failed." + ].join( "" ); + + if ( banner ) { + banner.className = ( config.stats.bad ? "qunit-fail" : "qunit-pass" ); + } + + if ( tests ) { + id( "qunit-testresult" ).innerHTML = html; + } + + if ( config.altertitle && typeof document !== "undefined" && document.title ) { + // show ✖ for good, ✔ for bad suite result in title + // use escape sequences in case file gets loaded with non-utf-8-charset + document.title = [ + ( config.stats.bad ? "\u2716" : "\u2714" ), + document.title.replace( /^[\u2714\u2716] /i, "" ) + ].join( " " ); + } + + // clear own sessionStorage items if all tests passed + if ( config.reorder && defined.sessionStorage && config.stats.bad === 0 ) { + // `key` & `i` initialized at top of scope + for ( i = 0; i < sessionStorage.length; i++ ) { + key = sessionStorage.key( i++ ); + if ( key.indexOf( "qunit-test-" ) === 0 ) { + sessionStorage.removeItem( key ); + } + } + } + + runLoggingCallbacks( "done", QUnit, { + failed: config.stats.bad, + passed: passed, + total: config.stats.all, + runtime: runtime + }); +} + +/** @return Boolean: true if this test should be ran */ +function validTest( test ) { + var include, + filter = config.filter && config.filter.toLowerCase(), + module = config.module && config.module.toLowerCase(), + fullName = (test.module + ": " + test.testName).toLowerCase(); + + if ( config.testNumber ) { + return test.testNumber === config.testNumber; + } + + if ( module && ( !test.module || test.module.toLowerCase() !== module ) ) { + return false; + } + + if ( !filter ) { + return true; + } + + include = filter.charAt( 0 ) !== "!"; + if ( !include ) { + filter = filter.slice( 1 ); + } + + // If the filter matches, we need to honour include + if ( fullName.indexOf( filter ) !== -1 ) { + return include; + } + + // Otherwise, do the opposite + return !include; +} + +// so far supports only Firefox, Chrome and Opera (buggy), Safari (for real exceptions) +// Later Safari and IE10 are supposed to support error.stack as well +// See also https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error/Stack +function extractStacktrace( e, offset ) { + offset = offset === undefined ? 3 : offset; + + var stack, include, i, regex; + + if ( e.stacktrace ) { + // Opera + return e.stacktrace.split( "\n" )[ offset + 3 ]; + } else if ( e.stack ) { + // Firefox, Chrome + stack = e.stack.split( "\n" ); + if (/^error$/i.test( stack[0] ) ) { + stack.shift(); + } + if ( fileName ) { + include = []; + for ( i = offset; i < stack.length; i++ ) { + if ( stack[ i ].indexOf( fileName ) != -1 ) { + break; + } + include.push( stack[ i ] ); + } + if ( include.length ) { + return include.join( "\n" ); + } + } + return stack[ offset ]; + } else if ( e.sourceURL ) { + // Safari, PhantomJS + // hopefully one day Safari provides actual stacktraces + // exclude useless self-reference for generated Error objects + if ( /qunit.js$/.test( e.sourceURL ) ) { + return; + } + // for actual exceptions, this is useful + return e.sourceURL + ":" + e.line; + } +} +function sourceFromStacktrace( offset ) { + try { + throw new Error(); + } catch ( e ) { + return extractStacktrace( e, offset ); + } +} + +function escapeInnerText( s ) { + if ( !s ) { + return ""; + } + s = s + ""; + return s.replace( /[\&<>]/g, function( s ) { + switch( s ) { + case "&": return "&"; + case "<": return "<"; + case ">": return ">"; + default: return s; + } + }); +} + +function synchronize( callback, last ) { + config.queue.push( callback ); + + if ( config.autorun && !config.blocking ) { + process( last ); + } +} + +function process( last ) { + function next() { + process( last ); + } + var start = new Date().getTime(); + config.depth = config.depth ? config.depth + 1 : 1; + + while ( config.queue.length && !config.blocking ) { + if ( !defined.setTimeout || config.updateRate <= 0 || ( ( new Date().getTime() - start ) < config.updateRate ) ) { + config.queue.shift()(); + } else { + window.setTimeout( next, 13 ); + break; + } + } + config.depth--; + if ( last && !config.blocking && !config.queue.length && config.depth === 0 ) { + done(); + } +} + +function saveGlobal() { + config.pollution = []; + + if ( config.noglobals ) { + for ( var key in window ) { + // in Opera sometimes DOM element ids show up here, ignore them + if ( !hasOwn.call( window, key ) || /^qunit-test-output/.test( key ) ) { + continue; + } + config.pollution.push( key ); + } + } +} + +function checkPollution( name ) { + var newGlobals, + deletedGlobals, + old = config.pollution; + + saveGlobal(); + + newGlobals = diff( config.pollution, old ); + if ( newGlobals.length > 0 ) { + QUnit.pushFailure( "Introduced global variable(s): " + newGlobals.join(", ") ); + } + + deletedGlobals = diff( old, config.pollution ); + if ( deletedGlobals.length > 0 ) { + QUnit.pushFailure( "Deleted global variable(s): " + deletedGlobals.join(", ") ); + } +} + +// returns a new Array with the elements that are in a but not in b +function diff( a, b ) { + var i, j, + result = a.slice(); + + for ( i = 0; i < result.length; i++ ) { + for ( j = 0; j < b.length; j++ ) { + if ( result[i] === b[j] ) { + result.splice( i, 1 ); + i--; + break; + } + } + } + return result; +} + +function extend( a, b ) { + for ( var prop in b ) { + if ( b[ prop ] === undefined ) { + delete a[ prop ]; + + // Avoid "Member not found" error in IE8 caused by setting window.constructor + } else if ( prop !== "constructor" || a !== window ) { + a[ prop ] = b[ prop ]; + } + } + + return a; +} + +function addEvent( elem, type, fn ) { + if ( elem.addEventListener ) { + elem.addEventListener( type, fn, false ); + } else if ( elem.attachEvent ) { + elem.attachEvent( "on" + type, fn ); + } else { + fn(); + } +} + +function id( name ) { + return !!( typeof document !== "undefined" && document && document.getElementById ) && + document.getElementById( name ); +} + +function registerLoggingCallback( key ) { + return function( callback ) { + config[key].push( callback ); + }; +} + +// Supports deprecated method of completely overwriting logging callbacks +function runLoggingCallbacks( key, scope, args ) { + //debugger; + var i, callbacks; + if ( QUnit.hasOwnProperty( key ) ) { + QUnit[ key ].call(scope, args ); + } else { + callbacks = config[ key ]; + for ( i = 0; i < callbacks.length; i++ ) { + callbacks[ i ].call( scope, args ); + } + } +} + +// Test for equality any JavaScript type. +// Author: Philippe Rathé +QUnit.equiv = (function() { + + // Call the o related callback with the given arguments. + function bindCallbacks( o, callbacks, args ) { + var prop = QUnit.objectType( o ); + if ( prop ) { + if ( QUnit.objectType( callbacks[ prop ] ) === "function" ) { + return callbacks[ prop ].apply( callbacks, args ); + } else { + return callbacks[ prop ]; // or undefined + } + } + } + + // the real equiv function + var innerEquiv, + // stack to decide between skip/abort functions + callers = [], + // stack to avoiding loops from circular referencing + parents = [], + + getProto = Object.getPrototypeOf || function ( obj ) { + return obj.__proto__; + }, + callbacks = (function () { + + // for string, boolean, number and null + function useStrictEquality( b, a ) { + if ( b instanceof a.constructor || a instanceof b.constructor ) { + // to catch short annotaion VS 'new' annotation of a + // declaration + // e.g. var i = 1; + // var j = new Number(1); + return a == b; + } else { + return a === b; + } + } + + return { + "string": useStrictEquality, + "boolean": useStrictEquality, + "number": useStrictEquality, + "null": useStrictEquality, + "undefined": useStrictEquality, + + "nan": function( b ) { + return isNaN( b ); + }, + + "date": function( b, a ) { + return QUnit.objectType( b ) === "date" && a.valueOf() === b.valueOf(); + }, + + "regexp": function( b, a ) { + return QUnit.objectType( b ) === "regexp" && + // the regex itself + a.source === b.source && + // and its modifers + a.global === b.global && + // (gmi) ... + a.ignoreCase === b.ignoreCase && + a.multiline === b.multiline; + }, + + // - skip when the property is a method of an instance (OOP) + // - abort otherwise, + // initial === would have catch identical references anyway + "function": function() { + var caller = callers[callers.length - 1]; + return caller !== Object && typeof caller !== "undefined"; + }, + + "array": function( b, a ) { + var i, j, len, loop; + + // b could be an object literal here + if ( QUnit.objectType( b ) !== "array" ) { + return false; + } + + len = a.length; + if ( len !== b.length ) { + // safe and faster + return false; + } + + // track reference to avoid circular references + parents.push( a ); + for ( i = 0; i < len; i++ ) { + loop = false; + for ( j = 0; j < parents.length; j++ ) { + if ( parents[j] === a[i] ) { + loop = true;// dont rewalk array + } + } + if ( !loop && !innerEquiv(a[i], b[i]) ) { + parents.pop(); + return false; + } + } + parents.pop(); + return true; + }, + + "object": function( b, a ) { + var i, j, loop, + // Default to true + eq = true, + aProperties = [], + bProperties = []; + + // comparing constructors is more strict than using + // instanceof + if ( a.constructor !== b.constructor ) { + // Allow objects with no prototype to be equivalent to + // objects with Object as their constructor. + if ( !(( getProto(a) === null && getProto(b) === Object.prototype ) || + ( getProto(b) === null && getProto(a) === Object.prototype ) ) ) { + return false; + } + } + + // stack constructor before traversing properties + callers.push( a.constructor ); + // track reference to avoid circular references + parents.push( a ); + + for ( i in a ) { // be strict: don't ensures hasOwnProperty + // and go deep + loop = false; + for ( j = 0; j < parents.length; j++ ) { + if ( parents[j] === a[i] ) { + // don't go down the same path twice + loop = true; + } + } + aProperties.push(i); // collect a's properties + + if (!loop && !innerEquiv( a[i], b[i] ) ) { + eq = false; + break; + } + } + + callers.pop(); // unstack, we are done + parents.pop(); + + for ( i in b ) { + bProperties.push( i ); // collect b's properties + } + + // Ensures identical properties name + return eq && innerEquiv( aProperties.sort(), bProperties.sort() ); + } + }; + }()); + + innerEquiv = function() { // can take multiple arguments + var args = [].slice.apply( arguments ); + if ( args.length < 2 ) { + return true; // end transition + } + + return (function( a, b ) { + if ( a === b ) { + return true; // catch the most you can + } else if ( a === null || b === null || typeof a === "undefined" || + typeof b === "undefined" || + QUnit.objectType(a) !== QUnit.objectType(b) ) { + return false; // don't lose time with error prone cases + } else { + return bindCallbacks(a, callbacks, [ b, a ]); + } + + // apply transition with (1..n) arguments + }( args[0], args[1] ) && arguments.callee.apply( this, args.splice(1, args.length - 1 )) ); + }; + + return innerEquiv; +}()); + +/** + * jsDump Copyright (c) 2008 Ariel Flesler - aflesler(at)gmail(dot)com | + * http://flesler.blogspot.com Licensed under BSD + * (http://www.opensource.org/licenses/bsd-license.php) Date: 5/15/2008 + * + * @projectDescription Advanced and extensible data dumping for Javascript. + * @version 1.0.0 + * @author Ariel Flesler + * @link {http://flesler.blogspot.com/2008/05/jsdump-pretty-dump-of-any-javascript.html} + */ +QUnit.jsDump = (function() { + function quote( str ) { + return '"' + str.toString().replace( /"/g, '\\"' ) + '"'; + } + function literal( o ) { + return o + ""; + } + function join( pre, arr, post ) { + var s = jsDump.separator(), + base = jsDump.indent(), + inner = jsDump.indent(1); + if ( arr.join ) { + arr = arr.join( "," + s + inner ); + } + if ( !arr ) { + return pre + post; + } + return [ pre, inner + arr, base + post ].join(s); + } + function array( arr, stack ) { + var i = arr.length, ret = new Array(i); + this.up(); + while ( i-- ) { + ret[i] = this.parse( arr[i] , undefined , stack); + } + this.down(); + return join( "[", ret, "]" ); + } + + var reName = /^function (\w+)/, + jsDump = { + parse: function( obj, type, stack ) { //type is used mostly internally, you can fix a (custom)type in advance + stack = stack || [ ]; + var inStack, res, + parser = this.parsers[ type || this.typeOf(obj) ]; + + type = typeof parser; + inStack = inArray( obj, stack ); + + if ( inStack != -1 ) { + return "recursion(" + (inStack - stack.length) + ")"; + } + //else + if ( type == "function" ) { + stack.push( obj ); + res = parser.call( this, obj, stack ); + stack.pop(); + return res; + } + // else + return ( type == "string" ) ? parser : this.parsers.error; + }, + typeOf: function( obj ) { + var type; + if ( obj === null ) { + type = "null"; + } else if ( typeof obj === "undefined" ) { + type = "undefined"; + } else if ( QUnit.is( "regexp", obj) ) { + type = "regexp"; + } else if ( QUnit.is( "date", obj) ) { + type = "date"; + } else if ( QUnit.is( "function", obj) ) { + type = "function"; + } else if ( typeof obj.setInterval !== undefined && typeof obj.document !== "undefined" && typeof obj.nodeType === "undefined" ) { + type = "window"; + } else if ( obj.nodeType === 9 ) { + type = "document"; + } else if ( obj.nodeType ) { + type = "node"; + } else if ( + // native arrays + toString.call( obj ) === "[object Array]" || + // NodeList objects + ( typeof obj.length === "number" && typeof obj.item !== "undefined" && ( obj.length ? obj.item(0) === obj[0] : ( obj.item( 0 ) === null && typeof obj[0] === "undefined" ) ) ) + ) { + type = "array"; + } else { + type = typeof obj; + } + return type; + }, + separator: function() { + return this.multiline ? this.HTML ? "
        " : "\n" : this.HTML ? " " : " "; + }, + indent: function( extra ) {// extra can be a number, shortcut for increasing-calling-decreasing + if ( !this.multiline ) { + return ""; + } + var chr = this.indentChar; + if ( this.HTML ) { + chr = chr.replace( /\t/g, " " ).replace( / /g, " " ); + } + return new Array( this._depth_ + (extra||0) ).join(chr); + }, + up: function( a ) { + this._depth_ += a || 1; + }, + down: function( a ) { + this._depth_ -= a || 1; + }, + setParser: function( name, parser ) { + this.parsers[name] = parser; + }, + // The next 3 are exposed so you can use them + quote: quote, + literal: literal, + join: join, + // + _depth_: 1, + // This is the list of parsers, to modify them, use jsDump.setParser + parsers: { + window: "[Window]", + document: "[Document]", + error: "[ERROR]", //when no parser is found, shouldn"t happen + unknown: "[Unknown]", + "null": "null", + "undefined": "undefined", + "function": function( fn ) { + var ret = "function", + name = "name" in fn ? fn.name : (reName.exec(fn) || [])[1];//functions never have name in IE + + if ( name ) { + ret += " " + name; + } + ret += "( "; + + ret = [ ret, QUnit.jsDump.parse( fn, "functionArgs" ), "){" ].join( "" ); + return join( ret, QUnit.jsDump.parse(fn,"functionCode" ), "}" ); + }, + array: array, + nodelist: array, + "arguments": array, + object: function( map, stack ) { + var ret = [ ], keys, key, val, i; + QUnit.jsDump.up(); + if ( Object.keys ) { + keys = Object.keys( map ); + } else { + keys = []; + for ( key in map ) { + keys.push( key ); + } + } + keys.sort(); + for ( i = 0; i < keys.length; i++ ) { + key = keys[ i ]; + val = map[ key ]; + ret.push( QUnit.jsDump.parse( key, "key" ) + ": " + QUnit.jsDump.parse( val, undefined, stack ) ); + } + QUnit.jsDump.down(); + return join( "{", ret, "}" ); + }, + node: function( node ) { + var a, val, + open = QUnit.jsDump.HTML ? "<" : "<", + close = QUnit.jsDump.HTML ? ">" : ">", + tag = node.nodeName.toLowerCase(), + ret = open + tag; + + for ( a in QUnit.jsDump.DOMAttrs ) { + val = node[ QUnit.jsDump.DOMAttrs[a] ]; + if ( val ) { + ret += " " + a + "=" + QUnit.jsDump.parse( val, "attribute" ); + } + } + return ret + close + open + "/" + tag + close; + }, + functionArgs: function( fn ) {//function calls it internally, it's the arguments part of the function + var args, + l = fn.length; + + if ( !l ) { + return ""; + } + + args = new Array(l); + while ( l-- ) { + args[l] = String.fromCharCode(97+l);//97 is 'a' + } + return " " + args.join( ", " ) + " "; + }, + key: quote, //object calls it internally, the key part of an item in a map + functionCode: "[code]", //function calls it internally, it's the content of the function + attribute: quote, //node calls it internally, it's an html attribute value + string: quote, + date: quote, + regexp: literal, //regex + number: literal, + "boolean": literal + }, + DOMAttrs: { + //attributes to dump from nodes, name=>realName + id: "id", + name: "name", + "class": "className" + }, + HTML: false,//if true, entities are escaped ( <, >, \t, space and \n ) + indentChar: " ",//indentation unit + multiline: true //if true, items in a collection, are separated by a \n, else just a space. + }; + + return jsDump; +}()); + +// from Sizzle.js +function getText( elems ) { + var i, elem, + ret = ""; + + for ( i = 0; elems[i]; i++ ) { + elem = elems[i]; + + // Get the text from text nodes and CDATA nodes + if ( elem.nodeType === 3 || elem.nodeType === 4 ) { + ret += elem.nodeValue; + + // Traverse everything else, except comment nodes + } else if ( elem.nodeType !== 8 ) { + ret += getText( elem.childNodes ); + } + } + + return ret; +} + +// from jquery.js +function inArray( elem, array ) { + if ( array.indexOf ) { + return array.indexOf( elem ); + } + + for ( var i = 0, length = array.length; i < length; i++ ) { + if ( array[ i ] === elem ) { + return i; + } + } + + return -1; +} + +/* + * Javascript Diff Algorithm + * By John Resig (http://ejohn.org/) + * Modified by Chu Alan "sprite" + * + * Released under the MIT license. + * + * More Info: + * http://ejohn.org/projects/javascript-diff-algorithm/ + * + * Usage: QUnit.diff(expected, actual) + * + * QUnit.diff( "the quick brown fox jumped over", "the quick fox jumps over" ) == "the quick brown fox jumped jumps over" + */ +QUnit.diff = (function() { + function diff( o, n ) { + var i, + ns = {}, + os = {}; + + for ( i = 0; i < n.length; i++ ) { + if ( ns[ n[i] ] == null ) { + ns[ n[i] ] = { + rows: [], + o: null + }; + } + ns[ n[i] ].rows.push( i ); + } + + for ( i = 0; i < o.length; i++ ) { + if ( os[ o[i] ] == null ) { + os[ o[i] ] = { + rows: [], + n: null + }; + } + os[ o[i] ].rows.push( i ); + } + + for ( i in ns ) { + if ( !hasOwn.call( ns, i ) ) { + continue; + } + if ( ns[i].rows.length == 1 && typeof os[i] != "undefined" && os[i].rows.length == 1 ) { + n[ ns[i].rows[0] ] = { + text: n[ ns[i].rows[0] ], + row: os[i].rows[0] + }; + o[ os[i].rows[0] ] = { + text: o[ os[i].rows[0] ], + row: ns[i].rows[0] + }; + } + } + + for ( i = 0; i < n.length - 1; i++ ) { + if ( n[i].text != null && n[ i + 1 ].text == null && n[i].row + 1 < o.length && o[ n[i].row + 1 ].text == null && + n[ i + 1 ] == o[ n[i].row + 1 ] ) { + + n[ i + 1 ] = { + text: n[ i + 1 ], + row: n[i].row + 1 + }; + o[ n[i].row + 1 ] = { + text: o[ n[i].row + 1 ], + row: i + 1 + }; + } + } + + for ( i = n.length - 1; i > 0; i-- ) { + if ( n[i].text != null && n[ i - 1 ].text == null && n[i].row > 0 && o[ n[i].row - 1 ].text == null && + n[ i - 1 ] == o[ n[i].row - 1 ]) { + + n[ i - 1 ] = { + text: n[ i - 1 ], + row: n[i].row - 1 + }; + o[ n[i].row - 1 ] = { + text: o[ n[i].row - 1 ], + row: i - 1 + }; + } + } + + return { + o: o, + n: n + }; + } + + return function( o, n ) { + o = o.replace( /\s+$/, "" ); + n = n.replace( /\s+$/, "" ); + + var i, pre, + str = "", + out = diff( o === "" ? [] : o.split(/\s+/), n === "" ? [] : n.split(/\s+/) ), + oSpace = o.match(/\s+/g), + nSpace = n.match(/\s+/g); + + if ( oSpace == null ) { + oSpace = [ " " ]; + } + else { + oSpace.push( " " ); + } + + if ( nSpace == null ) { + nSpace = [ " " ]; + } + else { + nSpace.push( " " ); + } + + if ( out.n.length === 0 ) { + for ( i = 0; i < out.o.length; i++ ) { + str += "" + out.o[i] + oSpace[i] + ""; + } + } + else { + if ( out.n[0].text == null ) { + for ( n = 0; n < out.o.length && out.o[n].text == null; n++ ) { + str += "" + out.o[n] + oSpace[n] + ""; + } + } + + for ( i = 0; i < out.n.length; i++ ) { + if (out.n[i].text == null) { + str += "" + out.n[i] + nSpace[i] + ""; + } + else { + // `pre` initialized at top of scope + pre = ""; + + for ( n = out.n[i].row + 1; n < out.o.length && out.o[n].text == null; n++ ) { + pre += "" + out.o[n] + oSpace[n] + ""; + } + str += " " + out.n[i].text + nSpace[i] + pre; + } + } + } + + return str; + }; +}()); + +// for CommonJS enviroments, export everything +if ( typeof exports !== "undefined" ) { + extend(exports, QUnit); +} + +// get at whatever the global object is, like window in browsers +}( (function() {return this;}.call()) )); diff --git a/web/src/vendor/benchmark/vendor/requirejs/LICENSE b/web/src/vendor/benchmark/vendor/requirejs/LICENSE new file mode 100644 index 00000000..ffaf3171 --- /dev/null +++ b/web/src/vendor/benchmark/vendor/requirejs/LICENSE @@ -0,0 +1,58 @@ +RequireJS is released under two licenses: new BSD, and MIT. You may pick the +license that best suits your development needs. The text of both licenses are +provided below. + + +The "New" BSD License: +---------------------- + +Copyright (c) 2010-2011, The Dojo Foundation +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of the Dojo Foundation nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + + +MIT License +----------- + +Copyright (c) 2010-2011, The Dojo Foundation + +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. diff --git a/web/src/vendor/benchmark/vendor/requirejs/README.md b/web/src/vendor/benchmark/vendor/requirejs/README.md new file mode 100644 index 00000000..4d3f25e3 --- /dev/null +++ b/web/src/vendor/benchmark/vendor/requirejs/README.md @@ -0,0 +1,51 @@ +# RequireJS + +RequireJS loads plain JavaScript files as well as more defined modules. It is +optimized for in-browser use, including in +[a Web Worker](http://requirejs.org/docs/api.html#webworker), but it can be used +in other JavaScript environments, like Rhino and +[Node](http://requirejs.org/docs/node.html). It implements the +[Asynchronous Module](https://github.com/amdjs/amdjs-api/wiki/AMD) +API. + +RequireJS uses plain script tags to load modules/files, so it should allow for +easy debugging. It can be used +[simply to load existing JavaScript files](http://requirejs.org/docs/api.html#jsfiles), +so you can add it to your existing project without having to re-write your +JavaScript files. + +RequireJS includes [an optimization tool](http://requirejs.org/docs/optimization.html) +you can run as part of your packaging steps for deploying your code. The +optimization tool can combine and minify your JavaScript files to allow for +better performance. + +If the JavaScript file defines a JavaScript module via +[define()](http://requirejs.org/docs/api.html#define), then there are other benefits +RequireJS can offer: [improvements over traditional CommonJS modules](http://requirejs.org/docs/commonjs.html) +and [loading multiple versions](http://requirejs.org/docs/api.html#multiversion) +of a module in a page. RequireJS also has a plugin system that supports features like +[i18n string bundles](http://requirejs.org/docs/api.html#i18n), and +[text file dependencies](http://requirejs.org/docs/api.html#text). + +RequireJS does not have any dependencies on a JavaScript framework. +It is dual-licensed -- new BSD or MIT. + +The standard require.js file is around 5.5KB when minified via Closure Compiler +and gzipped. + +RequireJS works in IE 6+, Firefox 2+, Safari 3.2+, Chrome 3+, and Opera 10+. + +[Latest Release](http://requirejs.org/docs/download.html) + +## Directories + +* **dist**: Scripts and assets to generate the requirejs.org docs, and for +generating a require.js release. +* **docs**: The raw HTML files for the requirejs.org docs. Only includes the +body of each page. Files in **dist** are used to generate a complete HTML page. +* **tests**: Tests for require.js. +* **testBaseUrl.js**: A file used in the tests inside **tests**. Purposely +placed outside the tests directory for testing paths that go outside a baseUrl. +* **updatesubs.sh**: Updates projects that depend on require.js Assumes the +projects are siblings to this directory and have specific names. Useful to +copy require.js to dependent projects easily while in development. diff --git a/web/src/vendor/benchmark/vendor/requirejs/require.js b/web/src/vendor/benchmark/vendor/requirejs/require.js new file mode 100644 index 00000000..34cfe231 --- /dev/null +++ b/web/src/vendor/benchmark/vendor/requirejs/require.js @@ -0,0 +1,2053 @@ +/** vim: et:ts=4:sw=4:sts=4 + * @license RequireJS 2.0.5 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, jQuery, setTimeout, opera */ + +var requirejs, require, define; +(function (global) { + var req, s, head, baseElement, dataMain, src, + interactiveScript, currentlyAddingScript, mainScript, subPath, + version = '2.0.5', + 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, + aps = ap.slice, + apsp = ap.splice, + isBrowser = !!(typeof window !== 'undefined' && navigator && 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); + } + + /** + * 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 (obj.hasOwnProperty(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. + * This is not robust in IE for transferring methods that match + * Object.prototype names, but the uses of mixin here seem unlikely to + * trigger a problem related to that. + */ + 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'); + } + + //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; + } + + function makeContextModuleFunc(func, relMap, enableBuildCallback) { + return function () { + //A version of a require function that passes a moduleName + //value for items that may need to + //look up paths relative to the moduleName + var args = aps.call(arguments, 0), lastArg; + if (enableBuildCallback && + isFunction((lastArg = args[args.length - 1]))) { + lastArg.__requireJsBuild = true; + } + args.push(relMap); + return func.apply(null, args); + }; + } + + function addRequireMethods(req, context, relMap) { + each([ + ['toUrl'], + ['undef'], + ['defined', 'requireDefined'], + ['specified', 'requireSpecified'] + ], function (item) { + var prop = item[1] || item[0]; + req[item[0]] = context ? makeContextModuleFunc(context[prop], relMap) : + //If no context, then use default context. 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. + function () { + var ctx = contexts[defContextName]; + return ctx[prop].apply(ctx, arguments); + }; + }); + } + + /** + * 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 = { + waitSeconds: 7, + baseUrl: './', + paths: {}, + pkgs: {}, + shim: {} + }, + registry = {}, + undefEvents = {}, + defQueue = [], + defined = {}, + urlFetched = {}, + requireCounter = 1, + unnormalizedCounter = 1, + //Used to track the order in which modules + //should be executed, by the order they + //load. Important for consistent cycle resolution + //behavior. + waitAry = []; + + /** + * 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 (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 = 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 && (baseParts || starMap) && map) { + 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 = map[baseParts.slice(0, j).join('/')]; + + //baseName segment has config, find if it has one for + //this name. + if (mapValue) { + mapValue = 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 && starMap[nameSegment]) { + foundStarMap = 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 = config.paths[id]; + if (pathConfig && isArray(pathConfig) && pathConfig.length > 1) { + removeScript(id); + //Pop off the first array value, since it failed, and + //retry + pathConfig.shift(); + context.undef(id); + context.require([id]); + return true; + } + } + + /** + * 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, + index = name ? name.indexOf('!') : -1, + 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); + } + + if (index !== -1) { + prefix = name.substring(0, index); + name = name.substring(index + 1, name.length); + } + + if (prefix) { + prefix = normalize(prefix, parentName, applyMap); + pluginModule = 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); + 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 = registry[id]; + + if (!mod) { + mod = registry[id] = new context.Module(depMap); + } + + return mod; + } + + function on(depMap, name, fn) { + var id = depMap.id, + mod = registry[id]; + + if (hasProp(defined, id) && + (!mod || mod.defineEmitComplete)) { + if (name === 'defined') { + fn(defined[id]); + } + } else { + getModule(depMap).on(name, fn); + } + } + + function onError(err, errback) { + var ids = err.requireModules, + notified = false; + + if (errback) { + errback(err); + } else { + each(ids, function (id) { + var mod = 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 = []; + } + } + + /** + * Helper function that creates a require function object to give to + * modules that ask for it as a dependency. It needs to be specific + * per module because of the implication of path mappings that may + * need to be relative to the module name. + */ + function makeRequire(mod, enableBuildCallback, altRequire) { + var relMap = mod && mod.map, + modRequire = makeContextModuleFunc(altRequire || context.require, + relMap, + enableBuildCallback); + + addRequireMethods(modRequire, context, relMap); + modRequire.isBrowser = isBrowser; + + return modRequire; + } + + handlers = { + 'require': function (mod) { + return makeRequire(mod); + }, + 'exports': function (mod) { + mod.usingExports = true; + if (mod.map.isDefine) { + return (mod.exports = defined[mod.map.id] = {}); + } + }, + 'module': function (mod) { + return (mod.module = { + id: mod.map.id, + uri: mod.map.url, + config: function () { + return (config.config && config.config[mod.map.id]) || {}; + }, + exports: defined[mod.map.id] + }); + } + }; + + function removeWaiting(id) { + //Clean up machinery used for waiting modules. + delete registry[id]; + + each(waitAry, function (mod, i) { + if (mod.map.id === id) { + waitAry.splice(i, 1); + if (!mod.defined) { + context.waitCount -= 1; + } + return true; + } + }); + } + + function findCycle(mod, traced) { + var id = mod.map.id, + depArray = mod.depMaps, + foundModule; + + //Do not bother with unitialized modules or not yet enabled + //modules. + if (!mod.inited) { + return; + } + + //Found the cycle. + if (traced[id]) { + return mod; + } + + traced[id] = true; + + //Trace through the dependencies. + each(depArray, function (depMap) { + var depId = depMap.id, + depMod = registry[depId]; + + if (!depMod) { + return; + } + + if (!depMod.inited || !depMod.enabled) { + //Dependency is not inited, so this cannot + //be used to determine a cycle. + foundModule = null; + delete traced[id]; + return true; + } + + //mixin traced to a new object for each dependency, so that + //sibling dependencies in this object to not generate a + //false positive match on a cycle. Ideally an Object.create + //type of prototype delegation would be used here, but + //optimizing for file size vs. execution speed since hopefully + //the trees are small for circular dependency scans relative + //to the full app perf. + return (foundModule = findCycle(depMod, mixin({}, traced))); + }); + + return foundModule; + } + + function forceExec(mod, traced, uninited) { + var id = mod.map.id, + depArray = mod.depMaps; + + if (!mod.inited || !mod.map.isDefine) { + return; + } + + if (traced[id]) { + return defined[id]; + } + + traced[id] = mod; + + each(depArray, function (depMap) { + var depId = depMap.id, + depMod = registry[depId], + value; + + if (handlers[depId]) { + return; + } + + if (depMod) { + if (!depMod.inited || !depMod.enabled) { + //Dependency is not inited, + //so this module cannot be + //given a forced value yet. + uninited[id] = true; + return; + } + + //Get the value for the current dependency + value = forceExec(depMod, traced, uninited); + + //Even with forcing it may not be done, + //in particular if the module is waiting + //on a plugin resource. + if (!uninited[depId]) { + mod.defineDepById(depId, value); + } + } + }); + + mod.check(true); + + return defined[id]; + } + + function modCheck(mod) { + mod.check(); + } + + 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 = [], + 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(registry, function (mod) { + map = mod.map; + modId = map.id; + + //Skip things that are not enabled or in error state. + if (!mod.enabled) { + return; + } + + 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(waitAry, function (mod) { + if (mod.defined) { + return; + } + + var cycleMod = findCycle(mod, {}), + traced = {}; + + if (cycleMod) { + forceExec(cycleMod, traced, {}); + + //traced modules may have been + //removed from the registry, but + //their listeners still need to + //be called. + eachProp(traced, modCheck); + } + }); + + //Now that dependencies have + //been satisfied, trigger the + //completion check that then + //notifies listeners. + eachProp(registry, modCheck); + } + + //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 = undefEvents[map.id] || {}; + this.map = map; + this.shim = 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.depMaps.rjsSkipMap = depMaps.rjsSkipMap; + + 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(); + } + }, + + defineDepById: function (id, depExports) { + var i; + + //Find the index for this dependency. + each(this.depMaps, function (map, index) { + if (map.id === id) { + i = index; + return true; + } + }); + + return this.defineDep(i, depExports); + }, + + 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) { + makeRequire(this, 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 is the module is ready to define itself, and if so, + * define it. If the silent argument is true, then it will just + * define, but not notify listeners, and not ask for a context-wide + * check of all loaded modules. That is useful for cycle breaking. + */ + check: function (silent) { + 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. + if (this.events.error) { + 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.id]; + err.requireType = 'define'; + 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 + delete registry[id]; + + this.defined = true; + context.waitCount -= 1; + if (context.waitCount === 0) { + //Clear the wait array used for cycles. + waitAry = []; + } + } + + //Finished the define stage. Allow calling check again + //to allow define notifications below in the case of a + //cycle. + this.defining = false; + + if (!silent) { + 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, + pluginMap = makeModuleMap(map.prefix, null, false, true); + + on(pluginMap, 'defined', bind(this, function (plugin) { + var load, normalizedMap, normalizedMod, + name = this.map.name, + parentName = this.map.parentMap ? this.map.parentMap.name : null; + + //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); + }) || ''; + } + + normalizedMap = makeModuleMap(map.prefix + '!' + name, + this.map.parentMap, + false, + true); + on(normalizedMap, + 'defined', bind(this, function (value) { + this.init([], function () { return value; }, null, { + enabled: true, + ignore: true + }); + })); + normalizedMod = registry[normalizedMap.id]; + if (normalizedMod) { + 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) { + removeWaiting(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 = function (moduleName, text) { + /*jslint evil: true */ + var hasInteractive = useInteractive; + + //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(makeModuleMap(moduleName)); + + req.exec(text); + + if (hasInteractive) { + useInteractive = true; + } + + //Support anonymous modules. + context.completeLoad(moduleName); + }; + + //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, makeRequire(map.parentMap, true, function (deps, cb, er) { + deps.rjsSkipMap = true; + return context.require(deps, cb, er); + }), load, config); + })); + + context.enable(pluginMap, this); + this.pluginMaps[pluginMap.id] = pluginMap; + }, + + enable: function () { + this.enabled = true; + + if (!this.waitPushed) { + waitAry.push(this); + context.waitCount += 1; + this.waitPushed = 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.depMaps.rjsSkipMap); + this.depMaps[i] = depMap; + + handler = 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', 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 (!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 = 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/waitAry. + delete this.events[name]; + } + } + }; + + function callGetModule(args) { + 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') + }; + } + + return (context = { + config: config, + contextName: contextName, + registry: registry, + defined: defined, + urlFetched: urlFetched, + waitCount: 0, + defQueue: defQueue, + Module: Module, + makeModuleMap: makeModuleMap, + + /** + * 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, + paths = config.paths, + map = config.map; + + //Mix in the config values, favoring the new values over + //existing ones in context.config. + mixin(config, cfg, true); + + //Merge paths. + config.paths = mixin(paths, cfg.paths, true); + + //Merge map + if (cfg.map) { + config.map = mixin(map || {}, cfg.map, true, true); + } + + //Merge shim + if (cfg.shim) { + eachProp(cfg.shim, function (value, id) { + //Normalize the structure + if (isArray(value)) { + value = { + deps: value + }; + } + if (value.exports && !value.exports.__buildReady) { + value.exports = context.makeShimExports(value.exports); + } + 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 (exports) { + var func; + if (typeof exports === 'string') { + func = function () { + return getGlobal(exports); + }; + //Save the exports for use in nodefine checking. + func.exports = exports; + return func; + } else { + return function () { + return exports.apply(global, arguments); + }; + } + }, + + requireDefined: function (id, relMap) { + return hasProp(defined, makeModuleMap(id, relMap, false, true).id); + }, + + requireSpecified: function (id, relMap) { + id = makeModuleMap(id, relMap, false, true).id; + return hasProp(defined, id) || hasProp(registry, id); + }, + + require: function (deps, callback, errback, relMap) { + var moduleName, id, map, requireMod, args; + if (typeof deps === 'string') { + if (isFunction(callback)) { + //Invalid call + return onError(makeError('requireargs', 'Invalid require call'), errback); + } + + //Synchronous access to one module. If require.get is + //available (as in the Node adapter), prefer that. + //In this case deps is the moduleName and callback is + //the relMap + if (req.get) { + return req.get(context, deps, callback); + } + + //Just return the module wanted. In this scenario, the + //second arg (if passed) is just the relMap. + moduleName = deps; + relMap = callback; + + //Normalize module name, if it contains . or .. + map = makeModuleMap(moduleName, 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)); + } + return defined[id]; + } + + //Callback require. Normalize args. if callback or errback is + //not a function, it means it is a relMap. Test errback first. + if (errback && !isFunction(errback)) { + relMap = errback; + errback = undefined; + } + if (callback && !isFunction(callback)) { + relMap = callback; + callback = undefined; + } + + //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); + } + } + + //Mark all the dependencies as needing to be loaded. + requireMod = getModule(makeModuleMap(null, relMap)); + + requireMod.init(deps, callback, errback, { + enabled: true + }); + + checkLoaded(); + + return context.require; + }, + + undef: function (id) { + //Bind any waiting define() calls to this context, + //fix for #408 + takeGlobalQueue(); + + var map = makeModuleMap(id, null, true), + mod = registry[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; + } + + removeWaiting(id); + } + }, + + /** + * Called to enable a module if it is still in the registry + * awaiting enablement. parent module is passed in for context, + * used by the optimizer. + */ + enable: function (depMap, parent) { + var mod = 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 = config.shim[moduleName] || {}, + shExports = shim.exports && shim.exports.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 = registry[moduleName]; + + if (!found && !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.exports]); + } + } + + checkLoaded(); + }, + + /** + * 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, relModuleMap) { + var index = moduleNamePlusExt.lastIndexOf('.'), + ext = null; + + if (index !== -1) { + ext = moduleNamePlusExt.substring(index, moduleNamePlusExt.length); + moduleNamePlusExt = moduleNamePlusExt.substring(0, index); + } + + return context.nameToUrl(normalize(moduleNamePlusExt, relModuleMap && relModuleMap.id, true), + ext); + }, + + /** + * 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) { + 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 = pkgs[parentModule]; + parentPath = 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 || (/\?/.test(url) ? '' : '.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 callack 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', evt, [data.id])); + } + } + }); + } + + /** + * 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 = 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); + }; + + /** + * 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, using + //default context if no context specified. + addRequireMethods(req); + + 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 = function (err) { + throw err; + }; + + /** + * 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 = 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; + + 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 addEvenListener + //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) { + //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); + } + }; + + 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) { + //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) { + //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 = dataMain.split('/'); + mainScript = src.pop(); + subPath = src.length ? src.join('/') + '/' : './'; + + cfg.baseUrl = subPath; + dataMain = mainScript; + } + + //Strip off any trailing .js since dataMain is now + //like a module name. + dataMain = dataMain.replace(jsSuffixRegExp, ''); + + //Put the data-main script in the files to load. + cfg.deps = cfg.deps ? cfg.deps.concat(dataMain) : [dataMain]; + + 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 functions + 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 = []; + } + + //If no name, and callback is a function, then figure out if it a + //CommonJS thing with dependencies. + if (!deps.length && isFunction(callback)) { + //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)); diff --git a/web/src/vendor/benchmarkjs-runner/.bower.json b/web/src/vendor/benchmarkjs-runner/.bower.json new file mode 100644 index 00000000..896dc966 --- /dev/null +++ b/web/src/vendor/benchmarkjs-runner/.bower.json @@ -0,0 +1,30 @@ +{ + "name": "benchmark-runner", + "version": "0.0.2", + "homepage": "https://github.com/rstacruz/benchmarkjs-runner", + "authors": [ + "Rico Sta. Cruz " + ], + "main": "runner.js", + "devDependencies": { + "jquery": "*", + "benchmark": "*" + }, + "license": "MIT", + "ignore": [ + "**/.*", + "node_modules", + "bower_components", + "test", + "tests" + ], + "_release": "0.0.2", + "_resolution": { + "type": "version", + "tag": "v0.0.2", + "commit": "b01c67643150bc4eb6f712a03c3b463023997b00" + }, + "_source": "git://github.com/rstacruz/benchmarkjs-runner.git", + "_target": "*", + "_originalSource": "benchmarkjs-runner" +} \ No newline at end of file diff --git a/web/src/vendor/benchmarkjs-runner/History.md b/web/src/vendor/benchmarkjs-runner/History.md new file mode 100644 index 00000000..9ec0840c --- /dev/null +++ b/web/src/vendor/benchmarkjs-runner/History.md @@ -0,0 +1,7 @@ +## v0.0.2 - Sept 9, 2013 + +Added source code display. + +## v0.0.1 - Sept 9, 2013 + +Initial release. diff --git a/web/src/vendor/benchmarkjs-runner/Makefile b/web/src/vendor/benchmarkjs-runner/Makefile new file mode 100644 index 00000000..a4a64f39 --- /dev/null +++ b/web/src/vendor/benchmarkjs-runner/Makefile @@ -0,0 +1,12 @@ +runner.js: \ + bower_components/jquery/jquery.js \ + bower_components/benchmark/benchmark.js \ + src/runner.js + cat $^ > $@ + +bower_components/jquery/jquery.js: bower_components +bower_components/benchmark/benchmark.js: bower_components + +bower_components: bower.json + bower install + touch bower_components diff --git a/web/src/vendor/benchmarkjs-runner/Readme.md b/web/src/vendor/benchmarkjs-runner/Readme.md new file mode 100644 index 00000000..9545b230 --- /dev/null +++ b/web/src/vendor/benchmarkjs-runner/Readme.md @@ -0,0 +1,64 @@ +# Benchmark.js runner [(demo)](http://rstacruz.github.io/benchmarkjs-runner/example.html) + +Easy way to create performance tests for browser JS performance using +[Benchmark.js]. Think of it like an easy-to-use version of [jsperf.com]. + +![Screenshot](http://rstacruz.github.io/benchmarkjs-runner/support/screenshot.png?v=0852) + +## Usage + +Simply create a plain HTML file that includes the `benchmark-runner` script, +like below. Also see [example.html](example.html) for more detailed +examples. + +~~~ html + + +Benchmarks + + +~~~ + +## API + +* `suite(name, [options], function)` -- Defines a Benchmark suite. You may +optionally pass *options* to be used by Benchmark.js. + +* `bench(name, function, [options])` -- Defines a Benchmark. You may optionally +pass *options* to be used by Benchmark.js. + +* `afterEach(function)` -- Defines a function to be called after each benchmark +cycle. These routines do not contribute to the elapsed time of the benchmarks. + +* `before(function)` -- Defines a function to be called *before* all benchmarks in +the suite are to be invoked. These routines do not contribute to the elapsed +time of the benchmarks. + +* `after(function)` -- Defines a function to be called *after* all benchmarks in +the suite are invoked. + +## Acknowledgements + +Disclaimer: hastily cobbled together out of a need. Expect support to be sparse. + +© 2013, Rico Sta. Cruz. Released under the [MIT License]. + +[MIT License]: http://www.opensource.org/licenses/mit-license.php +[jsperf.com]: http://jsperf.com/ +[benchmark.js]: http://benchmarkjs.com/ diff --git a/web/src/vendor/benchmarkjs-runner/bower.json b/web/src/vendor/benchmarkjs-runner/bower.json new file mode 100644 index 00000000..d0ef57fd --- /dev/null +++ b/web/src/vendor/benchmarkjs-runner/bower.json @@ -0,0 +1,21 @@ +{ + "name": "benchmark-runner", + "version": "0.0.2", + "homepage": "https://github.com/rstacruz/benchmarkjs-runner", + "authors": [ + "Rico Sta. Cruz " + ], + "main": "runner.js", + "devDependencies": { + "jquery": "*", + "benchmark": "*" + }, + "license": "MIT", + "ignore": [ + "**/.*", + "node_modules", + "bower_components", + "test", + "tests" + ] +} diff --git a/web/src/vendor/benchmarkjs-runner/example.html b/web/src/vendor/benchmarkjs-runner/example.html new file mode 100644 index 00000000..72c87d3e --- /dev/null +++ b/web/src/vendor/benchmarkjs-runner/example.html @@ -0,0 +1,44 @@ + + +Benchmarks + + diff --git a/web/src/vendor/benchmarkjs-runner/runner.js b/web/src/vendor/benchmarkjs-runner/runner.js new file mode 100644 index 00000000..30dcf2f8 --- /dev/null +++ b/web/src/vendor/benchmarkjs-runner/runner.js @@ -0,0 +1,13019 @@ +/*! + * jQuery JavaScript Library v2.0.3 + * http://jquery.com/ + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * + * Copyright 2005, 2013 jQuery Foundation, Inc. and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2013-07-03T13:30Z + */ +(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 + // A central reference to the root jQuery(document) + rootjQuery, + + // The deferred used on DOM ready + readyList, + + // Support: IE9 + // For `typeof xmlNode.method` instead of `xmlNode.method !== undefined` + core_strundefined = typeof undefined, + + // Use the correct document accordingly with window argument (sandbox) + location = window.location, + document = window.document, + docElem = document.documentElement, + + // Map over jQuery in case of overwrite + _jQuery = window.jQuery, + + // Map over the $ in case of overwrite + _$ = window.$, + + // [[Class]] -> type pairs + class2type = {}, + + // List of deleted data cache ids, so we can reuse them + core_deletedIds = [], + + core_version = "2.0.3", + + // 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, + + // A simple way to check for HTML strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + // Strict HTML recognition (#11290: must start with <) + rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/, + + // Match a standalone tag + rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>|)$/, + + // 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 and self cleanup method + completed = function() { + document.removeEventListener( "DOMContentLoaded", completed, false ); + window.removeEventListener( "load", completed, false ); + jQuery.ready(); + }; + +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 ) { + // Inject the element directly into the jQuery object + this.length = 1; + this[0] = elem; + } + + this.context = document; + this.selector = selector; + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || rootjQuery ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(DOMElement) + } else if ( selector.nodeType ) { + this.context = this[0] = selector; + this.length = 1; + return this; + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( jQuery.isFunction( selector ) ) { + return rootjQuery.ready( selector ); + } + + if ( selector.selector !== undefined ) { + this.selector = selector.selector; + this.context = selector.context; + } + + return jQuery.makeArray( selector, this ); + }, + + // Start with an empty selector + selector: "", + + // The default length of a jQuery object is 0 + length: 0, + + toArray: function() { + return core_slice.call( this ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + return num == null ? + + // Return a 'clean' array + this.toArray() : + + // Return just the object + ( num < 0 ? this[ this.length + num ] : this[ num ] ); + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems ) { + + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + ret.context = this.context; + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + // (You can seed the arguments with an array of args, but this is + // only used internally.) + each: function( callback, args ) { + return jQuery.each( this, callback, args ); + }, + + ready: function( fn ) { + // Add the callback + jQuery.ready.promise().done( fn ); + + return this; + }, + + slice: function() { + return this.pushStack( core_slice.apply( this, arguments ) ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + eq: function( i ) { + var len = this.length, + j = +i + ( i < 0 ? len : 0 ); + return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map(this, function( elem, i ) { + return callback.call( elem, i, elem ); + })); + }, + + end: function() { + return this.prevObject || this.constructor(null); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: core_push, + sort: [].sort, + splice: [].splice +}; + +// Give the init function the jQuery prototype for later instantiation +jQuery.fn.init.prototype = jQuery.fn; + +jQuery.extend = jQuery.fn.extend = function() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[0] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + target = arguments[1] || {}; + // skip the boolean and the target + i = 2; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !jQuery.isFunction(target) ) { + target = {}; + } + + // extend jQuery itself if only one argument is passed + if ( length === i ) { + target = this; + --i; + } + + for ( ; i < length; i++ ) { + // Only deal with non-null/undefined values + if ( (options = arguments[ i ]) != null ) { + // Extend the base object + for ( name in options ) { + src = target[ name ]; + copy = options[ name ]; + + // Prevent never-ending loop + if ( target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { + if ( copyIsArray ) { + copyIsArray = false; + clone = src && jQuery.isArray(src) ? src : []; + + } else { + clone = src && jQuery.isPlainObject(src) ? src : {}; + } + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend({ + // Unique for each copy of jQuery on the page + expando: "jQuery" + ( core_version + Math.random() ).replace( /\D/g, "" ), + + noConflict: function( deep ) { + if ( window.$ === jQuery ) { + window.$ = _$; + } + + if ( deep && window.jQuery === jQuery ) { + window.jQuery = _jQuery; + } + + return jQuery; + }, + + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Hold (or release) the ready event + holdReady: function( hold ) { + if ( hold ) { + jQuery.readyWait++; + } else { + jQuery.ready( true ); + } + }, + + // Handle when the DOM is ready + ready: function( wait ) { + + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; + } + + // 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, + + 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 ); + } + // Support: Safari <= 5.1 (functionish RegExp) + return typeof obj === "object" || typeof obj === "function" ? + class2type[ core_toString.call(obj) ] || "object" : + typeof obj; + }, + + isPlainObject: function( obj ) { + // Not plain objects: + // - Any object or value whose internal [[Class]] property is not "[object Object]" + // - DOM nodes + // - window + if ( jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { + return false; + } + + // Support: Firefox <20 + // The try/catch suppresses exceptions thrown when attempting to access + // the "constructor" property of certain host objects, ie. |window.location| + // https://bugzilla.mozilla.org/show_bug.cgi?id=814622 + try { + if ( obj.constructor && + !core_hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) { + return false; + } + } catch ( e ) { + return false; + } + + // If the function hasn't returned already, we're confident that + // |obj| is a plain object, created by {} or constructed with new Object + return true; + }, + + 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: JSON.parse, + + // Cross-browser xml parsing + parseXML: function( data ) { + var xml, tmp; + if ( !data || typeof data !== "string" ) { + return null; + } + + // Support: IE9 + try { + tmp = new DOMParser(); + xml = tmp.parseFromString( data , "text/xml" ); + } catch ( e ) { + xml = undefined; + } + + if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) { + jQuery.error( "Invalid XML: " + data ); + } + return xml; + }, + + noop: function() {}, + + // Evaluates a script in a global context + globalEval: function( code ) { + var script, + indirect = eval; + + code = jQuery.trim( code ); + + if ( code ) { + // If the code includes a valid, prologue position + // strict mode pragma, execute code by injecting a + // script tag into the document. + if ( code.indexOf("use strict") === 1 ) { + script = document.createElement("script"); + script.text = code; + document.head.appendChild( script ).parentNode.removeChild( script ); + } else { + // Otherwise, avoid the DOM node creation, insertion + // and removal by using an indirect global eval + indirect( code ); + } + } + }, + + // 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; + }, + + trim: function( text ) { + return text == null ? "" : core_trim.call( text ); + }, + + // 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 ) { + return arr == null ? -1 : core_indexOf.call( arr, elem, i ); + }, + + 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 tmp, args, proxy; + + 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: Date.now, + + // A method for quickly swapping in/out CSS properties to get correct calculations. + // Note: this method belongs to the css module but it's needed here for the support module. + // If support gets modularized, this method should be moved back to the css module. + swap: function( elem, options, callback, args ) { + var ret, name, + old = {}; + + // Remember the old values, and insert the new ones + for ( name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + ret = callback.apply( elem, args || [] ); + + // Revert the old values + for ( name in options ) { + elem.style[ name ] = old[ name ]; + } + + return ret; + } +}); + +jQuery.ready.promise = function( obj ) { + if ( !readyList ) { + + readyList = jQuery.Deferred(); + + // Catch cases where $(document).ready() is called after the browser event has already occurred. + // we once tried to use readyState "interactive" here, but it caused issues like the one + // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15 + if ( document.readyState === "complete" ) { + // Handle it asynchronously to allow scripts the opportunity to delay ready + setTimeout( jQuery.ready ); + + } else { + + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", completed, false ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", completed, false ); + } + } + return readyList.promise( obj ); +}; + +// Populate the class2type map +jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +}); + +function isArraylike( obj ) { + var length = obj.length, + type = jQuery.type( obj ); + + if ( jQuery.isWindow( obj ) ) { + return false; + } + + if ( obj.nodeType === 1 && length ) { + return true; + } + + return type === "array" || type !== "function" && + ( length === 0 || + typeof length === "number" && length > 0 && ( length - 1 ) in obj ); +} + +// All jQuery objects should point back to these +rootjQuery = jQuery(document); +/*! + * Sizzle CSS Selector Engine v1.9.4-pre + * http://sizzlejs.com/ + * + * Copyright 2013 jQuery Foundation, Inc. and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2013-06-03 + */ +(function( window, undefined ) { + +var i, + support, + cachedruns, + Expr, + getText, + isXML, + compile, + outermostContext, + sortInput, + + // Local document vars + setDocument, + document, + docElem, + documentIsHTML, + rbuggyQSA, + rbuggyMatches, + matches, + contains, + + // Instance-specific data + expando = "sizzle" + -(new Date()), + preferredDoc = window.document, + dirruns = 0, + done = 0, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + hasDuplicate = false, + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + return 0; + } + return 0; + }, + + // General-purpose constants + strundefined = typeof undefined, + MAX_NEGATIVE = 1 << 31, + + // Instance methods + hasOwn = ({}).hasOwnProperty, + arr = [], + pop = arr.pop, + push_native = arr.push, + push = arr.push, + slice = arr.slice, + // Use a stripped-down indexOf if we can't use a native one + indexOf = arr.indexOf || function( elem ) { + var i = 0, + len = this.length; + for ( ; i < len; i++ ) { + if ( this[i] === elem ) { + return i; + } + } + return -1; + }, + + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", + + // Regular expressions + + // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + // http://www.w3.org/TR/css3-syntax/#characters + characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", + + // Loosely modeled on CSS identifier characters + // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors + // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier + identifier = characterEncoding.replace( "w", "w#" ), + + // Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors + attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace + + "*(?:([*^$|!~]?=)" + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]", + + // Prefer arguments quoted, + // then not containing pseudos/brackets, + // then attribute selectors/non-parenthetical expressions, + // then anything else + // These preferences are here to reduce the number of selectors + // needing tokenize in the PSEUDO preFilter + pseudos = ":(" + characterEncoding + ")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|" + attributes.replace( 3, 8 ) + ")*)|.*)\\)|)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), + + rsibling = new RegExp( whitespace + "*[+~]" ), + rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*)" + whitespace + "*\\]", "g" ), + + rpseudo = new RegExp( pseudos ), + ridentifier = new RegExp( "^" + identifier + "$" ), + + matchExpr = { + "ID": new RegExp( "^#(" + characterEncoding + ")" ), + "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ), + "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), + // For use in libraries implementing .is() + // We use this for POS matching in `select` + "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) + }, + + rnative = /^[^{]+\{\s*\[native \w/, + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + + rescape = /'|\\/g, + + // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), + funescape = function( _, escaped, escapedWhitespace ) { + var high = "0x" + escaped - 0x10000; + // NaN means non-codepoint + // Support: Firefox + // Workaround erroneous numeric interpretation of +"0x" + return high !== high || escapedWhitespace ? + escaped : + // BMP codepoint + high < 0 ? + String.fromCharCode( high + 0x10000 ) : + // Supplemental Plane codepoint (surrogate pair) + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); + }; + +// Optimize for push.apply( _, NodeList ) +try { + push.apply( + (arr = slice.call( preferredDoc.childNodes )), + preferredDoc.childNodes + ); + // Support: Android<4.0 + // Detect silently failing push.apply + arr[ preferredDoc.childNodes.length ].nodeType; +} catch ( e ) { + push = { apply: arr.length ? + + // Leverage slice if possible + function( target, els ) { + push_native.apply( target, slice.call(els) ); + } : + + // Support: IE<9 + // Otherwise append directly + function( target, els ) { + var j = target.length, + i = 0; + // Can't trust NodeList.length + while ( (target[j++] = els[i++]) ) {} + target.length = j - 1; + } + }; +} + +function Sizzle( selector, context, results, seed ) { + var match, elem, m, nodeType, + // QSA vars + i, groups, old, nid, newContext, newSelector; + + if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { + setDocument( context ); + } + + context = context || document; + results = results || []; + + if ( !selector || typeof selector !== "string" ) { + return results; + } + + if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) { + return []; + } + + if ( documentIsHTML && !seed ) { + + // Shortcuts + if ( (match = rquickExpr.exec( selector )) ) { + // Speed-up: Sizzle("#ID") + if ( (m = match[1]) ) { + if ( nodeType === 9 ) { + elem = context.getElementById( m ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE, Opera, and Webkit return items + // by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + } else { + // Context is not a document + if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) && + contains( context, elem ) && elem.id === m ) { + results.push( elem ); + return results; + } + } + + // Speed-up: Sizzle("TAG") + } else if ( match[2] ) { + push.apply( results, context.getElementsByTagName( selector ) ); + return results; + + // Speed-up: Sizzle(".CLASS") + } else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) { + push.apply( results, context.getElementsByClassName( m ) ); + return results; + } + } + + // QSA path + if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { + nid = old = expando; + newContext = context; + newSelector = nodeType === 9 && selector; + + // qSA works strangely on Element-rooted queries + // We can work around this by specifying an extra ID on the root + // and working up from there (Thanks to Andrew Dupont for the technique) + // IE 8 doesn't work on object elements + if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { + groups = tokenize( selector ); + + if ( (old = context.getAttribute("id")) ) { + nid = old.replace( rescape, "\\$&" ); + } else { + context.setAttribute( "id", nid ); + } + nid = "[id='" + nid + "'] "; + + i = groups.length; + while ( i-- ) { + groups[i] = nid + toSelector( groups[i] ); + } + newContext = rsibling.test( selector ) && context.parentNode || context; + newSelector = groups.join(","); + } + + if ( newSelector ) { + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch(qsaError) { + } finally { + if ( !old ) { + context.removeAttribute("id"); + } + } + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed ); +} + +/** + * Create key-value caches of limited size + * @returns {Function(string, Object)} Returns the Object data after storing it on itself with + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) + * deleting the oldest entry + */ +function createCache() { + var keys = []; + + function cache( key, value ) { + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) + if ( keys.push( key += " " ) > Expr.cacheLength ) { + // Only keep the most recent entries + delete cache[ keys.shift() ]; + } + return (cache[ key ] = value); + } + return cache; +} + +/** + * Mark a function for special use by Sizzle + * @param {Function} fn The function to mark + */ +function markFunction( fn ) { + fn[ expando ] = true; + return fn; +} + +/** + * Support testing using an element + * @param {Function} fn Passed the created div and expects a boolean result + */ +function assert( fn ) { + var div = document.createElement("div"); + + try { + return !!fn( div ); + } catch (e) { + return false; + } finally { + // Remove from its parent by default + if ( div.parentNode ) { + div.parentNode.removeChild( div ); + } + // release memory in IE + div = null; + } +} + +/** + * Adds the same handler for all of the specified attrs + * @param {String} attrs Pipe-separated list of attributes + * @param {Function} handler The method that will be applied + */ +function addHandle( attrs, handler ) { + var arr = attrs.split("|"), + i = attrs.length; + + while ( i-- ) { + Expr.attrHandle[ arr[i] ] = handler; + } +} + +/** + * Checks document order of two siblings + * @param {Element} a + * @param {Element} b + * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b + */ +function siblingCheck( a, b ) { + var cur = b && a, + diff = cur && a.nodeType === 1 && b.nodeType === 1 && + ( ~b.sourceIndex || MAX_NEGATIVE ) - + ( ~a.sourceIndex || MAX_NEGATIVE ); + + // Use IE sourceIndex if available on both nodes + if ( diff ) { + return diff; + } + + // Check if b follows a + if ( cur ) { + while ( (cur = cur.nextSibling) ) { + if ( cur === b ) { + return -1; + } + } + } + + return a ? 1 : -1; +} + +/** + * Returns a function to use in pseudos for input types + * @param {String} type + */ +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for buttons + * @param {String} type + */ +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for positionals + * @param {Function} fn + */ +function createPositionalPseudo( fn ) { + return markFunction(function( argument ) { + argument = +argument; + return markFunction(function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ (j = matchIndexes[i]) ] ) { + seed[j] = !(matches[j] = seed[j]); + } + } + }); + }); +} + +/** + * Detect xml + * @param {Element|Object} elem An element or a document + */ +isXML = Sizzle.isXML = function( elem ) { + // documentElement is verified for cases where it doesn't yet exist + // (such as loading iframes in IE - #4833) + var documentElement = elem && (elem.ownerDocument || elem).documentElement; + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +// Expose support vars for convenience +support = Sizzle.support = {}; + +/** + * Sets document-related variables once based on the current document + * @param {Element|Object} [doc] An element or document object to use to set the document + * @returns {Object} Returns the current document + */ +setDocument = Sizzle.setDocument = function( node ) { + var doc = node ? node.ownerDocument || node : preferredDoc, + parent = doc.defaultView; + + // If no document and documentElement is available, return + if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { + return document; + } + + // Set our document + document = doc; + docElem = doc.documentElement; + + // Support tests + documentIsHTML = !isXML( doc ); + + // Support: IE>8 + // If iframe document is assigned to "document" variable and if iframe has been reloaded, + // IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936 + // IE6-8 do not support the defaultView property so parent will be undefined + if ( parent && parent.attachEvent && parent !== parent.top ) { + parent.attachEvent( "onbeforeunload", function() { + setDocument(); + }); + } + + /* Attributes + ---------------------------------------------------------------------- */ + + // Support: IE<8 + // Verify that getAttribute really returns attributes and not properties (excepting IE8 booleans) + support.attributes = assert(function( div ) { + div.className = "i"; + return !div.getAttribute("className"); + }); + + /* getElement(s)By* + ---------------------------------------------------------------------- */ + + // Check if getElementsByTagName("*") returns only elements + support.getElementsByTagName = assert(function( div ) { + div.appendChild( doc.createComment("") ); + return !div.getElementsByTagName("*").length; + }); + + // Check if getElementsByClassName can be trusted + support.getElementsByClassName = assert(function( div ) { + div.innerHTML = "
        "; + + // Support: Safari<4 + // Catch class over-caching + div.firstChild.className = "i"; + // Support: Opera<10 + // Catch gEBCN failure to find non-leading classes + return div.getElementsByClassName("i").length === 2; + }); + + // Support: IE<10 + // Check if getElementById returns elements by name + // The broken getElementById methods don't pick up programatically-set names, + // so use a roundabout getElementsByName test + support.getById = assert(function( div ) { + docElem.appendChild( div ).id = expando; + return !doc.getElementsByName || !doc.getElementsByName( expando ).length; + }); + + // ID find and filter + if ( support.getById ) { + Expr.find["ID"] = function( id, context ) { + if ( typeof context.getElementById !== strundefined && documentIsHTML ) { + var m = context.getElementById( id ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + return m && m.parentNode ? [m] : []; + } + }; + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + return elem.getAttribute("id") === attrId; + }; + }; + } else { + // Support: IE6/7 + // getElementById is not reliable as a find shortcut + delete Expr.find["ID"]; + + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id"); + return node && node.value === attrId; + }; + }; + } + + // Tag + Expr.find["TAG"] = support.getElementsByTagName ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== strundefined ) { + return context.getElementsByTagName( tag ); + } + } : + function( tag, context ) { + var elem, + tmp = [], + i = 0, + results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + while ( (elem = results[i++]) ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }; + + // Class + Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { + if ( typeof context.getElementsByClassName !== strundefined && documentIsHTML ) { + return context.getElementsByClassName( className ); + } + }; + + /* QSA/matchesSelector + ---------------------------------------------------------------------- */ + + // QSA and matchesSelector support + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + rbuggyMatches = []; + + // qSa(:focus) reports false when true (Chrome 21) + // We allow this because of a bug in IE8/9 that throws an error + // whenever `document.activeElement` is accessed on an iframe + // So, we allow :focus to pass through QSA all the time to avoid the IE error + // See http://bugs.jquery.com/ticket/13378 + rbuggyQSA = []; + + if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) { + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert(function( div ) { + // Select is set to empty string on purpose + // This is to test IE's treatment of not explicitly + // setting a boolean content attribute, + // since its presence should be enough + // http://bugs.jquery.com/ticket/12359 + div.innerHTML = ""; + + // Support: IE8 + // Boolean attributes and "value" are not treated correctly + if ( !div.querySelectorAll("[selected]").length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here and will not see later tests + if ( !div.querySelectorAll(":checked").length ) { + rbuggyQSA.push(":checked"); + } + }); + + assert(function( div ) { + + // Support: Opera 10-12/IE8 + // ^= $= *= and empty values + // Should not select anything + // Support: Windows 8 Native Apps + // The type attribute is restricted during .innerHTML assignment + var input = doc.createElement("input"); + input.setAttribute( "type", "hidden" ); + div.appendChild( input ).setAttribute( "t", "" ); + + if ( div.querySelectorAll("[t^='']").length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here and will not see later tests + if ( !div.querySelectorAll(":enabled").length ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Opera 10-11 does not throw on post-comma invalid pseudos + div.querySelectorAll("*,:x"); + rbuggyQSA.push(",.*:"); + }); + } + + if ( (support.matchesSelector = rnative.test( (matches = docElem.webkitMatchesSelector || + docElem.mozMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector) )) ) { + + assert(function( div ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + support.disconnectedMatch = matches.call( div, "div" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( div, "[s!='']:x" ); + rbuggyMatches.push( "!=", pseudos ); + }); + } + + rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); + rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); + + /* Contains + ---------------------------------------------------------------------- */ + + // Element contains another + // Purposefully does not implement inclusive descendent + // As in, an element does not contain itself + contains = rnative.test( docElem.contains ) || docElem.compareDocumentPosition ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && ( + adown.contains ? + adown.contains( bup ) : + a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 + )); + } : + function( a, b ) { + if ( b ) { + while ( (b = b.parentNode) ) { + if ( b === a ) { + return true; + } + } + } + return false; + }; + + /* Sorting + ---------------------------------------------------------------------- */ + + // Document order sorting + sortOrder = docElem.compareDocumentPosition ? + function( a, b ) { + + // Flag for duplicate removal + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + var compare = b.compareDocumentPosition && a.compareDocumentPosition && a.compareDocumentPosition( b ); + + if ( compare ) { + // Disconnected nodes + if ( compare & 1 || + (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { + + // Choose the first element that is related to our preferred document + if ( a === doc || contains(preferredDoc, a) ) { + return -1; + } + if ( b === doc || contains(preferredDoc, b) ) { + return 1; + } + + // Maintain original order + return sortInput ? + ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : + 0; + } + + return compare & 4 ? -1 : 1; + } + + // Not directly comparable, sort on existence of method + return a.compareDocumentPosition ? -1 : 1; + } : + function( a, b ) { + var cur, + i = 0, + aup = a.parentNode, + bup = b.parentNode, + ap = [ a ], + bp = [ b ]; + + // Exit early if the nodes are identical + if ( a === b ) { + hasDuplicate = true; + return 0; + + // Parentless nodes are either documents or disconnected + } else if ( !aup || !bup ) { + return a === doc ? -1 : + b === doc ? 1 : + aup ? -1 : + bup ? 1 : + sortInput ? + ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : + 0; + + // If the nodes are siblings, we can do a quick check + } else if ( aup === bup ) { + return siblingCheck( a, b ); + } + + // Otherwise we need full lists of their ancestors for comparison + cur = a; + while ( (cur = cur.parentNode) ) { + ap.unshift( cur ); + } + cur = b; + while ( (cur = cur.parentNode) ) { + bp.unshift( cur ); + } + + // Walk down the tree looking for a discrepancy + while ( ap[i] === bp[i] ) { + i++; + } + + return i ? + // Do a sibling check if the nodes have a common ancestor + siblingCheck( ap[i], bp[i] ) : + + // Otherwise nodes in our document sort first + ap[i] === preferredDoc ? -1 : + bp[i] === preferredDoc ? 1 : + 0; + }; + + return doc; +}; + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + // Make sure that attribute selectors are quoted + expr = expr.replace( rattributeQuotes, "='$1']" ); + + if ( support.matchesSelector && documentIsHTML && + ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && + ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { + + try { + var ret = matches.call( elem, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || support.disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch(e) {} + } + + return Sizzle( expr, document, null, [elem] ).length > 0; +}; + +Sizzle.contains = function( context, elem ) { + // Set document vars if needed + if ( ( context.ownerDocument || context ) !== document ) { + setDocument( context ); + } + return contains( context, elem ); +}; + +Sizzle.attr = function( elem, name ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + var fn = Expr.attrHandle[ name.toLowerCase() ], + // Don't get fooled by Object.prototype properties (jQuery #13807) + val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? + fn( elem, name, !documentIsHTML ) : + undefined; + + return val === undefined ? + support.attributes || !documentIsHTML ? + elem.getAttribute( name ) : + (val = elem.getAttributeNode(name)) && val.specified ? + val.value : + null : + val; +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Document sorting and removing duplicates + * @param {ArrayLike} results + */ +Sizzle.uniqueSort = function( results ) { + var elem, + duplicates = [], + j = 0, + i = 0; + + // Unless we *know* we can detect duplicates, assume their presence + hasDuplicate = !support.detectDuplicates; + sortInput = !support.sortStable && results.slice( 0 ); + results.sort( sortOrder ); + + if ( hasDuplicate ) { + while ( (elem = results[i++]) ) { + if ( elem === results[ i ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } + } + + return results; +}; + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( !nodeType ) { + // If no nodeType, this is expected to be an array + for ( ; (node = elem[i]); i++ ) { + // Do not traverse comment nodes + ret += getText( node ); + } + } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + // Use textContent for elements + // innerText usage removed for consistency of new lines (see #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + // Do not include comment or processing instruction nodes + + return ret; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + attrHandle: {}, + + find: {}, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[1] = match[1].replace( runescape, funescape ); + + // Move the given value to match[3] whether quoted or unquoted + match[3] = ( match[4] || match[5] || "" ).replace( runescape, funescape ); + + if ( match[2] === "~=" ) { + match[3] = " " + match[3] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 what (child|of-type) + 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 4 xn-component of xn+y argument ([+-]?\d*n|) + 5 sign of xn-component + 6 x of xn-component + 7 sign of y-component + 8 y of y-component + */ + match[1] = match[1].toLowerCase(); + + if ( match[1].slice( 0, 3 ) === "nth" ) { + // nth-* requires argument + if ( !match[3] ) { + Sizzle.error( match[0] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); + match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); + + // other types prohibit arguments + } else if ( match[3] ) { + Sizzle.error( match[0] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var excess, + unquoted = !match[5] && match[2]; + + if ( matchExpr["CHILD"].test( match[0] ) ) { + return null; + } + + // Accept quoted arguments as-is + if ( match[3] && match[4] !== undefined ) { + match[2] = match[4]; + + // Strip excess characters from unquoted arguments + } else if ( unquoted && rpseudo.test( unquoted ) && + // Get excess from tokenize (recursively) + (excess = tokenize( unquoted, true )) && + // advance to the next closing parenthesis + (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { + + // excess is a negative index + match[0] = match[0].slice( 0, excess ); + match[2] = unquoted.slice( 0, excess ); + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + + "TAG": function( nodeNameSelector ) { + var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); + return nodeNameSelector === "*" ? + function() { return true; } : + function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ className + " " ]; + + return pattern || + (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && + classCache( className, function( elem ) { + return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute("class") || "" ); + }); + }, + + "ATTR": function( name, operator, check ) { + return function( elem ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.slice( -check.length ) === check : + operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : + false; + }; + }, + + "CHILD": function( type, what, argument, first, last ) { + var simple = type.slice( 0, 3 ) !== "nth", + forward = type.slice( -4 ) !== "last", + ofType = what === "of-type"; + + return first === 1 && last === 0 ? + + // Shortcut for :nth-*(n) + function( elem ) { + return !!elem.parentNode; + } : + + function( elem, context, xml ) { + var cache, outerCache, node, diff, nodeIndex, start, + dir = simple !== forward ? "nextSibling" : "previousSibling", + parent = elem.parentNode, + name = ofType && elem.nodeName.toLowerCase(), + useCache = !xml && !ofType; + + if ( parent ) { + + // :(first|last|only)-(child|of-type) + if ( simple ) { + while ( dir ) { + node = elem; + while ( (node = node[ dir ]) ) { + if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) { + return false; + } + } + // Reverse direction for :only-* (if we haven't yet done so) + start = dir = type === "only" && !start && "nextSibling"; + } + return true; + } + + start = [ forward ? parent.firstChild : parent.lastChild ]; + + // non-xml :nth-child(...) stores cache data on `parent` + if ( forward && useCache ) { + // Seek `elem` from a previously-cached index + outerCache = parent[ expando ] || (parent[ expando ] = {}); + cache = outerCache[ type ] || []; + nodeIndex = cache[0] === dirruns && cache[1]; + diff = cache[0] === dirruns && cache[2]; + node = nodeIndex && parent.childNodes[ nodeIndex ]; + + while ( (node = ++nodeIndex && node && node[ dir ] || + + // Fallback to seeking `elem` from the start + (diff = nodeIndex = 0) || start.pop()) ) { + + // When found, cache indexes on `parent` and break + if ( node.nodeType === 1 && ++diff && node === elem ) { + outerCache[ type ] = [ dirruns, nodeIndex, diff ]; + break; + } + } + + // Use previously-cached element index if available + } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) { + diff = cache[1]; + + // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...) + } else { + // Use the same loop as above to seek `elem` from the start + while ( (node = ++nodeIndex && node && node[ dir ] || + (diff = nodeIndex = 0) || start.pop()) ) { + + if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) { + // Cache the index of each encountered element + if ( useCache ) { + (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ]; + } + + if ( node === elem ) { + break; + } + } + } + } + + // Incorporate the offset, then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction(function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf.call( seed, matched[i] ); + seed[ idx ] = !( matches[ idx ] = matched[i] ); + } + }) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + // Potentially complex pseudos + "not": markFunction(function( selector ) { + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction(function( seed, matches, context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( (elem = unmatched[i]) ) { + seed[i] = !(matches[i] = elem); + } + } + }) : + function( elem, context, xml ) { + input[0] = elem; + matcher( input, null, xml, results ); + return !results.pop(); + }; + }), + + "has": markFunction(function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + }), + + "contains": markFunction(function( text ) { + return function( elem ) { + return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; + }; + }), + + // "Whether an element is represented by a :lang() selector + // is based solely on the element's language value + // being equal to the identifier C, + // or beginning with the identifier C immediately followed by "-". + // The matching of C against the element's language value is performed case-insensitively. + // The identifier C does not have to be a valid language name." + // http://www.w3.org/TR/selectors/#lang-pseudo + "lang": markFunction( function( lang ) { + // lang value must be a valid identifier + if ( !ridentifier.test(lang || "") ) { + Sizzle.error( "unsupported lang: " + lang ); + } + lang = lang.replace( runescape, funescape ).toLowerCase(); + return function( elem ) { + var elemLang; + do { + if ( (elemLang = documentIsHTML ? + elem.lang : + elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { + + elemLang = elemLang.toLowerCase(); + return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; + } + } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); + return false; + }; + }), + + // Miscellaneous + "target": function( elem ) { + var hash = window.location && window.location.hash; + return hash && hash.slice( 1 ) === elem.id; + }, + + "root": function( elem ) { + return elem === docElem; + }, + + "focus": function( elem ) { + return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); + }, + + // Boolean properties + "enabled": function( elem ) { + return elem.disabled === false; + }, + + "disabled": function( elem ) { + return elem.disabled === true; + }, + + "checked": function( elem ) { + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); + }, + + "selected": function( elem ) { + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + // Contents + "empty": function( elem ) { + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is only affected by element nodes and content nodes(including text(3), cdata(4)), + // not comment, processing instructions, or others + // Thanks to Diego Perini for the nodeName shortcut + // Greater than "@" means alpha characters (specifically not starting with "#" or "?") + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + if ( elem.nodeName > "@" || elem.nodeType === 3 || elem.nodeType === 4 ) { + return false; + } + } + return true; + }, + + "parent": function( elem ) { + return !Expr.pseudos["empty"]( elem ); + }, + + // Element/input types + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "text": function( elem ) { + var attr; + // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) + // use getAttribute instead to test this case + return elem.nodeName.toLowerCase() === "input" && + elem.type === "text" && + ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === elem.type ); + }, + + // Position-in-collection + "first": createPositionalPseudo(function() { + return [ 0 ]; + }), + + "last": createPositionalPseudo(function( matchIndexes, length ) { + return [ length - 1 ]; + }), + + "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + }), + + "even": createPositionalPseudo(function( matchIndexes, length ) { + var i = 0; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "odd": createPositionalPseudo(function( matchIndexes, length ) { + var i = 1; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }) + } +}; + +Expr.pseudos["nth"] = Expr.pseudos["eq"]; + +// Add button/input type pseudos +for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { + Expr.pseudos[ i ] = createInputPseudo( i ); +} +for ( i in { submit: true, reset: true } ) { + Expr.pseudos[ i ] = createButtonPseudo( i ); +} + +// Easy API for creating new setFilters +function setFilters() {} +setFilters.prototype = Expr.filters = Expr.pseudos; +Expr.setFilters = new setFilters(); + +function tokenize( selector, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ selector + " " ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || (match = rcomma.exec( soFar )) ) { + if ( match ) { + // Don't consume trailing commas as valid + soFar = soFar.slice( match[0].length ) || soFar; + } + groups.push( tokens = [] ); + } + + matched = false; + + // Combinators + if ( (match = rcombinators.exec( soFar )) ) { + matched = match.shift(); + tokens.push({ + value: matched, + // Cast descendant combinators to space + type: match[0].replace( rtrim, " " ) + }); + soFar = soFar.slice( matched.length ); + } + + // Filters + for ( type in Expr.filter ) { + if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || + (match = preFilters[ type ]( match ))) ) { + matched = match.shift(); + tokens.push({ + value: matched, + type: type, + matches: match + }); + soFar = soFar.slice( matched.length ); + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); +} + +function toSelector( tokens ) { + var i = 0, + len = tokens.length, + selector = ""; + for ( ; i < len; i++ ) { + selector += tokens[i].value; + } + return selector; +} + +function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + checkNonElements = base && dir === "parentNode", + doneName = done++; + + return combinator.first ? + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + return matcher( elem, context, xml ); + } + } + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + var data, cache, outerCache, + dirkey = dirruns + " " + doneName; + + // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching + if ( xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + if ( matcher( elem, context, xml ) ) { + return true; + } + } + } + } else { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + outerCache = elem[ expando ] || (elem[ expando ] = {}); + if ( (cache = outerCache[ dir ]) && cache[0] === dirkey ) { + if ( (data = cache[1]) === true || data === cachedruns ) { + return data === true; + } + } else { + cache = outerCache[ dir ] = [ dirkey ]; + cache[1] = matcher( elem, context, xml ) || cachedruns; + if ( cache[1] === true ) { + return true; + } + } + } + } + } + }; +} + +function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[i]( elem, context, xml ) ) { + return false; + } + } + return true; + } : + matchers[0]; +} + +function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for ( ; i < len; i++ ) { + if ( (elem = unmatched[i]) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } + } + } + + return newUnmatched; +} + +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction(function( seed, results, context, xml ) { + var temp, i, elem, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( (elem = temp[i]) ) { + matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); + } + } + } + + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) ) { + // Restore matcherIn since elem is not yet a final match + temp.push( (matcherIn[i] = elem) ); + } + } + postFinder( null, (matcherOut = []), temp, xml ); + } + + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) && + (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) { + + seed[temp] = !(results[temp] = elem); + } + } + } + + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + }); +} + +function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[0].type ], + implicitRelative = leadingRelative || Expr.relative[" "], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf.call( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + return ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + (checkContext = context).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + } ]; + + for ( ; i < len; i++ ) { + if ( (matcher = Expr.relative[ tokens[i].type ]) ) { + matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; + } else { + matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[j].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && toSelector( + // If the preceding token was a descendant combinator, insert an implicit any-element `*` + tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" }) + ).replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), + j < len && toSelector( tokens ) + ); + } + matchers.push( matcher ); + } + } + + return elementMatcher( matchers ); +} + +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + // A counter to specify which element is currently being matched + var matcherCachedRuns = 0, + bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, expandContext ) { + var elem, j, matcher, + setMatched = [], + matchedCount = 0, + i = "0", + unmatched = seed && [], + outermost = expandContext != null, + contextBackup = outermostContext, + // We must always have either seed elements or context + elems = seed || byElement && Expr.find["TAG"]( "*", expandContext && context.parentNode || context ), + // Use integer dirruns iff this is the outermost matcher + dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1); + + if ( outermost ) { + outermostContext = context !== document && context; + cachedruns = matcherCachedRuns; + } + + // Add elements passing elementMatchers directly to results + // Keep `i` a string if there are no elements so `matchedCount` will be "00" below + for ( ; (elem = elems[i]) != null; i++ ) { + if ( byElement && elem ) { + j = 0; + while ( (matcher = elementMatchers[j++]) ) { + if ( matcher( elem, context, xml ) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + cachedruns = ++matcherCachedRuns; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + // They will have gone through all possible matchers + if ( (elem = !matcher && elem) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // Apply set filters to unmatched elements + matchedCount += i; + if ( bySet && i !== matchedCount ) { + j = 0; + while ( (matcher = setMatchers[j++]) ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !(unmatched[i] || setMatched[i]) ) { + setMatched[i] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ selector + " " ]; + + if ( !cached ) { + // Generate a function of recursive functions that can be used to check each element + if ( !group ) { + group = tokenize( selector ); + } + i = group.length; + while ( i-- ) { + cached = matcherFromTokens( group[i] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); + } + return cached; +}; + +function multipleContexts( selector, contexts, results ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[i], results ); + } + return results; +} + +function select( selector, context, results, seed ) { + var i, tokens, token, type, find, + match = tokenize( selector ); + + if ( !seed ) { + // Try to minimize operations if there is only one group + if ( match.length === 1 ) { + + // Take a shortcut and set the context if the root selector is an ID + tokens = match[0] = match[0].slice( 0 ); + if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && + support.getById && context.nodeType === 9 && documentIsHTML && + Expr.relative[ tokens[1].type ] ) { + + context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0]; + if ( !context ) { + return results; + } + selector = selector.slice( tokens.shift().value.length ); + } + + // Fetch a seed set for right-to-left matching + i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; + while ( i-- ) { + token = tokens[i]; + + // Abort if we hit a combinator + if ( Expr.relative[ (type = token.type) ] ) { + break; + } + if ( (find = Expr.find[ type ]) ) { + // Search, expanding context for leading sibling combinators + if ( (seed = find( + token.matches[0].replace( runescape, funescape ), + rsibling.test( tokens[0].type ) && context.parentNode || context + )) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && toSelector( tokens ); + if ( !selector ) { + push.apply( results, seed ); + return results; + } + + break; + } + } + } + } + } + + // Compile and execute a filtering function + // Provide `match` to avoid retokenization if we modified the selector above + compile( selector, match )( + seed, + context, + !documentIsHTML, + results, + rsibling.test( selector ) + ); + return results; +} + +// One-time assignments + +// Sort stability +support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; + +// Support: Chrome<14 +// Always assume duplicates if they aren't passed to the comparison function +support.detectDuplicates = hasDuplicate; + +// Initialize against the default document +setDocument(); + +// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) +// Detached nodes confoundingly follow *each other* +support.sortDetached = assert(function( div1 ) { + // Should return 1, but returns 4 (following) + return div1.compareDocumentPosition( document.createElement("div") ) & 1; +}); + +// Support: IE<8 +// Prevent attribute/property "interpolation" +// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !assert(function( div ) { + div.innerHTML = ""; + return div.firstChild.getAttribute("href") === "#" ; +}) ) { + addHandle( "type|href|height|width", function( elem, name, isXML ) { + if ( !isXML ) { + return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); + } + }); +} + +// Support: IE<9 +// Use defaultValue in place of getAttribute("value") +if ( !support.attributes || !assert(function( div ) { + div.innerHTML = ""; + div.firstChild.setAttribute( "value", "" ); + return div.firstChild.getAttribute( "value" ) === ""; +}) ) { + addHandle( "value", function( elem, name, isXML ) { + if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { + return elem.defaultValue; + } + }); +} + +// Support: IE<9 +// Use getAttributeNode to fetch booleans when getAttribute lies +if ( !assert(function( div ) { + return div.getAttribute("disabled") == null; +}) ) { + addHandle( booleans, function( elem, name, isXML ) { + var val; + if ( !isXML ) { + return (val = elem.getAttributeNode( name )) && val.specified ? + val.value : + elem[ name ] === true ? name.toLowerCase() : null; + } + }); +} + +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; +jQuery.expr[":"] = jQuery.expr.pseudos; +jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; + + +})( window ); +// String to Object options format cache +var optionsCache = {}; + +// Convert String-formatted options into Object-formatted ones and store in cache +function createOptions( options ) { + var object = optionsCache[ options ] = {}; + jQuery.each( options.match( core_rnotwhite ) || [], function( _, flag ) { + object[ flag ] = true; + }); + return object; +} + +/* + * Create a callback list using the following parameters: + * + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible options: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( options ) { + + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? + ( optionsCache[ options ] || createOptions( options ) ) : + jQuery.extend( {}, options ); + + var // Last fire value (for non-forgettable lists) + memory, + // Flag to know if list was already fired + fired, + // Flag to know if list is currently firing + firing, + // First callback to fire (used internally by add and fireWith) + firingStart, + // End of the loop when firing + firingLength, + // Index of currently firing callback (modified by remove if needed) + firingIndex, + // Actual callback list + list = [], + // Stack of fire calls for repeatable lists + stack = !options.once && [], + // Fire callbacks + fire = function( data ) { + memory = options.memory && data; + fired = true; + firingIndex = firingStart || 0; + firingStart = 0; + firingLength = list.length; + firing = true; + for ( ; list && firingIndex < firingLength; firingIndex++ ) { + if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) { + memory = false; // To prevent further calls using add + break; + } + } + firing = false; + if ( list ) { + if ( stack ) { + if ( stack.length ) { + fire( stack.shift() ); + } + } else if ( memory ) { + list = []; + } else { + self.disable(); + } + } + }, + // Actual Callbacks object + self = { + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + // First, we save the current length + var start = list.length; + (function add( args ) { + jQuery.each( args, function( _, arg ) { + var type = jQuery.type( arg ); + if ( type === "function" ) { + if ( !options.unique || !self.has( arg ) ) { + list.push( arg ); + } + } else if ( arg && arg.length && type !== "string" ) { + // Inspect recursively + add( arg ); + } + }); + })( arguments ); + // Do we need to add the callbacks to the + // current firing batch? + if ( firing ) { + firingLength = list.length; + // With memory, if we're not firing then + // we should call right away + } else if ( memory ) { + firingStart = start; + fire( memory ); + } + } + return this; + }, + // Remove a callback from the list + remove: function() { + if ( list ) { + jQuery.each( arguments, function( _, arg ) { + var index; + while( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + // Handle firing indexes + if ( firing ) { + if ( index <= firingLength ) { + firingLength--; + } + if ( index <= firingIndex ) { + firingIndex--; + } + } + } + }); + } + return this; + }, + // Check if a given callback is in the list. + // If no argument is given, return whether or not list has callbacks attached. + has: function( fn ) { + return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length ); + }, + // Remove all callbacks from the list + empty: function() { + list = []; + firingLength = 0; + return this; + }, + // Have the list do nothing anymore + disable: function() { + list = stack = memory = undefined; + return this; + }, + // Is it disabled? + disabled: function() { + return !list; + }, + // Lock the list in its current state + lock: function() { + stack = undefined; + if ( !memory ) { + self.disable(); + } + return this; + }, + // Is it locked? + locked: function() { + return !stack; + }, + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( list && ( !fired || stack ) ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + if ( firing ) { + stack.push( args ); + } else { + fire( args ); + } + } + return this; + }, + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; +jQuery.extend({ + + Deferred: function( func ) { + var tuples = [ + // action, add listener, listener list, final state + [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ], + [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ], + [ "notify", "progress", jQuery.Callbacks("memory") ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + then: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + return jQuery.Deferred(function( newDefer ) { + jQuery.each( tuples, function( i, tuple ) { + var action = tuple[ 0 ], + fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; + // deferred[ done | fail | progress ] for forwarding actions to newDefer + deferred[ tuple[1] ](function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise() + .done( newDefer.resolve ) + .fail( newDefer.reject ) + .progress( newDefer.notify ); + } else { + newDefer[ action + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments ); + } + }); + }); + fns = null; + }).promise(); + }, + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return obj != null ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; + + // Keep pipe for back-compat + promise.pipe = promise.then; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 3 ]; + + // promise[ done | fail | progress ] = list.add + promise[ tuple[1] ] = list.add; + + // Handle state + if ( stateString ) { + list.add(function() { + // state = [ resolved | rejected ] + state = stateString; + + // [ reject_list | resolve_list ].disable; progress_list.lock + }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock ); + } + + // deferred[ resolve | reject | notify ] + deferred[ tuple[0] ] = function() { + deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments ); + return this; + }; + deferred[ tuple[0] + "With" ] = list.fireWith; + }); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( subordinate /* , ..., subordinateN */ ) { + var i = 0, + resolveValues = core_slice.call( arguments ), + length = resolveValues.length, + + // the count of uncompleted subordinates + remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, + + // the master Deferred. If resolveValues consist of only a single Deferred, just use that. + deferred = remaining === 1 ? subordinate : jQuery.Deferred(), + + // Update function for both resolve and progress values + updateFunc = function( i, contexts, values ) { + return function( value ) { + contexts[ i ] = this; + values[ i ] = arguments.length > 1 ? core_slice.call( arguments ) : value; + if( values === progressValues ) { + deferred.notifyWith( contexts, values ); + } else if ( !( --remaining ) ) { + deferred.resolveWith( contexts, values ); + } + }; + }, + + progressValues, progressContexts, resolveContexts; + + // add listeners to Deferred subordinates; treat others as resolved + if ( length > 1 ) { + progressValues = new Array( length ); + progressContexts = new Array( length ); + resolveContexts = new Array( length ); + for ( ; i < length; i++ ) { + if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { + resolveValues[ i ].promise() + .done( updateFunc( i, resolveContexts, resolveValues ) ) + .fail( deferred.reject ) + .progress( updateFunc( i, progressContexts, progressValues ) ); + } else { + --remaining; + } + } + } + + // if we're not waiting on anything, resolve the master + if ( !remaining ) { + deferred.resolveWith( resolveContexts, resolveValues ); + } + + return deferred.promise(); + } +}); +jQuery.support = (function( support ) { + var input = document.createElement("input"), + fragment = document.createDocumentFragment(), + div = document.createElement("div"), + select = document.createElement("select"), + opt = select.appendChild( document.createElement("option") ); + + // Finish early in limited environments + if ( !input.type ) { + return support; + } + + input.type = "checkbox"; + + // Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3 + // Check the default checkbox/radio value ("" on old WebKit; "on" elsewhere) + support.checkOn = input.value !== ""; + + // Must access the parent to make an option select properly + // Support: IE9, IE10 + support.optSelected = opt.selected; + + // Will be defined later + support.reliableMarginRight = true; + support.boxSizingReliable = true; + support.pixelPosition = false; + + // Make sure checked status is properly cloned + // Support: IE9, IE10 + 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; + + // Check if an input maintains its value after becoming a radio + // Support: IE9, IE10 + input = document.createElement("input"); + input.value = "t"; + input.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.appendChild( input ); + + // Support: Safari 5.1, Android 4.x, Android 2.3 + // old WebKit doesn't clone checked state correctly in fragments + support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Support: Firefox, Chrome, Safari + // Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP) + support.focusinBubbles = "onfocusin" in window; + + 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, + // Support: Firefox, Android 2.3 (Prefixed box-sizing versions). + divReset = "padding:0;margin:0;border:0;display:block;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;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"; + + // Check box-sizing and margin behavior. + body.appendChild( container ).appendChild( div ); + div.innerHTML = ""; + // Support: Firefox, Android 2.3 (Prefixed box-sizing versions). + div.style.cssText = "-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%"; + + // Workaround failing boxSizing test due to offsetWidth returning wrong value + // with some non-1 values of body zoom, ticket #13543 + jQuery.swap( body, body.style.zoom != null ? { zoom: 1 } : {}, function() { + support.boxSizing = div.offsetWidth === 4; + }); + + // Use window.getComputedStyle because jsdom on node.js will break without it. + if ( window.getComputedStyle ) { + support.pixelPosition = ( window.getComputedStyle( div, null ) || {} ).top !== "1%"; + support.boxSizingReliable = ( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px"; + + // Support: Android 2.3 + // Check if div with explicit width and no margin-right incorrectly + // gets computed margin-right based on width of container. (#3333) + // 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 ); + } + + body.removeChild( container ); + }); + + return support; +})( {} ); + +/* + Implementation Summary + + 1. Enforce API surface and semantic compatibility with 1.9.x branch + 2. Improve the module's maintainability by reducing the storage + paths to a single mechanism. + 3. Use the same single mechanism to support "private" and "user" data. + 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) + 5. Avoid exposing implementation details on user objects (eg. expando properties) + 6. Provide a clear path for implementation upgrade to WeakMap in 2014 +*/ +var data_user, data_priv, + rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/, + rmultiDash = /([A-Z])/g; + +function Data() { + // Support: Android < 4, + // Old WebKit does not have Object.preventExtensions/freeze method, + // return new empty object instead with no [[set]] accessor + Object.defineProperty( this.cache = {}, 0, { + get: function() { + return {}; + } + }); + + this.expando = jQuery.expando + Math.random(); +} + +Data.uid = 1; + +Data.accepts = function( owner ) { + // Accepts only: + // - Node + // - Node.ELEMENT_NODE + // - Node.DOCUMENT_NODE + // - Object + // - Any + return owner.nodeType ? + owner.nodeType === 1 || owner.nodeType === 9 : true; +}; + +Data.prototype = { + key: function( owner ) { + // We can accept data for non-element nodes in modern browsers, + // but we should not, see #8335. + // Always return the key for a frozen object. + if ( !Data.accepts( owner ) ) { + return 0; + } + + var descriptor = {}, + // Check if the owner object already has a cache key + unlock = owner[ this.expando ]; + + // If not, create one + if ( !unlock ) { + unlock = Data.uid++; + + // Secure it in a non-enumerable, non-writable property + try { + descriptor[ this.expando ] = { value: unlock }; + Object.defineProperties( owner, descriptor ); + + // Support: Android < 4 + // Fallback to a less secure definition + } catch ( e ) { + descriptor[ this.expando ] = unlock; + jQuery.extend( owner, descriptor ); + } + } + + // Ensure the cache object + if ( !this.cache[ unlock ] ) { + this.cache[ unlock ] = {}; + } + + return unlock; + }, + set: function( owner, data, value ) { + var prop, + // There may be an unlock assigned to this node, + // if there is no entry for this "owner", create one inline + // and set the unlock as though an owner entry had always existed + unlock = this.key( owner ), + cache = this.cache[ unlock ]; + + // Handle: [ owner, key, value ] args + if ( typeof data === "string" ) { + cache[ data ] = value; + + // Handle: [ owner, { properties } ] args + } else { + // Fresh assignments by object are shallow copied + if ( jQuery.isEmptyObject( cache ) ) { + jQuery.extend( this.cache[ unlock ], data ); + // Otherwise, copy the properties one-by-one to the cache object + } else { + for ( prop in data ) { + cache[ prop ] = data[ prop ]; + } + } + } + return cache; + }, + get: function( owner, key ) { + // Either a valid cache is found, or will be created. + // New caches will be created and the unlock returned, + // allowing direct access to the newly created + // empty data object. A valid owner object must be provided. + var cache = this.cache[ this.key( owner ) ]; + + return key === undefined ? + cache : cache[ key ]; + }, + access: function( owner, key, value ) { + var stored; + // In cases where either: + // + // 1. No key was specified + // 2. A string key was specified, but no value provided + // + // Take the "read" path and allow the get method to determine + // which value to return, respectively either: + // + // 1. The entire cache object + // 2. The data stored at the key + // + if ( key === undefined || + ((key && typeof key === "string") && value === undefined) ) { + + stored = this.get( owner, key ); + + return stored !== undefined ? + stored : this.get( owner, jQuery.camelCase(key) ); + } + + // [*]When the key is not a string, or both a key and value + // are specified, set or extend (existing objects) with either: + // + // 1. An object of properties + // 2. A key and value + // + this.set( owner, key, value ); + + // Since the "set" path can have two possible entry points + // return the expected data based on which path was taken[*] + return value !== undefined ? value : key; + }, + remove: function( owner, key ) { + var i, name, camel, + unlock = this.key( owner ), + cache = this.cache[ unlock ]; + + if ( key === undefined ) { + this.cache[ unlock ] = {}; + + } else { + // Support array or space separated string of keys + if ( jQuery.isArray( key ) ) { + // 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 = key.concat( key.map( jQuery.camelCase ) ); + } else { + camel = jQuery.camelCase( key ); + // Try the string as a key before any manipulation + if ( key in cache ) { + name = [ key, camel ]; + } else { + // If a key with the spaces exists, use it. + // Otherwise, create an array by matching non-whitespace + name = camel; + name = name in cache ? + [ name ] : ( name.match( core_rnotwhite ) || [] ); + } + } + + i = name.length; + while ( i-- ) { + delete cache[ name[ i ] ]; + } + } + }, + hasData: function( owner ) { + return !jQuery.isEmptyObject( + this.cache[ owner[ this.expando ] ] || {} + ); + }, + discard: function( owner ) { + if ( owner[ this.expando ] ) { + delete this.cache[ owner[ this.expando ] ]; + } + } +}; + +// These may be used throughout the jQuery core codebase +data_user = new Data(); +data_priv = new Data(); + + +jQuery.extend({ + acceptData: Data.accepts, + + hasData: function( elem ) { + return data_user.hasData( elem ) || data_priv.hasData( elem ); + }, + + data: function( elem, name, data ) { + return data_user.access( elem, name, data ); + }, + + removeData: function( elem, name ) { + data_user.remove( elem, name ); + }, + + // TODO: Now that all calls to _data and _removeData have been replaced + // with direct calls to data_priv methods, these can be deprecated. + _data: function( elem, name, data ) { + return data_priv.access( elem, name, data ); + }, + + _removeData: function( elem, name ) { + data_priv.remove( elem, name ); + } +}); + +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 = data_user.get( elem ); + + if ( elem.nodeType === 1 && !data_priv.get( elem, "hasDataAttrs" ) ) { + attrs = elem.attributes; + for ( ; i < attrs.length; i++ ) { + name = attrs[ i ].name; + + if ( name.indexOf( "data-" ) === 0 ) { + name = jQuery.camelCase( name.slice(5) ); + dataAttr( elem, name, data[ name ] ); + } + } + data_priv.set( elem, "hasDataAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each(function() { + data_user.set( this, key ); + }); + } + + return jQuery.access( this, function( value ) { + var data, + camelKey = jQuery.camelCase( key ); + + // The calling jQuery object (element matches) is not empty + // (and therefore has an element appears at this[ 0 ]) and the + // `value` parameter was not undefined. An empty jQuery object + // will result in `undefined` for elem = this[ 0 ] which will + // throw an exception if an attempt to read a data cache is made. + if ( elem && value === undefined ) { + // Attempt to get data from the cache + // with the key as-is + data = data_user.get( elem, key ); + if ( data !== undefined ) { + return data; + } + + // Attempt to get data from the cache + // with the key camelized + data = data_user.get( elem, camelKey ); + if ( data !== undefined ) { + return data; + } + + // Attempt to "discover" the data in + // HTML5 custom data-* attrs + data = dataAttr( elem, camelKey, undefined ); + if ( data !== undefined ) { + return data; + } + + // We tried really hard, but the data doesn't exist. + return; + } + + // Set the data... + this.each(function() { + // First, attempt to store a copy or reference of any + // data that might've been store with a camelCased key. + var data = data_user.get( this, camelKey ); + + // For HTML5 data-* attribute interop, we have to + // store property names with dashes in a camelCase form. + // This might not apply to all properties...* + data_user.set( this, camelKey, value ); + + // *... In the case of properties that might _actually_ + // have dashes, we need to also store a copy of that + // unchanged property. + if ( key.indexOf("-") !== -1 && data !== undefined ) { + data_user.set( this, key, value ); + } + }); + }, null, value, arguments.length > 1, null, true ); + }, + + removeData: function( key ) { + return this.each(function() { + data_user.remove( this, key ); + }); + } +}); + +function dataAttr( elem, key, data ) { + var name; + + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + 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 ) ? JSON.parse( data ) : + data; + } catch( e ) {} + + // Make sure we set the data so it isn't changed later + data_user.set( elem, key, data ); + } else { + data = undefined; + } + } + return data; +} +jQuery.extend({ + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = data_priv.get( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || jQuery.isArray( data ) ) { + queue = data_priv.access( elem, type, jQuery.makeArray(data) ); + } else { + queue.push( data ); + } + } + return queue || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } + + if ( fn ) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + // clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } + + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, + + // not intended for public consumption - generates a queueHooks object, or returns the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return data_priv.get( elem, key ) || data_priv.access( elem, key, { + empty: jQuery.Callbacks("once memory").add(function() { + data_priv.remove( elem, [ type + "queue", 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 = data_priv.get( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { + count++; + tmp.empty.add( resolve ); + } + } + resolve(); + return defer.promise( obj ); + } +}); +var nodeHook, boolHook, + rclass = /[\t\r\n\f]/g, + rreturn = /\r/g, + rfocusable = /^(?:input|select|textarea|button)$/i; + +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 ) { + return this.each(function() { + delete this[ jQuery.propFix[ name ] || name ]; + }); + }, + + addClass: function( value ) { + var classes, elem, cur, clazz, j, + i = 0, + len = this.length, + proceed = typeof value === "string" && value; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).addClass( value.call( this, j, this.className ) ); + }); + } + + if ( proceed ) { + // The disjunction here is for better compressibility (see removeClass) + classes = ( value || "" ).match( core_rnotwhite ) || []; + + for ( ; i < len; i++ ) { + elem = this[ i ]; + cur = elem.nodeType === 1 && ( elem.className ? + ( " " + elem.className + " " ).replace( rclass, " " ) : + " " + ); + + if ( cur ) { + j = 0; + while ( (clazz = classes[j++]) ) { + if ( cur.indexOf( " " + clazz + " " ) < 0 ) { + cur += clazz + " "; + } + } + elem.className = jQuery.trim( cur ); + + } + } + } + + return this; + }, + + removeClass: function( value ) { + var classes, elem, cur, clazz, j, + i = 0, + len = this.length, + proceed = arguments.length === 0 || typeof value === "string" && value; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).removeClass( value.call( this, j, this.className ) ); + }); + } + if ( proceed ) { + classes = ( value || "" ).match( core_rnotwhite ) || []; + + for ( ; i < len; i++ ) { + elem = this[ i ]; + // This expression is here for better compressibility (see addClass) + cur = elem.nodeType === 1 && ( elem.className ? + ( " " + elem.className + " " ).replace( rclass, " " ) : + "" + ); + + if ( cur ) { + j = 0; + while ( (clazz = classes[j++]) ) { + // Remove *all* instances + while ( cur.indexOf( " " + clazz + " " ) >= 0 ) { + cur = cur.replace( " " + clazz + " ", " " ); + } + } + elem.className = value ? jQuery.trim( cur ) : ""; + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value; + + if ( typeof stateVal === "boolean" && type === "string" ) { + return stateVal ? this.addClass( value ) : this.removeClass( value ); + } + + if ( jQuery.isFunction( value ) ) { + return this.each(function( i ) { + jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal ); + }); + } + + return this.each(function() { + if ( type === "string" ) { + // toggle individual class names + var className, + i = 0, + self = jQuery( this ), + classNames = value.match( core_rnotwhite ) || []; + + while ( (className = classNames[ i++ ]) ) { + // check each className given, space separated list + if ( self.hasClass( className ) ) { + self.removeClass( className ); + } else { + self.addClass( className ); + } + } + + // Toggle whole class name + } else if ( type === core_strundefined || type === "boolean" ) { + if ( this.className ) { + // store className if set + data_priv.set( 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 ? "" : data_priv.get( 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 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 val; + + if ( this.nodeType !== 1 ) { + return; + } + + if ( isFunction ) { + val = value.call( this, i, jQuery( this ).val() ); + } else { + val = value; + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + } else if ( typeof val === "number" ) { + val += ""; + } else if ( jQuery.isArray( val ) ) { + val = jQuery.map(val, function ( value ) { + return value == null ? "" : value + ""; + }); + } + + hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; + + // If set returns undefined, fall back to normal setting + if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) { + this.value = val; + } + }); + } +}); + +jQuery.extend({ + valHooks: { + option: { + get: function( elem ) { + // 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 ]; + + // IE6-9 doesn't update selected after form reset (#2551) + if ( ( option.selected || i === index ) && + // Don't return options that are disabled or in a disabled optgroup + ( jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null ) && + ( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) { + + // Get the specific value for the option + value = jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + return values; + }, + + set: function( elem, value ) { + var optionSet, option, + options = elem.options, + values = jQuery.makeArray( value ), + i = options.length; + + while ( i-- ) { + option = options[ i ]; + if ( (option.selected = jQuery.inArray( jQuery(option).val(), values ) >= 0) ) { + optionSet = true; + } + } + + // force browsers to behave consistently when non-matching value is set + if ( !optionSet ) { + elem.selectedIndex = -1; + } + return values; + } + } + }, + + attr: function( elem, name, value ) { + var hooks, ret, + nType = elem.nodeType; + + // don't get/set attributes on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === core_strundefined ) { + return jQuery.prop( elem, name, value ); + } + + // All attributes are lowercase + // Grab necessary hook if one is defined + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + name = name.toLowerCase(); + hooks = jQuery.attrHooks[ name ] || + ( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook ); + } + + if ( value !== undefined ) { + + if ( value === null ) { + jQuery.removeAttr( elem, name ); + + } else if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + elem.setAttribute( name, value + "" ); + return value; + } + + } else if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { + return ret; + + } else { + ret = jQuery.find.attr( elem, name ); + + // Non-existent attributes return null, we normalize to undefined + return ret == null ? + undefined : + ret; + } + }, + + removeAttr: function( elem, value ) { + var name, propName, + i = 0, + attrNames = value && value.match( core_rnotwhite ); + + if ( attrNames && elem.nodeType === 1 ) { + while ( (name = attrNames[i++]) ) { + propName = jQuery.propFix[ name ] || name; + + // Boolean attributes get special treatment (#10870) + if ( jQuery.expr.match.bool.test( name ) ) { + // Set corresponding property to false + elem[ propName ] = false; + } + + elem.removeAttribute( name ); + } + } + }, + + attrHooks: { + type: { + set: function( elem, value ) { + if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) { + // Setting the type on a radio button after the value resets the value in IE6-9 + // Reset value to default in case type is set after value during creation + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + } + }, + + propFix: { + "for": "htmlFor", + "class": "className" + }, + + prop: function( elem, name, value ) { + var ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set properties on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + if ( notxml ) { + // Fix name and attach hooks + name = jQuery.propFix[ name ] || name; + hooks = jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + return hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ? + ret : + ( elem[ name ] = value ); + + } else { + return hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ? + ret : + elem[ name ]; + } + }, + + propHooks: { + tabIndex: { + get: function( elem ) { + return elem.hasAttribute( "tabindex" ) || rfocusable.test( elem.nodeName ) || elem.href ? + elem.tabIndex : + -1; + } + } + } +}); + +// Hooks for boolean attributes +boolHook = { + set: function( elem, value, name ) { + if ( value === false ) { + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else { + elem.setAttribute( name, name ); + } + return name; + } +}; +jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) { + var getter = jQuery.expr.attrHandle[ name ] || jQuery.find.attr; + + jQuery.expr.attrHandle[ name ] = function( elem, name, isXML ) { + var fn = jQuery.expr.attrHandle[ name ], + ret = isXML ? + undefined : + /* jshint eqeqeq: false */ + // Temporarily disable this handler to check existence + (jQuery.expr.attrHandle[ name ] = undefined) != + getter( elem, name, isXML ) ? + + name.toLowerCase() : + null; + + // Restore handler + jQuery.expr.attrHandle[ name ] = fn; + + return ret; + }; +}); + +// Support: IE9+ +// Selectedness for an option in an optgroup can be inaccurate +if ( !jQuery.support.optSelected ) { + jQuery.propHooks.selected = { + get: function( elem ) { + var parent = elem.parentNode; + if ( parent && parent.parentNode ) { + parent.parentNode.selectedIndex; + } + return null; + } + }; +} + +jQuery.each([ + "tabIndex", + "readOnly", + "maxLength", + "cellSpacing", + "cellPadding", + "rowSpan", + "colSpan", + "useMap", + "frameBorder", + "contentEditable" +], function() { + jQuery.propFix[ this.toLowerCase() ] = this; +}); + +// Radios and checkboxes getter/setter +jQuery.each([ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = { + set: function( elem, value ) { + if ( jQuery.isArray( value ) ) { + return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 ); + } + } + }; + if ( !jQuery.support.checkOn ) { + jQuery.valHooks[ this ].get = function( elem ) { + // Support: Webkit + // "" is returned instead of "on" if a value isn't specified + return elem.getAttribute("value") === null ? "on" : elem.value; + }; + } +}); +var rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|contextmenu)|click/, + rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + rtypenamespace = /^([^.]*)(?:\.(.+)|)$/; + +function returnTrue() { + return true; +} + +function returnFalse() { + return false; +} + +function safeActiveElement() { + try { + return document.activeElement; + } catch ( err ) { } +} + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + global: {}, + + add: function( elem, types, handler, data, selector ) { + + var handleObjIn, eventHandle, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = data_priv.get( elem ); + + // Don't attach events to noData or text/comment nodes (but allow plain objects) + if ( !elemData ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + if ( !(events = elemData.events) ) { + events = elemData.events = {}; + } + if ( !(eventHandle = elemData.handle) ) { + eventHandle = elemData.handle = function( e ) { + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== core_strundefined && (!e || jQuery.event.triggered !== e.type) ? + jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : + undefined; + }; + // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events + eventHandle.elem = elem; + } + + // Handle multiple events separated by a space + types = ( types || "" ).match( core_rnotwhite ) || [""]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[t] ) || []; + type = origType = tmp[1]; + namespaces = ( tmp[2] || "" ).split( "." ).sort(); + + // There *must* be a type, no attaching namespace-only handlers + if ( !type ) { + continue; + } + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend({ + type: type, + origType: origType, + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), + namespace: namespaces.join(".") + }, handleObjIn ); + + // Init the event handler queue if we're the first + if ( !(handlers = events[ type ]) ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener if the special events handler returns false + if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle, false ); + } + } + } + + 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, origCount, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = data_priv.hasData( elem ) && data_priv.get( 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; + data_priv.remove( elem, "events" ); + } + }, + + trigger: function( event, data, elem, onlyHandlers ) { + + var i, cur, tmp, bubbleType, ontype, handle, special, + eventPath = [ elem || document ], + type = core_hasOwn.call( event, "type" ) ? event.type : event, + namespaces = core_hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : []; + + cur = tmp = elem = elem || document; + + // Don't do events on text and comment nodes + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf(".") >= 0 ) { + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split("."); + type = namespaces.shift(); + namespaces.sort(); + } + ontype = type.indexOf(":") < 0 && "on" + type; + + // Caller can pass in a jQuery.Event object, Object, or just an event type string + event = event[ jQuery.expando ] ? + event : + new jQuery.Event( type, typeof event === "object" && event ); + + // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) + event.isTrigger = onlyHandlers ? 2 : 3; + event.namespace = namespaces.join("."); + event.namespace_re = event.namespace ? + new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) : + null; + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data == null ? + [ event ] : + jQuery.makeArray( data, [ event ] ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + if ( !rfocusMorph.test( bubbleType + type ) ) { + cur = cur.parentNode; + } + for ( ; cur; cur = cur.parentNode ) { + eventPath.push( cur ); + tmp = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( tmp === (elem.ownerDocument || document) ) { + eventPath.push( tmp.defaultView || tmp.parentWindow || window ); + } + } + + // Fire handlers on the event path + i = 0; + while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) { + + event.type = i > 1 ? + bubbleType : + special.bindType || type; + + // jQuery handler + handle = ( data_priv.get( cur, "events" ) || {} )[ event.type ] && data_priv.get( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + + // Native handler + handle = ontype && cur[ ontype ]; + if ( handle && jQuery.acceptData( cur ) && handle.apply && handle.apply( cur, data ) === false ) { + event.preventDefault(); + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) && + jQuery.acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name name as the event. + // Don't do default actions on window, that's where global variables be (#6170) + if ( ontype && jQuery.isFunction( 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; + elem[ type ](); + 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, j, ret, matched, handleObj, + handlerQueue = [], + args = core_slice.call( arguments ), + handlers = ( data_priv.get( 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 i, matches, sel, handleObj, + 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 process clicks on disabled elements (#6911, #8165, #11382, #11764) + if ( 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; + }, + + // 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 offsetX offsetY pageX pageY screenX screenY toElement".split(" "), + filter: function( event, original ) { + var eventDoc, doc, body, + button = original.button; + + // 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 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, 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: Cordova 2.5 (WebKit) (#13255) + // All events should have a target; Cordova deviceready doesn't + if ( !event.target ) { + event.target = document; + } + + // Support: Safari 6.0+, Chrome < 28 + // Target should not be a text node (#504, #13143) + if ( event.target.nodeType === 3 ) { + event.target = event.target.parentNode; + } + + return fixHook.filter? fixHook.filter( event, originalEvent ) : event; + }, + + special: { + load: { + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + focus: { + // Fire native event if possible so blur/focus sequence is correct + trigger: function() { + if ( this !== safeActiveElement() && this.focus ) { + this.focus(); + return false; + } + }, + delegateType: "focusin" + }, + blur: { + trigger: function() { + if ( this === safeActiveElement() && this.blur ) { + this.blur(); + return false; + } + }, + delegateType: "focusout" + }, + click: { + // For checkbox, fire native event so checked state will be right + trigger: function() { + if ( this.type === "checkbox" && this.click && jQuery.nodeName( this, "input" ) ) { + this.click(); + return false; + } + }, + + // For cross-browser consistency, don't fire native .click() on links + _default: function( event ) { + return jQuery.nodeName( event.target, "a" ); + } + }, + + beforeunload: { + postDispatch: function( event ) { + + // Support: Firefox 20+ + // Firefox doesn't alert if the returnValue field is not set. + 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 = function( elem, type, handle ) { + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle, false ); + } +}; + +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.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 && e.preventDefault ) { + e.preventDefault(); + } + }, + stopPropagation: function() { + var e = this.originalEvent; + + this.isPropagationStopped = returnTrue; + + if ( e && e.stopPropagation ) { + e.stopPropagation(); + } + }, + stopImmediatePropagation: function() { + this.isImmediatePropagationStopped = returnTrue; + this.stopPropagation(); + } +}; + +// Create mouseenter/leave events using mouseover/out and event-time checks +// Support: Chrome 15+ +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; + } + }; +}); + +// Create "bubbling" focus and blur events +// Support: Firefox, Chrome, Safari +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" ) { + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + this.on( type, selector, data, types[ type ], one ); + } + return this; + } + + if ( data == null && fn == null ) { + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return this; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return this.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + }); + }, + one: function( types, selector, data, fn ) { + return this.on( types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each(function() { + jQuery.event.remove( this, types, fn, selector ); + }); + }, + + trigger: function( type, data ) { + return this.each(function() { + jQuery.event.trigger( type, data, this ); + }); + }, + triggerHandler: function( type, data ) { + var elem = this[0]; + if ( elem ) { + return jQuery.event.trigger( type, data, elem, true ); + } + } +}); +var isSimple = /^.[^:#\[\.,]*$/, + rparentsprev = /^(?:parents|prev(?:Until|All))/, + rneedsContext = jQuery.expr.match.needsContext, + // methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.fn.extend({ + find: function( selector ) { + var i, + ret = [], + self = this, + len = self.length; + + if ( typeof selector !== "string" ) { + return this.pushStack( jQuery( selector ).filter(function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + }) ); + } + + for ( i = 0; i < len; i++ ) { + jQuery.find( selector, self[ i ], ret ); + } + + // Needed because $( selector, context ) becomes $( context ).find( selector ) + ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret ); + ret.selector = this.selector ? this.selector + " " + selector : selector; + return ret; + }, + + has: function( target ) { + var targets = jQuery( target, this ), + l = targets.length; + + return this.filter(function() { + var i = 0; + for ( ; i < l; i++ ) { + if ( jQuery.contains( this, targets[i] ) ) { + return true; + } + } + }); + }, + + not: function( selector ) { + return this.pushStack( winnow(this, selector || [], true) ); + }, + + filter: function( selector ) { + return this.pushStack( winnow(this, selector || [], false) ); + }, + + is: function( selector ) { + return !!winnow( + this, + + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + typeof selector === "string" && rneedsContext.test( selector ) ? + jQuery( selector ) : + selector || [], + false + ).length; + }, + + closest: function( selectors, context ) { + var cur, + i = 0, + l = this.length, + matched = [], + pos = ( rneedsContext.test( selectors ) || typeof selectors !== "string" ) ? + jQuery( selectors, context || this.context ) : + 0; + + for ( ; i < l; i++ ) { + for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) { + // Always skip document fragments + if ( cur.nodeType < 11 && (pos ? + pos.index(cur) > -1 : + + // Don't pass non-elements to Sizzle + cur.nodeType === 1 && + jQuery.find.matchesSelector(cur, selectors)) ) { + + cur = matched.push( cur ); + break; + } + } + } + + return this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched ); + }, + + // 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 core_indexOf.call( jQuery( elem ), this[ 0 ] ); + } + + // Locate the position of the desired element + return core_indexOf.call( this, + + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[ 0 ] : elem + ); + }, + + add: function( selector, context ) { + var set = typeof selector === "string" ? + jQuery( selector, context ) : + jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ), + all = jQuery.merge( this.get(), set ); + + return this.pushStack( jQuery.unique(all) ); + }, + + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter(selector) + ); + } +}); + +function sibling( cur, dir ) { + while ( (cur = cur[dir]) && 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 elem.contentDocument || jQuery.merge( [], elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var matched = jQuery.map( this, fn, until ); + + if ( name.slice( -5 ) !== "Until" ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + matched = jQuery.filter( selector, matched ); + } + + if ( this.length > 1 ) { + // Remove duplicates + if ( !guaranteedUnique[ name ] ) { + jQuery.unique( matched ); + } + + // Reverse order for parents* and prev-derivatives + if ( rparentsprev.test( name ) ) { + matched.reverse(); + } + } + + return this.pushStack( matched ); + }; +}); + +jQuery.extend({ + filter: function( expr, elems, not ) { + var elem = elems[ 0 ]; + + if ( not ) { + expr = ":not(" + expr + ")"; + } + + return elems.length === 1 && elem.nodeType === 1 ? + jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] : + jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { + return elem.nodeType === 1; + })); + }, + + dir: function( elem, dir, until ) { + var matched = [], + truncate = until !== undefined; + + while ( (elem = elem[ dir ]) && elem.nodeType !== 9 ) { + if ( elem.nodeType === 1 ) { + if ( truncate && jQuery( elem ).is( until ) ) { + break; + } + matched.push( elem ); + } + } + return matched; + }, + + sibling: function( n, elem ) { + var matched = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + matched.push( n ); + } + } + + return matched; + } +}); + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, not ) { + if ( jQuery.isFunction( qualifier ) ) { + return jQuery.grep( elements, function( elem, i ) { + /* jshint -W018 */ + return !!qualifier.call( elem, i, elem ) !== not; + }); + + } + + if ( qualifier.nodeType ) { + return jQuery.grep( elements, function( elem ) { + return ( elem === qualifier ) !== not; + }); + + } + + if ( typeof qualifier === "string" ) { + if ( isSimple.test( qualifier ) ) { + return jQuery.filter( qualifier, elements, not ); + } + + qualifier = jQuery.filter( qualifier, elements ); + } + + return jQuery.grep( elements, function( elem ) { + return ( core_indexOf.call( qualifier, elem ) >= 0 ) !== not; + }); +} +var rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, + rtagName = /<([\w:]+)/, + rhtml = /<|&#?\w+;/, + rnoInnerhtml = /<(?:script|style|link)/i, + manipulation_rcheckableType = /^(?:checkbox|radio)$/i, + // checked="checked" or checked + rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, + rscriptType = /^$|\/(?:java|ecma)script/i, + rscriptTypeMasked = /^true\/(.*)/, + rcleanScript = /^\s*\s*$/g, + + // We have to close these tags to support XHTML (#13200) + wrapMap = { + + // Support: IE 9 + option: [ 1, "" ], + + thead: [ 1, "", "
        " ], + col: [ 2, "", "
        " ], + tr: [ 2, "", "
        " ], + td: [ 3, "", "
        " ], + + _default: [ 0, "", "" ] + }; + +// Support: IE 9 +wrapMap.optgroup = wrapMap.option; + +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +jQuery.fn.extend({ + text: function( value ) { + return jQuery.access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().append( ( this[ 0 ] && this[ 0 ].ownerDocument || document ).createTextNode( value ) ); + }, null, value, arguments.length ); + }, + + append: function() { + return this.domManip( arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.appendChild( elem ); + } + }); + }, + + prepend: function() { + return this.domManip( arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.insertBefore( elem, target.firstChild ); + } + }); + }, + + before: function() { + return this.domManip( arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this ); + } + }); + }, + + after: function() { + return this.domManip( arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + } + }); + }, + + // keepData is for internal use only--do not document + remove: function( selector, keepData ) { + var elem, + elems = selector ? jQuery.filter( selector, this ) : this, + i = 0; + + for ( ; (elem = elems[i]) != null; i++ ) { + if ( !keepData && elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem ) ); + } + + if ( elem.parentNode ) { + if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) { + setGlobalEval( getAll( elem, "script" ) ); + } + elem.parentNode.removeChild( elem ); + } + } + + return this; + }, + + empty: function() { + var elem, + i = 0; + + for ( ; (elem = this[i]) != null; i++ ) { + if ( elem.nodeType === 1 ) { + + // Prevent memory leaks + jQuery.cleanData( getAll( elem, false ) ); + + // Remove any remaining nodes + elem.textContent = ""; + } + } + + 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 && elem.nodeType === 1 ) { + return elem.innerHTML; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { + + value = value.replace( rxhtmlTag, "<$1>" ); + + try { + for ( ; i < l; i++ ) { + elem = this[ i ] || {}; + + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch( e ) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function() { + var + // Snapshot the DOM in case .domManip sweeps something relevant into its fragment + args = jQuery.map( this, function( elem ) { + return [ elem.nextSibling, elem.parentNode ]; + }), + i = 0; + + // Make the changes, replacing each context element with the new content + this.domManip( arguments, function( elem ) { + var next = args[ i++ ], + parent = args[ i++ ]; + + if ( parent ) { + // Don't use the snapshot next if it has moved (#13810) + if ( next && next.parentNode !== parent ) { + next = this.nextSibling; + } + jQuery( this ).remove(); + parent.insertBefore( elem, next ); + } + // Allow new content to include elements from the context set + }, true ); + + // Force removal if there was no new content (e.g., from empty arguments) + return i ? this : this.remove(); + }, + + detach: function( selector ) { + return this.remove( selector, true ); + }, + + domManip: function( args, callback, allowIntersection ) { + + // Flatten any nested arrays + args = core_concat.apply( [], args ); + + var fragment, first, scripts, hasScripts, node, doc, + i = 0, + l = this.length, + set = this, + iNoClone = l - 1, + value = args[ 0 ], + isFunction = jQuery.isFunction( value ); + + // We can't cloneNode fragments that contain checked, in WebKit + if ( isFunction || !( l <= 1 || typeof value !== "string" || jQuery.support.checkClone || !rchecked.test( value ) ) ) { + return this.each(function( index ) { + var self = set.eq( index ); + if ( isFunction ) { + args[ 0 ] = value.call( this, index, self.html() ); + } + self.domManip( args, callback, allowIntersection ); + }); + } + + if ( l ) { + fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, !allowIntersection && this ); + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + if ( first ) { + scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); + hasScripts = scripts.length; + + // Use the original fragment for the last item instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + for ( ; i < l; i++ ) { + node = fragment; + + if ( i !== iNoClone ) { + node = jQuery.clone( node, true, true ); + + // Keep references to cloned scripts for later restoration + if ( hasScripts ) { + // Support: QtWebKit + // jQuery.merge because core_push.apply(_, arraylike) throws + jQuery.merge( scripts, getAll( node, "script" ) ); + } + } + + callback.call( this[ i ], node, i ); + } + + if ( hasScripts ) { + doc = scripts[ scripts.length - 1 ].ownerDocument; + + // Reenable scripts + jQuery.map( scripts, restoreScript ); + + // Evaluate executable scripts on first document insertion + for ( i = 0; i < hasScripts; i++ ) { + node = scripts[ i ]; + if ( rscriptType.test( node.type || "" ) && + !data_priv.access( node, "globalEval" ) && jQuery.contains( doc, node ) ) { + + if ( node.src ) { + // Hope ajax is available... + jQuery._evalUrl( node.src ); + } else { + jQuery.globalEval( node.textContent.replace( rcleanScript, "" ) ); + } + } + } + } + } + } + + return this; + } +}); + +jQuery.each({ + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + ret = [], + insert = jQuery( selector ), + last = insert.length - 1, + i = 0; + + for ( ; i <= last; i++ ) { + elems = i === last ? this : this.clone( true ); + jQuery( insert[ i ] )[ original ]( elems ); + + // Support: QtWebKit + // .get() because core_push.apply(_, arraylike) throws + core_push.apply( ret, elems.get() ); + } + + return this.pushStack( ret ); + }; +}); + +jQuery.extend({ + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var i, l, srcElements, destElements, + clone = elem.cloneNode( true ), + inPage = jQuery.contains( elem.ownerDocument, elem ); + + // Support: IE >= 9 + // Fix Cloning issues + if ( !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 ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + fixInput( srcElements[ i ], 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, l = srcElements.length; i < l; i++ ) { + cloneCopyEvent( srcElements[ i ], destElements[ i ] ); + } + } else { + cloneCopyEvent( elem, clone ); + } + } + + // Preserve script evaluation history + destElements = getAll( clone, "script" ); + if ( destElements.length > 0 ) { + setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); + } + + // Return the cloned set + return clone; + }, + + buildFragment: function( elems, context, scripts, selection ) { + var elem, tmp, tag, wrap, contains, j, + i = 0, + l = elems.length, + fragment = context.createDocumentFragment(), + nodes = []; + + for ( ; i < l; i++ ) { + elem = elems[ i ]; + + if ( elem || elem === 0 ) { + + // Add nodes directly + if ( jQuery.type( elem ) === "object" ) { + // Support: QtWebKit + // jQuery.merge because core_push.apply(_, arraylike) throws + 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 || fragment.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; + } + + // Support: QtWebKit + // jQuery.merge because core_push.apply(_, arraylike) throws + jQuery.merge( nodes, tmp.childNodes ); + + // Remember the top-level container + tmp = fragment.firstChild; + + // Fixes #12346 + // Support: Webkit, IE + tmp.textContent = ""; + } + } + } + + // Remove wrapper from fragment + fragment.textContent = ""; + + 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( fragment.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 ); + } + } + } + } + + return fragment; + }, + + cleanData: function( elems ) { + var data, elem, events, type, key, j, + special = jQuery.event.special, + i = 0; + + for ( ; (elem = elems[ i ]) !== undefined; i++ ) { + if ( Data.accepts( elem ) ) { + key = elem[ data_priv.expando ]; + + if ( key && (data = data_priv.cache[ key ]) ) { + events = Object.keys( data.events || {} ); + if ( events.length ) { + for ( j = 0; (type = events[j]) !== undefined; j++ ) { + 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 ); + } + } + } + if ( data_priv.cache[ key ] ) { + // Discard any remaining `private` data + delete data_priv.cache[ key ]; + } + } + } + // Discard any remaining `user` data + delete data_user.cache[ elem[ data_user.expando ] ]; + } + }, + + _evalUrl: function( url ) { + return jQuery.ajax({ + url: url, + type: "GET", + dataType: "script", + async: false, + global: false, + "throws": true + }); + } +}); + +// Support: 1.x compatibility +// Manipulating tables requires a tbody +function manipulationTarget( elem, content ) { + return jQuery.nodeName( elem, "table" ) && + jQuery.nodeName( content.nodeType === 1 ? content : content.firstChild, "tr" ) ? + + elem.getElementsByTagName("tbody")[0] || + elem.appendChild( elem.ownerDocument.createElement("tbody") ) : + elem; +} + +// Replace/restore the type attribute of script elements for safe DOM manipulation +function disableScript( elem ) { + elem.type = (elem.getAttribute("type") !== null) + "/" + elem.type; + return elem; +} +function restoreScript( elem ) { + var match = rscriptTypeMasked.exec( elem.type ); + + if ( match ) { + elem.type = match[ 1 ]; + } else { + elem.removeAttribute("type"); + } + + return elem; +} + +// Mark scripts as having already been evaluated +function setGlobalEval( elems, refElements ) { + var l = elems.length, + i = 0; + + for ( ; i < l; i++ ) { + data_priv.set( + elems[ i ], "globalEval", !refElements || data_priv.get( refElements[ i ], "globalEval" ) + ); + } +} + +function cloneCopyEvent( src, dest ) { + var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events; + + if ( dest.nodeType !== 1 ) { + return; + } + + // 1. Copy private data: events, handlers, etc. + if ( data_priv.hasData( src ) ) { + pdataOld = data_priv.access( src ); + pdataCur = data_priv.set( dest, pdataOld ); + events = pdataOld.events; + + if ( events ) { + delete pdataCur.handle; + pdataCur.events = {}; + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + } + + // 2. Copy user data + if ( data_user.hasData( src ) ) { + udataOld = data_user.access( src ); + udataCur = jQuery.extend( {}, udataOld ); + + data_user.set( dest, udataCur ); + } +} + + +function getAll( context, tag ) { + var ret = context.getElementsByTagName ? context.getElementsByTagName( tag || "*" ) : + context.querySelectorAll ? context.querySelectorAll( tag || "*" ) : + []; + + return tag === undefined || tag && jQuery.nodeName( context, tag ) ? + jQuery.merge( [ context ], ret ) : + ret; +} + +// Support: IE >= 9 +function fixInput( src, dest ) { + var nodeName = dest.nodeName.toLowerCase(); + + // Fails to persist the checked state of a cloned checkbox or radio button. + if ( nodeName === "input" && manipulation_rcheckableType.test( src.type ) ) { + dest.checked = src.checked; + + // Fails to return the selected option to the default selected state when cloning options + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + } +} +jQuery.fn.extend({ + wrapAll: function( html ) { + var wrap; + + 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 + 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.firstElementChild ) { + elem = elem.firstElementChild; + } + + return elem; + }).append( this ); + } + + return this; + }, + + wrapInner: function( html ) { + if ( jQuery.isFunction( html ) ) { + return this.each(function( i ) { + jQuery( this ).wrapInner( html.call(this, i) ); + }); + } + + return this.each(function() { + var self = jQuery( this ), + contents = self.contents(); + + if ( contents.length ) { + contents.wrapAll( html ); + + } else { + self.append( html ); + } + }); + }, + + wrap: function( html ) { + var isFunction = jQuery.isFunction( html ); + + return this.each(function( i ) { + jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html ); + }); + }, + + unwrap: function() { + return this.parent().each(function() { + if ( !jQuery.nodeName( this, "body" ) ) { + jQuery( this ).replaceWith( this.childNodes ); + } + }).end(); + } +}); +var curCSS, iframe, + // 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 ); +} + +// NOTE: we've included the "window" in window.getComputedStyle +// because jsdom on node.js will break without it. +function getStyles( elem ) { + return window.getComputedStyle( elem, null ); +} + +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 ] = data_priv.get( 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 ] = data_priv.access( elem, "olddisplay", css_defaultDisplay(elem.nodeName) ); + } + } else { + + if ( !values[ index ] ) { + hidden = isHidden( elem ); + + if ( display && display !== "none" || !hidden ) { + data_priv.set( 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 styles, len, + map = {}, + i = 0; + + if ( jQuery.isArray( name ) ) { + styles = getStyles( elem ); + len = name.length; + + for ( ; i < len; i++ ) { + map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); + } + + return map; + } + + return value !== undefined ? + jQuery.style( elem, name, value ) : + jQuery.css( elem, name ); + }, name, value, arguments.length > 1 ); + }, + show: function() { + return showHide( this, true ); + }, + hide: function() { + return showHide( this ); + }, + toggle: function( state ) { + if ( typeof state === "boolean" ) { + return state ? this.show() : this.hide(); + } + + return this.each(function() { + if ( isHidden( this ) ) { + jQuery( this ).show(); + } else { + jQuery( this ).hide(); + } + }); + } +}); + +jQuery.extend({ + // Add in style property hooks for overriding the default + // behavior of getting and setting a style property + cssHooks: { + opacity: { + get: function( elem, computed ) { + if ( computed ) { + // We should always get a number back from opacity + var ret = curCSS( elem, "opacity" ); + return ret === "" ? "1" : ret; + } + } + } + }, + + // Don't automatically add "px" to these possibly-unitless properties + cssNumber: { + "columnCount": true, + "fillOpacity": true, + "fontWeight": true, + "lineHeight": true, + "opacity": true, + "order": true, + "orphans": true, + "widows": true, + "zIndex": true, + "zoom": true + }, + + // Add in properties whose names you wish to fix before + // setting or getting the value + cssProps: { + // normalize float css property + "float": "cssFloat" + }, + + // 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 specifying 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 ) { + style[ name ] = value; + } + + } 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 val, num, 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; + } +}); + +curCSS = function( elem, name, _computed ) { + var width, minWidth, maxWidth, + computed = _computed || getStyles( elem ), + + // Support: IE9 + // 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 ); + } + + // Support: Safari 5.1 + // A tribute to the "awesome hack by Dean Edwards" + // 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; +}; + + +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("