[
  {
    "path": ".eslintrc",
    "content": "{\n\t\"root\": true,\n\n\t\"extends\": \"@ljharb\",\n\n\t\"ignorePatterns\": [\n\t\t\"*.min.js\",\n\t\t\"tests/lib/*\",\n\t],\n\n\t\"rules\": {\n\t\t\"array-bracket-newline\": 0,\n\t\t\"object-curly-newline\": 0,\n\t\t\"camelcase\": [0],\n\t\t\"complexity\": [0],\n\t\t\"eqeqeq\": [2, \"allow-null\"],\n\t\t\"func-name-matching\": 0,\n\t\t\"id-length\": [2, { \"min\": 1, \"max\": 40 }],\n\t\t\"indent\": [2, 4],\n\t\t\"max-lines\": 0,\n        \"max-lines-per-function\": 0,\n\t\t\"max-nested-callbacks\": [2, 5],\n\t\t\"max-params\": [2, 7],\n\t\t\"max-statements\": [1, 30],\n\t\t\"new-cap\": [2, { \"capIsNewExceptions\": [\"ToInteger\", \"ToObject\", \"ToPrimitive\", \"ToUint32\"] }],\n\t\t\"no-constant-condition\": [1],\n\t\t\"no-extend-native\": [2, {\"exceptions\": [\"Date\", \"Error\", \"RegExp\"]}],\n\t\t\"no-extra-parens\": [0],\n\t\t\"no-extra-semi\": [1],\n\t\t\"no-func-assign\": [1],\n\t\t\"no-implicit-coercion\": [2, {\n\t\t\t\"boolean\": false,\n\t\t\t\"number\": false,\n\t\t\t\"string\": true,\n\t\t\t\"disallowTemplateShorthand\": false,\n\t\t\t\"allow\": []\n\t\t }],\n\t\t\"no-invalid-this\": [0],\n\t\t\"no-magic-numbers\": [0],\n\t\t\"no-native-reassign\": [2, {\"exceptions\": [\"Date\", \"parseInt\"]}],\n\t\t\"no-new-func\": [1],\n\t\t\"no-plusplus\": [1],\n\t\t\"no-restricted-syntax\": [2, \"ContinueStatement\", \"DebuggerStatement\", \"LabeledStatement\", \"WithStatement\"],\n\t\t\"no-shadow\": [1],\n\t\t\"no-unused-vars\": [1, { \"vars\": \"all\", \"args\": \"after-used\" }],\n\t\t\"operator-linebreak\": [2, \"before\"],\n        \"sort-keys\": [0],\n\t\t\"spaced-comment\": [0],\n\t\t\"strict\": [0],\n\n        \"multiline-comment-style\": 0,\n\t},\n\n\t\"overrides\": [\n\t\t{\n\t\t\t\"files\": \"tests/**\",\n\t\t\t\"rules\": {\n\t\t\t\t\"max-len\": 0,\n\t\t\t\t\"max-statements-per-line\": [2, { \"max\": 2 }],\n\t\t\t},\n    \t\t\"env\": {\n       \t\t\t\"jasmine\": true\n    \t\t},\n\t\t},\n\t],\n}\n"
  },
  {
    "path": ".gitattributes",
    "content": "*.min.js   -diff merge=ours\n*.map      -diff merge=ours\n"
  },
  {
    "path": ".github/workflows/node-aught.yml",
    "content": "name: 'Tests: node.js < 10'\n\non: [pull_request, push]\n\njobs:\n  tests:\n    uses: ljharb/actions/.github/workflows/node.yml@main\n    with:\n      range: '< 10'\n      type: minors\n      command: npm run tests-only\n\n  node:\n    name: 'node < 10'\n    needs: [tests]\n    runs-on: ubuntu-latest\n    steps:\n      - run: 'echo tests completed'\n"
  },
  {
    "path": ".github/workflows/node-pretest.yml",
    "content": "name: 'Tests: pretest/posttest'\n\non: [pull_request, push]\n\njobs:\n  tests:\n    uses: ljharb/actions/.github/workflows/pretest.yml@main\n"
  },
  {
    "path": ".github/workflows/node-tens.yml",
    "content": "name: 'Tests: node.js >= 10'\n\non: [pull_request, push]\n\njobs:\n  tests:\n    uses: ljharb/actions/.github/workflows/node.yml@main\n    with:\n      range: '>= 10'\n      type: minors\n      command: npm run tests-only\n\n  node:\n    name: 'node >= 10'\n    needs: [tests]\n    runs-on: ubuntu-latest\n    steps:\n      - run: 'echo tests completed'\n"
  },
  {
    "path": ".github/workflows/rebase.yml",
    "content": "name: Automatic Rebase\n\non: [pull_request_target]\n\njobs:\n  _:\n    uses: ljharb/actions/.github/workflows/rebase.yml@main\n    secrets:\n      token: ${{ secrets.GITHUB_TOKEN }}\n"
  },
  {
    "path": ".github/workflows/require-allow-edits.yml",
    "content": "name: Require “Allow Edits”\n\non: [pull_request_target]\n\njobs:\n  _:\n    name: \"Require “Allow Edits”\"\n\n    runs-on: ubuntu-latest\n\n    steps:\n      - uses: ljharb/require-allow-edits@main\n"
  },
  {
    "path": ".gitignore",
    "content": "# gitignore\nnode_modules\n.DS_Store\n\n# Only apps should have lockfiles\nnpm-shrinkwrap.json\npackage-lock.json\nyarn.lock\n\n# coverage data\ncoverage/\n.nyc_output/\n\n.npmignore\n"
  },
  {
    "path": ".npmrc",
    "content": "package-lock=false\n"
  },
  {
    "path": ".nycrc",
    "content": "{\n\t\"all\": true,\n\t\"check-coverage\": false,\n\t\"reporter\": [\"text-summary\", \"text\", \"html\", \"json\"],\n\t\"exclude\": [\n\t\t\"coverage\",\n\t\t\"test\",\n\t\t\"*.map\",\n\t\t\"*.min.js\"\n\t]\n}\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "4.6.7\n - [Fix] `parseInt`, `String#trim`: properly consider Mongolian Vowel Separator\n - [Robustness] `substr`: call-bind original substr method\n - [Tests] ensure only the actual shims are included in tests\n\n4.6.6\n - [Fix] `splice`: IE 8: upgrade ES5 impls to ES6 default argument behavior\n - [Fix] `toExponential`: IE 6 native toExponential does not throw with infinite fractionDigits\n - [Fix] `Date`: fix a bug in modern Safari (#481)\n - [Fix] ensure `parseInt` replacements are not constructible\n - [readme] add standalone shims\n - [readme] add `Array.prototype.splice` and standalone shim\n - [Tests] fix a test failure with a custom matcher in IE 6\n - [Tests] pave over Firefox’s increased getMinutes precision\n - [Dev Deps] update `eslint`, `@ljharb/eslint-config`\n\n4.6.5\n - [Fix] IE 8 has a broken `Object.defineProperty`\n - [patch] replace dead link in comment with archive.org link\n - [Docs] update all possible http: links to https:\n - [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `aud`\n\n4.6.4\n - [Fix] `Object.defineProperty`: when shimmed in Chrome <= 36, properly handle writability\n - [Tests] add some additional tests\n\n4.6.3\n - [Fix] `Object.defineProperty`: Chrome <= 36 has a broken dP when setting \"prototype\" while changing writability\n - [Fix] `toExponential`: use `thisNumberValue` instead of `Number()`\n - [readme] fix badges\n - [readme] add standalone shims\n - [actions] reuse common workflows\n - [actions] update codecov uploader\n - [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `safe-publish-latest`\n - [Tests] avoid loading coverage data when running tests\n\n4.6.2\n  - [Fix] IE 6-8 fails to throw on infinite fractional digits\n\n4.6.1\n  - [Fix] `Math.log10` does not exist in older engines, oops\n  - [Fix] `toExponential`: start from 16 instead of 22\n  - [Fix] `toExponential`: ensure ToNumber is only called once on the receiver\n  - [Robustness] `toExponential`, `toPrecision`: ensure things do not break with later builtin modification\n\n4.6.0\n  - [New] detect and patch `Number#toExponential` in Edge 15-18, which rounds incorrectly\n  - [Fix] `parseInt`: fails to throw on boxed Symbols in Edge 15-18\n  - [eslint] ensure autofix makes no further changes\n  - [readme] remove travis badge\n  - [meta] use `prepublishOnly`, for npm 7+\n  - [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `aud`\n  - [tests] use `ljharb/actions/node/install` instead of `ljharb/actions/node/run`; use codecov action\n  - [actions] update workflows\n\n4.5.15\n  - [Fix] `es5-sham`: `getPrototypeOf`: avoid infinite loop in pre-`__proto__` browsers\n  - [Fix] `split`: add a function name to the \"broken capturing groups\" shim\n  - [Robustness] cache Math methods\n  - [readme] add standalone shims\n  - [meta] add `in-publish` to avoid running the minifier on install\n  - [meta] run `aud` in `posttest`\n  - [Tests] migrate tests to Github Actions (#474)\n  - [Tests] run `nyc` on all tests\n  - [actions] add \"Allow Edits\" workflow\n  - [actions] switch Automatic Rebase workflow to `pull_request_target` event\n  - [Dev Deps] update `eslint`, `@ljharb/eslint-config`\n\n4.5.14\n  - [Fix] handle no `deleteCount` to `splice()` in Opera (#465)\n  - [Refactor] remove unnecessary comparison\n  - [meta] remove unused Makefile and associated utilities\n  - [meta] add `funding` field\n  - [meta] Rename CHANGES to CHANGELOG.md\n  - [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `replace`, `semver`; add `safe-publish-latest`\n  - [Tests] fix negative Date tests to handle TZData\n  - [Tests] use shared travis-ci configs\n  - [Tests] remove `jscs`\n  - [Tests] clarify toPrecision's range increased in ES2018\n  - [actions] add automatic rebasing / merge commit blocking\n\n4.5.13\n  - [Fix] exclude deprecated Firefox keys (#460)\n  - [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `jasmine-node`, `replace`, `semver`\n\n4.5.12\n  - [meta] republish broken 4.5.11\n\n4.5.11\n  - [Fix] sync Object.keys excluded list from object-keys (#456)\n  - [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `jasmine-node`, `replace`, `semver`\n  - [Tests] pin jasmine-node to ~1.13\n\n4.5.10\n  - [Fix] Safari 11 throws on `.sort({})`, but not on `.sort(null)`\n  - [Fix] ensure the shimmed parseInt throws with Symbols (#450)\n  - [Fix] skip over `localStorage`, which can’t be accessed on file://\n  - [Fix] Accessing window.top.{constructor|prototype} throws error in iOS (#445)\n  - [Fix] avoid `width` and `height` on `window`, to prevent reflow (https://github.com/ljharb/object-keys/issues/31)\n  - [Fix] ensure minified literal of `1000000000000000128` stays as that literal (#441)\n  - [Robustness] always prefer `String(x)` over `x.toString()`\n  - [Tests] up to `node` `v9.3`, `v8.9`, `v7.10`, `v6.12`, `v5.12`, `v4.8`; improve test matrix; use `nvm install-latest-npm`; comment out OS X builds; pin included builds to LTS\n  - [Tests] `parseInt`: add another test for NaN parsing (#433)\n  - [Dev Deps] `uglify-js`: add `--support-ie8` and peg to v2.7.x since it doesn’t follow semver\n  - [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `jscs`, `uglify-js`, `semver`; remove `concurrently` (#421)\n\n4.5.9\n  - [Fix] parseInt and parseFloat should both accept null/undefined (#402)\n  - [Tests] up to `node` `v6.2`\n  - [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `jscs`, `concurrently`\n\n4.5.8\n  - [Fix] Check if property descriptor is configurable before re-defining it (#394, #373)\n  - [Dev Deps] update `eslint`, `jscs`, `@ljharb/eslint-config`\n  - [Tests] up to `node` `v5.10`, `v4.4`\n  - [Tests] Use `concurrently` instead of `parallelshell`\n  - [Tests] use `pretest` to run the linter\n\n4.5.7\n  - [Fix] `bind` in IE 8: Update `is-callable` implementation to v1.1.3 (#390)\n\n4.5.6\n  - [Fix] `new Date(new Date())` should work in IE 8 (#389)\n  - [Tests] on `node` `v5.7`\n  - [Dev Deps] update `uglify-js`\n\n4.5.5\n  - [Fix] Adobe Photoshop’s JS engine bizarrely can have `+date !== date.getTime()` (#365)\n  - [Dev Deps] update `eslint`\n  - [Refactor] Update `is-callable` implementation to match latest\n  - [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `jscs`\n\n4.5.4\n  - [Fix] careless error from 5cf99aca49e59bae03b5d542381424bb1b13ec42\n\n4.5.3\n  - [Fix] Saturday is a day in the week (#386)\n  - [Robustness] improve Function#bind (#381)\n  - [Tests] on `node` `v5.6`, `v4.3`\n  - [Tests] use json3 (#382)\n  - [Dev Deps] update `eslint`, `@ljharb/eslint-config`\n  - [Docs] add note about script order (#379)\n\n4.5.2\n  - [shim: fix] use `Array#slice`, not `String#slice`, on `String#split` output (#380)\n\n4.5.1\n  - [Fix] Make sure preexisting + broken `Array#` methods that throw don’t break the runtime (#377)\n  - [Dev Deps] update `jscs`\n\n4.5.0\n  - [New] `parseFloat('-0')` should return -0 in Opera 12 (#371)\n  - [New] Provide and replace Date UTC methods (#360)\n  - [Robustness] cache `Date` getUTC methods so that `Date#toISOString` doesn’t observably look them up on the receiver\n  - [Robustness] use a cached and shimmed `String#trim`\n  - [Tests] up to `node` `v5.5`\n  - [Tests] add `parallelshell` and use it in a few tasks\n  - [Refactor] rename cached methods to avoid linter warnings\n  - [Dev Deps] update `eslint`, `jscs`, '@ljharb/eslint-config'\n  - [Docs] Update license year to 2016 (#374)\n\n4.4.2\n  - [shim: fix] use `Array#slice`, not `String#slice`, on `String#split` output (#380)\n\n4.4.1\n  - [Fix] ensure that IE 11 in compatibility mode doesn't throw (#370)\n  - [Docs] add missing shimmed things\n\n4.4.0\n  - [New] Detect and patch `RegExp#toString` in IE 8, which returns flags in the wrong order (#364)\n  - [Fix] Patch `Array#sort` on {Chrome, Safari, IE < 9, FF 4} that throws improperly, per ES5 (#354)\n  - [Fix] In IE 6, `window.external` makes `Object.keys` throw\n  - [Fix] `Array#slice`: boxed string access on IE <= 8 (#349)\n  - [Fix] `Array#join`: fix IE 6-8 join called on string literal (#352)\n  - [Fix] Ensure that `Error#message` and `Error#name` are non-enumerable (#358)\n  - [Fix: sham] `Object.getOwnPropertyDescriptor`: In Opera 11.6, `propertyIsEnumerable` is a nonshadowable global, like `toString`\n  - [Robustness] Use a bound form of `Array#slice.call`\n  - [Tests] Properly check for descriptor support in IE <= 8\n  - [Tests] on `node` `v5.1`\n  - [Tests] Add `Array#slice` tests (#346)\n  - [Dev Deps] update `uglify-js`, `eslint`, `jscs`, `uglify-js`, `semver`\n  - [Docs] Fix broken UMD links (#344)\n\n4.3.2\n  - [shim: fix] use `Array#slice`, not `String#slice`, on `String#split` output (#380)\n\n4.3.1\n  - [Fix] `String#split`: revert part of dcce96ae21185a69d2d40e67416e7496b73e8e47 which broke in older browsers (#342)\n  - [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `jscs`\n  - [Tests] Firefox allows `Number#toPrecision` values of [1,100], which the spec permits\n\n4.3.0\n  - [New] `Array#push`: in IE <= 7, `Array#push` was not generic (#336)\n  - [New] `Array#push` in Opera `10.6` has a super weird bug when pushing `undefined`\n  - [New] `Array#join`: In IE <= 7, passing `undefined` didn't use the default separator (#333)\n  - [New] `Error#toString`: prints out the proper message in IE 7 and below (#334)\n  - [New] `Number#toPrecision`: IE 7 and below incorrectly throw when an explicit `undefined` precision is passed (#340)\n  - [Fix] `String#lastIndexOf`: ensure the correct length in IE 8\n  - [Fix] ensure `parseInt` accepts negative and plus-prefixed hex values (#332)\n  - [Robustness] Use a bound `Array#push` instead of relying on `Function#call`\n  - [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `jscs`\n  - [Tests] Add some conditionals to avoid impossible-to-fix test failures in IE 6-8, due to it being unable to distinguish between `undefined` and an absent index (#114)\n  - [Tests] Fix false negatives in IE 6-8 with jasmine comparing arrays to arraylikes (#114)\n  - [Tests] add additional `Array#shift` tests (#337)\n  - [Tests] Add additional `Array#splice` tests (#339)\n  - [Tests] Add `Array#pop` tests, just in case (#338)\n  - [Tests] include `global` tests in HTML test files\n  - [Tests] Make sure the HTML tests run with the right charset\n  - [Tests] ensure `node` `v0.8` tests stay passing.\n  - [Tests] Prevent nondeterminism in the tests - this sometime produced values that are one ms off\n  - [Tests] on `node` `v5.0`\n  - [Tests] fix npm upgrades for older nodes\n\n4.2.1\n  - [shim: fix] use `Array#slice`, not `String#slice`, on `String#split` output (#380)\n\n4.2.0\n  - [shim: new] Overwrite `String#lastIndexOf` in IE 9, 10, 11, and Edge, so it has proper unicode support.\n  - [Dev Deps] update `eslint`, `jscs`\n\n4.1.16\n  - [shim: fix] use `Array#slice`, not `String#slice`, on `String#split` output (#380)\n\n4.1.15\n  - [shim: fix] new Date + Date.parse: Fix a Safari 8 & 9 bug where the `ms` arg is treated as a signed instead of unsigned int (#329)\n  - [shim: fix] add 'frame' to blacklisted keys (#330)\n  - [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `jscs`, `uglify-js`\n  - [Tests] on `node` `v4.2`\n  - [Tests] Date: prevent nondeterminism in the tests - this sometime produced values that are one ms off\n\n4.1.14\n  - [shim: fix] Wrap more things in a try/catch, because IE sucks and sometimes throws on [[Get]] of window.localStorage (#327)\n  - [Refactor] Use `ES.ToUint32` instead of inline `>>>`\n  - [Tests] up to `node` `v4.1`\n  - [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `semver`, `jscs`\n\n4.1.13\n  - [shim: fix] Fix a bug where `Date(x)` threw instead of equalling `String(Date(x))` (#326)\n\n4.1.12\n  - [fix] Make sure uglify doesn't remove function names\n  - [shim: fix] Use `is-arguments` implementation; don't call down legacy code path in modern engines (#325)\n  - [Tests] up to `io.js` `v3.3`\n  - [Dev Deps] update `eslint`, `@ljharb/eslint-config`\n\n4.1.11\n  - [shim: fix] Object.keys in Safari 9 has some bugs. (Already fixed in Webkit Nightly)\n  - [shim: fix] Omit !Date.parse check in the if statement (#323)\n  - [sham: fix] Fix Object.create sham to not set __proto__ (#301)\n  - [sham: fix] Add a typeof check to Object.getPrototypeOf (#319, #320)\n  - [Tests] up to `io.js` `v3.1`\n  - [Tests] Make sure `Object.getPrototypeOf` tests don't fail when engines implement ES6 semantics\n  - [Docs] Switch from vb.teelaun.ch to versionbadg.es for the npm version badge SVG (#318)\n  - [Dev Deps] Update `eslint`, `uglify-js`, `jscs`; use my personal shared `eslint` config\n\n4.1.10\n  - [Fix] Fix IE 8 issue with `window.frameElement` access in a child iframe (#322)\n  - [Tests] Consolidating `Date.parse` extended year tests\n  - [Tests] Account for a `Date.parse` precision variance in Safari 8\n  - [Tests] DRY up some Date.parse tests\n  - [Tests] Don't create globals in Date tests\n  - [Tests] Better failure output when an invalid date's toJSON throws\n  - [Tests] Also compare lengths of array-likes\n  - [Tests] Extra check on Object.keys(arguments)\n  - [Tests] Skip appropriate tests when objects aren't extensible/freezeable/sealable\n\n4.1.9\n  - [Fix] Remove \"extended\", add \"unicode\" in `String#split` shim, to match ES6\n  - [Fix] Object.keys: Preserve the IE 8 dontEnum bugfix, and the automation equality bugfix.\n  - [Fix] Object.keys: Prevent a deprecation message from showing up in Chrome.\n  - [Performance] Speed up blacklisted key check for Object.keys automation equality bug.\n  - [Tests] Test on `io.js` `v2.4`\n  - [Dev Deps] Update `eslint`, `semver`\n\n4.1.8\n  - [Fix] Fix an `Object.keys` IE 8 bug where `localStorage.prototype.constructor === localStorage` would throw (#275)\n  - [Fix] Shimmed `Object.defineProperty` should not throw for an empty descriptor (#315)\n  - [Fix] Fix `Date#toISOString` in Safari 5.1 (#243)\n  - [Fix] Use `Object#propertyIsEnumerable` to default the initial \"enumerable\" value in `Object.getOwnPropertyDescriptor` sham (#289)\n  - [Fix] Fix `Array#splice` with large sparse arrays in Safari 7/8, and Opera 12.15 (#295)\n  - [Robustness] Safely use and reference many builtins internally (also see #313)\n  - [Tests] Add `Date#{getUTCDate,getUTCMonth}` tests to expose Opera 10.6/11.61/12 `Date` bugs\n  - [Dev Deps] Update `eslint`\n\n4.1.7\n  - Make sure `Date.parse` is not enumerable (#310)\n\n4.1.6\n  - Support IE 8 when `document.domain` is set (#306, #150)\n  - Remove version from `bower.json` (#307)\n\n4.1.5\n  - Add a failing runtime check for Safari 8 `Date.parse`\n  - Update `eslint`, `semver`\n  - Test on `io.js` `v2.2`\n\n4.1.4\n  - Make sure copied `Date` properties remain non-enumerable.\n  - Using a more reliable check for supported property descriptors in non-IE ES3\n  - Fix 'constructor' in Object.defineProperties sham in ES3 (#252, #305)\n  - Use a reference to `Array#concat` rather than relying on the runtime environment's `concat`.\n  - Test on `io.js` `v2.1`\n  - Clean up `Array.prototype` iteration methods\n\n4.1.3\n  - Update `license` in `package.json` per https://docs.npmjs.com/files/package.json#license\n  - Update `uglify-js`, `eslint`\n\n4.1.2\n  - In IE 6-8, `Date` inside the function expression does not reference `DateShim` (#303)\n  - Date: Ensure all code paths have the correct `constructor` property\n  - Date: Don't copy non-own properties from original `Date`\n  - Test up to `io.js` `v2.0.0`\n  - Simplify `isPrimitive` check.\n  - Adding sanity check tests for ES5 `Number` constants.\n  - Update `uglify-js`, `eslint`, `semver`\n\n4.1.1\n  - Fix name of `parseInt` replacement.\n  - Update copyright year\n  - Update `eslint`, `jscs`\n  - Lock `uglify-js` down to v2.4.17, since v2.4.18 and v2.4.19 have a breaking change.\n  - All grade A-supported `node`/`iojs` versions now ship with an `npm` that understands `^`.\n  - Run `travis-ci` tests on latest `node` and `iojs`; speed up builds; allow 0.8 failures.\n  - Ensure some Object tests don't fail in ES6\n  - Make sure `Date` instances don't have an enumerable `constructor` property, when possible.\n\n4.1.0\n  - Update `eslint`\n  - Improve type checks: `Array.isArray`, `isRegex`\n  - Replace `isRegex`/`isString`/`isCallable` checks with inlined versions from npm modules\n  - Note which ES abstract methods are replaceable via `es-abstract`\n  - Run `travis-ci` tests on `iojs`!\n\n4.0.6\n  - Update `jscs`, `uglify-js`, add `eslint`\n  - es5-sham: fix Object.defineProperty to not check for own properties (#211)\n  - Fix Array#splice bug in Safari 5 (#284)\n  - Fix `Object.keys` issue with boxed primitives with extra properties in older browsers. (#242, #285)\n\n4.0.5\n  - Update `jscs` so tests pass\n\n4.0.4\n  - Style/indentation/whitespace cleanups.\n  - README tweaks\n\n4.0.3\n  - Fix keywords (#268)\n  - add some Date tests\n  - Note in README that the es5-sham requires the es5-shim (https://github.com/es-shims/es5-shim/issues/256#issuecomment-52875710)\n\n4.0.2\n  - Start including version numbers in minified files (#267)\n\n4.0.1\n  - Fix legacy arguments object detection in Object.keys (#260)\n\n4.0.0\n  - No longer shim the ES5-spec behavior of splice when `deleteCount` is omitted - since no engines implement it, and ES6 changes it. (#255)\n  - Use Object.defineProperty where available, so that polyfills are non-enumerable when possible (#250)\n  - lots of internal refactoring\n  - Fixed a bug referencing String#indexOf and String#lastIndexOf before polyfilling it (#253, #254)\n\n3.4.0\n  - Removed nonstandard SpiderMonkey extension to Array#splice - when `deleteCount` is omitted, it's now treated as 0. (#192, #239)\n  - Fix Object.keys with Arguments objects in Safari 5.0\n  - Now shimming String#split in Opera 10.6\n  - Avoid using \"toString\" as a variable name, since that breaks Opera\n  - Internal implementation and test cleanups\n\n3.3.2\n - Remove an internal \"bind\" call, which should make the shim a bit faster\n - Fix a bug with object boxing in Array#reduceRight that was failing a test in IE 6\n\n3.3.1\n - Fixing an Array#splice bug in IE 6/7\n - cleaning up Array#splice tests\n\n3.3.0\n - Fix Array#reduceRight in node 0.6 and older browsers (#238)\n\n3.2.0\n - Fix es5-sham UMD definition to work properly with AMD (#237)\n - Ensure that Array methods do not autobox context in strict mode (#233)\n\n3.1.1\n - Update minified files (#231)\n\n3.1.0\n - Fix String#replace in Firefox up through 29 (#228)\n\n3.0.2\n - Fix `Function#bind` in IE 7 and 8 (#224, #225, #226)\n\n3.0.1\n - Version bump to ensure npm has newest minified assets\n\n3.0.0\n - es5-sham: fix `Object.getPrototypeOf` and `Object.getOwnPropertyDescriptor` for Opera Mini\n - Better override noncompliant native ES5 methods: `Array#forEach`, `Array#map`, `Array#filter`, `Array#every`, `Array#some`, `Array#reduce`, `Date.parse`, `String#trim`\n - Added spec-compliant shim for `parseInt`\n - Ensure `Object.keys` handles more edge cases with `arguments` objects and boxed primitives\n - Improve minification of builds\n\n2.3.0\n - parseInt is now properly shimmed in ES3 browsers to default the radix\n - update URLs to point to the new organization\n\n2.2.0\n - Function.prototype.bind shim now reports correct length on a bound function\n - fix node 0.6.x v8 bug in Array#forEach\n - test improvements\n\n2.1.0\n - Object.create fixes\n - tweaks to the Object.defineProperties shim\n\n2.0.0\n - Separate reliable shims from dubious shims (shams).\n\n1.2.10\n - Group-effort Style Cleanup\n - Took a stab at fixing Object.defineProperty on IE8 without\n   bad side-effects. (@hax)\n - Object.isExtensible no longer fakes it. (@xavierm)\n - Date.prototype.toISOString no longer deals with partial\n   ISO dates, per spec (@kitcambridge)\n - More (mostly from @bryanforbes)\n\n1.2.9\n - Corrections to toISOString by @kitcambridge\n - Fixed three bugs in array methods revealed by Jasmine tests.\n - Cleaned up Function.prototype.bind with more fixes and tests from\n   @bryanforbes.\n\n1.2.8\n - Actually fixed problems with Function.prototype.bind, and regressions\n   from 1.2.7 (@bryanforbes, @jdalton #36)\n\n1.2.7 - REGRESSED\n - Fixed problems with Function.prototype.bind when called as a constructor.\n   (@jdalton #36)\n\n1.2.6\n - Revised Date.parse to match ES 5.1 (kitcambridge)\n\n1.2.5\n - Fixed a bug for padding it Date..toISOString (tadfisher issue #33)\n\n1.2.4\n - Fixed a descriptor bug in Object.defineProperty (raynos)\n\n1.2.3\n - Cleaned up RequireJS and <script> boilerplate\n\n1.2.2\n - Changed reduce to follow the letter of the spec with regard to having and\n   owning properties.\n - Fixed a bug where RegExps pass as Functions in some engines in reduce.\n\n1.2.1\n - Adding few fixes to make jshint happy.\n - Fix for issue #12, function expressions can cause scoping issues in IE.\n - NPM will minify on install or when `npm run-script install` is executed.\n - Adding .gitignore to avoid publishing dev dependencies.\n\n1.2.0\n - Making script loadable as AMD module.\n - Adding `indexOf` to the list of safe shims.\n\n1.1.0\n - Added support for accessor properties where possible (which is all browsers\n   except IE).\n - Stop exposing bound function's (that are returned by\n   `Function.prototype.bind`) internal properties (`bound, boundTo, boundArgs`)\n   as in some cases (when using facade objects for example) capabilities of the\n   enclosed functions will be leaked.\n - `Object.create` now explicitly sets `__proto__` property to guarantee\n   correct behavior of `Object.getPrototypeOf`'s on all objects created using\n   `Object.create`.\n - Switched to `===` from `==` where possible as it's slightly faster on older\n   browsers that are target of this lib.\n - Added names to all anonymous functions to have a better stack traces.\n\n1.0.0\n - fixed Date.toISODate, using UTC accessors, as in\n   http://code.google.com/p/v8/source/browse/trunk/src/date.js?r=6120#986\n   (arian)\n\n0.0.4\n - Revised Object.getPrototypeOf to work in more cases\n   in response to https://johnresig.com/blog/objectgetprototypeof/\n   [issue #2] (fschaefer)\n\n0.0.3\n - Fixed typos in Object.keys (samsonjs)\n\n0.0.2\n   Per kangax's recommendations:\n - faster Object.create(null)\n - fixed a function-scope function declaration statement in Object.create\n\n0.0.1\n - fixed Object.create(null), in so far as that's possible\n - reworked Rhino Object.freeze(Function) bug detector and patcher\n\n0.0.0\n - forked from narwhal-lib\n\n"
  },
  {
    "path": "CONTRIBUTORS.md",
    "content": "\n-   kriskowal Kris Kowal Copyright (C) 2009-2011 MIT License\n-   tlrobinson Tom Robinson Copyright (C) 2009-2010 MIT License (Narwhal\n    Project)\n-   dantman Daniel Friesen Copyright (C) 2010 XXX TODO License or CLA\n-   fschaefer Florian Schäfer Copyright (C) 2010 MIT License\n-   Gozala Irakli Gozalishvili Copyright (C) 2010 MIT License\n-   kitcambridge Kit Cambridge Copyright (C) 2011 MIT License\n-   kossnocorp Sasha Koss XXX TODO License or CLA\n-   bryanforbes Bryan Forbes XXX TODO License or CLA\n-   killdream Quildreen Motta Copyright (C) 2011 MIT Licence\n-   michaelficarra Michael Ficarra Copyright (C) 2011 3-clause BSD\n    License\n-   sharkbrainguy Gerard Paapu Copyright (C) 2011 MIT License\n-   bbqsrc Brendan Molloy (C) 2011 Creative Commons Zero (public domain)\n-   iwyg XXX TODO License or CLA\n-   DomenicDenicola Domenic Denicola Copyright (C) 2011 MIT License\n-   xavierm02 Montillet Xavier Copyright (C) 2011 MIT License\n-   Raynos Jake Verbaten Copyright (C) 2011 MIT Licence\n-   samsonjs Sami Samhuri Copyright (C) 2010 MIT License\n-   rwldrn Rick Waldron Copyright (C) 2011 MIT License\n-   lexer Alexey Zakharov XXX TODO License or CLA\n-   280 North Inc. (Now Motorola LLC, a subsidiary of Google Inc.)\n    Copyright (C) 2009 MIT License\n-   Steven Levithan Copyright (C) 2012 MIT License\n-   Jordan Harband (C) 2013 MIT License\n\n"
  },
  {
    "path": "LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (C) 2009-2016 Kristopher Michael Kowal and contributors\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n"
  },
  {
    "path": "README.md",
    "content": "# es5-shim <sup>[![Version Badge][npm-version-svg]][package-url]</sup>\n\n[![github actions][actions-image]][actions-url]\n[![coverage][codecov-image]][codecov-url]\n[![dependency status][deps-svg]][deps-url]\n[![dev dependency status][dev-deps-svg]][dev-deps-url]\n[![License][license-image]][license-url]\n[![Downloads][downloads-image]][downloads-url]\n\n[![npm badge][npm-badge-png]][package-url]\n\n`es5-shim.js` and `es5-shim.min.js` monkey-patch a JavaScript context to\ncontain all EcmaScript 5 methods that can be faithfully emulated with a\nlegacy JavaScript engine.\n**Note:** As `es5-shim.js` is designed to patch the native Javascript\nengine, it should be the library that is loaded first.\n\n`es5-sham.js` and `es5-sham.min.js` monkey-patch other ES5 methods as\nclosely as possible.  For these methods, as closely as possible to ES5\nis not very close.  Many of these shams are intended only to allow code\nto be written to ES5 without causing run-time errors in older engines.\nIn many cases, this means that these shams cause many ES5 methods to\nsilently fail.  Decide carefully whether this is what you want.\n**Note:** `es5-sham.js` requires `es5-shim.js` to be able to work properly.\n\n## Tests\n\nThe tests are written with the Jasmine BDD test framework.\nTo run the tests, navigate to <root-folder>/tests/ , or,\nsimply `npm install` and `npm test`.\n\n## Shims\n\n### Complete tests ###\n\n* Array.prototype.every ([standalone shim](https://www.npmjs.com/package/array.prototype.every))\n* Array.prototype.filter ([standalone shim](https://www.npmjs.com/package/array.prototype.filter))\n* Array.prototype.forEach ([standalone shim](https://www.npmjs.com/package/array.prototype.foreach))\n* Array.prototype.indexOf ([standalone shim](https://www.npmjs.com/package/array.prototype.indexof))\n* Array.prototype.lastIndexOf ([standalone shim](https://www.npmjs.com/package/array.prototype.lastindexof))\n* Array.prototype.map ([standalone shim](https://www.npmjs.com/package/array.prototype.map))\n* Array.prototype.slice\n* Array.prototype.some ([standalone shim](https://www.npmjs.com/package/array.prototype.some))\n* Array.prototype.sort\n* Array.prototype.reduce ([standalone shim](https://www.npmjs.com/package/array.prototype.reduce))\n* Array.prototype.reduceRight ([standalone shim](https://www.npmjs.com/package/array.prototype.reduceright))\n* Array.prototype.push ([standalone shim](https://www.npmjs.com/package/array.prototype.push))\n* Array.prototype.join\n* Array.prototype.splice ([standalone shim](https://www.npmjs.com/package/array.prototype.splice))\n* Array.isArray\n* Date.now ([standalone shim](https://www.npmjs.com/package/date))\n* Date.prototype.toJSON ([standalone shim](https://www.npmjs.com/package/date))\n* Function.prototype.bind\n    * :warning: Caveat: the bound function has a prototype property.\n    * :warning: Caveat: bound functions do not try too hard to keep you\n      from manipulating their ``arguments`` and ``caller`` properties.\n    * :warning: Caveat: bound functions don't have checks in ``call`` and\n      ``apply`` to avoid executing as a constructor.\n* Number.prototype.toExponential ([standalone shim](https://www.npmjs.com/package/number.prototype.toexponential))\n* Number.prototype.toFixed\n* Number.prototype.toPrecision\n* Object.keys ([standalone shim](https://www.npmjs.com/package/object-keys))\n* String.prototype.split ([standalone shim](https://www.npmjs.com/package/string.prototype.split))\n* String.prototype.trim ([standalone shim](https://www.npmjs.com/package/string.prototype.trim))\n* String.prototype.lastIndexOf ([standalone shim](https://www.npmjs.com/package/string.prototype.lastindexof))\n* String.prototype.replace\n    * Firefox (through v29) natively handles capturing groups incorrectly.\n* Date.parse (for ISO parsing) ([standalone shim](https://www.npmjs.com/package/date))\n* Date.prototype.toISOString ([standalone shim](https://www.npmjs.com/package/date))\n* parseInt ([standalone shim](https://www.npmjs.com/package/parseint))\n* parseFloat\n* Error.prototype.toString\n* Error.prototype.name\n* Error.prototype.message\n* RegExp.prototype.toString\n\n## Shams\n\n* :warning: Object.create\n\n    For the case of simply \"begetting\" an object that inherits\n    prototypically from another, this should work fine across legacy\n    engines.\n\n    :warning: The second argument is passed to Object.defineProperties\n    which will probably fail either silently or with extreme prejudice.\n\n* :warning: Object.getPrototypeOf\n\n    This will return \"undefined\" in some cases.  It uses `__proto__` if\n    it's available.  Failing that, it uses constructor.prototype, which\n    depends on the constructor property of the object's prototype having\n    not been replaced.  If your object was created like this, it won't\n    work:\n\n        function Foo() {\n        }\n        Foo.prototype = {};\n\n    Because the prototype reassignment destroys the constructor\n    property.\n\n    This will work for all objects that were created using\n    `Object.create` implemented with this library.\n\n* :warning: Object.getOwnPropertyNames\n\n    This method uses Object.keys, so it will not be accurate on legacy\n    engines.\n\n* Object.isSealed\n\n    Returns \"false\" in all legacy engines for all objects, which is\n    conveniently guaranteed to be accurate.\n\n* Object.isFrozen\n\n    Returns \"false\" in all legacy engines for all objects, which is\n    conveniently guaranteed to be accurate.\n\n* Object.isExtensible\n\n    Works like a charm, by trying very hard to extend the object then\n    redacting the extension.\n\n### May fail\n\n* :warning: Object.getOwnPropertyDescriptor\n\n    The behavior of this shim does not conform to ES5.  It should\n    probably not be used at this time, until its behavior has been\n    reviewed and been confirmed to be useful in legacy engines.\n\n* :warning: Object.defineProperty\n\n    In the worst of circumstances, IE 8 provides a version of this\n    method that only works on DOM objects.  This sham will not be\n    installed.  The given version of `defineProperty` will throw an\n    exception if used on non-DOM objects.\n\n    In slightly better circumstances, this method will silently fail to\n    set \"writable\", \"enumerable\", and \"configurable\" properties.\n\n    Providing a getter or setter with \"get\" or \"set\" on a descriptor\n    will silently fail on engines that lack \"__defineGetter__\" and\n    \"__defineSetter__\", which include all versions of IE.\n\n    https://github.com/es-shims/es5-shim/issues#issue/5\n\n* :warning: Object.defineProperties\n\n    This uses the Object.defineProperty shim.\n\n* Object.seal\n\n    Silently fails on all legacy engines.  This should be\n    fine unless you are depending on the safety and security\n    provisions of this method, which you cannot possibly\n    obtain in legacy engines.\n\n* Object.freeze\n\n    Silently fails on all legacy engines.  This should be\n    fine unless you are depending on the safety and security\n    provisions of this method, which you cannot possibly\n    obtain in legacy engines.\n\n* Object.preventExtensions\n\n    Silently fails on all legacy engines.  This should be\n    fine unless you are depending on the safety and security\n    provisions of this method, which you cannot possibly\n    obtain in legacy engines.\n\n### Example of applying ES compatibility shims in a browser project\n\n```html\n<script src=\"https://cdnjs.cloudflare.com/ajax/libs/es5-shim/4.5.14/es5-shim.min.js\"></script>\n<script src=\"https://cdnjs.cloudflare.com/ajax/libs/es5-shim/4.5.14/es5-sham.min.js\"></script>\n<script src=\"https://cdnjs.cloudflare.com/ajax/libs/json3/3.3.2/json3.min.js\"></script>\n<script src=\"https://cdnjs.cloudflare.com/ajax/libs/es6-shim/0.35.5/es6-shim.min.js\"></script>\n<script src=\"https://cdnjs.cloudflare.com/ajax/libs/es6-shim/0.35.5/es6-sham.min.js\"></script>\n<script src=\"other-libs.js\"></script>\n```\n\n[package-url]: https://npmjs.org/package/es5-shim\n[npm-version-svg]: https://versionbadg.es/es-shims/es5-shim.svg\n[deps-svg]: https://david-dm.org/es-shims/es5-shim.svg\n[deps-url]: https://david-dm.org/es-shims/es5-shim\n[dev-deps-svg]: https://david-dm.org/es-shims/es5-shim/dev-status.svg\n[dev-deps-url]: https://david-dm.org/es-shims/es5-shim#info=devDependencies\n[npm-badge-png]: https://nodei.co/npm/es5-shim.png?downloads=true&stars=true\n[license-image]: https://img.shields.io/npm/l/es5-shim.svg\n[license-url]: LICENSE\n[downloads-image]: https://img.shields.io/npm/dm/es5-shim.svg\n[downloads-url]: https://npm-stat.com/charts.html?package=es5-shim\n[codecov-image]: https://codecov.io/gh/es-shims/es5-shim/branch/main/graphs/badge.svg\n[codecov-url]: https://app.codecov.io/gh/es-shims/es5-shim/\n[actions-image]: https://img.shields.io/github/check-runs/es-shims/es5-shim/master\n[actions-url]: https://github.com/es-shims/es5-shim/actions\n"
  },
  {
    "path": "bower.json",
    "content": "{\n    \"name\": \"es5-shim\",\n    \"main\": \"es5-shim.js\",\n    \"repository\": {\n        \"type\": \"git\",\n        \"url\": \"git://github.com/es-shims/es5-shim\"\n    },\n    \"homepage\": \"https://github.com/es-shims/es5-shim\",\n    \"authors\": [\n        \"Kris Kowal <kris@cixar.com> (https://github.com/kriskowal/)\",\n        \"Sami Samhuri <sami.samhuri@gmail.com> (https://samhuri.net/)\",\n        \"Florian Schäfer <florian.schaefer@gmail.com> (https://github.com/fschaefer)\",\n        \"Irakli Gozalishvili <rfobic@gmail.com> (https://gozala.io)\",\n        \"Kit Cambridge <kitcambridge@gmail.com> (https://github.com/kitcambridge)\",\n        \"Jordan Harband <ljharb@gmail.com> (https://github.com/ljharb/)\"\n    ],\n    \"description\": \"ECMAScript 5 compatibility shims for legacy JavaScript engines\",\n    \"keywords\": [\n        \"shim\",\n        \"es5\",\n        \"es5 shim\",\n        \"javascript\",\n        \"ecmascript\",\n        \"polyfill\"\n    ],\n    \"license\": \"MIT\",\n    \"ignore\": [\n        \"**/.*\",\n        \"node_modules\",\n        \"bower_components\",\n        \"tests\"\n    ]\n}\n"
  },
  {
    "path": "component.json",
    "content": "{\n    \"name\": \"es5-shim\",\n    \"repo\": \"es-shims/es5-shim\",\n    \"description\": \"ECMAScript 5 compatibility shims for legacy JavaScript engines\",\n    \"version\": \"v4.5.1\",\n    \"keywords\": [\n        \"shim\",\n        \"es5\",\n        \"es5 shim\",\n        \"javascript\",\n        \"ecmascript\",\n        \"polyfill\"\n    ],\n    \"license\": \"MIT\",\n    \"main\": \"es5-shim.js\",\n    \"scripts\": [\n        \"es5-shim.js\"\n    ]\n}\n"
  },
  {
    "path": "es5-sham.js",
    "content": "/*!\n * https://github.com/es-shims/es5-shim\n * @license es5-shim Copyright 2009-2020 by contributors, MIT License\n * see https://github.com/es-shims/es5-shim/blob/master/LICENSE\n */\n\n// vim: ts=4 sts=4 sw=4 expandtab\n\n// Add semicolon to prevent IIFE from being passed as argument to concatenated code.\n; // eslint-disable-line no-extra-semi\n\n// UMD (Universal Module Definition)\n// see https://github.com/umdjs/umd/blob/master/templates/returnExports.js\n(function (root, factory) {\n    'use strict';\n\n    /* global define */\n    if (typeof define === 'function' && define.amd) {\n        // AMD. Register as an anonymous module.\n        define(factory);\n    } else if (typeof exports === 'object') {\n        // Node. Does not work with strict CommonJS, but\n        // only CommonJS-like enviroments that support module.exports,\n        // like Node.\n        module.exports = factory();\n    } else {\n        // Browser globals (root is window)\n        root.returnExports = factory(); // eslint-disable-line no-param-reassign\n    }\n}(this, function () {\n\n    var call = Function.call;\n    var prototypeOfObject = Object.prototype;\n    var owns = call.bind(prototypeOfObject.hasOwnProperty);\n    var isEnumerable = call.bind(prototypeOfObject.propertyIsEnumerable);\n    var toStr = call.bind(prototypeOfObject.toString);\n\n    // If JS engine supports accessors creating shortcuts.\n    var defineGetter;\n    var defineSetter;\n    var lookupGetter;\n    var lookupSetter;\n    var supportsAccessors = owns(prototypeOfObject, '__defineGetter__');\n    if (supportsAccessors) {\n        /* eslint-disable no-underscore-dangle, no-restricted-properties */\n        defineGetter = call.bind(prototypeOfObject.__defineGetter__);\n        defineSetter = call.bind(prototypeOfObject.__defineSetter__);\n        lookupGetter = call.bind(prototypeOfObject.__lookupGetter__);\n        lookupSetter = call.bind(prototypeOfObject.__lookupSetter__);\n        /* eslint-enable no-underscore-dangle, no-restricted-properties */\n    }\n\n    var isPrimitive = function isPrimitive(o) {\n        return o == null || (typeof o !== 'object' && typeof o !== 'function');\n    };\n\n    // ES5 15.2.3.2\n    // https://es5.github.io/#x15.2.3.2\n    if (!Object.getPrototypeOf) {\n        // https://github.com/es-shims/es5-shim/issues#issue/2\n        // https://johnresig.com/blog/objectgetprototypeof/\n        // recommended by fschaefer on github\n        //\n        // sure, and webreflection says ^_^\n        // ... this will nerever possibly return null\n        // ... Opera Mini breaks here with infinite loops\n        Object.getPrototypeOf = function getPrototypeOf(object) {\n            // eslint-disable-next-line no-proto\n            var proto = object.__proto__;\n            if (proto || proto == null) { // `undefined` is for pre-proto browsers\n                return proto;\n            } else if (toStr(object.constructor) === '[object Function]') {\n                return object.constructor.prototype;\n            } else if (object instanceof Object) {\n                return prototypeOfObject;\n            }\n            // Correctly return null for Objects created with `Object.create(null)`\n            // (shammed or native) or `{ __proto__: null}`.  Also returns null for\n            // cross-realm objects on browsers that lack `__proto__` support (like\n            // IE <11), but that's the best we can do.\n            return null;\n\n        };\n    }\n\n    // ES5 15.2.3.3\n    // https://es5.github.io/#x15.2.3.3\n\n    // check whether getOwnPropertyDescriptor works if it's given. Otherwise, shim partially.\n    if (Object.defineProperty) {\n        var doesGetOwnPropertyDescriptorWork = function doesGetOwnPropertyDescriptorWork(object) {\n            try {\n                object.sentinel = 0; // eslint-disable-line no-param-reassign\n                return Object.getOwnPropertyDescriptor(object, 'sentinel').value === 0;\n            } catch (exception) {\n                return false;\n            }\n        };\n        var getOwnPropertyDescriptorWorksOnObject = doesGetOwnPropertyDescriptorWork({});\n        var getOwnPropertyDescriptorWorksOnDom = typeof document === 'undefined'\n            || doesGetOwnPropertyDescriptorWork(document.createElement('div'));\n        if (!getOwnPropertyDescriptorWorksOnDom || !getOwnPropertyDescriptorWorksOnObject) {\n            var getOwnPropertyDescriptorFallback = Object.getOwnPropertyDescriptor;\n        }\n    }\n\n    if (!Object.getOwnPropertyDescriptor || getOwnPropertyDescriptorFallback) {\n        var ERR_NON_OBJECT = 'Object.getOwnPropertyDescriptor called on a non-object: ';\n\n        /* eslint-disable no-proto */\n        Object.getOwnPropertyDescriptor = function getOwnPropertyDescriptor(object, property) {\n            if (isPrimitive(object)) {\n                throw new TypeError(ERR_NON_OBJECT + object);\n            }\n\n            // make a valiant attempt to use the real getOwnPropertyDescriptor\n            // for I8's DOM elements.\n            if (getOwnPropertyDescriptorFallback) {\n                try {\n                    return getOwnPropertyDescriptorFallback.call(Object, object, property);\n                } catch (exception) {\n                    // try the shim if the real one doesn't work\n                }\n            }\n\n            var descriptor;\n\n            // If object does not owns property return undefined immediately.\n            if (!owns(object, property)) {\n                return descriptor;\n            }\n\n            // If object has a property then it's for sure `configurable`, and\n            // probably `enumerable`. Detect enumerability though.\n            descriptor = {\n                enumerable: isEnumerable(object, property),\n                configurable: true\n            };\n\n            // If JS engine supports accessor properties then property may be a\n            // getter or setter.\n            if (supportsAccessors) {\n                // Unfortunately `__lookupGetter__` will return a getter even\n                // if object has own non getter property along with a same named\n                // inherited getter. To avoid misbehavior we temporary remove\n                // `__proto__` so that `__lookupGetter__` will return getter only\n                // if it's owned by an object.\n                var prototype = object.__proto__;\n                var notPrototypeOfObject = object !== prototypeOfObject;\n                // avoid recursion problem, breaking in Opera Mini when\n                // Object.getOwnPropertyDescriptor(Object.prototype, 'toString')\n                // or any other Object.prototype accessor\n                if (notPrototypeOfObject) {\n                    object.__proto__ = prototypeOfObject; // eslint-disable-line no-param-reassign\n                }\n\n                var getter = lookupGetter(object, property);\n                var setter = lookupSetter(object, property);\n\n                if (notPrototypeOfObject) {\n                    // Once we have getter and setter we can put values back.\n                    object.__proto__ = prototype; // eslint-disable-line no-param-reassign\n                }\n\n                if (getter || setter) {\n                    if (getter) {\n                        descriptor.get = getter;\n                    }\n                    if (setter) {\n                        descriptor.set = setter;\n                    }\n                    // If it was accessor property we're done and return here\n                    // in order to avoid adding `value` to the descriptor.\n                    return descriptor;\n                }\n            }\n\n            // If we got this far we know that object has an own property that is\n            // not an accessor so we set it as a value and return descriptor.\n            descriptor.value = object[property];\n            descriptor.writable = true;\n            return descriptor;\n        };\n        /* eslint-enable no-proto */\n    }\n\n    // ES5 15.2.3.4\n    // https://es5.github.io/#x15.2.3.4\n    if (!Object.getOwnPropertyNames) {\n        Object.getOwnPropertyNames = function getOwnPropertyNames(object) {\n            return Object.keys(object);\n        };\n    }\n\n    // ES5 15.2.3.5\n    // https://es5.github.io/#x15.2.3.5\n    if (!Object.create) {\n\n        // Contributed by Brandon Benvie, October, 2012\n        var createEmpty;\n        var supportsProto = !({ __proto__: null } instanceof Object);\n        // the following produces false positives\n        // in Opera Mini => not a reliable check\n        // Object.prototype.__proto__ === null\n\n        // Check for document.domain and active x support\n        // No need to use active x approach when document.domain is not set\n        // see https://github.com/es-shims/es5-shim/issues/150\n        // variation of https://github.com/kitcambridge/es5-shim/commit/4f738ac066346\n        /* global ActiveXObject */\n        var shouldUseActiveX = function shouldUseActiveX() {\n            // return early if document.domain not set\n            if (!document.domain) {\n                return false;\n            }\n\n            try {\n                return !!new ActiveXObject('htmlfile');\n            } catch (exception) {\n                return false;\n            }\n        };\n\n        // This supports IE8 when document.domain is used\n        // see https://github.com/es-shims/es5-shim/issues/150\n        // variation of https://github.com/kitcambridge/es5-shim/commit/4f738ac066346\n        var getEmptyViaActiveX = function getEmptyViaActiveX() {\n            var empty;\n            var xDoc;\n\n            xDoc = new ActiveXObject('htmlfile');\n\n            var script = 'script';\n            xDoc.write('<' + script + '></' + script + '>');\n            xDoc.close();\n\n            empty = xDoc.parentWindow.Object.prototype;\n            xDoc = null;\n\n            return empty;\n        };\n\n        // The original implementation using an iframe\n        // before the activex approach was added\n        // see https://github.com/es-shims/es5-shim/issues/150\n        var getEmptyViaIFrame = function getEmptyViaIFrame() {\n            var iframe = document.createElement('iframe');\n            var parent = document.body || document.documentElement;\n            var empty;\n\n            iframe.style.display = 'none';\n            parent.appendChild(iframe);\n            // eslint-disable-next-line no-script-url\n            iframe.src = 'javascript:';\n\n            empty = iframe.contentWindow.Object.prototype;\n            parent.removeChild(iframe);\n            iframe = null;\n\n            return empty;\n        };\n\n        /* global document */\n        if (supportsProto || typeof document === 'undefined') {\n            createEmpty = function () {\n                return { __proto__: null };\n            };\n        } else {\n            // In old IE __proto__ can't be used to manually set `null`, nor does\n            // any other method exist to make an object that inherits from nothing,\n            // aside from Object.prototype itself. Instead, create a new global\n            // object and *steal* its Object.prototype and strip it bare. This is\n            // used as the prototype to create nullary objects.\n            createEmpty = function () {\n                // Determine which approach to use\n                // see https://github.com/es-shims/es5-shim/issues/150\n                var empty = shouldUseActiveX() ? getEmptyViaActiveX() : getEmptyViaIFrame();\n\n                delete empty.constructor;\n                delete empty.hasOwnProperty;\n                delete empty.propertyIsEnumerable;\n                delete empty.isPrototypeOf;\n                delete empty.toLocaleString;\n                delete empty.toString;\n                delete empty.valueOf;\n\n                var Empty = function Empty() {};\n                Empty.prototype = empty;\n                // short-circuit future calls\n                createEmpty = function () {\n                    return new Empty();\n                };\n                return new Empty();\n            };\n        }\n\n        Object.create = function create(prototype, properties) {\n\n            var object;\n            var Type = function Type() {}; // An empty constructor.\n\n            if (prototype === null) {\n                object = createEmpty();\n            } else if (isPrimitive(prototype)) {\n                // In the native implementation `parent` can be `null`\n                // OR *any* `instanceof Object`  (Object|Function|Array|RegExp|etc)\n                // Use `typeof` tho, b/c in old IE, DOM elements are not `instanceof Object`\n                // like they are in modern browsers. Using `Object.create` on DOM elements\n                // is...err...probably inappropriate, but the native version allows for it.\n                throw new TypeError('Object prototype may only be an Object or null'); // same msg as Chrome\n            } else {\n                Type.prototype = prototype;\n                object = new Type();\n                // IE has no built-in implementation of `Object.getPrototypeOf`\n                // neither `__proto__`, but this manually setting `__proto__` will\n                // guarantee that `Object.getPrototypeOf` will work as expected with\n                // objects created using `Object.create`\n                // eslint-disable-next-line no-proto\n                object.__proto__ = prototype;\n            }\n\n            if (properties !== void 0) {\n                Object.defineProperties(object, properties);\n            }\n\n            return object;\n        };\n    }\n\n    // ES5 15.2.3.6\n    // https://es5.github.io/#x15.2.3.6\n\n    // Patch for WebKit and IE8 standard mode\n    // Designed by hax <hax.github.com>\n    // related issue: https://github.com/es-shims/es5-shim/issues#issue/5\n    // IE8 Reference:\n    //     https://msdn.microsoft.com/en-us/library/dd282900.aspx\n    //     https://msdn.microsoft.com/en-us/library/dd229916.aspx\n    // WebKit Bugs:\n    //     https://bugs.webkit.org/show_bug.cgi?id=36423\n\n    var doesDefinePropertyWork = function doesDefinePropertyWork(object) {\n        try {\n            Object.defineProperty(object, 'sentinel', {});\n            return 'sentinel' in object;\n        } catch (exception) {\n            return false;\n        }\n    };\n\n    // check whether defineProperty works if it's given. Otherwise,\n    // shim partially.\n    if (Object.defineProperty) {\n        var definePropertyWorksOnObject = doesDefinePropertyWork({});\n        var definePropertyWorksOnDom = typeof document === 'undefined'\n            || doesDefinePropertyWork(document.createElement('div'));\n        if (!definePropertyWorksOnObject || !definePropertyWorksOnDom) {\n            var definePropertyFallback = Object.defineProperty,\n                definePropertiesFallback = Object.defineProperties;\n        }\n    }\n\n    if (!Object.defineProperty || definePropertyFallback) {\n        var ERR_NON_OBJECT_DESCRIPTOR = 'Property description must be an object: ';\n        var ERR_NON_OBJECT_TARGET = 'Object.defineProperty called on non-object: ';\n        var ERR_ACCESSORS_NOT_SUPPORTED = 'getters & setters can not be defined on this javascript engine';\n\n        Object.defineProperty = function defineProperty(object, property, descriptor) {\n            if (isPrimitive(object)) {\n                throw new TypeError(ERR_NON_OBJECT_TARGET + object);\n            }\n            if (isPrimitive(descriptor)) {\n                throw new TypeError(ERR_NON_OBJECT_DESCRIPTOR + descriptor);\n            }\n            // make a valiant attempt to use the real defineProperty\n            // for I8's DOM elements.\n            if (definePropertyFallback) {\n                try {\n                    return definePropertyFallback.call(Object, object, property, descriptor);\n                } catch (exception) {\n                    // try the shim if the real one doesn't work\n                }\n            }\n\n            // If it's a data property.\n            if ('value' in descriptor) {\n                // fail silently if 'writable', 'enumerable', or 'configurable'\n                // are requested but not supported\n                /*\n                // alternate approach:\n                if ( // can't implement these features; allow false but not true\n                    ('writable' in descriptor && !descriptor.writable) ||\n                    ('enumerable' in descriptor && !descriptor.enumerable) ||\n                    ('configurable' in descriptor && !descriptor.configurable)\n                ))\n                    throw new RangeError(\n                        'This implementation of Object.defineProperty does not support configurable, enumerable, or writable.'\n                    );\n                */\n\n                if (supportsAccessors && (lookupGetter(object, property) || lookupSetter(object, property))) {\n                    // As accessors are supported only on engines implementing\n                    // `__proto__` we can safely override `__proto__` while defining\n                    // a property to make sure that we don't hit an inherited\n                    // accessor.\n                    /* eslint-disable no-proto, no-param-reassign */\n                    var prototype = object.__proto__;\n                    object.__proto__ = prototypeOfObject;\n                    // Deleting a property anyway since getter / setter may be\n                    // defined on object itself.\n                    delete object[property];\n                    object[property] = descriptor.value;\n                    // Setting original `__proto__` back now.\n                    object.__proto__ = prototype;\n                    /* eslint-enable no-proto, no-param-reassign */\n                } else {\n                    object[property] = descriptor.value; // eslint-disable-line no-param-reassign\n                }\n            } else {\n                var hasGetter = 'get' in descriptor;\n                var hasSetter = 'set' in descriptor;\n                if (!supportsAccessors && (hasGetter || hasSetter)) {\n                    throw new TypeError(ERR_ACCESSORS_NOT_SUPPORTED);\n                }\n                // If we got that far then getters and setters can be defined !!\n                if (hasGetter) {\n                    defineGetter(object, property, descriptor.get);\n                }\n                if (hasSetter) {\n                    defineSetter(object, property, descriptor.set);\n                }\n            }\n            return object;\n        };\n    }\n\n    // ES5 15.2.3.7\n    // https://es5.github.io/#x15.2.3.7\n    if (!Object.defineProperties || definePropertiesFallback) {\n        Object.defineProperties = function defineProperties(object, properties) {\n            // make a valiant attempt to use the real defineProperties\n            if (definePropertiesFallback) {\n                try {\n                    return definePropertiesFallback.call(Object, object, properties);\n                } catch (exception) {\n                    // try the shim if the real one doesn't work\n                }\n            }\n\n            Object.keys(properties).forEach(function (property) {\n                if (property !== '__proto__') {\n                    Object.defineProperty(object, property, properties[property]);\n                }\n            });\n            return object;\n        };\n    }\n\n    // ES5 15.2.3.8\n    // https://es5.github.io/#x15.2.3.8\n    if (!Object.seal) {\n        Object.seal = function seal(object) {\n            if (Object(object) !== object) {\n                throw new TypeError('Object.seal can only be called on Objects.');\n            }\n            // this is misleading and breaks feature-detection, but\n            // allows \"securable\" code to \"gracefully\" degrade to working\n            // but insecure code.\n            return object;\n        };\n    }\n\n    // ES5 15.2.3.9\n    // https://es5.github.io/#x15.2.3.9\n    if (!Object.freeze) {\n        Object.freeze = function freeze(object) {\n            if (Object(object) !== object) {\n                throw new TypeError('Object.freeze can only be called on Objects.');\n            }\n            // this is misleading and breaks feature-detection, but\n            // allows \"securable\" code to \"gracefully\" degrade to working\n            // but insecure code.\n            return object;\n        };\n    }\n\n    // detect a Rhino bug and patch it\n    try {\n        Object.freeze(function () {});\n    } catch (exception) {\n        Object.freeze = (function (freezeObject) {\n            return function freeze(object) {\n                if (typeof object === 'function') {\n                    return object;\n                }\n                return freezeObject(object);\n\n            };\n        }(Object.freeze));\n    }\n\n    // ES5 15.2.3.10\n    // https://es5.github.io/#x15.2.3.10\n    if (!Object.preventExtensions) {\n        Object.preventExtensions = function preventExtensions(object) {\n            if (Object(object) !== object) {\n                throw new TypeError('Object.preventExtensions can only be called on Objects.');\n            }\n            // this is misleading and breaks feature-detection, but\n            // allows \"securable\" code to \"gracefully\" degrade to working\n            // but insecure code.\n            return object;\n        };\n    }\n\n    // ES5 15.2.3.11\n    // https://es5.github.io/#x15.2.3.11\n    if (!Object.isSealed) {\n        Object.isSealed = function isSealed(object) {\n            if (Object(object) !== object) {\n                throw new TypeError('Object.isSealed can only be called on Objects.');\n            }\n            return false;\n        };\n    }\n\n    // ES5 15.2.3.12\n    // https://es5.github.io/#x15.2.3.12\n    if (!Object.isFrozen) {\n        Object.isFrozen = function isFrozen(object) {\n            if (Object(object) !== object) {\n                throw new TypeError('Object.isFrozen can only be called on Objects.');\n            }\n            return false;\n        };\n    }\n\n    // ES5 15.2.3.13\n    // https://es5.github.io/#x15.2.3.13\n    if (!Object.isExtensible) {\n        Object.isExtensible = function isExtensible(object) {\n            // 1. If Type(O) is not Object throw a TypeError exception.\n            if (Object(object) !== object) {\n                throw new TypeError('Object.isExtensible can only be called on Objects.');\n            }\n            // 2. Return the Boolean value of the [[Extensible]] internal property of O.\n            var name = '';\n            while (owns(object, name)) {\n                name += '?';\n            }\n            object[name] = true; // eslint-disable-line no-param-reassign\n            var returnValue = owns(object, name);\n            delete object[name]; // eslint-disable-line no-param-reassign\n            return returnValue;\n        };\n    }\n\n}));\n"
  },
  {
    "path": "es5-shim.js",
    "content": "/*!\n * https://github.com/es-shims/es5-shim\n * @license es5-shim Copyright 2009-2020 by contributors, MIT License\n * see https://github.com/es-shims/es5-shim/blob/master/LICENSE\n */\n\n// vim: ts=4 sts=4 sw=4 expandtab\n\n// Add semicolon to prevent IIFE from being passed as argument to concatenated code.\n; // eslint-disable-line no-extra-semi\n\n// UMD (Universal Module Definition)\n// see https://github.com/umdjs/umd/blob/master/templates/returnExports.js\n(function (root, factory) {\n    'use strict';\n\n    /* global define */\n    if (typeof define === 'function' && define.amd) {\n        // AMD. Register as an anonymous module.\n        define(factory);\n    } else if (typeof exports === 'object') {\n        // Node. Does not work with strict CommonJS, but\n        // only CommonJS-like enviroments that support module.exports,\n        // like Node.\n        module.exports = factory();\n    } else {\n        // Browser globals (root is window)\n        root.returnExports = factory(); // eslint-disable-line no-param-reassign\n    }\n}(this, function () {\n    /**\n     * Brings an environment as close to ECMAScript 5 compliance\n     * as is possible with the facilities of erstwhile engines.\n     *\n     * Annotated ES5: https://es5.github.io/ (specific links below)\n     * ES5 Spec: https://www.ecma-international.org/wp-content/uploads/ECMA-262_5.1_edition_june_2011.pdf\n     * Required reading: https://javascriptweblog.wordpress.com/2011/12/05/extending-javascript-natives/\n     */\n\n    // Shortcut to an often accessed properties, in order to avoid multiple\n    // dereference that costs universally. This also holds a reference to known-good\n    // functions.\n    var $Array = Array;\n    var ArrayPrototype = $Array.prototype;\n    var $Object = Object;\n    var ObjectPrototype = $Object.prototype;\n    var $Function = Function;\n    var FunctionPrototype = $Function.prototype;\n    var $String = String;\n    var StringPrototype = $String.prototype;\n    var $Number = Number;\n    var NumberPrototype = $Number.prototype;\n    var array_slice = ArrayPrototype.slice;\n    var array_splice = ArrayPrototype.splice;\n    var array_push = ArrayPrototype.push;\n    var array_unshift = ArrayPrototype.unshift;\n    var array_concat = ArrayPrototype.concat;\n    var array_join = ArrayPrototype.join;\n    var call = FunctionPrototype.call;\n    var apply = FunctionPrototype.apply;\n    var max = Math.max;\n    var min = Math.min;\n    var floor = Math.floor;\n    var abs = Math.abs;\n    var pow = Math.pow;\n    var round = Math.round;\n    var log = Math.log;\n    var LOG10E = Math.LOG10E;\n    var log10 = Math.log10 || function log10(value) {\n        return log(value) * LOG10E;\n    };\n\n    // Having a toString local variable name breaks in Opera so use to_string.\n    var to_string = ObjectPrototype.toString;\n\n    /* eslint-disable one-var-declaration-per-line, no-redeclare, max-statements-per-line */\n    var hasToStringTag = typeof Symbol === 'function' && typeof Symbol.toStringTag === 'symbol';\n    var isCallable; /* inlined from https://npmjs.com/is-callable */ var fnToStr = Function.prototype.toString, constructorRegex = /^\\s*class /, isES6ClassFn = function isES6ClassFn(value) { try { var fnStr = fnToStr.call(value); var singleStripped = fnStr.replace(/\\/\\/.*\\n/g, ''); var multiStripped = singleStripped.replace(/\\/\\*[.\\s\\S]*\\*\\//g, ''); var spaceStripped = multiStripped.replace(/\\n/mg, ' ').replace(/ {2}/g, ' '); return constructorRegex.test(spaceStripped); } catch (e) { return false; /* not a function */ } }, tryFunctionObject = function tryFunctionObject(value) { try { if (isES6ClassFn(value)) { return false; } fnToStr.call(value); return true; } catch (e) { return false; } }, fnClass = '[object Function]', genClass = '[object GeneratorFunction]', isCallable = function isCallable(value) { if (!value) { return false; } if (typeof value !== 'function' && typeof value !== 'object') { return false; } if (hasToStringTag) { return tryFunctionObject(value); } if (isES6ClassFn(value)) { return false; } var strClass = to_string.call(value); return strClass === fnClass || strClass === genClass; };\n\n    var isRegex; /* inlined from https://npmjs.com/is-regex */ var regexExec = RegExp.prototype.exec, tryRegexExec = function tryRegexExec(value) { try { regexExec.call(value); return true; } catch (e) { return false; } }, regexClass = '[object RegExp]'; isRegex = function isRegex(value) { if (typeof value !== 'object') { return false; } return hasToStringTag ? tryRegexExec(value) : to_string.call(value) === regexClass; };\n    var isString; /* inlined from https://npmjs.com/is-string */ var strValue = String.prototype.valueOf, tryStringObject = function tryStringObject(value) { try { strValue.call(value); return true; } catch (e) { return false; } }, stringClass = '[object String]'; isString = function isString(value) { if (typeof value === 'string') { return true; } if (typeof value !== 'object') { return false; } return hasToStringTag ? tryStringObject(value) : to_string.call(value) === stringClass; };\n    /* eslint-enable one-var-declaration-per-line, no-redeclare, max-statements-per-line */\n\n    /* inlined from https://npmjs.com/define-properties */\n    var supportsDescriptors = $Object.defineProperty && (function () {\n        try {\n            var obj = {};\n            $Object.defineProperty(obj, 'x', { enumerable: false, value: obj });\n            // eslint-disable-next-line no-unreachable-loop, max-statements-per-line\n            for (var _ in obj) { return false; } // jscs:ignore disallowUnusedVariables\n            return obj.x === obj;\n        } catch (e) { /* this is ES3 */\n            return false;\n        }\n    }());\n    var defineProperties = (function (has) {\n        // Define configurable, writable, and non-enumerable props\n        // if they don't exist.\n        var defineProperty;\n        if (supportsDescriptors) {\n            defineProperty = function (object, name, method, forceAssign) {\n                if (!forceAssign && (name in object)) {\n                    return;\n                }\n                $Object.defineProperty(object, name, {\n                    configurable: true,\n                    enumerable: false,\n                    writable: true,\n                    value: method\n                });\n            };\n        } else {\n            defineProperty = function (object, name, method, forceAssign) {\n                if (!forceAssign && (name in object)) {\n                    return;\n                }\n                object[name] = method; // eslint-disable-line no-param-reassign\n            };\n        }\n        return function defineProperties(object, map, forceAssign) {\n            for (var name in map) {\n                if (has.call(map, name)) {\n                    defineProperty(object, name, map[name], forceAssign);\n                }\n            }\n        };\n    }(ObjectPrototype.hasOwnProperty));\n\n    // this is needed in Chrome 15 (probably earlier) - 36\n    // https://bugs.chromium.org/p/v8/issues/detail?id=3334\n    if ($Object.defineProperty && supportsDescriptors) {\n        var F = function () {};\n        var toStringSentinel = {};\n        var sentinel = { toString: toStringSentinel };\n        $Object.defineProperty(F, 'prototype', { value: sentinel, writable: false });\n        if ((new F()).toString !== toStringSentinel) {\n            var $dP = $Object.defineProperty;\n            var $gOPD = $Object.getOwnPropertyDescriptor;\n            defineProperties($Object, {\n                defineProperty: function defineProperty(o, k, d) {\n                    var key = $String(k);\n                    if (typeof o === 'function' && key === 'prototype') {\n                        var desc = $gOPD(o, key);\n                        if (desc.writable && !d.writable && 'value' in d) {\n                            try {\n                                o[key] = d.value; // eslint-disable-line no-param-reassign\n                            } catch (e) { /**/ }\n                        }\n                        return $dP(o, key, {\n                            configurable: 'configurable' in d ? d.configurable : desc.configurable,\n                            enumerable: 'enumerable' in d ? d.enumerable : desc.enumerable,\n                            writable: d.writable\n                        });\n                    }\n                    return $dP(o, key, d);\n                }\n            }, true);\n        }\n    }\n\n    //\n    // Util\n    // ======\n    //\n\n    /* replaceable with https://npmjs.com/package/es-abstract /helpers/isPrimitive */\n    var isPrimitive = function isPrimitive(input) {\n        var type = typeof input;\n        return input === null || (type !== 'object' && type !== 'function');\n    };\n\n    var isActualNaN = $Number.isNaN || function isActualNaN(x) {\n        return x !== x;\n    };\n\n    var ES = {\n        // ES5 9.4\n        // https://es5.github.io/#x9.4\n        // http://jsperf.com/to-integer\n        /* replaceable with https://npmjs.com/package/es-abstract ES5.ToInteger */\n        ToInteger: function ToInteger(num) {\n            var n = +num;\n            if (isActualNaN(n)) {\n                n = 0;\n            } else if (n !== 0 && n !== (1 / 0) && n !== -(1 / 0)) {\n                n = (n > 0 || -1) * floor(abs(n));\n            }\n            return n;\n        },\n\n        /* replaceable with https://npmjs.com/package/es-abstract ES5.ToPrimitive */\n        ToPrimitive: function ToPrimitive(input) {\n            var val, valueOf, toStr;\n            if (isPrimitive(input)) {\n                return input;\n            }\n            valueOf = input.valueOf;\n            if (isCallable(valueOf)) {\n                val = valueOf.call(input);\n                if (isPrimitive(val)) {\n                    return val;\n                }\n            }\n            toStr = input.toString;\n            if (isCallable(toStr)) {\n                val = toStr.call(input);\n                if (isPrimitive(val)) {\n                    return val;\n                }\n            }\n            throw new TypeError();\n        },\n\n        // ES5 9.9\n        // https://es5.github.io/#x9.9\n        /* replaceable with https://npmjs.com/package/es-abstract ES5.ToObject */\n        ToObject: function (o) {\n            if (o == null) { // this matches both null and undefined\n                throw new TypeError(\"can't convert \" + o + ' to object');\n            }\n            return $Object(o);\n        },\n\n        /* replaceable with https://npmjs.com/package/es-abstract ES5.ToUint32 */\n        ToUint32: function ToUint32(x) {\n            return x >>> 0;\n        }\n    };\n\n    //\n    // Function\n    // ========\n    //\n\n    // ES-5 15.3.4.5\n    // https://es5.github.io/#x15.3.4.5\n\n    var Empty = function Empty() {};\n\n    defineProperties(FunctionPrototype, {\n        bind: function bind(that) { // .length is 1\n            // 1. Let Target be the this value.\n            var target = this;\n            // 2. If IsCallable(Target) is false, throw a TypeError exception.\n            if (!isCallable(target)) {\n                throw new TypeError('Function.prototype.bind called on incompatible ' + target);\n            }\n            // 3. Let A be a new (possibly empty) internal list of all of the\n            //   argument values provided after thisArg (arg1, arg2 etc), in order.\n            // XXX slicedArgs will stand in for \"A\" if used\n            var args = array_slice.call(arguments, 1); // for normal call\n            // 4. Let F be a new native ECMAScript object.\n            // 11. Set the [[Prototype]] internal property of F to the standard\n            //   built-in Function prototype object as specified in 15.3.3.1.\n            // 12. Set the [[Call]] internal property of F as described in\n            //   15.3.4.5.1.\n            // 13. Set the [[Construct]] internal property of F as described in\n            //   15.3.4.5.2.\n            // 14. Set the [[HasInstance]] internal property of F as described in\n            //   15.3.4.5.3.\n            var bound;\n            var binder = function () {\n\n                if (this instanceof bound) {\n                    // 15.3.4.5.2 [[Construct]]\n                    // When the [[Construct]] internal method of a function object,\n                    // F that was created using the bind function is called with a\n                    // list of arguments ExtraArgs, the following steps are taken:\n                    // 1. Let target be the value of F's [[TargetFunction]]\n                    //   internal property.\n                    // 2. If target has no [[Construct]] internal method, a\n                    //   TypeError exception is thrown.\n                    // 3. Let boundArgs be the value of F's [[BoundArgs]] internal\n                    //   property.\n                    // 4. Let args be a new list containing the same values as the\n                    //   list boundArgs in the same order followed by the same\n                    //   values as the list ExtraArgs in the same order.\n                    // 5. Return the result of calling the [[Construct]] internal\n                    //   method of target providing args as the arguments.\n\n                    var result = apply.call(\n                        target,\n                        this,\n                        array_concat.call(args, array_slice.call(arguments))\n                    );\n                    if ($Object(result) === result) {\n                        return result;\n                    }\n                    return this;\n\n                }\n                // 15.3.4.5.1 [[Call]]\n                // When the [[Call]] internal method of a function object, F,\n                // which was created using the bind function is called with a\n                // this value and a list of arguments ExtraArgs, the following\n                // steps are taken:\n                // 1. Let boundArgs be the value of F's [[BoundArgs]] internal\n                //   property.\n                // 2. Let boundThis be the value of F's [[BoundThis]] internal\n                //   property.\n                // 3. Let target be the value of F's [[TargetFunction]] internal\n                //   property.\n                // 4. Let args be a new list containing the same values as the\n                //   list boundArgs in the same order followed by the same\n                //   values as the list ExtraArgs in the same order.\n                // 5. Return the result of calling the [[Call]] internal method\n                //   of target providing boundThis as the this value and\n                //   providing args as the arguments.\n\n                // equiv: target.call(this, ...boundArgs, ...args)\n                return apply.call(\n                    target,\n                    that,\n                    array_concat.call(args, array_slice.call(arguments))\n                );\n\n            };\n\n            // 15. If the [[Class]] internal property of Target is \"Function\", then\n            //     a. Let L be the length property of Target minus the length of A.\n            //     b. Set the length own property of F to either 0 or L, whichever is\n            //       larger.\n            // 16. Else set the length own property of F to 0.\n\n            var boundLength = max(0, target.length - args.length);\n\n            // 17. Set the attributes of the length own property of F to the values\n            //   specified in 15.3.5.1.\n            var boundArgs = [];\n            for (var i = 0; i < boundLength; i++) {\n                array_push.call(boundArgs, '$' + i);\n            }\n\n            // XXX Build a dynamic function with desired amount of arguments is the only\n            // way to set the length property of a function.\n            // In environments where Content Security Policies enabled (Chrome extensions,\n            // for ex.) all use of eval or Function costructor throws an exception.\n            // However in all of these environments Function.prototype.bind exists\n            // and so this code will never be executed.\n            bound = $Function('binder', 'return function (' + array_join.call(boundArgs, ',') + '){ return binder.apply(this, arguments); }')(binder);\n\n            if (target.prototype) {\n                Empty.prototype = target.prototype;\n                bound.prototype = new Empty();\n                // Clean up dangling references.\n                Empty.prototype = null;\n            }\n\n            // TODO\n            // 18. Set the [[Extensible]] internal property of F to true.\n\n            // TODO\n            // 19. Let thrower be the [[ThrowTypeError]] function Object (13.2.3).\n            // 20. Call the [[DefineOwnProperty]] internal method of F with\n            //   arguments \"caller\", PropertyDescriptor {[[Get]]: thrower, [[Set]]:\n            //   thrower, [[Enumerable]]: false, [[Configurable]]: false}, and\n            //   false.\n            // 21. Call the [[DefineOwnProperty]] internal method of F with\n            //   arguments \"arguments\", PropertyDescriptor {[[Get]]: thrower,\n            //   [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: false},\n            //   and false.\n\n            // TODO\n            // NOTE Function objects created using Function.prototype.bind do not\n            // have a prototype property or the [[Code]], [[FormalParameters]], and\n            // [[Scope]] internal properties.\n            // XXX can't delete prototype in pure-js.\n\n            // 22. Return F.\n            return bound;\n        }\n    });\n\n    // _Please note: Shortcuts are defined after `Function.prototype.bind` as we\n    // use it in defining shortcuts.\n    var owns = call.bind(ObjectPrototype.hasOwnProperty);\n    var toStr = call.bind(ObjectPrototype.toString);\n    var arraySlice = call.bind(array_slice);\n    var arraySliceApply = apply.bind(array_slice);\n    /* globals document */\n    if (typeof document === 'object' && document && document.documentElement) {\n        try {\n            arraySlice(document.documentElement.childNodes);\n        } catch (e) {\n            var origArraySlice = arraySlice;\n            var origArraySliceApply = arraySliceApply;\n            arraySlice = function arraySliceIE(arr) {\n                var r = [];\n                var i = arr.length;\n                while (i-- > 0) {\n                    r[i] = arr[i];\n                }\n                return origArraySliceApply(r, origArraySlice(arguments, 1));\n            };\n            arraySliceApply = function arraySliceApplyIE(arr, args) {\n                return origArraySliceApply(arraySlice(arr), args);\n            };\n        }\n    }\n    var strSlice = call.bind(StringPrototype.slice);\n    var strSplit = call.bind(StringPrototype.split);\n    var strIndexOf = call.bind(StringPrototype.indexOf);\n    var pushCall = call.bind(array_push);\n    var isEnum = call.bind(ObjectPrototype.propertyIsEnumerable);\n    var arraySort = call.bind(ArrayPrototype.sort);\n\n    //\n    // Array\n    // =====\n    //\n\n    var isArray = $Array.isArray || function isArray(obj) {\n        return toStr(obj) === '[object Array]';\n    };\n\n    // ES5 15.4.4.12\n    // https://es5.github.io/#x15.4.4.13\n    // Return len+argCount.\n    // [bugfix, ielt8]\n    // IE < 8 bug: [].unshift(0) === undefined but should be \"1\"\n    var hasUnshiftReturnValueBug = [].unshift(0) !== 1;\n    defineProperties(ArrayPrototype, {\n        unshift: function () {\n            array_unshift.apply(this, arguments);\n            return this.length;\n        }\n    }, hasUnshiftReturnValueBug);\n\n    // ES5 15.4.3.2\n    // https://es5.github.io/#x15.4.3.2\n    // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/isArray\n    defineProperties($Array, { isArray: isArray });\n\n    // The IsCallable() check in the Array functions\n    // has been replaced with a strict check on the\n    // internal class of the object to trap cases where\n    // the provided function was actually a regular\n    // expression literal, which in V8 and\n    // JavaScriptCore is a typeof \"function\".  Only in\n    // V8 are regular expression literals permitted as\n    // reduce parameters, so it is desirable in the\n    // general case for the shim to match the more\n    // strict and common behavior of rejecting regular\n    // expressions.\n\n    // ES5 15.4.4.18\n    // https://es5.github.io/#x15.4.4.18\n    // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/forEach\n\n    // Check failure of by-index access of string characters (IE < 9)\n    // and failure of `0 in boxedString` (Rhino)\n    var boxedString = $Object('a');\n    var splitString = boxedString[0] !== 'a' || !(0 in boxedString);\n\n    var properlyBoxesContext = function properlyBoxed(method) {\n        // Check node 0.6.21 bug where third parameter is not boxed\n        var properlyBoxesNonStrict = true;\n        var properlyBoxesStrict = true;\n        var threwException = false;\n        if (method) {\n            try {\n                method.call('foo', function (_, __, context) {\n                    if (typeof context !== 'object') {\n                        properlyBoxesNonStrict = false;\n                    }\n                });\n\n                method.call([1], function () {\n                    'use strict';\n\n                    properlyBoxesStrict = typeof this === 'string';\n                }, 'x');\n            } catch (e) {\n                threwException = true;\n            }\n        }\n        return !!method && !threwException && properlyBoxesNonStrict && properlyBoxesStrict;\n    };\n\n    defineProperties(ArrayPrototype, {\n        forEach: function forEach(callbackfn/*, thisArg*/) {\n            var object = ES.ToObject(this);\n            var self = splitString && isString(this) ? strSplit(this, '') : object;\n            var i = -1;\n            var length = ES.ToUint32(self.length);\n            var T;\n            if (arguments.length > 1) {\n                T = arguments[1];\n            }\n\n            // If no callback function or if callback is not a callable function\n            if (!isCallable(callbackfn)) {\n                throw new TypeError('Array.prototype.forEach callback must be a function');\n            }\n\n            while (++i < length) {\n                if (i in self) {\n                    // Invoke the callback function with call, passing arguments:\n                    // context, property value, property key, thisArg object\n                    if (typeof T === 'undefined') {\n                        callbackfn(self[i], i, object);\n                    } else {\n                        callbackfn.call(T, self[i], i, object);\n                    }\n                }\n            }\n        }\n    }, !properlyBoxesContext(ArrayPrototype.forEach));\n\n    // ES5 15.4.4.19\n    // https://es5.github.io/#x15.4.4.19\n    // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map\n    defineProperties(ArrayPrototype, {\n        map: function map(callbackfn/*, thisArg*/) {\n            var object = ES.ToObject(this);\n            var self = splitString && isString(this) ? strSplit(this, '') : object;\n            var length = ES.ToUint32(self.length);\n            var result = $Array(length);\n            var T;\n            if (arguments.length > 1) {\n                T = arguments[1];\n            }\n\n            // If no callback function or if callback is not a callable function\n            if (!isCallable(callbackfn)) {\n                throw new TypeError('Array.prototype.map callback must be a function');\n            }\n\n            for (var i = 0; i < length; i++) {\n                if (i in self) {\n                    if (typeof T === 'undefined') {\n                        result[i] = callbackfn(self[i], i, object);\n                    } else {\n                        result[i] = callbackfn.call(T, self[i], i, object);\n                    }\n                }\n            }\n            return result;\n        }\n    }, !properlyBoxesContext(ArrayPrototype.map));\n\n    // ES5 15.4.4.20\n    // https://es5.github.io/#x15.4.4.20\n    // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter\n    defineProperties(ArrayPrototype, {\n        filter: function filter(callbackfn/*, thisArg*/) {\n            var object = ES.ToObject(this);\n            var self = splitString && isString(this) ? strSplit(this, '') : object;\n            var length = ES.ToUint32(self.length);\n            var result = [];\n            var value;\n            var T;\n            if (arguments.length > 1) {\n                T = arguments[1];\n            }\n\n            // If no callback function or if callback is not a callable function\n            if (!isCallable(callbackfn)) {\n                throw new TypeError('Array.prototype.filter callback must be a function');\n            }\n\n            for (var i = 0; i < length; i++) {\n                if (i in self) {\n                    value = self[i];\n                    if (typeof T === 'undefined' ? callbackfn(value, i, object) : callbackfn.call(T, value, i, object)) {\n                        pushCall(result, value);\n                    }\n                }\n            }\n            return result;\n        }\n    }, !properlyBoxesContext(ArrayPrototype.filter));\n\n    // ES5 15.4.4.16\n    // https://es5.github.io/#x15.4.4.16\n    // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/every\n    defineProperties(ArrayPrototype, {\n        every: function every(callbackfn/*, thisArg*/) {\n            var object = ES.ToObject(this);\n            var self = splitString && isString(this) ? strSplit(this, '') : object;\n            var length = ES.ToUint32(self.length);\n            var T;\n            if (arguments.length > 1) {\n                T = arguments[1];\n            }\n\n            // If no callback function or if callback is not a callable function\n            if (!isCallable(callbackfn)) {\n                throw new TypeError('Array.prototype.every callback must be a function');\n            }\n\n            for (var i = 0; i < length; i++) {\n                if (i in self && !(typeof T === 'undefined' ? callbackfn(self[i], i, object) : callbackfn.call(T, self[i], i, object))) {\n                    return false;\n                }\n            }\n            return true;\n        }\n    }, !properlyBoxesContext(ArrayPrototype.every));\n\n    // ES5 15.4.4.17\n    // https://es5.github.io/#x15.4.4.17\n    // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/some\n    defineProperties(ArrayPrototype, {\n        some: function some(callbackfn/*, thisArg */) {\n            var object = ES.ToObject(this);\n            var self = splitString && isString(this) ? strSplit(this, '') : object;\n            var length = ES.ToUint32(self.length);\n            var T;\n            if (arguments.length > 1) {\n                T = arguments[1];\n            }\n\n            // If no callback function or if callback is not a callable function\n            if (!isCallable(callbackfn)) {\n                throw new TypeError('Array.prototype.some callback must be a function');\n            }\n\n            for (var i = 0; i < length; i++) {\n                if (i in self && (typeof T === 'undefined' ? callbackfn(self[i], i, object) : callbackfn.call(T, self[i], i, object))) {\n                    return true;\n                }\n            }\n            return false;\n        }\n    }, !properlyBoxesContext(ArrayPrototype.some));\n\n    // ES5 15.4.4.21\n    // https://es5.github.io/#x15.4.4.21\n    // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduce\n    var reduceCoercesToObject = false;\n    if (ArrayPrototype.reduce) {\n        reduceCoercesToObject = typeof ArrayPrototype.reduce.call('es5', function (_, __, ___, list) {\n            return list;\n        }) === 'object';\n    }\n    defineProperties(ArrayPrototype, {\n        reduce: function reduce(callbackfn/*, initialValue*/) {\n            var object = ES.ToObject(this);\n            var self = splitString && isString(this) ? strSplit(this, '') : object;\n            var length = ES.ToUint32(self.length);\n\n            // If no callback function or if callback is not a callable function\n            if (!isCallable(callbackfn)) {\n                throw new TypeError('Array.prototype.reduce callback must be a function');\n            }\n\n            // no value to return if no initial value and an empty array\n            if (length === 0 && arguments.length === 1) {\n                throw new TypeError('reduce of empty array with no initial value');\n            }\n\n            var i = 0;\n            var result;\n            if (arguments.length >= 2) {\n                result = arguments[1];\n            } else {\n                do {\n                    if (i in self) {\n                        result = self[i++];\n                        break;\n                    }\n\n                    // if array contains no values, no initial value to return\n                    if (++i >= length) {\n                        throw new TypeError('reduce of empty array with no initial value');\n                    }\n                } while (true);\n            }\n\n            for (; i < length; i++) {\n                if (i in self) {\n                    result = callbackfn(result, self[i], i, object);\n                }\n            }\n\n            return result;\n        }\n    }, !reduceCoercesToObject);\n\n    // ES5 15.4.4.22\n    // https://es5.github.io/#x15.4.4.22\n    // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduceRight\n    var reduceRightCoercesToObject = false;\n    if (ArrayPrototype.reduceRight) {\n        reduceRightCoercesToObject = typeof ArrayPrototype.reduceRight.call('es5', function (_, __, ___, list) {\n            return list;\n        }) === 'object';\n    }\n    defineProperties(ArrayPrototype, {\n        reduceRight: function reduceRight(callbackfn/*, initial*/) {\n            var object = ES.ToObject(this);\n            var self = splitString && isString(this) ? strSplit(this, '') : object;\n            var length = ES.ToUint32(self.length);\n\n            // If no callback function or if callback is not a callable function\n            if (!isCallable(callbackfn)) {\n                throw new TypeError('Array.prototype.reduceRight callback must be a function');\n            }\n\n            // no value to return if no initial value, empty array\n            if (length === 0 && arguments.length === 1) {\n                throw new TypeError('reduceRight of empty array with no initial value');\n            }\n\n            var result;\n            var i = length - 1;\n            if (arguments.length >= 2) {\n                result = arguments[1];\n            } else {\n                do {\n                    if (i in self) {\n                        result = self[i--];\n                        break;\n                    }\n\n                    // if array contains no values, no initial value to return\n                    if (--i < 0) {\n                        throw new TypeError('reduceRight of empty array with no initial value');\n                    }\n                } while (true);\n            }\n\n            if (i < 0) {\n                return result;\n            }\n\n            do {\n                if (i in self) {\n                    result = callbackfn(result, self[i], i, object);\n                }\n            } while (i--);\n\n            return result;\n        }\n    }, !reduceRightCoercesToObject);\n\n    // ES5 15.4.4.14\n    // https://es5.github.io/#x15.4.4.14\n    // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf\n    var hasFirefox2IndexOfBug = ArrayPrototype.indexOf && [0, 1].indexOf(1, 2) !== -1;\n    defineProperties(ArrayPrototype, {\n        indexOf: function indexOf(searchElement/*, fromIndex */) {\n            var self = splitString && isString(this) ? strSplit(this, '') : ES.ToObject(this);\n            var length = ES.ToUint32(self.length);\n\n            if (length === 0) {\n                return -1;\n            }\n\n            var i = 0;\n            if (arguments.length > 1) {\n                i = ES.ToInteger(arguments[1]);\n            }\n\n            // handle negative indices\n            i = i >= 0 ? i : max(0, length + i);\n            for (; i < length; i++) {\n                if (i in self && self[i] === searchElement) {\n                    return i;\n                }\n            }\n            return -1;\n        }\n    }, hasFirefox2IndexOfBug);\n\n    // ES5 15.4.4.15\n    // https://es5.github.io/#x15.4.4.15\n    // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/lastIndexOf\n    var hasFirefox2LastIndexOfBug = ArrayPrototype.lastIndexOf && [0, 1].lastIndexOf(0, -3) !== -1;\n    defineProperties(ArrayPrototype, {\n        lastIndexOf: function lastIndexOf(searchElement/*, fromIndex */) {\n            var self = splitString && isString(this) ? strSplit(this, '') : ES.ToObject(this);\n            var length = ES.ToUint32(self.length);\n\n            if (length === 0) {\n                return -1;\n            }\n            var i = length - 1;\n            if (arguments.length > 1) {\n                i = min(i, ES.ToInteger(arguments[1]));\n            }\n            // handle negative indices\n            i = i >= 0 ? i : length - abs(i);\n            for (; i >= 0; i--) {\n                if (i in self && searchElement === self[i]) {\n                    return i;\n                }\n            }\n            return -1;\n        }\n    }, hasFirefox2LastIndexOfBug);\n\n    // ES5 15.4.4.12\n    // https://es5.github.io/#x15.4.4.12\n    var spliceNoopReturnsEmptyArray = (function () {\n        var a = [1, 2];\n        var result = a.splice();\n        return a.length === 2 && isArray(result) && result.length === 0;\n    }());\n    defineProperties(ArrayPrototype, {\n        // Safari 5.0 bug where .splice() returns undefined\n        splice: function splice(start, deleteCount) {\n            if (arguments.length === 0) {\n                return [];\n            }\n            return array_splice.apply(this, arguments);\n\n        }\n    }, !spliceNoopReturnsEmptyArray);\n\n    var spliceWorksWithEmptyObject = (function () {\n        var obj = {};\n        ArrayPrototype.splice.call(obj, 0, 0, 1);\n        return obj.length === 1;\n    }());\n    var hasES6Defaults = [0, 1, 2].splice(0).length === 3;\n    defineProperties(ArrayPrototype, {\n        splice: function splice(start, deleteCount) {\n            if (arguments.length === 0) {\n                return [];\n            }\n            var args = arguments;\n            this.length = max(ES.ToInteger(this.length), 0);\n            if (arguments.length > 0 && typeof deleteCount !== 'number') {\n                args = arraySlice(arguments);\n                if (args.length < 2) {\n                    pushCall(args, this.length - start);\n                } else {\n                    args[1] = ES.ToInteger(deleteCount);\n                }\n            }\n            return array_splice.apply(this, args);\n        }\n    }, !spliceWorksWithEmptyObject || !hasES6Defaults);\n    var spliceWorksWithLargeSparseArrays = (function () {\n        // Per https://github.com/es-shims/es5-shim/issues/295\n        // Safari 7/8 breaks with sparse arrays of size 1e5 or greater\n        var arr = new $Array(1e5);\n        // note: the index MUST be 8 or larger or the test will false pass\n        arr[8] = 'x';\n        arr.splice(1, 1);\n        // note: this test must be defined *after* the indexOf shim\n        // per https://github.com/es-shims/es5-shim/issues/313\n        return arr.indexOf('x') === 7;\n    }());\n    var spliceWorksWithSmallSparseArrays = (function () {\n        // Per https://github.com/es-shims/es5-shim/issues/295\n        // Opera 12.15 breaks on this, no idea why.\n        var n = 256;\n        var arr = [];\n        arr[n] = 'a';\n        arr.splice(n + 1, 0, 'b');\n        return arr[n] === 'a';\n    }());\n    defineProperties(ArrayPrototype, {\n        splice: function splice(start, deleteCount) {\n            var O = ES.ToObject(this);\n            var A = [];\n            var len = ES.ToUint32(O.length);\n            var relativeStart = ES.ToInteger(start);\n            var actualStart = relativeStart < 0 ? max((len + relativeStart), 0) : min(relativeStart, len);\n            var actualDeleteCount = arguments.length === 0\n                ? 0\n                : arguments.length === 1\n                    ? len - actualStart\n                    : min(max(ES.ToInteger(deleteCount), 0), len - actualStart);\n\n            var k = 0;\n            var from;\n            while (k < actualDeleteCount) {\n                from = $String(actualStart + k);\n                if (owns(O, from)) {\n                    A[k] = O[from];\n                }\n                k += 1;\n            }\n\n            var items = arraySlice(arguments, 2);\n            var itemCount = items.length;\n            var to;\n            if (itemCount < actualDeleteCount) {\n                k = actualStart;\n                var maxK = len - actualDeleteCount;\n                while (k < maxK) {\n                    from = $String(k + actualDeleteCount);\n                    to = $String(k + itemCount);\n                    if (owns(O, from)) {\n                        O[to] = O[from];\n                    } else {\n                        delete O[to];\n                    }\n                    k += 1;\n                }\n                k = len;\n                var minK = len - actualDeleteCount + itemCount;\n                while (k > minK) {\n                    delete O[k - 1];\n                    k -= 1;\n                }\n            } else if (itemCount > actualDeleteCount) {\n                k = len - actualDeleteCount;\n                while (k > actualStart) {\n                    from = $String(k + actualDeleteCount - 1);\n                    to = $String(k + itemCount - 1);\n                    if (owns(O, from)) {\n                        O[to] = O[from];\n                    } else {\n                        delete O[to];\n                    }\n                    k -= 1;\n                }\n            }\n            k = actualStart;\n            for (var i = 0; i < items.length; ++i) {\n                O[k] = items[i];\n                k += 1;\n            }\n            O.length = len - actualDeleteCount + itemCount;\n\n            return A;\n        }\n    }, !spliceWorksWithLargeSparseArrays || !spliceWorksWithSmallSparseArrays);\n\n    var originalJoin = ArrayPrototype.join;\n    var hasStringJoinBug;\n    try {\n        hasStringJoinBug = Array.prototype.join.call('123', ',') !== '1,2,3';\n    } catch (e) {\n        hasStringJoinBug = true;\n    }\n    if (hasStringJoinBug) {\n        defineProperties(ArrayPrototype, {\n            join: function join(separator) {\n                var sep = typeof separator === 'undefined' ? ',' : separator;\n                return originalJoin.call(isString(this) ? strSplit(this, '') : this, sep);\n            }\n        }, hasStringJoinBug);\n    }\n\n    var hasJoinUndefinedBug = [1, 2].join(undefined) !== '1,2';\n    if (hasJoinUndefinedBug) {\n        defineProperties(ArrayPrototype, {\n            join: function join(separator) {\n                var sep = typeof separator === 'undefined' ? ',' : separator;\n                return originalJoin.call(this, sep);\n            }\n        }, hasJoinUndefinedBug);\n    }\n\n    var pushShim = function push(item) {\n        var O = ES.ToObject(this);\n        var n = ES.ToUint32(O.length);\n        var i = 0;\n        while (i < arguments.length) {\n            O[n + i] = arguments[i];\n            i += 1;\n        }\n        O.length = n + i;\n        return n + i;\n    };\n\n    var pushIsNotGeneric = (function () {\n        var obj = {};\n        var result = Array.prototype.push.call(obj, undefined);\n        return result !== 1 || obj.length !== 1 || typeof obj[0] !== 'undefined' || !owns(obj, 0);\n    }());\n    defineProperties(ArrayPrototype, {\n        push: function push(item) {\n            if (isArray(this)) {\n                return array_push.apply(this, arguments);\n            }\n            return pushShim.apply(this, arguments);\n        }\n    }, pushIsNotGeneric);\n\n    // This fixes a very weird bug in Opera 10.6 when pushing `undefined\n    var pushUndefinedIsWeird = (function () {\n        var arr = [];\n        var result = arr.push(undefined);\n        return result !== 1 || arr.length !== 1 || typeof arr[0] !== 'undefined' || !owns(arr, 0);\n    }());\n    defineProperties(ArrayPrototype, { push: pushShim }, pushUndefinedIsWeird);\n\n    // ES5 15.2.3.14\n    // https://es5.github.io/#x15.4.4.10\n    // Fix boxed string bug\n    defineProperties(ArrayPrototype, {\n        slice: function (start, end) {\n            var arr = isString(this) ? strSplit(this, '') : this;\n            return arraySliceApply(arr, arguments);\n        }\n    }, splitString);\n\n    var sortIgnoresNonFunctions = (function () {\n        try {\n            [1, 2].sort(null);\n        } catch (e) {\n            try {\n                [1, 2].sort({});\n            } catch (e2) {\n                return false;\n            }\n        }\n        return true;\n    }());\n    var sortThrowsOnRegex = (function () {\n        // this is a problem in Firefox 4, in which `typeof /a/ === 'function'`\n        try {\n            [1, 2].sort(/a/);\n            return false;\n        } catch (e) {}\n        return true;\n    }());\n    var sortIgnoresUndefined = (function () {\n        // applies in IE 8, for one.\n        try {\n            [1, 2].sort(undefined);\n            return true;\n        } catch (e) {}\n        return false;\n    }());\n    defineProperties(ArrayPrototype, {\n        sort: function sort(compareFn) {\n            if (typeof compareFn === 'undefined') {\n                return arraySort(this);\n            }\n            if (!isCallable(compareFn)) {\n                throw new TypeError('Array.prototype.sort callback must be a function');\n            }\n            return arraySort(this, compareFn);\n        }\n    }, sortIgnoresNonFunctions || !sortIgnoresUndefined || !sortThrowsOnRegex);\n\n    //\n    // Object\n    // ======\n    //\n\n    // ES5 15.2.3.14\n    // https://es5.github.io/#x15.2.3.14\n\n    // https://web.archive.org/web/20140727042234/http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation\n    // eslint-disable-next-line quote-props\n    var hasDontEnumBug = !isEnum({ 'toString': null }, 'toString'); // jscs:ignore disallowQuotedKeysInObjects\n    var hasProtoEnumBug = isEnum(function () {}, 'prototype');\n    var hasStringEnumBug = !owns('x', '0');\n    var equalsConstructorPrototype = function (o) {\n        var ctor = o.constructor;\n        return ctor && ctor.prototype === o;\n    };\n    var excludedKeys = {\n        $applicationCache: true,\n        $console: true,\n        $external: true,\n        $frame: true,\n        $frameElement: true,\n        $frames: true,\n        $innerHeight: true,\n        $innerWidth: true,\n        $onmozfullscreenchange: true,\n        $onmozfullscreenerror: true,\n        $outerHeight: true,\n        $outerWidth: true,\n        $pageXOffset: true,\n        $pageYOffset: true,\n        $parent: true,\n        $scrollLeft: true,\n        $scrollTop: true,\n        $scrollX: true,\n        $scrollY: true,\n        $self: true,\n        $webkitIndexedDB: true,\n        $webkitStorageInfo: true,\n        $window: true,\n\n        $width: true,\n        $height: true,\n        $top: true,\n        $localStorage: true\n    };\n    var hasAutomationEqualityBug = (function () {\n        /* globals window */\n        if (typeof window === 'undefined') {\n            return false;\n        }\n        for (var k in window) {\n            try {\n                if (!excludedKeys['$' + k] && owns(window, k) && window[k] !== null && typeof window[k] === 'object') {\n                    equalsConstructorPrototype(window[k]);\n                }\n            } catch (e) {\n                return true;\n            }\n        }\n        return false;\n    }());\n    var equalsConstructorPrototypeIfNotBuggy = function (object) {\n        if (typeof window === 'undefined' || !hasAutomationEqualityBug) {\n            return equalsConstructorPrototype(object);\n        }\n        try {\n            return equalsConstructorPrototype(object);\n        } catch (e) {\n            return false;\n        }\n    };\n    var dontEnums = [\n        'toString',\n        'toLocaleString',\n        'valueOf',\n        'hasOwnProperty',\n        'isPrototypeOf',\n        'propertyIsEnumerable',\n        'constructor'\n    ];\n    var dontEnumsLength = dontEnums.length;\n\n    // taken directly from https://github.com/ljharb/is-arguments/blob/master/index.js\n    // can be replaced with require('is-arguments') if we ever use a build process instead\n    var isStandardArguments = function isArguments(value) {\n        return toStr(value) === '[object Arguments]';\n    };\n    var isLegacyArguments = function isArguments(value) {\n        return value !== null\n            && typeof value === 'object'\n            && typeof value.length === 'number'\n            && value.length >= 0\n            && !isArray(value)\n            && isCallable(value.callee);\n    };\n    var isArguments = isStandardArguments(arguments) ? isStandardArguments : isLegacyArguments;\n\n    defineProperties($Object, {\n        keys: function keys(object) {\n            var isFn = isCallable(object);\n            var isArgs = isArguments(object);\n            var isObject = object !== null && typeof object === 'object';\n            var isStr = isObject && isString(object);\n\n            if (!isObject && !isFn && !isArgs) {\n                throw new TypeError('Object.keys called on a non-object');\n            }\n\n            var theKeys = [];\n            var skipProto = hasProtoEnumBug && isFn;\n            if ((isStr && hasStringEnumBug) || isArgs) {\n                for (var i = 0; i < object.length; ++i) {\n                    pushCall(theKeys, $String(i));\n                }\n            }\n\n            if (!isArgs) {\n                for (var name in object) {\n                    if (!(skipProto && name === 'prototype') && owns(object, name)) {\n                        pushCall(theKeys, $String(name));\n                    }\n                }\n            }\n\n            if (hasDontEnumBug) {\n                var skipConstructor = equalsConstructorPrototypeIfNotBuggy(object);\n                for (var j = 0; j < dontEnumsLength; j++) {\n                    var dontEnum = dontEnums[j];\n                    if (!(skipConstructor && dontEnum === 'constructor') && owns(object, dontEnum)) {\n                        pushCall(theKeys, dontEnum);\n                    }\n                }\n            }\n            return theKeys;\n        }\n    });\n\n    var keysWorksWithArguments = $Object.keys && (function () {\n        // Safari 5.0 bug\n        return $Object.keys(arguments).length === 2;\n    }(1, 2));\n    var keysHasArgumentsLengthBug = $Object.keys && (function () {\n        var argKeys = $Object.keys(arguments);\n        return arguments.length !== 1 || argKeys.length !== 1 || argKeys[0] !== 1;\n    }(1));\n    var originalKeys = $Object.keys;\n    defineProperties($Object, {\n        keys: function keys(object) {\n            if (isArguments(object)) {\n                return originalKeys(arraySlice(object));\n            }\n            return originalKeys(object);\n\n        }\n    }, !keysWorksWithArguments || keysHasArgumentsLengthBug);\n\n    //\n    // Date\n    // ====\n    //\n\n    var hasNegativeMonthYearBug = new Date(-3509827329600292).getUTCMonth() !== 0;\n    var aNegativeTestDate = new Date(-1509842289600292);\n    var aPositiveTestDate = new Date(1449662400000);\n    var hasToUTCStringFormatBug = aNegativeTestDate.toUTCString() !== 'Mon, 01 Jan -45875 11:59:59 GMT';\n    var hasToDateStringFormatBug;\n    var hasToStringFormatBug;\n    var timeZoneOffset = aNegativeTestDate.getTimezoneOffset();\n    if (timeZoneOffset < -720) {\n        hasToDateStringFormatBug = aNegativeTestDate.toDateString() !== 'Tue Jan 02 -45875';\n        hasToStringFormatBug = !(/^Thu Dec 10 2015 \\d\\d:\\d\\d:\\d\\d GMT[-+]\\d\\d\\d\\d(?: |$)/).test(String(aPositiveTestDate));\n    } else {\n        hasToDateStringFormatBug = aNegativeTestDate.toDateString() !== 'Mon Jan 01 -45875';\n        hasToStringFormatBug = !(/^Wed Dec 09 2015 \\d\\d:\\d\\d:\\d\\d GMT[-+]\\d\\d\\d\\d(?: |$)/).test(String(aPositiveTestDate));\n    }\n\n    var originalGetFullYear = call.bind(Date.prototype.getFullYear);\n    var originalGetMonth = call.bind(Date.prototype.getMonth);\n    var originalGetDate = call.bind(Date.prototype.getDate);\n    var originalGetUTCFullYear = call.bind(Date.prototype.getUTCFullYear);\n    var originalGetUTCMonth = call.bind(Date.prototype.getUTCMonth);\n    var originalGetUTCDate = call.bind(Date.prototype.getUTCDate);\n    var originalGetUTCDay = call.bind(Date.prototype.getUTCDay);\n    var originalGetUTCHours = call.bind(Date.prototype.getUTCHours);\n    var originalGetUTCMinutes = call.bind(Date.prototype.getUTCMinutes);\n    var originalGetUTCSeconds = call.bind(Date.prototype.getUTCSeconds);\n    var originalGetUTCMilliseconds = call.bind(Date.prototype.getUTCMilliseconds);\n    var dayName = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];\n    var monthName = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];\n    var daysInMonth = function daysInMonth(month, year) {\n        return originalGetDate(new Date(year, month, 0));\n    };\n\n    defineProperties(Date.prototype, {\n        getFullYear: function getFullYear() {\n            if (!this || !(this instanceof Date)) {\n                throw new TypeError('this is not a Date object.');\n            }\n            var year = originalGetFullYear(this);\n            if (year < 0 && originalGetMonth(this) > 11) {\n                return year + 1;\n            }\n            return year;\n        },\n        getMonth: function getMonth() {\n            if (!this || !(this instanceof Date)) {\n                throw new TypeError('this is not a Date object.');\n            }\n            var year = originalGetFullYear(this);\n            var month = originalGetMonth(this);\n            if (year < 0 && month > 11) {\n                return 0;\n            }\n            return month;\n        },\n        getDate: function getDate() {\n            if (!this || !(this instanceof Date)) {\n                throw new TypeError('this is not a Date object.');\n            }\n            var year = originalGetFullYear(this);\n            var month = originalGetMonth(this);\n            var date = originalGetDate(this);\n            if (year < 0 && month > 11) {\n                if (month === 12) {\n                    return date;\n                }\n                var days = daysInMonth(0, year + 1);\n                return (days - date) + 1;\n            }\n            return date;\n        },\n        getUTCFullYear: function getUTCFullYear() {\n            if (!this || !(this instanceof Date)) {\n                throw new TypeError('this is not a Date object.');\n            }\n            var year = originalGetUTCFullYear(this);\n            if (year < 0 && originalGetUTCMonth(this) > 11) {\n                return year + 1;\n            }\n            return year;\n        },\n        getUTCMonth: function getUTCMonth() {\n            if (!this || !(this instanceof Date)) {\n                throw new TypeError('this is not a Date object.');\n            }\n            var year = originalGetUTCFullYear(this);\n            var month = originalGetUTCMonth(this);\n            if (year < 0 && month > 11) {\n                return 0;\n            }\n            return month;\n        },\n        getUTCDate: function getUTCDate() {\n            if (!this || !(this instanceof Date)) {\n                throw new TypeError('this is not a Date object.');\n            }\n            var year = originalGetUTCFullYear(this);\n            var month = originalGetUTCMonth(this);\n            var date = originalGetUTCDate(this);\n            if (year < 0 && month > 11) {\n                if (month === 12) {\n                    return date;\n                }\n                var days = daysInMonth(0, year + 1);\n                return (days - date) + 1;\n            }\n            return date;\n        }\n    }, hasNegativeMonthYearBug);\n\n    defineProperties(Date.prototype, {\n        toUTCString: function toUTCString() {\n            if (!this || !(this instanceof Date)) {\n                throw new TypeError('this is not a Date object.');\n            }\n            var day = originalGetUTCDay(this);\n            var date = originalGetUTCDate(this);\n            var month = originalGetUTCMonth(this);\n            var year = originalGetUTCFullYear(this);\n            var hour = originalGetUTCHours(this);\n            var minute = originalGetUTCMinutes(this);\n            var second = originalGetUTCSeconds(this);\n            return dayName[day] + ', '\n                + (date < 10 ? '0' + date : date) + ' '\n                + monthName[month] + ' '\n                + year + ' '\n                + (hour < 10 ? '0' + hour : hour) + ':'\n                + (minute < 10 ? '0' + minute : minute) + ':'\n                + (second < 10 ? '0' + second : second) + ' GMT';\n        }\n    }, hasNegativeMonthYearBug || hasToUTCStringFormatBug);\n\n    // Opera 12 has `,`\n    defineProperties(Date.prototype, {\n        toDateString: function toDateString() {\n            if (!this || !(this instanceof Date)) {\n                throw new TypeError('this is not a Date object.');\n            }\n            var day = this.getDay();\n            var date = this.getDate();\n            var month = this.getMonth();\n            var year = this.getFullYear();\n            return dayName[day] + ' '\n                + monthName[month] + ' '\n                + (date < 10 ? '0' + date : date) + ' '\n                + year;\n        }\n    }, hasNegativeMonthYearBug || hasToDateStringFormatBug);\n\n    // can't use defineProperties here because of toString enumeration issue in IE <= 8\n    if (hasNegativeMonthYearBug || hasToStringFormatBug) {\n        Date.prototype.toString = function toString() {\n            if (!this || !(this instanceof Date)) {\n                throw new TypeError('this is not a Date object.');\n            }\n            var day = this.getDay();\n            var date = this.getDate();\n            var month = this.getMonth();\n            var year = this.getFullYear();\n            var hour = this.getHours();\n            var minute = this.getMinutes();\n            var second = this.getSeconds();\n            var timezoneOffset = this.getTimezoneOffset();\n            var hoursOffset = floor(abs(timezoneOffset) / 60);\n            var minutesOffset = floor(abs(timezoneOffset) % 60);\n            return dayName[day] + ' '\n                + monthName[month] + ' '\n                + (date < 10 ? '0' + date : date) + ' '\n                + year + ' '\n                + (hour < 10 ? '0' + hour : hour) + ':'\n                + (minute < 10 ? '0' + minute : minute) + ':'\n                + (second < 10 ? '0' + second : second) + ' GMT'\n                + (timezoneOffset > 0 ? '-' : '+')\n                + (hoursOffset < 10 ? '0' + hoursOffset : hoursOffset)\n                + (minutesOffset < 10 ? '0' + minutesOffset : minutesOffset);\n        };\n        if (supportsDescriptors) {\n            $Object.defineProperty(Date.prototype, 'toString', {\n                configurable: true,\n                enumerable: false,\n                writable: true\n            });\n        }\n    }\n\n    // ES5 15.9.5.43\n    // https://es5.github.io/#x15.9.5.43\n    // This function returns a String value represent the instance in time\n    // represented by this Date object. The format of the String is the Date Time\n    // string format defined in 15.9.1.15. All fields are present in the String.\n    // The time zone is always UTC, denoted by the suffix Z. If the time value of\n    // this object is not a finite Number a RangeError exception is thrown.\n    var negativeDate = -62198755200000;\n    var negativeYearString = '-000001';\n    var hasNegativeDateBug = Date.prototype.toISOString && new Date(negativeDate).toISOString().indexOf(negativeYearString) === -1; // eslint-disable-line max-len\n    var hasSafari51DateBug = Date.prototype.toISOString && new Date(-1).toISOString() !== '1969-12-31T23:59:59.999Z';\n\n    var getTime = call.bind(Date.prototype.getTime);\n\n    defineProperties(Date.prototype, {\n        toISOString: function toISOString() {\n            if (!isFinite(this) || !isFinite(getTime(this))) {\n                // Adope Photoshop requires the second check.\n                throw new RangeError('Date.prototype.toISOString called on non-finite value.');\n            }\n\n            var year = originalGetUTCFullYear(this);\n\n            var month = originalGetUTCMonth(this);\n            // see https://github.com/es-shims/es5-shim/issues/111\n            year += floor(month / 12);\n            month = ((month % 12) + 12) % 12;\n\n            // the date time string format is specified in 15.9.1.15.\n            var result = [\n                month + 1,\n                originalGetUTCDate(this),\n                originalGetUTCHours(this),\n                originalGetUTCMinutes(this),\n                originalGetUTCSeconds(this)\n            ];\n            year = (\n                (year < 0 ? '-' : (year > 9999 ? '+' : ''))\n                + strSlice('00000' + abs(year), (0 <= year && year <= 9999) ? -4 : -6)\n            );\n\n            for (var i = 0; i < result.length; ++i) {\n                // pad months, days, hours, minutes, and seconds to have two digits.\n                result[i] = strSlice('00' + result[i], -2);\n            }\n            // pad milliseconds to have three digits.\n            return (\n                year + '-' + arraySlice(result, 0, 2).join('-')\n                + 'T' + arraySlice(result, 2).join(':') + '.'\n                + strSlice('000' + originalGetUTCMilliseconds(this), -3) + 'Z'\n            );\n        }\n    }, hasNegativeDateBug || hasSafari51DateBug);\n\n    // ES5 15.9.5.44\n    // https://es5.github.io/#x15.9.5.44\n    // This function provides a String representation of a Date object for use by\n    // JSON.stringify (15.12.3).\n    var dateToJSONIsSupported = (function () {\n        try {\n            return Date.prototype.toJSON\n                && new Date(NaN).toJSON() === null\n                && new Date(negativeDate).toJSON().indexOf(negativeYearString) !== -1\n                && Date.prototype.toJSON.call({ // generic\n                    toISOString: function () { return true; }\n                });\n        } catch (e) {\n            return false;\n        }\n    }());\n    if (!dateToJSONIsSupported) {\n        Date.prototype.toJSON = function toJSON(key) {\n            // When the toJSON method is called with argument key, the following\n            // steps are taken:\n\n            // 1.  Let O be the result of calling ToObject, giving it the this\n            // value as its argument.\n            // 2. Let tv be ES.ToPrimitive(O, hint Number).\n            var O = $Object(this);\n            var tv = ES.ToPrimitive(O);\n            // 3. If tv is a Number and is not finite, return null.\n            if (typeof tv === 'number' && !isFinite(tv)) {\n                return null;\n            }\n            // 4. Let toISO be the result of calling the [[Get]] internal method of\n            // O with argument \"toISOString\".\n            var toISO = O.toISOString;\n            // 5. If IsCallable(toISO) is false, throw a TypeError exception.\n            if (!isCallable(toISO)) {\n                throw new TypeError('toISOString property is not callable');\n            }\n            // 6. Return the result of calling the [[Call]] internal method of\n            //  toISO with O as the this value and an empty argument list.\n            return toISO.call(O);\n\n            // NOTE 1 The argument is ignored.\n\n            // NOTE 2 The toJSON function is intentionally generic; it does not\n            // require that its this value be a Date object. Therefore, it can be\n            // transferred to other kinds of objects for use as a method. However,\n            // it does require that any such object have a toISOString method. An\n            // object is free to use the argument key to filter its\n            // stringification.\n        };\n    }\n\n    // ES5 15.9.4.2\n    // https://es5.github.io/#x15.9.4.2\n    // based on work shared by Daniel Friesen (dantman)\n    // https://gist.github.com/303249\n    var supportsExtendedYears = Date.parse('+033658-09-27T01:46:40.000Z') === 1e15;\n    var acceptsInvalidDates = !isNaN(Date.parse('2012-04-04T24:00:00.500Z')) || !isNaN(Date.parse('2012-11-31T23:59:59.000Z')) || !isNaN(Date.parse('2012-12-31T23:59:60.000Z'));\n    var doesNotParseY2KNewYear = isNaN(Date.parse('2000-01-01T00:00:00.000Z'));\n    if (doesNotParseY2KNewYear || acceptsInvalidDates || !supportsExtendedYears) {\n        // XXX global assignment won't work in embeddings that use\n        // an alternate object for the context.\n        var maxSafeUnsigned32Bit = pow(2, 31) - 1;\n        var hasSafariSignedIntBug = isActualNaN(new Date(1970, 0, 1, 0, 0, 0, maxSafeUnsigned32Bit + 1).getTime());\n        // eslint-disable-next-line no-implicit-globals, no-global-assign\n        Date = (function (NativeDate) {\n            // Date.length === 7\n            var DateShim = function Date(Y, M, D, h, m, s, ms) {\n                var length = arguments.length;\n                var date;\n                if (this instanceof NativeDate) {\n                    var seconds = s;\n                    var millis = ms;\n                    if (hasSafariSignedIntBug && length >= 7 && ms > maxSafeUnsigned32Bit) {\n                        // work around a Safari 8/9 bug where it treats the seconds as signed\n                        var msToShift = floor(ms / maxSafeUnsigned32Bit) * maxSafeUnsigned32Bit;\n                        var sToShift = floor(msToShift / 1e3);\n                        seconds += sToShift;\n                        millis -= sToShift * 1e3;\n                    }\n                    var parsed = DateShim.parse(Y);\n                    var hasNegTimestampParseBug = isNaN(parsed);\n                    date = length === 1 && $String(Y) === Y && !hasNegTimestampParseBug // isString(Y)\n                        // We explicitly pass it through parse:\n                        ? new NativeDate(parsed)\n                        // We have to manually make calls depending on argument\n                        // length here\n                        : length >= 7 ? new NativeDate(Y, M, D, h, m, seconds, millis)\n                            : length >= 6 ? new NativeDate(Y, M, D, h, m, seconds)\n                                : length >= 5 ? new NativeDate(Y, M, D, h, m)\n                                    : length >= 4 ? new NativeDate(Y, M, D, h)\n                                        : length >= 3 ? new NativeDate(Y, M, D)\n                                            : length >= 2 ? new NativeDate(Y, M)\n                                                : length >= 1 ? new NativeDate(Y instanceof NativeDate ? +Y : Y)\n                                                    : new NativeDate();\n                } else {\n                    date = NativeDate.apply(this, arguments);\n                }\n                if (!isPrimitive(date)) {\n                    // Prevent mixups with unfixed Date object\n                    defineProperties(date, { constructor: DateShim }, true);\n                }\n                return date;\n            };\n\n            // 15.9.1.15 Date Time String Format.\n            var isoDateExpression = new RegExp('^'\n                + '(\\\\d{4}|[+-]\\\\d{6})' // four-digit year capture or sign + 6-digit extended year\n                + '(?:-(\\\\d{2})' // optional month capture\n                + '(?:-(\\\\d{2})' // optional day capture\n                + '(?:' // capture hours:minutes:seconds.milliseconds\n                    + 'T(\\\\d{2})' // hours capture\n                    + ':(\\\\d{2})' // minutes capture\n                    + '(?:' // optional :seconds.milliseconds\n                        + ':(\\\\d{2})' // seconds capture\n                        + '(?:(\\\\.\\\\d{1,}))?' // milliseconds capture\n                    + ')?'\n                + '(' // capture UTC offset component\n                    + 'Z|' // UTC capture\n                    + '(?:' // offset specifier +/-hours:minutes\n                        + '([-+])' // sign capture\n                        + '(\\\\d{2})' // hours offset capture\n                        + ':(\\\\d{2})' // minutes offset capture\n                    + ')'\n                + ')?)?)?)?'\n            + '$');\n\n            var months = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365];\n\n            var dayFromMonth = function dayFromMonth(year, month) {\n                var t = month > 1 ? 1 : 0;\n                return (\n                    months[month]\n                        + floor((year - 1969 + t) / 4)\n                        - floor((year - 1901 + t) / 100)\n                        + floor((year - 1601 + t) / 400)\n                        + (365 * (year - 1970))\n                );\n            };\n\n            var toUTC = function toUTC(t) {\n                var s = 0;\n                var ms = t;\n                if (hasSafariSignedIntBug && ms > maxSafeUnsigned32Bit) {\n                    // work around a Safari 8/9 bug where it treats the seconds as signed\n                    var msToShift = floor(ms / maxSafeUnsigned32Bit) * maxSafeUnsigned32Bit;\n                    var sToShift = floor(msToShift / 1e3);\n                    s += sToShift;\n                    ms -= sToShift * 1e3;\n                }\n                return $Number(new NativeDate(1970, 0, 1, 0, 0, s, ms));\n            };\n\n            // Copy any custom methods a 3rd party library may have added\n            for (var key in NativeDate) {\n                if (owns(NativeDate, key)) {\n                    DateShim[key] = NativeDate[key];\n                }\n            }\n\n            // Copy \"native\" methods explicitly; they may be non-enumerable\n            defineProperties(DateShim, {\n                now: NativeDate.now,\n                UTC: NativeDate.UTC\n            }, true);\n            DateShim.prototype = NativeDate.prototype;\n            defineProperties(DateShim.prototype, { constructor: DateShim }, true);\n\n            // Upgrade Date.parse to handle simplified ISO 8601 strings\n            var parseShim = function parse(string) {\n                var match = isoDateExpression.exec(string);\n                if (match) {\n                    // parse months, days, hours, minutes, seconds, and milliseconds\n                    // provide default values if necessary\n                    // parse the UTC offset component\n                    var year = $Number(match[1]),\n                        month = $Number(match[2] || 1) - 1,\n                        day = $Number(match[3] || 1) - 1,\n                        hour = $Number(match[4] || 0),\n                        minute = $Number(match[5] || 0),\n                        second = $Number(match[6] || 0),\n                        millisecond = floor($Number(match[7] || 0) * 1000),\n                        // When time zone is missed, local offset should be used\n                        // (ES 5.1 bug)\n                        // see https://bugs.ecmascript.org/show_bug.cgi?id=112\n                        isLocalTime = Boolean(match[4] && !match[8]),\n                        signOffset = match[9] === '-' ? 1 : -1,\n                        hourOffset = $Number(match[10] || 0),\n                        minuteOffset = $Number(match[11] || 0),\n                        result;\n                    var hasMinutesOrSecondsOrMilliseconds = minute > 0 || second > 0 || millisecond > 0;\n                    if (\n                        hour < (hasMinutesOrSecondsOrMilliseconds ? 24 : 25)\n                        && minute < 60 && second < 60 && millisecond < 1000\n                        && month > -1 && month < 12 && hourOffset < 24\n                        && minuteOffset < 60 // detect invalid offsets\n                        && day > -1\n                        && day < (dayFromMonth(year, month + 1) - dayFromMonth(year, month))\n                    ) {\n                        result = (\n                            ((dayFromMonth(year, month) + day) * 24)\n                            + hour\n                            + (hourOffset * signOffset)\n                        ) * 60;\n                        result = ((\n                            ((result + minute + (minuteOffset * signOffset)) * 60)\n                            + second\n                        ) * 1000) + millisecond;\n                        if (isLocalTime) {\n                            result = toUTC(result);\n                        }\n                        if (-8.64e15 <= result && result <= 8.64e15) {\n                            return result;\n                        }\n                    }\n                    return NaN;\n                }\n                return NativeDate.parse.apply(this, arguments);\n            };\n            defineProperties(DateShim, { parse: parseShim });\n\n            return DateShim;\n        }(Date));\n    }\n\n    // ES5 15.9.4.4\n    // https://es5.github.io/#x15.9.4.4\n    if (!Date.now) {\n        Date.now = function now() {\n            return new Date().getTime();\n        };\n    }\n\n    //\n    // Number\n    // ======\n    //\n\n    // ES5.1 15.7.4.5\n    // https://es5.github.io/#x15.7.4.5\n    var hasToFixedBugs = NumberPrototype.toFixed && (\n        (0.00008).toFixed(3) !== '0.000'\n        || (0.9).toFixed(0) !== '1'\n        || (1.255).toFixed(2) !== '1.25'\n        || (1000000000000000128).toFixed(0) !== '1000000000000000128'\n    );\n\n    var toFixedHelpers = {\n        base: 1e7,\n        size: 6,\n        data: [0, 0, 0, 0, 0, 0],\n        multiply: function multiply(n, c) {\n            var i = -1;\n            var c2 = c;\n            while (++i < toFixedHelpers.size) {\n                c2 += n * toFixedHelpers.data[i];\n                toFixedHelpers.data[i] = c2 % toFixedHelpers.base;\n                c2 = floor(c2 / toFixedHelpers.base);\n            }\n        },\n        divide: function divide(n) {\n            var i = toFixedHelpers.size;\n            var c = 0;\n            while (--i >= 0) {\n                c += toFixedHelpers.data[i];\n                toFixedHelpers.data[i] = floor(c / n);\n                c = (c % n) * toFixedHelpers.base;\n            }\n        },\n        numToString: function numToString() {\n            var i = toFixedHelpers.size;\n            var s = '';\n            while (--i >= 0) {\n                if (s !== '' || i === 0 || toFixedHelpers.data[i] !== 0) {\n                    var t = $String(toFixedHelpers.data[i]);\n                    if (s === '') {\n                        s = t;\n                    } else {\n                        s += strSlice('0000000', 0, 7 - t.length) + t;\n                    }\n                }\n            }\n            return s;\n        },\n        pow: function pow(x, n, acc) {\n            return (n === 0 ? acc : (n % 2 === 1 ? pow(x, n - 1, acc * x) : pow(x * x, n / 2, acc)));\n        },\n        log: function log(x) {\n            var n = 0;\n            var x2 = x;\n            while (x2 >= 4096) {\n                n += 12;\n                x2 /= 4096;\n            }\n            while (x2 >= 2) {\n                n += 1;\n                x2 /= 2;\n            }\n            return n;\n        }\n    };\n\n    var toFixedShim = function toFixed(fractionDigits) {\n        var f, x, s, m, e, z, j, k;\n\n        // Test for NaN and round fractionDigits down\n        f = $Number(fractionDigits);\n        f = isActualNaN(f) ? 0 : floor(f);\n\n        if (f < 0 || f > 20) {\n            throw new RangeError('Number.toFixed called with invalid number of decimals');\n        }\n\n        x = $Number(this);\n\n        if (isActualNaN(x)) {\n            return 'NaN';\n        }\n\n        // If it is too big or small, return the string value of the number\n        if (x <= -1e21 || x >= 1e21) {\n            return $String(x);\n        }\n\n        s = '';\n\n        if (x < 0) {\n            s = '-';\n            x = -x;\n        }\n\n        m = '0';\n\n        if (x > 1e-21) {\n            // 1e-21 < x < 1e21\n            // -70 < log2(x) < 70\n            e = toFixedHelpers.log(x * toFixedHelpers.pow(2, 69, 1)) - 69;\n            z = (e < 0 ? x * toFixedHelpers.pow(2, -e, 1) : x / toFixedHelpers.pow(2, e, 1));\n            z *= 0x10000000000000; // pow(2, 52);\n            e = 52 - e;\n\n            // -18 < e < 122\n            // x = z / 2 ^ e\n            if (e > 0) {\n                toFixedHelpers.multiply(0, z);\n                j = f;\n\n                while (j >= 7) {\n                    toFixedHelpers.multiply(1e7, 0);\n                    j -= 7;\n                }\n\n                toFixedHelpers.multiply(toFixedHelpers.pow(10, j, 1), 0);\n                j = e - 1;\n\n                while (j >= 23) {\n                    toFixedHelpers.divide(1 << 23);\n                    j -= 23;\n                }\n\n                toFixedHelpers.divide(1 << j);\n                toFixedHelpers.multiply(1, 1);\n                toFixedHelpers.divide(2);\n                m = toFixedHelpers.numToString();\n            } else {\n                toFixedHelpers.multiply(0, z);\n                toFixedHelpers.multiply(1 << (-e), 0);\n                m = toFixedHelpers.numToString() + strSlice('0.00000000000000000000', 2, 2 + f);\n            }\n        }\n\n        if (f > 0) {\n            k = m.length;\n\n            if (k <= f) {\n                m = s + strSlice('0.0000000000000000000', 0, f - k + 2) + m;\n            } else {\n                m = s + strSlice(m, 0, k - f) + '.' + strSlice(m, k - f);\n            }\n        } else {\n            m = s + m;\n        }\n\n        return m;\n    };\n    defineProperties(NumberPrototype, { toFixed: toFixedShim }, hasToFixedBugs);\n\n    var hasToExponentialRoundingBug = (function () {\n        try {\n            return (-6.9e-11).toExponential(4) !== '-6.9000e-11';\n        } catch (e) {\n            return false;\n        }\n    }());\n    var toExponentialAllowsInfiniteDigits = (function () {\n        try {\n            (1).toExponential(Infinity);\n            (1).toExponential(-Infinity);\n            return true;\n        } catch (e) {\n            return false;\n        }\n    }());\n    var originalToExponential = call.bind(NumberPrototype.toExponential);\n    var numberToString = call.bind(NumberPrototype.toString);\n    var numberValueOf = call.bind(NumberPrototype.valueOf);\n    defineProperties(NumberPrototype, {\n        toExponential: function toExponential(fractionDigits) {\n            // 1: Let x be this Number value.\n            var x = numberValueOf(this);\n\n            if (typeof fractionDigits === 'undefined') {\n                return originalToExponential(x);\n            }\n            var f = ES.ToInteger(fractionDigits);\n            if (isActualNaN(x)) {\n                return 'NaN';\n            }\n\n            if (f < 0 || f > 20) {\n                if (!isFinite(f)) {\n                    // IE 6 doesn't throw in the native one\n                    throw new RangeError('toExponential() argument must be between 0 and 20');\n                }\n                // this will probably have thrown already\n                return originalToExponential(x, f);\n            }\n\n            // only cases left are a finite receiver + in-range fractionDigits\n\n            // implementation adapted from https://gist.github.com/SheetJSDev/1100ad56b9f856c95299ed0e068eea08\n\n            // 4: Let s be the empty string\n            var s = '';\n\n            // 5: If x < 0\n            if (x < 0) {\n                s = '-';\n                x = -x;\n            }\n\n            // 6: If x = +Infinity\n            if (x === Infinity) {\n                return s + 'Infinity';\n            }\n\n            // 7: If fractionDigits is not undefined and (f < 0 or f > 20), throw a RangeError exception.\n            if (typeof fractionDigits !== 'undefined' && (f < 0 || f > 20)) {\n                throw new RangeError('Fraction digits ' + fractionDigits + ' out of range');\n            }\n\n            var m = '';\n            var e = 0;\n            var c = '';\n            var d = '';\n\n            // 8: If x = 0 then\n            if (x === 0) {\n                e = 0;\n                f = 0;\n                m = '0';\n            } else { // 9: Else, x != 0\n                var L = log10(x);\n                e = floor(L); // 10 ** e <= x and x < 10 ** (e+1)\n                var n = 0;\n                if (typeof fractionDigits !== 'undefined') { // eslint-disable-line no-negated-condition\n                    var w = pow(10, e - f); // x / 10 ** (f+1) < w and w <= x / 10 ** f\n                    n = round(x / w); // 10 ** f <= n and n < 10 ** (f+1)\n                    if (2 * x >= (((2 * n) + 1) * w)) {\n                        n += 1; // pick larger value\n                    }\n                    if (n >= pow(10, f + 1)) { // 10e-1 = 1e0\n                        n /= 10;\n                        e += 1;\n                    }\n                } else {\n                    f = 16; // start from Math.ceil(Math.log10(Number.MAX_SAFE_INTEGER)) and loop down\n                    var guess_n = round(pow(10, L - e + f));\n                    var target_f = f;\n                    while (f-- > 0) {\n                        guess_n = round(pow(10, L - e + f));\n                        if (\n                            abs((guess_n * pow(10, e - f)) - x)\n                            <= abs((n * pow(10, e - target_f)) - x)\n                        ) {\n                            target_f = f;\n                            n = guess_n;\n                        }\n                    }\n                }\n                m = numberToString(n, 10);\n                if (typeof fractionDigits === 'undefined') {\n                    while (strSlice(m, -1) === '0') {\n                        m = strSlice(m, 0, -1);\n                        d += 1;\n                    }\n                }\n            }\n\n            // 10: If f != 0, then\n            if (f !== 0) {\n                m = strSlice(m, 0, 1) + '.' + strSlice(m, 1);\n            }\n\n            // 11: If e = 0, then\n            if (e === 0) {\n                c = '+';\n                d = '0';\n            } else { // 12: Else\n                c = e > 0 ? '+' : '-';\n                d = numberToString(abs(e), 10);\n            }\n\n            // 13: Let m be the concatenation of the four Strings m, \"e\", c, and d.\n            m += 'e' + c + d;\n\n            // 14: Return the concatenation of the Strings s and m.\n            return s + m;\n        }\n    }, hasToExponentialRoundingBug || toExponentialAllowsInfiniteDigits);\n\n    var hasToPrecisionUndefinedBug = (function () {\n        try {\n            return 1.0.toPrecision(undefined) === '1';\n        } catch (e) {\n            return true;\n        }\n    }());\n    var originalToPrecision = call.bind(NumberPrototype.toPrecision);\n    defineProperties(NumberPrototype, {\n        toPrecision: function toPrecision(precision) {\n            return typeof precision === 'undefined' ? originalToPrecision(this) : originalToPrecision(this, precision);\n        }\n    }, hasToPrecisionUndefinedBug);\n\n    //\n    // String\n    // ======\n    //\n\n    // ES5 15.5.4.14\n    // https://es5.github.io/#x15.5.4.14\n\n    // [bugfix, IE lt 9, firefox 4, Konqueror, Opera, obscure browsers]\n    // Many browsers do not split properly with regular expressions or they\n    // do not perform the split correctly under obscure conditions.\n    // See https://blog.stevenlevithan.com/archives/cross-browser-split\n    // I've tested in many browsers and this seems to cover the deviant ones:\n    //    'ab'.split(/(?:ab)*/) should be [\"\", \"\"], not [\"\"]\n    //    '.'.split(/(.?)(.?)/) should be [\"\", \".\", \"\", \"\"], not [\"\", \"\"]\n    //    'tesst'.split(/(s)*/) should be [\"t\", undefined, \"e\", \"s\", \"t\"], not\n    //       [undefined, \"t\", undefined, \"e\", ...]\n    //    ''.split(/.?/) should be [], not [\"\"]\n    //    '.'.split(/()()/) should be [\".\"], not [\"\", \"\", \".\"]\n\n    if (\n        'ab'.split(/(?:ab)*/).length !== 2\n        || '.'.split(/(.?)(.?)/).length !== 4\n        || 'tesst'.split(/(s)*/)[1] === 't'\n        || 'test'.split(/(?:)/, -1).length !== 4\n        || ''.split(/.?/).length\n        || '.'.split(/()()/).length > 1\n    ) {\n        (function () {\n            var compliantExecNpcg = typeof (/()??/).exec('')[1] === 'undefined'; // NPCG: nonparticipating capturing group\n            var maxSafe32BitInt = pow(2, 32) - 1;\n\n            StringPrototype.split = function split(separator, limit) {\n                var string = String(this);\n                if (typeof separator === 'undefined' && limit === 0) {\n                    return [];\n                }\n\n                // If `separator` is not a regex, use native split\n                if (!isRegex(separator)) {\n                    return strSplit(this, separator, limit);\n                }\n\n                var output = [];\n                var flags = (separator.ignoreCase ? 'i' : '')\n                            + (separator.multiline ? 'm' : '')\n                            + (separator.unicode ? 'u' : '') // in ES6\n                            + (separator.sticky ? 'y' : ''), // Firefox 3+ and ES6\n                    lastLastIndex = 0,\n                    // Make `global` and avoid `lastIndex` issues by working with a copy\n                    separator2, match, lastIndex, lastLength;\n                var separatorCopy = new RegExp(separator.source, flags + 'g');\n                if (!compliantExecNpcg) {\n                    // Doesn't need flags gy, but they don't hurt\n                    separator2 = new RegExp('^' + separatorCopy.source + '$(?!\\\\s)', flags);\n                }\n                /* Values for `limit`, per the spec:\n                 * If undefined: 4294967295 // maxSafe32BitInt\n                 * If 0, Infinity, or NaN: 0\n                 * If positive number: limit = floor(limit); if (limit > 4294967295) limit -= 4294967296;\n                 * If negative number: 4294967296 - floor(abs(limit))\n                 * If other: Type-convert, then use the above rules\n                 */\n                var splitLimit = typeof limit === 'undefined' ? maxSafe32BitInt : ES.ToUint32(limit);\n                match = separatorCopy.exec(string);\n                while (match) {\n                    // `separatorCopy.lastIndex` is not reliable cross-browser\n                    lastIndex = match.index + match[0].length;\n                    if (lastIndex > lastLastIndex) {\n                        pushCall(output, strSlice(string, lastLastIndex, match.index));\n                        // Fix browsers whose `exec` methods don't consistently return `undefined` for\n                        // nonparticipating capturing groups\n                        if (!compliantExecNpcg && match.length > 1) {\n                            /* eslint-disable no-loop-func */\n                            match[0].replace(separator2, function () {\n                                for (var i = 1; i < arguments.length - 2; i++) {\n                                    if (typeof arguments[i] === 'undefined') {\n                                        match[i] = void 0;\n                                    }\n                                }\n                            });\n                            /* eslint-enable no-loop-func */\n                        }\n                        if (match.length > 1 && match.index < string.length) {\n                            array_push.apply(output, arraySlice(match, 1));\n                        }\n                        lastLength = match[0].length;\n                        lastLastIndex = lastIndex;\n                        if (output.length >= splitLimit) {\n                            break;\n                        }\n                    }\n                    if (separatorCopy.lastIndex === match.index) {\n                        separatorCopy.lastIndex++; // Avoid an infinite loop\n                    }\n                    match = separatorCopy.exec(string);\n                }\n                if (lastLastIndex === string.length) {\n                    if (lastLength || !separatorCopy.test('')) {\n                        pushCall(output, '');\n                    }\n                } else {\n                    pushCall(output, strSlice(string, lastLastIndex));\n                }\n                return output.length > splitLimit ? arraySlice(output, 0, splitLimit) : output;\n            };\n        }());\n\n    // [bugfix, chrome]\n    // If separator is undefined, then the result array contains just one String,\n    // which is the this value (converted to a String). If limit is not undefined,\n    // then the output array is truncated so that it contains no more than limit\n    // elements.\n    // \"0\".split(undefined, 0) -> []\n    } else if ('0'.split(void 0, 0).length) {\n        StringPrototype.split = function split(separator, limit) {\n            if (typeof separator === 'undefined' && limit === 0) {\n                return [];\n            }\n            return strSplit(this, separator, limit);\n        };\n    }\n\n    var str_replace = StringPrototype.replace;\n    var replaceReportsGroupsCorrectly = (function () {\n        var groups = [];\n        'x'.replace(/x(.)?/g, function (match, group) {\n            pushCall(groups, group);\n        });\n        return groups.length === 1 && typeof groups[0] === 'undefined';\n    }());\n\n    if (!replaceReportsGroupsCorrectly) {\n        StringPrototype.replace = function replace(searchValue, replaceValue) {\n            var isFn = isCallable(replaceValue);\n            var hasCapturingGroups = isRegex(searchValue) && (/\\)[*?]/).test(searchValue.source);\n            if (!isFn || !hasCapturingGroups) {\n                return str_replace.call(this, searchValue, replaceValue);\n            }\n            var wrappedReplaceValue = function (match) {\n                var length = arguments.length;\n                var originalLastIndex = searchValue.lastIndex;\n                searchValue.lastIndex = 0; // eslint-disable-line no-param-reassign\n                var args = searchValue.exec(match) || [];\n                searchValue.lastIndex = originalLastIndex; // eslint-disable-line no-param-reassign\n                pushCall(args, arguments[length - 2], arguments[length - 1]);\n                return replaceValue.apply(this, args);\n            };\n            return str_replace.call(this, searchValue, wrappedReplaceValue);\n\n        };\n    }\n\n    // ECMA-262, 3rd B.2.3\n    // Not an ECMAScript standard, although ECMAScript 3rd Edition has a\n    // non-normative section suggesting uniform semantics and it should be\n    // normalized across all browsers\n    // [bugfix, IE lt 9] IE < 9 substr() with negative value not working in IE\n    var hasNegativeSubstrBug = ''.substr && '0b'.substr(-1) !== 'b';\n    var string_substr = hasNegativeSubstrBug && call.bind(StringPrototype.substr);\n    defineProperties(StringPrototype, {\n        substr: function substr(start, length) {\n            var normalizedStart = start;\n            if (start < 0) {\n                normalizedStart = max(this.length + start, 0);\n            }\n            return string_substr(this, normalizedStart, length);\n        }\n    }, hasNegativeSubstrBug);\n\n    // ES5 15.5.4.20\n    // whitespace from: https://es5.github.io/#x15.5.4.20\n    var mvs = '\\u180E';\n    var mvsIsWS = (/\\s/).test(mvs);\n    var ws = '\\x09\\x0A\\x0B\\x0C\\x0D\\x20\\xA0\\u1680\\u180E\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200A\\u202F\\u205F\\u3000\\u2028\\u2029\\uFEFF'\n        .replace(/\\S/g, ''); // remove the mongolian vowel separator (\\u180E) in modern engines\n    var zeroWidth = '\\u200b';\n    var wsRegexChars = '[' + ws + ']';\n    var trimBeginRegexp = new RegExp('^' + wsRegexChars + wsRegexChars + '*');\n    var trimEndRegexp = new RegExp(wsRegexChars + wsRegexChars + '*$');\n    var hasTrimWhitespaceBug = StringPrototype.trim && (\n        ws.trim() !== '' // if ws is not considered whitespace\n        || zeroWidth.trim() === '' // if zero-width IS considered whitespace\n        || mvs.trim() !== (mvsIsWS ? '' : mvs) // if MVS is either wrongly considered whitespace, or, wrongly considered NOT whitespace\n    );\n    defineProperties(StringPrototype, {\n        // https://blog.stevenlevithan.com/archives/faster-trim-javascript\n        // http://perfectionkills.com/whitespace-deviations/\n        trim: function trim() {\n            'use strict';\n\n            if (typeof this === 'undefined' || this === null) {\n                throw new TypeError(\"can't convert \" + this + ' to object');\n            }\n            return $String(this).replace(trimBeginRegexp, '').replace(trimEndRegexp, '');\n        }\n    }, hasTrimWhitespaceBug);\n    var trim = call.bind(String.prototype.trim);\n\n    var hasLastIndexBug = StringPrototype.lastIndexOf && 'abcあい'.lastIndexOf('あい', 2) !== -1;\n    defineProperties(StringPrototype, {\n        lastIndexOf: function lastIndexOf(searchString) {\n            if (typeof this === 'undefined' || this === null) {\n                throw new TypeError(\"can't convert \" + this + ' to object');\n            }\n            var S = $String(this);\n            var searchStr = $String(searchString);\n            var numPos = arguments.length > 1 ? $Number(arguments[1]) : NaN;\n            var pos = isActualNaN(numPos) ? Infinity : ES.ToInteger(numPos);\n            var start = min(max(pos, 0), S.length);\n            var searchLen = searchStr.length;\n            var k = start + searchLen;\n            while (k > 0) {\n                k = max(0, k - searchLen);\n                var index = strIndexOf(strSlice(S, k, start + searchLen), searchStr);\n                if (index !== -1) {\n                    return k + index;\n                }\n            }\n            return -1;\n        }\n    }, hasLastIndexBug);\n\n    var originalLastIndexOf = StringPrototype.lastIndexOf;\n    defineProperties(StringPrototype, {\n        lastIndexOf: function lastIndexOf(searchString) {\n            return originalLastIndexOf.apply(this, arguments);\n        }\n    }, StringPrototype.lastIndexOf.length !== 1);\n\n    var hexRegex = /^[-+]?0[xX]/;\n\n    // ES-5 15.1.2.2\n    if (\n        parseInt(ws + '08') !== 8 // eslint-disable-line radix\n        || parseInt(ws + '0x16') !== 22 // eslint-disable-line radix\n        || (mvsIsWS ? parseInt(mvs + 1) !== 1 : !isNaN(parseInt(mvs + 1))) // eslint-disable-line radix\n    ) {\n        // eslint-disable-next-line no-global-assign, no-implicit-globals\n        parseInt = (function (origParseInt) {\n            return function parseInt(str, radix) {\n                if (this instanceof parseInt) { new origParseInt(); } // eslint-disable-line new-cap, no-new, max-statements-per-line\n                var string = trim(String(str));\n                var defaultedRadix = $Number(radix) || (hexRegex.test(string) ? 16 : 10);\n                return origParseInt(string, defaultedRadix);\n            };\n        }(parseInt));\n    }\n    // Edge 15-18\n    var parseIntFailsToThrowOnBoxedSymbols = (function () {\n        if (typeof Symbol !== 'function') {\n            return false;\n        }\n        try {\n            // eslint-disable-next-line radix\n            parseInt(Object(Symbol.iterator));\n            return true;\n        } catch (e) { /**/ }\n\n        try {\n            // eslint-disable-next-line radix\n            parseInt(Symbol.iterator);\n            return true;\n        } catch (e) { /**/ }\n\n        return false;\n    }());\n    if (parseIntFailsToThrowOnBoxedSymbols) {\n        var symbolValueOf = Symbol.prototype.valueOf;\n        // eslint-disable-next-line no-global-assign, no-implicit-globals\n        parseInt = (function (origParseInt) {\n            return function parseInt(str, radix) {\n                if (this instanceof parseInt) { new origParseInt(); } // eslint-disable-line new-cap, no-new, max-statements-per-line\n                var isSym = typeof str === 'symbol';\n                if (!isSym && str && typeof str === 'object') {\n                    try {\n                        symbolValueOf.call(str);\n                        isSym = true;\n                    } catch (e) { /**/ }\n                }\n                if (isSym) {\n                    // handle Symbols in node 8.3/8.4\n                    // eslint-disable-next-line no-implicit-coercion, no-unused-expressions\n                    '' + str; // jscs:ignore disallowImplicitTypeConversion\n                }\n                var string = trim(String(str));\n                var defaultedRadix = $Number(radix) || (hexRegex.test(string) ? 16 : 10);\n                return origParseInt(string, defaultedRadix);\n            };\n        }(parseInt));\n    }\n\n    // https://es5.github.io/#x15.1.2.3\n    if (1 / parseFloat('-0') !== -Infinity) {\n        // eslint-disable-next-line no-global-assign, no-implicit-globals, no-native-reassign\n        parseFloat = (function (origParseFloat) {\n            return function parseFloat(string) {\n                var inputString = trim(String(string));\n                var result = origParseFloat(inputString);\n                return result === 0 && strSlice(inputString, 0, 1) === '-' ? -0 : result;\n            };\n        }(parseFloat));\n    }\n\n    if (String(new RangeError('test')) !== 'RangeError: test') {\n        var errorToStringShim = function toString() {\n            if (typeof this === 'undefined' || this === null) {\n                throw new TypeError(\"can't convert \" + this + ' to object');\n            }\n            var name = this.name;\n            if (typeof name === 'undefined') {\n                name = 'Error';\n            } else if (typeof name !== 'string') {\n                name = $String(name);\n            }\n            var msg = this.message;\n            if (typeof msg === 'undefined') {\n                msg = '';\n            } else if (typeof msg !== 'string') {\n                msg = $String(msg);\n            }\n            if (!name) {\n                return msg;\n            }\n            if (!msg) {\n                return name;\n            }\n            return name + ': ' + msg;\n        };\n        // can't use defineProperties here because of toString enumeration issue in IE <= 8\n        Error.prototype.toString = errorToStringShim;\n    }\n\n    if (supportsDescriptors) {\n        var ensureNonEnumerable = function (obj, prop) {\n            if (isEnum(obj, prop)) {\n                var desc = Object.getOwnPropertyDescriptor(obj, prop);\n                if (desc.configurable) {\n                    desc.enumerable = false;\n                    Object.defineProperty(obj, prop, desc);\n                }\n            }\n        };\n        ensureNonEnumerable(Error.prototype, 'message');\n        if (Error.prototype.message !== '') {\n            Error.prototype.message = '';\n        }\n        ensureNonEnumerable(Error.prototype, 'name');\n    }\n\n    if (String(/a/mig) !== '/a/gim') {\n        var regexToString = function toString() {\n            var str = '/' + this.source + '/';\n            if (this.global) {\n                str += 'g';\n            }\n            if (this.ignoreCase) {\n                str += 'i';\n            }\n            if (this.multiline) {\n                str += 'm';\n            }\n            return str;\n        };\n        // can't use defineProperties here because of toString enumeration issue in IE <= 8\n        RegExp.prototype.toString = regexToString;\n    }\n}));\n"
  },
  {
    "path": "package.json",
    "content": "{\n\t\"name\": \"es5-shim\",\n\t\"version\": \"4.6.7\",\n\t\"description\": \"ECMAScript 5 compatibility shims for legacy JavaScript engines\",\n\t\"homepage\": \"https://github.com/es-shims/es5-shim/\",\n\t\"contributors\": [\n\t\t\"Kris Kowal <kris@cixar.com> (https://github.com/kriskowal/)\",\n\t\t\"Sami Samhuri <sami.samhuri@gmail.com> (https://samhuri.net/)\",\n\t\t\"Florian Schäfer <florian.schaefer@gmail.com> (https://github.com/fschaefer)\",\n\t\t\"Irakli Gozalishvili <rfobic@gmail.com> (https://gozala.io)\",\n\t\t\"Kit Cambridge <kitcambridge@gmail.com> (https://github.com/kitcambridge)\",\n\t\t\"Jordan Harband <ljharb@gmail.com> (https://github.com/ljharb/)\"\n\t],\n\t\"bugs\": {\n\t\t\"mail\": \"ljharb@gmail.com\",\n\t\t\"url\": \"https://github.com/es-shims/es5-shim/issues\"\n\t},\n\t\"license\": \"MIT\",\n\t\"main\": \"es5-shim.js\",\n\t\"repository\": {\n\t\t\"type\": \"git\",\n\t\t\"url\": \"https://github.com/es-shims/es5-shim.git\"\n\t},\n\t\"scripts\": {\n\t\t\"prepack\": \"npmignore --auto --commentLines=autogenerated\",\n\t\t\"prepublish\": \"not-in-publish || npm run prepublishOnly\",\n\t\t\"prepublishOnly\": \"safe-publish-latest && npm run minify\",\n\t\t\"minify\": \"npm run --silent minify-shim && npm run --silent minify-sham\",\n\t\t\"minify-shim\": \"uglifyjs es5-shim.js --support-ie8 --keep-fnames --comments --source-map=es5-shim.map -m -b ascii_only=true,beautify=false | sed 's/0xde0b6b3a7640080/1000000000000000128/' > es5-shim.min.js\",\n\t\t\"minify-sham\": \"uglifyjs es5-sham.js --support-ie8 --keep-fnames --comments --source-map=es5-sham.map -m -b ascii_only=true,beautify=false > es5-sham.min.js\",\n\t\t\"pretest\": \"npm run --silent lint\",\n\t\t\"test\": \"npm run tests-only\",\n\t\t\"posttest\": \"aud --production\",\n\t\t\"tests-only\": \"nyc jasmine-node --matchall es5-sh*m.js tests/helpers/ tests/spec/\",\n\t\t\"tests-native\": \"jasmine-node --matchall tests/helpers/ tests/spec/\",\n\t\t\"lint\": \"eslint .\"\n\t},\n\t\"devDependencies\": {\n\t\t\"@ljharb/eslint-config\": \"^21.0.0\",\n\t\t\"aud\": \"^2.0.1\",\n\t\t\"eslint\": \"=8.8.0\",\n\t\t\"in-publish\": \"^2.0.1\",\n\t\t\"jasmine-node\": \"^1.16.2\",\n\t\t\"npmignore\": \"^0.3.0\",\n\t\t\"nyc\": \"^10.3.2\",\n\t\t\"safe-publish-latest\": \"^2.0.0\",\n\t\t\"uglify-js\": \"2.7.3\"\n\t},\n\t\"engines\": {\n\t\t\"node\": \">=0.4.0\"\n\t},\n\t\"testling\": {\n\t\t\"browsers\": [\n\t\t\t\"iexplore/6.0..latest\",\n\t\t\t\"firefox/3.0..6.0\",\n\t\t\t\"firefox/18.0..latest\",\n\t\t\t\"firefox/nightly\",\n\t\t\t\"chrome/4.0..10.0\",\n\t\t\t\"chrome/25.0..latest\",\n\t\t\t\"chrome/canary\",\n\t\t\t\"opera/10.0..latest\",\n\t\t\t\"opera/next\",\n\t\t\t\"safari/4.0..latest\",\n\t\t\t\"ipad/6.0..latest\",\n\t\t\t\"iphone/6.0..latest\",\n\t\t\t\"android-browser/4.2\"\n\t\t]\n\t},\n\t\"keywords\": [\n\t\t\"shim\",\n\t\t\"es5\",\n\t\t\"es5 shim\",\n\t\t\"javascript\",\n\t\t\"ecmascript\",\n\t\t\"polyfill\"\n\t],\n\t\"publishConfig\": {\n\t\t\"ignore\": [\n\t\t\t\".github/workflows\"\n\t\t]\n\t}\n}\n"
  },
  {
    "path": "shims.json",
    "content": "{\n    \"Object\": {\n        \"prototype\": {},\n        \"keys\": \"object-keys\"\n    }\n}\n\n"
  },
  {
    "path": "tests/helpers/h-matchers.js",
    "content": "var has = Object.prototype.hasOwnProperty;\nvar getKeys = function (o) {\n    'use strict';\n\n    var key;\n    var a = [];\n    for (key in o) {\n        if (has.call(o, key)) {\n            a.push(key);\n        }\n    }\n    a.sort();\n    return a;\n};\n\nbeforeEach(function () {\n    'use strict';\n\n    this.addMatchers({\n        toExactlyMatch: function (expected) {\n            var a1, a2, l, i, key;\n            var actual = this.actual;\n\n            a1 = getKeys(actual);\n            a2 = getKeys(expected);\n\n            l = a1.length;\n            if (l !== a2.length) {\n                return false;\n            }\n            for (i = 0; i < l; i++) {\n                key = a1[i];\n                expect(key).toEqual(a2[i]);\n                expect(actual[key]).toEqual(expected[key]);\n            }\n\n            return true;\n        }\n    });\n});\n"
  },
  {
    "path": "tests/index.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n\t<meta charset=\"utf-8\" />\n\t<title>Jasmine Spec Runner</title>\n\n\t<link rel=\"shortcut icon\" type=\"image/png\" href=\"lib/jasmine_favicon.png\">\n\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"lib/jasmine.css\">\n\t<script type=\"text/javascript\" src=\"lib/jasmine.js\"></script>\n\t<script type=\"text/javascript\" src=\"lib/jasmine-html.js\"></script>\n\t<script type=\"text/javascript\" src=\"https://cdnjs.cloudflare.com/ajax/libs/json3/3.3.2/json3.min.js\"></script>\n\n\t<!-- include helper files here... -->\n\t<script src=\"helpers/h-matchers.js\"></script>\n\n\t<!-- include source files here... -->\n\t<script src=\"../es5-shim.js\"></script>\n\t<script src=\"../es5-sham.js\"></script>\n\n\t<!-- include spec files here... -->\n\t<script src=\"spec/s-array.js\"></script>\n\t<script src=\"spec/s-date.js\"></script>\n\t<script src=\"spec/s-error.js\"></script>\n\t<script src=\"spec/s-function.js\"></script>\n\t<script src=\"spec/s-global.js\"></script>\n\t<script src=\"spec/s-number.js\"></script>\n\t<script src=\"spec/s-object.js\"></script>\n\t<script src=\"spec/s-string.js\"></script>\n\t<script src=\"spec/s-regexp.js\"></script>\n\n\n\t<script type=\"text/javascript\">\n\t\t(function() {\n\t\t\tvar jasmineEnv = jasmine.getEnv();\n\t\t\tjasmineEnv.updateInterval = 1000;\n\n\t\t\tvar trivialReporter = new jasmine.TrivialReporter();\n\n\t\t\tjasmineEnv.addReporter(trivialReporter);\n\n\t\t\tjasmineEnv.specFilter = function(spec) {\n\t\t\t\treturn trivialReporter.specFilter(spec);\n\t\t\t};\n\n\t\t\tvar currentWindowOnload = window.onload;\n\n\t\t\twindow.onload = function() {\n\t\t\t\tif (currentWindowOnload) {\n\t\t\t\t\tcurrentWindowOnload();\n\t\t\t\t}\n\t\t\t\texecJasmine();\n\t\t\t};\n\n\t\t\tfunction execJasmine() {\n\t\t\t\tjasmineEnv.execute();\n\t\t\t}\n\n\t\t})();\n\t</script>\n\n</head>\n\n<body>\n</body>\n</html>\n"
  },
  {
    "path": "tests/index.min.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n\t<title>Jasmine Spec Runner</title>\n\n\t<link rel=\"shortcut icon\" type=\"image/png\" href=\"lib/jasmine_favicon.png\">\n\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"lib/jasmine.css\">\n\t<script type=\"text/javascript\" src=\"lib/jasmine.js\"></script>\n\t<script type=\"text/javascript\" src=\"lib/jasmine-html.js\"></script>\n\t<script type=\"text/javascript\" src=\"https://cdnjs.cloudflare.com/ajax/libs/json3/3.3.2/json3.min.js\"></script>\n\n\n\t<!-- include helper files here... -->\n\t<script src=\"helpers/h-matchers.js\"></script>\n\n\t<!-- include source files here... -->\n\t<script src=\"../es5-shim.min.js\"></script>\n\n\t<!-- include spec files here... -->\n\t<script src=\"spec/s-array.js\"></script>\n\t<script src=\"spec/s-date.js\"></script>\n\t<script src=\"spec/s-error.js\"></script>\n\t<script src=\"spec/s-function.js\"></script>\n\t<script src=\"spec/s-global.js\"></script>\n\t<script src=\"spec/s-number.js\"></script>\n\t<script src=\"spec/s-object.js\"></script>\n\t<script src=\"spec/s-string.js\"></script>\n\n\n\t<script type=\"text/javascript\">\n\t\t(function() {\n\t\t\tvar jasmineEnv = jasmine.getEnv();\n\t\t\tjasmineEnv.updateInterval = 1000;\n\n\t\t\tvar trivialReporter = new jasmine.TrivialReporter();\n\n\t\t\tjasmineEnv.addReporter(trivialReporter);\n\n\t\t\tjasmineEnv.specFilter = function(spec) {\n\t\t\t\treturn trivialReporter.specFilter(spec);\n\t\t\t};\n\n\t\t\tvar currentWindowOnload = window.onload;\n\n\t\t\twindow.onload = function() {\n\t\t\t\tif (currentWindowOnload) {\n\t\t\t\t\tcurrentWindowOnload();\n\t\t\t\t}\n\t\t\t\texecJasmine();\n\t\t\t};\n\n\t\t\tfunction execJasmine() {\n\t\t\t\tjasmineEnv.execute();\n\t\t\t}\n\n\t\t})();\n\t</script>\n\n</head>\n\n<body>\n</body>\n</html>\n"
  },
  {
    "path": "tests/lib/jasmine-html.js",
    "content": "jasmine.TrivialReporter = function(doc) {\n  this.document = doc || document;\n  this.suiteDivs = {};\n  this.logRunningSpecs = false;\n};\n\njasmine.TrivialReporter.prototype.createDom = function(type, attrs, childrenVarArgs) {\n  var el = document.createElement(type);\n\n  for (var i = 2; i < arguments.length; i++) {\n    var child = arguments[i];\n\n    if (typeof child === 'string') {\n      el.appendChild(document.createTextNode(child));\n    } else {\n      if (child) { el.appendChild(child); }\n    }\n  }\n\n  for (var attr in attrs) {\n    if (attr == \"className\") {\n      el[attr] = attrs[attr];\n    } else {\n      el.setAttribute(attr, attrs[attr]);\n    }\n  }\n\n  return el;\n};\n\njasmine.TrivialReporter.prototype.reportRunnerStarting = function(runner) {\n  var showPassed, showSkipped;\n\n  this.outerDiv = this.createDom('div', { className: 'jasmine_reporter' },\n      this.createDom('div', { className: 'banner' },\n        this.createDom('div', { className: 'logo' },\n            this.createDom('span', { className: 'title' }, \"Jasmine\"),\n            this.createDom('span', { className: 'version' }, runner.env.versionString())),\n        this.createDom('div', { className: 'options' },\n            \"Show \",\n            showPassed = this.createDom('input', { id: \"__jasmine_TrivialReporter_showPassed__\", type: 'checkbox' }),\n            this.createDom('label', { \"for\": \"__jasmine_TrivialReporter_showPassed__\" }, \" passed \"),\n            showSkipped = this.createDom('input', { id: \"__jasmine_TrivialReporter_showSkipped__\", type: 'checkbox' }),\n            this.createDom('label', { \"for\": \"__jasmine_TrivialReporter_showSkipped__\" }, \" skipped\")\n            )\n          ),\n\n      this.runnerDiv = this.createDom('div', { className: 'runner running' },\n          this.createDom('a', { className: 'run_spec', href: '?' }, \"run all\"),\n          this.runnerMessageSpan = this.createDom('span', {}, \"Running...\"),\n          this.finishedAtSpan = this.createDom('span', { className: 'finished-at' }, \"\"))\n      );\n\n  this.document.body.appendChild(this.outerDiv);\n\n  var suites = runner.suites();\n  for (var i = 0; i < suites.length; i++) {\n    var suite = suites[i];\n    var suiteDiv = this.createDom('div', { className: 'suite' },\n        this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, \"run\"),\n        this.createDom('a', { className: 'description', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, suite.description));\n    this.suiteDivs[suite.id] = suiteDiv;\n    var parentDiv = this.outerDiv;\n    if (suite.parentSuite) {\n      parentDiv = this.suiteDivs[suite.parentSuite.id];\n    }\n    parentDiv.appendChild(suiteDiv);\n  }\n\n  this.startedAt = new Date();\n\n  var self = this;\n  showPassed.onclick = function(evt) {\n    if (showPassed.checked) {\n      self.outerDiv.className += ' show-passed';\n    } else {\n      self.outerDiv.className = self.outerDiv.className.replace(/ show-passed/, '');\n    }\n  };\n\n  showSkipped.onclick = function(evt) {\n    if (showSkipped.checked) {\n      self.outerDiv.className += ' show-skipped';\n    } else {\n      self.outerDiv.className = self.outerDiv.className.replace(/ show-skipped/, '');\n    }\n  };\n};\n\njasmine.TrivialReporter.prototype.reportRunnerResults = function(runner) {\n  var results = runner.results();\n  var className = (results.failedCount > 0) ? \"runner failed\" : \"runner passed\";\n  this.runnerDiv.setAttribute(\"class\", className);\n  //do it twice for IE\n  this.runnerDiv.setAttribute(\"className\", className);\n  var specs = runner.specs();\n  var specCount = 0;\n  for (var i = 0; i < specs.length; i++) {\n    if (this.specFilter(specs[i])) {\n      specCount++;\n    }\n  }\n  var message = \"\" + specCount + \" spec\" + (specCount == 1 ? \"\" : \"s\" ) + \", \" + results.failedCount + \" failure\" + ((results.failedCount == 1) ? \"\" : \"s\");\n  message += \" in \" + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + \"s\";\n  this.runnerMessageSpan.replaceChild(this.createDom('a', { className: 'description', href: '?'}, message), this.runnerMessageSpan.firstChild);\n\n  this.finishedAtSpan.appendChild(document.createTextNode(\"Finished at \" + new Date().toString()));\n};\n\njasmine.TrivialReporter.prototype.reportSuiteResults = function(suite) {\n  var results = suite.results();\n  var status = results.passed() ? 'passed' : 'failed';\n  if (results.totalCount === 0) { // todo: change this to check results.skipped\n    status = 'skipped';\n  }\n  this.suiteDivs[suite.id].className += \" \" + status;\n};\n\njasmine.TrivialReporter.prototype.reportSpecStarting = function(spec) {\n  if (this.logRunningSpecs) {\n    this.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...');\n  }\n};\n\njasmine.TrivialReporter.prototype.reportSpecResults = function(spec) {\n  var results = spec.results();\n  var status = results.passed() ? 'passed' : 'failed';\n  if (results.skipped) {\n    status = 'skipped';\n  }\n  var specDiv = this.createDom('div', { className: 'spec '  + status },\n      this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(spec.getFullName()) }, \"run\"),\n      this.createDom('a', {\n        className: 'description',\n        href: '?spec=' + encodeURIComponent(spec.getFullName()),\n        title: spec.getFullName()\n      }, spec.description));\n\n\n  var resultItems = results.getItems();\n  var messagesDiv = this.createDom('div', { className: 'messages' });\n  for (var i = 0; i < resultItems.length; i++) {\n    var result = resultItems[i];\n\n    if (result.type == 'log') {\n      messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString()));\n    } else if (result.type == 'expect' && result.passed && !result.passed()) {\n      messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message));\n\n      if (result.trace.stack) {\n        messagesDiv.appendChild(this.createDom('div', {className: 'stackTrace'}, result.trace.stack));\n      }\n    }\n  }\n\n  if (messagesDiv.childNodes.length > 0) {\n    specDiv.appendChild(messagesDiv);\n  }\n\n  this.suiteDivs[spec.suite.id].appendChild(specDiv);\n};\n\njasmine.TrivialReporter.prototype.log = function() {\n  var console = jasmine.getGlobal().console;\n  if (console && console.log) {\n    if (console.log.apply) {\n      console.log.apply(console, arguments);\n    } else {\n      console.log(arguments); // ie fix: console.log.apply doesn't exist on ie\n    }\n  }\n};\n\njasmine.TrivialReporter.prototype.getLocation = function() {\n  return this.document.location;\n};\n\njasmine.TrivialReporter.prototype.specFilter = function(spec) {\n  var paramMap = {};\n  var params = this.getLocation().search.substring(1).split('&');\n  for (var i = 0; i < params.length; i++) {\n    var p = params[i].split('=');\n    paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);\n  }\n\n  if (!paramMap.spec) {\n    return true;\n  }\n  return spec.getFullName().indexOf(paramMap.spec) === 0;\n};\n"
  },
  {
    "path": "tests/lib/jasmine.css",
    "content": "body {\n  font-family: \"Helvetica Neue Light\", \"Lucida Grande\", \"Calibri\", \"Arial\", sans-serif;\n}\n\n\n.jasmine_reporter a:visited, .jasmine_reporter a {\n  color: #303; \n}\n\n.jasmine_reporter a:hover, .jasmine_reporter a:active {\n  color: blue; \n}\n\n.run_spec {\n  float:right;\n  padding-right: 5px;\n  font-size: .8em;\n  text-decoration: none;\n}\n\n.jasmine_reporter {\n  margin: 0 5px;\n}\n\n.banner {\n  color: #303;\n  background-color: #fef;\n  padding: 5px;\n}\n\n.logo {\n  float: left;\n  font-size: 1.1em;\n  padding-left: 5px;\n}\n\n.logo .version {\n  font-size: .6em;\n  padding-left: 1em;\n}\n\n.runner.running {\n  background-color: yellow;\n}\n\n\n.options {\n  text-align: right;\n  font-size: .8em;\n}\n\n\n\n\n.suite {\n  border: 1px outset gray;\n  margin: 5px 0;\n  padding-left: 1em;\n}\n\n.suite .suite {\n  margin: 5px; \n}\n\n.suite.passed {\n  background-color: #dfd;\n}\n\n.suite.failed {\n  background-color: #fdd;\n}\n\n.spec {\n  margin: 5px;\n  padding-left: 1em;\n  clear: both;\n}\n\n.spec.failed, .spec.passed, .spec.skipped {\n  padding-bottom: 5px;\n  border: 1px solid gray;\n}\n\n.spec.failed {\n  background-color: #fbb;\n  border-color: red;\n}\n\n.spec.passed {\n  background-color: #bfb;\n  border-color: green;\n}\n\n.spec.skipped {\n  background-color: #bbb;\n}\n\n.messages {\n  border-left: 1px dashed gray;\n  padding-left: 1em;\n  padding-right: 1em;\n}\n\n.passed {\n  background-color: #cfc;\n  display: none;\n}\n\n.failed {\n  background-color: #fbb;\n}\n\n.skipped {\n  color: #777;\n  background-color: #eee;\n  display: none;\n}\n\n\n/*.resultMessage {*/\n  /*white-space: pre;*/\n/*}*/\n\n.resultMessage span.result {\n  display: block;\n  line-height: 2em;\n  color: black;\n}\n\n.resultMessage .mismatch {\n  color: black;\n}\n\n.stackTrace {\n  white-space: pre;\n  font-size: .8em;\n  margin-left: 10px;\n  max-height: 5em;\n  overflow: auto;\n  border: 1px inset red;\n  padding: 1em;\n  background: #eef;\n}\n\n.finished-at {\n  padding-left: 1em;\n  font-size: .6em;\n}\n\n.show-passed .passed,\n.show-skipped .skipped {\n  display: block;\n}\n\n\n#jasmine_content {\n  position:fixed;\n  right: 100%;\n}\n\n.runner {\n  border: 1px solid gray;\n  display: block;\n  margin: 5px 0;\n  padding: 2px 0 2px 10px;\n}\n"
  },
  {
    "path": "tests/lib/jasmine.js",
    "content": "var isCommonJS = typeof window == \"undefined\" && typeof exports == \"object\";\n\n/**\n * Top level namespace for Jasmine, a lightweight JavaScript BDD/spec/testing framework.\n *\n * @namespace\n */\nvar jasmine = {};\nif (isCommonJS) exports.jasmine = jasmine;\n/**\n * @private\n */\njasmine.unimplementedMethod_ = function() {\n  throw new Error(\"unimplemented method\");\n};\n\n/**\n * Use <code>jasmine.undefined</code> instead of <code>undefined</code>, since <code>undefined</code> is just\n * a plain old variable and may be redefined by somebody else.\n *\n * @private\n */\njasmine.undefined = jasmine.___undefined___;\n\n/**\n * Show diagnostic messages in the console if set to true\n *\n */\njasmine.VERBOSE = false;\n\n/**\n * Default interval in milliseconds for event loop yields (e.g. to allow network activity or to refresh the screen with the HTML-based runner). Small values here may result in slow test running. Zero means no updates until all tests have completed.\n *\n */\njasmine.DEFAULT_UPDATE_INTERVAL = 250;\n\n/**\n * Maximum levels of nesting that will be included when an object is pretty-printed\n */\njasmine.MAX_PRETTY_PRINT_DEPTH = 40;\n\n/**\n * Default timeout interval in milliseconds for waitsFor() blocks.\n */\njasmine.DEFAULT_TIMEOUT_INTERVAL = 5000;\n\n/**\n * By default exceptions thrown in the context of a test are caught by jasmine so that it can run the remaining tests in the suite.\n * Set to false to let the exception bubble up in the browser.\n *\n */\njasmine.CATCH_EXCEPTIONS = true;\n\njasmine.getGlobal = function() {\n  function getGlobal() {\n    return this;\n  }\n\n  return getGlobal();\n};\n\n/**\n * Allows for bound functions to be compared.  Internal use only.\n *\n * @ignore\n * @private\n * @param base {Object} bound 'this' for the function\n * @param name {Function} function to find\n */\njasmine.bindOriginal_ = function(base, name) {\n  var original = base[name];\n  if (original.apply) {\n    return function() {\n      return original.apply(base, arguments);\n    };\n  } else {\n    // IE support\n    return jasmine.getGlobal()[name];\n  }\n};\n\njasmine.setTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'setTimeout');\njasmine.clearTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearTimeout');\njasmine.setInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'setInterval');\njasmine.clearInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearInterval');\n\njasmine.MessageResult = function(values) {\n  this.type = 'log';\n  this.values = values;\n  this.trace = new Error(); // todo: test better\n};\n\njasmine.MessageResult.prototype.toString = function() {\n  var text = \"\";\n  for (var i = 0; i < this.values.length; i++) {\n    if (i > 0) text += \" \";\n    if (jasmine.isString_(this.values[i])) {\n      text += this.values[i];\n    } else {\n      text += jasmine.pp(this.values[i]);\n    }\n  }\n  return text;\n};\n\njasmine.ExpectationResult = function(params) {\n  this.type = 'expect';\n  this.matcherName = params.matcherName;\n  this.passed_ = params.passed;\n  this.expected = params.expected;\n  this.actual = params.actual;\n  this.message = this.passed_ ? 'Passed.' : params.message;\n\n  var trace = (params.trace || new Error(this.message));\n  this.trace = this.passed_ ? '' : trace;\n};\n\njasmine.ExpectationResult.prototype.toString = function () {\n  return this.message;\n};\n\njasmine.ExpectationResult.prototype.passed = function () {\n  return this.passed_;\n};\n\n/**\n * Getter for the Jasmine environment. Ensures one gets created\n */\njasmine.getEnv = function() {\n  var env = jasmine.currentEnv_ = jasmine.currentEnv_ || new jasmine.Env();\n  return env;\n};\n\n/**\n * @ignore\n * @private\n * @param value\n * @returns {Boolean}\n */\njasmine.isArray_ = function(value) {\n  return jasmine.isA_(\"Array\", value);\n};\n\n/**\n * @ignore\n * @private\n * @param value\n * @returns {Boolean}\n */\njasmine.isString_ = function(value) {\n  return jasmine.isA_(\"String\", value);\n};\n\n/**\n * @ignore\n * @private\n * @param value\n * @returns {Boolean}\n */\njasmine.isNumber_ = function(value) {\n  return jasmine.isA_(\"Number\", value);\n};\n\n/**\n * @ignore\n * @private\n * @param {String} typeName\n * @param value\n * @returns {Boolean}\n */\njasmine.isA_ = function(typeName, value) {\n  return Object.prototype.toString.apply(value) === '[object ' + typeName + ']';\n};\n\n/**\n * Pretty printer for expecations.  Takes any object and turns it into a human-readable string.\n *\n * @param value {Object} an object to be outputted\n * @returns {String}\n */\njasmine.pp = function(value) {\n  var stringPrettyPrinter = new jasmine.StringPrettyPrinter();\n  stringPrettyPrinter.format(value);\n  return stringPrettyPrinter.string;\n};\n\n/**\n * Returns true if the object is a DOM Node.\n *\n * @param {Object} obj object to check\n * @returns {Boolean}\n */\njasmine.isDomNode = function(obj) {\n  return obj.nodeType > 0;\n};\n\n/**\n * Returns a matchable 'generic' object of the class type.  For use in expecations of type when values don't matter.\n *\n * @example\n * // don't care about which function is passed in, as long as it's a function\n * expect(mySpy).toHaveBeenCalledWith(jasmine.any(Function));\n *\n * @param {Class} clazz\n * @returns matchable object of the type clazz\n */\njasmine.any = function(clazz) {\n  return new jasmine.Matchers.Any(clazz);\n};\n\n/**\n * Returns a matchable subset of a JSON object. For use in expectations when you don't care about all of the\n * attributes on the object.\n *\n * @example\n * // don't care about any other attributes than foo.\n * expect(mySpy).toHaveBeenCalledWith(jasmine.objectContaining({foo: \"bar\"});\n *\n * @param sample {Object} sample\n * @returns matchable object for the sample\n */\njasmine.objectContaining = function (sample) {\n    return new jasmine.Matchers.ObjectContaining(sample);\n};\n\n/**\n * Jasmine Spies are test doubles that can act as stubs, spies, fakes or when used in an expecation, mocks.\n *\n * Spies should be created in test setup, before expectations.  They can then be checked, using the standard Jasmine\n * expectation syntax. Spies can be checked if they were called or not and what the calling params were.\n *\n * A Spy has the following fields: wasCalled, callCount, mostRecentCall, and argsForCall (see docs).\n *\n * Spies are torn down at the end of every spec.\n *\n * Note: Do <b>not</b> call new jasmine.Spy() directly - a spy must be created using spyOn, jasmine.createSpy or jasmine.createSpyObj.\n *\n * @example\n * // a stub\n * var myStub = jasmine.createSpy('myStub');  // can be used anywhere\n *\n * // spy example\n * var foo = {\n *   not: function(bool) { return !bool; }\n * }\n *\n * // actual foo.not will not be called, execution stops\n * spyOn(foo, 'not');\n\n // foo.not spied upon, execution will continue to implementation\n * spyOn(foo, 'not').andCallThrough();\n *\n * // fake example\n * var foo = {\n *   not: function(bool) { return !bool; }\n * }\n *\n * // foo.not(val) will return val\n * spyOn(foo, 'not').andCallFake(function(value) {return value;});\n *\n * // mock example\n * foo.not(7 == 7);\n * expect(foo.not).toHaveBeenCalled();\n * expect(foo.not).toHaveBeenCalledWith(true);\n *\n * @constructor\n * @see spyOn, jasmine.createSpy, jasmine.createSpyObj\n * @param {String} name\n */\njasmine.Spy = function(name) {\n  /**\n   * The name of the spy, if provided.\n   */\n  this.identity = name || 'unknown';\n  /**\n   *  Is this Object a spy?\n   */\n  this.isSpy = true;\n  /**\n   * The actual function this spy stubs.\n   */\n  this.plan = function() {\n  };\n  /**\n   * Tracking of the most recent call to the spy.\n   * @example\n   * var mySpy = jasmine.createSpy('foo');\n   * mySpy(1, 2);\n   * mySpy.mostRecentCall.args = [1, 2];\n   */\n  this.mostRecentCall = {};\n\n  /**\n   * Holds arguments for each call to the spy, indexed by call count\n   * @example\n   * var mySpy = jasmine.createSpy('foo');\n   * mySpy(1, 2);\n   * mySpy(7, 8);\n   * mySpy.mostRecentCall.args = [7, 8];\n   * mySpy.argsForCall[0] = [1, 2];\n   * mySpy.argsForCall[1] = [7, 8];\n   */\n  this.argsForCall = [];\n  this.calls = [];\n};\n\n/**\n * Tells a spy to call through to the actual implemenatation.\n *\n * @example\n * var foo = {\n *   bar: function() { // do some stuff }\n * }\n *\n * // defining a spy on an existing property: foo.bar\n * spyOn(foo, 'bar').andCallThrough();\n */\njasmine.Spy.prototype.andCallThrough = function() {\n  this.plan = this.originalValue;\n  return this;\n};\n\n/**\n * For setting the return value of a spy.\n *\n * @example\n * // defining a spy from scratch: foo() returns 'baz'\n * var foo = jasmine.createSpy('spy on foo').andReturn('baz');\n *\n * // defining a spy on an existing property: foo.bar() returns 'baz'\n * spyOn(foo, 'bar').andReturn('baz');\n *\n * @param {Object} value\n */\njasmine.Spy.prototype.andReturn = function(value) {\n  this.plan = function() {\n    return value;\n  };\n  return this;\n};\n\n/**\n * For throwing an exception when a spy is called.\n *\n * @example\n * // defining a spy from scratch: foo() throws an exception w/ message 'ouch'\n * var foo = jasmine.createSpy('spy on foo').andThrow('baz');\n *\n * // defining a spy on an existing property: foo.bar() throws an exception w/ message 'ouch'\n * spyOn(foo, 'bar').andThrow('baz');\n *\n * @param {String} exceptionMsg\n */\njasmine.Spy.prototype.andThrow = function(exceptionMsg) {\n  this.plan = function() {\n    throw exceptionMsg;\n  };\n  return this;\n};\n\n/**\n * Calls an alternate implementation when a spy is called.\n *\n * @example\n * var baz = function() {\n *   // do some stuff, return something\n * }\n * // defining a spy from scratch: foo() calls the function baz\n * var foo = jasmine.createSpy('spy on foo').andCall(baz);\n *\n * // defining a spy on an existing property: foo.bar() calls an anonymnous function\n * spyOn(foo, 'bar').andCall(function() { return 'baz';} );\n *\n * @param {Function} fakeFunc\n */\njasmine.Spy.prototype.andCallFake = function(fakeFunc) {\n  this.plan = fakeFunc;\n  return this;\n};\n\n/**\n * Resets all of a spy's the tracking variables so that it can be used again.\n *\n * @example\n * spyOn(foo, 'bar');\n *\n * foo.bar();\n *\n * expect(foo.bar.callCount).toEqual(1);\n *\n * foo.bar.reset();\n *\n * expect(foo.bar.callCount).toEqual(0);\n */\njasmine.Spy.prototype.reset = function() {\n  this.wasCalled = false;\n  this.callCount = 0;\n  this.argsForCall = [];\n  this.calls = [];\n  this.mostRecentCall = {};\n};\n\njasmine.createSpy = function(name) {\n\n  var spyObj = function() {\n    spyObj.wasCalled = true;\n    spyObj.callCount++;\n    var args = jasmine.util.argsToArray(arguments);\n    spyObj.mostRecentCall.object = this;\n    spyObj.mostRecentCall.args = args;\n    spyObj.argsForCall.push(args);\n    spyObj.calls.push({object: this, args: args});\n    return spyObj.plan.apply(this, arguments);\n  };\n\n  var spy = new jasmine.Spy(name);\n\n  for (var prop in spy) {\n    spyObj[prop] = spy[prop];\n  }\n\n  spyObj.reset();\n\n  return spyObj;\n};\n\n/**\n * Determines whether an object is a spy.\n *\n * @param {jasmine.Spy|Object} putativeSpy\n * @returns {Boolean}\n */\njasmine.isSpy = function(putativeSpy) {\n  return putativeSpy && putativeSpy.isSpy;\n};\n\n/**\n * Creates a more complicated spy: an Object that has every property a function that is a spy.  Used for stubbing something\n * large in one call.\n *\n * @param {String} baseName name of spy class\n * @param {Array} methodNames array of names of methods to make spies\n */\njasmine.createSpyObj = function(baseName, methodNames) {\n  if (!jasmine.isArray_(methodNames) || methodNames.length === 0) {\n    throw new Error('createSpyObj requires a non-empty array of method names to create spies for');\n  }\n  var obj = {};\n  for (var i = 0; i < methodNames.length; i++) {\n    obj[methodNames[i]] = jasmine.createSpy(baseName + '.' + methodNames[i]);\n  }\n  return obj;\n};\n\n/**\n * All parameters are pretty-printed and concatenated together, then written to the current spec's output.\n *\n * Be careful not to leave calls to <code>jasmine.log</code> in production code.\n */\njasmine.log = function() {\n  var spec = jasmine.getEnv().currentSpec;\n  spec.log.apply(spec, arguments);\n};\n\n/**\n * Function that installs a spy on an existing object's method name.  Used within a Spec to create a spy.\n *\n * @example\n * // spy example\n * var foo = {\n *   not: function(bool) { return !bool; }\n * }\n * spyOn(foo, 'not'); // actual foo.not will not be called, execution stops\n *\n * @see jasmine.createSpy\n * @param obj\n * @param methodName\n * @return {jasmine.Spy} a Jasmine spy that can be chained with all spy methods\n */\nvar spyOn = function(obj, methodName) {\n  return jasmine.getEnv().currentSpec.spyOn(obj, methodName);\n};\nif (isCommonJS) exports.spyOn = spyOn;\n\n/**\n * Creates a Jasmine spec that will be added to the current suite.\n *\n * // TODO: pending tests\n *\n * @example\n * it('should be true', function() {\n *   expect(true).toEqual(true);\n * });\n *\n * @param {String} desc description of this specification\n * @param {Function} func defines the preconditions and expectations of the spec\n */\nvar it = function(desc, func) {\n  return jasmine.getEnv().it(desc, func);\n};\nif (isCommonJS) exports.it = it;\n\n/**\n * Creates a <em>disabled</em> Jasmine spec.\n *\n * A convenience method that allows existing specs to be disabled temporarily during development.\n *\n * @param {String} desc description of this specification\n * @param {Function} func defines the preconditions and expectations of the spec\n */\nvar xit = function(desc, func) {\n  return jasmine.getEnv().xit(desc, func);\n};\nif (isCommonJS) exports.xit = xit;\n\n/**\n * Starts a chain for a Jasmine expectation.\n *\n * It is passed an Object that is the actual value and should chain to one of the many\n * jasmine.Matchers functions.\n *\n * @param {Object} actual Actual value to test against and expected value\n * @return {jasmine.Matchers}\n */\nvar expect = function(actual) {\n  return jasmine.getEnv().currentSpec.expect(actual);\n};\nif (isCommonJS) exports.expect = expect;\n\n/**\n * Defines part of a jasmine spec.  Used in cominbination with waits or waitsFor in asynchrnous specs.\n *\n * @param {Function} func Function that defines part of a jasmine spec.\n */\nvar runs = function(func) {\n  jasmine.getEnv().currentSpec.runs(func);\n};\nif (isCommonJS) exports.runs = runs;\n\n/**\n * Waits a fixed time period before moving to the next block.\n *\n * @deprecated Use waitsFor() instead\n * @param {Number} timeout milliseconds to wait\n */\nvar waits = function(timeout) {\n  jasmine.getEnv().currentSpec.waits(timeout);\n};\nif (isCommonJS) exports.waits = waits;\n\n/**\n * Waits for the latchFunction to return true before proceeding to the next block.\n *\n * @param {Function} latchFunction\n * @param {String} optional_timeoutMessage\n * @param {Number} optional_timeout\n */\nvar waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) {\n  jasmine.getEnv().currentSpec.waitsFor.apply(jasmine.getEnv().currentSpec, arguments);\n};\nif (isCommonJS) exports.waitsFor = waitsFor;\n\n/**\n * A function that is called before each spec in a suite.\n *\n * Used for spec setup, including validating assumptions.\n *\n * @param {Function} beforeEachFunction\n */\nvar beforeEach = function(beforeEachFunction) {\n  jasmine.getEnv().beforeEach(beforeEachFunction);\n};\nif (isCommonJS) exports.beforeEach = beforeEach;\n\n/**\n * A function that is called after each spec in a suite.\n *\n * Used for restoring any state that is hijacked during spec execution.\n *\n * @param {Function} afterEachFunction\n */\nvar afterEach = function(afterEachFunction) {\n  jasmine.getEnv().afterEach(afterEachFunction);\n};\nif (isCommonJS) exports.afterEach = afterEach;\n\n/**\n * Defines a suite of specifications.\n *\n * Stores the description and all defined specs in the Jasmine environment as one suite of specs. Variables declared\n * are accessible by calls to beforeEach, it, and afterEach. Describe blocks can be nested, allowing for specialization\n * of setup in some tests.\n *\n * @example\n * // TODO: a simple suite\n *\n * // TODO: a simple suite with a nested describe block\n *\n * @param {String} description A string, usually the class under test.\n * @param {Function} specDefinitions function that defines several specs.\n */\nvar describe = function(description, specDefinitions) {\n  return jasmine.getEnv().describe(description, specDefinitions);\n};\nif (isCommonJS) exports.describe = describe;\n\n/**\n * Disables a suite of specifications.  Used to disable some suites in a file, or files, temporarily during development.\n *\n * @param {String} description A string, usually the class under test.\n * @param {Function} specDefinitions function that defines several specs.\n */\nvar xdescribe = function(description, specDefinitions) {\n  return jasmine.getEnv().xdescribe(description, specDefinitions);\n};\nif (isCommonJS) exports.xdescribe = xdescribe;\n\n\n// Provide the XMLHttpRequest class for IE 5.x-6.x:\njasmine.XmlHttpRequest = (typeof XMLHttpRequest == \"undefined\") ? function() {\n  function tryIt(f) {\n    try {\n      return f();\n    } catch(e) {\n    }\n    return null;\n  }\n\n  var xhr = tryIt(function() {\n    return new ActiveXObject(\"Msxml2.XMLHTTP.6.0\");\n  }) ||\n    tryIt(function() {\n      return new ActiveXObject(\"Msxml2.XMLHTTP.3.0\");\n    }) ||\n    tryIt(function() {\n      return new ActiveXObject(\"Msxml2.XMLHTTP\");\n    }) ||\n    tryIt(function() {\n      return new ActiveXObject(\"Microsoft.XMLHTTP\");\n    });\n\n  if (!xhr) throw new Error(\"This browser does not support XMLHttpRequest.\");\n\n  return xhr;\n} : XMLHttpRequest;\n/**\n * @namespace\n */\njasmine.util = {};\n\n/**\n * Declare that a child class inherit it's prototype from the parent class.\n *\n * @private\n * @param {Function} childClass\n * @param {Function} parentClass\n */\njasmine.util.inherit = function(childClass, parentClass) {\n  /**\n   * @private\n   */\n  var subclass = function() {\n  };\n  subclass.prototype = parentClass.prototype;\n  childClass.prototype = new subclass();\n};\n\njasmine.util.formatException = function(e) {\n  var lineNumber;\n  if (e.line) {\n    lineNumber = e.line;\n  }\n  else if (e.lineNumber) {\n    lineNumber = e.lineNumber;\n  }\n\n  var file;\n\n  if (e.sourceURL) {\n    file = e.sourceURL;\n  }\n  else if (e.fileName) {\n    file = e.fileName;\n  }\n\n  var message = (e.name && e.message) ? (e.name + ': ' + e.message) : e.toString();\n\n  if (file && lineNumber) {\n    message += ' in ' + file + ' (line ' + lineNumber + ')';\n  }\n\n  return message;\n};\n\njasmine.util.htmlEscape = function(str) {\n  if (!str) return str;\n  return str.replace(/&/g, '&amp;')\n    .replace(/</g, '&lt;')\n    .replace(/>/g, '&gt;');\n};\n\njasmine.util.argsToArray = function(args) {\n  var arrayOfArgs = [];\n  for (var i = 0; i < args.length; i++) arrayOfArgs.push(args[i]);\n  return arrayOfArgs;\n};\n\njasmine.util.extend = function(destination, source) {\n  for (var property in source) destination[property] = source[property];\n  return destination;\n};\n\n/**\n * Environment for Jasmine\n *\n * @constructor\n */\njasmine.Env = function() {\n  this.currentSpec = null;\n  this.currentSuite = null;\n  this.currentRunner_ = new jasmine.Runner(this);\n\n  this.reporter = new jasmine.MultiReporter();\n\n  this.updateInterval = jasmine.DEFAULT_UPDATE_INTERVAL;\n  this.defaultTimeoutInterval = jasmine.DEFAULT_TIMEOUT_INTERVAL;\n  this.lastUpdate = 0;\n  this.specFilter = function() {\n    return true;\n  };\n\n  this.nextSpecId_ = 0;\n  this.nextSuiteId_ = 0;\n  this.equalityTesters_ = [];\n\n  // wrap matchers\n  this.matchersClass = function() {\n    jasmine.Matchers.apply(this, arguments);\n  };\n  jasmine.util.inherit(this.matchersClass, jasmine.Matchers);\n\n  jasmine.Matchers.wrapInto_(jasmine.Matchers.prototype, this.matchersClass);\n};\n\n\njasmine.Env.prototype.setTimeout = jasmine.setTimeout;\njasmine.Env.prototype.clearTimeout = jasmine.clearTimeout;\njasmine.Env.prototype.setInterval = jasmine.setInterval;\njasmine.Env.prototype.clearInterval = jasmine.clearInterval;\n\n/**\n * @returns an object containing jasmine version build info, if set.\n */\njasmine.Env.prototype.version = function () {\n  if (jasmine.version_) {\n    return jasmine.version_;\n  } else {\n    throw new Error('Version not set');\n  }\n};\n\n/**\n * @returns string containing jasmine version build info, if set.\n */\njasmine.Env.prototype.versionString = function() {\n  if (!jasmine.version_) {\n    return \"version unknown\";\n  }\n\n  var version = this.version();\n  var versionString = version.major + \".\" + version.minor + \".\" + version.build;\n  if (version.release_candidate) {\n    versionString += \".rc\" + version.release_candidate;\n  }\n  versionString += \" revision \" + version.revision;\n  return versionString;\n};\n\n/**\n * @returns a sequential integer starting at 0\n */\njasmine.Env.prototype.nextSpecId = function () {\n  return this.nextSpecId_++;\n};\n\n/**\n * @returns a sequential integer starting at 0\n */\njasmine.Env.prototype.nextSuiteId = function () {\n  return this.nextSuiteId_++;\n};\n\n/**\n * Register a reporter to receive status updates from Jasmine.\n * @param {jasmine.Reporter} reporter An object which will receive status updates.\n */\njasmine.Env.prototype.addReporter = function(reporter) {\n  this.reporter.addReporter(reporter);\n};\n\njasmine.Env.prototype.execute = function() {\n  this.currentRunner_.execute();\n};\n\njasmine.Env.prototype.describe = function(description, specDefinitions) {\n  var suite = new jasmine.Suite(this, description, specDefinitions, this.currentSuite);\n\n  var parentSuite = this.currentSuite;\n  if (parentSuite) {\n    parentSuite.add(suite);\n  } else {\n    this.currentRunner_.add(suite);\n  }\n\n  this.currentSuite = suite;\n\n  var declarationError = null;\n  try {\n    specDefinitions.call(suite);\n  } catch(e) {\n    declarationError = e;\n  }\n\n  if (declarationError) {\n    this.it(\"encountered a declaration exception\", function() {\n      throw declarationError;\n    });\n  }\n\n  this.currentSuite = parentSuite;\n\n  return suite;\n};\n\njasmine.Env.prototype.beforeEach = function(beforeEachFunction) {\n  if (this.currentSuite) {\n    this.currentSuite.beforeEach(beforeEachFunction);\n  } else {\n    this.currentRunner_.beforeEach(beforeEachFunction);\n  }\n};\n\njasmine.Env.prototype.currentRunner = function () {\n  return this.currentRunner_;\n};\n\njasmine.Env.prototype.afterEach = function(afterEachFunction) {\n  if (this.currentSuite) {\n    this.currentSuite.afterEach(afterEachFunction);\n  } else {\n    this.currentRunner_.afterEach(afterEachFunction);\n  }\n\n};\n\njasmine.Env.prototype.xdescribe = function(desc, specDefinitions) {\n  return {\n    execute: function() {\n    }\n  };\n};\n\njasmine.Env.prototype.it = function(description, func) {\n  var spec = new jasmine.Spec(this, this.currentSuite, description);\n  this.currentSuite.add(spec);\n  this.currentSpec = spec;\n\n  if (func) {\n    spec.runs(func);\n  }\n\n  return spec;\n};\n\njasmine.Env.prototype.xit = function(desc, func) {\n  return {\n    id: this.nextSpecId(),\n    runs: function() {\n    }\n  };\n};\n\njasmine.Env.prototype.compareRegExps_ = function(a, b, mismatchKeys, mismatchValues) {\n  if (a.source != b.source)\n    mismatchValues.push(\"expected pattern /\" + b.source + \"/ is not equal to the pattern /\" + a.source + \"/\");\n\n  if (a.ignoreCase != b.ignoreCase)\n    mismatchValues.push(\"expected modifier i was\" + (b.ignoreCase ? \" \" : \" not \") + \"set and does not equal the origin modifier\");\n\n  if (a.global != b.global)\n    mismatchValues.push(\"expected modifier g was\" + (b.global ? \" \" : \" not \") + \"set and does not equal the origin modifier\");\n\n  if (a.multiline != b.multiline)\n    mismatchValues.push(\"expected modifier m was\" + (b.multiline ? \" \" : \" not \") + \"set and does not equal the origin modifier\");\n\n  if (a.sticky != b.sticky)\n    mismatchValues.push(\"expected modifier y was\" + (b.sticky ? \" \" : \" not \") + \"set and does not equal the origin modifier\");\n\n  return (mismatchValues.length === 0);\n};\n\njasmine.Env.prototype.compareObjects_ = function(a, b, mismatchKeys, mismatchValues) {\n  if (a.__Jasmine_been_here_before__ === b && b.__Jasmine_been_here_before__ === a) {\n    return true;\n  }\n\n  a.__Jasmine_been_here_before__ = b;\n  b.__Jasmine_been_here_before__ = a;\n\n  var hasKey = function(obj, keyName) {\n    return obj !== null && obj[keyName] !== jasmine.undefined;\n  };\n\n  for (var property in b) {\n    if (!hasKey(a, property) && hasKey(b, property)) {\n      mismatchKeys.push(\"expected has key '\" + property + \"', but missing from actual.\");\n    }\n  }\n  for (property in a) {\n    if (!hasKey(b, property) && hasKey(a, property)) {\n      mismatchKeys.push(\"expected missing key '\" + property + \"', but present in actual.\");\n    }\n  }\n  for (property in b) {\n    if (property == '__Jasmine_been_here_before__') continue;\n    if (!this.equals_(a[property], b[property], mismatchKeys, mismatchValues)) {\n      mismatchValues.push(\"'\" + property + \"' was '\" + (b[property] ? jasmine.util.htmlEscape(b[property].toString()) : b[property]) + \"' in expected, but was '\" + (a[property] ? jasmine.util.htmlEscape(a[property].toString()) : a[property]) + \"' in actual.\");\n    }\n  }\n\n  if (jasmine.isArray_(a) && jasmine.isArray_(b) && a.length != b.length) {\n    mismatchValues.push(\"arrays were not the same length\");\n  }\n\n  delete a.__Jasmine_been_here_before__;\n  delete b.__Jasmine_been_here_before__;\n  return (mismatchKeys.length === 0 && mismatchValues.length === 0);\n};\n\njasmine.Env.prototype.equals_ = function(a, b, mismatchKeys, mismatchValues) {\n  mismatchKeys = mismatchKeys || [];\n  mismatchValues = mismatchValues || [];\n\n  for (var i = 0; i < this.equalityTesters_.length; i++) {\n    var equalityTester = this.equalityTesters_[i];\n    var result = equalityTester(a, b, this, mismatchKeys, mismatchValues);\n    if (result !== jasmine.undefined) return result;\n  }\n\n  if (a === b) return true;\n\n  if (a === jasmine.undefined || a === null || b === jasmine.undefined || b === null) {\n    return (a == jasmine.undefined && b == jasmine.undefined);\n  }\n\n  if (jasmine.isDomNode(a) && jasmine.isDomNode(b)) {\n    return a === b;\n  }\n\n  if (a instanceof Date && b instanceof Date) {\n    return a.getTime() == b.getTime();\n  }\n\n  if (a.jasmineMatches) {\n    return a.jasmineMatches(b);\n  }\n\n  if (b.jasmineMatches) {\n    return b.jasmineMatches(a);\n  }\n\n  if (a instanceof jasmine.Matchers.ObjectContaining) {\n    return a.matches(b);\n  }\n\n  if (b instanceof jasmine.Matchers.ObjectContaining) {\n    return b.matches(a);\n  }\n\n  if (jasmine.isString_(a) && jasmine.isString_(b)) {\n    return (a == b);\n  }\n\n  if (jasmine.isNumber_(a) && jasmine.isNumber_(b)) {\n    return (a == b);\n  }\n\n  if (a instanceof RegExp && b instanceof RegExp) {\n    return this.compareRegExps_(a, b, mismatchKeys, mismatchValues);\n  }\n\n  if (typeof a === \"object\" && typeof b === \"object\") {\n    return this.compareObjects_(a, b, mismatchKeys, mismatchValues);\n  }\n\n  //Straight check\n  return (a === b);\n};\n\njasmine.Env.prototype.contains_ = function(haystack, needle) {\n  if (jasmine.isArray_(haystack)) {\n    for (var i = 0; i < haystack.length; i++) {\n      if (this.equals_(haystack[i], needle)) return true;\n    }\n    return false;\n  }\n  return haystack.indexOf(needle) >= 0;\n};\n\njasmine.Env.prototype.addEqualityTester = function(equalityTester) {\n  this.equalityTesters_.push(equalityTester);\n};\n/** No-op base class for Jasmine reporters.\n *\n * @constructor\n */\njasmine.Reporter = function() {\n};\n\n//noinspection JSUnusedLocalSymbols\njasmine.Reporter.prototype.reportRunnerStarting = function(runner) {\n};\n\n//noinspection JSUnusedLocalSymbols\njasmine.Reporter.prototype.reportRunnerResults = function(runner) {\n};\n\n//noinspection JSUnusedLocalSymbols\njasmine.Reporter.prototype.reportSuiteResults = function(suite) {\n};\n\n//noinspection JSUnusedLocalSymbols\njasmine.Reporter.prototype.reportSpecStarting = function(spec) {\n};\n\n//noinspection JSUnusedLocalSymbols\njasmine.Reporter.prototype.reportSpecResults = function(spec) {\n};\n\n//noinspection JSUnusedLocalSymbols\njasmine.Reporter.prototype.log = function(str) {\n};\n\n/**\n * Blocks are functions with executable code that make up a spec.\n *\n * @constructor\n * @param {jasmine.Env} env\n * @param {Function} func\n * @param {jasmine.Spec} spec\n */\njasmine.Block = function(env, func, spec) {\n  this.env = env;\n  this.func = func;\n  this.spec = spec;\n};\n\njasmine.Block.prototype.execute = function(onComplete) {\n  if (!jasmine.CATCH_EXCEPTIONS) {\n    this.func.apply(this.spec);\n  }\n  else {\n    try {\n      this.func.apply(this.spec);\n    } catch (e) {\n      this.spec.fail(e);\n    }\n  }\n  onComplete();\n};\n/** JavaScript API reporter.\n *\n * @constructor\n */\njasmine.JsApiReporter = function() {\n  this.started = false;\n  this.finished = false;\n  this.suites_ = [];\n  this.results_ = {};\n};\n\njasmine.JsApiReporter.prototype.reportRunnerStarting = function(runner) {\n  this.started = true;\n  var suites = runner.topLevelSuites();\n  for (var i = 0; i < suites.length; i++) {\n    var suite = suites[i];\n    this.suites_.push(this.summarize_(suite));\n  }\n};\n\njasmine.JsApiReporter.prototype.suites = function() {\n  return this.suites_;\n};\n\njasmine.JsApiReporter.prototype.summarize_ = function(suiteOrSpec) {\n  var isSuite = suiteOrSpec instanceof jasmine.Suite;\n  var summary = {\n    id: suiteOrSpec.id,\n    name: suiteOrSpec.description,\n    type: isSuite ? 'suite' : 'spec',\n    children: []\n  };\n\n  if (isSuite) {\n    var children = suiteOrSpec.children();\n    for (var i = 0; i < children.length; i++) {\n      summary.children.push(this.summarize_(children[i]));\n    }\n  }\n  return summary;\n};\n\njasmine.JsApiReporter.prototype.results = function() {\n  return this.results_;\n};\n\njasmine.JsApiReporter.prototype.resultsForSpec = function(specId) {\n  return this.results_[specId];\n};\n\n//noinspection JSUnusedLocalSymbols\njasmine.JsApiReporter.prototype.reportRunnerResults = function(runner) {\n  this.finished = true;\n};\n\n//noinspection JSUnusedLocalSymbols\njasmine.JsApiReporter.prototype.reportSuiteResults = function(suite) {\n};\n\n//noinspection JSUnusedLocalSymbols\njasmine.JsApiReporter.prototype.reportSpecResults = function(spec) {\n  this.results_[spec.id] = {\n    messages: spec.results().getItems(),\n    result: spec.results().failedCount > 0 ? \"failed\" : \"passed\"\n  };\n};\n\n//noinspection JSUnusedLocalSymbols\njasmine.JsApiReporter.prototype.log = function(str) {\n};\n\njasmine.JsApiReporter.prototype.resultsForSpecs = function(specIds){\n  var results = {};\n  for (var i = 0; i < specIds.length; i++) {\n    var specId = specIds[i];\n    results[specId] = this.summarizeResult_(this.results_[specId]);\n  }\n  return results;\n};\n\njasmine.JsApiReporter.prototype.summarizeResult_ = function(result){\n  var summaryMessages = [];\n  var messagesLength = result.messages.length;\n  for (var messageIndex = 0; messageIndex < messagesLength; messageIndex++) {\n    var resultMessage = result.messages[messageIndex];\n    summaryMessages.push({\n      text: resultMessage.type == 'log' ? resultMessage.toString() : jasmine.undefined,\n      passed: resultMessage.passed ? resultMessage.passed() : true,\n      type: resultMessage.type,\n      message: resultMessage.message,\n      trace: {\n        stack: resultMessage.passed && !resultMessage.passed() ? resultMessage.trace.stack : jasmine.undefined\n      }\n    });\n  }\n\n  return {\n    result : result.result,\n    messages : summaryMessages\n  };\n};\n\n/**\n * @constructor\n * @param {jasmine.Env} env\n * @param actual\n * @param {jasmine.Spec} spec\n */\njasmine.Matchers = function(env, actual, spec, opt_isNot) {\n  this.env = env;\n  this.actual = actual;\n  this.spec = spec;\n  this.isNot = opt_isNot || false;\n  this.reportWasCalled_ = false;\n};\n\n// todo: @deprecated as of Jasmine 0.11, remove soon [xw]\njasmine.Matchers.pp = function(str) {\n  throw new Error(\"jasmine.Matchers.pp() is no longer supported, please use jasmine.pp() instead!\");\n};\n\n// todo: @deprecated Deprecated as of Jasmine 0.10. Rewrite your custom matchers to return true or false. [xw]\njasmine.Matchers.prototype.report = function(result, failing_message, details) {\n  throw new Error(\"As of jasmine 0.11, custom matchers must be implemented differently -- please see jasmine docs\");\n};\n\njasmine.Matchers.wrapInto_ = function(prototype, matchersClass) {\n  for (var methodName in prototype) {\n    if (methodName == 'report') continue;\n    var orig = prototype[methodName];\n    matchersClass.prototype[methodName] = jasmine.Matchers.matcherFn_(methodName, orig);\n  }\n};\n\njasmine.Matchers.matcherFn_ = function(matcherName, matcherFunction) {\n  return function() {\n    var matcherArgs = jasmine.util.argsToArray(arguments);\n    var result = matcherFunction.apply(this, arguments);\n\n    if (this.isNot) {\n      result = !result;\n    }\n\n    if (this.reportWasCalled_) return result;\n\n    var message;\n    if (!result) {\n      if (this.message) {\n        message = this.message.apply(this, arguments);\n        if (jasmine.isArray_(message)) {\n          message = message[this.isNot ? 1 : 0];\n        }\n      } else {\n        var englishyPredicate = matcherName.replace(/[A-Z]/g, function(s) { return ' ' + s.toLowerCase(); });\n        message = \"Expected \" + jasmine.pp(this.actual) + (this.isNot ? \" not \" : \" \") + englishyPredicate;\n        if (matcherArgs.length > 0) {\n          for (var i = 0; i < matcherArgs.length; i++) {\n            if (i > 0) message += \",\";\n            message += \" \" + jasmine.pp(matcherArgs[i]);\n          }\n        }\n        message += \".\";\n      }\n    }\n    var expectationResult = new jasmine.ExpectationResult({\n      matcherName: matcherName,\n      passed: result,\n      expected: matcherArgs.length > 1 ? matcherArgs : matcherArgs[0],\n      actual: this.actual,\n      message: message\n    });\n    this.spec.addMatcherResult(expectationResult);\n    return jasmine.undefined;\n  };\n};\n\n\n\n\n/**\n * toBe: compares the actual to the expected using ===\n * @param expected\n */\njasmine.Matchers.prototype.toBe = function(expected) {\n  return this.actual === expected;\n};\n\n/**\n * toNotBe: compares the actual to the expected using !==\n * @param expected\n * @deprecated as of 1.0. Use not.toBe() instead.\n */\njasmine.Matchers.prototype.toNotBe = function(expected) {\n  return this.actual !== expected;\n};\n\n/**\n * toEqual: compares the actual to the expected using common sense equality. Handles Objects, Arrays, etc.\n *\n * @param expected\n */\njasmine.Matchers.prototype.toEqual = function(expected) {\n  return this.env.equals_(this.actual, expected);\n};\n\n/**\n * toNotEqual: compares the actual to the expected using the ! of jasmine.Matchers.toEqual\n * @param expected\n * @deprecated as of 1.0. Use not.toEqual() instead.\n */\njasmine.Matchers.prototype.toNotEqual = function(expected) {\n  return !this.env.equals_(this.actual, expected);\n};\n\n/**\n * Matcher that compares the actual to the expected using a regular expression.  Constructs a RegExp, so takes\n * a pattern or a String.\n *\n * @param expected\n */\njasmine.Matchers.prototype.toMatch = function(expected) {\n  return new RegExp(expected).test(this.actual);\n};\n\n/**\n * Matcher that compares the actual to the expected using the boolean inverse of jasmine.Matchers.toMatch\n * @param expected\n * @deprecated as of 1.0. Use not.toMatch() instead.\n */\njasmine.Matchers.prototype.toNotMatch = function(expected) {\n  return !(new RegExp(expected).test(this.actual));\n};\n\n/**\n * Matcher that compares the actual to jasmine.undefined.\n */\njasmine.Matchers.prototype.toBeDefined = function() {\n  return (this.actual !== jasmine.undefined);\n};\n\n/**\n * Matcher that compares the actual to jasmine.undefined.\n */\njasmine.Matchers.prototype.toBeUndefined = function() {\n  return (this.actual === jasmine.undefined);\n};\n\n/**\n * Matcher that compares the actual to null.\n */\njasmine.Matchers.prototype.toBeNull = function() {\n  return (this.actual === null);\n};\n\n/**\n * Matcher that compares the actual to NaN.\n */\njasmine.Matchers.prototype.toBeNaN = function() {\n    this.message = function() {\n        return [ \"Expected \" + jasmine.pp(this.actual) + \" to be NaN.\" ];\n    };\n\n    return (this.actual !== this.actual);\n};\n\n/**\n * Matcher that boolean not-nots the actual.\n */\njasmine.Matchers.prototype.toBeTruthy = function() {\n  return !!this.actual;\n};\n\n\n/**\n * Matcher that boolean nots the actual.\n */\njasmine.Matchers.prototype.toBeFalsy = function() {\n  return !this.actual;\n};\n\n\n/**\n * Matcher that checks to see if the actual, a Jasmine spy, was called.\n */\njasmine.Matchers.prototype.toHaveBeenCalled = function() {\n  if (arguments.length > 0) {\n    throw new Error('toHaveBeenCalled does not take arguments, use toHaveBeenCalledWith');\n  }\n\n  if (!jasmine.isSpy(this.actual)) {\n    throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');\n  }\n\n  this.message = function() {\n    return [\n      \"Expected spy \" + this.actual.identity + \" to have been called.\",\n      \"Expected spy \" + this.actual.identity + \" not to have been called.\"\n    ];\n  };\n\n  return this.actual.wasCalled;\n};\n\n/** @deprecated Use expect(xxx).toHaveBeenCalled() instead */\njasmine.Matchers.prototype.wasCalled = jasmine.Matchers.prototype.toHaveBeenCalled;\n\n/**\n * Matcher that checks to see if the actual, a Jasmine spy, was not called.\n *\n * @deprecated Use expect(xxx).not.toHaveBeenCalled() instead\n */\njasmine.Matchers.prototype.wasNotCalled = function() {\n  if (arguments.length > 0) {\n    throw new Error('wasNotCalled does not take arguments');\n  }\n\n  if (!jasmine.isSpy(this.actual)) {\n    throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');\n  }\n\n  this.message = function() {\n    return [\n      \"Expected spy \" + this.actual.identity + \" to not have been called.\",\n      \"Expected spy \" + this.actual.identity + \" to have been called.\"\n    ];\n  };\n\n  return !this.actual.wasCalled;\n};\n\n/**\n * Matcher that checks to see if the actual, a Jasmine spy, was called with a set of parameters.\n *\n * @example\n *\n */\njasmine.Matchers.prototype.toHaveBeenCalledWith = function() {\n  var expectedArgs = jasmine.util.argsToArray(arguments);\n  if (!jasmine.isSpy(this.actual)) {\n    throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');\n  }\n  this.message = function() {\n    var invertedMessage = \"Expected spy \" + this.actual.identity + \" not to have been called with \" + jasmine.pp(expectedArgs) + \" but it was.\";\n    var positiveMessage = \"\";\n    if (this.actual.callCount === 0) {\n      positiveMessage = \"Expected spy \" + this.actual.identity + \" to have been called with \" + jasmine.pp(expectedArgs) + \" but it was never called.\";\n    } else {\n      positiveMessage = \"Expected spy \" + this.actual.identity + \" to have been called with \" + jasmine.pp(expectedArgs) + \" but actual calls were \" + jasmine.pp(this.actual.argsForCall).replace(/^\\[ | \\]$/g, '')\n    }\n    return [positiveMessage, invertedMessage];\n  };\n\n  return this.env.contains_(this.actual.argsForCall, expectedArgs);\n};\n\n/** @deprecated Use expect(xxx).toHaveBeenCalledWith() instead */\njasmine.Matchers.prototype.wasCalledWith = jasmine.Matchers.prototype.toHaveBeenCalledWith;\n\n/** @deprecated Use expect(xxx).not.toHaveBeenCalledWith() instead */\njasmine.Matchers.prototype.wasNotCalledWith = function() {\n  var expectedArgs = jasmine.util.argsToArray(arguments);\n  if (!jasmine.isSpy(this.actual)) {\n    throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');\n  }\n\n  this.message = function() {\n    return [\n      \"Expected spy not to have been called with \" + jasmine.pp(expectedArgs) + \" but it was\",\n      \"Expected spy to have been called with \" + jasmine.pp(expectedArgs) + \" but it was\"\n    ];\n  };\n\n  return !this.env.contains_(this.actual.argsForCall, expectedArgs);\n};\n\n/**\n * Matcher that checks that the expected item is an element in the actual Array.\n *\n * @param {Object} expected\n */\njasmine.Matchers.prototype.toContain = function(expected) {\n  return this.env.contains_(this.actual, expected);\n};\n\n/**\n * Matcher that checks that the expected item is NOT an element in the actual Array.\n *\n * @param {Object} expected\n * @deprecated as of 1.0. Use not.toContain() instead.\n */\njasmine.Matchers.prototype.toNotContain = function(expected) {\n  return !this.env.contains_(this.actual, expected);\n};\n\njasmine.Matchers.prototype.toBeLessThan = function(expected) {\n  return this.actual < expected;\n};\n\njasmine.Matchers.prototype.toBeGreaterThan = function(expected) {\n  return this.actual > expected;\n};\n\n/**\n * Matcher that checks that the expected item is equal to the actual item\n * up to a given level of decimal precision (default 2).\n *\n * @param {Number} expected\n * @param {Number} precision, as number of decimal places\n */\njasmine.Matchers.prototype.toBeCloseTo = function(expected, precision) {\n  if (!(precision === 0)) {\n    precision = precision || 2;\n  }\n  return Math.abs(expected - this.actual) < (Math.pow(10, -precision) / 2);\n};\n\n/**\n * Matcher that checks that the expected exception was thrown by the actual.\n *\n * @param {String} [expected]\n */\njasmine.Matchers.prototype.toThrow = function(expected) {\n  var result = false;\n  var exception;\n  if (typeof this.actual != 'function') {\n    throw new Error('Actual is not a function');\n  }\n  try {\n    this.actual();\n  } catch (e) {\n    exception = e;\n  }\n  if (exception) {\n    result = (expected === jasmine.undefined || this.env.equals_(exception.message || exception, expected.message || expected));\n  }\n\n  var not = this.isNot ? \"not \" : \"\";\n\n  this.message = function() {\n    if (exception && (expected === jasmine.undefined || !this.env.equals_(exception.message || exception, expected.message || expected))) {\n      return [\"Expected function \" + not + \"to throw\", expected ? expected.message || expected : \"an exception\", \", but it threw\", exception.message || exception].join(' ');\n    } else {\n      return \"Expected function to throw an exception.\";\n    }\n  };\n\n  return result;\n};\n\njasmine.Matchers.Any = function(expectedClass) {\n  this.expectedClass = expectedClass;\n};\n\njasmine.Matchers.Any.prototype.jasmineMatches = function(other) {\n  if (this.expectedClass == String) {\n    return typeof other == 'string' || other instanceof String;\n  }\n\n  if (this.expectedClass == Number) {\n    return typeof other == 'number' || other instanceof Number;\n  }\n\n  if (this.expectedClass == Function) {\n    return typeof other == 'function' || other instanceof Function;\n  }\n\n  if (this.expectedClass == Object) {\n    return typeof other == 'object';\n  }\n\n  return other instanceof this.expectedClass;\n};\n\njasmine.Matchers.Any.prototype.jasmineToString = function() {\n  return '<jasmine.any(' + this.expectedClass + ')>';\n};\n\njasmine.Matchers.ObjectContaining = function (sample) {\n  this.sample = sample;\n};\n\njasmine.Matchers.ObjectContaining.prototype.jasmineMatches = function(other, mismatchKeys, mismatchValues) {\n  mismatchKeys = mismatchKeys || [];\n  mismatchValues = mismatchValues || [];\n\n  var env = jasmine.getEnv();\n\n  var hasKey = function(obj, keyName) {\n    return obj != null && obj[keyName] !== jasmine.undefined;\n  };\n\n  for (var property in this.sample) {\n    if (!hasKey(other, property) && hasKey(this.sample, property)) {\n      mismatchKeys.push(\"expected has key '\" + property + \"', but missing from actual.\");\n    }\n    else if (!env.equals_(this.sample[property], other[property], mismatchKeys, mismatchValues)) {\n      mismatchValues.push(\"'\" + property + \"' was '\" + (other[property] ? jasmine.util.htmlEscape(other[property].toString()) : other[property]) + \"' in expected, but was '\" + (this.sample[property] ? jasmine.util.htmlEscape(this.sample[property].toString()) : this.sample[property]) + \"' in actual.\");\n    }\n  }\n\n  return (mismatchKeys.length === 0 && mismatchValues.length === 0);\n};\n\njasmine.Matchers.ObjectContaining.prototype.jasmineToString = function () {\n  return \"<jasmine.objectContaining(\" + jasmine.pp(this.sample) + \")>\";\n};\n// Mock setTimeout, clearTimeout\n// Contributed by Pivotal Computer Systems, www.pivotalsf.com\n\njasmine.FakeTimer = function() {\n  this.reset();\n\n  var self = this;\n  self.setTimeout = function(funcToCall, millis) {\n    self.timeoutsMade++;\n    self.scheduleFunction(self.timeoutsMade, funcToCall, millis, false);\n    return self.timeoutsMade;\n  };\n\n  self.setInterval = function(funcToCall, millis) {\n    self.timeoutsMade++;\n    self.scheduleFunction(self.timeoutsMade, funcToCall, millis, true);\n    return self.timeoutsMade;\n  };\n\n  self.clearTimeout = function(timeoutKey) {\n    self.scheduledFunctions[timeoutKey] = jasmine.undefined;\n  };\n\n  self.clearInterval = function(timeoutKey) {\n    self.scheduledFunctions[timeoutKey] = jasmine.undefined;\n  };\n\n};\n\njasmine.FakeTimer.prototype.reset = function() {\n  this.timeoutsMade = 0;\n  this.scheduledFunctions = {};\n  this.nowMillis = 0;\n};\n\njasmine.FakeTimer.prototype.tick = function(millis) {\n  var oldMillis = this.nowMillis;\n  var newMillis = oldMillis + millis;\n  this.runFunctionsWithinRange(oldMillis, newMillis);\n  this.nowMillis = newMillis;\n};\n\njasmine.FakeTimer.prototype.runFunctionsWithinRange = function(oldMillis, nowMillis) {\n  var scheduledFunc;\n  var funcsToRun = [];\n  for (var timeoutKey in this.scheduledFunctions) {\n    scheduledFunc = this.scheduledFunctions[timeoutKey];\n    if (scheduledFunc != jasmine.undefined &&\n        scheduledFunc.runAtMillis >= oldMillis &&\n        scheduledFunc.runAtMillis <= nowMillis) {\n      funcsToRun.push(scheduledFunc);\n      this.scheduledFunctions[timeoutKey] = jasmine.undefined;\n    }\n  }\n\n  if (funcsToRun.length > 0) {\n    funcsToRun.sort(function(a, b) {\n      return a.runAtMillis - b.runAtMillis;\n    });\n    for (var i = 0; i < funcsToRun.length; ++i) {\n      try {\n        var funcToRun = funcsToRun[i];\n        this.nowMillis = funcToRun.runAtMillis;\n        funcToRun.funcToCall();\n        if (funcToRun.recurring) {\n          this.scheduleFunction(funcToRun.timeoutKey,\n              funcToRun.funcToCall,\n              funcToRun.millis,\n              true);\n        }\n      } catch(e) {\n      }\n    }\n    this.runFunctionsWithinRange(oldMillis, nowMillis);\n  }\n};\n\njasmine.FakeTimer.prototype.scheduleFunction = function(timeoutKey, funcToCall, millis, recurring) {\n  this.scheduledFunctions[timeoutKey] = {\n    runAtMillis: this.nowMillis + millis,\n    funcToCall: funcToCall,\n    recurring: recurring,\n    timeoutKey: timeoutKey,\n    millis: millis\n  };\n};\n\n/**\n * @namespace\n */\njasmine.Clock = {\n  defaultFakeTimer: new jasmine.FakeTimer(),\n\n  reset: function() {\n    jasmine.Clock.assertInstalled();\n    jasmine.Clock.defaultFakeTimer.reset();\n  },\n\n  tick: function(millis) {\n    jasmine.Clock.assertInstalled();\n    jasmine.Clock.defaultFakeTimer.tick(millis);\n  },\n\n  runFunctionsWithinRange: function(oldMillis, nowMillis) {\n    jasmine.Clock.defaultFakeTimer.runFunctionsWithinRange(oldMillis, nowMillis);\n  },\n\n  scheduleFunction: function(timeoutKey, funcToCall, millis, recurring) {\n    jasmine.Clock.defaultFakeTimer.scheduleFunction(timeoutKey, funcToCall, millis, recurring);\n  },\n\n  useMock: function() {\n    if (!jasmine.Clock.isInstalled()) {\n      var spec = jasmine.getEnv().currentSpec;\n      spec.after(jasmine.Clock.uninstallMock);\n\n      jasmine.Clock.installMock();\n    }\n  },\n\n  installMock: function() {\n    jasmine.Clock.installed = jasmine.Clock.defaultFakeTimer;\n  },\n\n  uninstallMock: function() {\n    jasmine.Clock.assertInstalled();\n    jasmine.Clock.installed = jasmine.Clock.real;\n  },\n\n  real: {\n    setTimeout: jasmine.getGlobal().setTimeout,\n    clearTimeout: jasmine.getGlobal().clearTimeout,\n    setInterval: jasmine.getGlobal().setInterval,\n    clearInterval: jasmine.getGlobal().clearInterval\n  },\n\n  assertInstalled: function() {\n    if (!jasmine.Clock.isInstalled()) {\n      throw new Error(\"Mock clock is not installed, use jasmine.Clock.useMock()\");\n    }\n  },\n\n  isInstalled: function() {\n    return jasmine.Clock.installed == jasmine.Clock.defaultFakeTimer;\n  },\n\n  installed: null\n};\njasmine.Clock.installed = jasmine.Clock.real;\n\n//else for IE support\njasmine.getGlobal().setTimeout = function(funcToCall, millis) {\n  if (jasmine.Clock.installed.setTimeout.apply) {\n    return jasmine.Clock.installed.setTimeout.apply(this, arguments);\n  } else {\n    return jasmine.Clock.installed.setTimeout(funcToCall, millis);\n  }\n};\n\njasmine.getGlobal().setInterval = function(funcToCall, millis) {\n  if (jasmine.Clock.installed.setInterval.apply) {\n    return jasmine.Clock.installed.setInterval.apply(this, arguments);\n  } else {\n    return jasmine.Clock.installed.setInterval(funcToCall, millis);\n  }\n};\n\njasmine.getGlobal().clearTimeout = function(timeoutKey) {\n  if (jasmine.Clock.installed.clearTimeout.apply) {\n    return jasmine.Clock.installed.clearTimeout.apply(this, arguments);\n  } else {\n    return jasmine.Clock.installed.clearTimeout(timeoutKey);\n  }\n};\n\njasmine.getGlobal().clearInterval = function(timeoutKey) {\n  if (jasmine.Clock.installed.clearTimeout.apply) {\n    return jasmine.Clock.installed.clearInterval.apply(this, arguments);\n  } else {\n    return jasmine.Clock.installed.clearInterval(timeoutKey);\n  }\n};\n\n/**\n * @constructor\n */\njasmine.MultiReporter = function() {\n  this.subReporters_ = [];\n};\njasmine.util.inherit(jasmine.MultiReporter, jasmine.Reporter);\n\njasmine.MultiReporter.prototype.addReporter = function(reporter) {\n  this.subReporters_.push(reporter);\n};\n\n(function() {\n  var functionNames = [\n    \"reportRunnerStarting\",\n    \"reportRunnerResults\",\n    \"reportSuiteResults\",\n    \"reportSpecStarting\",\n    \"reportSpecResults\",\n    \"log\"\n  ];\n  for (var i = 0; i < functionNames.length; i++) {\n    var functionName = functionNames[i];\n    jasmine.MultiReporter.prototype[functionName] = (function(functionName) {\n      return function() {\n        for (var j = 0; j < this.subReporters_.length; j++) {\n          var subReporter = this.subReporters_[j];\n          if (subReporter[functionName]) {\n            subReporter[functionName].apply(subReporter, arguments);\n          }\n        }\n      };\n    })(functionName);\n  }\n})();\n/**\n * Holds results for a set of Jasmine spec. Allows for the results array to hold another jasmine.NestedResults\n *\n * @constructor\n */\njasmine.NestedResults = function() {\n  /**\n   * The total count of results\n   */\n  this.totalCount = 0;\n  /**\n   * Number of passed results\n   */\n  this.passedCount = 0;\n  /**\n   * Number of failed results\n   */\n  this.failedCount = 0;\n  /**\n   * Was this suite/spec skipped?\n   */\n  this.skipped = false;\n  /**\n   * @ignore\n   */\n  this.items_ = [];\n};\n\n/**\n * Roll up the result counts.\n *\n * @param result\n */\njasmine.NestedResults.prototype.rollupCounts = function(result) {\n  this.totalCount += result.totalCount;\n  this.passedCount += result.passedCount;\n  this.failedCount += result.failedCount;\n};\n\n/**\n * Adds a log message.\n * @param values Array of message parts which will be concatenated later.\n */\njasmine.NestedResults.prototype.log = function(values) {\n  this.items_.push(new jasmine.MessageResult(values));\n};\n\n/**\n * Getter for the results: message & results.\n */\njasmine.NestedResults.prototype.getItems = function() {\n  return this.items_;\n};\n\n/**\n * Adds a result, tracking counts (total, passed, & failed)\n * @param {jasmine.ExpectationResult|jasmine.NestedResults} result\n */\njasmine.NestedResults.prototype.addResult = function(result) {\n  if (result.type != 'log') {\n    if (result.items_) {\n      this.rollupCounts(result);\n    } else {\n      this.totalCount++;\n      if (result.passed()) {\n        this.passedCount++;\n      } else {\n        this.failedCount++;\n      }\n    }\n  }\n  this.items_.push(result);\n};\n\n/**\n * @returns {Boolean} True if <b>everything</b> below passed\n */\njasmine.NestedResults.prototype.passed = function() {\n  return this.passedCount === this.totalCount;\n};\n/**\n * Base class for pretty printing for expectation results.\n */\njasmine.PrettyPrinter = function() {\n  this.ppNestLevel_ = 0;\n};\n\n/**\n * Formats a value in a nice, human-readable string.\n *\n * @param value\n */\njasmine.PrettyPrinter.prototype.format = function(value) {\n  this.ppNestLevel_++;\n  try {\n    if (value === jasmine.undefined) {\n      this.emitScalar('undefined');\n    } else if (value === null) {\n      this.emitScalar('null');\n    } else if (value === jasmine.getGlobal()) {\n      this.emitScalar('<global>');\n    } else if (value.jasmineToString) {\n      this.emitScalar(value.jasmineToString());\n    } else if (typeof value === 'string') {\n      this.emitString(value);\n    } else if (jasmine.isSpy(value)) {\n      this.emitScalar(\"spy on \" + value.identity);\n    } else if (value instanceof RegExp) {\n      this.emitScalar(value.toString());\n    } else if (typeof value === 'function') {\n      this.emitScalar('Function');\n    } else if (typeof value.nodeType === 'number') {\n      this.emitScalar('HTMLNode');\n    } else if (value instanceof Date) {\n      this.emitScalar('Date(' + value + ')');\n    } else if (value.__Jasmine_been_here_before__) {\n      this.emitScalar('<circular reference: ' + (jasmine.isArray_(value) ? 'Array' : 'Object') + '>');\n    } else if (jasmine.isArray_(value) || typeof value == 'object') {\n      value.__Jasmine_been_here_before__ = true;\n      if (jasmine.isArray_(value)) {\n        this.emitArray(value);\n      } else {\n        this.emitObject(value);\n      }\n      delete value.__Jasmine_been_here_before__;\n    } else {\n      this.emitScalar(value.toString());\n    }\n  } finally {\n    this.ppNestLevel_--;\n  }\n};\n\njasmine.PrettyPrinter.prototype.iterateObject = function(obj, fn) {\n  for (var property in obj) {\n    if (!obj.hasOwnProperty(property)) continue;\n    if (property == '__Jasmine_been_here_before__') continue;\n    fn(property, obj.__lookupGetter__ ? (obj.__lookupGetter__(property) !== jasmine.undefined && \n                                         obj.__lookupGetter__(property) !== null) : false);\n  }\n};\n\njasmine.PrettyPrinter.prototype.emitArray = jasmine.unimplementedMethod_;\njasmine.PrettyPrinter.prototype.emitObject = jasmine.unimplementedMethod_;\njasmine.PrettyPrinter.prototype.emitScalar = jasmine.unimplementedMethod_;\njasmine.PrettyPrinter.prototype.emitString = jasmine.unimplementedMethod_;\n\njasmine.StringPrettyPrinter = function() {\n  jasmine.PrettyPrinter.call(this);\n\n  this.string = '';\n};\njasmine.util.inherit(jasmine.StringPrettyPrinter, jasmine.PrettyPrinter);\n\njasmine.StringPrettyPrinter.prototype.emitScalar = function(value) {\n  this.append(value);\n};\n\njasmine.StringPrettyPrinter.prototype.emitString = function(value) {\n  this.append(\"'\" + value + \"'\");\n};\n\njasmine.StringPrettyPrinter.prototype.emitArray = function(array) {\n  if (this.ppNestLevel_ > jasmine.MAX_PRETTY_PRINT_DEPTH) {\n    this.append(\"Array\");\n    return;\n  }\n\n  this.append('[ ');\n  for (var i = 0; i < array.length; i++) {\n    if (i > 0) {\n      this.append(', ');\n    }\n    this.format(array[i]);\n  }\n  this.append(' ]');\n};\n\njasmine.StringPrettyPrinter.prototype.emitObject = function(obj) {\n  if (this.ppNestLevel_ > jasmine.MAX_PRETTY_PRINT_DEPTH) {\n    this.append(\"Object\");\n    return;\n  }\n\n  var self = this;\n  this.append('{ ');\n  var first = true;\n\n  this.iterateObject(obj, function(property, isGetter) {\n    if (first) {\n      first = false;\n    } else {\n      self.append(', ');\n    }\n\n    self.append(property);\n    self.append(' : ');\n    if (isGetter) {\n      self.append('<getter>');\n    } else {\n      self.format(obj[property]);\n    }\n  });\n\n  this.append(' }');\n};\n\njasmine.StringPrettyPrinter.prototype.append = function(value) {\n  this.string += value;\n};\njasmine.Queue = function(env) {\n  this.env = env;\n\n  // parallel to blocks. each true value in this array means the block will\n  // get executed even if we abort\n  this.ensured = [];\n  this.blocks = [];\n  this.running = false;\n  this.index = 0;\n  this.offset = 0;\n  this.abort = false;\n};\n\njasmine.Queue.prototype.addBefore = function(block, ensure) {\n  if (ensure === jasmine.undefined) {\n    ensure = false;\n  }\n\n  this.blocks.unshift(block);\n  this.ensured.unshift(ensure);\n};\n\njasmine.Queue.prototype.add = function(block, ensure) {\n  if (ensure === jasmine.undefined) {\n    ensure = false;\n  }\n\n  this.blocks.push(block);\n  this.ensured.push(ensure);\n};\n\njasmine.Queue.prototype.insertNext = function(block, ensure) {\n  if (ensure === jasmine.undefined) {\n    ensure = false;\n  }\n\n  this.ensured.splice((this.index + this.offset + 1), 0, ensure);\n  this.blocks.splice((this.index + this.offset + 1), 0, block);\n  this.offset++;\n};\n\njasmine.Queue.prototype.start = function(onComplete) {\n  this.running = true;\n  this.onComplete = onComplete;\n  this.next_();\n};\n\njasmine.Queue.prototype.isRunning = function() {\n  return this.running;\n};\n\njasmine.Queue.LOOP_DONT_RECURSE = true;\n\njasmine.Queue.prototype.next_ = function() {\n  var self = this;\n  var goAgain = true;\n\n  while (goAgain) {\n    goAgain = false;\n\n    if (self.index < self.blocks.length && !(this.abort && !this.ensured[self.index])) {\n      var calledSynchronously = true;\n      var completedSynchronously = false;\n\n      var onComplete = function () {\n        if (jasmine.Queue.LOOP_DONT_RECURSE && calledSynchronously) {\n          completedSynchronously = true;\n          return;\n        }\n\n        if (self.blocks[self.index].abort) {\n          self.abort = true;\n        }\n\n        self.offset = 0;\n        self.index++;\n\n        var now = new Date().getTime();\n        if (self.env.updateInterval && now - self.env.lastUpdate > self.env.updateInterval) {\n          self.env.lastUpdate = now;\n          self.env.setTimeout(function() {\n            self.next_();\n          }, 0);\n        } else {\n          if (jasmine.Queue.LOOP_DONT_RECURSE && completedSynchronously) {\n            goAgain = true;\n          } else {\n            self.next_();\n          }\n        }\n      };\n      self.blocks[self.index].execute(onComplete);\n\n      calledSynchronously = false;\n      if (completedSynchronously) {\n        onComplete();\n      }\n\n    } else {\n      self.running = false;\n      if (self.onComplete) {\n        self.onComplete();\n      }\n    }\n  }\n};\n\njasmine.Queue.prototype.results = function() {\n  var results = new jasmine.NestedResults();\n  for (var i = 0; i < this.blocks.length; i++) {\n    if (this.blocks[i].results) {\n      results.addResult(this.blocks[i].results());\n    }\n  }\n  return results;\n};\n\n\n/**\n * Runner\n *\n * @constructor\n * @param {jasmine.Env} env\n */\njasmine.Runner = function(env) {\n  var self = this;\n  self.env = env;\n  self.queue = new jasmine.Queue(env);\n  self.before_ = [];\n  self.after_ = [];\n  self.suites_ = [];\n};\n\njasmine.Runner.prototype.execute = function() {\n  var self = this;\n  if (self.env.reporter.reportRunnerStarting) {\n    self.env.reporter.reportRunnerStarting(this);\n  }\n  self.queue.start(function () {\n    self.finishCallback();\n  });\n};\n\njasmine.Runner.prototype.beforeEach = function(beforeEachFunction) {\n  beforeEachFunction.typeName = 'beforeEach';\n  this.before_.splice(0,0,beforeEachFunction);\n};\n\njasmine.Runner.prototype.afterEach = function(afterEachFunction) {\n  afterEachFunction.typeName = 'afterEach';\n  this.after_.splice(0,0,afterEachFunction);\n};\n\n\njasmine.Runner.prototype.finishCallback = function() {\n  this.env.reporter.reportRunnerResults(this);\n};\n\njasmine.Runner.prototype.addSuite = function(suite) {\n  this.suites_.push(suite);\n};\n\njasmine.Runner.prototype.add = function(block) {\n  if (block instanceof jasmine.Suite) {\n    this.addSuite(block);\n  }\n  this.queue.add(block);\n};\n\njasmine.Runner.prototype.specs = function () {\n  var suites = this.suites();\n  var specs = [];\n  for (var i = 0; i < suites.length; i++) {\n    specs = specs.concat(suites[i].specs());\n  }\n  return specs;\n};\n\njasmine.Runner.prototype.suites = function() {\n  return this.suites_;\n};\n\njasmine.Runner.prototype.topLevelSuites = function() {\n  var topLevelSuites = [];\n  for (var i = 0; i < this.suites_.length; i++) {\n    if (!this.suites_[i].parentSuite) {\n      topLevelSuites.push(this.suites_[i]);\n    }\n  }\n  return topLevelSuites;\n};\n\njasmine.Runner.prototype.results = function() {\n  return this.queue.results();\n};\n/**\n * Internal representation of a Jasmine specification, or test.\n *\n * @constructor\n * @param {jasmine.Env} env\n * @param {jasmine.Suite} suite\n * @param {String} description\n */\njasmine.Spec = function(env, suite, description) {\n  if (!env) {\n    throw new Error('jasmine.Env() required');\n  }\n  if (!suite) {\n    throw new Error('jasmine.Suite() required');\n  }\n  var spec = this;\n  spec.id = env.nextSpecId ? env.nextSpecId() : null;\n  spec.env = env;\n  spec.suite = suite;\n  spec.description = description;\n  spec.queue = new jasmine.Queue(env);\n\n  spec.afterCallbacks = [];\n  spec.spies_ = [];\n\n  spec.results_ = new jasmine.NestedResults();\n  spec.results_.description = description;\n  spec.matchersClass = null;\n};\n\njasmine.Spec.prototype.getFullName = function() {\n  return this.suite.getFullName() + ' ' + this.description + '.';\n};\n\n\njasmine.Spec.prototype.results = function() {\n  return this.results_;\n};\n\n/**\n * All parameters are pretty-printed and concatenated together, then written to the spec's output.\n *\n * Be careful not to leave calls to <code>jasmine.log</code> in production code.\n */\njasmine.Spec.prototype.log = function() {\n  return this.results_.log(arguments);\n};\n\njasmine.Spec.prototype.runs = function (func) {\n  var block = new jasmine.Block(this.env, func, this);\n  this.addToQueue(block);\n  return this;\n};\n\njasmine.Spec.prototype.addToQueue = function (block) {\n  if (this.queue.isRunning()) {\n    this.queue.insertNext(block);\n  } else {\n    this.queue.add(block);\n  }\n};\n\n/**\n * @param {jasmine.ExpectationResult} result\n */\njasmine.Spec.prototype.addMatcherResult = function(result) {\n  this.results_.addResult(result);\n};\n\njasmine.Spec.prototype.expect = function(actual) {\n  var positive = new (this.getMatchersClass_())(this.env, actual, this);\n  positive.not = new (this.getMatchersClass_())(this.env, actual, this, true);\n  return positive;\n};\n\n/**\n * Waits a fixed time period before moving to the next block.\n *\n * @deprecated Use waitsFor() instead\n * @param {Number} timeout milliseconds to wait\n */\njasmine.Spec.prototype.waits = function(timeout) {\n  var waitsFunc = new jasmine.WaitsBlock(this.env, timeout, this);\n  this.addToQueue(waitsFunc);\n  return this;\n};\n\n/**\n * Waits for the latchFunction to return true before proceeding to the next block.\n *\n * @param {Function} latchFunction\n * @param {String} optional_timeoutMessage\n * @param {Number} optional_timeout\n */\njasmine.Spec.prototype.waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) {\n  var latchFunction_ = null;\n  var optional_timeoutMessage_ = null;\n  var optional_timeout_ = null;\n\n  for (var i = 0; i < arguments.length; i++) {\n    var arg = arguments[i];\n    switch (typeof arg) {\n      case 'function':\n        latchFunction_ = arg;\n        break;\n      case 'string':\n        optional_timeoutMessage_ = arg;\n        break;\n      case 'number':\n        optional_timeout_ = arg;\n        break;\n    }\n  }\n\n  var waitsForFunc = new jasmine.WaitsForBlock(this.env, optional_timeout_, latchFunction_, optional_timeoutMessage_, this);\n  this.addToQueue(waitsForFunc);\n  return this;\n};\n\njasmine.Spec.prototype.fail = function (e) {\n  var expectationResult = new jasmine.ExpectationResult({\n    passed: false,\n    message: e ? jasmine.util.formatException(e) : 'Exception',\n    trace: { stack: e.stack }\n  });\n  this.results_.addResult(expectationResult);\n};\n\njasmine.Spec.prototype.getMatchersClass_ = function() {\n  return this.matchersClass || this.env.matchersClass;\n};\n\njasmine.Spec.prototype.addMatchers = function(matchersPrototype) {\n  var parent = this.getMatchersClass_();\n  var newMatchersClass = function() {\n    parent.apply(this, arguments);\n  };\n  jasmine.util.inherit(newMatchersClass, parent);\n  jasmine.Matchers.wrapInto_(matchersPrototype, newMatchersClass);\n  this.matchersClass = newMatchersClass;\n};\n\njasmine.Spec.prototype.finishCallback = function() {\n  this.env.reporter.reportSpecResults(this);\n};\n\njasmine.Spec.prototype.finish = function(onComplete) {\n  this.removeAllSpies();\n  this.finishCallback();\n  if (onComplete) {\n    onComplete();\n  }\n};\n\njasmine.Spec.prototype.after = function(doAfter) {\n  if (this.queue.isRunning()) {\n    this.queue.add(new jasmine.Block(this.env, doAfter, this), true);\n  } else {\n    this.afterCallbacks.unshift(doAfter);\n  }\n};\n\njasmine.Spec.prototype.execute = function(onComplete) {\n  var spec = this;\n  if (!spec.env.specFilter(spec)) {\n    spec.results_.skipped = true;\n    spec.finish(onComplete);\n    return;\n  }\n\n  this.env.reporter.reportSpecStarting(this);\n\n  spec.env.currentSpec = spec;\n\n  spec.addBeforesAndAftersToQueue();\n\n  spec.queue.start(function () {\n    spec.finish(onComplete);\n  });\n};\n\njasmine.Spec.prototype.addBeforesAndAftersToQueue = function() {\n  var runner = this.env.currentRunner();\n  var i;\n\n  for (var suite = this.suite; suite; suite = suite.parentSuite) {\n    for (i = 0; i < suite.before_.length; i++) {\n      this.queue.addBefore(new jasmine.Block(this.env, suite.before_[i], this));\n    }\n  }\n  for (i = 0; i < runner.before_.length; i++) {\n    this.queue.addBefore(new jasmine.Block(this.env, runner.before_[i], this));\n  }\n  for (i = 0; i < this.afterCallbacks.length; i++) {\n    this.queue.add(new jasmine.Block(this.env, this.afterCallbacks[i], this), true);\n  }\n  for (suite = this.suite; suite; suite = suite.parentSuite) {\n    for (i = 0; i < suite.after_.length; i++) {\n      this.queue.add(new jasmine.Block(this.env, suite.after_[i], this), true);\n    }\n  }\n  for (i = 0; i < runner.after_.length; i++) {\n    this.queue.add(new jasmine.Block(this.env, runner.after_[i], this), true);\n  }\n};\n\njasmine.Spec.prototype.explodes = function() {\n  throw 'explodes function should not have been called';\n};\n\njasmine.Spec.prototype.spyOn = function(obj, methodName, ignoreMethodDoesntExist) {\n  if (obj == jasmine.undefined) {\n    throw \"spyOn could not find an object to spy upon for \" + methodName + \"()\";\n  }\n\n  if (!ignoreMethodDoesntExist && obj[methodName] === jasmine.undefined) {\n    throw methodName + '() method does not exist';\n  }\n\n  if (!ignoreMethodDoesntExist && obj[methodName] && obj[methodName].isSpy) {\n    throw new Error(methodName + ' has already been spied upon');\n  }\n\n  var spyObj = jasmine.createSpy(methodName);\n\n  this.spies_.push(spyObj);\n  spyObj.baseObj = obj;\n  spyObj.methodName = methodName;\n  spyObj.originalValue = obj[methodName];\n\n  obj[methodName] = spyObj;\n\n  return spyObj;\n};\n\njasmine.Spec.prototype.removeAllSpies = function() {\n  for (var i = 0; i < this.spies_.length; i++) {\n    var spy = this.spies_[i];\n    spy.baseObj[spy.methodName] = spy.originalValue;\n  }\n  this.spies_ = [];\n};\n\n/**\n * Internal representation of a Jasmine suite.\n *\n * @constructor\n * @param {jasmine.Env} env\n * @param {String} description\n * @param {Function} specDefinitions\n * @param {jasmine.Suite} parentSuite\n */\njasmine.Suite = function(env, description, specDefinitions, parentSuite) {\n  var self = this;\n  self.id = env.nextSuiteId ? env.nextSuiteId() : null;\n  self.description = description;\n  self.queue = new jasmine.Queue(env);\n  self.parentSuite = parentSuite;\n  self.env = env;\n  self.before_ = [];\n  self.after_ = [];\n  self.children_ = [];\n  self.suites_ = [];\n  self.specs_ = [];\n};\n\njasmine.Suite.prototype.getFullName = function() {\n  var fullName = this.description;\n  for (var parentSuite = this.parentSuite; parentSuite; parentSuite = parentSuite.parentSuite) {\n    fullName = parentSuite.description + ' ' + fullName;\n  }\n  return fullName;\n};\n\njasmine.Suite.prototype.finish = function(onComplete) {\n  this.env.reporter.reportSuiteResults(this);\n  this.finished = true;\n  if (typeof(onComplete) == 'function') {\n    onComplete();\n  }\n};\n\njasmine.Suite.prototype.beforeEach = function(beforeEachFunction) {\n  beforeEachFunction.typeName = 'beforeEach';\n  this.before_.unshift(beforeEachFunction);\n};\n\njasmine.Suite.prototype.afterEach = function(afterEachFunction) {\n  afterEachFunction.typeName = 'afterEach';\n  this.after_.unshift(afterEachFunction);\n};\n\njasmine.Suite.prototype.results = function() {\n  return this.queue.results();\n};\n\njasmine.Suite.prototype.add = function(suiteOrSpec) {\n  this.children_.push(suiteOrSpec);\n  if (suiteOrSpec instanceof jasmine.Suite) {\n    this.suites_.push(suiteOrSpec);\n    this.env.currentRunner().addSuite(suiteOrSpec);\n  } else {\n    this.specs_.push(suiteOrSpec);\n  }\n  this.queue.add(suiteOrSpec);\n};\n\njasmine.Suite.prototype.specs = function() {\n  return this.specs_;\n};\n\njasmine.Suite.prototype.suites = function() {\n  return this.suites_;\n};\n\njasmine.Suite.prototype.children = function() {\n  return this.children_;\n};\n\njasmine.Suite.prototype.execute = function(onComplete) {\n  var self = this;\n  this.queue.start(function () {\n    self.finish(onComplete);\n  });\n};\njasmine.WaitsBlock = function(env, timeout, spec) {\n  this.timeout = timeout;\n  jasmine.Block.call(this, env, null, spec);\n};\n\njasmine.util.inherit(jasmine.WaitsBlock, jasmine.Block);\n\njasmine.WaitsBlock.prototype.execute = function (onComplete) {\n  if (jasmine.VERBOSE) {\n    this.env.reporter.log('>> Jasmine waiting for ' + this.timeout + ' ms...');\n  }\n  this.env.setTimeout(function () {\n    onComplete();\n  }, this.timeout);\n};\n/**\n * A block which waits for some condition to become true, with timeout.\n *\n * @constructor\n * @extends jasmine.Block\n * @param {jasmine.Env} env The Jasmine environment.\n * @param {Number} timeout The maximum time in milliseconds to wait for the condition to become true.\n * @param {Function} latchFunction A function which returns true when the desired condition has been met.\n * @param {String} message The message to display if the desired condition hasn't been met within the given time period.\n * @param {jasmine.Spec} spec The Jasmine spec.\n */\njasmine.WaitsForBlock = function(env, timeout, latchFunction, message, spec) {\n  this.timeout = timeout || env.defaultTimeoutInterval;\n  this.latchFunction = latchFunction;\n  this.message = message;\n  this.totalTimeSpentWaitingForLatch = 0;\n  jasmine.Block.call(this, env, null, spec);\n};\njasmine.util.inherit(jasmine.WaitsForBlock, jasmine.Block);\n\njasmine.WaitsForBlock.TIMEOUT_INCREMENT = 10;\n\njasmine.WaitsForBlock.prototype.execute = function(onComplete) {\n  if (jasmine.VERBOSE) {\n    this.env.reporter.log('>> Jasmine waiting for ' + (this.message || 'something to happen'));\n  }\n  var latchFunctionResult;\n  try {\n    latchFunctionResult = this.latchFunction.apply(this.spec);\n  } catch (e) {\n    this.spec.fail(e);\n    onComplete();\n    return;\n  }\n\n  if (latchFunctionResult) {\n    onComplete();\n  } else if (this.totalTimeSpentWaitingForLatch >= this.timeout) {\n    var message = 'timed out after ' + this.timeout + ' msec waiting for ' + (this.message || 'something to happen');\n    this.spec.fail({\n      name: 'timeout',\n      message: message\n    });\n\n    this.abort = true;\n    onComplete();\n  } else {\n    this.totalTimeSpentWaitingForLatch += jasmine.WaitsForBlock.TIMEOUT_INCREMENT;\n    var self = this;\n    this.env.setTimeout(function() {\n      self.execute(onComplete);\n    }, jasmine.WaitsForBlock.TIMEOUT_INCREMENT);\n  }\n};\n\njasmine.version_= {\n  \"major\": 1,\n  \"minor\": 3,\n  \"build\": 1,\n  \"revision\": 1354556913\n};\n\n"
  },
  {
    "path": "tests/native.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n\t<meta charset=\"utf-8\" />\n\t<title>Jasmine Spec Runner</title>\n\n\t<link rel=\"shortcut icon\" type=\"image/png\" href=\"lib/jasmine_favicon.png\">\n\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"lib/jasmine.css\">\n\t<script type=\"text/javascript\" src=\"lib/jasmine.js\"></script>\n\t<script type=\"text/javascript\" src=\"lib/jasmine-html.js\"></script>\n\t<script type=\"text/javascript\" src=\"https://cdnjs.cloudflare.com/ajax/libs/json3/3.3.2/json3.min.js\"></script>\n\n\t<!-- include helper files here... -->\n\t<script src=\"helpers/h-matchers.js\"></script>\n\n\t<!-- include spec files here... -->\n\t<script src=\"spec/s-array.js\"></script>\n\t<script src=\"spec/s-date.js\"></script>\n\t<script src=\"spec/s-error.js\"></script>\n\t<script src=\"spec/s-function.js\"></script>\n\t<script src=\"spec/s-global.js\"></script>\n\t<script src=\"spec/s-number.js\"></script>\n\t<script src=\"spec/s-object.js\"></script>\n\t<script src=\"spec/s-string.js\"></script>\n\t<script src=\"spec/s-regexp.js\"></script>\n\n\n\t<script type=\"text/javascript\">\n\t\t(function() {\n\t\t\tvar jasmineEnv = jasmine.getEnv();\n\t\t\tjasmineEnv.updateInterval = 1000;\n\n\t\t\tvar trivialReporter = new jasmine.TrivialReporter();\n\n\t\t\tjasmineEnv.addReporter(trivialReporter);\n\n\t\t\tjasmineEnv.specFilter = function(spec) {\n\t\t\t\treturn trivialReporter.specFilter(spec);\n\t\t\t};\n\n\t\t\tvar currentWindowOnload = window.onload;\n\n\t\t\twindow.onload = function() {\n\t\t\t\tif (currentWindowOnload) {\n\t\t\t\t\tcurrentWindowOnload();\n\t\t\t\t}\n\t\t\t\texecJasmine();\n\t\t\t};\n\n\t\t\tfunction execJasmine() {\n\t\t\t\tjasmineEnv.execute();\n\t\t\t}\n\n\t\t})();\n\t</script>\n\n</head>\n\n<body>\n</body>\n</html>\n"
  },
  {
    "path": "tests/spec/s-array.js",
    "content": "/* globals document */\n\nvar toStr = Object.prototype.toString;\nvar canDistinguishSparseFromUndefined = 0 in [undefined]; // IE 6 - 8 have a bug where this returns false.\nvar ifHasDenseUndefinedsIt = canDistinguishSparseFromUndefined ? it : xit;\nvar undefinedIfNoSparseBug = canDistinguishSparseFromUndefined ? undefined : { valueOf: function () { return 0; } };\nvar hasStrictMode = (function () {\n    'use strict';\n\n    return !this;\n}());\nvar ifHasStrictIt = hasStrictMode ? it : xit;\n\ndescribe('Array', function () {\n    var testSubject;\n\n    beforeEach(function () {\n        testSubject = [2, 3, undefinedIfNoSparseBug, true, 'hej', null, false, 0];\n        delete testSubject[1];\n    });\n\n    var createArrayLikeFromArray = function createArrayLikeFromArray(arr) {\n        var o = {};\n        Array.prototype.forEach.call(arr, function (e, i) {\n            o[i] = e;\n        });\n        o.length = arr.length;\n        return o;\n    };\n\n    describe('#forEach()', function () {\n        var expected, actual;\n\n        beforeEach(function () {\n            expected = { 0: 2, 2: undefinedIfNoSparseBug, 3: true, 4: 'hej', 5: null, 6: false, 7: 0 };\n            actual = {};\n        });\n\n        it('should pass the right parameters', function () {\n            var callback = jasmine.createSpy('callback');\n            var array = ['1'];\n            array.forEach(callback);\n            expect(callback).toHaveBeenCalledWith('1', 0, array);\n        });\n\n        it('should not affect elements added to the array after it has begun', function () {\n            var arr = [1, 2, 3];\n            var i = 0;\n            arr.forEach(function (a) {\n                i += 1;\n                arr.push(a + 3);\n            });\n            expect(arr).toEqual([1, 2, 3, 4, 5, 6]);\n            expect(i).toBe(3);\n        });\n\n        it('should set the right context when given none', function () {\n            var context;\n            [1].forEach(function () { context = this; });\n            expect(context).toBe(function () { return this; }.call());\n        });\n\n        it('should iterate all', function () {\n            testSubject.forEach(function (obj, index) {\n                actual[index] = obj;\n            });\n            expect(actual).toExactlyMatch(expected);\n        });\n\n        it('should iterate all using a context', function () {\n            var o = { a: actual };\n\n            testSubject.forEach(function (obj, index) {\n                this.a[index] = obj;\n            }, o);\n            expect(actual).toExactlyMatch(expected);\n        });\n\n        it('should iterate all in an array-like object', function () {\n            var ts = createArrayLikeFromArray(testSubject);\n            Array.prototype.forEach.call(ts, function (obj, index) {\n                actual[index] = obj;\n            });\n            expect(actual).toExactlyMatch(expected);\n        });\n\n        it('should iterate all in an array-like object using a context', function () {\n            var ts = createArrayLikeFromArray(testSubject);\n            var o = { a: actual };\n\n            Array.prototype.forEach.call(ts, function (obj, index) {\n                this.a[index] = obj;\n            }, o);\n            expect(actual).toExactlyMatch(expected);\n        });\n\n        describe('strings', function () {\n            var str = 'Hello, World!';\n\n            it('should iterate all in a string', function () {\n                actual = [];\n                Array.prototype.forEach.call(str, function (item, index) {\n                    actual[index] = item;\n                });\n                expect(actual).toExactlyMatch(str.split(''));\n            });\n\n            it('should iterate all in a string using a context', function () {\n                actual = [];\n                var o = { a: actual };\n                Array.prototype.forEach.call(str, function (item, index) {\n                    this.a[index] = item;\n                }, o);\n                expect(actual).toExactlyMatch(str.split(''));\n            });\n        });\n\n        it('should have a boxed object as list argument of callback', function () {\n            var listArg;\n            Array.prototype.forEach.call('foo', function (item, index, list) {\n                listArg = list;\n            });\n            expect(typeof listArg).toBe('object');\n            expect(toStr.call(listArg)).toBe('[object String]');\n        });\n\n        ifHasStrictIt('does not autobox the content in strict mode', function () {\n            var context;\n            [1].forEach(function () {\n                'use strict';\n\n                context = this;\n            }, 'x');\n            expect(typeof context).toBe('string');\n        });\n    });\n    describe('#some()', function () {\n        var actual, expected, numberOfRuns;\n\n        beforeEach(function () {\n            expected = { 0: 2, 2: undefinedIfNoSparseBug, 3: true };\n            actual = {};\n            numberOfRuns = 0;\n        });\n\n        it('should pass the correct values along to the callback', function () {\n            var callback = jasmine.createSpy('callback');\n            var array = ['1'];\n            array.some(callback);\n            expect(callback).toHaveBeenCalledWith('1', 0, array);\n        });\n\n        it('should not affect elements added to the array after it has begun', function () {\n            var arr = [1, 2, 3];\n            var i = 0;\n            arr.some(function (a) {\n                i += 1;\n                arr.push(a + 3);\n                return i > 3;\n            });\n            expect(arr).toEqual([1, 2, 3, 4, 5, 6]);\n            expect(i).toBe(3);\n        });\n\n        it('should set the right context when given none', function () {\n            /* eslint-disable array-callback-return */\n            var context;\n            [1].some(function () { context = this; });\n            expect(context).toBe(function () { return this; }.call());\n        });\n\n        it('should return false if it runs to the end', function () {\n            /* eslint-disable array-callback-return */\n            actual = testSubject.some(function () {});\n            expect(actual).toBeFalsy();\n        });\n\n        it('should return true if it is stopped somewhere', function () {\n            actual = testSubject.some(function () { return true; });\n            expect(actual).toBeTruthy();\n        });\n\n        it('should return false if there are no elements', function () {\n            actual = [].some(function () { return true; });\n            expect(actual).toBeFalsy();\n        });\n\n        it('should stop after 3 elements', function () {\n            testSubject.some(function (obj, index) {\n                actual[index] = obj;\n                numberOfRuns += 1;\n                return numberOfRuns === 3;\n            });\n            expect(actual).toExactlyMatch(expected);\n        });\n\n        it('should stop after 3 elements using a context', function () {\n            var o = { a: actual };\n            testSubject.some(function (obj, index) {\n                this.a[index] = obj;\n                numberOfRuns += 1;\n                return numberOfRuns === 3;\n            }, o);\n            expect(actual).toExactlyMatch(expected);\n        });\n\n        it('should stop after 3 elements in an array-like object', function () {\n            var ts = createArrayLikeFromArray(testSubject);\n            Array.prototype.some.call(ts, function (obj, index) {\n                actual[index] = obj;\n                numberOfRuns += 1;\n                return numberOfRuns === 3;\n            });\n            expect(actual).toExactlyMatch(expected);\n        });\n\n        it('should stop after 3 elements in an array-like object using a context', function () {\n            var ts = createArrayLikeFromArray(testSubject);\n            var o = { a: actual };\n            Array.prototype.some.call(ts, function (obj, index) {\n                this.a[index] = obj;\n                numberOfRuns += 1;\n                return numberOfRuns === 3;\n            }, o);\n            expect(actual).toExactlyMatch(expected);\n        });\n\n        it('should have a boxed object as list argument of callback', function () {\n            var listArg;\n            Array.prototype.some.call('foo', function (item, index, list) {\n                listArg = list;\n            });\n            expect(typeof listArg).toBe('object');\n            expect(toStr.call(listArg)).toBe('[object String]');\n        });\n    });\n    describe('#every()', function () {\n        var actual, expected, numberOfRuns;\n\n        beforeEach(function () {\n            expected = { 0: 2, 2: undefinedIfNoSparseBug, 3: true };\n            actual = {};\n            numberOfRuns = 0;\n        });\n\n        it('should pass the correct values along to the callback', function () {\n            var callback = jasmine.createSpy('callback');\n            var array = ['1'];\n            array.every(callback);\n            expect(callback).toHaveBeenCalledWith('1', 0, array);\n        });\n\n        it('should not affect elements added to the array after it has begun', function () {\n            var arr = [1, 2, 3];\n            var i = 0;\n            arr.every(function (a) {\n                i += 1;\n                arr.push(a + 3);\n                return i <= 3;\n            });\n            expect(arr).toEqual([1, 2, 3, 4, 5, 6]);\n            expect(i).toBe(3);\n        });\n\n        it('should set the right context when given none', function () {\n            /* eslint-disable array-callback-return */\n            var context;\n            [1].every(function () { context = this; });\n            expect(context).toBe(function () { return this; }.call());\n        });\n\n        it('should return true if the array is empty', function () {\n            actual = [].every(function () { return true; });\n            expect(actual).toBeTruthy();\n\n            actual = [].every(function () { return false; });\n            expect(actual).toBeTruthy();\n        });\n\n        it('should return true if it runs to the end', function () {\n            actual = [1, 2, 3].every(function () { return true; });\n            expect(actual).toBeTruthy();\n        });\n\n        it('should return false if it is stopped before the end', function () {\n            actual = [1, 2, 3].every(function () { return false; });\n            expect(actual).toBeFalsy();\n        });\n\n        it('should return after 3 elements', function () {\n            testSubject.every(function (obj, index) {\n                actual[index] = obj;\n                numberOfRuns += 1;\n                return numberOfRuns !== 3;\n            });\n            expect(actual).toExactlyMatch(expected);\n        });\n\n        it('should stop after 3 elements using a context', function () {\n            var o = { a: actual };\n            testSubject.every(function (obj, index) {\n                this.a[index] = obj;\n                numberOfRuns += 1;\n                return numberOfRuns !== 3;\n            }, o);\n            expect(actual).toExactlyMatch(expected);\n        });\n\n        it('should stop after 3 elements in an array-like object', function () {\n            var ts = createArrayLikeFromArray(testSubject);\n            Array.prototype.every.call(ts, function (obj, index) {\n                actual[index] = obj;\n                numberOfRuns += 1;\n                return numberOfRuns !== 3;\n            });\n            expect(actual).toExactlyMatch(expected);\n        });\n\n        it('should stop after 3 elements in an array-like object using a context', function () {\n            var ts = createArrayLikeFromArray(testSubject);\n            var o = { a: actual };\n            Array.prototype.every.call(ts, function (obj, index) {\n                this.a[index] = obj;\n                numberOfRuns += 1;\n                return numberOfRuns !== 3;\n            }, o);\n            expect(actual).toExactlyMatch(expected);\n        });\n\n        it('should have a boxed object as list argument of callback', function () {\n            var listArg;\n            Array.prototype.every.call('foo', function (item, index, list) {\n                listArg = list;\n            });\n            expect(typeof listArg).toBe('object');\n            expect(toStr.call(listArg)).toBe('[object String]');\n        });\n    });\n\n    describe('#indexOf()', function () {\n        'use strict';\n\n        var actual, expected;\n\n        beforeEach(function () {\n            testSubject = [2, 3, undefinedIfNoSparseBug, true, 'hej', null, 2, false, 0];\n            delete testSubject[1];\n        });\n\n        it('should find the element', function () {\n            expected = 4;\n            actual = testSubject.indexOf('hej');\n            expect(actual).toBe(expected);\n        });\n\n        it('should not find the element', function () {\n            expected = -1;\n            actual = testSubject.indexOf('mus');\n            expect(actual).toBe(expected);\n        });\n\n        ifHasDenseUndefinedsIt('should find undefined as well', function () {\n            expected = -1;\n            actual = testSubject.indexOf(undefined);\n            expect(actual).not.toBe(expected);\n        });\n\n        ifHasDenseUndefinedsIt('should skip unset indexes', function () {\n            expected = 2;\n            actual = testSubject.indexOf(undefined);\n            expect(actual).toBe(expected);\n        });\n\n        it('should use a strict test', function () {\n            actual = testSubject.indexOf(null);\n            expect(actual).toBe(5);\n\n            actual = testSubject.indexOf('2');\n            expect(actual).toBe(-1);\n        });\n\n        it('should skip the first if fromIndex is set', function () {\n            expect(testSubject.indexOf(2, 2)).toBe(6);\n            expect(testSubject.indexOf(2, 0)).toBe(0);\n            expect(testSubject.indexOf(2, 6)).toBe(6);\n        });\n\n        it('should work with negative fromIndex', function () {\n            expect(testSubject.indexOf(2, -3)).toBe(6);\n            expect(testSubject.indexOf(2, -9)).toBe(0);\n        });\n\n        it('should work with fromIndex being greater than the length', function () {\n            expect(testSubject.indexOf(0, 20)).toBe(-1);\n        });\n\n        it('should work with fromIndex being negative and greater than the length', function () {\n            expect(testSubject.indexOf('hej', -20)).toBe(4);\n        });\n\n        describe('Array-like', function ArrayLike() {\n            var indexOf = Array.prototype.indexOf;\n            var testAL;\n\n            beforeEach(function beforeEach() {\n                testAL = {};\n                testSubject = [2, 3, undefinedIfNoSparseBug, true, 'hej', null, 2, false, 0];\n                testSubject.forEach(function (o, i) {\n                    testAL[i] = o;\n                });\n                testAL.length = testSubject.length;\n            });\n\n            it('should find the element (array-like)', function () {\n                expected = 4;\n                actual = indexOf.call(testAL, 'hej');\n                expect(actual).toBe(expected);\n            });\n\n            it('should not find the element (array-like)', function () {\n                expected = -1;\n                actual = indexOf.call(testAL, 'mus');\n                expect(actual).toBe(expected);\n            });\n\n            ifHasDenseUndefinedsIt('should find undefined as well (array-like)', function () {\n                expected = -1;\n                actual = indexOf.call(testAL, undefined);\n                expect(actual).not.toBe(expected);\n            });\n\n            ifHasDenseUndefinedsIt('should skip unset indexes (array-like)', function () {\n                expected = 2;\n                actual = indexOf.call(testAL, undefined);\n                expect(actual).toBe(expected);\n            });\n\n            it('should use a strict test (array-like)', function () {\n                actual = Array.prototype.indexOf.call(testAL, null);\n                expect(actual).toBe(5);\n\n                actual = Array.prototype.indexOf.call(testAL, '2');\n                expect(actual).toBe(-1);\n            });\n\n            it('should skip the first if fromIndex is set (array-like)', function () {\n                expect(indexOf.call(testAL, 2, 2)).toBe(6);\n                expect(indexOf.call(testAL, 2, 0)).toBe(0);\n                expect(indexOf.call(testAL, 2, 6)).toBe(6);\n            });\n\n            it('should work with negative fromIndex (array-like)', function () {\n                expect(indexOf.call(testAL, 2, -3)).toBe(6);\n                expect(indexOf.call(testAL, 2, -9)).toBe(0);\n            });\n\n            it('should work with fromIndex being greater than the length (array-like)', function () {\n                expect(indexOf.call(testAL, 0, 20)).toBe(-1);\n            });\n\n            it('should work with fromIndex being negative and greater than the length (array-like)', function () {\n                expect(indexOf.call(testAL, 'hej', -20)).toBe(4);\n            });\n        });\n    });\n    describe('#lastIndexOf()', function () {\n        'use strict';\n\n        var actual, expected;\n\n        beforeEach(function () {\n            testSubject = [2, 3, undefinedIfNoSparseBug, true, 'hej', null, 2, 3, false, 0];\n            delete testSubject[1];\n            delete testSubject[7];\n        });\n\n        describe('Array', function () {\n            it('should find the element', function () {\n                expected = 4;\n                actual = testSubject.lastIndexOf('hej');\n                expect(actual).toBe(expected);\n            });\n\n            it('should not find the element', function () {\n                expected = -1;\n                actual = testSubject.lastIndexOf('mus');\n                expect(actual).toBe(expected);\n            });\n\n            ifHasDenseUndefinedsIt('should find undefined as well', function () {\n                expected = -1;\n                actual = testSubject.lastIndexOf(undefined);\n                expect(actual).not.toBe(expected);\n            });\n\n            ifHasDenseUndefinedsIt('should skip unset indexes', function () {\n                expected = 2;\n                actual = testSubject.lastIndexOf(undefined);\n                expect(actual).toBe(expected);\n            });\n\n            it('should use a strict test', function () {\n                actual = testSubject.lastIndexOf(null);\n                expect(actual).toBe(5);\n\n                actual = testSubject.lastIndexOf('2');\n                expect(actual).toBe(-1);\n            });\n\n            it('should skip the first if fromIndex is set', function () {\n                expect(testSubject.lastIndexOf(2, 2)).toBe(0);\n                expect(testSubject.lastIndexOf(2, 0)).toBe(0);\n                expect(testSubject.lastIndexOf(2, 6)).toBe(6);\n            });\n\n            it('should work with negative fromIndex', function () {\n                expect(testSubject.lastIndexOf(2, -3)).toBe(6);\n                expect(testSubject.lastIndexOf(2, -9)).toBe(0);\n            });\n\n            it('should work with fromIndex being greater than the length', function () {\n                expect(testSubject.lastIndexOf(2, 20)).toBe(6);\n            });\n\n            it('should work with fromIndex being negative and greater than the length', function () {\n                expect(testSubject.lastIndexOf(2, -20)).toBe(-1);\n            });\n        });\n\n        describe('Array like', function () {\n            var lastIndexOf = Array.prototype.lastIndexOf;\n            var testAL;\n\n            beforeEach(function () {\n                testAL = {};\n                testSubject.forEach(function (o, i) {\n                    testAL[i] = o;\n                });\n                testAL.length = testSubject.length;\n            });\n\n            it('should find the element (array-like)', function () {\n                expected = 4;\n                actual = lastIndexOf.call(testAL, 'hej');\n                expect(actual).toBe(expected);\n            });\n\n            it('should not find the element (array-like)', function () {\n                expected = -1;\n                actual = lastIndexOf.call(testAL, 'mus');\n                expect(actual).toBe(expected);\n            });\n\n            ifHasDenseUndefinedsIt('should find undefined as well (array-like)', function () {\n                expected = -1;\n                actual = lastIndexOf.call(testAL, undefined);\n                expect(actual).not.toBe(expected);\n            });\n\n            ifHasDenseUndefinedsIt('should skip unset indexes (array-like)', function () {\n                expected = 2;\n                actual = lastIndexOf.call(testAL, undefined);\n                expect(actual).toBe(expected);\n            });\n\n            it('should use a strict test (array-like)', function () {\n                actual = lastIndexOf.call(testAL, null);\n                expect(actual).toBe(5);\n\n                actual = lastIndexOf.call(testAL, '2');\n                expect(actual).toBe(-1);\n            });\n\n            it('should skip the first if fromIndex is set', function () {\n                expect(lastIndexOf.call(testAL, 2, 2)).toBe(0);\n                expect(lastIndexOf.call(testAL, 2, 0)).toBe(0);\n                expect(lastIndexOf.call(testAL, 2, 6)).toBe(6);\n            });\n\n            it('should work with negative fromIndex', function () {\n                expect(lastIndexOf.call(testAL, 2, -3)).toBe(6);\n                expect(lastIndexOf.call(testAL, 2, -9)).toBe(0);\n            });\n\n            it('should work with fromIndex being greater than the length', function () {\n                expect(lastIndexOf.call(testAL, 2, 20)).toBe(6);\n            });\n\n            it('should work with fromIndex being negative and greater than the length', function () {\n                expect(lastIndexOf.call(testAL, 2, -20)).toBe(-1);\n            });\n        });\n    });\n\n    describe('#filter()', function () {\n        var filteredArray;\n        var callback = function callback(o, i) {\n            return i !== 3 && i !== 5;\n        };\n\n        beforeEach(function () {\n            testSubject = [2, 3, undefinedIfNoSparseBug, true, 'hej', 3, null, false, 0];\n            delete testSubject[1];\n            filteredArray = [2, undefinedIfNoSparseBug, 'hej', null, false, 0];\n        });\n        describe('Array object', function () {\n            it('should call the callback with the proper arguments', function () {\n                var predicate = jasmine.createSpy('predicate');\n                var arr = ['1'];\n                arr.filter(predicate);\n                expect(predicate).toHaveBeenCalledWith('1', 0, arr);\n            });\n\n            it('should not affect elements added to the array after it has begun', function () {\n                var arr = [1, 2, 3];\n                var i = 0;\n                arr.filter(function (a) {\n                    i += 1;\n                    if (i <= 4) {\n                        arr.push(a + 3);\n                    }\n                    return true;\n                });\n                expect(arr).toEqual([1, 2, 3, 4, 5, 6]);\n                expect(i).toBe(3);\n            });\n\n            ifHasDenseUndefinedsIt('should skip unset values', function () {\n                var passedValues = {};\n                testSubject = [1, 2, 3, 4];\n                delete testSubject[1];\n                testSubject.filter(function (o, i) {\n                    passedValues[i] = o;\n                    return true;\n                });\n                expect(passedValues).toExactlyMatch(testSubject);\n            });\n\n            it('should pass the right context to the filter', function () {\n                var passedValues = {};\n                testSubject = [1, 2, 3, 4];\n                delete testSubject[1];\n                testSubject.filter(function (o, i) {\n                    this[i] = o;\n                    return true;\n                }, passedValues);\n                expect(passedValues).toExactlyMatch(testSubject);\n            });\n\n            it('should set the right context when given none', function () {\n                /* eslint-disable array-callback-return */\n                var context;\n                [1].filter(function () { context = this; });\n                expect(context).toBe(function () { return this; }.call());\n            });\n\n            it('should remove only the values for which the callback returns false', function () {\n                var result = testSubject.filter(callback);\n                expect(result).toExactlyMatch(filteredArray);\n            });\n\n            it('should leave the original array untouched', function () {\n                var copy = testSubject.slice();\n                expect(copy).toNotBe(testSubject);\n\n                testSubject.filter(callback);\n\n                expect(testSubject).toExactlyMatch(copy);\n            });\n\n            it('should not be affected by same-index mutation', function () {\n                var results = [1, 2, 3].filter(function (value, index, array) {\n                    array[index] = 'a'; // eslint-disable-line no-param-reassign\n                    return true;\n                });\n                expect(results).toEqual([1, 2, 3]);\n            });\n        });\n\n        describe('Array like', function () {\n            beforeEach(function () {\n                testSubject = createArrayLikeFromArray(testSubject);\n            });\n\n            it('should call the predicate with the proper arguments', function () {\n                var predicate = jasmine.createSpy('predicate');\n                var arr = createArrayLikeFromArray(['1']);\n                Array.prototype.filter.call(arr, predicate);\n                expect(predicate).toHaveBeenCalledWith('1', 0, arr);\n            });\n\n            it('should not affect elements added to the array after it has begun', function () {\n                var arr = createArrayLikeFromArray([1, 2, 3]);\n                var i = 0;\n                Array.prototype.filter.call(arr, function (a) {\n                    i += 1;\n                    if (i <= 4) {\n                        arr[i + 2] = a + 3;\n                        arr.length += 1;\n                    }\n                    return true;\n                });\n                expect(Array.prototype.slice.call(arr)).toEqual([1, 2, 3, 4, 5, 6]);\n                expect(i).toBe(3);\n            });\n\n            it('should skip non-set values', function () {\n                var passedValues = createArrayLikeFromArray([]);\n                testSubject = createArrayLikeFromArray([1, 2, 3, 4]);\n                delete testSubject[1];\n                Array.prototype.filter.call(testSubject, function (o, i) {\n                    passedValues[i] = o;\n                    passedValues.length = i + 1;\n                    return true;\n                });\n                expect(passedValues).toEqual(testSubject);\n            });\n\n            it('should set the right context when given none', function () {\n                var context;\n                Array.prototype.filter.call(createArrayLikeFromArray([1]), function () { context = this; }, undefined);\n                expect(context).toBe(function () { return this; }.call());\n            });\n\n            it('should pass the right context to the filter', function () {\n                var passedValues = {};\n                testSubject = createArrayLikeFromArray([1, 2, 3, 4]);\n                delete testSubject[1];\n                Array.prototype.filter.call(testSubject, function (o, i) {\n                    this[i] = o;\n                    this.length = i + 1;\n                    return true;\n                }, passedValues);\n                expect(passedValues).toEqual(testSubject);\n            });\n\n            it('should remove only the values for which the callback returns false', function () {\n                var result = Array.prototype.filter.call(testSubject, callback);\n                expect(result).toExactlyMatch(filteredArray);\n            });\n\n            it('should leave the original array untouched', function () {\n                var copy = createArrayLikeFromArray(testSubject);\n                Array.prototype.filter.call(testSubject, callback);\n                expect(testSubject).toExactlyMatch(copy);\n            });\n        });\n\n        it('should have a boxed object as list argument of callback', function () {\n            var actual;\n            Array.prototype.filter.call('foo', function (item, index, list) {\n                actual = list;\n            });\n            expect(typeof actual).toBe('object');\n            expect(toStr.call(actual)).toBe('[object String]');\n        });\n    });\n    describe('#map()', function () {\n        var callback;\n        beforeEach(function () {\n            var i = 0;\n            callback = function () {\n                return i++;\n            };\n        });\n        describe('Array object', function () {\n            it('should call mapper with the right parameters', function () {\n                var mapper = jasmine.createSpy('mapper');\n                var array = [1];\n                array.map(mapper);\n                expect(mapper).toHaveBeenCalledWith(1, 0, array);\n            });\n\n            it('should set the context correctly', function () {\n                var context = {};\n                testSubject.map(function (o, i) {\n                    this[i] = o;\n                }, context);\n                expect(context).toExactlyMatch(testSubject);\n            });\n\n            it('should set the right context when given none', function () {\n                var context;\n                [1].map(function () { context = this; });\n                expect(context).toBe(function () { return this; }.call());\n            });\n\n            it('should not change the array it is called on', function () {\n                var copy = testSubject.slice();\n                testSubject.map(callback);\n                expect(testSubject).toExactlyMatch(copy);\n            });\n\n            it('should only run for the number of objects in the array when it started', function () {\n                var arr = [1, 2, 3];\n                var i = 0;\n                arr.map(function (o) {\n                    arr.push(o + 3);\n                    i += 1;\n                    return o;\n                });\n                expect(arr).toExactlyMatch([1, 2, 3, 4, 5, 6]);\n                expect(i).toBe(3);\n            });\n\n            it('should properly translate the values as according to the callback', function () {\n                var result = testSubject.map(callback);\n                var expected = [0, 0, 1, 2, 3, 4, 5, 6];\n                delete expected[1];\n                expect(result).toExactlyMatch(expected);\n            });\n\n            it('should skip non-existing values', function () {\n                var array = [1, 2, 3, 4];\n                var i = 0;\n                delete array[2];\n                array.map(function () {\n                    i += 1;\n                });\n                expect(i).toBe(3);\n            });\n        });\n        describe('Array-like', function () {\n            beforeEach(function () {\n                testSubject = createArrayLikeFromArray(testSubject);\n            });\n\n            it('should call mapper with the right parameters', function () {\n                var mapper = jasmine.createSpy('mapper');\n                var array = createArrayLikeFromArray([1]);\n                Array.prototype.map.call(array, mapper);\n                expect(mapper).toHaveBeenCalledWith(1, 0, array);\n            });\n\n            it('should set the context correctly', function () {\n                var context = {};\n                Array.prototype.map.call(testSubject, function (o, i) {\n                    this[i] = o;\n                    this.length = i + 1;\n                }, context);\n                expect(context).toEqual(testSubject);\n            });\n\n            it('should set the right context when given none', function () {\n                var context;\n                Array.prototype.map.call(createArrayLikeFromArray([1]), function () { context = this; });\n                expect(context).toBe(function () { return this; }.call());\n            });\n\n            it('should not change the array it is called on', function () {\n                var copy = createArrayLikeFromArray(testSubject);\n                Array.prototype.map.call(testSubject, callback);\n                expect(testSubject).toExactlyMatch(copy);\n            });\n\n            it('should only run for the number of objects in the array when it started', function () {\n                var arr = createArrayLikeFromArray([1, 2, 3]);\n                var i = 0;\n                Array.prototype.map.call(arr, function (o) {\n                    Array.prototype.push.call(arr, o + 3);\n                    i += 1;\n                    return o;\n                });\n                expect(Array.prototype.slice.call(arr)).toEqual([1, 2, 3, 4, 5, 6]);\n                expect(i).toBe(3);\n            });\n\n            it('should properly translate the values as according to the callback', function () {\n                var result = Array.prototype.map.call(testSubject, callback);\n                var expected = [0, 0, 1, 2, 3, 4, 5, 6];\n                delete expected[1];\n                expect(result).toExactlyMatch(expected);\n            });\n\n            it('should skip non-existing values', function () {\n                var array = createArrayLikeFromArray([1, 2, 3, 4]);\n                var i = 0;\n                delete array[2];\n                Array.prototype.map.call(array, function () {\n                    i += 1;\n                });\n                expect(i).toBe(3);\n            });\n        });\n\n        it('should have a boxed object as list argument of callback', function () {\n            var actual;\n            Array.prototype.map.call('foo', function (item, index, list) {\n                actual = list;\n            });\n            expect(typeof actual).toBe('object');\n            expect(toStr.call(actual)).toBe('[object String]');\n        });\n    });\n\n    describe('#reduce()', function () {\n        beforeEach(function () {\n            testSubject = [1, 2, 3];\n        });\n\n        describe('Array', function () {\n            it('should pass the correct arguments to the callback', function () {\n                var spy = jasmine.createSpy().andReturn(0);\n                testSubject.reduce(spy);\n                expect(spy.calls[0].args).toExactlyMatch([1, 2, 1, testSubject]);\n            });\n\n            it('should start with the right initialValue', function () {\n                var spy = jasmine.createSpy().andReturn(0);\n                testSubject.reduce(spy, 0);\n                expect(spy.calls[0].args).toExactlyMatch([0, 1, 0, testSubject]);\n            });\n\n            it('should not affect elements added to the array after it has begun', function () {\n                var arr = [1, 2, 3];\n                var i = 0;\n                arr.reduce(function (a, b) {\n                    i += 1;\n                    if (i <= 4) {\n                        arr.push(a + 3);\n                    }\n                    return b;\n                });\n                expect(arr).toEqual([1, 2, 3, 4, 5]);\n                expect(i).toBe(2);\n            });\n\n            it('should work as expected for empty arrays', function () {\n                var spy = jasmine.createSpy();\n                expect(function () {\n                    [].reduce(spy);\n                }).toThrow();\n                expect(spy).not.toHaveBeenCalled();\n            });\n\n            it('should throw correctly if no callback is given', function () {\n                expect(function () {\n                    testSubject.reduce();\n                }).toThrow();\n            });\n\n            it('should return the expected result', function () {\n                expect(testSubject.reduce(function (a, b) {\n                    return String(a || '') + String(b || '');\n                })).toBe(testSubject.join(''));\n            });\n\n            it('should not directly affect the passed array', function () {\n                var copy = testSubject.slice();\n                testSubject.reduce(function (a, b) {\n                    return a + b;\n                });\n                expect(testSubject).toEqual(copy);\n            });\n\n            it('should skip non-set values', function () {\n                delete testSubject[1];\n                var visited = {};\n                testSubject.reduce(function (a, b) {\n                    if (a) { visited[a] = true; }\n                    if (b) { visited[b] = true; }\n                    return 0;\n                });\n\n                expect(visited).toEqual({ 1: true, 3: true });\n            });\n\n            it('should have the right length', function () {\n                expect(testSubject.reduce.length).toBe(1);\n            });\n        });\n        describe('Array-like objects', function () {\n            beforeEach(function () {\n                testSubject = createArrayLikeFromArray(testSubject);\n                testSubject.reduce = Array.prototype.reduce;\n            });\n\n            it('should pass the correct arguments to the callback', function () {\n                var spy = jasmine.createSpy().andReturn(0);\n                testSubject.reduce(spy);\n                expect(spy.calls[0].args).toExactlyMatch([1, 2, 1, testSubject]);\n            });\n\n            it('should start with the right initialValue', function () {\n                var spy = jasmine.createSpy().andReturn(0);\n                testSubject.reduce(spy, 0);\n                expect(spy.calls[0].args).toExactlyMatch([0, 1, 0, testSubject]);\n            });\n\n            it('should not affect elements added to the array after it has begun', function () {\n                var arr = createArrayLikeFromArray([1, 2, 3]);\n                var i = 0;\n                Array.prototype.reduce.call(arr, function (a, b) {\n                    i += 1;\n                    if (i <= 4) {\n                        arr[i + 2] = a + 3;\n                    }\n                    return b;\n                });\n                expect(arr).toEqual({\n                    0: 1,\n                    1: 2,\n                    2: 3,\n                    3: 4,\n                    4: 5,\n                    length: 3\n                });\n                expect(i).toBe(2);\n            });\n\n            it('should work as expected for empty arrays', function () {\n                var spy = jasmine.createSpy();\n                expect(function () {\n                    Array.prototype.reduce.call({ length: 0 }, spy);\n                }).toThrow();\n                expect(spy).not.toHaveBeenCalled();\n            });\n\n            it('should throw correctly if no callback is given', function () {\n                expect(function () {\n                    testSubject.reduce();\n                }).toThrow();\n            });\n\n            it('should return the expected result', function () {\n                expect(testSubject.reduce(function (a, b) {\n                    return String(a || '') + String(b || '');\n                })).toBe('123');\n            });\n\n            it('should not directly affect the passed array', function () {\n                var copy = createArrayLikeFromArray(testSubject);\n                testSubject.reduce(function (a, b) {\n                    return a + b;\n                });\n                delete testSubject.reduce;\n                expect(testSubject).toEqual(copy);\n            });\n\n            it('should skip non-set values', function () {\n                delete testSubject[1];\n                var visited = {};\n                testSubject.reduce(function (a, b) {\n                    if (a) { visited[a] = true; }\n                    if (b) { visited[b] = true; }\n                    return 0;\n                });\n\n                expect(visited).toEqual({ 1: true, 3: true });\n            });\n\n            it('should have the right length', function () {\n                expect(testSubject.reduce.length).toBe(1);\n            });\n        });\n\n        it('should have a boxed object as list argument of callback', function () {\n            var actual;\n            Array.prototype.reduce.call('foo', function (accumulator, item, index, list) {\n                actual = list;\n            });\n            expect(typeof actual).toBe('object');\n            expect(toStr.call(actual)).toBe('[object String]');\n        });\n    });\n    describe('#reduceRight()', function () {\n        beforeEach(function () {\n            testSubject = [1, 2, 3];\n        });\n\n        describe('Array', function () {\n            it('should pass the correct arguments to the callback', function () {\n                var spy = jasmine.createSpy().andReturn(0);\n                testSubject.reduceRight(spy);\n                expect(spy.calls[0].args).toExactlyMatch([3, 2, 1, testSubject]);\n            });\n\n            it('should start with the right initialValue', function () {\n                var spy = jasmine.createSpy().andReturn(0);\n                testSubject.reduceRight(spy, 0);\n                expect(spy.calls[0].args).toExactlyMatch([0, 3, 2, testSubject]);\n            });\n\n            it('should not affect elements added to the array after it has begun', function () {\n                var arr = [1, 2, 3];\n                var i = 0;\n                arr.reduceRight(function (a, b) {\n                    i += 1;\n                    if (i <= 4) {\n                        arr.push(a + 3);\n                    }\n                    return b;\n                });\n                expect(arr).toEqual([1, 2, 3, 6, 5]);\n                expect(i).toBe(2);\n            });\n\n            it('should work as expected for empty arrays', function () {\n                var spy = jasmine.createSpy();\n                expect(function () {\n                    [].reduceRight(spy);\n                }).toThrow();\n                expect(spy).not.toHaveBeenCalled();\n            });\n\n            it('should work as expected for empty arrays with an initial value', function () {\n                var spy = jasmine.createSpy();\n                var result;\n\n                result = [].reduceRight(spy, '');\n                expect(spy).not.toHaveBeenCalled();\n                expect(result).toBe('');\n            });\n\n            it('should throw correctly if no callback is given', function () {\n                expect(function () {\n                    testSubject.reduceRight();\n                }).toThrow();\n            });\n\n            it('should return the expected result', function () {\n                expect(testSubject.reduceRight(function (a, b) {\n                    return String(a || '') + String(b || '');\n                })).toBe('321');\n            });\n\n            it('should not directly affect the passed array', function () {\n                var copy = testSubject.slice();\n                testSubject.reduceRight(function (a, b) {\n                    return a + b;\n                });\n                expect(testSubject).toEqual(copy);\n            });\n\n            it('should skip non-set values', function () {\n                delete testSubject[1];\n                var visited = {};\n                testSubject.reduceRight(function (a, b) {\n                    if (a) { visited[a] = true; }\n                    if (b) { visited[b] = true; }\n                    return 0;\n                });\n\n                expect(visited).toEqual({ 1: true, 3: true });\n            });\n\n            it('should have the right length', function () {\n                expect(testSubject.reduceRight.length).toBe(1);\n            });\n        });\n        describe('Array-like objects', function () {\n            beforeEach(function () {\n                testSubject = createArrayLikeFromArray(testSubject);\n                testSubject.reduceRight = Array.prototype.reduceRight;\n            });\n\n            it('should pass the correct arguments to the callback', function () {\n                var spy = jasmine.createSpy().andReturn(0);\n                testSubject.reduceRight(spy);\n                expect(spy.calls[0].args).toExactlyMatch([3, 2, 1, testSubject]);\n            });\n\n            it('should start with the right initialValue', function () {\n                var spy = jasmine.createSpy().andReturn(0);\n                testSubject.reduceRight(spy, 0);\n                expect(spy.calls[0].args).toExactlyMatch([0, 3, 2, testSubject]);\n            });\n\n            it('should not affect elements added to the array after it has begun', function () {\n                var arr = createArrayLikeFromArray([1, 2, 3]);\n                var i = 0;\n                Array.prototype.reduceRight.call(arr, function (a, b) {\n                    i += 1;\n                    if (i <= 4) {\n                        arr[i + 2] = a + 3;\n                    }\n                    return b;\n                });\n                expect(arr).toEqual({\n                    0: 1,\n                    1: 2,\n                    2: 3,\n                    3: 6,\n                    4: 5,\n                    length: 3 // does not get updated on property assignment\n                });\n                expect(i).toBe(2);\n            });\n\n            it('should work as expected for empty arrays', function () {\n                var spy = jasmine.createSpy();\n                expect(function () {\n                    Array.prototype.reduceRight.call({ length: 0 }, spy);\n                }).toThrow();\n                expect(spy).not.toHaveBeenCalled();\n            });\n\n            it('should throw correctly if no callback is given', function () {\n                expect(function () {\n                    testSubject.reduceRight();\n                }).toThrow();\n            });\n\n            it('should return the expected result', function () {\n                expect(testSubject.reduceRight(function (a, b) {\n                    return String(a || '') + String(b || '');\n                })).toBe('321');\n            });\n\n            it('should not directly affect the passed array', function () {\n                var copy = createArrayLikeFromArray(testSubject);\n                testSubject.reduceRight(function (a, b) {\n                    return a + b;\n                });\n                delete testSubject.reduceRight;\n                expect(testSubject).toEqual(copy);\n            });\n\n            it('should skip non-set values', function () {\n                delete testSubject[1];\n                var visited = {};\n                testSubject.reduceRight(function (a, b) {\n                    if (a) { visited[a] = true; }\n                    if (b) { visited[b] = true; }\n                    return 0;\n                });\n\n                expect(visited).toEqual({ 1: true, 3: true });\n            });\n\n            it('should have the right length', function () {\n                expect(testSubject.reduceRight.length).toBe(1);\n            });\n        });\n\n        it('should have a boxed object as list argument of callback', function () {\n            var actual;\n            Array.prototype.reduceRight.call('foo', function (accumulator, item, index, list) {\n                actual = list;\n            });\n            expect(typeof actual).toBe('object');\n            expect(toStr.call(actual)).toBe('[object String]');\n        });\n    });\n\n    describe('.isArray()', function () {\n        it('should be true for Array', function () {\n            expect(Array.isArray([])).toBe(true);\n        });\n\n        it('should be false for primitives', function () {\n            var primitives = [\n                'foo',\n                true,\n                false,\n                42,\n                0,\n                -0,\n                NaN,\n                Infinity,\n                -Infinity\n            ];\n            primitives.forEach(function (v) {\n                expect(Array.isArray(v)).toBe(false);\n            });\n        });\n\n        it('should fail for other objects', function () {\n            var objects = [\n                {},\n                /foo/,\n                arguments\n            ];\n            if (Object.create) {\n                objects.push(Object.create(null));\n            }\n\n            objects.forEach(function (v) {\n                expect(Array.isArray(v)).toBe(false);\n            });\n        });\n\n        if (typeof document !== 'undefined') {\n            it('should be false for an HTML element', function () {\n                var el = document.getElementsByTagName('div');\n                expect(Array.isArray(el)).toBe(false);\n            });\n        }\n    });\n\n    describe('#shift()', function () {\n        it('works on arrays', function () {\n            var arr = [1, 2];\n            var result = arr.shift();\n            expect(result).toBe(1);\n            expect(arr.length).toBe(1);\n            expect(Object.prototype.hasOwnProperty.call(arr, 0)).toBe(true);\n            expect(Object.prototype.hasOwnProperty.call(arr, 1)).toBe(false);\n            expect(arr[0]).toBe(2);\n            expect(arr[1]).toBeUndefined();\n        });\n\n        it('is generic', function () {\n            var obj = { 0: 1, 1: 2, length: 2 };\n            var result = Array.prototype.shift.call(obj);\n            expect(result).toBe(1);\n            expect(obj.length).toBe(1);\n            expect(Object.prototype.hasOwnProperty.call(obj, 0)).toBe(true);\n            expect(Object.prototype.hasOwnProperty.call(obj, 1)).toBe(false);\n            expect(obj[0]).toBe(2);\n            expect(obj[1]).toBeUndefined();\n        });\n    });\n\n    describe('#unshift()', function () {\n        it('should return length', function () {\n            expect([].unshift(0)).toBe(1);\n        });\n\n        it('works on arrays', function () {\n            var arr = [1];\n            var result = arr.unshift(undefined);\n            expect(result).toBe(2);\n            expect(arr.length).toBe(2);\n            expect(Object.prototype.hasOwnProperty.call(arr, 0)).toBe(true);\n            expect(Object.prototype.hasOwnProperty.call(arr, 1)).toBe(true);\n            expect(arr[0]).toBeUndefined();\n            expect(arr[1]).toBe(1);\n        });\n\n        it('is generic', function () {\n            var obj = { 0: 1, length: 1 };\n            var result = Array.prototype.unshift.call(obj, undefined);\n            expect(result).toBe(2);\n            expect(obj.length).toBe(2);\n            expect(Object.prototype.hasOwnProperty.call(obj, 0)).toBe(true);\n            expect(Object.prototype.hasOwnProperty.call(obj, 1)).toBe(true);\n            expect(obj[0]).toBeUndefined();\n            expect(obj[1]).toBe(1);\n        });\n    });\n\n    describe('#splice()', function () {\n        var b = ['b'];\n        var a = [1, 'a', b];\n        var test;\n\n        var makeArray = function (l, givenPrefix) {\n            var prefix = givenPrefix || '';\n            var length = l;\n            var arr = [];\n            while (length--) {\n                arr.unshift(prefix + Array(length + 1).join(' ') + length);\n            }\n            return arr;\n        };\n\n        beforeEach(function () {\n            test = a.slice(0);\n        });\n\n        it('has the right length', function () {\n            expect(Array.prototype.splice.length).toBe(2);\n        });\n\n        /* This test is disabled, because ES6 normalizes actual\n         * browser behavior, contradicting ES5.\n         */\n        xit('treats undefined deleteCount as 0', function () {\n            expect(test.splice(0).length).toBe(0);\n            expect(test.splice(0)).toEqual(test.splice(0, 0));\n        });\n\n        // ES6 introduced a proper default value\n        it('defaults deleteCount to length - start if there is only 1 argument', function () {\n            expect([0, 1, 2].splice(0).length).toBe(3);\n            expect([0, 1, 2].splice(1).length).toBe(2);\n        });\n\n        it('basic implementation test 1', function () {\n            expect(test.splice(0, 0)).toEqual([]);\n        });\n\n        it('basic implementation test 2', function () {\n            test.splice(0, 2);\n            expect(test).toEqual([b]);\n        });\n\n        it('should return right result 1', function () {\n            var array = [];\n\n            array.splice(0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20);\n            array.splice(1, 0, 'F1', 'F2', 'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9', 'F10', 'F11', 'F12', 'F13', 'F14', 'F15', 'F16', 'F17', 'F18', 'F19', 'F20', 'F21', 'F22', 'F23', 'F24', 'F25', 'F26');\n            array.splice(5, 0, 'XXX');\n\n            expect(array).toEqual([1, 'F1', 'F2', 'F3', 'F4', 'XXX', 'F5', 'F6', 'F7', 'F8', 'F9', 'F10', 'F11', 'F12', 'F13', 'F14', 'F15', 'F16', 'F17', 'F18', 'F19', 'F20', 'F21', 'F22', 'F23', 'F24', 'F25', 'F26', 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]);\n        });\n\n        it('should return right result 2', function () {\n            var array = makeArray(6);\n\n            array.splice(array.length - 1, 1, '');\n            array.splice(0, 1, 1, 2, 3, 4);\n            array.splice(0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45);\n\n            array.splice(4, 0, '99999999999999');\n\n            expect(array).toEqual([1, 2, 3, 4, '99999999999999', 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 1, 2, 3, 4, ' 1', '  2', '   3', '    4', '']);\n        });\n\n        it('should return right result 3', function () {\n            var array = [1, 2, 3];\n\n            array.splice(0, array.length);\n            array.splice(0, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);\n            array.splice(1, 1, 'F1', 'F2', 'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9', 'F10', 'F11', 'F12', 'F13', 'F14', 'F15', 'F16', 'F17', 'F18', 'F19', 'F20', 'F21', 'F22', 'F23', 'F24', 'F25', 'F26');\n            array.splice(5, 1, 'YYY', 'XXX');\n            array.splice(0, 1);\n            array.splice(0, 2);\n            array.pop();\n            array.push.apply(array, makeArray(10, '-'));\n            array.splice(array.length - 2, 10);\n            array.splice();\n            array.splice(1, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9);\n            array.splice(1, 1, 'F1', 'F2', 'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9', 'F10', 'F11', 'F12', 'F13', 'F14', 'F15', 'F16', 'F17', 'F18', 'F19', 'F20', 'F21', 'F22', 'F23', 'F24', 'F25', 'F26', 1, 23, 4, 5, 6, 7, 8);\n            array.splice(30, 10);\n            array.splice(30, 1);\n            array.splice(30, 0);\n            array.splice(2, 5, 1, 2, 3, 'P', 'LLL', 'CCC', 'YYY', 'XXX');\n            array.push(1, 2, 3, 4, 5, 6);\n            array.splice(1, 6, 1, 2, 3, 4, 5, 6, 7, 8, 9, 4, 5, 6, 7, 8, 9);\n            array.splice(3, 7);\n            array.unshift(7, 8, 9, 10, 11);\n            array.pop();\n            array.splice(5, 2);\n            array.pop();\n            array.unshift.apply(array, makeArray(8, '~'));\n            array.pop();\n            array.splice(3, 1, 'F1', 'F2', 'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9', 'F10', 'F11', 'F12', 'F13', 'F14', 'F15', 'F16', 'F17', 'F18', 'F19', 'F20', 'F21', 'F22', 'F23', 'F24', 'F25', 'F26', 1, 23, 4, 5, 6, 7, 8);\n            array.splice(4, 5, 'P', 'LLL', 'CCC', 'YYY', 'XXX');\n\n            expect(array).toEqual(['~0', '~ 1', '~  2', 'F1', 'P', 'LLL', 'CCC', 'YYY', 'XXX', 'F7', 'F8', 'F9', 'F10', 'F11', 'F12', 'F13', 'F14', 'F15', 'F16', 'F17', 'F18', 'F19', 'F20', 'F21', 'F22', 'F23', 'F24', 'F25', 'F26', 1, 23, 4, 5, 6, 7, 8, '~    4', '~     5', '~      6', '~       7', 7, 8, 9, 10, 11, 2, 4, 5, 6, 7, 8, 9, 'CCC', 'YYY', 'XXX', 'F7', 'F8', 'F9', 'F10', 'F11', 'F12', 'F13', 'F14', 'F15', 'F16', 'F17', 'F18', 'F19', 'F20', 'F21', 'F22', 'F23', 'F24', 'F25', 'F26', 1, 23, 4, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'YYY', 'XXX', 'F6', 'F7', 'F8', 'F9', 'F10', 'F11', 'F12', 'F13', 'F14', 'F15', 'F16', 'F17', 'F18', 'F19', 'F20', 'F21', 'F22', 'F23', 'F24', 'F25', 'F26', 3, 4, 5, 6, 7, 8, 9, '-0', '- 1', '-  2', '-   3', '-    4', '-     5', '-      6', '-       7', 1, 2, 3]);\n        });\n\n        it('should do nothing if method called with no arguments', function () {\n            expect(test.splice()).toEqual([]);\n            expect(test).toEqual(a);\n        });\n\n        it('should set first argument to 0 if first argument is set but undefined', function () {\n            var test2 = test.slice(0);\n            expect(test.splice(void 0, 2)).toEqual(test2.splice(0, 2));\n            expect(test).toEqual(test2);\n        });\n\n        it('should work with objects - adding 1', function () {\n            var obj = {};\n            Array.prototype.splice.call(obj, 0, 0, 1, 2, 3);\n            expect(obj.length).toBe(3);\n        });\n\n        it('should work with objects - adding 2', function () {\n            var obj = { 0: 1, length: 1 };\n            Array.prototype.splice.call(obj, 1, 0, 2, 3);\n            expect(obj.length).toBe(3);\n        });\n\n        it('should work with objects - removing', function () {\n            var obj = { 0: 1, 1: 2, 2: 3, length: 3 };\n            Array.prototype.splice.call(obj, 0, 3);\n            expect(obj.length).toBe(0);\n        });\n\n        it('should work with objects - replacing', function () {\n            var obj = { 0: 99, length: 1 };\n            Array.prototype.splice.call(obj, 0, 1, 1, 2, 3);\n            expect(obj.length).toBe(3);\n            expect(obj[0]).toBe(1);\n        });\n\n        ifHasDenseUndefinedsIt('should not break on sparse arrays in Opera', function () {\n            // test from https://github.com/wikimedia/VisualEditor/blob/d468b00311e69c2095b9da360c5745153342a5c3/src/ve.utils.js#L182-L196\n            var n = 256;\n            var arr = [];\n            arr[n] = 'a';\n            arr.splice(n + 1, 0, 'b');\n            expect(arr[n]).toBe('a');\n        });\n\n        ifHasDenseUndefinedsIt('should not break on sparse arrays in Safari 7/8', function () {\n            // test from https://github.com/wikimedia/VisualEditor/blob/d468b00311e69c2095b9da360c5745153342a5c3/src/ve.utils.js#L182-L196\n            var justFine = new Array(1e5 - 1);\n            justFine[10] = 'x';\n            var tooBig = new Array(1e5);\n            tooBig[8] = 'x';\n\n            justFine.splice(1, 1);\n            expect(8 in justFine).toBe(false);\n            expect(justFine.indexOf('x')).toBe(9);\n            tooBig.splice(1, 1);\n            expect(6 in tooBig).toBe(false);\n            expect(tooBig.indexOf('x')).toBe(7);\n        });\n    });\n\n    describe('#join()', function () {\n        it('defaults to a comma separator when none is provided', function () {\n            expect([1, 2].join()).toBe('1,2');\n        });\n\n        it('defaults to a comma separator when undefined is provided', function () {\n            expect([1, 2].join(undefined)).toBe('1,2');\n        });\n\n        it('works, extended', function () {\n            expect([].join()).toBe('');\n            expect([undefined].join()).toBe('');\n            expect([undefined, undefined].join()).toBe(',');\n            expect([null, null].join()).toBe(',');\n            expect([undefined, undefined].join('|')).toBe('|');\n            expect([null, null].join('|')).toBe('|');\n            expect([1, 2, 3].join('|')).toBe('1|2|3');\n            expect([1, 2, 3].join(null)).toBe('1null2null3');\n            expect([1, 2, 3].join({})).toBe('1[object Object]2[object Object]3');\n            expect([1, 2, 3].join('')).toBe('123');\n        });\n\n        it('is generic', function () {\n            var obj = { 0: 1, 1: 2, 2: 3, 3: 4, length: 3 };\n            expect(Array.prototype.join.call(obj, ',')).toBe('1,2,3');\n        });\n\n        it('works with a string literal', function () {\n            var str = '123';\n            expect(Array.prototype.join.call(str, ',')).toBe('1,2,3');\n        });\n\n        it('works with `arguments`', function () {\n            var args = (function () { return arguments; }(1, 2, 3));\n            expect(Array.prototype.join.call(args, ',')).toBe('1,2,3');\n        });\n    });\n\n    describe('#push()', function () {\n        it('works on arrays', function () {\n            var arr = [];\n            var result = arr.push(undefined);\n            expect(result).toBe(1);\n            expect(arr.length).toBe(1);\n            expect(Object.prototype.hasOwnProperty.call(arr, 0)).toBe(true);\n            expect(arr[0]).toBeUndefined();\n        });\n\n        it('is generic', function () {\n            var obj = {};\n            var result = Array.prototype.push.call(obj, undefined);\n            expect(result).toBe(1);\n            expect(obj.length).toBe(1);\n            expect(Object.prototype.hasOwnProperty.call(obj, 0)).toBe(true);\n            expect(obj[0]).toBeUndefined();\n        });\n    });\n\n    describe('#pop()', function () {\n        it('works on arrays', function () {\n            var arr = [1, 2, 3];\n            var result = arr.pop();\n            expect(result).toBe(3);\n            expect(arr.length).toBe(2);\n            expect(Object.prototype.hasOwnProperty.call(arr, 2)).toBe(false);\n            expect(arr[2]).toBeUndefined();\n        });\n\n        it('is generic', function () {\n            var obj = { 0: 1, 1: 2, 2: 3, length: 3 };\n            var result = Array.prototype.pop.call(obj);\n            expect(result).toBe(3);\n            expect(obj.length).toBe(2);\n            expect(Object.prototype.hasOwnProperty.call(obj, 2)).toBe(false);\n            expect(obj[2]).toBeUndefined();\n        });\n    });\n\n    describe('#slice()', function () {\n        it('works on arrays', function () {\n            var arr = [1, 2, 3, 4];\n            var result = arr.slice(1, 3);\n            expect(result).toEqual([2, 3]);\n        });\n\n        it('is generic', function () {\n            var obj = { 0: 1, 1: 2, 2: 3, 3: 4, length: 4 };\n            var result = Array.prototype.slice.call(obj, 1, 3);\n            expect(result).toEqual([2, 3]);\n        });\n\n        it('works with `arguments`', function () {\n            var obj = (function () {\n                return arguments;\n            }(1, 2, 3, 4));\n            var result = Array.prototype.slice.call(obj, 1, 3);\n            expect(result).toEqual([2, 3]);\n        });\n\n        it('boxed string access', function () {\n            var obj = '1234';\n            var result = Array.prototype.slice.call(obj, 1, 3);\n            expect(result).toEqual(['2', '3']);\n        });\n\n        if (typeof document !== 'undefined') {\n            it('should be able to slice a NodeList', function () {\n                var nodes = document.getElementsByTagName('div');\n                expect(Array.isArray(Array.prototype.slice.call(nodes))).toBe(true);\n            });\n        }\n    });\n\n    describe('#sort()', function () {\n        describe('usage', function () {\n            it('requires a function or undefined as first argument', function () {\n                var actual = [1, 2];\n                expect(actual.sort()).toBe(actual);\n                expect(actual.sort(undefined)).toBe(actual);\n                expect(actual.sort(function () { return 0; })).toBe(actual);\n            });\n\n            it('requires a non-function or non-undefined to throw a `TypeError`', function () {\n                expect(function () { [1, 2].sort(null); }).toThrow();\n                expect(function () { [1, 2].sort(1); }).toThrow();\n                expect(function () { [1, 2].sort(''); }).toThrow();\n                expect(function () { [1, 2].sort(true); }).toThrow();\n                expect(function () { [1, 2].sort({}); }).toThrow();\n                expect(function () { [1, 2].sort([]); }).toThrow();\n                expect(function () { [1, 2].sort(new Date()); }).toThrow();\n                expect(function () { [1, 2].sort(/pattern/); }).toThrow();\n            });\n        });\n\n        describe('ascending', function () {\n            it('[5,2,4,6,1,3] should result in [1,2,3,4,5,6]', function () {\n                var actual = [5, 2, 4, 6, 1, 3];\n                var expected = [1, 2, 3, 4, 5, 6];\n                actual.sort();\n                expect(actual).toEqual(expected);\n            });\n\n            it('[5,2,2,6,1,3] should result in [1,2,2,3,5,6]', function () {\n                var actual = [5, 2, 2, 6, 1, 3];\n                var expected = [1, 2, 2, 3, 5, 6];\n                actual.sort();\n                expect(actual).toEqual(expected);\n            });\n\n            it('[0,0,0,0,0,1] should result in [0,0,0,0,0,1]', function () {\n                var actual = [0, 0, 0, 0, 0, 1];\n                var expected = [0, 0, 0, 0, 0, 1];\n                actual.sort();\n                expect(actual).toEqual(expected);\n            });\n\n            it('[0,0,0,0,0,-1] should result in [-1,0,0,0,0,0]', function () {\n                var actual = [0, 0, 0, 0, 0, -1];\n                var expected = [-1, 0, 0, 0, 0, 0];\n                actual.sort();\n                expect(actual).toEqual(expected);\n            });\n\n            it('[f,e,d,a,c,b] should result in [a,b,c,d,e,f]', function () {\n                var actual = ['f', 'e', 'd', 'a', 'c', 'b'];\n                var expected = ['a', 'b', 'c', 'd', 'e', 'f'];\n                actual.sort();\n                expect(actual).toEqual(expected);\n            });\n\n            it('[f,e,d,,,,a,c,b] should result in [a,b,c,d,e,f,,,]', function () {\n                var actual = ['f', 'e', 'd', 1, 2, 'a', 'c', 'b'];\n                delete actual[3];\n                delete actual[4];\n                var expected = ['a', 'b', 'c', 'd', 'e', 'f'];\n                expected.length = 8;\n                actual.sort();\n                expect(actual).toEqual(expected);\n            });\n\n            it('[f,e,d,,null,,a,c,b] should result in [a,b,c,d,e,f,null,,,]', function () {\n                var actual = ['f', 'e', 'd', 1, null, 2, 'a', 'c', 'b'];\n                delete actual[3];\n                delete actual[5];\n                var expected = ['a', 'b', 'c', 'd', 'e', 'f', null];\n                expected.length = 9;\n                actual.sort();\n                expect(actual).toEqual(expected);\n            });\n\n            it('[f,e,d,,null,undefined,a,c,b] should result in [a,b,c,d,e,f,null,undefined,,]', function () {\n                var actual = ['f', 'e', 'd', 1, null, undefined, 'a', 'c', 'b'];\n                delete actual[3];\n                var expected = ['a', 'b', 'c', 'd', 'e', 'f', null, undefined];\n                expected.length = 9;\n                actual.sort();\n                expect(actual).toEqual(expected);\n            });\n\n            it('[] should result in []', function () {\n                var actual = [];\n                var expected = [];\n                actual.sort();\n                expect(actual).toEqual(expected);\n            });\n\n            it('[1] should result in [1]', function () {\n                var actual = [1];\n                var expected = [1];\n                actual.sort();\n                expect(actual).toEqual(expected);\n            });\n\n            it('result should find only greater or equal values', function () {\n                var actual = [];\n                var i;\n                for (i = 0; i < 100; i += 1) {\n                    actual.push(('00' + (Math.random() * 100).toFixed(0)).slice(-3));\n                }\n                actual.sort();\n                for (i = 0; i < actual.length - 1; i += 1) {\n                    expect(actual[i] <= actual[i + 1]).toBe(true);\n                }\n            });\n        });\n\n        describe('descending', function () {\n            var descending = function (left, right) {\n                var leftS = String(left);\n                var rightS = String(right);\n                if (leftS === rightS) {\n                    return +0;\n                }\n                if (leftS < rightS) {\n                    return 1;\n                }\n                return -1;\n            };\n\n            it('[5,2,4,6,1,3] should result in [6,5,4,3,2,1]', function () {\n                var actual = [5, 2, 4, 6, 1, 3];\n                var expected = [6, 5, 4, 3, 2, 1];\n                actual.sort(descending);\n                expect(actual).toEqual(expected);\n            });\n\n            it('[5,2,2,6,1,3] should result in [6,5,4,2,2,1]', function () {\n                var actual = [5, 2, 2, 6, 1, 3];\n                var expected = [6, 5, 3, 2, 2, 1];\n                actual.sort(descending);\n                expect(actual).toEqual(expected);\n            });\n\n            it('[0,0,0,0,0,1] should result in [1,0,0,0,0,0]', function () {\n                var actual = [0, 0, 0, 0, 0, 1];\n                var expected = [1, 0, 0, 0, 0, 0];\n                actual.sort(descending);\n                expect(actual).toEqual(expected);\n            });\n\n            it('[0,0,0,0,0,-1] should result in [0,0,0,0,0,-1]', function () {\n                var actual = [0, 0, 0, 0, 0, -1];\n                var expected = [0, 0, 0, 0, 0, -1];\n                actual.sort(descending);\n                expect(actual).toEqual(expected);\n            });\n\n            it('[f,e,d,a,c,b] should result in [f,e,d,c,b,a]', function () {\n                var actual = ['f', 'e', 'd', 'a', 'c', 'b'];\n                var expected = ['f', 'e', 'd', 'c', 'b', 'a'];\n                actual.sort(descending);\n                expect(actual).toEqual(expected);\n            });\n\n            it('[f,e,d,,,a,c,b] should result in [f,e,d,c,b,a,,,]', function () {\n                var actual = ['f', 'e', 'd', 1, 2, 'a', 'c', 'b'];\n                delete actual[3];\n                delete actual[4];\n                var expected = ['f', 'e', 'd', 'c', 'b', 'a'];\n                expected.length = 8;\n                actual.sort(descending);\n                expect(actual).toEqual(expected);\n            });\n\n            it('[f,e,d,,null,,a,c,b] should result in [null,f,e,d,c,b,a,,,]', function () {\n                var actual = ['f', 'e', 'd', 1, null, 2, 'a', 'c', 'b'];\n                delete actual[3];\n                delete actual[5];\n                var expected = [null, 'f', 'e', 'd', 'c', 'b', 'a'];\n                expected.length = 9;\n                actual.sort(descending);\n                expect(actual).toEqual(expected);\n            });\n\n            it('[f,e,d,undefined,null,,a,c,b] should result in [null,f,e,d,c,b,a,undefined,,]', function () {\n                var actual = ['f', 'e', 'd', undefined, null, 2, 'a', 'c', 'b'];\n                delete actual[5];\n                var expected = [null, 'f', 'e', 'd', 'c', 'b', 'a', undefined];\n                expected.length = 9;\n                actual.sort(descending);\n                expect(actual).toEqual(expected);\n            });\n\n            it('[] should result in []', function () {\n                var actual = [];\n                var expected = [];\n                actual.sort(descending);\n                expect(actual).toEqual(expected);\n            });\n\n            it('[1] should result in [1]', function () {\n                var actual = [1];\n                var expected = [1];\n                actual.sort(descending);\n                expect(actual).toEqual(expected);\n            });\n\n            it('result should find only lesser or equal values', function () {\n                var actual = [];\n                var i;\n                for (i = 0; i < 100; i += 1) {\n                    actual.push(('00' + (Math.random() * 100).toFixed(0)).slice(-3));\n                }\n                actual.sort(descending);\n                for (i = 0; i < actual.length - 1; i += 1) {\n                    expect(actual[i] >= actual[i + 1]).toBe(true);\n                }\n            });\n        });\n\n        describe('returned value', function () {\n            it('should be the source object', function () {\n                var actual = [1, 3, 2];\n                expect(actual.sort()).toBe(actual);\n            });\n        });\n\n        describe('when used generically', function () {\n            var descending = function (left, right) {\n                var leftS = String(left);\n                var rightS = String(right);\n                if (leftS === rightS) {\n                    return +0;\n                }\n                if (leftS < rightS) {\n                    return 1;\n                }\n                return -1;\n            };\n\n            var args = function () {\n                return arguments;\n            };\n\n            it('should not sort objects without length', function () {\n                var actual = {\n                    0: 5,\n                    1: 2,\n                    2: 4,\n                    3: 6,\n                    4: 1,\n                    5: 3\n                };\n                var expected = {\n                    0: 5,\n                    1: 2,\n                    2: 4,\n                    3: 6,\n                    4: 1,\n                    5: 3\n                };\n                Array.prototype.sort.call(actual);\n                expect(actual).toEqual(expected);\n                Array.prototype.sort.call(actual, descending);\n                expect(actual).toEqual(expected);\n            });\n\n            it('should sort objects ascending with length', function () {\n                var actual = {\n                    0: 5,\n                    1: 2,\n                    2: 4,\n                    3: 6,\n                    4: 1,\n                    5: 3,\n                    length: 6\n                };\n                var expected = {\n                    0: 1,\n                    1: 2,\n                    2: 3,\n                    3: 4,\n                    4: 5,\n                    5: 6,\n                    length: 6\n                };\n                Array.prototype.sort.call(actual);\n                expect(actual).toEqual(expected);\n            });\n\n            it('should sort objects descending with length', function () {\n                var actual = {\n                    0: 5,\n                    1: 2,\n                    2: 4,\n                    3: 6,\n                    4: 1,\n                    5: 3,\n                    length: 6\n                };\n                var expected = {\n                    0: 6,\n                    1: 5,\n                    2: 4,\n                    3: 3,\n                    4: 2,\n                    5: 1,\n                    length: 6\n                };\n                Array.prototype.sort.call(actual, descending);\n                expect(actual).toEqual(expected);\n            });\n\n            it('should sort objects descending with mixed content types and with length', function () {\n                var actual = {\n                    0: 5,\n                    1: 2,\n                    2: 4,\n                    4: null,\n                    6: 1,\n                    7: 3,\n                    length: 8\n                };\n                var expected = {\n                    0: null,\n                    1: 5,\n                    2: 4,\n                    3: 3,\n                    4: 2,\n                    5: 1,\n                    length: 8\n                };\n                Array.prototype.sort.call(actual, descending);\n                expect(actual).toEqual(expected);\n            });\n\n            it('should sort `arguments` object ascending', function () {\n                var actual = args(5, 2, 4, 6, 1, 3);\n                var expected = args(1, 2, 3, 4, 5, 6);\n                Array.prototype.sort.call(actual);\n                expect(actual).toEqual(expected);\n            });\n\n            it('should sort `arguments` object ascending with mixed content types', function () {\n                var actual = args(5, 2, 4, null, 1, 3);\n                var expected = args(1, 2, 3, 4, 5, null);\n                Array.prototype.sort.call(actual);\n                expect(actual).toEqual(expected);\n            });\n\n            it('should sort `arguments` object descending', function () {\n                var actual = args(5, 2, 4, 6, 1, 3);\n                var expected = args(6, 5, 4, 3, 2, 1);\n                Array.prototype.sort.call(actual, descending);\n                expect(actual).toEqual(expected);\n            });\n\n            it('should sort `arguments` object descending with mixed content types', function () {\n                var actual = args(5, 2, 4, null, 1, 3);\n                var expected = args(null, 5, 4, 3, 2, 1);\n                Array.prototype.sort.call(actual, descending);\n                expect(actual).toEqual(expected);\n            });\n        });\n    });\n});\n"
  },
  {
    "path": "tests/spec/s-date.js",
    "content": "describe('Date', function () {\n    'use strict';\n\n    var supportsDescriptors = Object.defineProperty && (function () {\n        try {\n            var obj = {};\n            Object.defineProperty(obj, 'x', {\n                enumerable: false,\n                value: obj\n            });\n            // eslint-disable-next-line no-unreachable-loop\n            for (var _ in obj) { return false; } // jscs:ignore disallowUnusedVariables\n            return obj.x === obj;\n        } catch (e) { /* this is ES3 */\n            return false;\n        }\n    }());\n    var ifSupportsDescriptorsIt = supportsDescriptors ? it : xit;\n    var has = Object.prototype.hasOwnProperty;\n\n    var negativeDate;\n    beforeEach(function () {\n        var negativeCanned = [\n            {\n                getTime: -3509827329600292,\n                getUTCDay: 4,\n                getDay: 4,\n                dim: 31\n            },\n            {\n                getTime: -3509824651200292,\n                getUTCDay: 0,\n                getDay: 0,\n                dim: 29\n            },\n            {\n                getTime: -3509822145600292,\n                getUTCDay: 1,\n                getDay: 1,\n                dim: 31\n            },\n            {\n                getTime: -3509819467200292,\n                getUTCDay: 4,\n                getDay: 4,\n                dim: 30\n            },\n            {\n                getTime: -3509816875200292,\n                getUTCDay: 6,\n                getDay: 6,\n                dim: 31\n            },\n            {\n                getTime: -3509814196800292,\n                getUTCDay: 2,\n                getDay: 2,\n                dim: 30\n            },\n            {\n                getTime: -3509811604800292,\n                getUTCDay: 4,\n                getDay: 4,\n                dim: 31\n            },\n            {\n                getTime: -3509808926400292,\n                getUTCDay: 0,\n                getDay: 0,\n                dim: 31\n            },\n            {\n                getTime: -3509806248000292,\n                getUTCDay: 3,\n                getDay: 3,\n                dim: 30\n            },\n            {\n                getTime: -3509803656000292,\n                getUTCDay: 5,\n                getDay: 5,\n                dim: 31\n            },\n            {\n                getTime: -3509800977600292,\n                getUTCDay: 1,\n                getDay: 1,\n                dim: 30\n            },\n            {\n                getTime: -3509798385600292,\n                getUTCDay: 3,\n                getDay: 3,\n                dim: 31\n            }\n        ];\n        negativeDate = negativeCanned.map(function (item) {\n            var dateFirst = new Date(item.getTime);\n            var dateLast = new Date(item.getTime + ((item.dim - 1) * 86400000));\n            return {\n                dates: [dateFirst, dateLast],\n                days: [1, item.dim],\n                getUTCDay: [item.getUTCDay, (item.getUTCDay + item.dim - 1) % 7],\n                getDay: [item.getDay, (item.getDay + item.dim - 1) % 7]\n            };\n        });\n    });\n\n    describe('.now()', function () {\n        it('should be the current time', function () {\n            var before = (new Date()).getTime();\n            var middle = Date.now();\n            var after = (new Date()).getTime();\n            expect(middle).not.toBeLessThan(before);\n            expect(middle).not.toBeGreaterThan(after);\n        });\n    });\n\n    describe('constructor', function () {\n        it('works with standard formats', function () {\n            //    Chrome 19     Opera 12      Firefox 11    IE 9          Safari 5.1.1\n            expect(+new Date('2012-12-31T23:59:59.000Z')).toBe(1356998399000); //    1356998399000 1356998399000 1356998399000 1356998399000 1356998399000\n            expect(+new Date('2012-04-04T05:02:02.170Z')).toBe(1333515722170); //    1333515722170 1333515722170 1333515722170 1333515722170 1333515722170\n            expect(+new Date('2012-04-04T05:02:02.170999Z')).toBe(1333515722170); // 1333515722170 1333515722170 1333515722170 1333515722170 1333515722170\n            expect(+new Date('2012-04-04T05:02:02.17Z')).toBe(1333515722170); //     1333515722170 1333515722170 1333515722170 1333515722170 1333515722170\n            expect(+new Date('2012-04-04T05:02:02.1Z')).toBe(1333515722100); //      1333515722170 1333515722170 1333515722170 1333515722170 1333515722170\n            expect(+new Date('2012-04-04T24:00:00.000Z')).toBe(1333584000000); //    NaN           1333584000000 1333584000000 1333584000000 1333584000000\n            expect(+new Date('2012-02-29T12:00:00.000Z')).toBe(1330516800000); //    1330516800000 1330516800000 1330516800000 1330516800000 1330516800000\n            expect(+new Date('2011-03-01T12:00:00.000Z')).toBe(1298980800000); //    1298980800000 1298980800000 1298980800000 1298980800000 1298980800000\n\n            // https://github.com/es-shims/es5-shim/issues/80 Safari bug with leap day\n            expect(new Date('2034-03-01T00:00:00.000Z')\n                - new Date('2034-02-27T23:59:59.999Z')).toBe(86400001); //           86400001      86400001      86400001      86400001             1\n\n        });\n\n        ifSupportsDescriptorsIt('is not enumerable', function () {\n            expect(Object.keys(new Date())).not.toContain('constructor');\n        });\n\n        it('works as a function', function () {\n            var zeroDate = Date(0);\n            expect(zeroDate).toBe(String(zeroDate));\n            var value = Date(1441705534578);\n            expect(value).toBe(String(value));\n        });\n\n        it('fixes this Safari 8/9 bug', function () {\n            var offset = new Date(1970).getTimezoneOffset() * 60e3;\n\n            var timestamp = 2147483647; // Math.pow(2, 31) - 1\n            var date = new Date(1970, 0, 1, 0, 0, 0, timestamp);\n            var expectedTimestamp = timestamp + offset;\n            expect(date.getTime()).toBe(expectedTimestamp);\n\n            var brokenTimestamp = 2147483648; // Math.pow(2, 31)\n            var brokenDate = new Date(1970, 0, 1, 0, 0, 0, brokenTimestamp);\n            var expectedBrokenTimestamp = brokenTimestamp + offset;\n            expect(brokenDate.getTime()).toBe(expectedBrokenTimestamp); // NaN in Safari 8/9\n\n            var veryBrokenTS = 1435734000000;\n            var veryBrokenDate = new Date(1970, 0, 1, 0, 0, 0, veryBrokenTS);\n            var largeDate = new Date('Wed Jul 01 2015 07:00:00 GMT-0700 (PDT)');\n            var expectedVeryBrokenTS = veryBrokenTS + (largeDate.getTimezoneOffset() * 60e3);\n            expect(veryBrokenDate.getTime()).toBe(expectedVeryBrokenTS); // NaN in Safari 8/9\n        });\n\n        it('works with a Date object', function () {\n            var date = new Date(1456297712984);\n            var copiedDate = new Date(date);\n            expect(date).not.toBe(copiedDate);\n            expect(copiedDate.getTime()).toBe(date.getTime());\n            expect(+copiedDate).toBe(+date);\n            expect(String(copiedDate)).toBe(String(date));\n        });\n    });\n\n    describe('.parse()', function () {\n        // TODO: Write the rest of the test.\n\n        ifSupportsDescriptorsIt('is not enumerable', function () {\n            expect(Object.getOwnPropertyDescriptor(Date, 'parse').enumerable).toBe(false);\n        });\n\n        it('should be an invalid date', function () {\n            //            Chrome 19     Opera 12      Firefox 11    IE 9          Safari 5.1.1\n            expect(Date.parse('2012-11-31T23:59:59.000Z')).toBeFalsy(); //            1354406399000 NaN           NaN           1354406399000 NaN\n            expect(Date.parse('2012-12-31T23:59:60.000Z')).toBeFalsy(); //            NaN           NaN           NaN           NaN           1356998400000\n            expect(Date.parse('2012-04-04T24:00:00.500Z')).toBeFalsy(); //            NaN           NaN           1333584000500 1333584000500 NaN\n            expect(Date.parse('2012-12-31T10:08:60.000Z')).toBeFalsy(); //            NaN           NaN           NaN           NaN           1356948540000\n            expect(Date.parse('2012-13-01T12:00:00.000Z')).toBeFalsy(); //            NaN           NaN           NaN           NaN           NaN\n            expect(Date.parse('2012-12-32T12:00:00.000Z')).toBeFalsy(); //            NaN           NaN           NaN           NaN           NaN\n            expect(Date.parse('2012-12-31T25:00:00.000Z')).toBeFalsy(); //            NaN           NaN           NaN           NaN           NaN\n            expect(Date.parse('2012-12-31T24:01:00.000Z')).toBeFalsy(); //            NaN           NaN           NaN           1356998460000 NaN\n            expect(Date.parse('2012-12-31T12:60:00.000Z')).toBeFalsy(); //            NaN           NaN           NaN           NaN           NaN\n            expect(Date.parse('2012-12-31T12:00:60.000Z')).toBeFalsy(); //            NaN           NaN           NaN           NaN           1356955260000\n            expect(Date.parse('2012-00-31T23:59:59.000Z')).toBeFalsy(); //            NaN           NaN           NaN           NaN           NaN\n            expect(Date.parse('2012-12-00T23:59:59.000Z')).toBeFalsy(); //            NaN           NaN           NaN           NaN           NaN\n            expect(Date.parse('2011-02-29T12:00:00.000Z')).toBeFalsy(); //            1298980800000 NaN           NaN           1298980800000 NaN\n        });\n\n        it('should work', function () {\n            var dates = {\n                //    Chrome 19     Opera 12      Firefox 11    IE 9          Safari 5.1.1  Safari 8\n                '2012-12-31T23:59:59.000Z': 1356998399000, //    1356998399000 1356998399000 1356998399000 1356998399000 1356998399000 1356998399000\n                '2012-04-04T05:02:02.170Z': 1333515722170, //    1333515722170 1333515722170 1333515722170 1333515722170 1333515722170 1333515722170\n                '2012-04-04T05:02:02.170999Z': 1333515722170, // 1333515722170 1333515722170 1333515722170 1333515722170 1333515722170 1333515722170.999\n                '2012-04-04T05:02:02.17Z': 1333515722170, //     1333515722170 1333515722170 1333515722170 1333515722170 1333515722170 1333515722170\n                '2012-04-04T05:02:02.1Z': 1333515722100, //      1333515722170 1333515722170 1333515722170 1333515722170 1333515722170 1333515722170\n                '2012-04-04T24:00:00.000Z': 1333584000000, //    NaN           1333584000000 1333584000000 1333584000000 1333584000000 1333584000000\n                '2012-02-29T12:00:00.000Z': 1330516800000, //    1330516800000 1330516800000 1330516800000 1330516800000 1330516800000 1330516800000\n                '2011-03-01T12:00:00.000Z': 1298980800000 //     1298980800000 1298980800000 1298980800000 1298980800000 1298980800000 1298980800000\n            };\n            for (var str in dates) {\n                if (has.call(dates, str)) {\n                    expect(Math.floor(Date.parse(str))).toBe(dates[str]);\n                }\n            }\n\n            // https://github.com/es-shims/es5-shim/issues/80 Safari bug with leap day\n            expect(Date.parse('2034-03-01T00:00:00.000Z')\n                - Date.parse('2034-02-27T23:59:59.999Z')).toBe(86400001); //       86400001      86400001      86400001      86400001             1\n\n        });\n\n        it('fixes a Safari 8/9 bug with parsing in UTC instead of local time', function () {\n            var offset = new Date('2015-07-01').getTimezoneOffset() * 60e3;\n            expect(Date.parse('2015-07-01T00:00:00')).toBe(1435708800000 + offset); // Safari 8/9 give NaN\n        });\n\n        it('should support extended years', function () {\n            //    Chrome 19     Opera 12      Firefox 11    IE 9          Safari 5.1.1\n            expect(Date.parse('0000-01-01T00:00:00.000Z')).toBe(-621672192e5); //   -621672192e5  -621672192e5  -621672192e5  -621672192e5  -621672192e5\n            expect(Date.parse('0001-01-01T00:00:00Z')).toBe(-621355968e5); //       -621355968e5  -621355968e5  -621355968e5   8.64e15      -621355968e5\n            expect(Date.parse('+275760-09-13T00:00:00.000Z')).toBe(8.64e15); //      8.64e15       NaN           8.64e15       8.64e15       8.64e15\n            expect(Date.parse('-271821-04-20T00:00:00.000Z')).toBe(-8.64e15); //    -8.64e15       NaN          -8.64e15      -8.64e15      -8.6400000864e15\n            expect(Date.parse('+275760-09-13T00:00:00.001Z')).toBeFalsy(); //        NaN           NaN           NaN           8.64e15 + 1   8.64e15 + 1\n            expect(Date.parse('-271821-04-19T23:59:59.999Z')).toBeFalsy(); //        NaN           NaN           NaN          -8.64e15 - 1  -8.6400000864e15 - 1\n            expect(Date.parse('+033658-09-27T01:46:40.000Z')).toBe(1e15); //         1e15          NaN           1e15          1e15          9999999136e5\n            expect(Date.parse('-000001-01-01T00:00:00Z')).toBe(-621987552e5); //    -621987552e5   NaN          -621987552e5  -621987552e5  -621987552e5\n            expect(Date.parse('+002009-12-15T00:00:00Z')).toBe(12608352e5); //       12608352e5    NaN           12608352e5    12608352e5    12608352e5\n        });\n\n        it('works with timezone offsets', function () {\n            //  Chrome 19   Opera 12     Firefox 11   IE 9             Safari 5.1.1\n            expect(Date.parse('2012-01-29T12:00:00.000+01:00')).toBe(132783480e4); //  132783480e4 132783480e4  132783480e4  132783480e4      132783480e4\n            expect(Date.parse('2012-01-29T12:00:00.000-00:00')).toBe(132783840e4); //  132783840e4 132783840e4  132783840e4  132783840e4      132783840e4\n            expect(Date.parse('2012-01-29T12:00:00.000+00:00')).toBe(132783840e4); //  132783840e4 132783840e4  132783840e4  132783840e4      132783840e4\n            expect(Date.parse('2012-01-29T12:00:00.000+23:59')).toBe(132775206e4); //  132775206e4 132775206e4  132775206e4  132775206e4      132775206e4\n            expect(Date.parse('2012-01-29T12:00:00.000-23:59')).toBe(132792474e4); //  132792474e4 132792474e4  132792474e4  132792474e4      132792474e4\n            expect(Date.parse('2012-01-29T12:00:00.000+24:00')).toBeFalsy(); //        NaN         1327752e6    NaN          1327752000000    1327752000000\n            expect(Date.parse('2012-01-29T12:00:00.000+24:01')).toBeFalsy(); //        NaN         NaN          NaN          1327751940000    1327751940000\n            expect(Date.parse('2012-01-29T12:00:00.000+24:59')).toBeFalsy(); //        NaN         NaN          NaN          1327748460000    1327748460000\n            expect(Date.parse('2012-01-29T12:00:00.000+25:00')).toBeFalsy(); //        NaN         NaN          NaN          NaN              NaN\n            expect(Date.parse('2012-01-29T12:00:00.000+00:60')).toBeFalsy(); //        NaN         NaN          NaN          NaN              NaN\n            expect(Date.parse('-271821-04-20T00:00:00.000+00:01')).toBeFalsy(); //     NaN         NaN          NaN         -864000000006e4 -864000008646e4\n            expect(Date.parse('-271821-04-20T00:01:00.000+00:01')).toBe(-8.64e15); // -8.64e15     NaN         -8.64e15     -8.64e15        -864000008640e4\n\n            // When time zone is missed, local offset should be used (ES 5.1 bug)\n            // see https://bugs.ecmascript.org/show_bug.cgi?id=112\n            var tzOffset = Number(new Date(1970, 0));\n            // same as (new Date().getTimezoneOffset() * 60000)\n            expect(Date.parse('1970-01-01T00:00:00')).toBe(tzOffset); //              tzOffset    0            0            0               NaN\n        });\n\n        it('should be able to coerce to a number', function () {\n            var actual = Number(new Date(1970, 0));\n            var expected = parseInt(actual, 10);\n            expect(actual).toBeDefined();\n            expect(actual).toBe(expected);\n            expect(isNaN(actual)).toBeFalsy();\n        });\n\n        it('matches web reality', function () {\n            var actual = Number(new Date('1900-01-01T00:00:00.000'));\n            var upperBound = -2208988800000; // safari 6.2 - 13.1\n            var expected = -2208960000000;\n\n            expect(actual).toBeDefined();\n            expect(actual).toBeGreaterThan(upperBound - 1);\n            expect(actual).toBeLessThan(expected + 1);\n            // expect(actual).toBe(expected); // TODO: figure out if `upperBound` is a bug or just a difference\n            expect(isNaN(actual)).toBeFalsy();\n        });\n    });\n\n    describe('#toString()', function () {\n        var actual;\n\n        beforeEach(function () {\n            actual = (new Date(1970, 0)).toString();\n        });\n\n        it('should show correct date info for ' + actual, function () {\n            expect(actual).toMatch(/1970/);\n            expect(actual).toMatch(/jan/i);\n            expect(actual).toMatch(/thu/i);\n            expect(actual).toMatch(/00:00:00/);\n        });\n    });\n\n    describe('#valueOf()', function () {\n        // Note that new Date(1970, 0).valueOf() is 0 in UTC timezone.\n        // Check check that it's a number (and an int), not that it's \"truthy\".\n        var actual;\n\n        beforeEach(function () {\n            actual = (new Date(1970, 0)).valueOf();\n        });\n        it('should give a numeric value', function () {\n            expect(typeof actual).toBe('number');\n        });\n        it('should not be NaN', function () {\n            expect(isNaN(actual)).toBe(false);\n        });\n        it('should give an int value', function () {\n            expect(actual).toBe(Math.floor(actual));\n        });\n    });\n\n    describe('#getUTCDate()', function () {\n        it('should return the right value for negative dates', function () {\n            // Opera 10.6/11.61/Opera 12 bug\n            negativeDate.forEach(function (item) {\n                item.dates.forEach(function (date, index) {\n                    expect(date.getUTCDate()).toBe(item.days[index], date);\n                });\n            });\n        });\n    });\n\n    describe('#getUTCDay()', function () {\n        it('should return the right value for negative dates', function () {\n            negativeDate.forEach(function (item) {\n                item.dates.forEach(function (date, index) {\n                    expect(date.getUTCDay()).toBe(item.getUTCDay[index]);\n                });\n            });\n        });\n    });\n\n    describe('#getUTCFullYear()', function () {\n        it('should return the right value for negative dates', function () {\n            // Opera 10.6/11.61/Opera 12 bug\n            negativeDate.forEach(function (item) {\n                item.dates.forEach(function (date) {\n                    expect(date.getUTCFullYear()).toBe(-109252);\n                });\n            });\n        });\n    });\n\n    describe('#getUTCMonth()', function () {\n        it('should return the right value for negative dates', function () {\n            // Opera 10.6/11.61/Opera 12 bug\n            negativeDate.forEach(function (item, index) {\n                item.dates.forEach(function (date) {\n                    expect(date.getUTCMonth()).toBe(index);\n                });\n            });\n        });\n\n        it('should return correct values', function () {\n            expect(new Date(8.64e15).getUTCMonth()).toBe(8);\n            expect(new Date(0).getUTCMonth()).toBe(0);\n        });\n    });\n\n    describe('#getUTCHours()', function () {\n        it('should return the right value for negative dates', function () {\n            negativeDate.forEach(function (item) {\n                item.dates.forEach(function (date) {\n                    expect(date.getUTCHours()).toBe(11);\n                });\n            });\n        });\n    });\n\n    describe('#getUTCMinutes()', function () {\n        it('should return the right value for negative dates', function () {\n            negativeDate.forEach(function (item) {\n                item.dates.forEach(function (date) {\n                    expect(date.getUTCMinutes()).toBe(59);\n                });\n            });\n        });\n    });\n\n    describe('#getUTCSeconds()', function () {\n        it('should return the right value for negative dates', function () {\n            negativeDate.forEach(function (item) {\n                item.dates.forEach(function (date) {\n                    expect(date.getUTCSeconds()).toBe(59);\n                });\n            });\n        });\n    });\n\n    describe('#getUTCMilliseconds()', function () {\n        it('should return the right value for negative dates', function () {\n            // Opera 10.6/11.61/Opera 12 bug\n            negativeDate.forEach(function (item) {\n                item.dates.forEach(function (date) {\n                    expect(date.getUTCMilliseconds()).toBe(708);\n                });\n            });\n        });\n    });\n\n    describe('#getDate()', function () {\n        it('should return the right value for negative dates', function () {\n            negativeDate.forEach(function (item) {\n                item.dates.forEach(function (date, index) {\n                    expect(date.getDate()).toBe(item.days[index]);\n                });\n            });\n        });\n    });\n\n    describe('#getDay()', function () {\n        it('should return the right value for negative dates', function () {\n            negativeDate.forEach(function (item) {\n                item.dates.forEach(function (date, index) {\n                    expect(date.getDay()).toBe(item.getDay[index]);\n                });\n            });\n        });\n    });\n\n    describe('#getFullYear()', function () {\n        it('should return the right value for negative dates', function () {\n            // Opera 10.6/11.61/Opera 12 bug\n            negativeDate.forEach(function (item) {\n                item.dates.forEach(function (date) {\n                    expect(date.getFullYear()).toBe(-109252);\n                });\n            });\n        });\n    });\n\n    describe('#getMonth()', function () {\n        it('should return the right value for negative dates', function () {\n            // Opera 10.6/11.61/Opera 12 bug\n            negativeDate.forEach(function (item, index) {\n                item.dates.forEach(function (date) {\n                    expect(date.getMonth()).toBe(index);\n                });\n            });\n        });\n    });\n\n    describe('#getHours()', function () {\n        it('should return the right value for negative dates', function () {\n            negativeDate.forEach(function (item) {\n                item.dates.forEach(function (date) {\n                    expect(date.getHours() + Math.floor(date.getTimezoneOffset() / 60)).toBe(11);\n                });\n            });\n        });\n    });\n\n    describe('#getMinutes()', function () {\n        it('should return the right value for negative dates', function () {\n            negativeDate.forEach(function (item) {\n                item.dates.forEach(function (date) {\n                    var off = date.getTimezoneOffset();\n                    var offHours = Math.floor(off / 60);\n                    var offMins = off - (offHours * 60);\n                    var result = date.getMinutes() + offMins;\n                    // ceil/floor is for Firefox\n                    expect(result < 0 ? Math.ceil(result) : Math.floor(result)).toBe(59);\n                });\n            });\n        });\n    });\n\n    describe('#getSeconds()', function () {\n        it('should return the right value for negative dates', function () {\n            negativeDate.forEach(function (item) {\n                item.dates.forEach(function (date, i) {\n                    // the regex here is because in UTC, it's 59, but with TZData applied,\n                    // which can have fractional hour offsets, it'll be 1.\n                    expect(i + ':' + date.getSeconds()).toMatch(new RegExp(i + ':(?:' + 59 + '|' + 1 + ')'));\n                });\n            });\n        });\n    });\n\n    describe('#getMilliseconds()', function () {\n        it('should return the right value for negative dates', function () {\n            // Opera 10.6/11.61/Opera 12 bug\n            negativeDate.forEach(function (item) {\n                item.dates.forEach(function (date) {\n                    expect(date.getMilliseconds()).toBe(708);\n                });\n            });\n        });\n    });\n\n    describe('#toISOString()', function () {\n        // TODO: write the rest of the test.\n\n        it('should support extended years', function () {\n            expect(new Date(-62198755200000).toISOString().indexOf('-000001-01-01')).toBe(0);\n            expect(new Date(8.64e15).toISOString().indexOf('+275760-09-13')).toBe(0);\n        });\n\n        it('should return correct dates', function () {\n            expect(new Date(-1).toISOString()).toBe('1969-12-31T23:59:59.999Z'); // Safari 5.1.5 \"1969-12-31T23:59:59.-01Z\"\n            negativeDate.forEach(function (item, index) {\n                var m = index + 1;\n                item.dates.forEach(function (date, idx) {\n                    var d = item.days[idx];\n                    expect(date.toISOString()).toBe('-109252-' + (m < 10 ? '0' + m : m) + '-' + (d < 10 ? '0' + d : d) + 'T11:59:59.708Z'); // Opera 11.61/Opera 12 bug with Date#getUTCMonth\n                });\n            });\n        });\n\n    });\n\n    describe('#toUTCString()', function () {\n        it('should return correct dates', function () {\n            expect(new Date(-1509842289600292).toUTCString()).toBe('Mon, 01 Jan -45875 11:59:59 GMT');\n        });\n    });\n\n    describe('#toDateString()', function () {\n        it('should return correct dates', function () {\n            expect(new Date(-1509842289600292).toDateString()).toBe('Mon Jan 01 -45875');\n        });\n    });\n\n    describe('#toString()', function () {\n        it('should return correct dates', function () {\n            var actual = new Date(1449662400000).toString();\n            var re = /^Wed Dec 09 2015 \\d\\d:\\d\\d:\\d\\d GMT[-+]\\d\\d\\d\\d(?: |$)/;\n            expect(re.test(actual)).toBe(true, actual);\n        });\n    });\n\n    describe('#toJSON()', function () {\n\n        // Opera 11.6x/12 bug\n        it('should call toISOString', function () {\n            var date = new Date(0);\n            date.toISOString = function () {\n                return 1;\n            };\n            expect(date.toJSON()).toBe(1);\n        });\n\n        it('should return null for not finite dates', function () {\n            var date = new Date(NaN),\n                json;\n            try {\n                json = date.toJSON();\n            } catch (e) {\n                /* invalid json */\n                expect(e).not.toEqual(jasmine.any(Error));\n            }\n            expect(json).toBe(null);\n        });\n\n        it('should return the isoString when stringified', function () {\n            var date = new Date();\n            expect(JSON.stringify(date.toISOString())).toBe(JSON.stringify(date));\n        });\n    });\n\n});\n"
  },
  {
    "path": "tests/spec/s-error.js",
    "content": "describe('Error', function () {\n    'use strict';\n\n    var supportsDescriptors = Object.defineProperty && (function () {\n        try {\n            var obj = {};\n            Object.defineProperty(obj, 'x', { enumerable: false, value: obj });\n            // eslint-disable-next-line no-unreachable-loop\n            for (var _ in obj) { return false; } // jscs:ignore disallowUnusedVariables\n            return obj.x === obj;\n        } catch (e) { /* this is ES3 */\n            return false;\n        }\n    }());\n    var ifSupportsDescriptorsIt = supportsDescriptors ? it : xit;\n\n    describe('#toString()', function () {\n        it('stringifies a newed error properly', function () {\n            var msg = 'test';\n            var error = new RangeError(msg);\n            expect(error.name).toBe('RangeError');\n            expect(error.message).toBe(msg);\n            expect(String(error)).toBe(error.name + ': ' + msg);\n        });\n\n        it('stringifies a thrown error properly', function () {\n            var msg = 'test';\n            var error;\n            try {\n                throw new RangeError(msg);\n            } catch (e) {\n                error = e;\n            }\n            expect(error.name).toBe('RangeError');\n            expect(error.message).toBe(msg);\n            expect(String(error)).toBe(error.name + ': ' + msg);\n        });\n    });\n\n    describe('enumerability of prototype properties', function () {\n        ifSupportsDescriptorsIt('#message', function () {\n            expect(Object.prototype.propertyIsEnumerable.call(Error.prototype, 'message')).toBe(false);\n        });\n\n        ifSupportsDescriptorsIt('#name', function () {\n            expect(Object.prototype.propertyIsEnumerable.call(Error.prototype, 'name')).toBe(false);\n        });\n    });\n});\n"
  },
  {
    "path": "tests/spec/s-function.js",
    "content": "describe('Function', function () {\n    'use strict';\n\n    describe('#apply()', function () {\n        it('works with arraylike objects', function () {\n            var arrayLike = { length: 4, 0: 1, 2: 4, 3: true };\n            var expectedArray = [1, undefined, 4, true];\n            var actualArray = (function () {\n                return Array.prototype.slice.apply(arguments);\n            }.apply(null, arrayLike));\n            expect(actualArray).toEqual(expectedArray);\n        });\n    });\n\n    describe('#bind()', function () {\n        var actual;\n\n        var testSubject = {\n            push: function (o) {\n                this.a.push(o);\n            }\n        };\n\n        var func = function func() {\n            Array.prototype.forEach.call(arguments, function (a) {\n                this.push(a);\n            }, this);\n            return this;\n        };\n\n        beforeEach(function () {\n            actual = [];\n            testSubject.a = [];\n        });\n\n        it('binds properly without a context', function () {\n            var context;\n            testSubject.func = function () {\n                context = this;\n            }.bind();\n            testSubject.func();\n            expect(context).toBe(function () { return this; }.call());\n        });\n        it('binds properly without a context, and still supplies bound arguments', function () {\n            var a, context;\n            testSubject.func = function () {\n                a = Array.prototype.slice.call(arguments);\n                context = this;\n            }.bind(undefined, 1, 2, 3);\n            testSubject.func(1, 2, 3);\n            expect(a).toEqual([1, 2, 3, 1, 2, 3]);\n            expect(context).toBe(function () { return this; }.call());\n        });\n        it('binds a context properly', function () {\n            testSubject.func = func.bind(actual);\n            testSubject.func(1, 2, 3);\n            expect(actual).toEqual([1, 2, 3]);\n            expect(testSubject.a).toEqual([]);\n        });\n        it('binds a context and supplies bound arguments', function () {\n            testSubject.func = func.bind(actual, 1, 2, 3);\n            testSubject.func(4, 5, 6);\n            expect(actual).toEqual([1, 2, 3, 4, 5, 6]);\n            expect(testSubject.a).toEqual([]);\n        });\n\n        it('returns properly without binding a context', function () {\n            testSubject.func = function () {\n                return this;\n            }.bind();\n            var context = testSubject.func();\n            expect(context).toBe(function () { return this; }.call());\n        });\n        it('returns properly without binding a context, and still supplies bound arguments', function () {\n            var context;\n            testSubject.func = function () {\n                context = this;\n                return Array.prototype.slice.call(arguments);\n            }.bind(undefined, 1, 2, 3);\n            actual = testSubject.func(1, 2, 3);\n            expect(context).toBe(function () { return this; }.call());\n            expect(actual).toEqual([1, 2, 3, 1, 2, 3]);\n        });\n        it('returns properly while binding a context properly', function () {\n            var ret;\n            testSubject.func = func.bind(actual);\n            ret = testSubject.func(1, 2, 3);\n            expect(ret).toBe(actual);\n            expect(ret).not.toBe(testSubject);\n        });\n        it('returns properly while binding a context and supplies bound arguments', function () {\n            var ret;\n            testSubject.func = func.bind(actual, 1, 2, 3);\n            ret = testSubject.func(4, 5, 6);\n            expect(ret).toBe(actual);\n            expect(ret).not.toBe(testSubject);\n        });\n        it('has the new instance\\'s context as a constructor', function () {\n            var actualContext;\n            var expectedContext = { foo: 'bar' };\n            testSubject.Func = function () {\n                actualContext = this;\n            }.bind(expectedContext);\n            var result = new testSubject.Func();\n            expect(result).toBeTruthy();\n            expect(actualContext).not.toBe(expectedContext);\n        });\n        it('passes the correct arguments as a constructor', function () {\n            var expected = { name: 'Correct' };\n            testSubject.Func = function (arg) {\n                expect(Object.prototype.hasOwnProperty.call(this, 'name')).toBe(false);\n                return arg;\n            }.bind({ name: 'Incorrect' });\n            var ret = new testSubject.Func(expected);\n            expect(ret).toBe(expected);\n        });\n        it('returns the return value of the bound function when called as a constructor', function () {\n            var oracle = [1, 2, 3];\n            var Subject = function () {\n                expect(this).not.toBe(oracle);\n                return oracle;\n            }.bind(null);\n            var result = new Subject();\n            expect(result).toBe(oracle);\n        });\n\n        it('returns the correct value if constructor returns primitive', function () {\n            var Subject = function (oracle) {\n                expect(this).not.toBe(oracle);\n                return oracle;\n            }.bind(null);\n\n            var primitives = ['asdf', null, true, 1];\n            for (var i = 0; i < primitives.length; ++i) {\n                expect(new Subject(primitives[i])).not.toBe(primitives[i]);\n            }\n\n            var objects = [[1, 2, 3], {}, function () {}];\n            for (var j = 0; j < objects.length; ++j) {\n                expect(new Subject(objects[j])).toBe(objects[j]);\n            }\n        });\n        it('returns the value that instance of original \"class\" when called as a constructor', function () {\n            var ClassA = function (x) {\n                this.name = x || 'A';\n            };\n            var ClassB = ClassA.bind(null, 'B');\n\n            var result = new ClassB();\n            expect(result instanceof ClassA).toBe(true);\n            expect(result instanceof ClassB).toBe(true);\n        });\n        it('sets a correct length without thisArg', function () {\n            var Subject = function (a, b, c) { return a + b + c; }.bind();\n            expect(Subject.length).toBe(3);\n        });\n        it('sets a correct length with thisArg', function () {\n            var Subject = function (a, b, c) { return a + b + c + this.d; }.bind({ d: 1 });\n            expect(Subject.length).toBe(3);\n        });\n        it('sets a correct length with thisArg and first argument', function () {\n            var Subject = function (a, b, c) { return a + b + c + this.d; }.bind({ d: 1 }, 1);\n            expect(Subject.length).toBe(2);\n        });\n        it('sets a correct length without thisArg and first argument', function () {\n            var Subject = function (a, b, c) { return a + b + c; }.bind(undefined, 1);\n            expect(Subject.length).toBe(2);\n        });\n        it('sets a correct length without thisArg and too many argument', function () {\n            var Subject = function (a, b, c) { return a + b + c; }.bind(undefined, 1, 2, 3, 4);\n            expect(Subject.length).toBe(0);\n        });\n    });\n});\n"
  },
  {
    "path": "tests/spec/s-global.js",
    "content": "describe('global methods', function () {\n    'use strict';\n\n    var foo = function foo() {};\n    var functionsHaveNames = foo.name === 'foo';\n    var ifFunctionsHaveNamesIt = functionsHaveNames ? it : xit;\n    var hasSymbols = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol';\n    var ifSymbolsIt = hasSymbols ? it : xit;\n\n    var is = function (x, y) {\n        if (x === 0 && y === 0) {\n            return 1 / x === 1 / y;\n        }\n        return x === y;\n    };\n\n    describe('parseInt', function () {\n        /* eslint-disable radix */\n\n        ifFunctionsHaveNamesIt('has the right name', function () {\n            expect(parseInt.name).toBe('parseInt');\n        });\n\n        it('accepts a radix', function () {\n            for (var i = 2; i <= 36; ++i) {\n                expect(parseInt('10', i)).toBe(i);\n            }\n        });\n\n        it('defaults the radix to 10 when the number does not start with 0x or 0X', function () {\n            [\n                '01',\n                '08',\n                '10',\n                '42'\n            ].forEach(function (str) {\n                expect(parseInt(str)).toBe(parseInt(str, 10));\n            });\n        });\n\n        it('defaults the radix to 16 when the number starts with 0x or 0X', function () {\n            expect(parseInt('0x16')).toBe(parseInt('0x16', 16));\n            expect(parseInt('0X16')).toBe(parseInt('0X16', 16));\n        });\n\n        it('ignores leading whitespace', function () {\n            expect(parseInt('  0x16')).toBe(parseInt('0x16', 16));\n            expect(parseInt('  42')).toBe(parseInt('42', 10));\n            expect(parseInt('  08')).toBe(parseInt('08', 10));\n\n            var mvsIsWS = (/\\s/).test('\\u180E');\n            if (mvsIsWS) {\n                expect(parseInt('\\u180E' + 1)).toBe(1);\n            } else {\n                expect(parseInt('\\u180E' + 1)).toBeNaN();\n            }\n\n            var ws = '\\x09\\x0A\\x0B\\x0C\\x0D\\x20\\xA0\\u1680\\u180E\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200A\\u202F\\u205F\\u3000\\u2028\\u2029\\uFEFF'\n                .replace(/\\S/g, ''); // remove the mongolian vowel separator (/u180E) on modern engines\n            expect(parseInt(ws + '08')).toBe(parseInt('08', 10));\n            expect(parseInt(ws + '0x16')).toBe(parseInt('0x16', 16));\n        });\n\n        it('defaults the radix properly when not a true number', function () {\n            var fakeZero = { valueOf: function () { return 0; } };\n            expect(parseInt('08', fakeZero)).toBe(parseInt('08', 10));\n            expect(parseInt('0x16', fakeZero)).toBe(parseInt('0x16', 16));\n        });\n\n        it('allows sign-prefixed hex values', function () {\n            expect(parseInt('-0xF')).toBe(-15);\n            expect(parseInt('-0xF', 16)).toBe(-15);\n            expect(parseInt('+0xF')).toBe(15);\n            expect(parseInt('+0xF', 16)).toBe(15);\n        });\n\n        it('NaN parsing', function () {\n            expect(parseInt()).toBeNaN();\n            expect(parseInt(undefined)).toBeNaN();\n            expect(parseInt(null)).toBeNaN();\n            expect(parseInt(NaN)).toBeNaN();\n        });\n\n        ifSymbolsIt('throws on symbols', function () {\n            expect(function () { parseInt(Symbol('')); }).toThrow();\n            expect(function () { parseInt(Object(Symbol(''))); }).toThrow();\n        });\n        /* eslint-enable radix */\n    });\n\n    describe('parseFloat()', function () {\n        it('works with zeroes', function () {\n            expect(is(parseFloat('0'), 0) ? '+0' : '-0').toBe('+0');\n            expect(is(parseFloat(' 0'), 0) ? '+0' : '-0').toBe('+0');\n            expect(is(parseFloat('+0'), 0) ? '+0' : '-0').toBe('+0');\n            expect(is(parseFloat(' +0'), 0) ? '+0' : '-0').toBe('+0');\n            expect(is(parseFloat('-0'), -0) ? '-0' : '+0').toBe('-0');\n            expect(is(parseFloat(' -0'), -0) ? '-0' : '+0').toBe('-0');\n        });\n\n        it('NaN parsing', function () {\n            expect(parseFloat(undefined)).toBeNaN();\n            expect(parseFloat(null)).toBeNaN();\n            expect(parseFloat(NaN)).toBeNaN();\n        });\n    });\n});\n"
  },
  {
    "path": "tests/spec/s-number.js",
    "content": "describe('Number', function () {\n    'use strict';\n\n    describe('#toExponential()', function () {\n        // the spec allows for this test to fail.\n        it('throws a RangeError when < 0 or > 20 (or > 100 in ES2018+)', function () {\n            expect(function () { return 1.0.toExponential(-1); }).toThrow();\n            expect(function () { return 1.0.toExponential(-Infinity); }).toThrow();\n            expect(function () { return 1.0.toExponential(Infinity); }).toThrow();\n            expect(function () {\n                return [\n                    (0.9).toExponential(21), // ES2018 increased the limit from 21 to 100\n                    (0.9).toExponential(101)\n                ];\n            }).toThrow();\n        });\n\n        it('works for NaN receiver', function () {\n            expect(NaN.toExponential(NaN)).toBe('NaN');\n            expect(NaN.toExponential('abc')).toBe('NaN');\n        });\n\n        it('works for non-finite receivers', function () {\n            expect(Infinity.toExponential()).toBe('Infinity');\n            expect((-Infinity).toExponential()).toBe('-Infinity');\n        });\n\n        it('should round properly', function () {\n            expect(1.0.toExponential()).toBe('1e+0');\n            expect(1.0.toExponential(0)).toBe('1e+0');\n            expect(1.0.toExponential(1)).toBe('1.0e+0');\n            expect(1.0.toExponential(2)).toBe('1.00e+0');\n\n            expect(1.2345.toExponential()).toBe('1.2345e+0');\n            expect(1.2345.toExponential(0)).toBe('1e+0');\n            expect(1.2345.toExponential(1)).toBe('1.2e+0');\n            expect(1.2345.toExponential(2)).toBe('1.23e+0');\n            expect(1.2345.toExponential(3)).toMatch(/^1.23[45]e\\+0$/);\n            expect(1.2345.toExponential(4)).toBe('1.2345e+0');\n            expect(1.2345.toExponential(5)).toBe('1.23450e+0');\n\n            expect((-6.9e-11).toExponential(4)).toBe('-6.9000e-11');\n        });\n    });\n\n    describe('#toFixed()', function () {\n        it('should convert numbers correctly', function () {\n            expect((0.00008).toFixed(3)).toBe('0.000');\n            expect((0.9).toFixed(0)).toBe('1');\n            expect((1.255).toFixed(2)).toBe('1.25');\n            expect((1843654265.0774949).toFixed(5)).toBe('1843654265.07749');\n            expect((1000000000000000128).toFixed(0)).toBe('1000000000000000128');\n        });\n    });\n\n    describe('#toPrecision()', function () {\n        // the spec allows for this test to fail.\n        it('throws a RangeError when < 1 or > 21 (or > 100 in ES2018+)', function () {\n            expect(function () { return (0.9).toPrecision(0); }).toThrow();\n            expect(function () {\n                return [\n                    (0.9).toPrecision(22), // ES2018 increased the limit from 21 to 100\n                    (0.9).toPrecision(101)\n                ];\n            }).toThrow();\n        });\n\n        it('works as expected', function () {\n            expect((0.00008).toPrecision(3)).toBe('0.0000800');\n            expect((1.255).toPrecision(2)).toBe('1.3');\n            expect((1843654265.0774949).toPrecision(13)).toBe('1843654265.077');\n            expect(NaN.toPrecision(1)).toBe('NaN');\n        });\n\n        it('works with an undefined precision', function () {\n            var num = 123.456;\n            expect(num.toPrecision()).toBe(String(num));\n            expect(num.toPrecision(undefined)).toBe(String(num));\n        });\n    });\n\n    describe('constants', function () {\n        it('should have MAX_VALUE', function () {\n            expect(Number.MAX_VALUE).toBe(1.7976931348623157e308);\n        });\n\n        it('should have MIN_VALUE', function () {\n            expect(Number.MIN_VALUE).toBe(5e-324);\n        });\n\n        it('should have NaN', function () {\n            expect(Number.NaN).not.toBe(Number.NaN);\n        });\n\n        it('should have POSITIVE_INFINITY', function () {\n            expect(Number.POSITIVE_INFINITY).toBe(Infinity);\n        });\n\n        it('should have NEGATIVE_INFINITY', function () {\n            expect(Number.NEGATIVE_INFINITY).toBe(-Infinity);\n        });\n    });\n});\n"
  },
  {
    "path": "tests/spec/s-object.js",
    "content": "/* global window */\n\nvar has = Object.prototype.hasOwnProperty;\nvar supportsDescriptors = Object.defineProperty && (function () {\n    try {\n        var obj = {};\n        Object.defineProperty(obj, 'x', { enumerable: false, value: obj });\n        // eslint-disable-next-line no-unreachable-loop\n        for (var _ in obj) { return false; } // jscs:ignore disallowUnusedVariables\n        return obj.x === obj;\n    } catch (e) { /* this is ES3 */\n        return false;\n    }\n}());\nvar ifSupportsDescriptorsIt = supportsDescriptors ? it : xit;\nvar ifWindowIt = typeof window === 'undefined' ? xit : it;\nvar extensionsPreventible = typeof Object.preventExtensions === 'function' && (function () {\n    var obj = {};\n    Object.preventExtensions(obj);\n    obj.a = 3;\n    return obj.a !== 3;\n}());\nvar ifExtensionsPreventibleIt = extensionsPreventible ? it : xit;\nvar canSeal = typeof Object.seal === 'function' && (function () {\n    var obj = { a: 3 };\n    Object.seal(obj);\n    delete obj.a;\n    return obj.a === 3;\n}());\nvar ifCanSealIt = canSeal ? it : xit;\nvar canFreeze = typeof Object.freeze === 'function' && (function () {\n    var obj = {};\n    Object.freeze(obj);\n    obj.a = 3;\n    return obj.a !== 3;\n}());\nvar ifCanFreezeIt = canFreeze ? it : xit;\n\ndescribe('Object', function () {\n    'use strict';\n\n    describe('.keys()', function () {\n        var obj = {\n            str: 'boz',\n            obj: { },\n            arr: [],\n            bool: true,\n            num: 42,\n            'null': null,\n            undefined: undefined\n        };\n\n        var loopedValues = [];\n        for (var key in obj) {\n            loopedValues.push(key);\n        }\n\n        var keys = Object.keys(obj);\n        it('should have correct length', function () {\n            expect(keys.length).toBe(7);\n        });\n\n        describe('arguments objects', function () {\n            it('works with an arguments object', function () {\n                (function () {\n                    expect(arguments.length).toBe(3);\n                    expect(Object.keys(arguments).length).toBe(arguments.length);\n                    expect(Object.keys(arguments)).toEqual(['0', '1', '2']);\n                }(1, 2, 3));\n            });\n\n            it('works with a legacy arguments object', function () {\n                var FakeArguments = function (args) {\n                    args.forEach(function (arg, i) {\n                        this[i] = arg;\n                    }.bind(this));\n                };\n                FakeArguments.prototype.length = 3;\n                FakeArguments.prototype.callee = function () {};\n\n                var fakeOldArguments = new FakeArguments(['a', 'b', 'c']);\n                expect(Object.keys(fakeOldArguments)).toEqual(['0', '1', '2']);\n            });\n        });\n\n        it('should return an Array', function () {\n            expect(Array.isArray(keys)).toBe(true);\n        });\n\n        it('should return names which are own properties', function () {\n            keys.forEach(function (name) {\n                expect(has.call(obj, name)).toBe(true);\n            });\n        });\n\n        it('should return names which are enumerable', function () {\n            keys.forEach(function (name) {\n                expect(loopedValues.indexOf(name)).toNotBe(-1);\n            });\n        });\n\n        // ES6 Object.keys does not require this throw\n        xit('should throw error for non object', function () {\n            var e = {};\n            expect(function () {\n                try {\n                    Object.keys(42);\n                } catch (err) {\n                    throw e;\n                }\n            }).toThrow(e);\n        });\n\n        describe('enumerating over non-enumerable properties', function () {\n            it('has no enumerable keys on a Function', function () {\n                var Foo = function () {};\n                expect(Object.keys(Foo.prototype)).toEqual([]);\n            });\n\n            it('has no enumerable keys on a boolean', function () {\n                expect(Object.keys(Boolean.prototype)).toEqual([]);\n            });\n\n            it('has no enumerable keys on an object', function () {\n                expect(Object.keys(Object.prototype)).toEqual([]);\n            });\n        });\n\n        it('works with boxed primitives', function () {\n            expect(Object.keys(Object('hello'))).toEqual(['0', '1', '2', '3', '4']);\n        });\n\n        it('works with boxed primitives with extra properties', function () {\n            var x = Object('x');\n            x.y = 1;\n            var actual = Object.keys(x);\n            var expected = ['0', 'y'];\n            actual.sort();\n            expected.sort();\n            expect(actual).toEqual(expected);\n        });\n\n        ifWindowIt('can serialize all objects on the `window`', function () {\n            var windowItemKeys, exception;\n            var excludedKeys = ['window', 'console', 'parent', 'self', 'frame', 'frames', 'frameElement', 'external', 'height', 'width', 'top', 'localStorage', 'applicationCache'];\n            if (supportsDescriptors) {\n                Object.defineProperty(window, 'thrower', {\n                    configurable: true,\n                    get: function () { throw new RangeError('thrower!'); }\n                });\n            }\n            for (var k in window) {\n                exception = void 0;\n                windowItemKeys = exception;\n                if (excludedKeys.indexOf(k) === -1 && has.call(window, k) && window[k] !== null && typeof window[k] === 'object') {\n                    try {\n                        windowItemKeys = Object.keys(window[k]);\n                    } catch (e) {\n                        exception = e;\n                    }\n                    expect(Array.isArray(windowItemKeys)).toBe(true);\n                    expect(exception).toBeUndefined();\n                }\n            }\n            if (supportsDescriptors) {\n                delete window.thrower;\n            }\n        });\n    });\n\n    describe('.isExtensible()', function () {\n        var obj = { };\n\n        it('should return true if object is extensible', function () {\n            expect(Object.isExtensible(obj)).toBe(true);\n        });\n\n        ifExtensionsPreventibleIt('should return false if object is not extensible', function () {\n            expect(Object.isExtensible(Object.preventExtensions(obj))).toBe(false);\n        });\n\n        ifCanSealIt('should return false if object is sealed', function () {\n            expect(Object.isExtensible(Object.seal(obj))).toBe(false);\n        });\n\n        ifCanFreezeIt('should return false if object is frozen', function () {\n            expect(Object.isExtensible(Object.freeze(obj))).toBe(false);\n        });\n\n        it('should throw error for non object', function () {\n            try {\n                // note: in ES6, this is expected to return false.\n                expect(Object.isExtensible(42)).toBe(false);\n            } catch (err) {\n                expect(err).toEqual(jasmine.any(TypeError));\n            }\n        });\n    });\n\n    describe('.defineProperty()', function () {\n        var obj;\n\n        beforeEach(function () {\n            obj = {};\n\n            Object.defineProperty(obj, 'name', {\n                value: 'Testing',\n                configurable: true,\n                enumerable: true,\n                writable: true\n            });\n        });\n\n        it('should return the initial value', function () {\n            expect(has.call(obj, 'name')).toBeTruthy();\n            expect(obj.name).toBe('Testing');\n        });\n\n        it('should be setable', function () {\n            obj.name = 'Other';\n            expect(obj.name).toBe('Other');\n        });\n\n        it('should return the parent initial value', function () {\n            var child = Object.create(obj, {});\n\n            expect(child.name).toBe('Testing');\n            expect(has.call(child, 'name')).toBeFalsy();\n        });\n\n        it('should not override the parent value', function () {\n            var child = Object.create(obj, {});\n\n            Object.defineProperty(child, 'name', { value: 'Other' });\n\n            expect(obj.name).toBe('Testing');\n            expect(child.name).toBe('Other');\n        });\n\n        it('should throw error for non object', function () {\n            expect(function () {\n                Object.defineProperty(42, 'name', {});\n            }).toThrow();\n        });\n\n        it('should not throw error for empty descriptor', function () {\n            expect(function () {\n                Object.defineProperty({}, 'name', {});\n            }).not.toThrow();\n        });\n\n        ifSupportsDescriptorsIt('allows setting a nonwritable prototype', function () {\n            var F = function () {};\n            expect(F.prototype).toEqual(Object.getOwnPropertyDescriptor(F, 'prototype').value);\n            expect((new F()).toString).toEqual(Object.prototype.toString);\n\n            F.prototype = Number.prototype;\n            expect(F.prototype).toEqual(Object.getOwnPropertyDescriptor(F, 'prototype').value);\n            expect((new F()).toString).toEqual(Number.prototype.toString);\n\n            var toStringSentinel = {};\n            var sentinel = { toString: toStringSentinel };\n            Object.defineProperty(F, 'prototype', { value: sentinel, writable: false });\n\n            expect(F.prototype).toEqual(Object.getOwnPropertyDescriptor(F, 'prototype').value);\n            expect((new F()).toString).toEqual(toStringSentinel);\n        });\n\n        ifSupportsDescriptorsIt('properly makes a prototype non-writable', function () {\n            var O = { prototype: 1 };\n            expect(O.prototype).toEqual(Object.getOwnPropertyDescriptor(O, 'prototype').value);\n            expect(O.prototype).toEqual(1);\n\n            expect(function () {\n                Object.defineProperty(O, 'prototype', { writable: false, configurable: true });\n            }).not.toThrow();\n\n            var sentinel = {};\n            expect(function () {\n                Object.defineProperty(O, 'prototype', { value: sentinel });\n            }).not.toThrow();\n\n            expect(O.prototype).toEqual(Object.getOwnPropertyDescriptor(O, 'prototype').value);\n            expect(O.prototype).toEqual(sentinel);\n        });\n    });\n\n    describe('.getOwnPropertyDescriptor()', function () {\n        it('should return undefined because the object does not own the property', function () {\n            var descr = Object.getOwnPropertyDescriptor({}, 'name');\n\n            expect(descr).toBeUndefined();\n        });\n\n        it('should return a data descriptor', function () {\n            var descr = Object.getOwnPropertyDescriptor({ name: 'Testing' }, 'name');\n            var expected = {\n                value: 'Testing',\n                enumerable: true,\n                writable: true,\n                configurable: true\n            };\n\n            expect(descr).toEqual(expected);\n        });\n\n        it('should return undefined because the object does not own the property', function () {\n            var descr = Object.getOwnPropertyDescriptor(Object.create({ name: 'Testing' }, {}), 'name');\n\n            expect(descr).toBeUndefined();\n        });\n\n        it('should return a data descriptor', function () {\n            var expected = {\n                value: 'Testing',\n                configurable: true,\n                enumerable: true,\n                writable: true\n            };\n            var obj = Object.create({}, { name: expected });\n\n            var descr = Object.getOwnPropertyDescriptor(obj, 'name');\n\n            expect(descr).toEqual(expected);\n        });\n\n        it('should throw error for non object', function () {\n            try {\n                // note: in ES6, we expect this to return undefined.\n                expect(Object.getOwnPropertyDescriptor(42, 'name')).toBeUndefined();\n            } catch (err) {\n                expect(err).toEqual(jasmine.any(TypeError));\n            }\n        });\n    });\n\n    describe('.getPrototypeOf()', function () {\n        it('should return the [[Prototype]] of an object', function () {\n            var Foo = function () {};\n\n            var proto = Object.getPrototypeOf(new Foo());\n\n            expect(proto).toBe(Foo.prototype);\n        });\n\n        it('should shamone to the `Object.prototype` if `object.constructor` is not a function', function () {\n            var Foo = function () {};\n            Foo.prototype.constructor = 1;\n\n            var proto = Object.getPrototypeOf(new Foo()),\n                fnToString = Function.prototype.toString;\n\n            if (fnToString.call(Object.getPrototypeOf).indexOf('[native code]') < 0) {\n                expect(proto).toBe(Object.prototype);\n            } else {\n                expect(proto).toBe(Foo.prototype);\n            }\n        });\n\n        it('should throw error for non object', function () {\n            try {\n                expect(Object.getPrototypeOf(1)).toBe(Number.prototype); // ES6 behavior\n            } catch (err) {\n                expect(err).toEqual(jasmine.any(TypeError));\n            }\n        });\n\n        it('should return null on Object.create(null)', function () {\n            var obj = Object.create(null);\n\n            expect(Object.getPrototypeOf(obj) === null).toBe(true);\n        });\n    });\n\n    describe('.defineProperties()', function () {\n        it('should define the constructor property', function () {\n            var target = {};\n            var newProperties = { constructor: { value: 'new constructor' } };\n            Object.defineProperties(target, newProperties);\n            expect(target.constructor).toBe('new constructor');\n        });\n    });\n\n    describe('.create()', function () {\n        it('should create objects with no properties when called as `Object.create(null)`', function () {\n            var obj = Object.create(null);\n\n            expect('hasOwnProperty' in obj).toBe(false);\n            expect('toString' in obj).toBe(false);\n            expect('constructor' in obj).toBe(false);\n\n            var protoIsEnumerable = false;\n            for (var k in obj) {\n                if (k === '__proto__') {\n                    protoIsEnumerable = true;\n                }\n            }\n            expect(protoIsEnumerable).toBe(false);\n\n            expect(obj instanceof Object).toBe(false);\n        });\n    });\n});\n"
  },
  {
    "path": "tests/spec/s-regexp.js",
    "content": "describe('RegExp', function () {\n    'use strict';\n\n    describe('#toString()', function () {\n        describe('literals', function () {\n            it('should return correct flags and in correct order', function () {\n                expect(String(/pattern/)).toBe('/pattern/');\n                expect(String(/pattern/i)).toBe('/pattern/i');\n                expect(String(/pattern/mi)).toBe('/pattern/im');\n                expect(String(/pattern/im)).toBe('/pattern/im');\n                expect(String(/pattern/mgi)).toBe('/pattern/gim');\n            });\n        });\n\n        describe('objects', function () {\n            it('should return correct flags and in correct order', function () {\n                /* eslint prefer-regex-literals: 0 */\n                expect(String(new RegExp('pattern'))).toBe('/pattern/');\n                expect(String(new RegExp('pattern', 'i'))).toBe('/pattern/i');\n                expect(String(new RegExp('pattern', 'mi'))).toBe('/pattern/im');\n                expect(String(new RegExp('pattern', 'im'))).toBe('/pattern/im');\n                expect(String(new RegExp('pattern', 'mgi'))).toBe('/pattern/gim');\n            });\n        });\n    });\n});\n"
  },
  {
    "path": "tests/spec/s-string.js",
    "content": "describe('String', function () {\n    'use strict';\n\n    describe('#trim()', function () {\n        var mvs = '\\u180E';\n        var mvsIsWS = (/\\s/).test(mvs);\n        var test = '\\x09\\x0A\\x0B\\x0C\\x0D\\x20\\xA0\\u1680' + (mvsIsWS ? mvs : '') + '\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200A\\u202F\\u205F\\u3000\\u2028\\u2029\\uFEFFHello, World!\\x09\\x0A\\x0B\\x0C\\x0D\\x20\\xA0\\u1680' + (mvsIsWS ? mvs : '') + '\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200A\\u202F\\u205F\\u3000\\u2028\\u2029\\uFEFF';\n\n        it('trims all ES5 whitespace', function () {\n            expect(test.trim()).toBe('Hello, World!');\n            expect(test.trim().length).toBe(13);\n        });\n\n        it('does not trim the zero-width space', function () {\n            var zws = '\\u200b';\n            expect(zws.trim()).toBe(zws);\n        });\n\n        it('properly handles the mongolian vowel separator', function () {\n            if (mvsIsWS) {\n                expect(mvs.trim()).toBe('');\n            } else {\n                expect(mvs.trim()).toBe(mvs);\n            }\n        });\n    });\n\n    describe('#replace()', function () {\n        it('returns undefined for non-capturing groups', function () {\n            var groups = [];\n            'x'.replace(/x(.)?/g, function (m, group) {\n                groups.push(group); /* \"\" in FF, `undefined` in CH/WK/IE */\n            });\n            expect(groups.length).toBe(1);\n            expect(groups[0]).toBeUndefined();\n        });\n\n        it('should not fail in Firefox', function () {\n            expect(function () {\n                return '* alef\\n* beth \\n* gimel~0\\n'.replace(\n                    /(\\n)?(^[ \\t]*)([*+-]|\\d+[.])[ \\t]+([^\\r]+?(\\n{1,2}))(?=\\n*(~0|\\2([*+-]|\\d+[.])[ \\t]+))/gm,\n                    function (match, m1, m2, m3, m4) { return '<li>' + m4 + '</li>\\n'; }\n                );\n            }).not.toThrow();\n        });\n    });\n\n    describe('#split()', function () {\n        var test = 'ab';\n\n        it('If \"separator\" is undefined must return Array with one String - \"this\" string', function () {\n            expect(test.split()).toEqual([test]);\n            expect(test.split(void 0)).toEqual([test]);\n        });\n\n        it('If \"separator\" is undefined and \"limit\" set to 0 must return Array[]', function () {\n            expect(test.split(void 0, 0)).toEqual([]);\n        });\n\n        describe('Tests from Steven Levithan', function () {\n            it(\"''.split() results in ['']\", function () {\n                expect(''.split()).toEqual(['']);\n            });\n            it(\"''.split(/./) results in ['']\", function () {\n                expect(''.split(/./)).toEqual(['']);\n            });\n            it(\"''.split(/.?/) results in []\", function () {\n                expect(''.split(/.?/)).toEqual([]);\n            });\n            it(\"''.split(/.??/) results in []\", function () {\n                expect(''.split(/.??/)).toEqual([]);\n            });\n            it(\"'ab'.split(/a*/) results in ['', 'b']\", function () {\n                expect('ab'.split(/a*/)).toEqual(['', 'b']);\n            });\n            it(\"'ab'.split(/a*?/) results in ['a', 'b']\", function () {\n                expect('ab'.split(/a*?/)).toEqual(['a', 'b']);\n            });\n            it(\"'ab'.split(/(?:ab)/) results in ['', '']\", function () {\n                expect('ab'.split(/(?:ab)/)).toEqual(['', '']);\n            });\n            it(\"'ab'.split(/(?:ab)*/) results in ['', '']\", function () {\n                expect('ab'.split(/(?:ab)*/)).toEqual(['', '']);\n            });\n            it(\"'ab'.split(/(?:ab)*?/) results in ['a', 'b']\", function () {\n                expect('ab'.split(/(?:ab)*?/)).toEqual(['a', 'b']);\n            });\n            it(\"'test'.split('') results in ['t', 'e', 's', 't']\", function () {\n                expect('test'.split('')).toEqual(['t', 'e', 's', 't']);\n            });\n            it(\"'test'.split() results in ['test']\", function () {\n                expect('test'.split()).toEqual(['test']);\n            });\n            it(\"'111'.split(1) results in ['', '', '', '']\", function () {\n                expect('111'.split(1)).toEqual(['', '', '', '']);\n            });\n            it(\"'test'.split(/(?:)/, 2) results in ['t', 'e']\", function () {\n                expect('test'.split(/(?:)/, 2)).toEqual(['t', 'e']);\n            });\n            it(\"'test'.split(/(?:)/, -1) results in ['t', 'e', 's', 't']\", function () {\n                expect('test'.split(/(?:)/, -1)).toEqual(['t', 'e', 's', 't']);\n            });\n            it(\"'test'.split(/(?:)/, undefined) results in ['t', 'e', 's', 't']\", function () {\n                expect('test'.split(/(?:)/, undefined)).toEqual(['t', 'e', 's', 't']);\n            });\n            it(\"'test'.split(/(?:)/, null) results in []\", function () {\n                expect('test'.split(/(?:)/, null)).toEqual([]);\n            });\n            it(\"'test'.split(/(?:)/, NaN) results in []\", function () {\n                expect('test'.split(/(?:)/, NaN)).toEqual([]);\n            });\n            it(\"'test'.split(/(?:)/, true) results in ['t']\", function () {\n                expect('test'.split(/(?:)/, true)).toEqual(['t']);\n            });\n            it(\"'test'.split(/(?:)/, '2') results in ['t', 'e']\", function () {\n                expect('test'.split(/(?:)/, '2')).toEqual(['t', 'e']);\n            });\n            it(\"'test'.split(/(?:)/, 'two') results in []\", function () {\n                expect('test'.split(/(?:)/, 'two')).toEqual([]);\n            });\n            it(\"'a'.split(/-/) results in ['a']\", function () {\n                expect('a'.split(/-/)).toEqual(['a']);\n            });\n            it(\"'a'.split(/-?/) results in ['a']\", function () {\n                expect('a'.split(/-?/)).toEqual(['a']);\n            });\n            it(\"'a'.split(/-??/) results in ['a']\", function () {\n                expect('a'.split(/-??/)).toEqual(['a']);\n            });\n            it(\"'a'.split(/a/) results in ['', '']\", function () {\n                expect('a'.split(/a/)).toEqual(['', '']);\n            });\n            it(\"'a'.split(/a?/) results in ['', '']\", function () {\n                expect('a'.split(/a?/)).toEqual(['', '']);\n            });\n            it(\"'a'.split(/a??/) results in ['a']\", function () {\n                expect('a'.split(/a??/)).toEqual(['a']);\n            });\n            it(\"'ab'.split(/-/) results in ['ab']\", function () {\n                expect('ab'.split(/-/)).toEqual(['ab']);\n            });\n            it(\"'ab'.split(/-?/) results in ['a', 'b']\", function () {\n                expect('ab'.split(/-?/)).toEqual(['a', 'b']);\n            });\n            it(\"'ab'.split(/-??/) results in ['a', 'b']\", function () {\n                expect('ab'.split(/-??/)).toEqual(['a', 'b']);\n            });\n            it(\"'a-b'.split(/-/) results in ['a', 'b']\", function () {\n                expect('a-b'.split(/-/)).toEqual(['a', 'b']);\n            });\n            it(\"'a-b'.split(/-?/) results in ['a', 'b']\", function () {\n                expect('a-b'.split(/-?/)).toEqual(['a', 'b']);\n            });\n            it(\"'a-b'.split(/-??/) results in ['a', '-', 'b']\", function () {\n                expect('a-b'.split(/-??/)).toEqual(['a', '-', 'b']);\n            });\n            it(\"'a--b'.split(/-/) results in ['a', '', 'b']\", function () {\n                expect('a--b'.split(/-/)).toEqual(['a', '', 'b']);\n            });\n            it(\"'a--b'.split(/-?/) results in ['a', '', 'b']\", function () {\n                expect('a--b'.split(/-?/)).toEqual(['a', '', 'b']);\n            });\n            it(\"'a--b'.split(/-??/) results in ['a', '-', '-', 'b']\", function () {\n                expect('a--b'.split(/-??/)).toEqual(['a', '-', '-', 'b']);\n            });\n            it(\"''.split(/()()/) results in []\", function () {\n                expect(''.split(/()()/)).toEqual([]);\n            });\n            it(\"'.'.split(/()()/) results in ['.']\", function () {\n                expect('.'.split(/()()/)).toEqual(['.']);\n            });\n            it(\"'.'.split(/(.?)(.?)/) results in ['', '.', '', '']\", function () {\n                expect('.'.split(/(.?)(.?)/)).toEqual(['', '.', '', '']);\n            });\n            it(\"'.'.split(/(.??)(.??)/) results in ['.']\", function () {\n                expect('.'.split(/(.??)(.??)/)).toEqual(['.']);\n            });\n            it(\"'.'.split(/(.)?(.)?/) results in ['', '.', undefined, '']\", function () {\n                expect('.'.split(/(.)?(.)?/)).toEqual(['', '.', undefined, '']);\n            });\n            it(\"'A<B>bold</B>and<CODE>coded</CODE>'.split(/<(\\\\/)?([^<>]+)>/) results in ['A', undefined, 'B', 'bold', '/', 'B', 'and', undefined, 'CODE', 'coded', '/', 'CODE', '']\", function () {\n                expect('A<B>bold</B>and<CODE>coded</CODE>'.split(/<(\\/)?([^<>]+)>/)).toEqual(['A', undefined, 'B', 'bold', '/', 'B', 'and', undefined, 'CODE', 'coded', '/', 'CODE', '']);\n            });\n            it(\"'tesst'.split(/(s)*/) results in ['t', undefined, 'e', 's', 't']\", function () {\n                expect('tesst'.split(/(s)*/)).toEqual(['t', undefined, 'e', 's', 't']);\n            });\n            it(\"'tesst'.split(/(s)*?/) results in ['t', undefined, 'e', undefined, 's', undefined, 's', undefined, 't']\", function () {\n                expect('tesst'.split(/(s)*?/)).toEqual(['t', undefined, 'e', undefined, 's', undefined, 's', undefined, 't']);\n            });\n            it(\"'tesst'.split(/(s*)/) results in ['t', '', 'e', 'ss', 't']\", function () {\n                expect('tesst'.split(/(s*)/)).toEqual(['t', '', 'e', 'ss', 't']);\n            });\n            it(\"'tesst'.split(/(s*?)/) results in ['t', '', 'e', '', 's', '', 's', '', 't']\", function () {\n                expect('tesst'.split(/(s*?)/)).toEqual(['t', '', 'e', '', 's', '', 's', '', 't']);\n            });\n            it(\"'tesst'.split(/(?:s)*/) results in ['t', 'e', 't']\", function () {\n                expect('tesst'.split(/(?:s)*/)).toEqual(['t', 'e', 't']);\n            });\n            it(\"'tesst'.split(/(?=s+)/) results in ['te', 's', 'st']\", function () {\n                expect('tesst'.split(/(?=s+)/)).toEqual(['te', 's', 'st']);\n            });\n            it(\"'test'.split('t') results in ['', 'es', '']\", function () {\n                expect('test'.split('t')).toEqual(['', 'es', '']);\n            });\n            it(\"'test'.split('es') results in ['t', 't']\", function () {\n                expect('test'.split('es')).toEqual(['t', 't']);\n            });\n            it(\"'test'.split(/t/) results in ['', 'es', '']\", function () {\n                expect('test'.split(/t/)).toEqual(['', 'es', '']);\n            });\n            it(\"'test'.split(/es/) results in ['t', 't']\", function () {\n                expect('test'.split(/es/)).toEqual(['t', 't']);\n            });\n            it(\"'test'.split(/(t)/) results in ['', 't', 'es', 't', '']\", function () {\n                expect('test'.split(/(t)/)).toEqual(['', 't', 'es', 't', '']);\n            });\n            it(\"'test'.split(/(es)/) results in ['t', 'es', 't']\", function () {\n                expect('test'.split(/(es)/)).toEqual(['t', 'es', 't']);\n            });\n            it(\"'test'.split(/(t)(e)(s)(t)/) results in ['', 't', 'e', 's', 't', '']\", function () {\n                expect('test'.split(/(t)(e)(s)(t)/)).toEqual(['', 't', 'e', 's', 't', '']);\n            });\n            it(\"'.'.split(/(((.((.??)))))/) results in ['', '.', '.', '.', '', '', '']\", function () {\n                expect('.'.split(/(((.((.??)))))/)).toEqual(['', '.', '.', '.', '', '', '']);\n            });\n            it(\"'.'.split(/(((((.??)))))/) results in ['.']\", function () {\n                expect('.'.split(/(((((.??)))))/)).toEqual(['.']);\n            });\n            it(\"'a b c d'.split(/ /, -(Math.pow(2, 32) - 1)) results in ['a']\", function () {\n                expect('a b c d'.split(/ /, -(Math.pow(2, 32) - 1))).toEqual(['a']);\n            });\n            it(\"'a b c d'.split(/ /, Math.pow(2, 32) + 1) results in ['a']\", function () {\n                expect('a b c d'.split(/ /, Math.pow(2, 32) + 1)).toEqual(['a']);\n            });\n            it(\"'a b c d'.split(/ /, Infinity) results in []\", function () {\n                expect('a b c d'.split(/ /, Infinity)).toEqual([]);\n            });\n        });\n\n        it('works with the second argument', function () {\n            expect('a b'.split(/ /, 1)).toEqual(['a']);\n        });\n    });\n\n    describe('#indexOf()', function () {\n        it('has basic support', function () {\n            expect('abcab'.indexOf('a')).toBe(0);\n            expect('abcab'.indexOf('a', 1)).toBe(3);\n            expect('abcab'.indexOf('a', 4)).toBe(-1);\n        });\n\n        it('works with unicode', function () {\n            expect('あいabcあいabc'.indexOf('あい')).toBe(0);\n            expect('あいabcあいabc'.indexOf('あい', 0)).toBe(0);\n            expect('あいabcあいabc'.indexOf('あい', 1)).toBe(5);\n            expect('あいabcあいabc'.indexOf('あい', 6)).toBe(-1);\n        });\n    });\n\n    describe('#lastIndexOf()', function () {\n        it('has the right length', function () {\n            expect(String.prototype.lastIndexOf.length).toBe(1);\n        });\n\n        it('has basic support', function () {\n            expect('abcd'.lastIndexOf('d')).toBe(3);\n            expect('abcd'.lastIndexOf('d', 3)).toBe(3);\n            expect('abcd'.lastIndexOf('d', 2)).toBe(-1);\n        });\n\n        it('works with unicode', function () {\n            expect('abcあい'.lastIndexOf('あい')).toBe(3);\n            expect('abcあい'.lastIndexOf('あい', 3)).toBe(3);\n            expect('abcあい'.lastIndexOf('あい', 2)).toBe(-1);\n        });\n    });\n});\n"
  }
]