diff --git a/.babelrc b/.babelrc deleted file mode 100644 index cdcfbd8..0000000 --- a/.babelrc +++ /dev/null @@ -1,22 +0,0 @@ -{ - "presets": [ - [ - "env", - { - "targets": { - "node": "current" - } - } - ] - ], - - "plugins": [ - "add-module-exports" - ], - - "env": { - "test": { - "plugins": [ "istanbul" ] - } - } -} diff --git a/build/unicode.js b/build/unicode.js index ea21e4f..ef1a0e2 100644 --- a/build/unicode.js +++ b/build/unicode.js @@ -40,6 +40,6 @@ const source = Object.keys(matchers).map(m => ).join(''); fs.writeFileSync( - path.join(__dirname, '..', 'src', 'language', 'matchers.js'), + path.join(__dirname, '..', 'src', 'language', 'matchers.ts'), source ); diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 0000000..1a20160 --- /dev/null +++ b/jest.config.js @@ -0,0 +1,26 @@ +module.exports = { + transform: { + ".(ts|tsx)": "ts-jest" + }, + "testEnvironment": "node", + "testRegex": "(/__tests__/.*|\\.(test|spec))\\.(ts|tsx)$", + "moduleFileExtensions": [ + "ts", + "tsx", + "js" + ], + "coveragePathIgnorePatterns": [ + "/node_modules/", + "/test/" + ], + "collectCoverageFrom": [ + "src/**/*.{js,ts}" + ], + globals: { + "ts-jest": { + "diagnostics": { + "ignoreCodes": "TS2531" + } + } + } +} diff --git a/language/en/package.json b/language/en/package.json index 201bdf1..bb4ed25 100644 --- a/language/en/package.json +++ b/language/en/package.json @@ -1,4 +1,5 @@ { - "main": "../../cjs/language/en/index.js", - "module": "../../src/language/en/index.js" + "main": "../../dist/cjs/language/en/index.js", + "module": "../../dist/esm/language/en/index.js", + "types":"../../dist/types/language/en/index.d.ts" } diff --git a/package-lock.json b/package-lock.json index a12a5a3..3a1bc7d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,45 +5,57 @@ "requires": true, "dependencies": { "@babel/code-frame": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", - "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", + "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", "dev": true, "requires": { "@babel/highlight": "^7.0.0" } }, "@babel/core": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.1.2.tgz", - "integrity": "sha512-IFeSSnjXdhDaoysIlev//UzHZbdEmm7D0EIH2qtse9xK7mXEZQpYjs2P00XlP1qYsYvid79p+Zgg6tz1mp6iVw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/generator": "^7.1.2", - "@babel/helpers": "^7.1.2", - "@babel/parser": "^7.1.2", - "@babel/template": "^7.1.2", - "@babel/traverse": "^7.1.0", - "@babel/types": "^7.1.2", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.6.2.tgz", + "integrity": "sha512-l8zto/fuoZIbncm+01p8zPSDZu/VuuJhAfA7d/AbzM09WR7iVhavvfNDYCNpo1VvLk6E6xgAoP9P+/EMJHuRkQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.5.5", + "@babel/generator": "^7.6.2", + "@babel/helpers": "^7.6.2", + "@babel/parser": "^7.6.2", + "@babel/template": "^7.6.0", + "@babel/traverse": "^7.6.2", + "@babel/types": "^7.6.0", "convert-source-map": "^1.1.0", - "debug": "^3.1.0", - "json5": "^0.5.0", - "lodash": "^4.17.10", + "debug": "^4.1.0", + "json5": "^2.1.0", + "lodash": "^4.17.13", "resolve": "^1.3.2", "semver": "^5.4.1", "source-map": "^0.5.0" }, "dependencies": { "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", "dev": true, "requires": { "ms": "^2.1.1" } }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -53,18 +65,23 @@ } }, "@babel/generator": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.1.3.tgz", - "integrity": "sha512-ZoCZGcfIJFJuZBqxcY9OjC1KW2lWK64qrX1o4UYL3yshVhwKFYgzpWZ0vvtGMNJdTlvkw0W+HR1VnYN8q3QPFQ==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.2.tgz", + "integrity": "sha512-j8iHaIW4gGPnViaIHI7e9t/Hl8qLjERI6DcV9kEpAIDJsAOrcnXqRS7t+QbhL76pwbtqP+QCQLL0z1CyVmtjjQ==", "dev": true, "requires": { - "@babel/types": "^7.1.3", + "@babel/types": "^7.6.0", "jsesc": "^2.5.1", - "lodash": "^4.17.10", - "source-map": "^0.5.0", - "trim-right": "^1.0.1" + "lodash": "^4.17.13", + "source-map": "^0.5.0" }, "dependencies": { + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "dev": true + }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -93,30 +110,36 @@ "@babel/types": "^7.0.0" } }, - "@babel/helper-split-export-declaration": { + "@babel/helper-plugin-utils": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0.tgz", - "integrity": "sha512-MXkOJqva62dfC0w85mEf/LucPPS/1+04nmmRMPEBUB++hiiThQ2zPtX/mEWQ3mtzCEjIJvPY8nuwxXtQeQwUag==", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz", + "integrity": "sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA==", + "dev": true + }, + "@babel/helper-split-export-declaration": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz", + "integrity": "sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q==", "dev": true, "requires": { - "@babel/types": "^7.0.0" + "@babel/types": "^7.4.4" } }, "@babel/helpers": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.1.2.tgz", - "integrity": "sha512-Myc3pUE8eswD73aWcartxB16K6CGmHDv9KxOmD2CeOs/FaEAQodr3VYGmlvOmog60vNQ2w8QbatuahepZwrHiA==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.6.2.tgz", + "integrity": "sha512-3/bAUL8zZxYs1cdX2ilEE0WobqbCmKWr/889lf2SS0PpDcpEIY8pb1CCyz0pEcX3pEb+MCbks1jIokz2xLtGTA==", "dev": true, "requires": { - "@babel/template": "^7.1.2", - "@babel/traverse": "^7.1.0", - "@babel/types": "^7.1.2" + "@babel/template": "^7.6.0", + "@babel/traverse": "^7.6.2", + "@babel/types": "^7.6.0" } }, "@babel/highlight": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", - "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", + "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==", "dev": true, "requires": { "chalk": "^2.0.0", @@ -125,141 +148,467 @@ } }, "@babel/parser": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.1.3.tgz", - "integrity": "sha512-gqmspPZOMW3MIRb9HlrnbZHXI1/KHTOroBwN1NcLL6pWxzqzEKGvRTq0W/PxS45OtQGbaFikSQpkS5zbnsQm2w==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.2.tgz", + "integrity": "sha512-mdFqWrSPCmikBoaBYMuBulzTIKuXVPtEISFbRRVNwMWpCms/hmE2kRq0bblUHaNRKrjRlmVbx1sDHmjmRgD2Xg==", "dev": true }, - "@babel/register": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.0.0.tgz", - "integrity": "sha512-f/+CRmaCe7rVEvcvPvxeA8j5aJhHC3aJie7YuqcMDhUOuyWLA7J/aNrTaHIzoWPEhpHA54mec4Mm8fv8KBlv3g==", + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.2.0.tgz", + "integrity": "sha512-t0JKGgqk2We+9may3t0xDdmneaXmyxq0xieYcKHxIsrJO64n1OiMWNUtc5gQK1PA0NpdCRrtZp4z+IUaKugrSA==", "dev": true, "requires": { - "core-js": "^2.5.7", - "find-cache-dir": "^1.0.0", - "home-or-tmp": "^3.0.0", - "lodash": "^4.17.10", - "mkdirp": "^0.5.1", - "pirates": "^4.0.0", - "source-map-support": "^0.5.9" - }, - "dependencies": { - "home-or-tmp": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-3.0.0.tgz", - "integrity": "sha1-V6j+JM8zzdUkhgoVgh3cJchmcfs=", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-support": { - "version": "0.5.9", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.9.tgz", - "integrity": "sha512-gR6Rw4MvUlYy83vP0vxoVNzM6t8MUXqNuRsuBmBHQDu1Fh6X015FrLdgoDKcNdkwGubozq0P4N0Q37UyFVr1EA==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - } + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/template": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.1.2.tgz", - "integrity": "sha512-SY1MmplssORfFiLDcOETrW7fCLl+PavlwMh92rrGcikQaRq4iWPVH0MpwPpY3etVMx6RnDjXtr6VZYr/IbP/Ag==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.6.0.tgz", + "integrity": "sha512-5AEH2EXD8euCk446b7edmgFdub/qfH1SN6Nii3+fyXP807QRx9Q73A2N5hNwRRslC2H9sNzaFhsPubkS4L8oNQ==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.1.2", - "@babel/types": "^7.1.2" + "@babel/parser": "^7.6.0", + "@babel/types": "^7.6.0" } }, "@babel/traverse": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.1.4.tgz", - "integrity": "sha512-my9mdrAIGdDiSVBuMjpn/oXYpva0/EZwWL3sm3Wcy/AVWO2eXnsoZruOT9jOGNRXU8KbCIu5zsKnXcAJ6PcV6Q==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.2.tgz", + "integrity": "sha512-8fRE76xNwNttVEF2TwxJDGBLWthUkHWSldmfuBzVRmEDWOtu4XdINTgN7TDWzuLg4bbeIMLvfMFD9we5YcWkRQ==", "dev": true, "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/generator": "^7.1.3", + "@babel/code-frame": "^7.5.5", + "@babel/generator": "^7.6.2", "@babel/helper-function-name": "^7.1.0", - "@babel/helper-split-export-declaration": "^7.0.0", - "@babel/parser": "^7.1.3", - "@babel/types": "^7.1.3", - "debug": "^3.1.0", + "@babel/helper-split-export-declaration": "^7.4.4", + "@babel/parser": "^7.6.2", + "@babel/types": "^7.6.0", + "debug": "^4.1.0", "globals": "^11.1.0", - "lodash": "^4.17.10" + "lodash": "^4.17.13" }, "dependencies": { "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", "dev": true, "requires": { "ms": "^2.1.1" } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true } } }, "@babel/types": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.1.3.tgz", - "integrity": "sha512-RpPOVfK+yatXyn8n4PB1NW6k9qjinrXrRR8ugBN8fD6hCy5RXI6PSbVqpOJBO9oSaY7Nom4ohj35feb0UR9hSA==", + "version": "7.6.1", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.1.tgz", + "integrity": "sha512-X7gdiuaCmA0uRjCmRtYJNAVCc/q+5xSgsfKJHqMN4iNLILX39677fJE1O40arPMh0TTtS9ItH67yre6c7k6t0g==", "dev": true, "requires": { "esutils": "^2.0.2", - "lodash": "^4.17.10", + "lodash": "^4.17.13", "to-fast-properties": "^2.0.0" + }, + "dependencies": { + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "dev": true + } + } + }, + "@cnakazawa/watch": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.3.tgz", + "integrity": "sha512-r5160ogAvGyHsal38Kux7YYtodEKOj89RGb28ht1jh3SJb08VwRwAKKJL0bGb04Zd/3r9FL3BFIc3bBidYffCA==", + "dev": true, + "requires": { + "exec-sh": "^0.3.2", + "minimist": "^1.2.0" + } + }, + "@jest/console": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.9.0.tgz", + "integrity": "sha512-Zuj6b8TnKXi3q4ymac8EQfc3ea/uhLeCGThFqXeC8H9/raaH8ARPUTdId+XyGd03Z4In0/VjD2OYFcBF09fNLQ==", + "dev": true, + "requires": { + "@jest/source-map": "^24.9.0", + "chalk": "^2.0.1", + "slash": "^2.0.0" + } + }, + "@jest/core": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-24.9.0.tgz", + "integrity": "sha512-Fogg3s4wlAr1VX7q+rhV9RVnUv5tD7VuWfYy1+whMiWUrvl7U3QJSJyWcDio9Lq2prqYsZaeTv2Rz24pWGkJ2A==", + "dev": true, + "requires": { + "@jest/console": "^24.7.1", + "@jest/reporters": "^24.9.0", + "@jest/test-result": "^24.9.0", + "@jest/transform": "^24.9.0", + "@jest/types": "^24.9.0", + "ansi-escapes": "^3.0.0", + "chalk": "^2.0.1", + "exit": "^0.1.2", + "graceful-fs": "^4.1.15", + "jest-changed-files": "^24.9.0", + "jest-config": "^24.9.0", + "jest-haste-map": "^24.9.0", + "jest-message-util": "^24.9.0", + "jest-regex-util": "^24.3.0", + "jest-resolve": "^24.9.0", + "jest-resolve-dependencies": "^24.9.0", + "jest-runner": "^24.9.0", + "jest-runtime": "^24.9.0", + "jest-snapshot": "^24.9.0", + "jest-util": "^24.9.0", + "jest-validate": "^24.9.0", + "jest-watcher": "^24.9.0", + "micromatch": "^3.1.10", + "p-each-series": "^1.0.0", + "realpath-native": "^1.1.0", + "rimraf": "^2.5.4", + "slash": "^2.0.0", + "strip-ansi": "^5.0.0" + }, + "dependencies": { + "ansi-escapes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", + "dev": true + }, + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "@jest/environment": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-24.9.0.tgz", + "integrity": "sha512-5A1QluTPhvdIPFYnO3sZC3smkNeXPVELz7ikPbhUj0bQjB07EoE9qtLrem14ZUYWdVayYbsjVwIiL4WBIMV4aQ==", + "dev": true, + "requires": { + "@jest/fake-timers": "^24.9.0", + "@jest/transform": "^24.9.0", + "@jest/types": "^24.9.0", + "jest-mock": "^24.9.0" + } + }, + "@jest/fake-timers": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-24.9.0.tgz", + "integrity": "sha512-eWQcNa2YSwzXWIMC5KufBh3oWRIijrQFROsIqt6v/NS9Io/gknw1jsAC9c+ih/RQX4A3O7SeWAhQeN0goKhT9A==", + "dev": true, + "requires": { + "@jest/types": "^24.9.0", + "jest-message-util": "^24.9.0", + "jest-mock": "^24.9.0" + } + }, + "@jest/reporters": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-24.9.0.tgz", + "integrity": "sha512-mu4X0yjaHrffOsWmVLzitKmmmWSQ3GGuefgNscUSWNiUNcEOSEQk9k3pERKEQVBb0Cnn88+UESIsZEMH3o88Gw==", + "dev": true, + "requires": { + "@jest/environment": "^24.9.0", + "@jest/test-result": "^24.9.0", + "@jest/transform": "^24.9.0", + "@jest/types": "^24.9.0", + "chalk": "^2.0.1", + "exit": "^0.1.2", + "glob": "^7.1.2", + "istanbul-lib-coverage": "^2.0.2", + "istanbul-lib-instrument": "^3.0.1", + "istanbul-lib-report": "^2.0.4", + "istanbul-lib-source-maps": "^3.0.1", + "istanbul-reports": "^2.2.6", + "jest-haste-map": "^24.9.0", + "jest-resolve": "^24.9.0", + "jest-runtime": "^24.9.0", + "jest-util": "^24.9.0", + "jest-worker": "^24.6.0", + "node-notifier": "^5.4.2", + "slash": "^2.0.0", + "source-map": "^0.6.0", + "string-length": "^2.0.0" + } + }, + "@jest/source-map": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-24.9.0.tgz", + "integrity": "sha512-/Xw7xGlsZb4MJzNDgB7PW5crou5JqWiBQaz6xyPd3ArOg2nfn/PunV8+olXbbEZzNl591o5rWKE9BRDaFAuIBg==", + "dev": true, + "requires": { + "callsites": "^3.0.0", + "graceful-fs": "^4.1.15", + "source-map": "^0.6.0" + } + }, + "@jest/test-result": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-24.9.0.tgz", + "integrity": "sha512-XEFrHbBonBJ8dGp2JmF8kP/nQI/ImPpygKHwQ/SY+es59Z3L5PI4Qb9TQQMAEeYsThG1xF0k6tmG0tIKATNiiA==", + "dev": true, + "requires": { + "@jest/console": "^24.9.0", + "@jest/types": "^24.9.0", + "@types/istanbul-lib-coverage": "^2.0.0" + } + }, + "@jest/test-sequencer": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-24.9.0.tgz", + "integrity": "sha512-6qqsU4o0kW1dvA95qfNog8v8gkRN9ph6Lz7r96IvZpHdNipP2cBcb07J1Z45mz/VIS01OHJ3pY8T5fUY38tg4A==", + "dev": true, + "requires": { + "@jest/test-result": "^24.9.0", + "jest-haste-map": "^24.9.0", + "jest-runner": "^24.9.0", + "jest-runtime": "^24.9.0" + } + }, + "@jest/transform": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-24.9.0.tgz", + "integrity": "sha512-TcQUmyNRxV94S0QpMOnZl0++6RMiqpbH/ZMccFB/amku6Uwvyb1cjYX7xkp5nGNkbX4QPH/FcB6q1HBTHynLmQ==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/types": "^24.9.0", + "babel-plugin-istanbul": "^5.1.0", + "chalk": "^2.0.1", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.1.15", + "jest-haste-map": "^24.9.0", + "jest-regex-util": "^24.9.0", + "jest-util": "^24.9.0", + "micromatch": "^3.1.10", + "pirates": "^4.0.1", + "realpath-native": "^1.1.0", + "slash": "^2.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "2.4.1" + } + }, + "@jest/types": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz", + "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^13.0.0" + } + }, + "@types/babel__core": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.3.tgz", + "integrity": "sha512-8fBo0UR2CcwWxeX7WIIgJ7lXjasFxoYgRnFHUj+hRvKkpiBJbxhdAPTCY6/ZKM0uxANFVzt4yObSLuTiTnazDA==", + "dev": true, + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "@types/babel__generator": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.0.tgz", + "integrity": "sha512-c1mZUu4up5cp9KROs/QAw0gTeHrw/x7m52LcnvMxxOZ03DmLwPV0MlGmlgzV3cnSdjhJOZsj7E7FHeioai+egw==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@types/babel__template": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.0.2.tgz", + "integrity": "sha512-/K6zCpeW7Imzgab2bLkLEbz0+1JlFSrUMdw7KoIIu+IUdu51GWaBZpd3y1VXGVXzynvGa4DaIaxNZHiON3GXUg==", + "dev": true, + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@types/babel__traverse": { + "version": "7.0.7", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.7.tgz", + "integrity": "sha512-CeBpmX1J8kWLcDEnI3Cl2Eo6RfbGvzUctA+CjZUhOKDFbLfcr7fc4usEqLNWetrlJd7RhAkyYe2czXop4fICpw==", + "dev": true, + "requires": { + "@babel/types": "^7.3.0" + } + }, + "@types/istanbul-lib-coverage": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", + "integrity": "sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==", + "dev": true + }, + "@types/istanbul-lib-report": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-1.1.1.tgz", + "integrity": "sha512-3BUTyMzbZa2DtDI2BkERNC6jJw2Mr2Y0oGI7mRxYNBPxppbtEK1F66u3bKwU2g+wxwWI7PAoRpJnOY1grJqzHg==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "*" + } + }, + "@types/istanbul-reports": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.1.tgz", + "integrity": "sha512-UpYjBi8xefVChsCoBpKShdxTllC9pwISirfoZsUa2AAdQg/Jd2KQGtSbw+ya7GPo7x/wAPlH6JBhKhAsXUEZNA==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, + "@types/jest": { + "version": "24.0.18", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-24.0.18.tgz", + "integrity": "sha512-jcDDXdjTcrQzdN06+TSVsPPqxvsZA/5QkYfIZlq1JMw7FdP5AZylbOc+6B/cuDurctRe+MziUMtQ3xQdrbjqyQ==", + "dev": true, + "requires": { + "@types/jest-diff": "*" + } + }, + "@types/jest-diff": { + "version": "20.0.1", + "resolved": "https://registry.npmjs.org/@types/jest-diff/-/jest-diff-20.0.1.tgz", + "integrity": "sha512-yALhelO3i0hqZwhjtcr6dYyaLoCHbAMshwtj6cGxTvHZAKXHsYGdff6E8EPw3xLKY0ELUTQ69Q1rQiJENnccMA==", + "dev": true + }, + "@types/jest-expect-message": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/jest-expect-message/-/jest-expect-message-1.0.0.tgz", + "integrity": "sha512-i94h9qffVHx3tHbpNtLx9+5URZ6DKODRNzQWf/Ow8MDfskWcuwClUXt+sFf0YaGiFVm8t+B5V9ugQaww+nT0EQ==", + "dev": true, + "requires": { + "@types/jest": "*" + } + }, + "@types/stack-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", + "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==", + "dev": true + }, + "@types/yargs": { + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.3.tgz", + "integrity": "sha512-K8/LfZq2duW33XW/tFwEAfnZlqIfVsoyRB3kfXdPXYhl0nfM8mmh7GS0jg7WrX2Dgq/0Ha/pR1PaR+BvmWwjiQ==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" } }, + "@types/yargs-parser": { + "version": "13.1.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-13.1.0.tgz", + "integrity": "sha512-gCubfBUZ6KxzoibJ+SCUc/57Ms1jz5NjHe4+dI2krNmU5zCPAphyLJYyTOg06ueIyfj+SaCUqmzun7ImlxDcKg==", + "dev": true + }, + "abab": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.2.tgz", + "integrity": "sha512-2scffjvioEmNz0OyDSLGWDfKCVwaKc6l9Pm9kOIREU13ClXZvHpg/nRL5xyjSSSLhOnXqft2HpsAzNEEA8cFFg==", + "dev": true + }, "acorn": { "version": "5.7.3", "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz", "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==", "dev": true }, - "acorn-jsx": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-4.1.1.tgz", - "integrity": "sha512-JY+iV6r+cO21KtntVvFkD+iqjtdpRUpGqKWgfkCdZq1R+kbreEl8EcdcJR4SmiIgsIQT33s6QzheQ9a275Q8xw==", + "acorn-globals": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz", + "integrity": "sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==", "dev": true, "requires": { - "acorn": "^5.0.3" + "acorn": "^6.0.1", + "acorn-walk": "^6.0.1" + }, + "dependencies": { + "acorn": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.3.0.tgz", + "integrity": "sha512-/czfa8BwS88b9gWQVhc8eknunSA2DoJpJyTQkhheIf5E48u1N0R4q/YxxsAeqRrmK9TQ/uYfgLDfZo91UlANIA==", + "dev": true + } } }, + "acorn-walk": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz", + "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==", + "dev": true + }, "ajv": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", - "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", + "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", "dev": true, "requires": { - "co": "^4.6.0", - "fast-deep-equal": "^1.0.0", + "fast-deep-equal": "^2.0.1", "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.3.0" + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" }, "dependencies": { "fast-deep-equal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", - "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", "dev": true } } }, - "ajv-keywords": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.2.0.tgz", - "integrity": "sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo=", - "dev": true - }, "ansi-escapes": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-2.0.0.tgz", @@ -282,14 +631,13 @@ } }, "anymatch": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", - "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", "dev": true, - "optional": true, "requires": { - "micromatch": "^2.1.5", - "normalize-path": "^2.0.0" + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" } }, "argparse": { @@ -302,14 +650,10 @@ } }, "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "dev": true, - "optional": true, - "requires": { - "arr-flatten": "^1.0.1" - } + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true }, "arr-flatten": { "version": "1.1.0", @@ -323,32 +667,16 @@ "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", "dev": true }, - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "^1.0.1" - } - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "array-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", + "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=", "dev": true }, "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", - "dev": true, - "optional": true - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", "dev": true }, "asn1": { @@ -366,24 +694,23 @@ "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", "dev": true }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true - }, "assign-symbols": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", "dev": true }, - "async-each": { + "astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "dev": true + }, + "async-limiter": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", - "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", - "dev": true, - "optional": true + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", + "dev": true }, "asynckit": { "version": "0.4.0", @@ -409,1268 +736,928 @@ "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", "dev": true }, - "babel-cli": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-cli/-/babel-cli-6.26.0.tgz", - "integrity": "sha1-UCq1SHTX24itALiHoGODzgPQAvE=", + "babel-jest": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-24.9.0.tgz", + "integrity": "sha512-ntuddfyiN+EhMw58PTNL1ph4C9rECiQXjI4nMMBKBaNjXvqLdkXpPRcMSr4iyBrJg/+wz9brFUD6RhOAT6r4Iw==", "dev": true, "requires": { - "babel-core": "^6.26.0", - "babel-polyfill": "^6.26.0", - "babel-register": "^6.26.0", - "babel-runtime": "^6.26.0", - "chokidar": "^1.6.1", - "commander": "^2.11.0", - "convert-source-map": "^1.5.0", - "fs-readdir-recursive": "^1.0.0", - "glob": "^7.1.2", - "lodash": "^4.17.4", - "output-file-sync": "^1.1.2", - "path-is-absolute": "^1.0.1", - "slash": "^1.0.0", - "source-map": "^0.5.6", - "v8flags": "^2.1.1" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } + "@jest/transform": "^24.9.0", + "@jest/types": "^24.9.0", + "@types/babel__core": "^7.1.0", + "babel-plugin-istanbul": "^5.1.0", + "babel-preset-jest": "^24.9.0", + "chalk": "^2.4.2", + "slash": "^2.0.0" } }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "babel-plugin-istanbul": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-5.2.0.tgz", + "integrity": "sha512-5LphC0USA8t4i1zCtjbbNb6jJj/9+X6P37Qfirc/70EQ34xKlMW+a1RHGwxGI+SwWpNwZ27HqvzAobeqaXwiZw==", "dev": true, "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } + "@babel/helper-plugin-utils": "^7.0.0", + "find-up": "^3.0.0", + "istanbul-lib-instrument": "^3.3.0", + "test-exclude": "^5.2.3" } }, - "babel-core": { - "version": "6.26.3", - "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.3.tgz", - "integrity": "sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==", - "dev": true, - "requires": { - "babel-code-frame": "^6.26.0", - "babel-generator": "^6.26.0", - "babel-helpers": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-register": "^6.26.0", - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "convert-source-map": "^1.5.1", - "debug": "^2.6.9", - "json5": "^0.5.1", - "lodash": "^4.17.4", - "minimatch": "^3.0.4", - "path-is-absolute": "^1.0.1", - "private": "^0.1.8", - "slash": "^1.0.0", - "source-map": "^0.5.7" + "babel-plugin-jest-hoist": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.9.0.tgz", + "integrity": "sha512-2EMA2P8Vp7lG0RAzr4HXqtYwacfMErOuv1U3wrvxHX6rD1sV6xS3WXG3r8TRQ2r6w8OhvSdWt+z41hQNwNm3Xw==", + "dev": true, + "requires": { + "@types/babel__traverse": "^7.0.6" + } + }, + "babel-preset-jest": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-24.9.0.tgz", + "integrity": "sha512-izTUuhE4TMfTRPF92fFwD2QfdXaZW08qvWTFCI51V8rW5x00UuPgc3ajRoWofXOuxjfcOM5zzSYsQS3H8KGCAg==", + "dev": true, + "requires": { + "@babel/plugin-syntax-object-rest-spread": "^7.0.0", + "babel-plugin-jest-hoist": "^24.9.0" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" }, "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, "requires": { - "ms": "2.0.0" + "is-descriptor": "^1.0.0" } }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } } } }, - "babel-eslint": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.0.1.tgz", - "integrity": "sha512-z7OT1iNV+TjOwHNLLyJk+HN+YVWX+CLE6fPD2SymJZOZQBs+QIexFjhm4keGTm8MW9xr4EC9Q0PbaLB24V5GoQ==", + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", "dev": true, "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.0.0", - "@babel/traverse": "^7.0.0", - "@babel/types": "^7.0.0", - "eslint-scope": "3.7.1", - "eslint-visitor-keys": "^1.0.0" + "tweetnacl": "^0.14.3" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" }, "dependencies": { - "eslint-scope": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz", - "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=", + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" + "is-extendable": "^0.1.0" } } } }, - "babel-generator": { - "version": "6.26.1", - "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz", - "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==", + "browser-process-hrtime": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-0.1.3.tgz", + "integrity": "sha512-bRFnI4NnjO6cnyLmOV/7PVoDEMJChlcfN0z4s1YMBY989/SvlfMI1lgCnkFUs53e9gQF+w7qu7XdllSTiSl8Aw==", + "dev": true + }, + "browser-resolve": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.3.tgz", + "integrity": "sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==", "dev": true, "requires": { - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "detect-indent": "^4.0.0", - "jsesc": "^1.3.0", - "lodash": "^4.17.4", - "source-map": "^0.5.7", - "trim-right": "^1.0.1" + "resolve": "1.1.7" }, "dependencies": { - "jsesc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", - "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", - "dev": true - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", "dev": true } } }, - "babel-helper-builder-binary-assignment-operator-visitor": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz", - "integrity": "sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=", - "dev": true, - "requires": { - "babel-helper-explode-assignable-expression": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-helper-call-delegate": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz", - "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=", + "bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", "dev": true, "requires": { - "babel-helper-hoist-variables": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "fast-json-stable-stringify": "2.x" } }, - "babel-helper-define-map": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz", - "integrity": "sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8=", + "bser": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.0.tgz", + "integrity": "sha512-8zsjWrQkkBoLK6uxASk1nJ2SKv97ltiGDo6A3wA0/yRPz+CwmEyDo0hUrhIuukG2JHpAl3bvFIixw2/3Hi0DOg==", "dev": true, "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" + "node-int64": "^0.4.0" } }, - "babel-helper-explode-assignable-expression": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz", - "integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true }, - "babel-helper-function-name": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz", - "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=", - "dev": true, - "requires": { - "babel-helper-get-function-arity": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "dev": true }, - "babel-helper-get-function-arity": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz", - "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=", + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" } }, - "babel-helper-hoist-variables": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz", - "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true }, - "babel-helper-optimise-call-expression": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz", - "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true }, - "babel-helper-regex": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz", - "integrity": "sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI=", + "capture-exit": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz", + "integrity": "sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==", "dev": true, "requires": { - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" + "rsvp": "^4.8.4" } }, - "babel-helper-remap-async-to-generator": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz", - "integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=", - "dev": true, - "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true }, - "babel-helper-replace-supers": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz", - "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=", + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { - "babel-helper-optimise-call-expression": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" } }, - "babel-helpers": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", - "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true }, - "babel-messages": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", - "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } } }, - "babel-plugin-add-module-exports": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/babel-plugin-add-module-exports/-/babel-plugin-add-module-exports-1.0.0.tgz", - "integrity": "sha512-m0sMxPL4FaN2K69GQgaRJa4Ny15qKSdoknIcpN+gz+NaJlAW9pge/povs13tPYsKDboflrEQC+/3kfIsONBTaw==", + "cli-autocomplete": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/cli-autocomplete/-/cli-autocomplete-0.4.1.tgz", + "integrity": "sha512-a77WGCjFwfzAp48vPeqHCejqW+BkHobTsxFktmZDc5Y8Hq+CKEH92SFU00Qc6xy/JqQLiv1ubt4zE6tn7w/eDQ==", "dev": true, "requires": { - "chokidar": "^2.0.4" + "ansi-escapes": "^2.0.0", + "chalk": "^1.1.1", + "cli-styles": "^0.6.2", + "prompt-skeleton": "^0.4.0", + "so": "^1.0.1", + "strip-ansi": "^3.0.1" }, "dependencies": { - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "optional": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true, - "optional": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", "dev": true }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "chokidar": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz", - "integrity": "sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==", + "chalk": { + "version": "1.1.3", + "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, - "optional": true, "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.0", - "braces": "^2.3.0", - "fsevents": "^1.2.2", - "glob-parent": "^3.1.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "lodash.debounce": "^4.0.8", - "normalize-path": "^2.1.1", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0", - "upath": "^1.0.5" + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" } }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "optional": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "optional": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "optional": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "optional": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "optional": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "optional": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "optional": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "optional": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "optional": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true, - "optional": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "optional": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "optional": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "optional": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "optional": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "optional": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "optional": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "optional": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "optional": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", "dev": true - }, - "is-glob": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", - "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", - "dev": true, - "optional": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + } + } + }, + "cli-styles": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/cli-styles/-/cli-styles-0.6.2.tgz", + "integrity": "sha512-6U6UYJlsx6Ok53PKioqDui23OrJoCKUFWLxEP8nxRSWMZnZ9zSXuNa+f13Nfl+PsTKM651uj7WPEYmpINJUuIQ==", + "dev": true, + "requires": { + "ansi-escapes": "^1.4.0", + "chalk": "^1.1.3", + "figures": "^2", + "line-count": "^0.1.0", + "split-lines": "^1.1.0", + "string-width": "^2.0.0", + "window-size": "^0.3.0" + }, + "dependencies": { + "ansi-escapes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", + "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", "dev": true }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", "dev": true }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "chalk": { + "version": "1.1.3", + "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, - "optional": true, "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" } }, - "ms": { + "supports-color": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true, - "optional": true + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true } } }, - "babel-plugin-check-es2015-constants": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz", - "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-istanbul": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-5.1.0.tgz", - "integrity": "sha512-CLoXPRSUWiR8yao8bShqZUIC6qLfZVVY3X1wj+QPNXu0wfmrRRfarh1LYy+dYMVI+bDj0ghy3tuqFFRFZmL1Nw==", + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", "dev": true, "requires": { - "find-up": "^3.0.0", - "istanbul-lib-instrument": "^3.0.0", - "test-exclude": "^5.0.0" + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" }, "dependencies": { - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true }, - "p-limit": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.0.0.tgz", - "integrity": "sha512-fl5s52lI5ahKCernzzIyAP0QAZbGIovtVHGwpcu1Jr/EpzLVDI2myISHwGqK7m8uQFugVWSrbxH7XnhGtvEc+A==", + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", "dev": true, "requires": { - "p-try": "^2.0.0" + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" } }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "dev": true, "requires": { - "p-limit": "^2.0.0" + "ansi-regex": "^4.1.0" } - }, - "p-try": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz", - "integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true } } }, - "babel-plugin-syntax-async-functions": { - "version": "6.13.0", - "resolved": "http://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz", - "integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=", - "dev": true - }, - "babel-plugin-syntax-exponentiation-operator": { - "version": "6.13.0", - "resolved": "http://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz", - "integrity": "sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=", - "dev": true - }, - "babel-plugin-syntax-trailing-function-commas": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz", - "integrity": "sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM=", + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", "dev": true }, - "babel-plugin-transform-async-to-generator": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz", - "integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=", + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", "dev": true, "requires": { - "babel-helper-remap-async-to-generator": "^6.24.1", - "babel-plugin-syntax-async-functions": "^6.8.0", - "babel-runtime": "^6.22.0" + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" } }, - "babel-plugin-transform-es2015-arrow-functions": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz", - "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=", + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "color-name": "1.1.3" } }, - "babel-plugin-transform-es2015-block-scoped-functions": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz", - "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true }, - "babel-plugin-transform-es2015-block-scoping": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz", - "integrity": "sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=", + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "dev": true, "requires": { - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" + "delayed-stream": "~1.0.0" } }, - "babel-plugin-transform-es2015-classes": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz", - "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=", - "dev": true, - "requires": { - "babel-helper-define-map": "^6.24.1", - "babel-helper-function-name": "^6.24.1", - "babel-helper-optimise-call-expression": "^6.24.1", - "babel-helper-replace-supers": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } + "commander": { + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", + "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==", + "dev": true }, - "babel-plugin-transform-es2015-computed-properties": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz", - "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } + "component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "dev": true }, - "babel-plugin-transform-es2015-destructuring": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz", - "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true }, - "babel-plugin-transform-es2015-duplicate-keys": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz", - "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=", + "convert-source-map": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz", + "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "safe-buffer": "~5.1.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + } } }, - "babel-plugin-transform-es2015-for-of": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz", - "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true }, - "babel-plugin-transform-es2015-function-name": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz", - "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=", - "dev": true, - "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true }, - "babel-plugin-transform-es2015-literals": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz", - "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=", + "coveralls": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.0.6.tgz", + "integrity": "sha512-Pgh4v3gCI4T/9VijVrm8Ym5v0OgjvGLKj3zTUwkvsCiwqae/p6VLzpsFNjQS2i6ewV7ef+DjFJ5TSKxYt/mCrA==", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "growl": "~> 1.10.0", + "js-yaml": "^3.13.1", + "lcov-parse": "^0.0.10", + "log-driver": "^1.2.7", + "minimist": "^1.2.0", + "request": "^2.86.0" } }, - "babel-plugin-transform-es2015-modules-amd": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz", - "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=", + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", "dev": true, "requires": { - "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" } }, - "babel-plugin-transform-es2015-modules-commonjs": { - "version": "6.26.2", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz", - "integrity": "sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==", - "dev": true, - "requires": { - "babel-plugin-transform-strict-mode": "^6.24.1", - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-types": "^6.26.0" - } + "cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "dev": true }, - "babel-plugin-transform-es2015-modules-systemjs": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz", - "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=", + "cssstyle": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.4.0.tgz", + "integrity": "sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA==", "dev": true, "requires": { - "babel-helper-hoist-variables": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "cssom": "0.3.x" } }, - "babel-plugin-transform-es2015-modules-umd": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz", - "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=", + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", "dev": true, "requires": { - "babel-plugin-transform-es2015-modules-amd": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "assert-plus": "^1.0.0" } }, - "babel-plugin-transform-es2015-object-super": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz", - "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=", + "data-urls": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz", + "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==", "dev": true, "requires": { - "babel-helper-replace-supers": "^6.24.1", - "babel-runtime": "^6.22.0" + "abab": "^2.0.0", + "whatwg-mimetype": "^2.2.0", + "whatwg-url": "^7.0.0" + }, + "dependencies": { + "whatwg-url": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.0.0.tgz", + "integrity": "sha512-37GeVSIJ3kn1JgKyjiYNmSLP1yzbpb29jdmwBSgkD9h40/hyrR/OifpVUndji3tmwGgD8qpw7iQu3RSbCrBpsQ==", + "dev": true, + "requires": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + } } }, - "babel-plugin-transform-es2015-parameters": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz", - "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=", - "dev": true, - "requires": { - "babel-helper-call-delegate": "^6.24.1", - "babel-helper-get-function-arity": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } + "date-fns": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.4.0.tgz", + "integrity": "sha512-xS547fK1omgCgOGbyU0fBY2pdeXQ9/WO/PMsVgX1jtF56dXNHrV3Z+GKWIOE7IG+UEeu+fTyTlnIvBKbxXxdSw==" }, - "babel-plugin-transform-es2015-shorthand-properties": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz", - "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=", + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "ms": "2.0.0" } }, - "babel-plugin-transform-es2015-spread": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz", - "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=", + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "object-keys": "^1.0.12" } }, - "babel-plugin-transform-es2015-sticky-regex": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz", - "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=", + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", "dev": true, "requires": { - "babel-helper-regex": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } } }, - "babel-plugin-transform-es2015-template-literals": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz", - "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=", + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true + }, + "detect-newline": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz", + "integrity": "sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I=", + "dev": true + }, + "diff": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.1.tgz", + "integrity": "sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q==", + "dev": true + }, + "diff-sequences": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-24.9.0.tgz", + "integrity": "sha512-Dj6Wk3tWyTE+Fo1rW8v0Xhwk80um6yFYKbuAxc9c3EZxIHFDYwbi34Uk42u1CdnIiVorvt4RmlSDjIPyzGC2ew==", + "dev": true + }, + "domexception": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz", + "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "webidl-conversions": "^4.0.2" } }, - "babel-plugin-transform-es2015-typeof-symbol": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz", - "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=", + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" } }, - "babel-plugin-transform-es2015-unicode-regex": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz", - "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=", + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", "dev": true, "requires": { - "babel-helper-regex": "^6.24.1", - "babel-runtime": "^6.22.0", - "regexpu-core": "^2.0.0" + "once": "^1.4.0" } }, - "babel-plugin-transform-exponentiation-operator": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz", - "integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=", + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "dev": true, "requires": { - "babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1", - "babel-plugin-syntax-exponentiation-operator": "^6.8.0", - "babel-runtime": "^6.22.0" + "is-arrayish": "^0.2.1" } }, - "babel-plugin-transform-regenerator": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz", - "integrity": "sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8=", + "es-abstract": { + "version": "1.14.2", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.14.2.tgz", + "integrity": "sha512-DgoQmbpFNOofkjJtKwr87Ma5EW4Dc8fWhD0R+ndq7Oc456ivUfGOOP6oAZTTKl5/CcNMP+EN+e3/iUzgE0veZg==", "dev": true, "requires": { - "regenerator-transform": "^0.10.0" + "es-to-primitive": "^1.2.0", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.0", + "is-callable": "^1.1.4", + "is-regex": "^1.0.4", + "object-inspect": "^1.6.0", + "object-keys": "^1.1.1", + "string.prototype.trimleft": "^2.0.0", + "string.prototype.trimright": "^2.0.0" } }, - "babel-plugin-transform-strict-mode": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz", - "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=", + "es-to-primitive": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", + "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" } }, - "babel-polyfill": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz", - "integrity": "sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=", + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "escodegen": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.12.0.tgz", + "integrity": "sha512-TuA+EhsanGcme5T3R0L80u4t8CpbXQjegRmf7+FPTJrtCTErXFeelblRgHQa1FofEzqYYJmJ/OqjTwREp9qgmg==", "dev": true, "requires": { - "babel-runtime": "^6.26.0", - "core-js": "^2.5.0", - "regenerator-runtime": "^0.10.5" + "esprima": "^3.1.3", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" }, "dependencies": { - "regenerator-runtime": { - "version": "0.10.5", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", - "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=", + "esprima": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", + "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", "dev": true } } }, - "babel-preset-env": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.7.0.tgz", - "integrity": "sha512-9OR2afuKDneX2/q2EurSftUYM0xGu4O2D9adAhVfADDhrYDaxXV0rBbevVYoY9n6nyX1PmQW/0jtpJvUNr9CHg==", - "dev": true, - "requires": { - "babel-plugin-check-es2015-constants": "^6.22.0", - "babel-plugin-syntax-trailing-function-commas": "^6.22.0", - "babel-plugin-transform-async-to-generator": "^6.22.0", - "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoping": "^6.23.0", - "babel-plugin-transform-es2015-classes": "^6.23.0", - "babel-plugin-transform-es2015-computed-properties": "^6.22.0", - "babel-plugin-transform-es2015-destructuring": "^6.23.0", - "babel-plugin-transform-es2015-duplicate-keys": "^6.22.0", - "babel-plugin-transform-es2015-for-of": "^6.23.0", - "babel-plugin-transform-es2015-function-name": "^6.22.0", - "babel-plugin-transform-es2015-literals": "^6.22.0", - "babel-plugin-transform-es2015-modules-amd": "^6.22.0", - "babel-plugin-transform-es2015-modules-commonjs": "^6.23.0", - "babel-plugin-transform-es2015-modules-systemjs": "^6.23.0", - "babel-plugin-transform-es2015-modules-umd": "^6.23.0", - "babel-plugin-transform-es2015-object-super": "^6.22.0", - "babel-plugin-transform-es2015-parameters": "^6.23.0", - "babel-plugin-transform-es2015-shorthand-properties": "^6.22.0", - "babel-plugin-transform-es2015-spread": "^6.22.0", - "babel-plugin-transform-es2015-sticky-regex": "^6.22.0", - "babel-plugin-transform-es2015-template-literals": "^6.22.0", - "babel-plugin-transform-es2015-typeof-symbol": "^6.23.0", - "babel-plugin-transform-es2015-unicode-regex": "^6.22.0", - "babel-plugin-transform-exponentiation-operator": "^6.22.0", - "babel-plugin-transform-regenerator": "^6.22.0", - "browserslist": "^3.2.6", - "invariant": "^2.2.2", - "semver": "^5.3.0" - } - }, - "babel-register": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz", - "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=", - "dev": true, - "requires": { - "babel-core": "^6.26.0", - "babel-runtime": "^6.26.0", - "core-js": "^2.5.0", - "home-or-tmp": "^2.0.0", - "lodash": "^4.17.4", - "mkdirp": "^0.5.1", - "source-map-support": "^0.4.15" - } + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "dev": true, - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - } + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "exec-sh": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.2.tgz", + "integrity": "sha512-9sLAvzhI5nc8TpuQUh4ahMdCrWT00wPWz7j47/emR5+2qEfoZP5zzUXvx+vdx+H6ohhnsYC31iX04QLYJK8zTg==", + "dev": true }, - "babel-template": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", - "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", "dev": true, "requires": { - "babel-runtime": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "lodash": "^4.17.4" + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" } }, - "babel-traverse": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", - "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "dev": true + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", "dev": true, "requires": { - "babel-code-frame": "^6.26.0", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "debug": "^2.6.8", - "globals": "^9.18.0", - "invariant": "^2.2.2", - "lodash": "^4.17.4" + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" }, "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { - "ms": "2.0.0" + "is-descriptor": "^0.1.0" } }, - "globals": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", - "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", - "dev": true - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } } } }, - "babel-types": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", - "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", + "expect": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-24.9.0.tgz", + "integrity": "sha512-wvVAx8XIol3Z5m9zvZXiyZOQ+sRJqNTIm6sGjdWlaZIeupQGO3WbYI+15D/AmEwZywL6wtJkbAbJtzkOfBuR0Q==", "dev": true, "requires": { - "babel-runtime": "^6.26.0", - "esutils": "^2.0.2", - "lodash": "^4.17.4", - "to-fast-properties": "^1.0.3" - }, - "dependencies": { - "to-fast-properties": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", - "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", - "dev": true - } + "@jest/types": "^24.9.0", + "ansi-styles": "^3.2.0", + "jest-get-type": "^24.9.0", + "jest-matcher-utils": "^24.9.0", + "jest-message-util": "^24.9.0", + "jest-regex-util": "^24.9.0" } }, - "babylon": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", - "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", "dev": true }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", "dev": true, "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", + "array-unique": "^0.3.2", "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" }, "dependencies": { "define-property": { @@ -1682,6 +1669,15 @@ "is-descriptor": "^1.0.0" } }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, "is-accessor-descriptor": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", @@ -1710,1727 +1706,670 @@ "is-data-descriptor": "^1.0.0", "kind-of": "^6.0.2" } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true } } }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "dev": true, - "optional": true, - "requires": { - "tweetnacl": "^0.14.3" - } + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true }, - "binary-extensions": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.12.0.tgz", - "integrity": "sha512-DYWGk01lDcxeS/K9IHPGWfT8PsJmbXRtRd2Sx72Tnb8pcYZQFF1oSDb8hJtS1vhp212q1Rzi5dUf9+nq0o9UIg==", - "dev": true, - "optional": true + "fast-clone": { + "version": "1.5.13", + "resolved": "https://registry.npmjs.org/fast-clone/-/fast-clone-1.5.13.tgz", + "integrity": "sha512-0ez7coyFBQFjZtId+RJqJ+EQs61w9xARfqjqK0AD9vIUkSxWD4HvPt80+5evebZ1tTnv1GYKrPTipx7kOW5ipA==" }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } + "fast-deep-equal": { + "version": "3.0.0-beta.2", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.0.0-beta.2.tgz", + "integrity": "sha512-/1ttQLbtYMjR0n+pR0dIuYELUJ4QMhT7sqatQBY+ux4snfkGS9gG/bDQq7i94IeNn3XUO2sVw5/EuxKzFEHWGw==" }, - "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", - "dev": true, - "optional": true, - "requires": { - "expand-range": "^1.8.1", - "preserve": "^0.2.0", - "repeat-element": "^1.1.2" - } + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", + "dev": true }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true }, - "browserslist": { - "version": "3.2.8", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-3.2.8.tgz", - "integrity": "sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ==", + "fb-watchman": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.0.tgz", + "integrity": "sha1-VOmr99+i8mzZsWNsWIwa/AXeXVg=", "dev": true, "requires": { - "caniuse-lite": "^1.0.30000844", - "electron-to-chromium": "^1.3.47" + "bser": "^2.0.0" } }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", "dev": true, "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" }, "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } } } }, - "caller-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", - "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", "dev": true, "requires": { - "callsites": "^0.2.0" + "locate-path": "^3.0.0" } }, - "callsites": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", - "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", - "dev": true - }, - "caniuse-lite": { - "version": "1.0.30000892", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000892.tgz", - "integrity": "sha512-X9rxMaWZNbJB5qjkDqPtNv/yfViTeUL6ILk0QJNxLV3OhKC5Acn5vxsuUvllR6B48mog8lmS+whwHq/QIYSL9w==", + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", "dev": true }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", "dev": true }, - "chai": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", - "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", - "dev": true, - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "pathval": "^1.1.0", - "type-detect": "^4.0.5" - } - }, - "chai-as-promised": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-7.1.1.tgz", - "integrity": "sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA==", + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", "dev": true, "requires": { - "check-error": "^1.0.2" + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" } }, - "chalk": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", "dev": true, "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "map-cache": "^0.2.2" } }, - "chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true - }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, - "chokidar": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", - "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", + "fsevents": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", + "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", "dev": true, "optional": true, "requires": { - "anymatch": "^1.3.0", - "async-each": "^1.0.0", - "fsevents": "^1.0.0", - "glob-parent": "^2.0.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^2.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0" - } - }, - "circular-json": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", - "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", - "dev": true - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" + "nan": "^2.12.1", + "node-pre-gyp": "^0.12.0" }, "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "abbrev": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "aproba": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.5", + "bundled": true, "dev": true, + "optional": true, "requires": { - "is-descriptor": "^0.1.0" + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" } }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "cli-autocomplete": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/cli-autocomplete/-/cli-autocomplete-0.4.1.tgz", - "integrity": "sha512-a77WGCjFwfzAp48vPeqHCejqW+BkHobTsxFktmZDc5Y8Hq+CKEH92SFU00Qc6xy/JqQLiv1ubt4zE6tn7w/eDQ==", - "dev": true, - "requires": { - "ansi-escapes": "^2.0.0", - "chalk": "^1.1.1", - "cli-styles": "^0.6.2", - "prompt-skeleton": "^0.4.0", - "so": "^1.0.1", - "strip-ansi": "^3.0.1" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true }, - "chalk": { - "version": "1.1.3", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "brace-expansion": { + "version": "1.1.11", + "bundled": true, "dev": true, + "optional": true, "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", - "dev": true, - "requires": { - "restore-cursor": "^2.0.0" - } - }, - "cli-styles": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/cli-styles/-/cli-styles-0.6.2.tgz", - "integrity": "sha512-6U6UYJlsx6Ok53PKioqDui23OrJoCKUFWLxEP8nxRSWMZnZ9zSXuNa+f13Nfl+PsTKM651uj7WPEYmpINJUuIQ==", - "dev": true, - "requires": { - "ansi-escapes": "^1.4.0", - "chalk": "^1.1.3", - "figures": "^2", - "line-count": "^0.1.0", - "split-lines": "^1.1.0", - "string-width": "^2.0.0", - "window-size": "^0.3.0" - }, - "dependencies": { - "ansi-escapes": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", - "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true + "chownr": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true }, - "chalk": { - "version": "1.1.3", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "code-point-at": { + "version": "1.1.0", + "bundled": true, "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } + "optional": true }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "cli-width": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", - "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", - "dev": true - }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", - "dev": true - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "combined-stream": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", - "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", - "dev": true, - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "2.15.1", - "resolved": "http://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", - "dev": true - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true - }, - "component-emitter": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", - "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "contains-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", - "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", - "dev": true - }, - "convert-source-map": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz", - "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.1" - } - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true - }, - "core-js": { - "version": "2.5.7", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz", - "integrity": "sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw==", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true - }, - "coveralls": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.0.2.tgz", - "integrity": "sha512-Tv0LKe/MkBOilH2v7WBiTBdudg2ChfGbdXafc/s330djpF3zKOmuehTeRwjXWc7pzfj9FrDUTA7tEx6Div8NFw==", - "dev": true, - "requires": { - "growl": "~> 1.10.0", - "js-yaml": "^3.11.0", - "lcov-parse": "^0.0.10", - "log-driver": "^1.2.7", - "minimist": "^1.2.0", - "request": "^2.85.0" - }, - "dependencies": { - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true, + "optional": true }, - "js-yaml": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz", - "integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==", + "console-control-strings": { + "version": "1.1.0", + "bundled": true, "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - } - } - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "date-fns": { - "version": "2.0.0-alpha.22", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.0.0-alpha.22.tgz", - "integrity": "sha512-ovlz0I0OFhyn9bgTfqFAUvJvo8VS9mUuOxZ6cwKwBjSx42lMpXPGolcINYZoTNAG2M4YJ3QoApiQQljQEuy/Uw==" - }, - "debug": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.0.1.tgz", - "integrity": "sha512-K23FHJ/Mt404FSlp6gSZCevIbTMLX0j3fmHhUEhQ3Wq0FMODW3+cUSoLdy1Gx4polAf4t/lphhmHH35BB8cLYw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true - }, - "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, - "requires": { - "type-detect": "^4.0.0" - } - }, - "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true - }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "optional": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, "dev": true, + "optional": true + }, + "debug": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true, "requires": { - "kind-of": "^6.0.0" + "ms": "^2.1.1" } }, - "is-data-descriptor": { + "deep-extend": { + "version": "0.6.0", + "bundled": true, + "dev": true, + "optional": true + }, + "delegates": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "bundled": true, "dev": true, - "requires": { - "kind-of": "^6.0.0" - } + "optional": true }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "detect-libc": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "fs-minipass": { + "version": "1.2.5", + "bundled": true, "dev": true, + "optional": true, "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" + "minipass": "^2.2.1" } }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - } - } - }, - "del": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", - "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", - "dev": true, - "requires": { - "globby": "^5.0.0", - "is-path-cwd": "^1.0.0", - "is-path-in-cwd": "^1.0.0", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "rimraf": "^2.2.8" - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true - }, - "detect-indent": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", - "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", - "dev": true, - "requires": { - "repeating": "^2.0.0" - } - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "dev": true, - "optional": true, - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "electron-to-chromium": { - "version": "1.3.79", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.79.tgz", - "integrity": "sha512-LQdY3j4PxuUl6xfxiFruTSlCniTrTrzAd8/HfsLEMi0PUpaQ0Iy+Pr4N4VllDYjs0Hyu2lkTbvzqlG+PX9NsNw==", - "dev": true - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "eslint": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.6.1.tgz", - "integrity": "sha512-hgrDtGWz368b7Wqf+v1Z69O3ZebNR0+GA7PtDdbmuz4rInFVUV9uw7whjZEiWyLzCjVb5Rs5WRN1TAS6eo7AYA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "ajv": "^6.5.3", - "chalk": "^2.1.0", - "cross-spawn": "^6.0.5", - "debug": "^4.0.1", - "doctrine": "^2.1.0", - "eslint-scope": "^4.0.0", - "eslint-utils": "^1.3.1", - "eslint-visitor-keys": "^1.0.0", - "espree": "^4.0.0", - "esquery": "^1.0.1", - "esutils": "^2.0.2", - "file-entry-cache": "^2.0.0", - "functional-red-black-tree": "^1.0.1", - "glob": "^7.1.2", - "globals": "^11.7.0", - "ignore": "^4.0.6", - "imurmurhash": "^0.1.4", - "inquirer": "^6.1.0", - "is-resolvable": "^1.1.0", - "js-yaml": "^3.12.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.5", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", - "natural-compare": "^1.4.0", - "optionator": "^0.8.2", - "path-is-inside": "^1.0.2", - "pluralize": "^7.0.0", - "progress": "^2.0.0", - "regexpp": "^2.0.0", - "require-uncached": "^1.0.3", - "semver": "^5.5.1", - "strip-ansi": "^4.0.0", - "strip-json-comments": "^2.0.1", - "table": "^4.0.3", - "text-table": "^0.2.0" - }, - "dependencies": { - "ajv": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.4.tgz", - "integrity": "sha512-4Wyjt8+t6YszqaXnLDfMmG/8AlO5Zbcsy3ATHncCzjW/NoPzAId8AK6749Ybjmdt+kUY1gP60fCu46oDxPv/mg==", + "gauge": { + "version": "2.7.4", + "bundled": true, "dev": true, + "optional": true, "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" } }, - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true + "glob": { + "version": "7.1.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } }, - "fast-deep-equal": { + "has-unicode": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", - "dev": true + "bundled": true, + "dev": true, + "optional": true }, - "js-yaml": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz", - "integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==", + "iconv-lite": { + "version": "0.4.24", + "bundled": true, "dev": true, + "optional": true, "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "safer-buffer": ">= 2.1.2 < 3" } }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "ignore-walk": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimatch": "^3.0.4" + } }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "inflight": { + "version": "1.0.6", + "bundled": true, "dev": true, + "optional": true, "requires": { - "ansi-regex": "^3.0.0" + "once": "^1.3.0", + "wrappy": "1" } - } - } - }, - "eslint-import-resolver-node": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz", - "integrity": "sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q==", - "dev": true, - "requires": { - "debug": "^2.6.9", - "resolve": "^1.5.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "ini": { + "version": "1.3.5", + "bundled": true, + "dev": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, "dev": true, + "optional": true, "requires": { - "ms": "2.0.0" + "number-is-nan": "^1.0.0" } }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "eslint-module-utils": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.2.0.tgz", - "integrity": "sha1-snA2LNiLGkitMIl2zn+lTphBF0Y=", - "dev": true, - "requires": { - "debug": "^2.6.8", - "pkg-dir": "^1.0.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "isarray": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, "dev": true, + "optional": true, "requires": { - "ms": "2.0.0" + "brace-expansion": "^1.1.7" } }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "eslint-plugin-es": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-1.3.1.tgz", - "integrity": "sha512-9XcVyZiQRVeFjqHw8qHNDAZcQLqaHlOGGpeYqzYh8S4JYCWTCO3yzyen8yVmA5PratfzTRWDwCOFphtDEG+w/w==", - "dev": true, - "requires": { - "eslint-utils": "^1.3.0", - "regexpp": "^2.0.0" - } - }, - "eslint-plugin-import": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.14.0.tgz", - "integrity": "sha512-FpuRtniD/AY6sXByma2Wr0TXvXJ4nA/2/04VPlfpmUDPOpOY264x+ILiwnrk/k4RINgDAyFZByxqPUbSQ5YE7g==", - "dev": true, - "requires": { - "contains-path": "^0.1.0", - "debug": "^2.6.8", - "doctrine": "1.5.0", - "eslint-import-resolver-node": "^0.3.1", - "eslint-module-utils": "^2.2.0", - "has": "^1.0.1", - "lodash": "^4.17.4", - "minimatch": "^3.0.3", - "read-pkg-up": "^2.0.0", - "resolve": "^1.6.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true, + "optional": true + }, + "minipass": { + "version": "2.3.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.2.1", + "bundled": true, "dev": true, + "optional": true, "requires": { - "ms": "2.0.0" + "minipass": "^2.2.1" } }, - "doctrine": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", - "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "mkdirp": { + "version": "0.5.1", + "bundled": true, "dev": true, + "optional": true, "requires": { - "esutils": "^2.0.2", - "isarray": "^1.0.0" + "minimist": "0.0.8" } }, "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "eslint-plugin-node": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-7.0.1.tgz", - "integrity": "sha512-lfVw3TEqThwq0j2Ba/Ckn2ABdwmL5dkOgAux1rvOk6CO7A6yGyPI2+zIxN6FyNkp1X1X/BSvKOceD6mBWSj4Yw==", - "dev": true, - "requires": { - "eslint-plugin-es": "^1.3.1", - "eslint-utils": "^1.3.1", - "ignore": "^4.0.2", - "minimatch": "^3.0.4", - "resolve": "^1.8.1", - "semver": "^5.5.0" - } - }, - "eslint-scope": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.0.tgz", - "integrity": "sha512-1G6UTDi7Jc1ELFwnR58HV4fK9OQK4S6N985f166xqXxpjU6plxFISJa2Ba9KCQuFa8RCnj/lSFJbHo7UFDBnUA==", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "eslint-utils": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.3.1.tgz", - "integrity": "sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q==", - "dev": true - }, - "eslint-visitor-keys": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", - "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==", - "dev": true - }, - "espree": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-4.0.0.tgz", - "integrity": "sha512-kapdTCt1bjmspxStVKX6huolXVV5ZfyZguY1lcfhVVZstce3bqxH9mcLzNn3/mlgW6wQ732+0fuG9v7h0ZQoKg==", - "dev": true, - "requires": { - "acorn": "^5.6.0", - "acorn-jsx": "^4.1.1" - } - }, - "esquery": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", - "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", - "dev": true, - "requires": { - "estraverse": "^4.0.0" - } - }, - "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", - "dev": true, - "requires": { - "estraverse": "^4.1.0" - } - }, - "estraverse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", - "dev": true - }, - "esutils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", - "dev": true - }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", - "dev": true, - "optional": true, - "requires": { - "is-posix-bracket": "^0.1.0" - } - }, - "expand-range": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", - "dev": true, - "optional": true, - "requires": { - "fill-range": "^2.1.0" - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "version": "2.1.1", + "bundled": true, "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "external-editor": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.0.3.tgz", - "integrity": "sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA==", - "dev": true, - "requires": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - } - }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", - "dev": true, - "optional": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "dev": true - }, - "fast-clone": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/fast-clone/-/fast-clone-1.5.3.tgz", - "integrity": "sha512-o+FDnlwswtBJqisjSmHdyMVcPZCZYTX7sBHTBLYQKYSiwp8QlFfU/ucSsnbDzdMTrRwzaIXuD+EXIFWIvga1uQ==" - }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5" - } - }, - "file-entry-cache": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", - "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", - "dev": true, - "requires": { - "flat-cache": "^1.2.1", - "object-assign": "^4.0.1" - } - }, - "filename-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", - "dev": true, - "optional": true - }, - "fill-range": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", - "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", - "dev": true, - "optional": true, - "requires": { - "is-number": "^2.1.0", - "isobject": "^2.0.0", - "randomatic": "^3.0.0", - "repeat-element": "^1.1.2", - "repeat-string": "^1.5.2" - } - }, - "find-cache-dir": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-1.0.0.tgz", - "integrity": "sha1-kojj6ePMN0hxfTnq3hfPcfww7m8=", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^1.0.0", - "pkg-dir": "^2.0.0" - }, - "dependencies": { - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "optional": true + }, + "needle": { + "version": "2.3.0", + "bundled": true, "dev": true, + "optional": true, "requires": { - "locate-path": "^2.0.0" + "debug": "^4.1.0", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" } }, - "pkg-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "node-pre-gyp": { + "version": "0.12.0", + "bundled": true, "dev": true, + "optional": true, "requires": { - "find-up": "^2.1.0" + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" } - } - } - }, - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "dev": true, - "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "flat-cache": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz", - "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=", - "dev": true, - "requires": { - "circular-json": "^0.3.1", - "del": "^2.0.2", - "graceful-fs": "^4.1.2", - "write": "^0.2.1" - } - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "dev": true, - "optional": true, - "requires": { - "for-in": "^1.0.1" - } - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "dev": true - }, - "form-data": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz", - "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "1.0.6", - "mime-types": "^2.1.12" - }, - "dependencies": { - "combined-stream": { - "version": "1.0.6", - "resolved": "http://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", - "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", + }, + "nopt": { + "version": "4.0.1", + "bundled": true, "dev": true, + "optional": true, "requires": { - "delayed-stream": "~1.0.0" + "abbrev": "1", + "osenv": "^0.1.4" } - } - } - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, - "requires": { - "map-cache": "^0.2.2" - } - }, - "fs-readdir-recursive": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", - "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", - "dev": true - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.4.tgz", - "integrity": "sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==", - "dev": true, - "optional": true, - "requires": { - "nan": "^2.9.2", - "node-pre-gyp": "^0.10.0" - }, - "dependencies": { - "abbrev": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true, - "dev": true }, - "aproba": { - "version": "1.2.0", + "npm-bundled": { + "version": "1.0.6", "bundled": true, "dev": true, "optional": true }, - "are-we-there-yet": { - "version": "1.1.4", + "npm-packlist": { + "version": "1.4.1", "bundled": true, "dev": true, "optional": true, "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" } }, - "balanced-match": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", + "npmlog": { + "version": "4.1.2", "bundled": true, "dev": true, + "optional": true, "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" } }, - "chownr": { + "number-is-nan": { "version": "1.0.1", "bundled": true, "dev": true, "optional": true }, - "code-point-at": { - "version": "1.1.0", + "object-assign": { + "version": "4.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, - "concat-map": { - "version": "0.0.1", - "bundled": true, - "dev": true - }, - "console-control-strings": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "debug": { - "version": "2.6.9", + "once": { + "version": "1.4.0", "bundled": true, "dev": true, "optional": true, "requires": { - "ms": "2.0.0" + "wrappy": "1" } }, - "deep-extend": { - "version": "0.5.1", - "bundled": true, - "dev": true, - "optional": true - }, - "delegates": { - "version": "1.0.0", + "os-homedir": { + "version": "1.0.2", "bundled": true, "dev": true, "optional": true }, - "detect-libc": { - "version": "1.0.3", + "os-tmpdir": { + "version": "1.0.2", "bundled": true, "dev": true, "optional": true }, - "fs-minipass": { - "version": "1.2.5", + "osenv": { + "version": "0.1.5", "bundled": true, "dev": true, "optional": true, "requires": { - "minipass": "^2.2.1" + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" } }, - "fs.realpath": { - "version": "1.0.0", + "path-is-absolute": { + "version": "1.0.1", "bundled": true, "dev": true, "optional": true }, - "gauge": { - "version": "2.7.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "glob": { - "version": "7.1.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-unicode": { - "version": "2.0.1", + "process-nextick-args": { + "version": "2.0.0", "bundled": true, "dev": true, "optional": true }, - "iconv-lite": { - "version": "0.4.21", + "rc": { + "version": "1.2.8", "bundled": true, "dev": true, "optional": true, "requires": { - "safer-buffer": "^2.1.0" + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + } } }, - "ignore-walk": { - "version": "3.0.1", + "readable-stream": { + "version": "2.3.6", "bundled": true, "dev": true, "optional": true, "requires": { - "minimatch": "^3.0.4" + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, - "inflight": { - "version": "1.0.6", + "rimraf": { + "version": "2.6.3", "bundled": true, "dev": true, "optional": true, "requires": { - "once": "^1.3.0", - "wrappy": "1" + "glob": "^7.1.3" } }, - "inherits": { - "version": "2.0.3", - "bundled": true, - "dev": true - }, - "ini": { - "version": "1.3.5", + "safe-buffer": { + "version": "5.1.2", "bundled": true, "dev": true, "optional": true }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "isarray": { - "version": "1.0.0", + "safer-buffer": { + "version": "2.1.2", "bundled": true, "dev": true, "optional": true }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "bundled": true, - "dev": true - }, - "minipass": { - "version": "2.2.4", + "sax": { + "version": "1.2.4", "bundled": true, "dev": true, - "requires": { - "safe-buffer": "^5.1.1", - "yallist": "^3.0.0" - } + "optional": true }, - "minizlib": { - "version": "1.1.0", + "semver": { + "version": "5.7.0", "bundled": true, "dev": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } + "optional": true }, - "mkdirp": { - "version": "0.5.1", + "set-blocking": { + "version": "2.0.0", "bundled": true, "dev": true, - "requires": { - "minimist": "0.0.8" - } + "optional": true }, - "ms": { - "version": "2.0.0", + "signal-exit": { + "version": "3.0.2", "bundled": true, "dev": true, "optional": true }, - "needle": { - "version": "2.2.0", + "string-width": { + "version": "1.0.2", "bundled": true, "dev": true, "optional": true, "requires": { - "debug": "^2.1.2", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" } }, - "node-pre-gyp": { - "version": "0.10.0", + "string_decoder": { + "version": "1.1.1", "bundled": true, "dev": true, "optional": true, "requires": { - "detect-libc": "^1.0.2", - "mkdirp": "^0.5.1", - "needle": "^2.2.0", - "nopt": "^4.0.1", - "npm-packlist": "^1.1.6", - "npmlog": "^4.0.2", - "rc": "^1.1.7", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^4" + "safe-buffer": "~5.1.0" } }, - "nopt": { - "version": "4.0.1", + "strip-ansi": { + "version": "3.0.1", "bundled": true, "dev": true, "optional": true, "requires": { - "abbrev": "1", - "osenv": "^0.1.4" + "ansi-regex": "^2.0.0" } }, - "npm-bundled": { - "version": "1.0.3", + "strip-json-comments": { + "version": "2.0.1", "bundled": true, "dev": true, "optional": true }, - "npm-packlist": { - "version": "1.1.10", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" - } - }, - "npmlog": { - "version": "4.1.2", + "tar": { + "version": "4.4.8", "bundled": true, "dev": true, "optional": true, "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.3.4", + "minizlib": "^1.1.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.2" } }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "object-assign": { - "version": "4.1.1", + "util-deprecate": { + "version": "1.0.2", "bundled": true, "dev": true, "optional": true }, - "once": { - "version": "1.4.0", + "wide-align": { + "version": "1.1.3", "bundled": true, "dev": true, + "optional": true, "requires": { - "wrappy": "1" + "string-width": "^1.0.2 || 2" } }, - "os-homedir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "os-tmpdir": { + "wrappy": { "version": "1.0.2", "bundled": true, "dev": true, "optional": true }, - "osenv": { - "version": "0.1.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", + "yallist": { + "version": "3.0.3", "bundled": true, "dev": true, "optional": true - }, - "process-nextick-args": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "rc": { - "version": "1.2.7", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "deep-extend": "^0.5.1", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "readable-stream": { - "version": "2.3.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "rimraf": { - "version": "2.6.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "glob": "^7.0.5" - } - }, - "safe-buffer": { - "version": "5.1.1", - "bundled": true, - "dev": true - }, - "safer-buffer": { - "version": "2.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "sax": { - "version": "1.2.4", - "bundled": true, - "dev": true, - "optional": true - }, - "semver": { - "version": "5.5.0", - "bundled": true, - "dev": true, - "optional": true - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "string-width": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "tar": { - "version": "4.4.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "chownr": "^1.0.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.2.4", - "minizlib": "^1.1.0", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.1", - "yallist": "^3.0.2" - } - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "wide-align": { - "version": "1.1.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "string-width": "^1.0.2" - } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "yallist": { - "version": "3.0.2", - "bundled": true, - "dev": true } } }, @@ -3440,17 +2379,20 @@ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", - "dev": true + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } }, "get-value": { "version": "2.0.6", @@ -3468,9 +2410,9 @@ } }, "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -3481,50 +2423,16 @@ "path-is-absolute": "^1.0.0" } }, - "glob-base": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", - "dev": true, - "optional": true, - "requires": { - "glob-parent": "^2.0.0", - "is-glob": "^2.0.0" - } - }, - "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "dev": true, - "requires": { - "is-glob": "^2.0.0" - } - }, "globals": { - "version": "11.7.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.7.0.tgz", - "integrity": "sha512-K8BNSPySfeShBQXsahYB/AbbWruVOTyVpgoIDnl8odPpeSfP2J5QO2oLFFdl2j7GfDCtZj2bMKar2T49itTPCg==", + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true }, - "globby": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", - "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "arrify": "^1.0.0", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", + "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", "dev": true }, "growl": { @@ -3533,6 +2441,24 @@ "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", "dev": true }, + "growly": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", + "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", + "dev": true + }, + "handlebars": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.3.3.tgz", + "integrity": "sha512-VupOxR91xcGojfINrzMqrvlyYbBs39sXIrWa7YdaQWeBudOlvKEGvCczMfJPgnuwHE/zyH1M6J+IUP6cgDVyxg==", + "dev": true, + "requires": { + "neo-async": "^2.6.0", + "optimist": "^0.6.1", + "source-map": "^0.6.1", + "uglify-js": "^3.1.4" + } + }, "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", @@ -3540,12 +2466,12 @@ "dev": true }, "har-validator": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.0.tgz", - "integrity": "sha512-+qnmNjI4OfH2ipQ9VQOw23bBd/ibtfbVdK2fYbY4acTDqKTW/YDp9McimZdDbG8iV9fZizUqQMD5xvriB146TA==", + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", "dev": true, "requires": { - "ajv": "^5.3.0", + "ajv": "^6.5.5", "har-schema": "^2.0.0" } }, @@ -3567,6 +2493,18 @@ "ansi-regex": "^2.0.0" } }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "has-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", + "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", + "dev": true + }, "has-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", @@ -3576,14 +2514,6 @@ "get-value": "^2.0.6", "has-values": "^1.0.0", "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } } }, "has-values": { @@ -3596,26 +2526,6 @@ "kind-of": "^4.0.0" }, "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, "kind-of": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", @@ -3627,28 +2537,21 @@ } } }, - "he": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", + "hosted-git-info": { + "version": "2.8.4", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.4.tgz", + "integrity": "sha512-pzXIvANXEFrc5oFFXRMkbLPQ2rXRoDERwDLyrcUxGhaZhgP54BBSl9Oheh7Vv0T090cszWBxPjkQQ5Sq1PbBRQ==", "dev": true }, - "home-or-tmp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", - "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", + "html-encoding-sniffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", + "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", "dev": true, "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.1" + "whatwg-encoding": "^1.0.1" } }, - "hosted-git-info": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz", - "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==", - "dev": true - }, "html-entities": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.2.1.tgz", @@ -3674,11 +2577,15 @@ "safer-buffer": ">= 2.1.2 < 3" } }, - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true + "import-local": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", + "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", + "dev": true, + "requires": { + "pkg-dir": "^3.0.0", + "resolve-cwd": "^2.0.0" + } }, "imurmurhash": { "version": "0.1.4", @@ -3697,55 +2604,11 @@ } }, "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, - "inquirer": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.2.0.tgz", - "integrity": "sha512-QIEQG4YyQ2UYZGDC4srMZ7BjHOmNk1lR2JQj5UknBapklm6WHA+VVH7N+sUdX3A7NeCfGF8o4X1S3Ao7nAcIeg==", - "dev": true, - "requires": { - "ansi-escapes": "^3.0.0", - "chalk": "^2.0.0", - "cli-cursor": "^2.1.0", - "cli-width": "^2.0.0", - "external-editor": "^3.0.0", - "figures": "^2.0.0", - "lodash": "^4.17.10", - "mute-stream": "0.0.7", - "run-async": "^2.2.0", - "rxjs": "^6.1.0", - "string-width": "^2.1.0", - "strip-ansi": "^4.0.0", - "through": "^2.3.6" - }, - "dependencies": { - "ansi-escapes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz", - "integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw==", - "dev": true - }, - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, "invariant": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", @@ -3762,6 +2625,17 @@ "dev": true, "requires": { "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } } }, "is-arrayish": { @@ -3770,29 +2644,25 @@ "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", "dev": true }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "dev": true, - "optional": true, - "requires": { - "binary-extensions": "^1.0.0" - } - }, "is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true }, - "is-builtin-module": { - "version": "1.0.0", - "resolved": "http://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", - "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", + "is-callable": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", + "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", + "dev": true + }, + "is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", "dev": true, "requires": { - "builtin-modules": "^1.0.0" + "ci-info": "^2.0.0" } }, "is-data-descriptor": { @@ -3802,8 +2672,25 @@ "dev": true, "requires": { "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } } }, + "is-date-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", + "dev": true + }, "is-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", @@ -3823,91 +2710,42 @@ } } }, - "is-dotfile": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", - "dev": true, - "optional": true - }, - "is-equal-shallow": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", - "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", - "dev": true, - "optional": true, - "requires": { - "is-primitive": "^2.0.0" - } - }, "is-extendable": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", "dev": true }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-finite": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", - "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "is-number": { + "is-generator-fn": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", - "dev": true, - "optional": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-path-cwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", - "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", "dev": true }, - "is-path-in-cwd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", - "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", - "dev": true, - "requires": { - "is-path-inside": "^1.0.0" - } - }, - "is-path-inside": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", - "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, "requires": { - "path-is-inside": "^1.0.1" + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } } }, "is-plain-object": { @@ -3917,42 +2755,32 @@ "dev": true, "requires": { "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } } }, - "is-posix-bracket": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", - "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", - "dev": true, - "optional": true - }, - "is-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", + "is-regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", + "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", "dev": true, - "optional": true - }, - "is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", - "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", - "dev": true + "requires": { + "has": "^1.0.1" + } }, - "is-resolvable": { + "is-stream": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", - "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", "dev": true }, + "is-symbol": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", + "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.0" + } + }, "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", @@ -3965,6 +2793,12 @@ "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", "dev": true }, + "is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", + "dev": true + }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -3978,14 +2812,10 @@ "dev": true }, "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "optional": true, - "requires": { - "isarray": "1.0.0" - } + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true }, "isstream": { "version": "0.1.2", @@ -3994,387 +2824,537 @@ "dev": true }, "istanbul-lib-coverage": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", - "integrity": "sha512-nPvSZsVlbG9aLhZYaC3Oi1gT/tpyo3Yt5fNyf6NmcKIayz4VV/txxJFFKAK/gU4dcNn8ehsanBbVHVl0+amOLA==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", + "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==", "dev": true }, "istanbul-lib-instrument": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.0.0.tgz", - "integrity": "sha512-eQY9vN9elYjdgN9Iv6NS/00bptm02EBBk70lRMaVjeA6QYocQgenVrSgC28TJurdnZa80AGO3ASdFN+w/njGiQ==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz", + "integrity": "sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA==", + "dev": true, + "requires": { + "@babel/generator": "^7.4.0", + "@babel/parser": "^7.4.3", + "@babel/template": "^7.4.0", + "@babel/traverse": "^7.4.3", + "@babel/types": "^7.4.0", + "istanbul-lib-coverage": "^2.0.5", + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "istanbul-lib-report": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz", + "integrity": "sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ==", "dev": true, "requires": { - "@babel/generator": "^7.0.0", - "@babel/parser": "^7.0.0", - "@babel/template": "^7.0.0", - "@babel/traverse": "^7.0.0", - "@babel/types": "^7.0.0", - "istanbul-lib-coverage": "^2.0.1", - "semver": "^5.5.0" + "istanbul-lib-coverage": "^2.0.5", + "make-dir": "^2.1.0", + "supports-color": "^6.1.0" + }, + "dependencies": { + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } } }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "istanbul-lib-source-maps": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz", + "integrity": "sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==", "dev": true, - "optional": true - }, - "jsesc": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.1.tgz", - "integrity": "sha1-5CGiqOINawgZ3yiQj3glJrlt0f4=", - "dev": true - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", - "dev": true - }, - "json-schema-traverse": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", - "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", - "dev": true - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true - }, - "json5": { - "version": "0.5.1", - "resolved": "http://registry.npmjs.org/json5/-/json5-0.5.1.tgz", - "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", - "dev": true + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^2.0.5", + "make-dir": "^2.1.0", + "rimraf": "^2.6.3", + "source-map": "^0.6.1" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } + } }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "istanbul-reports": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.6.tgz", + "integrity": "sha512-SKi4rnMyLBKe0Jy2uUdx28h8oG7ph2PPuQPvIAh31d+Ci+lSiEu4C+h3oBPuJ9+mPKhOyW0M8gY4U5NM1WLeXA==", "dev": true, "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" + "handlebars": "^4.1.2" } }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "jest": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-24.9.0.tgz", + "integrity": "sha512-YvkBL1Zm7d2B1+h5fHEOdyjCG+sGMz4f8D86/0HiqJ6MB4MnDc8FgP5vdWsGnemOQro7lnYo8UakZ3+5A0jxGw==", "dev": true, "requires": { - "is-buffer": "^1.1.5" + "import-local": "^2.0.0", + "jest-cli": "^24.9.0" + }, + "dependencies": { + "jest-cli": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-24.9.0.tgz", + "integrity": "sha512-+VLRKyitT3BWoMeSUIHRxV/2g8y9gw91Jh5z2UmXZzkZKpbC08CSehVxgHUwTpy+HwGcns/tqafQDJW7imYvGg==", + "dev": true, + "requires": { + "@jest/core": "^24.9.0", + "@jest/test-result": "^24.9.0", + "@jest/types": "^24.9.0", + "chalk": "^2.0.1", + "exit": "^0.1.2", + "import-local": "^2.0.0", + "is-ci": "^2.0.0", + "jest-config": "^24.9.0", + "jest-util": "^24.9.0", + "jest-validate": "^24.9.0", + "prompts": "^2.0.1", + "realpath-native": "^1.1.0", + "yargs": "^13.3.0" + } + } } }, - "lcov-parse": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-0.0.10.tgz", - "integrity": "sha1-GwuP+ayceIklBYK3C3ExXZ2m2aM=", - "dev": true + "jest-changed-files": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-24.9.0.tgz", + "integrity": "sha512-6aTWpe2mHF0DhL28WjdkO8LyGjs3zItPET4bMSeXU6T3ub4FPMw+mcOcbdGXQOAfmLcxofD23/5Bl9Z4AkFwqg==", + "dev": true, + "requires": { + "@jest/types": "^24.9.0", + "execa": "^1.0.0", + "throat": "^4.0.0" + } }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "jest-config": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-24.9.0.tgz", + "integrity": "sha512-RATtQJtVYQrp7fvWg6f5y3pEFj9I+H8sWw4aKxnDZ96mob5i5SD6ZEGWgMLXQ4LE8UurrjbdlLWdUeo+28QpfQ==", "dev": true, "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" + "@babel/core": "^7.1.0", + "@jest/test-sequencer": "^24.9.0", + "@jest/types": "^24.9.0", + "babel-jest": "^24.9.0", + "chalk": "^2.0.1", + "glob": "^7.1.1", + "jest-environment-jsdom": "^24.9.0", + "jest-environment-node": "^24.9.0", + "jest-get-type": "^24.9.0", + "jest-jasmine2": "^24.9.0", + "jest-regex-util": "^24.3.0", + "jest-resolve": "^24.9.0", + "jest-util": "^24.9.0", + "jest-validate": "^24.9.0", + "micromatch": "^3.1.10", + "pretty-format": "^24.9.0", + "realpath-native": "^1.1.0" } }, - "line-count": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/line-count/-/line-count-0.1.0.tgz", - "integrity": "sha1-N0n/NxWYDBkjCW/4aUKDFrwirzU=", - "dev": true + "jest-diff": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-24.9.0.tgz", + "integrity": "sha512-qMfrTs8AdJE2iqrTp0hzh7kTd2PQWrsFyj9tORoKmu32xjPjeE4NyjVRDz8ybYwqS2ik8N4hsIpiVTyFeo2lBQ==", + "dev": true, + "requires": { + "chalk": "^2.0.1", + "diff-sequences": "^24.9.0", + "jest-get-type": "^24.9.0", + "pretty-format": "^24.9.0" + } }, - "load-json-file": { - "version": "2.0.0", - "resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", - "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "jest-docblock": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-24.9.0.tgz", + "integrity": "sha512-F1DjdpDMJMA1cN6He0FNYNZlo3yYmOtRUnktrT9Q37njYzC5WEaDdmbynIgy0L/IvXvvgsG8OsqhLPXTpfmZAA==", "dev": true, "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "strip-bom": "^3.0.0" + "detect-newline": "^2.1.0" } }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "jest-each": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-24.9.0.tgz", + "integrity": "sha512-ONi0R4BvW45cw8s2Lrx8YgbeXL1oCQ/wIDwmsM3CqM/nlblNCPmnC3IPQlMbRFZu3wKdQ2U8BqM6lh3LJ5Bsog==", "dev": true, "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - }, - "dependencies": { - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - } + "@jest/types": "^24.9.0", + "chalk": "^2.0.1", + "jest-get-type": "^24.9.0", + "jest-util": "^24.9.0", + "pretty-format": "^24.9.0" } }, - "lodash": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" + "jest-environment-jsdom": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-24.9.0.tgz", + "integrity": "sha512-Zv9FV9NBRzLuALXjvRijO2351DRQeLYXtpD4xNvfoVFw21IOKNhZAEUKcbiEtjTkm2GsJ3boMVgkaR7rN8qetA==", + "dev": true, + "requires": { + "@jest/environment": "^24.9.0", + "@jest/fake-timers": "^24.9.0", + "@jest/types": "^24.9.0", + "jest-mock": "^24.9.0", + "jest-util": "^24.9.0", + "jsdom": "^11.5.1" + } }, - "lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", + "jest-environment-node": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-24.9.0.tgz", + "integrity": "sha512-6d4V2f4nxzIzwendo27Tr0aFm+IXWa0XEUnaH6nU0FMaozxovt+sfRvh4J47wL1OvF83I3SSTu0XK+i4Bqe7uA==", "dev": true, - "optional": true + "requires": { + "@jest/environment": "^24.9.0", + "@jest/fake-timers": "^24.9.0", + "@jest/types": "^24.9.0", + "jest-mock": "^24.9.0", + "jest-util": "^24.9.0" + } }, - "log-driver": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", - "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==", + "jest-expect-message": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/jest-expect-message/-/jest-expect-message-1.0.2.tgz", + "integrity": "sha512-WFiXMgwS2lOqQZt1iJMI/hOXpUm32X+ApsuzYcQpW5m16Pv6/Gd9kgC+Q+Q1YVNU04kYcAOv9NXMnjg6kKUy6Q==", "dev": true }, - "long": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/long/-/long-3.2.0.tgz", - "integrity": "sha1-2CG3E4yhy1gcFymQ7xTbIAtcR0s=" + "jest-get-type": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-24.9.0.tgz", + "integrity": "sha512-lUseMzAley4LhIcpSP9Jf+fTrQ4a1yHQwLNeeVa2cEmbCGeoZAtYPOIv8JaxLD/sUpKxetKGP+gsHl8f8TSj8Q==", + "dev": true }, - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "jest-haste-map": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-24.9.0.tgz", + "integrity": "sha512-kfVFmsuWui2Sj1Rp1AJ4D9HqJwE4uwTlS/vO+eRUaMmd54BFpli2XhMQnPC2k4cHFVbB2Q2C+jtI1AGLgEnCjQ==", "dev": true, "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" + "@jest/types": "^24.9.0", + "anymatch": "^2.0.0", + "fb-watchman": "^2.0.0", + "fsevents": "^1.2.7", + "graceful-fs": "^4.1.15", + "invariant": "^2.2.4", + "jest-serializer": "^24.9.0", + "jest-util": "^24.9.0", + "jest-worker": "^24.9.0", + "micromatch": "^3.1.10", + "sane": "^4.0.3", + "walker": "^1.0.7" } }, - "make-dir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "jest-jasmine2": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-24.9.0.tgz", + "integrity": "sha512-Cq7vkAgaYKp+PsX+2/JbTarrk0DmNhsEtqBXNwUHkdlbrTBLtMJINADf2mf5FkowNsq8evbPc07/qFO0AdKTzw==", "dev": true, "requires": { - "pify": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } + "@babel/traverse": "^7.1.0", + "@jest/environment": "^24.9.0", + "@jest/test-result": "^24.9.0", + "@jest/types": "^24.9.0", + "chalk": "^2.0.1", + "co": "^4.6.0", + "expect": "^24.9.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^24.9.0", + "jest-matcher-utils": "^24.9.0", + "jest-message-util": "^24.9.0", + "jest-runtime": "^24.9.0", + "jest-snapshot": "^24.9.0", + "jest-util": "^24.9.0", + "pretty-format": "^24.9.0", + "throat": "^4.0.0" } }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true + "jest-leak-detector": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-24.9.0.tgz", + "integrity": "sha512-tYkFIDsiKTGwb2FG1w8hX9V0aUb2ot8zY/2nFg087dUageonw1zrLMP4W6zsRO59dPkTSKie+D4rhMuP9nRmrA==", + "dev": true, + "requires": { + "jest-get-type": "^24.9.0", + "pretty-format": "^24.9.0" + } }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "jest-matcher-utils": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-24.9.0.tgz", + "integrity": "sha512-OZz2IXsu6eaiMAwe67c1T+5tUAtQyQx27/EMEkbFAGiw52tB9em+uGbzpcgYVpA8wl0hlxKPZxrly4CXU/GjHA==", "dev": true, "requires": { - "object-visit": "^1.0.0" + "chalk": "^2.0.1", + "jest-diff": "^24.9.0", + "jest-get-type": "^24.9.0", + "pretty-format": "^24.9.0" } }, - "math-random": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.1.tgz", - "integrity": "sha1-izqsWIuKZuSXXjzepn97sylgH6w=", + "jest-message-util": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.9.0.tgz", + "integrity": "sha512-oCj8FiZ3U0hTP4aSui87P4L4jC37BtQwUMqk+zk/b11FR19BJDeZsZAvIHutWnmtw7r85UmR3CEWZ0HWU2mAlw==", "dev": true, - "optional": true + "requires": { + "@babel/code-frame": "^7.0.0", + "@jest/test-result": "^24.9.0", + "@jest/types": "^24.9.0", + "@types/stack-utils": "^1.0.1", + "chalk": "^2.0.1", + "micromatch": "^3.1.10", + "slash": "^2.0.0", + "stack-utils": "^1.0.1" + } }, - "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "jest-mock": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-24.9.0.tgz", + "integrity": "sha512-3BEYN5WbSq9wd+SyLDES7AHnjH9A/ROBwmz7l2y+ol+NtSFO8DYiEBzoO1CeFc9a8DYy10EO4dDFVv/wN3zl1w==", "dev": true, - "optional": true, "requires": { - "arr-diff": "^2.0.0", - "array-unique": "^0.2.1", - "braces": "^1.8.2", - "expand-brackets": "^0.1.4", - "extglob": "^0.3.1", - "filename-regex": "^2.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.1", - "kind-of": "^3.0.2", - "normalize-path": "^2.0.1", - "object.omit": "^2.0.0", - "parse-glob": "^3.0.4", - "regex-cache": "^0.4.2" + "@jest/types": "^24.9.0" } }, - "mime-db": { - "version": "1.36.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.36.0.tgz", - "integrity": "sha512-L+xvyD9MkoYMXb1jAmzI/lWYAxAMCPvIBSWur0PZ5nOf5euahRLVqH//FKW9mWp2lkqUgYiXPgkzfMUFi4zVDw==", + "jest-pnp-resolver": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.1.tgz", + "integrity": "sha512-pgFw2tm54fzgYvc/OHrnysABEObZCUNFnhjoRjaVOCN8NYc032/gVjPaHD4Aq6ApkSieWtfKAFQtmDKAmhupnQ==", "dev": true }, - "mime-types": { - "version": "2.1.20", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.20.tgz", - "integrity": "sha512-HrkrPaP9vGuWbLK1B1FfgAkbqNjIuy4eHlIYnFi7kamZyLLrGlo2mpcx0bBmNpKqBtYtAfGbodDddIgddSJC2A==", + "jest-regex-util": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-24.9.0.tgz", + "integrity": "sha512-05Cmb6CuxaA+Ys6fjr3PhvV3bGQmO+2p2La4hFbU+W5uOc479f7FdLXUWXw4pYMAhhSZIuKHwSXSu6CsSBAXQA==", + "dev": true + }, + "jest-resolve": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-24.9.0.tgz", + "integrity": "sha512-TaLeLVL1l08YFZAt3zaPtjiVvyy4oSA6CRe+0AFPPVX3Q/VI0giIWWoAvoS5L96vj9Dqxj4fB5p2qrHCmTU/MQ==", "dev": true, "requires": { - "mime-db": "~1.36.0" + "@jest/types": "^24.9.0", + "browser-resolve": "^1.11.3", + "chalk": "^2.0.1", + "jest-pnp-resolver": "^1.2.1", + "realpath-native": "^1.1.0" } }, - "mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "jest-resolve-dependencies": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-24.9.0.tgz", + "integrity": "sha512-Fm7b6AlWnYhT0BXy4hXpactHIqER7erNgIsIozDXWl5dVm+k8XdGVe1oTg1JyaFnOxarMEbax3wyRJqGP2Pq+g==", "dev": true, "requires": { - "brace-expansion": "^1.1.7" + "@jest/types": "^24.9.0", + "jest-regex-util": "^24.3.0", + "jest-snapshot": "^24.9.0" } }, - "minimist": { - "version": "1.2.0", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true + "jest-runner": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-24.9.0.tgz", + "integrity": "sha512-KksJQyI3/0mhcfspnxxEOBueGrd5E4vV7ADQLT9ESaCzz02WnbdbKWIf5Mkaucoaj7obQckYPVX6JJhgUcoWWg==", + "dev": true, + "requires": { + "@jest/console": "^24.7.1", + "@jest/environment": "^24.9.0", + "@jest/test-result": "^24.9.0", + "@jest/types": "^24.9.0", + "chalk": "^2.4.2", + "exit": "^0.1.2", + "graceful-fs": "^4.1.15", + "jest-config": "^24.9.0", + "jest-docblock": "^24.3.0", + "jest-haste-map": "^24.9.0", + "jest-jasmine2": "^24.9.0", + "jest-leak-detector": "^24.9.0", + "jest-message-util": "^24.9.0", + "jest-resolve": "^24.9.0", + "jest-runtime": "^24.9.0", + "jest-util": "^24.9.0", + "jest-worker": "^24.6.0", + "source-map-support": "^0.5.6", + "throat": "^4.0.0" + } }, - "mixin-deep": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", - "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", + "jest-runtime": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-24.9.0.tgz", + "integrity": "sha512-8oNqgnmF3v2J6PVRM2Jfuj8oX3syKmaynlDMMKQ4iyzbQzIG6th5ub/lM2bCMTmoTKM3ykcUYI2Pw9xwNtjMnw==", "dev": true, "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" + "@jest/console": "^24.7.1", + "@jest/environment": "^24.9.0", + "@jest/source-map": "^24.3.0", + "@jest/transform": "^24.9.0", + "@jest/types": "^24.9.0", + "@types/yargs": "^13.0.0", + "chalk": "^2.0.1", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.1.15", + "jest-config": "^24.9.0", + "jest-haste-map": "^24.9.0", + "jest-message-util": "^24.9.0", + "jest-mock": "^24.9.0", + "jest-regex-util": "^24.3.0", + "jest-resolve": "^24.9.0", + "jest-snapshot": "^24.9.0", + "jest-util": "^24.9.0", + "jest-validate": "^24.9.0", + "realpath-native": "^1.1.0", + "slash": "^2.0.0", + "strip-bom": "^3.0.0", + "yargs": "^13.3.0" + } + }, + "jest-serializer": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-24.9.0.tgz", + "integrity": "sha512-DxYipDr8OvfrKH3Kel6NdED3OXxjvxXZ1uIY2I9OFbGg+vUkkg7AGvi65qbhbWNPvDckXmzMPbK3u3HaDO49bQ==", + "dev": true + }, + "jest-snapshot": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-24.9.0.tgz", + "integrity": "sha512-uI/rszGSs73xCM0l+up7O7a40o90cnrk429LOiK3aeTvfC0HHmldbd81/B7Ix81KSFe1lwkbl7GnBGG4UfuDew==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0", + "@jest/types": "^24.9.0", + "chalk": "^2.0.1", + "expect": "^24.9.0", + "jest-diff": "^24.9.0", + "jest-get-type": "^24.9.0", + "jest-matcher-utils": "^24.9.0", + "jest-message-util": "^24.9.0", + "jest-resolve": "^24.9.0", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "pretty-format": "^24.9.0", + "semver": "^6.2.0" }, "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true } } }, - "mkdirp": { - "version": "0.5.1", - "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "jest-util": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.9.0.tgz", + "integrity": "sha512-x+cZU8VRmOJxbA1K5oDBdxQmdq0OIdADarLxk0Mq+3XS4jgvhG/oKGWcIDCtPG0HgjxOYvF+ilPJQsAyXfbNOg==", "dev": true, "requires": { - "minimist": "0.0.8" + "@jest/console": "^24.9.0", + "@jest/fake-timers": "^24.9.0", + "@jest/source-map": "^24.9.0", + "@jest/test-result": "^24.9.0", + "@jest/types": "^24.9.0", + "callsites": "^3.0.0", + "chalk": "^2.0.1", + "graceful-fs": "^4.1.15", + "is-ci": "^2.0.0", + "mkdirp": "^0.5.1", + "slash": "^2.0.0", + "source-map": "^0.6.0" + } + }, + "jest-validate": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-24.9.0.tgz", + "integrity": "sha512-HPIt6C5ACwiqSiwi+OfSSHbK8sG7akG8eATl+IPKaeIjtPOeBUd/g3J7DghugzxrGjI93qS/+RPKe1H6PqvhRQ==", + "dev": true, + "requires": { + "@jest/types": "^24.9.0", + "camelcase": "^5.3.1", + "chalk": "^2.0.1", + "jest-get-type": "^24.9.0", + "leven": "^3.1.0", + "pretty-format": "^24.9.0" + } + }, + "jest-watcher": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-24.9.0.tgz", + "integrity": "sha512-+/fLOfKPXXYJDYlks62/4R4GoT+GU1tYZed99JSCOsmzkkF7727RqKrjNAxtfO4YpGv11wybgRvCjR73lK2GZw==", + "dev": true, + "requires": { + "@jest/test-result": "^24.9.0", + "@jest/types": "^24.9.0", + "@types/yargs": "^13.0.0", + "ansi-escapes": "^3.0.0", + "chalk": "^2.0.1", + "jest-util": "^24.9.0", + "string-length": "^2.0.0" }, "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "ansi-escapes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", "dev": true } } }, - "mnemonist": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.14.0.tgz", - "integrity": "sha512-GosoNab9mShR9w6QJA+bFT9NC2fN+2smFuQ6dEvjt4myuMLFvy63qeFE0cJZ8DQQxmCrqKftTAA/8N686cRPiQ==", + "jest-worker": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.9.0.tgz", + "integrity": "sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw==", + "dev": true, "requires": { - "obliterator": "^1.2.1" - } - }, - "mocha": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", - "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==", - "dev": true, - "requires": { - "browser-stdout": "1.3.1", - "commander": "2.15.1", - "debug": "3.1.0", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "glob": "7.1.2", - "growl": "1.10.5", - "he": "1.1.1", - "minimatch": "3.0.4", - "mkdirp": "0.5.1", - "supports-color": "5.4.0" + "merge-stream": "^2.0.0", + "supports-color": "^6.1.0" }, "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", "dev": true, "requires": { "has-flag": "^3.0.0" @@ -4382,1275 +3362,486 @@ } } }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", "dev": true }, - "mute-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", + "jsdom": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-11.12.0.tgz", + "integrity": "sha512-y8Px43oyiBM13Zc1z780FrfNLJCXTL40EWlty/LXUtcjykRBNgLlCjWXpfSPBl2iv+N7koQN+dvqszHZgT/Fjw==", + "dev": true, + "requires": { + "abab": "^2.0.0", + "acorn": "^5.5.3", + "acorn-globals": "^4.1.0", + "array-equal": "^1.0.0", + "cssom": ">= 0.3.2 < 0.4.0", + "cssstyle": "^1.0.0", + "data-urls": "^1.0.0", + "domexception": "^1.0.1", + "escodegen": "^1.9.1", + "html-encoding-sniffer": "^1.0.2", + "left-pad": "^1.3.0", + "nwsapi": "^2.0.7", + "parse5": "4.0.0", + "pn": "^1.1.0", + "request": "^2.87.0", + "request-promise-native": "^1.0.5", + "sax": "^1.2.4", + "symbol-tree": "^3.2.2", + "tough-cookie": "^2.3.4", + "w3c-hr-time": "^1.0.1", + "webidl-conversions": "^4.0.2", + "whatwg-encoding": "^1.0.3", + "whatwg-mimetype": "^2.1.0", + "whatwg-url": "^6.4.1", + "ws": "^5.2.0", + "xml-name-validator": "^3.0.0" + } + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true }, - "nan": { - "version": "2.11.1", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.11.1.tgz", - "integrity": "sha512-iji6k87OSXa0CcrLl9z+ZiYSuR2o+c0bGuNmXdrhTQTakxytAFsC56SArGYoiHlJlFoHSnvmhpceZJaXkVuOtA==", + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "json5": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.0.tgz", + "integrity": "sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ==", "dev": true, - "optional": true + "requires": { + "minimist": "^1.2.0" + } }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", "dev": true, "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - } + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" } }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", "dev": true }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", "dev": true }, - "node-modules-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", - "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", + "lcov-parse": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-0.0.10.tgz", + "integrity": "sha1-GwuP+ayceIklBYK3C3ExXZ2m2aM=", "dev": true }, - "normalize-package-data": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", - "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "is-builtin-module": "^1.0.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } + "left-pad": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/left-pad/-/left-pad-1.3.0.tgz", + "integrity": "sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA==", + "dev": true }, - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", "dev": true, "requires": { - "remove-trailing-separator": "^1.0.1" + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" } }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "line-count": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/line-count/-/line-count-0.1.0.tgz", + "integrity": "sha1-N0n/NxWYDBkjCW/4aUKDFrwirzU=", "dev": true }, - "nyc": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/nyc/-/nyc-13.1.0.tgz", - "integrity": "sha512-3GyY6TpQ58z9Frpv4GMExE1SV2tAgYqC7HSy2omEhNiCT3mhT9NyiOvIE8zkbuJVFzmvvNTnE4h/7/wQae7xLg==", + "load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", "dev": true, "requires": { - "archy": "^1.0.0", - "arrify": "^1.0.1", - "caching-transform": "^2.0.0", - "convert-source-map": "^1.6.0", - "debug-log": "^1.0.1", - "find-cache-dir": "^2.0.0", - "find-up": "^3.0.0", - "foreground-child": "^1.5.6", - "glob": "^7.1.3", - "istanbul-lib-coverage": "^2.0.1", - "istanbul-lib-hook": "^2.0.1", - "istanbul-lib-instrument": "^3.0.0", - "istanbul-lib-report": "^2.0.2", - "istanbul-lib-source-maps": "^2.0.1", - "istanbul-reports": "^2.0.1", - "make-dir": "^1.3.0", - "merge-source-map": "^1.1.0", - "resolve-from": "^4.0.0", - "rimraf": "^2.6.2", - "signal-exit": "^3.0.2", - "spawn-wrap": "^1.4.2", - "test-exclude": "^5.0.0", - "uuid": "^3.3.2", - "yargs": "11.1.0", - "yargs-parser": "^9.0.2" - }, - "dependencies": { - "align-text": { - "version": "0.1.4", - "bundled": true, - "dev": true, - "requires": { - "kind-of": "^3.0.2", - "longest": "^1.0.1", - "repeat-string": "^1.5.2" - } - }, - "amdefine": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "ansi-regex": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "append-transform": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "default-require-extensions": "^2.0.0" - } - }, - "archy": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "arrify": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "async": { - "version": "1.5.2", - "bundled": true, - "dev": true - }, - "balanced-match": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "bundled": true, - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "builtin-modules": { - "version": "1.1.1", - "bundled": true, - "dev": true - }, - "caching-transform": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "make-dir": "^1.0.0", - "md5-hex": "^2.0.0", - "package-hash": "^2.0.0", - "write-file-atomic": "^2.0.0" - } - }, - "camelcase": { - "version": "1.2.1", - "bundled": true, - "dev": true, - "optional": true - }, - "center-align": { - "version": "0.1.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "align-text": "^0.1.3", - "lazy-cache": "^1.0.3" - } - }, - "cliui": { - "version": "2.1.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "center-align": "^0.1.1", - "right-align": "^0.1.1", - "wordwrap": "0.0.2" - }, - "dependencies": { - "wordwrap": { - "version": "0.0.2", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "code-point-at": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "commondir": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "bundled": true, + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" + }, + "lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", + "dev": true + }, + "lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", + "dev": true + }, + "log-driver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", + "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==", + "dev": true + }, + "long": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/long/-/long-3.2.0.tgz", + "integrity": "sha1-2CG3E4yhy1gcFymQ7xTbIAtcR0s=" + }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "dependencies": { + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", "dev": true - }, - "convert-source-map": { - "version": "1.6.0", - "bundled": true, - "dev": true, - "requires": { - "safe-buffer": "~5.1.1" - } - }, - "cross-spawn": { - "version": "4.0.2", - "bundled": true, - "dev": true, - "requires": { - "lru-cache": "^4.0.1", - "which": "^1.2.9" - } - }, - "debug": { - "version": "3.1.0", - "bundled": true, - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "debug-log": { + } + } + }, + "make-error": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", + "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", + "dev": true + }, + "makeerror": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", + "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", + "dev": true, + "requires": { + "tmpl": "1.0.x" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "requires": { + "object-visit": "^1.0.0" + } + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "mime-db": { + "version": "1.40.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", + "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==", + "dev": true + }, + "mime-types": { + "version": "2.1.24", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", + "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", + "dev": true, + "requires": { + "mime-db": "1.40.0" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "dev": true, + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { "version": "1.0.1", - "bundled": true, - "dev": true - }, - "decamelize": { - "version": "1.2.0", - "bundled": true, - "dev": true - }, - "default-require-extensions": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "strip-bom": "^3.0.0" - } - }, - "error-ex": { - "version": "1.3.2", - "bundled": true, - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es6-error": { - "version": "4.1.1", - "bundled": true, - "dev": true - }, - "execa": { - "version": "0.7.0", - "bundled": true, - "dev": true, - "requires": { - "cross-spawn": "^5.0.1", - "get-stream": "^3.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - }, - "dependencies": { - "cross-spawn": { - "version": "5.1.0", - "bundled": true, - "dev": true, - "requires": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - } - } - }, - "find-cache-dir": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^1.0.0", - "pkg-dir": "^3.0.0" - } - }, - "find-up": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "foreground-child": { - "version": "1.5.6", - "bundled": true, - "dev": true, - "requires": { - "cross-spawn": "^4", - "signal-exit": "^3.0.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "get-caller-file": { - "version": "1.0.3", - "bundled": true, - "dev": true - }, - "get-stream": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "glob": { - "version": "7.1.3", - "bundled": true, - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "graceful-fs": { - "version": "4.1.11", - "bundled": true, - "dev": true - }, - "handlebars": { - "version": "4.0.11", - "bundled": true, - "dev": true, - "requires": { - "async": "^1.4.0", - "optimist": "^0.6.1", - "source-map": "^0.4.4", - "uglify-js": "^2.6" - }, - "dependencies": { - "source-map": { - "version": "0.4.4", - "bundled": true, - "dev": true, - "requires": { - "amdefine": ">=0.0.4" - } - } - } - }, - "has-flag": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "hosted-git-info": { - "version": "2.7.1", - "bundled": true, - "dev": true - }, - "imurmurhash": { - "version": "0.1.4", - "bundled": true, - "dev": true - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "bundled": true, - "dev": true - }, - "invert-kv": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "is-arrayish": { - "version": "0.2.1", - "bundled": true, - "dev": true - }, - "is-buffer": { - "version": "1.1.6", - "bundled": true, - "dev": true - }, - "is-builtin-module": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "builtin-modules": "^1.0.0" - } - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "is-stream": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "isexe": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "istanbul-lib-coverage": { - "version": "2.0.1", - "bundled": true, - "dev": true - }, - "istanbul-lib-hook": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "append-transform": "^1.0.0" - } - }, - "istanbul-lib-instrument": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.0.0.tgz", - "integrity": "sha512-eQY9vN9elYjdgN9Iv6NS/00bptm02EBBk70lRMaVjeA6QYocQgenVrSgC28TJurdnZa80AGO3ASdFN+w/njGiQ==", - "dev": true, - "requires": { - "@babel/generator": "^7.0.0", - "@babel/parser": "^7.0.0", - "@babel/template": "^7.0.0", - "@babel/traverse": "^7.0.0", - "@babel/types": "^7.0.0", - "istanbul-lib-coverage": "^2.0.1", - "semver": "^5.5.0" - } - }, - "istanbul-lib-report": { - "version": "2.0.2", - "bundled": true, - "dev": true, - "requires": { - "istanbul-lib-coverage": "^2.0.1", - "make-dir": "^1.3.0", - "supports-color": "^5.4.0" - } - }, - "istanbul-lib-source-maps": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "debug": "^3.1.0", - "istanbul-lib-coverage": "^2.0.1", - "make-dir": "^1.3.0", - "rimraf": "^2.6.2", - "source-map": "^0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "bundled": true, - "dev": true - } - } - }, - "istanbul-reports": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "handlebars": "^4.0.11" - } - }, - "json-parse-better-errors": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "kind-of": { - "version": "3.2.2", - "bundled": true, - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - }, - "lazy-cache": { - "version": "1.0.4", - "bundled": true, - "dev": true, - "optional": true - }, - "lcid": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "invert-kv": "^1.0.0" - } - }, - "load-json-file": { - "version": "4.0.0", - "bundled": true, - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash.flattendeep": { - "version": "4.4.0", - "bundled": true, - "dev": true - }, - "longest": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "lru-cache": { - "version": "4.1.3", - "bundled": true, - "dev": true, - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "make-dir": { - "version": "1.3.0", - "bundled": true, - "dev": true, - "requires": { - "pify": "^3.0.0" - } - }, - "md5-hex": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "md5-o-matic": "^0.1.1" - } - }, - "md5-o-matic": { - "version": "0.1.1", - "bundled": true, - "dev": true - }, - "mem": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "requires": { - "mimic-fn": "^1.0.0" - } - }, - "merge-source-map": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "requires": { - "source-map": "^0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "bundled": true, - "dev": true - } - } - }, - "mimic-fn": { - "version": "1.2.0", - "bundled": true, - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.10", - "bundled": true, - "dev": true - }, - "mkdirp": { - "version": "0.5.1", - "bundled": true, - "dev": true, - "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "bundled": true, - "dev": true - } - } - }, - "ms": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "normalize-package-data": { - "version": "2.4.0", - "bundled": true, - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "is-builtin-module": "^1.0.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "npm-run-path": { - "version": "2.0.2", - "bundled": true, - "dev": true, - "requires": { - "path-key": "^2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "once": { - "version": "1.4.0", - "bundled": true, - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "optimist": { - "version": "0.6.1", - "bundled": true, - "dev": true, - "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" - } - }, - "os-homedir": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "os-locale": { - "version": "2.1.0", - "bundled": true, - "dev": true, - "requires": { - "execa": "^0.7.0", - "lcid": "^1.0.0", - "mem": "^1.1.0" - } - }, - "p-finally": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "p-limit": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "package-hash": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "lodash.flattendeep": "^4.4.0", - "md5-hex": "^2.0.0", - "release-zalgo": "^1.0.0" - } - }, - "parse-json": { - "version": "4.0.0", - "bundled": true, - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, - "path-exists": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "path-key": { - "version": "2.0.1", - "bundled": true, - "dev": true - }, - "path-type": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "pify": "^3.0.0" - } - }, - "pify": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "pkg-dir": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "find-up": "^3.0.0" - } - }, - "pseudomap": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "read-pkg": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" - } - }, - "read-pkg-up": { - "version": "4.0.0", - "bundled": true, - "dev": true, - "requires": { - "find-up": "^3.0.0", - "read-pkg": "^3.0.0" - } - }, - "release-zalgo": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "es6-error": "^4.0.1" - } - }, - "repeat-string": { - "version": "1.6.1", - "bundled": true, - "dev": true - }, - "require-directory": { - "version": "2.1.1", - "bundled": true, - "dev": true - }, - "require-main-filename": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "resolve-from": { - "version": "4.0.0", - "bundled": true, - "dev": true - }, - "right-align": { - "version": "0.1.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "align-text": "^0.1.1" - } - }, - "rimraf": { - "version": "2.6.2", - "bundled": true, - "dev": true, - "requires": { - "glob": "^7.0.5" - } - }, - "safe-buffer": { - "version": "5.1.2", - "bundled": true, - "dev": true - }, - "semver": { - "version": "5.5.0", - "bundled": true, - "dev": true - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "shebang-command": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true, - "dev": true - }, - "source-map": { - "version": "0.5.7", - "bundled": true, - "dev": true, - "optional": true - }, - "spawn-wrap": { - "version": "1.4.2", - "bundled": true, - "dev": true, - "requires": { - "foreground-child": "^1.5.6", - "mkdirp": "^0.5.0", - "os-homedir": "^1.0.1", - "rimraf": "^2.6.2", - "signal-exit": "^3.0.2", - "which": "^1.3.0" - } - }, - "spdx-correct": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.1.0", - "bundled": true, - "dev": true - }, - "spdx-expression-parse": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "string-width": { - "version": "2.1.1", - "bundled": true, - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - }, - "strip-bom": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "strip-eof": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "supports-color": { - "version": "5.4.0", - "bundled": true, - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "test-exclude": { - "version": "5.0.0", - "bundled": true, - "dev": true, - "requires": { - "arrify": "^1.0.1", - "minimatch": "^3.0.4", - "read-pkg-up": "^4.0.0", - "require-main-filename": "^1.0.1" - } - }, - "uglify-js": { - "version": "2.8.29", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "source-map": "~0.5.1", - "uglify-to-browserify": "~1.0.0", - "yargs": "~3.10.0" - }, - "dependencies": { - "yargs": { - "version": "3.10.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "camelcase": "^1.0.2", - "cliui": "^2.1.0", - "decamelize": "^1.0.0", - "window-size": "0.1.0" - } - } - } - }, - "uglify-to-browserify": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "uuid": { - "version": "3.3.2", - "bundled": true, - "dev": true - }, - "validate-npm-package-license": { - "version": "3.0.3", - "bundled": true, - "dev": true, - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "which": { - "version": "1.3.1", - "bundled": true, - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "window-size": { - "version": "0.1.0", - "bundled": true, - "dev": true, - "optional": true - }, - "wordwrap": { - "version": "0.0.3", - "bundled": true, - "dev": true - }, - "wrap-ansi": { - "version": "2.1.0", - "bundled": true, - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "bundled": true, - "dev": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "string-width": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "write-file-atomic": { - "version": "2.3.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dev": true, "requires": { - "graceful-fs": "^4.1.11", - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.2" + "is-plain-object": "^2.0.4" } - }, - "y18n": { - "version": "3.2.1", - "bundled": true, - "dev": true - }, - "yallist": { - "version": "2.1.2", - "bundled": true, + } + } + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", "dev": true - }, - "yargs": { - "version": "11.1.0", - "bundled": true, - "dev": true, - "requires": { - "cliui": "^4.0.0", - "decamelize": "^1.1.1", - "find-up": "^2.1.0", - "get-caller-file": "^1.0.1", - "os-locale": "^2.0.0", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^2.0.0", - "which-module": "^2.0.0", - "y18n": "^3.2.1", - "yargs-parser": "^9.0.2" - }, - "dependencies": { - "cliui": { - "version": "4.1.0", - "bundled": true, - "dev": true, - "requires": { - "string-width": "^2.1.1", - "strip-ansi": "^4.0.0", - "wrap-ansi": "^2.0.0" - } - }, - "find-up": { - "version": "2.1.0", - "bundled": true, - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "1.3.0", - "bundled": true, - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "bundled": true, - "dev": true - } - } - }, - "yargs-parser": { - "version": "9.0.2", - "bundled": true, - "dev": true, - "requires": { - "camelcase": "^4.1.0" - }, - "dependencies": { - "camelcase": { - "version": "4.1.0", - "bundled": true, - "dev": true - } - } } } }, + "mnemonist": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.14.0.tgz", + "integrity": "sha512-GosoNab9mShR9w6QJA+bFT9NC2fN+2smFuQ6dEvjt4myuMLFvy63qeFE0cJZ8DQQxmCrqKftTAA/8N686cRPiQ==", + "requires": { + "obliterator": "^1.2.1" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "nan": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", + "dev": true, + "optional": true + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + } + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "neo-async": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", + "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", + "dev": true + }, + "node-modules-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", + "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", + "dev": true + }, + "node-notifier": { + "version": "5.4.3", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.4.3.tgz", + "integrity": "sha512-M4UBGcs4jeOK9CjTsYwkvH6/MzuUmGCyTW+kCY7uO+1ZVr0+FHGdPdIf5CCLqAaxnRrWidyoQlNkMIIVwbKB8Q==", + "dev": true, + "requires": { + "growly": "^1.3.0", + "is-wsl": "^1.1.0", + "semver": "^5.5.0", + "shellwords": "^0.1.1", + "which": "^1.3.0" + } + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "requires": { + "path-key": "^2.0.0" + } + }, + "nwsapi": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.1.4.tgz", + "integrity": "sha512-iGfd9Y6SFdTNldEy2L0GUhcarIutFmk+MPWIn9dmj8NMIup03G08uUF2KGbbmv/Ux4RT0VZJoP/sVbWA6d/VIw==", + "dev": true + }, "oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", "dev": true }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, "object-copy": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", @@ -5670,9 +3861,30 @@ "requires": { "is-descriptor": "^0.1.0" } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } } } }, + "object-inspect": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.6.0.tgz", + "integrity": "sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ==", + "dev": true + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, "object-visit": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", @@ -5680,25 +3892,16 @@ "dev": true, "requires": { "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } } }, - "object.omit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", + "object.getownpropertydescriptors": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz", + "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=", "dev": true, - "optional": true, "requires": { - "for-own": "^0.1.4", - "is-extendable": "^0.1.1" + "define-properties": "^1.1.2", + "es-abstract": "^1.5.1" } }, "object.pick": { @@ -5708,14 +3911,6 @@ "dev": true, "requires": { "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } } }, "obliterator": { @@ -5732,13 +3927,22 @@ "wrappy": "1" } }, - "onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "optimist": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", + "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", "dev": true, "requires": { - "mimic-fn": "^1.0.0" + "minimist": "~0.0.1", + "wordwrap": "~0.0.2" + }, + "dependencies": { + "minimist": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", + "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=", + "dev": true + } } }, "optionator": { @@ -5753,53 +3957,59 @@ "prelude-ls": "~1.1.2", "type-check": "~0.3.2", "wordwrap": "~1.0.0" + }, + "dependencies": { + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + } } }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true - }, - "output-file-sync": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/output-file-sync/-/output-file-sync-1.1.2.tgz", - "integrity": "sha1-0KM+7+YaIF+suQCS6CZZjVJFznY=", + "p-each-series": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-1.0.0.tgz", + "integrity": "sha1-kw89Et0fUOdDRFeiLNbwSsatf3E=", "dev": true, "requires": { - "graceful-fs": "^4.1.4", - "mkdirp": "^0.5.1", - "object-assign": "^4.1.0" + "p-reduce": "^1.0.0" } }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", + "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", "dev": true, "requires": { - "p-try": "^1.0.0" + "p-try": "^2.0.0" } }, "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", "dev": true, "requires": { - "p-limit": "^1.1.0" + "p-limit": "^2.0.0" } }, - "p-try": { + "p-reduce": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-1.0.0.tgz", + "integrity": "sha1-GMKw3ZNqRpClKfgjH1ig/bakffo=", + "dev": true + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, "pandemonium": { @@ -5807,28 +4017,22 @@ "resolved": "https://registry.npmjs.org/pandemonium/-/pandemonium-1.4.1.tgz", "integrity": "sha512-KhwY9xv8tZGQE8L7FfzaTHrLH+JnarUsDlsa8mqfisjtU3J00P362IL52Ei/EhDp025yBDzPuES/zMdWvvAR5g==" }, - "parse-glob": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", - "dev": true, - "optional": true, - "requires": { - "glob-base": "^0.3.0", - "is-dotfile": "^1.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.0" - } - }, "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", "dev": true, "requires": { - "error-ex": "^1.2.0" + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" } }, + "parse5": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", + "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==", + "dev": true + }, "pascalcase": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", @@ -5844,21 +4048,11 @@ "readable-stream": "https://github.com/jeffbski/readable-stream/archive/v1.0.2-object-transform2-ret-self.tar.gz" } }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true, - "optional": true - }, "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "dev": true, - "requires": { - "pinkie-promise": "^2.0.0" - } + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true }, "path-is-absolute": { "version": "1.0.1", @@ -5866,12 +4060,6 @@ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, "path-key": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", @@ -5885,20 +4073,14 @@ "dev": true }, "path-type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", - "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", "dev": true, "requires": { - "pify": "^2.0.0" + "pify": "^3.0.0" } }, - "pathval": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", - "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", - "dev": true - }, "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", @@ -5906,48 +4088,33 @@ "dev": true }, "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true }, "pirates": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.0.tgz", - "integrity": "sha512-8t5BsXy1LUIjn3WWOlOuFDuKswhQb/tkak641lvBgmPOBUQHXveORtlMCp6OdPV1dtuTaEahKA8VNz6uLfKBtA==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", + "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", "dev": true, "requires": { "node-modules-regexp": "^1.0.0" } }, "pkg-dir": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz", - "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", "dev": true, "requires": { - "find-up": "^1.0.0" + "find-up": "^3.0.0" } }, - "pluralize": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", - "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", + "pn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz", + "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==", "dev": true }, "posix-character-classes": { @@ -5962,31 +4129,25 @@ "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", "dev": true }, - "preserve": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", - "dev": true, - "optional": true - }, - "private": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", - "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "pretty-format": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.9.0.tgz", + "integrity": "sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA==", "dev": true, - "optional": true - }, - "progress": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz", - "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=", - "dev": true + "requires": { + "@jest/types": "^24.9.0", + "ansi-regex": "^4.0.0", + "ansi-styles": "^3.2.0", + "react-is": "^16.8.4" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + } + } }, "prompt-skeleton": { "version": "0.4.0", @@ -6006,16 +4167,36 @@ } } }, + "prompts": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.2.1.tgz", + "integrity": "sha512-VObPvJiWPhpZI6C5m60XOzTfnYg/xc/an+r9VYymj9WJW3B/DIH+REzjpAACPf8brwPeP+7vz3bIim3S+AaMjw==", + "dev": true, + "requires": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.3" + } + }, "psl": { - "version": "1.1.29", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.29.tgz", - "integrity": "sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.4.0.tgz", + "integrity": "sha512-HZzqCGPecFLyoRj5HLfuDSKYTJkAfB5thKBIkRHtGjWwY7p1dAyveIbXIq4tO0KYfDF2tHqPUgY9SDnGm00uFw==", "dev": true }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", "dev": true }, "qs": { @@ -6024,64 +4205,31 @@ "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", "dev": true }, - "randomatic": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.0.tgz", - "integrity": "sha512-KnGPVE0lo2WoXxIZ7cPR8YBpiol4gsSuOwDSg410oHh80ZMp5EiypNqL2K4Z77vJn6lB5rap7IkAmcUlalcnBQ==", - "dev": true, - "optional": true, - "requires": { - "is-number": "^4.0.0", - "kind-of": "^6.0.0", - "math-random": "^1.0.1" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true, - "optional": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true, - "optional": true - } - } + "react-is": { + "version": "16.9.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.9.0.tgz", + "integrity": "sha512-tJBzzzIgnnRfEm046qRcURvwQnZVXmuCbscxUO5RWrGTXpon2d4c8mI0D8WE6ydVIm29JiLB6+RslkIvym9Rjw==", + "dev": true }, "read-pkg": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", - "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", "dev": true, "requires": { - "load-json-file": "^2.0.0", + "load-json-file": "^4.0.0", "normalize-package-data": "^2.3.2", - "path-type": "^2.0.0" + "path-type": "^3.0.0" } }, "read-pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", - "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-4.0.0.tgz", + "integrity": "sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==", "dev": true, "requires": { - "find-up": "^2.0.0", - "read-pkg": "^2.0.0" - }, - "dependencies": { - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - } + "find-up": "^3.0.0", + "read-pkg": "^3.0.0" } }, "readable-stream": { @@ -6089,349 +4237,13 @@ "integrity": "sha512-4DfqsAX+1OToUZ/uHLsC3NUHN7wCn2BNfkG/Eyr2ii4c4suSipjLFbVymS7pj49+aRcSutnK9dIuHS3X7fwApQ==", "dev": true }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "realpath-native": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-1.1.0.tgz", + "integrity": "sha512-wlgPA6cCIIg9gKz0fgAPjnzh4yR/LnXovwuo9hvyGvx3h8nX4+/iLZplfUWasXpqD8BdnGnP5njOFjkUwPzvjA==", "dev": true, - "optional": true, "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true, - "optional": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "optional": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "optional": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "optional": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "optional": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "optional": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "optional": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "optional": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "optional": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "optional": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "optional": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "optional": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true, - "optional": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "optional": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "optional": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "optional": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "optional": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "optional": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "optional": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "optional": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "optional": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "optional": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "optional": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true, - "optional": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "optional": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true, - "optional": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - } + "util.promisify": "^1.0.0" } }, "regenerate": { @@ -6440,81 +4252,14 @@ "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==", "dev": true }, - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", - "dev": true - }, - "regenerator-transform": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.10.1.tgz", - "integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==", - "dev": true, - "requires": { - "babel-runtime": "^6.18.0", - "babel-types": "^6.19.0", - "private": "^0.1.6" - } - }, - "regex-cache": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", - "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", - "dev": true, - "optional": true, - "requires": { - "is-equal-shallow": "^0.1.3" - } - }, "regex-not": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", "dev": true, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, - "regexpp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.0.tgz", - "integrity": "sha512-g2FAVtR8Uh8GO1Nv5wpxW7VFVwHcCEr4wyA8/MHiRkO8uHoR5ntAA8Uq3P1vvMTX/BeQiRVSpDGLd+Wn5HNOTA==", - "dev": true - }, - "regexpu-core": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", - "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=", - "dev": true, - "requires": { - "regenerate": "^1.2.1", - "regjsgen": "^0.2.0", - "regjsparser": "^0.1.4" - } - }, - "regjsgen": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", - "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=", - "dev": true - }, - "regjsparser": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", - "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", - "dev": true, - "requires": { - "jsesc": "~0.5.0" - }, - "dependencies": { - "jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", - "dev": true - } + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" } }, "remove-trailing-separator": { @@ -6535,15 +4280,6 @@ "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", "dev": true }, - "repeating": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", - "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", - "dev": true, - "requires": { - "is-finite": "^1.0.0" - } - }, "request": { "version": "2.88.0", "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", @@ -6572,35 +4308,60 @@ "uuid": "^3.3.2" } }, + "request-promise-core": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.2.tgz", + "integrity": "sha512-UHYyq1MO8GsefGEt7EprS8UrXsm1TxEvFUX1IMTuSLU2Rh7fTIdFtl8xD7JiEYiWU2dl+NYAjCTksTehQUxPag==", + "dev": true, + "requires": { + "lodash": "^4.17.11" + } + }, + "request-promise-native": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.7.tgz", + "integrity": "sha512-rIMnbBdgNViL37nZ1b3L/VfPOpSi0TqVDQPAvO6U14lMzOLrt5nilxCQqtDKhZeDiW0/hkCXGoQjhgJd/tCh6w==", + "dev": true, + "requires": { + "request-promise-core": "1.1.2", + "stealthy-require": "^1.1.1", + "tough-cookie": "^2.3.3" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, "require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", "dev": true }, - "require-uncached": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", - "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", + "resolve": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", + "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", "dev": true, "requires": { - "caller-path": "^0.1.0", - "resolve-from": "^1.0.0" + "path-parse": "^1.0.6" } }, - "resolve": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz", - "integrity": "sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==", + "resolve-cwd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", + "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", "dev": true, "requires": { - "path-parse": "^1.0.5" + "resolve-from": "^3.0.0" } }, "resolve-from": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", - "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", "dev": true }, "resolve-url": { @@ -6609,16 +4370,6 @@ "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", "dev": true }, - "restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", - "dev": true, - "requires": { - "onetime": "^2.0.0", - "signal-exit": "^3.0.2" - } - }, "ret": { "version": "0.1.15", "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", @@ -6626,36 +4377,24 @@ "dev": true }, "rimraf": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", - "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", - "dev": true, - "requires": { - "glob": "^7.0.5" - } - }, - "run-async": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", - "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.0.tgz", + "integrity": "sha512-NDGVxTsjqfunkds7CqsOiEnxln4Bo7Nddl3XhS4pXg5OzwkLqJ971ZVAAnB+DDLnF76N+VnDEiBHaVV8I06SUg==", "dev": true, "requires": { - "is-promise": "^2.1.0" + "glob": "^7.1.3" } }, - "rxjs": { - "version": "6.3.3", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz", - "integrity": "sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } + "rsvp": { + "version": "4.8.5", + "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", + "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==", + "dev": true }, "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", + "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==", "dev": true }, "safe-regex": { @@ -6673,16 +4412,45 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, + "sane": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz", + "integrity": "sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==", + "dev": true, + "requires": { + "@cnakazawa/watch": "^1.0.3", + "anymatch": "^2.0.0", + "capture-exit": "^2.0.0", + "exec-sh": "^0.3.2", + "execa": "^1.0.0", + "fb-watchman": "^2.0.0", + "micromatch": "^3.1.4", + "minimist": "^1.1.1", + "walker": "~1.0.5" + } + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "dev": true + }, "semver": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.1.tgz", - "integrity": "sha512-PqpAxfrEhlSUWge8dwIp4tZnQ25DIOthpiaHNIthsjEFQD6EvqUKUDM7L8O2rShkFccYo1VjJR0coWfNkCubRw==", + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true }, - "set-value": { + "set-blocking": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", - "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", "dev": true, "requires": { "extend-shallow": "^2.0.1", @@ -6717,26 +4485,29 @@ "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", "dev": true }, + "shellwords": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", + "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", + "dev": true + }, "signal-exit": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", "dev": true }, - "slash": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", - "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", + "sisteransi": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.3.tgz", + "integrity": "sha512-SbEG75TzH8G7eVXFSN5f9EExILKfly7SUvVY5DhhYLvfhKqhDFY0OzevWa/zwak0RLRfWS5AvfMWpd9gJvr5Yg==", "dev": true }, - "slice-ansi": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", - "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0" - } + "slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "dev": true }, "snapdragon": { "version": "0.8.2", @@ -6754,15 +4525,6 @@ "use": "^3.1.0" }, "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, "define-property": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", @@ -6781,12 +4543,6 @@ "is-extendable": "^0.1.0" } }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -6843,18 +4599,6 @@ "is-data-descriptor": "^1.0.0", "kind-of": "^6.0.2" } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true } } }, @@ -6865,6 +4609,17 @@ "dev": true, "requires": { "kind-of": "^3.2.0" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } } }, "so": { @@ -6873,6 +4628,12 @@ "integrity": "sha1-inkaBsgjwJCIUbttxlt1gxhbrfE=", "dev": true }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, "source-map-resolve": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", @@ -6887,20 +4648,13 @@ } }, "source-map-support": { - "version": "0.4.18", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", - "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", "dev": true, "requires": { - "source-map": "^0.5.6" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" } }, "source-map-url": { @@ -6910,9 +4664,9 @@ "dev": true }, "spdx-correct": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.2.tgz", - "integrity": "sha512-q9hedtzyXHr5S0A1vEPoK/7l8NpfkFYTq6iCY+Pno2ZbdZR6WexZFtqeVGkGxW3TEJMN914Z55EnAGMmenlIQQ==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", + "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", "dev": true, "requires": { "spdx-expression-parse": "^3.0.0", @@ -6936,9 +4690,9 @@ } }, "spdx-license-ids": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.1.tgz", - "integrity": "sha512-TfOfPcYGBB5sDuPn3deByxPhmfegAhpDYKSOXZQN81Oyrrif8ZCodOLzK3AesELnCx03kikhyDwh0pfvvQvF8w==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", + "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", "dev": true }, "split-lines": { @@ -6963,9 +4717,9 @@ "dev": true }, "sshpk": { - "version": "1.14.2", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.2.tgz", - "integrity": "sha1-xvxhZIo9nE52T9P8306hBeSSupg=", + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", "dev": true, "requires": { "asn1": "~0.2.3", @@ -6979,6 +4733,12 @@ "tweetnacl": "~0.14.0" } }, + "stack-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.2.tgz", + "integrity": "sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA==", + "dev": true + }, "static-extend": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", @@ -7000,13 +4760,19 @@ } } }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "stealthy-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", + "dev": true + }, + "string-length": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-2.0.0.tgz", + "integrity": "sha1-1A27aGo6zpYMHP/KVivyxF+DY+0=", "dev": true, "requires": { - "is-fullwidth-code-point": "^2.0.0", + "astral-regex": "^1.0.0", "strip-ansi": "^4.0.0" }, "dependencies": { @@ -7027,249 +4793,126 @@ } } }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - }, - "dependencies": { - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - } - } - }, - "table": { - "version": "4.0.3", - "resolved": "http://registry.npmjs.org/table/-/table-4.0.3.tgz", - "integrity": "sha512-S7rnFITmBH1EnyKcvxBh1LjYeQMmnZtCXSEbHcH6S0NoKit24ZuFO/T1vDcLdYsLQkM188PVVhQmzKIuThNkKg==", - "dev": true, - "requires": { - "ajv": "^6.0.1", - "ajv-keywords": "^3.0.0", - "chalk": "^2.1.0", - "lodash": "^4.17.4", - "slice-ansi": "1.0.0", - "string-width": "^2.1.1" - }, - "dependencies": { - "ajv": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.4.tgz", - "integrity": "sha512-4Wyjt8+t6YszqaXnLDfMmG/8AlO5Zbcsy3ATHncCzjW/NoPzAId8AK6749Ybjmdt+kUY1gP60fCu46oDxPv/mg==", - "dev": true, - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - } - } - }, - "talisman": { - "version": "0.21.0", - "resolved": "https://registry.npmjs.org/talisman/-/talisman-0.21.0.tgz", - "integrity": "sha512-KUUq5mpHxJlvENZLsgngVxc08rtCGIs+v1Xfs41fbni+ysDJGWsZUDVER6JVV79eKiIFzECEQLrgunchc3M5WQ==", - "requires": { - "html-entities": "^1.2.0", - "lodash": "^4.6.1", - "long": "^3.1.0", - "mnemonist": "^0.14.0", - "obliterator": "^1.2.0", - "pandemonium": "^1.0.2" - } - }, - "test-exclude": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-5.0.0.tgz", - "integrity": "sha512-bO3Lj5+qFa9YLfYW2ZcXMOV1pmQvw+KS/DpjqhyX6Y6UZ8zstpZJ+mA2ERkXfpOqhxsJlQiLeVXD3Smsrs6oLw==", + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "dev": true, "requires": { - "arrify": "^1.0.1", - "minimatch": "^3.0.4", - "read-pkg-up": "^4.0.0", - "require-main-filename": "^1.0.1" + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" }, "dependencies": { - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.0.0.tgz", - "integrity": "sha512-fl5s52lI5ahKCernzzIyAP0QAZbGIovtVHGwpcu1Jr/EpzLVDI2myISHwGqK7m8uQFugVWSrbxH7XnhGtvEc+A==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz", - "integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==", - "dev": true - }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "requires": { - "pify": "^3.0.0" - } - }, - "pify": { + "ansi-regex": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", "dev": true }, - "read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", - "dev": true, - "requires": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" - } - }, - "read-pkg-up": { + "strip-ansi": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-4.0.0.tgz", - "integrity": "sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "dev": true, "requires": { - "find-up": "^3.0.0", - "read-pkg": "^3.0.0" + "ansi-regex": "^3.0.0" } } } }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "string.prototype.trimleft": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz", + "integrity": "sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + } + }, + "string.prototype.trimright": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz", + "integrity": "sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", "dev": true }, - "through": { - "version": "2.3.8", - "resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", "dev": true }, - "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "talisman": { + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/talisman/-/talisman-0.21.0.tgz", + "integrity": "sha512-KUUq5mpHxJlvENZLsgngVxc08rtCGIs+v1Xfs41fbni+ysDJGWsZUDVER6JVV79eKiIFzECEQLrgunchc3M5WQ==", + "requires": { + "html-entities": "^1.2.0", + "lodash": "^4.6.1", + "long": "^3.1.0", + "mnemonist": "^0.14.0", + "obliterator": "^1.2.0", + "pandemonium": "^1.0.2" + } + }, + "test-exclude": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-5.2.3.tgz", + "integrity": "sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g==", "dev": true, "requires": { - "os-tmpdir": "~1.0.2" + "glob": "^7.1.3", + "minimatch": "^3.0.4", + "read-pkg-up": "^4.0.0", + "require-main-filename": "^2.0.0" } }, + "throat": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/throat/-/throat-4.1.0.tgz", + "integrity": "sha1-iQN8vJLFarGJJua6TLsgDhVnKmo=", + "dev": true + }, + "tmpl": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", + "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=", + "dev": true + }, "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", @@ -7283,6 +4926,17 @@ "dev": true, "requires": { "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } } }, "to-regex": { @@ -7305,17 +4959,6 @@ "requires": { "is-number": "^3.0.0", "repeat-string": "^1.6.1" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - } } }, "tough-cookie": { @@ -7326,20 +4969,96 @@ "requires": { "psl": "^1.1.24", "punycode": "^1.4.1" + }, + "dependencies": { + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + } } }, - "trim-right": { + "tr46": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", - "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", - "dev": true + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "ts-jest": { + "version": "24.1.0", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-24.1.0.tgz", + "integrity": "sha512-HEGfrIEAZKfu1pkaxB9au17b1d9b56YZSqz5eCVE8mX68+5reOvlM93xGOzzCREIov9mdH7JBG+s0UyNAqr0tQ==", + "dev": true, + "requires": { + "bs-logger": "0.x", + "buffer-from": "1.x", + "fast-json-stable-stringify": "2.x", + "json5": "2.x", + "lodash.memoize": "4.x", + "make-error": "1.x", + "mkdirp": "0.x", + "resolve": "1.x", + "semver": "^5.5", + "yargs-parser": "10.x" + }, + "dependencies": { + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + }, + "yargs-parser": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz", + "integrity": "sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==", + "dev": true, + "requires": { + "camelcase": "^4.1.0" + } + } + } }, "tslib": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", - "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", + "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", "dev": true }, + "tslint": { + "version": "5.20.0", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.20.0.tgz", + "integrity": "sha512-2vqIvkMHbnx8acMogAERQ/IuINOq6DFqgF8/VDvhEkBqQh/x6SP0Y+OHnKth9/ZcHQSroOZwUQSN18v8KKF0/g==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "builtin-modules": "^1.1.1", + "chalk": "^2.3.0", + "commander": "^2.12.1", + "diff": "^4.0.1", + "glob": "^7.1.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "resolve": "^1.3.2", + "semver": "^5.3.0", + "tslib": "^1.8.0", + "tsutils": "^2.29.0" + } + }, + "tsutils": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", + "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + }, "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", @@ -7353,8 +5072,7 @@ "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true, - "optional": true + "dev": true }, "type-check": { "version": "0.3.2", @@ -7365,12 +5083,23 @@ "prelude-ls": "~1.1.2" } }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "typescript": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.6.3.tgz", + "integrity": "sha512-N7bceJL1CtRQ2RiG0AQME13ksR7DiuQh/QehubYcghzv20tnh+MQnQIuJddTmsbqYj+dztchykemz0zFzlvdQw==", "dev": true }, + "uglify-js": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.6.0.tgz", + "integrity": "sha512-W+jrUHJr3DXKhrsS7NUVxn3zqMOFn0hL/Ei6v0anCIMoKC93TjcflTagwIHLW7SfMFfiQuktQyFVCFHGUE0+yg==", + "dev": true, + "optional": true, + "requires": { + "commander": "~2.20.0", + "source-map": "~0.6.1" + } + }, "unicode-9.0.0": { "version": "0.7.5", "resolved": "https://registry.npmjs.org/unicode-9.0.0/-/unicode-9.0.0-0.7.5.tgz", @@ -7378,38 +5107,15 @@ "dev": true }, "union-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", - "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", "dev": true, "requires": { "arr-union": "^3.1.0", "get-value": "^2.0.6", "is-extendable": "^0.1.1", - "set-value": "^0.4.3" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "set-value": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", - "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.1", - "to-object-path": "^0.3.0" - } - } + "set-value": "^2.0.1" } }, "unset-value": { @@ -7449,22 +5155,9 @@ "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true } } }, - "upath": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.0.tgz", - "integrity": "sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw==", - "dev": true, - "optional": true - }, "uri-js": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", @@ -7472,14 +5165,6 @@ "dev": true, "requires": { "punycode": "^2.1.0" - }, - "dependencies": { - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true - } } }, "urix": { @@ -7494,34 +5179,22 @@ "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", "dev": true }, - "user-home": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz", - "integrity": "sha1-K1viOjK2Onyd640PKNSFcko98ZA=", - "dev": true - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "util.promisify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz", + "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==", "dev": true, - "optional": true + "requires": { + "define-properties": "^1.1.2", + "object.getownpropertydescriptors": "^2.0.3" + } }, "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz", + "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==", "dev": true }, - "v8flags": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-2.1.1.tgz", - "integrity": "sha1-qrGh+jDUX4jdMhFIh1rALAtV5bQ=", - "dev": true, - "requires": { - "user-home": "^1.1.1" - } - }, "validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", @@ -7543,6 +5216,56 @@ "extsprintf": "^1.2.0" } }, + "w3c-hr-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz", + "integrity": "sha1-gqwr/2PZUOqeMYmlimViX+3xkEU=", + "dev": true, + "requires": { + "browser-process-hrtime": "^0.1.2" + } + }, + "walker": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", + "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", + "dev": true, + "requires": { + "makeerror": "1.0.x" + } + }, + "webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", + "dev": true + }, + "whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "dev": true, + "requires": { + "iconv-lite": "0.4.24" + } + }, + "whatwg-mimetype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", + "dev": true + }, + "whatwg-url": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.5.0.tgz", + "integrity": "sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ==", + "dev": true, + "requires": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, "which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", @@ -7552,6 +5275,12 @@ "isexe": "^2.0.0" } }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, "window-size": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.3.0.tgz", @@ -7559,24 +5288,142 @@ "dev": true }, "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", "dev": true }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, - "write": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", - "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", + "write-file-atomic": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.1.tgz", + "integrity": "sha512-TGHFeZEZMnv+gBFRfjAcxL5bPHrsGKtnb4qsFAws7/vlh+QfwAaySIw4AXP9ZskTTh5GWu3FLuJhsWVdiJPGvg==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } + }, + "ws": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz", + "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==", + "dev": true, + "requires": { + "async-limiter": "~1.0.0" + } + }, + "xml-name-validator": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", + "dev": true + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "dev": true + }, + "yargs": { + "version": "13.3.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.0.tgz", + "integrity": "sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "yargs-parser": { + "version": "13.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", + "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", "dev": true, "requires": { - "mkdirp": "^0.5.1" + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" } } } diff --git a/package.json b/package.json index a9647e2..da52686 100644 --- a/package.json +++ b/package.json @@ -3,11 +3,14 @@ "version": "0.6.0", "description": "Natural language handling for commands and intents", "scripts": { - "test": "mocha --require @babel/register --recursive test/", - "coverage": "NODE_ENV=test nyc mocha --recursive test/", - "lint": "node_modules/.bin/eslint .", - "build": "node ./build/unicode.js && babel src --out-dir cjs", - "prepublish": "npm run build" + "test": "jest", + "test:watch": "jest --watch", + "ci": "npm run coverage", + "coverage": "jest --coverage", + "lint": "tslint --project tsconfig.json -t codeFrame 'src/**/*.ts' 'test/**/*.ts'", + "build": "tsc --module commonjs --target es5 --outDir dist/cjs && tsc --module es6 --target es6 --outDir dist/esm", + "prebuild": "rimraf dist", + "prepublishOnly": "npm run build" }, "license": "MIT", "repository": "aholstenson/ecolect-js", @@ -18,43 +21,33 @@ "commands", "parsing" ], - "main": "./cjs/index.js", - "module": "./src/index.js", + "main": "./dist/cjs/index.js", + "module": "./dist/esm/index.js", + "types": "./dist/types/index.d.ts", + "sideEffects": false, "engines": { "node": ">=8.0.0" }, "dependencies": { - "date-fns": "^2.0.0-alpha.22", - "fast-clone": "^1.5.3", - "fast-deep-equal": "^2.0.1", + "date-fns": "^2.4.0", + "fast-clone": "^1.5.13", + "fast-deep-equal": "^3.0.0-beta.2", "talisman": "^0.21.0" }, "devDependencies": { - "@babel/core": "^7.1.2", - "@babel/register": "^7.0.0", - "babel-cli": "^6.26.0", - "babel-eslint": "^10.0.1", - "babel-plugin-add-module-exports": "^1.0.0", - "babel-plugin-istanbul": "^5.1.0", - "babel-preset-env": "^1.7.0", - "chai": "^4.2.0", - "chai-as-promised": "^7.1.1", - "chalk": "^2.4.1", + "@types/jest": "^24.0.18", + "@types/jest-expect-message": "^1.0.0", + "chalk": "^2.4.2", "cli-autocomplete": "^0.4.1", - "coveralls": "^3.0.2", - "eslint": "^5.6.1", - "eslint-plugin-import": "^2.14.0", - "eslint-plugin-node": "^7.0.1", - "mocha": "^5.2.0", - "nyc": "^13.1.0", + "coveralls": "^3.0.6", + "jest": "^24.9.0", + "jest-config": "^24.9.0", + "jest-expect-message": "^1.0.2", "regenerate": "^1.4.0", + "rimraf": "^3.0.0", + "ts-jest": "^24.1.0", + "tslint": "^5.20.0", + "typescript": "^3.6.3", "unicode-9.0.0": "^0.7.5" - }, - "nyc": { - "require": [ - "@babel/register" - ], - "sourceMap": false, - "instrument": false } } diff --git a/src/@types/fast-deep-equal/es6.d.ts b/src/@types/fast-deep-equal/es6.d.ts new file mode 100644 index 0000000..51e2edb --- /dev/null +++ b/src/@types/fast-deep-equal/es6.d.ts @@ -0,0 +1,4 @@ +declare module 'fast-deep-equal/es6' { + const equal: (a: any, b: any) => boolean; + export = equal; +} diff --git a/src/@types/talisman/metrics/distance/jaro-winkler.d.ts b/src/@types/talisman/metrics/distance/jaro-winkler.d.ts new file mode 100644 index 0000000..42bbae4 --- /dev/null +++ b/src/@types/talisman/metrics/distance/jaro-winkler.d.ts @@ -0,0 +1,3 @@ +declare module 'talisman/metrics/distance/jaro-winkler' { + export function similarity(a: string, b: string): number; +} diff --git a/src/@types/talisman/stemmers/porter.d.ts b/src/@types/talisman/stemmers/porter.d.ts new file mode 100644 index 0000000..c5be34f --- /dev/null +++ b/src/@types/talisman/stemmers/porter.d.ts @@ -0,0 +1,5 @@ +declare module 'talisman/stemmers/porter' { + export = stem; + + function stem(input: string): string; +} diff --git a/src/@types/talisman/tokenizers/words/treebank.d.ts b/src/@types/talisman/tokenizers/words/treebank.d.ts new file mode 100644 index 0000000..d75f8e8 --- /dev/null +++ b/src/@types/talisman/tokenizers/words/treebank.d.ts @@ -0,0 +1,5 @@ +declare module 'talisman/tokenizers/words/treebank' { + export = tokenize; + + function tokenize(input: string): string[]; +} diff --git a/src/actions.js b/src/actions.js deleted file mode 100644 index f727059..0000000 --- a/src/actions.js +++ /dev/null @@ -1,85 +0,0 @@ -import { Builder as IntentsBuilder } from './intents'; - -export class Builder { - constructor(lang) { - this.builder = new IntentsBuilder(lang); - this.handlers = new Map(); - this.id = 0; - } - - action(id) { - // Auto assign an id - if(! id) id = ('__auto__' + ++this.id); - - const builder = this.builder.intent(id); - - const self = this; - builder.handler = function(handler) { - self.handlers.set(id, handler); - return this; - }; - - const previousDone = builder.done; - builder.done = function() { - previousDone.apply(this); - return self; - }; - - return builder; - } - - build() { - return new Actions(this.builder.build(), this.handlers); - } -} - -class Actions { - constructor(matcher, handlers) { - this.matcher = matcher; - this.handlers = handlers; - } - - get language() { - return this.matcher.language; - } - - match(expression, options) { - const map = item => { - if(! item) return item; - - item.activate = (...args) => { - const handler = this.handlers.get(item.intent); - const result = handler(item, ...args); - return Promise.resolve(result); - }; - - return item; - }; - - return this.matcher.match(expression, options) - .then(result => { - result.matches = result.matches.map(map); - result.best = map(result.best); - - return result; - }); - } - - handle(expression, options) { - return this.match(expression, options) - .then(result => { - if(! result.best) { - return Promise.resolve({ - intent: null - }); - } else { - const r = options && options.arguments ? result.best.activate(...options.arguments) : result.best.activate(); - return Promise.resolve(r) - .then(d => ({ - intent: result.best.intent, - result: d - })); - } - }); - } -} diff --git a/src/actions.ts b/src/actions.ts new file mode 100644 index 0000000..612fbf6 --- /dev/null +++ b/src/actions.ts @@ -0,0 +1,108 @@ +import { IntentsBuilder } from './intents'; +import { Language } from './language/language'; +import { LanguageSpecificValue, NodeConvertable } from './values/base'; +import { Matcher, EncounterOptions } from './graph/matching'; +import { ResolvedIntent } from './resolver/resolved-intent'; +import { ResolvedIntents } from './resolver/ResolvedIntents'; + +export type Action = (item: ResolvedIntent) => void; + +export class ActionsBuilder { + private builder: IntentsBuilder; + private handlers: Map; + private id: number; + + constructor(lang: Language) { + this.builder = new IntentsBuilder(lang); + this.handlers = new Map(); + this.id = 0; + } + + public action(id?: string): ActionBuilder { + // Auto assign an id + const actualId = id ? id : id = ('__auto__' + ++this.id); + + const builder = this.builder.intent(id); + + const self = this; + return { + value(id, type) { + builder.value(id, type); + return this; + }, + + add(...args) { + builder.add(...args); + return this; + }, + + handler(func) { + self.handlers.set(actualId, func); + return this; + }, + + done() { + builder.done(); + return self; + } + }; + } + + public build() { + return new Actions(this.builder.build(), this.handlers); + } +} + +export interface ActionBuilder { + value(id: string, type: LanguageSpecificValue | NodeConvertable): this; + + add(...args: string[]): this; + + handler(func: Action): this; + + done(): ActionsBuilder; +} + +export class Actions { + private handlers: Map; + private matcher: Matcher; + + constructor(matcher: Matcher, handlers: Map) { + this.matcher = matcher; + this.handlers = handlers; + } + + get language() { + return this.matcher.language; + } + + public match(expression: string, options: EncounterOptions): Promise { + const map = (item: ResolvedIntent): ResolvedAction => { + const result = item as any; + result.activate = (...args: any[]) => { + const handler = this.handlers.get(item.intent); + const r = handler(item, ...args); + return Promise.resolve(r); + }; + + return result; + }; + + return this.matcher.match(expression, options) + .then(result => { + return { + best: result.best ? map(result.best) : null, + matches: result.matches.map(map) + }; + }); + } +} + +export interface ResolvedAction extends ResolvedIntent { + activate: () => void; +} + +export interface ResolvedActions { + best: ResolvedAction | null; + matches: ResolvedAction[]; +} diff --git a/src/graph/builder.js b/src/graph/builder.ts similarity index 50% rename from src/graph/builder.js rename to src/graph/builder.ts index d6bdfd6..41f42f7 100644 --- a/src/graph/builder.js +++ b/src/graph/builder.ts @@ -1,23 +1,41 @@ -import Node from './node'; -import RegExpNode from './regexp'; -import TokenNode from './token'; -import SubNode from './sub'; -import CollectorNode from './collector'; -import CustomNode from './custom'; +import { Node } from './node'; +import { RegExpNode } from './regexp'; +import { TokenNode } from './token'; +import { SubNode } from './sub'; +import { CollectorNode, Collectable } from './collector'; +import { CustomNode, TokenValidator } from './custom'; + +import { Matcher, MatcherOptions, MatchReductionEncounter } from './matching/matcher'; +import { Language } from '../language/language'; +import { Encounter, Match } from './matching'; +import { Predicate } from '../utils/predicates'; -import Matcher from './matching/matcher'; +/** + * Object that can be mapped into another one. + */ +export interface MappableObject { + [x: string]: V; +} + +export type GraphBuildable = string | RegExp | Node | Matcher | ((builder: GraphBuilder) => Node); + +export type GraphBuildableArray = GraphBuildable | GraphBuildable[]; /** * Builder for a graph. This class is used to build matchers that can later * be used within the graph or standalone to match expressions. * */ -export default class GraphBuilder extends Node { - constructor(language) { - super(); +export class GraphBuilder { + protected language: Language; + private nodes: Node[]; + private options: MatcherOptions; + constructor(language: Language) { this.language = language; + this.nodes = []; + this.options = { supportsPartial: false, skipPunctuation: false, @@ -33,7 +51,7 @@ export default class GraphBuilder extends Node { * @return * self */ - name(name) { + public name(name: string): this { this.options.name = this.language.id + ':' + name; return this; } @@ -44,7 +62,7 @@ export default class GraphBuilder extends Node { * @return * self */ - allowPartial(active=true) { + public allowPartial(active=true): this { this.options.supportsPartial = active; return this; } @@ -55,7 +73,7 @@ export default class GraphBuilder extends Node { * @return * self */ - skipPunctuation(active=true) { + public skipPunctuation(active=true): this { this.options.skipPunctuation = active; return this; } @@ -66,7 +84,7 @@ export default class GraphBuilder extends Node { * @return * self */ - supportsFuzzy(active=true) { + public supportsFuzzy(active=true): this { this.options.supportsFuzzy = active; return this; } @@ -85,14 +103,14 @@ export default class GraphBuilder extends Node { * @param {Array|Node} nodes * @param {*} value */ - add(nodes, value) { + public add(nodes: GraphBuildableArray, value: Collectable): this { if(! Array.isArray(nodes)) { nodes = [ nodes ]; } let values = 0; - let last = this; - const push = node => { + let last: Node[] = this.nodes; + const push = (node: Node) => { if(! (node instanceof Node)) { throw new Error('Not a node: ' + node); } @@ -101,16 +119,16 @@ export default class GraphBuilder extends Node { * Check if we can attach to an existing node or if we need to * create a new branch. */ - for(let i=0; i { + const mergeOutgoing = (subNodes: Node[]) => { // TODO: This needs to handle multiple nodes and multiple outgoing - if(node.outgoing.length === 1) { - push(node.outgoing[0]); - } else if(node.outgoing.length > 1) { + if(subNodes.length === 1) { + push(subNodes[0]); + } else if(subNodes.length > 1) { throw new Error('Too many outgoing nodes, branching is not supported yet'); } }; - const createNode = n => { + const createNode = (n: GraphBuildable) => { if(typeof n === 'function') { const result = n(this); return push(result); @@ -156,9 +174,9 @@ export default class GraphBuilder extends Node { return this; } - parse(text) { + protected parse(text: string): Node { let first; - let last; + let last: Node; this.language.tokenize(text).forEach(t => { const node = new TokenNode(this.language, t); if(last) { @@ -168,60 +186,76 @@ export default class GraphBuilder extends Node { } last = node; }); + + if(! first) { + throw new Error('Could not parse data into nodes'); + } + return first; } - map(values, func) { - Object.keys(values).forEach(k => this.add(k, () => func(values[k]))); + public map(values: MappableObject, func: (value: D) => V | null) { + for(const key of Object.keys(values)) { + const value = values[key]; + this.add(key, () => func(value)); + } return this; } - mapResults(mapper) { - this.options.mapper = mapper; - - return this; + /** + * Setup a mapper that turns the intermediate representation into the + * public facing value type. + */ + public mapResults(mapper: (result: V, encounter: Encounter) => N): GraphBuilder { + const self = this as unknown as GraphBuilder; + self.options.mapper = mapper; + return self; } - finalizer(func) { - if(this.options.finalizer) { - // Chain finalizer if several are requested - const previous = this.options.finalizer; - this.options.finalizer = function(results, encounter) { - return func(previous(results, encounter)); - }; - } else { - this.options.finalizer = func; - } - return this; + /** + * Reduce the results down to a new object. This can be used to perform + * a transformation on all of the results at once. + * + * @param func + */ + public reducer(func: (results: MatchReductionEncounter) => NewR): GraphBuilder { + const self = this as unknown as GraphBuilder; + self.options.reducer = func; + return self; } - onlyBest() { - return this.finalizer((results, encounter) => { - let data = results[0] ? results[0].data : null; - if(data && this.options.mapper) { - data = this.options.mapper(data, encounter); + /** + * Reduce the results down so only the best match is returned when this + * matcher is queried. + */ + public onlyBest(): GraphBuilder { + return this.reducer(({ results, map }) => { + const match = results.first(); + if(match) { + return map(match.data); + } else { + return null; } - return data; }); } /** * Build this graph and turn it into a matcher. */ - toMatcher() { - return this.createMatcher(this.language, this.outgoing, this.options); + public toMatcher(): Matcher { + return this.createMatcher(this.language, this.nodes, this.options); } - createMatcher(lang, nodes, options) { + protected createMatcher(lang: Language, nodes: Node[], options: MatcherOptions) { return new Matcher(lang, nodes, options); } - static result(matcher, validator) { + public static result(matcher?: Matcher | Predicate, validator?: Predicate): (builder: GraphBuilder) => Node { if(typeof validator === 'undefined') { if(typeof matcher === 'function') { validator = matcher; - matcher = null; + matcher = undefined; } else if(matcher) { throw new Error('Expected graph or a validation function, got ' + matcher); } @@ -231,15 +265,15 @@ export default class GraphBuilder extends Node { throw new Error('matcher is not actually an instance of Matcher'); } - return function(builder) { - const sub = matcher + return function(builder: GraphBuilder) { + const sub = matcher instanceof Matcher ? new SubNode(matcher, matcher.options, validator) - : new SubNode(builder.outgoing, builder.options, validator); + : new SubNode(builder.nodes, builder.options as any, validator); sub.recursive = ! matcher; if(validator) { - let name = matcher ? matcher.options.name : builder.options.name; + let name = matcher instanceof Matcher ? matcher.options.name : builder.options.name; if(validator.name) { if(name) { name += ':' + validator.name; @@ -247,15 +281,16 @@ export default class GraphBuilder extends Node { name = validator.name; } } - sub.name = name; + sub.name = name || 'unknown'; } else if(! matcher) { sub.name = builder.options.name + ':self'; } + return sub; }; } - static custom(validator) { + public static custom(validator: TokenValidator) { return function() { return new CustomNode(validator); }; diff --git a/src/graph/collector.js b/src/graph/collector.js deleted file mode 100644 index 4025abb..0000000 --- a/src/graph/collector.js +++ /dev/null @@ -1,43 +0,0 @@ -import Node from './node'; - - -/** - * Node that generates a match based on the current values. - */ -export default class Collector extends Node { - constructor(depth, value) { - super(); - - this.depth = depth; - this.value = value; - } - - match(encounter) { - let value = this.value; - if(typeof value === 'function') { - /** - * For the case where the value is a function to be invoked slice - * the data based on the number of nodes used. This allows the - * parsers to use zero-based indexing instead of length - idx. - */ - let data = encounter.data(); - if(data.length > this.depth && data.length > 0) { - data = data.slice(data.length - this.depth); - } - value = value(data, encounter); - } - - if(typeof value !== 'undefined' && value !== null) { - // If the value is not undefined or null count it as a match - return encounter.match(value); - } - } - - toString() { - return 'Collector[' + this.value + ']'; - } - - toDot() { - return 'shape=diamond, label=""'; - } -} diff --git a/src/graph/collector.ts b/src/graph/collector.ts new file mode 100644 index 0000000..af8941c --- /dev/null +++ b/src/graph/collector.ts @@ -0,0 +1,64 @@ +import { Node } from './node'; +import { Encounter } from './matching'; + +/** + * Function that can resolve a value given data collected during graph + * evaluation. + */ +export type ValueResolver = (data: any[], encounter: Encounter) => V | null; + +/** + * Collectable value, either a value or a function to invoke to receive the + * value. + */ +export type Collectable = V | ValueResolver; + +/** + * Node that generates a match based on the current values. + */ +export class CollectorNode extends Node { + private depth: number; + private value: Collectable; + + constructor(depth: number, value: Collectable) { + super(); + + this.depth = depth; + this.value = value; + } + + public match(encounter: Encounter) { + let value: Collectable | null = this.value; + if(typeof value === 'function') { + /** + * For the case where the value is a function to be invoked slice + * the data based on the number of nodes used. This allows the + * parsers to use zero-based indexing instead of length - idx. + */ + let data = encounter.data(); + if(data.length > this.depth && data.length > 0) { + data = data.slice(data.length - this.depth); + } + value = (value as ValueResolver)(data, encounter); + } + + if(typeof value !== 'undefined' && value !== null) { + // If the value is not undefined or null count it as a match + return encounter.match(value); + } + } + + public equals(other: Node): boolean { + return other instanceof CollectorNode + && other.depth === this.depth + && other.value === this.value; + } + + public toString() { + return 'Collector[' + this.value + ']'; + } + + public toDot() { + return 'shape=diamond, label=""'; + } +} diff --git a/src/graph/custom.js b/src/graph/custom.js deleted file mode 100644 index 9f5a2cd..0000000 --- a/src/graph/custom.js +++ /dev/null @@ -1,34 +0,0 @@ -import Node from './node'; - -/** - * Node that will validate the current token against a custom function. - */ -export default class CustomNode extends Node { - constructor(validator) { - super(); - - this.validator = validator; - } - - match(encounter) { - const token = encounter.token(); - if(! token) return; - - return Promise.resolve(this.validator(token)) - .then(r => { - if(typeof r !== 'undefined' && r !== null) { - // This validator resolved a value, continue matching - return encounter.next(1, 1, r); - } - }); - } - - equals(other) { - return other instanceof CustomNode - && this.validator === other.validator; - } - - toDot() { - return 'label="Custom"'; - } -} diff --git a/src/graph/custom.ts b/src/graph/custom.ts new file mode 100644 index 0000000..8d4ec58 --- /dev/null +++ b/src/graph/custom.ts @@ -0,0 +1,40 @@ +import { Node } from './node'; +import { Token } from '../language/tokens/token'; +import { Encounter } from './matching/encounter'; + +export type TokenValidator = (token: Token) => Promise | boolean | null; + +/** + * Node that will validate the current token against a custom function. + */ +export class CustomNode extends Node { + private validator: TokenValidator; + + constructor(validator: TokenValidator) { + super(); + + this.validator = validator; + } + + public match(encounter: Encounter) { + const token = encounter.token(); + if(! token) return; + + return Promise.resolve(this.validator(token)) + .then(r => { + if(r != null && typeof r !== 'undefined') { + // This validator resolved a value, continue matching + return encounter.next(1, 1, r); + } + }); + } + + public equals(other: Node): boolean { + return other instanceof CustomNode + && this.validator === other.validator; + } + + public toDot() { + return 'label="Custom"'; + } +} diff --git a/src/graph/matching/encounter.js b/src/graph/matching/encounter.ts similarity index 72% rename from src/graph/matching/encounter.js rename to src/graph/matching/encounter.ts index 5ae4aa3..360f94c 100644 --- a/src/graph/matching/encounter.js +++ b/src/graph/matching/encounter.ts @@ -1,14 +1,66 @@ -import Match from './match'; -import MatchSet from './match-set'; +import { Match } from './match'; +import { MatchSet } from './match-set'; +import { Token } from '../../language/tokens/token'; +import { Node } from '../node'; + +import { DateTimeOptions } from '../../time/options'; +import { Tokens } from '../../language/tokens'; + +export interface EncounterOptions extends DateTimeOptions { + verbose?: boolean; + + partial?: boolean; + fuzzy?: boolean; + + onlyComplete?: boolean; + skipPunctuation?: boolean; + supportsPartial?: boolean; + supportsFuzzy?: boolean; + + matchIsEqual?: (a: any, b: any) => boolean; + onMatch?: (match: Match) => void; +} + +export type MatchHandler = (match: Match) => void; /** * Encounter used when trying to match an expression. Contains all the tokens - * and functions for accessinng tokens, the current index and the current + * and functions for accessing tokens, the current index and the current * score. */ -export default class Encounter { - constructor(lang, text, options) { - this.tokens = lang.tokenize(text); +export class Encounter { + /** + * Tokens that this encounter is working through. + */ + public tokens: Tokens; + + public currentIndex: number; + public currentScore: number; + public currentNodes: Node[]; + public currentTokens: number[]; + private currentData: any[]; + private currentDataDepth: number; + + public matches: MatchSet; + private maxDepth: number; + + private verbose: boolean; + private onlyComplete: boolean; + + public skipPunctuation: boolean; + + public supportsPartial: boolean; + public supportsFuzzy: boolean; + + private onMatch?: MatchHandler; + + public readonly options: EncounterOptions; + + public outgoing: Node[]; + private _cache: Map[]; + + constructor(tokens: Tokens, options: EncounterOptions) { + this.tokens = tokens; this.currentIndex = 0; this.currentScore = 0; @@ -22,27 +74,22 @@ export default class Encounter { this.maxDepth = 0; this.onMatch = options.onMatch; - this.verbose = options.verbose; + this.verbose = options.verbose || false; this.onlyComplete = options.onlyComplete || false; this.skipPunctuation = options.skipPunctuation || false; this.supportsPartial = options.supportsPartial || false; this.supportsFuzzy = options.supportsFuzzy || false; - // Turn some options into booleans - options.partial = !! options.partial; - options.fuzzy = !! options.fuzzy; - this.options = options; + this.outgoing = []; this._cache = []; } /** * Get the token at the given index, or at the current index. */ - token(index) { - if(typeof index === 'undefined') index = this.currentIndex; - + public token(index: number = this.currentIndex): Token { return this.tokens[index]; } @@ -66,7 +113,7 @@ export default class Encounter { return this.options.partial && this.supportsPartial; } - data() { + public data() { return this.currentDataDepth > 0 ? this.currentData.slice(this.currentDataDepth) : this.currentData; @@ -78,8 +125,8 @@ export default class Encounter { * For every outgoing node: * - Run the match method, checking if it matches */ - next(score, consumedTokens, data) { - let nextIndex = this.currentIndex + (consumedTokens || 0); + public next(score: number, consumedTokens: number, data?: any): Promise { + const nextIndex = this.currentIndex + (consumedTokens || 0); const nextScore = this.currentScore + (score || 0); let nextIndexAfterPunctuation = nextIndex; @@ -108,7 +155,7 @@ export default class Encounter { * * @param {Node} node */ - const branchInto = node => () => { + const branchInto = (node: Node) => () => { this.maxDepth = Math.max(this.maxDepth, this.currentNodes.length); // Switch to the next index and score @@ -180,14 +227,16 @@ export default class Encounter { * * @param {array} nodes */ - branchInto(nodes) { + public branchInto(nodes: Node[]): Promise { const outgoing = this.outgoing; this.outgoing = nodes; - return this.next() - .then(() => this.outgoing = outgoing); + return this.next(0, 0) + .then(() => { + this.outgoing = outgoing; + }); } - branchWithOnMatch(newOnMatch, func) { + public branchWithOnMatch(newOnMatch: MatchHandler, func: () => Promise | any): Promise { const onMatch = this.onMatch; const currentDataDepth = this.currentDataDepth; this.onMatch = newOnMatch; @@ -210,7 +259,7 @@ export default class Encounter { /** * Read any punctuation we can. */ - readPunctuation() { + public readPunctuation() { let token = this.tokens[this.currentIndex]; while(token && token.punctuation) { token = this.tokens[++this.currentIndex]; @@ -224,7 +273,7 @@ export default class Encounter { * non-punctuation token. Used by SubNodes to allow puncutation to be * used both the parent parser and the sub-parser. */ - previousNonSkipped() { + public previousNonSkipped(): number { if(! this.skipPunctuation) return this.currentIndex; let idx = this.currentIndex - 1; @@ -235,20 +284,20 @@ export default class Encounter { return idx + 1; } - remainingTokens() { + public remainingTokens() { return this.tokens.slice(this.currentIndex); } /** * Push the current match onto the result. */ - match(data) { + public match(data: any) { let match; if(data instanceof Match) { match = data; } else { - let scoreData = { - partial: this.options.partial, + const scoreData = { + partial: this.options.partial || false, tokens: this.tokens.length, depth: this.currentIndex, score: this.currentScore @@ -276,7 +325,7 @@ export default class Encounter { * * @param {number} index */ - cache(index=this.currentIndex) { + public cache(index=this.currentIndex): Map { let map = this._cache[index]; if(map) return map; diff --git a/src/graph/matching/index.ts b/src/graph/matching/index.ts new file mode 100644 index 0000000..4e179fd --- /dev/null +++ b/src/graph/matching/index.ts @@ -0,0 +1,5 @@ +export * from './encounter'; +export * from './matcher'; +export * from './match-set'; +export * from './match'; +export * from './matching-state'; diff --git a/src/graph/matching/match-set.js b/src/graph/matching/match-set.ts similarity index 78% rename from src/graph/matching/match-set.js rename to src/graph/matching/match-set.ts index 1665d9a..a4c11d4 100644 --- a/src/graph/matching/match-set.js +++ b/src/graph/matching/match-set.ts @@ -1,6 +1,7 @@ import { isDeepEqual } from '../../utils/equality'; +import { Match } from './match'; -function binarySearch(items, fromIndex, toIndex, key) { +function binarySearch(items: Match[], fromIndex: number, toIndex: number, key: number) { let low = fromIndex; let high = toIndex - 1; while(low <= high) { @@ -25,7 +26,7 @@ function binarySearch(items, fromIndex, toIndex, key) { * * @param {number} score */ -function findInsertLocation(matches, score) { +function findInsertLocation(matches: Match[], score: number) { const idx = binarySearch(matches, 0, matches.length, score); if(idx < 0) { @@ -44,6 +45,10 @@ function findInsertLocation(matches, score) { return matches.length; } +export interface MatchSetOptions { + isEqual?: (a: any, b: any) => boolean; +} + /** * Set that helps with keeping track of matches. This set will always keep * matches ordered by score in descending order. @@ -52,9 +57,11 @@ function findInsertLocation(matches, score) { * only a single match should be kept, such as only a single intent with the * highest score. */ -export default class MatchSet { +export class MatchSet { + private matches: Match[]; + private isEqual: (a: any, b: any) => boolean; - constructor(options={}) { + constructor(options: MatchSetOptions = {}) { this.matches = []; this.isEqual = options.isEqual || isDeepEqual; } @@ -64,7 +71,7 @@ export default class MatchSet { * * @param {Match} match */ - add(match) { + public add(match: Match) { // Check if this is a duplicate match for(let i=0; i { + return this.matches[0]; + } + /** * Get an iterator for this set. */ - [Symbol.iterator]() { + public [Symbol.iterator]() { return this.matches[Symbol.iterator](); } /** * Get the array representation of this set. */ - toArray() { + public toArray(): Match[] { return this.matches; } } diff --git a/src/graph/matching/match.js b/src/graph/matching/match.ts similarity index 64% rename from src/graph/matching/match.js rename to src/graph/matching/match.ts index 6793869..f01bb1d 100644 --- a/src/graph/matching/match.js +++ b/src/graph/matching/match.ts @@ -1,7 +1,21 @@ import { clone } from '../../utils/cloning'; -export default class Match { - constructor(index, data, scoreData) { +export interface ScoreData { + partial: boolean; + + depth: number; + + score: number; + + tokens: number; +} + +export class Match { + public index: number; + public data: V; + public scoreData: ScoreData; + + constructor(index: number, data: V, scoreData: ScoreData) { this.index = index; this.scoreData = scoreData; this.data = data; @@ -15,7 +29,7 @@ export default class Match { } } - copy() { + public copy() { return new Match(this.index, clone(this.data), clone(this.scoreData)); } } @@ -25,13 +39,13 @@ export default class Match { * scores higher with a normalized score added to differentiate between hits * at the same depth. */ -function scorePartial(scoreData) { +function scorePartial(scoreData: ScoreData) { return 1 / scoreData.depth + scoreData.score / scoreData.depth; } /** * Normal */ -function scoreNormal(scoreData) { +function scoreNormal(scoreData: ScoreData) { return scoreData.score / scoreData.tokens; } diff --git a/src/graph/matching/matcher.js b/src/graph/matching/matcher.js deleted file mode 100644 index e96f299..0000000 --- a/src/graph/matching/matcher.js +++ /dev/null @@ -1,43 +0,0 @@ -import Encounter from './encounter'; - -/** - * Matcher that can match expressions against a graph. - */ -export default class Matcher { - constructor(language, nodes, options={}) { - this.language = language; - this.nodes = nodes; - - this.options = options; - this._cache = {}; - } - - /** - * Match against the given expression. - * - * @param {string} expression - * @param {object} options - * @return {Promise} - */ - match(expression, options={}) { - if(typeof expression !== 'string') { - throw new Error('Can only match against string expressions'); - } - - const encounter = new Encounter(this.language, expression, Object.assign({ - onlyComplete: true - }, this.options, options)); - encounter.outgoing = this.nodes; - - let promise = encounter.next(0, 0) - .then(() => { - return encounter.matches.toArray(); - }); - - if(this.options.finalizer) { - promise = promise.then(results => this.options.finalizer(results, encounter)); - } - - return promise; - } -} diff --git a/src/graph/matching/matcher.ts b/src/graph/matching/matcher.ts new file mode 100644 index 0000000..20bb568 --- /dev/null +++ b/src/graph/matching/matcher.ts @@ -0,0 +1,97 @@ +import { Encounter, EncounterOptions } from './encounter'; +import { Language } from '../../language/language'; +import { Node } from '../node'; + +import { MatchingState, emptyState } from './matching-state'; +import { MatchSet } from './match-set'; + +export interface MatchReductionEncounter { + encounter: Encounter; + + results: MatchSet; + + map: (object: RawData) => MappedData; +} + +export interface MatcherOptions extends EncounterOptions { + name?: string; + + reducer?: (reduction: MatchReductionEncounter) => V; + + mapper?: (result: any, encounter: Encounter) => any; +} + +/** + * Matcher that can match expressions against a graph. + */ +export class Matcher { + public readonly language: Language; + public readonly nodes: Node[]; + public readonly options: MatcherOptions; + + /** + * Internal state of this matcher that is accessed if it is used as a + * sub graph. + */ + public matchingState: MatchingState; + + constructor(language: Language, nodes: Node[], options: MatcherOptions) { + this.language = language; + this.nodes = nodes; + + this.options = options; + this.matchingState = emptyState(); + } + + /** + * Match against the given expression. + * + * @param {string} expression + * @param {object} options + * @return {Promise} + */ + public match(expression: string, options: EncounterOptions={}): Promise { + if(typeof expression !== 'string') { + throw new Error('Can only match against string expressions'); + } + + const resolvedOptions = Object.assign({ + onlyComplete: true + }, this.options, options); + + const tokens = this.language.tokenize(expression); + const encounter = new Encounter(tokens, resolvedOptions); + encounter.outgoing = this.nodes; + + const promise = encounter.next(0, 0) + .then(() => { + return encounter.matches; + }); + + if(this.options.reducer) { + const reducer = this.options.reducer; + return promise.then((results: MatchSet) => reducer({ + results, + encounter, + map: (object: any) => this.options.mapper + ? this.options.mapper(object, encounter) + : object + } + )); + } else { + return promise.then((results: MatchSet) => { + const asArray = results.toArray(); + let mapped; + if(this.options.mapper) { + const mapper = this.options.mapper; + mapped = asArray.map(match => mapper(match.data, encounter)); + } else { + mapped = asArray.map(match => match.data); + } + + // Forcefully convert into V type + return mapped as unknown as V; + }); + } + } +} diff --git a/src/graph/matching/matching-state.ts b/src/graph/matching/matching-state.ts new file mode 100644 index 0000000..5945192 --- /dev/null +++ b/src/graph/matching/matching-state.ts @@ -0,0 +1,10 @@ +export interface MatchingState { + currentIndex: number; + +} + +export function emptyState(): MatchingState { + return { + currentIndex: -1 + }; +} diff --git a/src/graph/node.js b/src/graph/node.js deleted file mode 100644 index 3d44cb8..0000000 --- a/src/graph/node.js +++ /dev/null @@ -1,9 +0,0 @@ -export default class Node { - constructor() { - this.outgoing = []; - } - - equals() { - return false; - } -} diff --git a/src/graph/node.ts b/src/graph/node.ts new file mode 100644 index 0000000..0d5a96e --- /dev/null +++ b/src/graph/node.ts @@ -0,0 +1,18 @@ +import { Encounter } from './matching/encounter'; + +/** + * The base class for nodes. + */ +export abstract class Node { + public outgoing: Node[]; + public supportsPunctuation: boolean; + + constructor() { + this.outgoing = []; + this.supportsPunctuation = false; + } + + public abstract match(encounter: Encounter): void | Promise; + + public abstract equals(other: Node): boolean; +} diff --git a/src/graph/regexp.js b/src/graph/regexp.ts similarity index 64% rename from src/graph/regexp.js rename to src/graph/regexp.ts index f68f8b0..dd5ac73 100644 --- a/src/graph/regexp.js +++ b/src/graph/regexp.ts @@ -1,22 +1,25 @@ -import Node from './node'; +import { Node } from './node'; +import { Encounter } from './matching/encounter'; /** * Node that matches a token against a regular expression. */ -export default class RegExpNode extends Node { - constructor(regexp) { +export class RegExpNode extends Node { + private regexp: RegExp; + + constructor(regexp: RegExp) { super(); this.regexp = regexp; } - match(encounter) { + public match(encounter: Encounter) { // If there is no token available - skip this node const token = encounter.token(); if(! token) return; // Reset and check the regular expression - this.regexp.previousIndex = 0; + this.regexp.lastIndex = 0; const match = this.regexp.exec(token.raw); if(! match) return; @@ -24,15 +27,15 @@ export default class RegExpNode extends Node { return encounter.next(1, 1, match[0]); } - equals(other) { + public equals(other: Node): boolean { return other instanceof RegExpNode && this.regexp.source === other.regexp.source; } - toString() { + public toString(): string { return 'RegExp[' + this.regexp + ']'; } - toDot() { + public toDot(): string { return 'label="' + this.regexp + '"'; } } diff --git a/src/graph/sub.js b/src/graph/sub.ts similarity index 72% rename from src/graph/sub.js rename to src/graph/sub.ts index 44b0ff2..04e891e 100644 --- a/src/graph/sub.js +++ b/src/graph/sub.ts @@ -1,7 +1,6 @@ -import Node from './node'; -import Matcher from './matching/matcher'; - -const ALWAYS_TRUE = () => true; +import { Node } from './node'; +import { Matcher, MatcherOptions, Encounter, Match, MatchingState, emptyState } from './matching'; +import { Predicate, alwaysTruePredicate } from '../utils/predicates'; /* * Small penalty applied when a SubNode matches. This helps the algorithm @@ -11,6 +10,15 @@ const ALWAYS_TRUE = () => true; */ const PARSER_PENALTY = 0.001; +/** + * A variant as resolved by the sub-graph. Used for caching of data. + */ +interface Variant { + index: number; + score: number; + data: any; +} + /** * Node that points to a sub-graph that should be evaluated as part of another * graph. This type of node will resolve all variants it can starting from the @@ -21,32 +29,53 @@ const PARSER_PENALTY = 0.001; * nodes will be evaluated both against both matches, so it will be invoked * once starting from `T3` and once from `T4`. */ -export default class SubNode extends Node { - constructor(roots, options, filter) { +export class SubNode extends Node { + private roots: Node[]; + private state: MatchingState; + + public name: string; + + public recursive: boolean; + public supportsPartial: boolean; + private skipPunctuation: boolean; + private supportsFuzzy: boolean; + + private filter: Predicate; + public mapper: ((result: any, encounter: Encounter) => any) | undefined; + + /** + * Fallback value to apply in case this is a partial match and the graph + * doesn't fully match. + */ + public partialFallback?: any; + + constructor(roots: Matcher | Node[], options: MatcherOptions, filter?: Predicate) { super(); - this.filter = filter || ALWAYS_TRUE; + this.recursive = false; + this.filter = filter || alwaysTruePredicate; if(roots instanceof Matcher) { // Roots is actually a matcher, copy the graph from the matcher this.roots = roots.nodes; - this.state = roots._cache; + this.state = roots.matchingState; } else { this.roots = roots; - this.state = options.state || this; + this.state = emptyState(); } this.supportsPartial = options.supportsPartial || false; - this.name = options.name || null; + this.name = options.name || 'unknown'; this.skipPunctuation = options.skipPunctuation || false; this.supportsFuzzy = options.supportsFuzzy || false; + //this.mapper = options.mapper; } - match(encounter) { + public match(encounter: Encounter) { if(this.state.currentIndex === encounter.currentIndex) { /* * If this node is called with the same index again we skip - * evaulating. + * evaluating. */ return; } @@ -62,9 +91,9 @@ export default class SubNode extends Node { if(! this.supportsPartial) { /** - * Partial match for nothing without support for it. Assume - * we will match in the future. - */ + * Partial match for nothing without support for it. Assume + * we will match in the future. + */ return; } } @@ -73,8 +102,8 @@ export default class SubNode extends Node { const previousIndex = this.state.currentIndex; this.state.currentIndex = encounter.currentIndex; - const variants = []; - const branchIntoVariants = variants0 => { + const variants: Variant[] = []; + const branchIntoVariants = (variants0: Variant[]) => { let promise; if(variants0.length === 0) { @@ -109,14 +138,14 @@ export default class SubNode extends Node { // Check the cache const cache = encounter.cache(); - let cached = cache.get(this.roots); + const cached = cache.get(this.roots); if(cached) { return branchIntoVariants(cached); } const baseScore = encounter.currentScore; - const onMatch = match => { - let result = match.data; + const onMatch = (match: Match) => { + let result: V | null = match.data; if(result !== null && typeof result !== 'undefined') { if(this.mapper) { result = this.mapper(result, encounter); @@ -164,8 +193,8 @@ export default class SubNode extends Node { }); } - equals(other) { - function arrayEquals(a, b) { + public equals(other: Node): boolean { + function arrayEquals(a: E[], b: E[]) { if(a.length !== b.length) return false; for(let i=0; i> = new Map(); + + public abstract readonly id: string; + + public abstract tokenize(input: string): Tokens; + + public abstract compareTokens(a: Token, b: Token): number; + + public abstract comparePartialTokens(a: Token, b: Token): number; + + public abstract repeating(matcher: Matcher): GraphBuilder; + + public matcher(factory: ValueMatcherFactory): Matcher { + const result = this.cachedMatchers.get(factory.id); + if(result) { + return result; + } + + const created = factory.create(this); + this.cachedMatchers.set(factory.id, created); + return created; + } + + public findMatcher(id: string): Matcher | null { + return this.cachedMatchers.get(id) || null; + } + + public getMatcher(id: string): Matcher { + const result = this.cachedMatchers.get(id); + if(! result) { + throw new Error('No matcher with id `' + id + '` available'); + } + + return result; + } +} diff --git a/src/language/en/boolean.js b/src/language/en/boolean.js deleted file mode 100644 index 304e5be..0000000 --- a/src/language/en/boolean.js +++ /dev/null @@ -1,18 +0,0 @@ -import GraphBuilder from '../../graph/builder'; - -export default function(language) { - return new GraphBuilder(language) - .name('boolean') - - .add('true', true) - .add('on', true) - .add('yes', true) - - .add('false', false) - .add('off', false) - .add('no', false) - - .onlyBest() - - .toMatcher(); -} diff --git a/src/language/en/boolean.ts b/src/language/en/boolean.ts new file mode 100644 index 0000000..538d4e9 --- /dev/null +++ b/src/language/en/boolean.ts @@ -0,0 +1,24 @@ +import { GraphBuilder } from '../../graph/builder'; +import { ValueMatcherFactory } from '../value-matcher-factory'; +import { Language } from '../language'; + +export const booleanMatcher: ValueMatcherFactory = { + id: 'boolean', + + create(language: Language) { + return new GraphBuilder(language) + .name('boolean') + + .add('true', true) + .add('on', true) + .add('yes', true) + + .add('false', false) + .add('off', false) + .add('no', false) + + .onlyBest() + + .toMatcher(); + } +}; diff --git a/src/language/en/date-duration.js b/src/language/en/date-duration.js deleted file mode 100644 index ccf5860..0000000 --- a/src/language/en/date-duration.js +++ /dev/null @@ -1,35 +0,0 @@ -import GraphBuilder from '../../graph/builder'; - -import { combine } from '../../time/matching'; -import { map } from '../../time/durations'; - -export default function(language) { - const integer = language.integer; - - return new GraphBuilder(language) - .name('date-duration') - - .skipPunctuation() - - .add([ integer, 'years' ], v => ({ relativeYears: v[0].value })) - .add([ integer, 'yrs' ], v => ({ relativeYears: v[0].value })) - .add([ integer, 'y' ], v => ({ relativeYears: v[0].value })) - .add([ integer, 'quarters' ], v => ({ relativeQuarters: v[0].value })) - .add([ integer, 'q' ], v => ({ relativeQuarters: v[0].value })) - .add([ integer, 'weeks' ], v => ({ relativeWeeks: v[0].value })) - .add([ integer, 'wks' ], v => ({ relativeWeeks: v[0].value })) - .add([ integer, 'w' ], v => ({ relativeWeeks: v[0].value })) - .add([ integer, 'months' ], v => ({ relativeMonths: v[0].value })) - .add([ integer, 'mths' ], v => ({ relativeMonths: v[0].value })) - .add([ integer, 'mon' ], v => ({ relativeMonths: v[0].value })) - .add([ integer, 'm' ], v => ({ relativeMonths: v[0].value })) - .add([ integer, 'days' ], v => ({ relativeDays: v[0].value })) - .add([ integer, 'd' ], v => ({ relativeDays: v[0].value })) - - .add([ GraphBuilder.result(), GraphBuilder.result() ], v => combine(v[0], v[1])) - .add([ GraphBuilder.result(), 'and', GraphBuilder.result() ], v => combine(v[0], v[1])) - - .mapResults(map) - .onlyBest() - .toMatcher(); -} diff --git a/src/language/en/date-duration.ts b/src/language/en/date-duration.ts new file mode 100644 index 0000000..359cf17 --- /dev/null +++ b/src/language/en/date-duration.ts @@ -0,0 +1,44 @@ +import { ValueMatcherFactory } from '../value-matcher-factory'; +import { Language } from '../language'; +import { GraphBuilder } from '../../graph/builder'; + +import { integerMatcher } from './integer'; + +import { DateTimeData } from '../../time/date-time-data'; +import { combine } from '../../time/matching'; +import { map, Duration } from '../../time/durations'; + +export const dateDurationMatcher: ValueMatcherFactory = { + id: 'date-duration', + + create(language: Language) { + const integer = language.matcher(integerMatcher); + + return new GraphBuilder(language) + .name('date-duration') + + .skipPunctuation() + + .add([ integer, 'years' ], v => ({ relativeYears: v[0].value })) + .add([ integer, 'yrs' ], v => ({ relativeYears: v[0].value })) + .add([ integer, 'y' ], v => ({ relativeYears: v[0].value })) + .add([ integer, 'quarters' ], v => ({ relativeQuarters: v[0].value })) + .add([ integer, 'q' ], v => ({ relativeQuarters: v[0].value })) + .add([ integer, 'weeks' ], v => ({ relativeWeeks: v[0].value })) + .add([ integer, 'wks' ], v => ({ relativeWeeks: v[0].value })) + .add([ integer, 'w' ], v => ({ relativeWeeks: v[0].value })) + .add([ integer, 'months' ], v => ({ relativeMonths: v[0].value })) + .add([ integer, 'mths' ], v => ({ relativeMonths: v[0].value })) + .add([ integer, 'mon' ], v => ({ relativeMonths: v[0].value })) + .add([ integer, 'm' ], v => ({ relativeMonths: v[0].value })) + .add([ integer, 'days' ], v => ({ relativeDays: v[0].value })) + .add([ integer, 'd' ], v => ({ relativeDays: v[0].value })) + + .add([ GraphBuilder.result(), GraphBuilder.result() ], v => combine(v[0], v[1])) + .add([ GraphBuilder.result(), 'and', GraphBuilder.result() ], v => combine(v[0], v[1])) + + .mapResults(map) + .onlyBest() + .toMatcher(); + } +}; diff --git a/src/language/en/date-interval.js b/src/language/en/date-interval.js deleted file mode 100644 index 6cd6f94..0000000 --- a/src/language/en/date-interval.js +++ /dev/null @@ -1,47 +0,0 @@ -import GraphBuilder from '../../graph/builder'; - -import { between, until, before, from, after } from '../../time/matching'; -import { hasSingle, map, inThePast, inTheFuture, anyTime } from '../../time/date-intervals'; - -export default function(language) { - const date = language.date; - - return new GraphBuilder(language) - .name('date-interval') - - .add('any time', anyTime) - .add('at any time', anyTime) - - .add('in the past', inThePast) - .add('past', inThePast) - - .add('in the future', inTheFuture) - .add('future', inTheFuture) - - .add(date, between) - - // X to Y - // January to February - // January 2010 to March 2011 - // 2010-01-01 to 2010-02-05 - // February to 2020 - .add([ GraphBuilder.result(hasSingle), 'to', GraphBuilder.result(hasSingle) ], between) - .add([ GraphBuilder.result(hasSingle), 'until', GraphBuilder.result(hasSingle) ], between) - .add([ GraphBuilder.result(hasSingle), '-', GraphBuilder.result(hasSingle) ], between) - .add([ GraphBuilder.result(hasSingle), 'and', GraphBuilder.result(hasSingle) ], between) - - .add([ 'before', date ], before) - .add([ 'after', date ], after) - - .add([ 'until', date ], until) - .add([ 'til', date ], until) - .add([ 'from', date ], from) - - .add([ 'from', GraphBuilder.result() ], v => v[0]) - .add([ 'between', GraphBuilder.result() ], v => v[0]) - - .mapResults(map) - - .onlyBest() - .toMatcher(); -} diff --git a/src/language/en/date-interval.ts b/src/language/en/date-interval.ts new file mode 100644 index 0000000..4ee1ab3 --- /dev/null +++ b/src/language/en/date-interval.ts @@ -0,0 +1,54 @@ +import { GraphBuilder } from '../../graph/builder'; +import { ValueMatcherFactory } from '../value-matcher-factory'; + +import { between, until, before, from, after } from '../../time/matching'; +import { hasSingle, map, inThePast, inTheFuture, anyTime } from '../../time/date-intervals'; +import { IntervalValue } from '../../time/interval-value'; +import { dateMatcher } from './date'; +import { IntervalData } from '../../time/interval-data'; + +export const dateIntervalMatcher: ValueMatcherFactory = { + id: 'date-interval', + + create(language) { + const date = language.matcher(dateMatcher); + + return new GraphBuilder(language) + .name('date-interval') + + .add('any time', anyTime) + .add('at any time', anyTime) + + .add('in the past', inThePast) + .add('past', inThePast) + + .add('in the future', inTheFuture) + .add('future', inTheFuture) + + .add(date, v => between(v[0])) + + // X to Y + // January to February + // January 2010 to March 2011 + // 2010-01-01 to 2010-02-05 + // February to 2020 + .add([ GraphBuilder.result(hasSingle), 'to', GraphBuilder.result(hasSingle) ], v => between(v[0], v[1])) + .add([ GraphBuilder.result(hasSingle), 'until', GraphBuilder.result(hasSingle) ], v => between(v[0], v[1])) + .add([ GraphBuilder.result(hasSingle), '-', GraphBuilder.result(hasSingle) ], v => between(v[0], v[1])) + .add([ GraphBuilder.result(hasSingle), 'and', GraphBuilder.result(hasSingle) ], v => between(v[0], v[1])) + + .add([ 'before', date ], v => before(v[0])) + .add([ 'after', date ], v => after(v[0])) + + .add([ 'until', date ], v => until(v[0])) + .add([ 'til', date ], v => until(v[0])) + .add([ 'from', date ], v => from(v[0])) + + .add([ 'from', GraphBuilder.result() ], v => v[0]) + .add([ 'between', GraphBuilder.result() ], v => v[0]) + + .mapResults(map) + .onlyBest() + .toMatcher(); + } +}; diff --git a/src/language/en/date-time-duration.js b/src/language/en/date-time-duration.js deleted file mode 100644 index 534fb00..0000000 --- a/src/language/en/date-time-duration.js +++ /dev/null @@ -1,24 +0,0 @@ -import GraphBuilder from '../../graph/builder'; - -import { combine } from '../../time/matching'; -import { map } from '../../time/durations'; - -export default function(language) { - const timeDuration = language.timeDuration; - const dateDuration = language.dateDuration; - - return new GraphBuilder(language) - .name('date-time-duration') - - .skipPunctuation() - - .add(timeDuration, v => v[0]) - .add(dateDuration, v => v[0]) - - .add([ GraphBuilder.result(), GraphBuilder.result() ], v => combine(v[0], v[1])) - .add([ GraphBuilder.result(), 'and', GraphBuilder.result() ], v => combine(v[0], v[1])) - - .mapResults(map) - .onlyBest() - .toMatcher(); -} diff --git a/src/language/en/date-time-duration.ts b/src/language/en/date-time-duration.ts new file mode 100644 index 0000000..117c539 --- /dev/null +++ b/src/language/en/date-time-duration.ts @@ -0,0 +1,32 @@ +import { GraphBuilder } from '../../graph/builder'; +import { ValueMatcherFactory } from '../value-matcher-factory'; + +import { combine } from '../../time/matching'; +import { map, Duration } from '../../time/durations'; +import { timeDurationMatcher } from './time-duration'; +import { dateDurationMatcher } from './date-duration'; +import { DateTimeData } from '../../time/date-time-data'; + +export const dateTimeDurationMatcher: ValueMatcherFactory = { + id: 'date-time-duration', + + create(language) { + const timeDuration = language.matcher(timeDurationMatcher); + const dateDuration = language.matcher(dateDurationMatcher); + + return new GraphBuilder(language) + .name('date-time-duration') + + .skipPunctuation() + + .add(timeDuration, v => v[0]) + .add(dateDuration, v => v[0]) + + .add([ GraphBuilder.result(), GraphBuilder.result() ], v => combine(v[0], v[1])) + .add([ GraphBuilder.result(), 'and', GraphBuilder.result() ], v => combine(v[0], v[1])) + + .mapResults(map) + .onlyBest() + .toMatcher(); + } +}; diff --git a/src/language/en/date-time.js b/src/language/en/date-time.js deleted file mode 100644 index b619d4a..0000000 --- a/src/language/en/date-time.js +++ /dev/null @@ -1,29 +0,0 @@ -import GraphBuilder from '../../graph/builder'; - -import { combine, isRelative } from '../../time/matching'; -import { map } from '../../time/date-times'; - -export default function(language) { - const time = language.time; - const date = language.date; - - return new GraphBuilder(language) - .name('date-time') - - .skipPunctuation() - - .add(time, v => v[0]) - .add(date, v => v[0]) - - .add([ time, date ], v => combine(v[0], v[1])) - .add([ time, 'and', date ], v => combine(v[0], v[1])) - - .add([ date, time ], v => combine(v[0], v[1])) - .add([ date, 'and', time ], v => combine(v[0], v[1])) - - .add(GraphBuilder.result(date, isRelative), (v, e) => v[0]) - - .mapResults(map) - .onlyBest() - .toMatcher(); -} diff --git a/src/language/en/date-time.ts b/src/language/en/date-time.ts new file mode 100644 index 0000000..15e58cf --- /dev/null +++ b/src/language/en/date-time.ts @@ -0,0 +1,38 @@ +import { GraphBuilder } from '../../graph/builder'; +import { ValueMatcherFactory } from '../value-matcher-factory'; +import { DateValue } from '../../time/date-value'; +import { DateTimeData } from '../../time/date-time-data'; + +import { combine, isRelative } from '../../time/matching'; +import { map } from '../../time/date-times'; +import { dateMatcher } from './date'; +import { timeMatcher } from './time'; + +export const dateTimeMatcher: ValueMatcherFactory = { + id: 'date-time', + + create(language) { + const time = language.matcher(timeMatcher); + const date = language.matcher(dateMatcher); + + return new GraphBuilder(language) + .name('date-time') + + .skipPunctuation() + + .add(time, v => v[0]) + .add(date, v => v[0]) + + .add([ time, date ], v => combine(v[0], v[1])) + .add([ time, 'and', date ], v => combine(v[0], v[1])) + + .add([ date, time ], v => combine(v[0], v[1])) + .add([ date, 'and', time ], v => combine(v[0], v[1])) + + .add(GraphBuilder.result(date, isRelative), (v, e) => v[0]) + + .mapResults(map) + .onlyBest() + .toMatcher(); + } +}; diff --git a/src/language/en/date.js b/src/language/en/date.js deleted file mode 100644 index 09c06dd..0000000 --- a/src/language/en/date.js +++ /dev/null @@ -1,240 +0,0 @@ -import GraphBuilder from '../../graph/builder'; - -import { - combine, - isRelative, - startOf, - endOf, - isWeek, - isMonth, - hasMonth, - reverse -} from '../../time/matching'; -import { thisWeek } from '../../time/weeks'; -import { thisQuarter } from '../../time/quarters'; -import { map, today, yesterday, tomorrow, dayAfterTomorrow } from '../../time/dates'; - -function value(v) { - if(Array.isArray(v)) { - if(v[0] === v) return null; - - return value(v[0]); - } else if(v && v.value) { - return v.value; - } - - return v; -} - -function withDay(date, day) { - return combine(date, { - day: value(day) - }); -} - -function withYear(v) { - const year = parseInt(value(v[1])); - return combine(v[0], { - year: year < 1000 ? year + 2000 : year - }); -} - -function nextDayOfWeek(v) { - return { dayOfWeek: v[0].value }; -} - -export default function(language) { - const ordinal = language.ordinal; - const dayOfWeek = language.dayOfWeek; - const year = language.year; - const quarter = language.quarter; - const week = language.week; - const month = language.month; - const dateDuration = language.dateDuration; - - const day = GraphBuilder.result(ordinal, v => v.value >= 0 && v.value < 31); - - return new GraphBuilder(language) - .name('date') - - .skipPunctuation() - - // Relative - .add([ dateDuration ], v => v[0]) - .add([ dateDuration, 'after', GraphBuilder.result() ], v => combine(v[0], { - relativeTo: v[1] - })) - .add([ dateDuration, 'from', GraphBuilder.result() ], v => combine(v[0], { - relativeTo: v[1] - })) - .add([ dateDuration, 'before', GraphBuilder.result() ], v => combine(reverse(v[0]), { - relativeTo: v[1] - })) - .add([ GraphBuilder.result(), 'plus', dateDuration ], v => combine(v[1], { - relativeTo: v[0] - })) - .add([ GraphBuilder.result(), '+', dateDuration ], v => combine(v[1], { - relativeTo: v[0] - })) - .add([ GraphBuilder.result(), 'minus', dateDuration ], v => combine(reverse(v[1]), { - relativeTo: v[0] - })) - .add([ GraphBuilder.result(), '-', dateDuration ], v => combine(reverse(v[1]), { - relativeTo: v[0] - })) - - // This Sunday, Next Monday or On Tuesday - .add(dayOfWeek, nextDayOfWeek) - .add([ 'this', dayOfWeek ], nextDayOfWeek) - .add([ 'next', dayOfWeek ], nextDayOfWeek) - .add([ 'on', dayOfWeek ], nextDayOfWeek) - - // Expressions for describing the day, such as today and tomorrow - .add('today', today) - .add('tomorrow', tomorrow) - .add('day after tomorrow', dayAfterTomorrow) - .add('the day after tomorrow', dayAfterTomorrow) - .add('yesterday', yesterday) - - // Month followed by day - Jan 12, February 1st - .add([ month, day ], v => withDay(v[0], v[1])) - - // Just the day - .add([ day ], v => ({ day: v[0].value })) - - // Day followed by month - 12 Jan, 1st February - .add([ day, month ], v => withDay(v[1], v[0])) - .add([ day, 'of', month ], v => withDay(v[1], v[0])) - - // Month - .add([ month ], v => v[0]) - .add([ 'last month', year ], v => combine(v[0], { month: 11 })) - .add([ 'first month', year ], v => combine(v[0], { month: 0 })) - - // Non-year (month and day) followed by year - // With day: 12 Jan 2018, 1st February 2018 - // Without day: Jan 2018, this month 2018 - .add([ GraphBuilder.result(hasMonth), year ], v => combine(v[0], v[1])) - - .add([ month, 'in', /^[0-9]{1,2}$/ ], withYear) - .add([ month, 'of', /^[0-9]{1,2}$/ ], withYear) - - // Year - Month - Day, such as 2017-01-24 or 2017 2 5 - .add([ /^[0-9]{4}$/, '-', /^[0-9]{1,2}$/, '-', /^[0-9]{1,2}$/ ], v => { - return { - year: parseInt(v[0]), - month: parseInt(v[1]) - 1, - day: parseInt(v[2]) - }; - }) - - // Month / Day / Year - .add([ /^[0-9]{1,2}$/, '/', /^[0-9]{1,2}$/, '/', /^[0-9]{4}$/ ], v => { - return { - year: parseInt(v[2]), - month: parseInt(v[0]) - 1, - day: parseInt(v[1]) - }; - }) - - // Month / Day - .add([ /^[0-9]{1,2}$/, '/', /^[0-9]{1,2}$/ ], v => { - return { - month: parseInt(v[0]) - 1, - day: parseInt(v[1]) - }; - }) - - // Standalone year - .add([ year ], v => v[0]) - - // Quarters - .add(quarter, v => v[0]) - .add('start of quarter', thisQuarter) - .add('end of quarter', (v, e) => combine(thisQuarter(v, e), { intervalEdge: 'end' })) - - // Quarter N of year - .add([ quarter, year ], v => combine(v[1], { - quarter: v[0].quarter - })) - - .add([ year, quarter ], v => combine(v[0], { - quarter: v[1].quarter - })) - - // Weeks relative to current time - .add(week, v => v[0]) - .add('start of week', thisWeek) - .add('end of week', (v, e) => combine(thisWeek(v, e), { intervalEdge: 'end' })) - - // Week N of year - .add([ week, year ], v => combine(v[1], { - week: v[0].week - })) - - .add([ year, week ], v => combine(v[0], { - week: v[1].week - })) - - // nth day of week in month - .add([ ordinal, dayOfWeek, GraphBuilder.result(isMonth) ], v => combine(v[2], { - dayOfWeek: v[1].value, - dayOfWeekOrdinal: v[0].value - })) - - // first day of week in month - .add([ dayOfWeek, GraphBuilder.result(isMonth) ], v => combine(v[1], { - dayOfWeek: v[0].value, - dayOfWeekOrdinal: 1 - })) - - // nth day of week in year - .add([ ordinal, dayOfWeek, year ], v => combine(v[2], { - dayOfWeek: v[1].value, - dayOfWeekOrdinal: v[0].value - })) - - // first day of week in year - .add([ dayOfWeek, year ], v => combine(v[1], { - dayOfWeek: v[0].value, - dayOfWeekOrdinal: 1 - })) - - // nth day of week in X time - .add([ ordinal, dayOfWeek, GraphBuilder.result(isRelative) ], v => combine(v[2], { - dayOfWeek: v[1].value, - dayOfWeekOrdinal: v[0].value - })) - - // first day of week in X time - .add([ dayOfWeek, GraphBuilder.result(isRelative) ], v => combine(v[1], { - dayOfWeek: v[0].value, - dayOfWeekOrdinal: 1 - })) - - // day of week in week X - .add([ dayOfWeek, GraphBuilder.result(isWeek) ], v => combine(v[1], { - dayOfWeek: v[0].value, - dayOfWeekOrdinal: 1 - })) - - .add([ GraphBuilder.result(isWeek), dayOfWeek ], v => combine(v[0], { - dayOfWeek: v[1].value, - dayOfWeekOrdinal: 1 - })) - - // Extra qualifiers such as in and on - .add([ 'in', GraphBuilder.result(isRelative) ], v => v[0]) - .add([ 'on', GraphBuilder.result() ], v => v[0]) - .add([ 'on', 'the', GraphBuilder.result() ], v => v[0]) - .add([ dateDuration, 'ago' ], reverse) - - // Edges, such as start of [date] or end of [date] - .add([ 'start of', GraphBuilder.result() ], startOf) - .add([ 'beginning of', GraphBuilder.result() ], startOf) - .add([ 'end of', GraphBuilder.result() ], endOf) - - .mapResults(map) - .onlyBest() - .toMatcher(); -} diff --git a/src/language/en/date.ts b/src/language/en/date.ts new file mode 100644 index 0000000..7447157 --- /dev/null +++ b/src/language/en/date.ts @@ -0,0 +1,230 @@ +import { GraphBuilder } from '../../graph/builder'; +import { ValueMatcherFactory } from '../value-matcher-factory'; +import { DateValue } from '../../time/date-value'; + +import { + combine, + isRelative, + startOf, + endOf, + isWeek, + isMonth, + hasMonth, + reverse +} from '../../time/matching'; + +import { IntervalEdge } from '../../time/edge'; +import { DateTimeData } from '../../time/date-time-data'; +import { thisWeek } from '../../time/weeks'; +import { thisQuarter } from '../../time/quarters'; +import { map, today, yesterday, tomorrow, dayAfterTomorrow, nextDayOfWeek, withDay, withYear } from '../../time/dates'; + +import { OrdinalValue } from '../../numbers/ordinal-value'; + +import { ordinalMatcher } from './ordinal'; +import { dayOfWeekMatcher } from './day-of-week'; +import { yearMatcher } from './year'; +import { quarterMatcher } from './quarter'; +import { weekMatcher } from './week'; +import { monthMatcher } from './month'; +import { dateDurationMatcher } from './date-duration'; + +export const dateMatcher: ValueMatcherFactory = { + id: 'date', + + create(language) { + const ordinal = language.matcher(ordinalMatcher); + const dayOfWeek = language.matcher(dayOfWeekMatcher); + const year = language.matcher(yearMatcher); + const quarter = language.matcher(quarterMatcher); + const week = language.matcher(weekMatcher); + const month = language.matcher(monthMatcher); + const dateDuration = language.matcher(dateDurationMatcher); + + const day = GraphBuilder.result(ordinal, (v: OrdinalValue) => v.value >= 0 && v.value < 31); + + return new GraphBuilder(language) + .name('date') + + .skipPunctuation() + + // Relative + .add([ dateDuration ], v => v[0]) + .add([ dateDuration, 'after', GraphBuilder.result() ], v => combine(v[0], { + relativeTo: v[1] + })) + .add([ dateDuration, 'from', GraphBuilder.result() ], v => combine(v[0], { + relativeTo: v[1] + })) + .add([ dateDuration, 'before', GraphBuilder.result() ], v => combine(reverse(v[0]), { + relativeTo: v[1] + })) + .add([ GraphBuilder.result(), 'plus', dateDuration ], v => combine(v[1], { + relativeTo: v[0] + })) + .add([ GraphBuilder.result(), '+', dateDuration ], v => combine(v[1], { + relativeTo: v[0] + })) + .add([ GraphBuilder.result(), 'minus', dateDuration ], v => combine(reverse(v[1]), { + relativeTo: v[0] + })) + .add([ GraphBuilder.result(), '-', dateDuration ], v => combine(reverse(v[1]), { + relativeTo: v[0] + })) + + // This Sunday, Next Monday or On Tuesday + .add(dayOfWeek, v => nextDayOfWeek(v[0])) + .add([ 'this', dayOfWeek ], v => nextDayOfWeek(v[0])) + .add([ 'next', dayOfWeek ], v => nextDayOfWeek(v[0])) + .add([ 'on', dayOfWeek ], v => nextDayOfWeek(v[0])) + + // Expressions for describing the day, such as today and tomorrow + .add('today', today) + .add('tomorrow', tomorrow) + .add('day after tomorrow', dayAfterTomorrow) + .add('the day after tomorrow', dayAfterTomorrow) + .add('yesterday', yesterday) + + // Month followed by day - Jan 12, February 1st + .add([ month, day ], v => withDay(v[0], v[1].value)) + + // Just the day + .add([ day ], v => ({ day: v[0].value })) + + // Day followed by month - 12 Jan, 1st February + .add([ day, month ], v => withDay(v[1], v[0].value)) + .add([ day, 'of', month ], v => withDay(v[1], v[0].value)) + + // Month + .add([ month ], v => v[0]) + .add([ 'last month', year ], v => combine(v[0], { month: 11 })) + .add([ 'first month', year ], v => combine(v[0], { month: 0 })) + + // Non-year (month and day) followed by year + // With day: 12 Jan 2018, 1st February 2018 + // Without day: Jan 2018, this month 2018 + .add([ GraphBuilder.result(hasMonth), year ], v => combine(v[0], v[1])) + + .add([ month, 'in', /^[0-9]{1,2}$/ ], v => withYear(v[0], parseInt(v[1], 10))) + .add([ month, 'of', /^[0-9]{1,2}$/ ], v => withYear(v[0], parseInt(v[1], 10))) + + // Year - Month - Day, such as 2017-01-24 or 2017 2 5 + .add([ /^[0-9]{4}$/, '-', /^[0-9]{1,2}$/, '-', /^[0-9]{1,2}$/ ], v => { + return { + year: parseInt(v[0], 10), + month: parseInt(v[1], 10) - 1, + day: parseInt(v[2], 10) + }; + }) + + // Month / Day / Year + .add([ /^[0-9]{1,2}$/, '/', /^[0-9]{1,2}$/, '/', /^[0-9]{4}$/ ], v => { + return { + year: parseInt(v[2], 10), + month: parseInt(v[0], 10) - 1, + day: parseInt(v[1], 10) + }; + }) + + // Month / Day + .add([ /^[0-9]{1,2}$/, '/', /^[0-9]{1,2}$/ ], v => { + return { + month: parseInt(v[0], 10) - 1, + day: parseInt(v[1], 10) + }; + }) + + // Standalone year + .add([ year ], v => v[0]) + + // Quarters + .add(quarter, v => v[0]) + .add('start of quarter', thisQuarter) + .add('end of quarter', (v, e) => combine(thisQuarter(v, e), { intervalEdge: IntervalEdge.End })) + + // Quarter N of year + .add([ quarter, year ], v => combine(v[1], { + quarter: v[0].quarter + })) + + .add([ year, quarter ], v => combine(v[0], { + quarter: v[1].quarter + })) + + // Weeks relative to current time + .add(week, v => v[0]) + .add('start of week', thisWeek) + .add('end of week', (v, e) => combine(thisWeek(v, e), { intervalEdge: IntervalEdge.End })) + + // Week N of year + .add([ week, year ], v => combine(v[1], { + week: v[0].week + })) + + .add([ year, week ], v => combine(v[0], { + week: v[1].week + })) + + // nth day of week in month + .add([ ordinal, dayOfWeek, GraphBuilder.result(isMonth) ], v => combine(v[2], { + dayOfWeek: v[1], + dayOfWeekOrdinal: v[0].value + })) + + // first day of week in month + .add([ dayOfWeek, GraphBuilder.result(isMonth) ], v => combine(v[1], { + dayOfWeek: v[0], + dayOfWeekOrdinal: 1 + })) + + // nth day of week in year + .add([ ordinal, dayOfWeek, year ], v => combine(v[2], { + dayOfWeek: v[1], + dayOfWeekOrdinal: v[0].value + })) + + // first day of week in year + .add([ dayOfWeek, year ], v => combine(v[1], { + dayOfWeek: v[0], + dayOfWeekOrdinal: 1 + })) + + // nth day of week in X time + .add([ ordinal, dayOfWeek, GraphBuilder.result(isRelative) ], v => combine(v[2], { + dayOfWeek: v[1], + dayOfWeekOrdinal: v[0].value + })) + + // first day of week in X time + .add([ dayOfWeek, GraphBuilder.result(isRelative) ], v => combine(v[1], { + dayOfWeek: v[0], + dayOfWeekOrdinal: 1 + })) + + // day of week in week X + .add([ dayOfWeek, GraphBuilder.result(isWeek) ], v => combine(v[1], { + dayOfWeek: v[0], + dayOfWeekOrdinal: 1 + })) + + .add([ GraphBuilder.result(isWeek), dayOfWeek ], v => combine(v[0], { + dayOfWeek: v[1], + dayOfWeekOrdinal: 1 + })) + + // Extra qualifiers such as in and on + .add([ 'in', GraphBuilder.result(isRelative) ], v => v[0]) + .add([ 'on', GraphBuilder.result() ], v => v[0]) + .add([ 'on', 'the', GraphBuilder.result() ], v => v[0]) + .add([ dateDuration, 'ago' ], v => reverse(v[0])) + + // Edges, such as start of [date] or end of [date] + .add([ 'start of', GraphBuilder.result() ], v => startOf(v[0])) + .add([ 'beginning of', GraphBuilder.result() ], v => startOf(v[0])) + .add([ 'end of', GraphBuilder.result() ], v => endOf(v[0])) + + .mapResults(map) + .onlyBest() + .toMatcher(); + } +}; diff --git a/src/language/en/day-of-week.ts b/src/language/en/day-of-week.ts new file mode 100644 index 0000000..a2ae4a4 --- /dev/null +++ b/src/language/en/day-of-week.ts @@ -0,0 +1,48 @@ +import { ValueMatcherFactory } from '../value-matcher-factory'; +import { Language } from '../language'; +import { GraphBuilder } from '../../graph/builder'; + +import { Weekday } from '../../time/weekday'; + +export const dayOfWeekMatcher: ValueMatcherFactory = { + id: 'day-of-week', + + create(language: Language) { + return new GraphBuilder(language) + .name('day-of-week') + + // Day of week + .map( + { + 'mon': 1, + 'monday': 1, + + 'tue': 2, + 'tuesday': 2, + + 'wed': 3, + 'wednesday': 3, + + 'thu': 4, + 'thurs': 4, + 'thursday': 4, + + 'fri': 5, + 'friday': 5, + + 'sat': 6, + 'saturday': 6, + + 'sun': 0, + 'sunday': 0 + }, + l => l + ) + + .add([ 'on', GraphBuilder.result() ], v => v[0]) + + .mapResults(m => m as Weekday) + .onlyBest() + .toMatcher(); + } +}; diff --git a/src/language/en/dayOfWeek.js b/src/language/en/dayOfWeek.js deleted file mode 100644 index 1c56a01..0000000 --- a/src/language/en/dayOfWeek.js +++ /dev/null @@ -1,42 +0,0 @@ -import GraphBuilder from '../../graph/builder'; - -import { cloneObject } from '../../utils/cloning'; - -export default function(language) { - return new GraphBuilder(language) - .name('dayOfWeek') - - // Day of week - .map( - { - 'mon': 1, - 'monday': 1, - - 'tue': 2, - 'tuesday': 2, - - 'wed': 3, - 'wednesday': 3, - - 'thu': 4, - 'thurs': 4, - 'thursday': 4, - - 'fri': 5, - 'friday': 5, - - 'sat': 6, - 'saturday': 6, - - 'sun': 7, - 'sunday': 7 - }, - l => ({ value: l }) - ) - - .add([ 'on', GraphBuilder.result() ], v => v[0]) - - .mapResults(cloneObject) - .onlyBest() - .toMatcher(); -} diff --git a/src/language/en/index.js b/src/language/en/index.js deleted file mode 100644 index 912555d..0000000 --- a/src/language/en/index.js +++ /dev/null @@ -1,141 +0,0 @@ -import { tokenize } from '../utils'; - -import integer from './integer'; -import number from './number'; -import ordinal from './ordinal'; -import boolean from './boolean'; -import temperature from './temperature'; - -import dayOfWeek from './dayOfWeek'; -import year from './year'; -import quarter from './quarter'; -import week from './week'; -import month from './month'; - -import dateDuration from './date-duration'; -import date from './date'; - -import timeDuration from './time-duration'; -import time from './time'; - -import dateTimeDuration from './date-time-duration'; -import dateTime from './date-time'; - -import dateInterval from './date-interval'; - -import repeating from './repeating'; - -import stemmer from 'talisman/stemmers/porter'; -import { similarity } from 'talisman/metrics/distance/jaro-winkler'; -import treebank from 'talisman/tokenizers/words/treebank'; - -function normalize(word, next) { - word = word.toLowerCase(); - - switch(word) { - case 'ca': - if(next === 'n\'t') { - return 'can'; - } - return word; - case 'n\'t': - return 'not'; - case '\'m': - return 'am'; - case '\'re': - return 'are'; - case '\'ll': - return 'will'; - case '\'s': - return 'is'; - case '\'ve': - return 'have'; - case '&': - return 'and'; - default: - return word; - } -} - -/** - * Normalized tokens that can be skipped if they are missing in the input. - */ -const SKIPPABLE = [ - 'in', 'at', 'for', 'a', 'an', 'the', 'by', 'to' -]; - -/* - * Implementation of English. Uses stemming and a distance metric to determine - * if a token matches or not. - */ -const language = { - id: 'en', - - tokenize(string) { - return tokenize(string, input => { - const tokens = treebank(input.raw); - for(let i=0; i= 0 - }; - } - return tokens; - }); - }, - - compareTokens(a, b) { - if(a.normalized === b.normalized) return 1.0; - - if(a.stemmed === b.stemmed) return 0.95; - - if(a.short || b.short) return 0; - - const d = similarity(a.normalized, b.normalized); - if(d > 0.9) return d * 0.9; - - return 0; - }, - - comparePartialTokens(a, b) { - if(a.normalized.indexOf(b.normalized) === 0) return 1.0; - - const d = similarity(a.normalized.substring(0, b.normalized.length), b.normalized); - if(d > 0.9) return d * 0.9; - - return 0; - } -}; - -language.integer = integer(language); -language.number = number(language); -language.ordinal = ordinal(language); -language.boolean = boolean(language); - -language.dayOfWeek = dayOfWeek(language); -language.year = year(language); -language.quarter = quarter(language); -language.month = month(language); -language.week = week(language); -language.dateDuration = dateDuration(language); -language.date = date(language); - -language.timeDuration = timeDuration(language); -language.time = time(language); - -language.dateTimeDuration = dateTimeDuration(language); -language.dateTime = dateTime(language); - -language.dateInterval = dateInterval(language); - -language.temperature = temperature(language); - -language.repeating = repeating(language); - -export default language; diff --git a/src/language/en/index.ts b/src/language/en/index.ts new file mode 100644 index 0000000..c471482 --- /dev/null +++ b/src/language/en/index.ts @@ -0,0 +1,143 @@ +import { tokenize } from '../tokens/utils'; + +import stemmer from 'talisman/stemmers/porter'; +import { similarity } from 'talisman/metrics/distance/jaro-winkler'; +import treebank from 'talisman/tokenizers/words/treebank'; + +import { Matcher } from '../../graph/matching'; +import { GraphBuilder } from '../../graph/builder'; + +import { AbstractLanguage } from '../abstract-language'; +import { Token } from '../tokens'; +import { integerMatcher } from './integer'; +import { numberMatcher } from './number'; +import { ordinalMatcher } from './ordinal'; +import { booleanMatcher } from './boolean'; +import { dayOfWeekMatcher } from './day-of-week'; +import { yearMatcher } from './year'; +import { quarterMatcher } from './quarter'; +import { monthMatcher } from './month'; +import { weekMatcher } from './week'; +import { dateDurationMatcher } from './date-duration'; +import { dateMatcher } from './date'; +import { timeDurationMatcher } from './time-duration'; +import { timeMatcher } from './time'; +import { dateTimeDurationMatcher } from './date-time-duration'; +import { dateTimeMatcher } from './date-time'; +import { dateIntervalMatcher } from './date-interval'; +import { createRepeating } from './repeating'; + +function normalize(word: string, next?: string) { + word = word.toLowerCase(); + + switch(word) { + case 'ca': + if(next === 'n\'t') { + return 'can'; + } + return word; + case 'n\'t': + return 'not'; + case '\'m': + return 'am'; + case '\'re': + return 'are'; + case '\'ll': + return 'will'; + case '\'s': + return 'is'; + case '\'ve': + return 'have'; + case '&': + return 'and'; + default: + return word; + } +} + +/** + * Normalized tokens that can be skipped if they are missing in the input. + */ +const SKIPPABLE = new Set([ + 'in', 'at', 'for', 'a', 'an', 'the', 'by', 'to' +]); + +/* + * Implementation of English. Uses stemming and a distance metric to determine + * if a token matches or not. + */ +export class EnglishLanguage extends AbstractLanguage { + public readonly id = 'en'; + + public tokenize(string: string) { + return tokenize(string, input => { + const tokens: string[] = treebank(input.raw); + const result = []; + for(let i=0; i 0.9) return d * 0.9; + + return 0; + } + + public comparePartialTokens(a: Token, b: Token) { + if(a.normalized.indexOf(b.normalized) === 0) return 1.0; + + const d = similarity(a.normalized.substring(0, b.normalized.length), b.normalized); + if(d > 0.9) return d * 0.9; + + return 0; + } + + public repeating(matcher: Matcher): GraphBuilder { + return createRepeating(this)(matcher); + } +} + +export const en = new EnglishLanguage(); +en.matcher(integerMatcher); +en.matcher(numberMatcher); +en.matcher(ordinalMatcher); +en.matcher(booleanMatcher); + +en.matcher(dayOfWeekMatcher); +en.matcher(yearMatcher); +en.matcher(quarterMatcher); +en.matcher(monthMatcher); +en.matcher(weekMatcher); +en.matcher(dateDurationMatcher); +en.matcher(dateMatcher); + +en.matcher(timeDurationMatcher); +en.matcher(timeMatcher); + +en.matcher(dateTimeDurationMatcher); +en.matcher(dateTimeMatcher); + +en.matcher(dateIntervalMatcher); + +//language.temperature = temperature(language); + +//language.repeating = repeating(language); diff --git a/src/language/en/integer.js b/src/language/en/integer.js deleted file mode 100644 index e5bc950..0000000 --- a/src/language/en/integer.js +++ /dev/null @@ -1,84 +0,0 @@ -import GraphBuilder from '../../graph/builder'; - -import { combine, map } from '../numbers'; - -function isDigits(o) { - return ! o.literal; -} - -function isDigitsCompatible(o) { - return o.suffix || ! o.literal; -} - -function isLiteral(o) { - return o.literal; -} - -export default function(language) { - return new GraphBuilder(language) - .name('integer') - - .add(/^[0-9]+$/, v => { - const raw = v[0]; - return { value: parseInt(raw), raw: raw }; - }) - - .map( - { - 'zero': 0, - 'none': 0, - 'nought': 0, - 'nil': 0, - 'zilch': 0, - 'one': 1, - 'single': 1, - 'two': 2, - 'three': 3, - 'four': 4, - 'five': 5, - 'six': 6, - 'seven': 7, - 'eight': 8, - 'nine': 9, - 'ten': 10, - 'eleven': 11, - 'twelve': 12, - 'thirteen': 13, - 'fourteen': 14, - 'fifteen': 15, - 'sixteen': 16, - 'seventeen': 17, - 'eighteen': 18, - 'nineteen': 19 - }, - l => ({ value: l, raw: l, literal: true }) - ) - - .map( - { - 'dozen': 12, - - 'hundred': 100, - 'thousand': 1000, - 'million': 1000000, - 'billion': 1000000000, - - 'K': 1000, - 'M': 1000000 - }, - l => ({ value: l, raw: l, suffix: true, literal: true }) - ) - - // Digits + digits or digits + suffix, combines 1 000 and 1 thousand but not one 000 - .add([ GraphBuilder.result(isDigits), GraphBuilder.result(isDigitsCompatible) ], v => combine(v[0], v[1])) - - // Literal + literal - to avoid combining things as `one 000` - .add([ GraphBuilder.result(isLiteral), GraphBuilder.result(isLiteral) ], v => combine(v[0], v[1])) - - // Thousands separator - .add([ GraphBuilder.result(isDigits), ',', GraphBuilder.result(isDigits) ], v => combine(v[0], v[1])) - - .mapResults(map) - .onlyBest() - .toMatcher(); -} diff --git a/src/language/en/integer.ts b/src/language/en/integer.ts new file mode 100644 index 0000000..40cdebe --- /dev/null +++ b/src/language/en/integer.ts @@ -0,0 +1,92 @@ +import { GraphBuilder } from '../../graph/builder'; + +import { + literalNumber, + digitNumber, + + combine, + map, + + isDigits, + isDigitsCompatible, + isLiteral, +} from '../../numbers/numbers'; + +import { Language } from '../language'; +import { Matcher } from '../../graph/matching'; +import { NumberData } from '../../numbers/number-data'; +import { NumberValue } from '../../numbers/number-value'; +import { ValueMatcherFactory } from '../value-matcher-factory'; + +export const integerMatcher: ValueMatcherFactory = { + id: 'integer', + + create(language: Language): Matcher { + return new GraphBuilder(language) + .name('integer') + + .add(/^[0-9]+$/, v => { + const raw = v[0]; + return digitNumber(parseInt(raw, 10), raw); + }) + + .map( + { + 'zero': 0, + 'none': 0, + 'nought': 0, + 'nil': 0, + 'zilch': 0, + 'one': 1, + 'single': 1, + 'two': 2, + 'three': 3, + 'four': 4, + 'five': 5, + 'six': 6, + 'seven': 7, + 'eight': 8, + 'nine': 9, + 'ten': 10, + 'eleven': 11, + 'twelve': 12, + 'thirteen': 13, + 'fourteen': 14, + 'fifteen': 15, + 'sixteen': 16, + 'seventeen': 17, + 'eighteen': 18, + 'nineteen': 19 + }, + l => literalNumber(l, String(l)) + ) + + .map( + { + 'dozen': 12, + + 'hundred': 100, + 'thousand': 1000, + 'million': 1000000, + 'billion': 1000000000, + + 'K': 1000, + 'M': 1000000 + }, + l => literalNumber(l, String(l), true) + ) + + // Digits + digits or digits + suffix, combines 1 000 and 1 thousand but not one 000 + .add([ GraphBuilder.result(isDigits), GraphBuilder.result(isDigitsCompatible) ], v => combine(v[0], v[1])) + + // Literal + literal - to avoid combining things as `one 000` + .add([ GraphBuilder.result(isLiteral), GraphBuilder.result(isLiteral) ], v => combine(v[0], v[1])) + + // Thousands separator + .add([ GraphBuilder.result(isDigits), ',', GraphBuilder.result(isDigits) ], v => combine(v[0], v[1])) + + .mapResults(map) + .onlyBest() + .toMatcher(); + } +}; diff --git a/src/language/en/month.js b/src/language/en/month.js deleted file mode 100644 index a89ae63..0000000 --- a/src/language/en/month.js +++ /dev/null @@ -1,83 +0,0 @@ -import GraphBuilder from '../../graph/builder'; - -import { reverse } from '../../time/matching'; -import { map, thisMonth, nextMonth, previousMonth } from '../../time/months'; - -export default function(language) { - const integer = language.integer; - const ordinal = language.ordinal; - const ordinalMonth = GraphBuilder.result(ordinal, v => v.type === 'specific' && v.value >= 1 && v.value <= 12); - - const relative = new GraphBuilder(language) - .name('relativeMonths') - - .add([ integer, 'months' ], v => ({ relativeMonths: v[0].value })) - - .toMatcher(); - - return new GraphBuilder(language) - .name('month') - - .skipPunctuation() - - // Named months - .map( - { - 'jan': 0, - 'january': 0, - - 'feb': 1, - 'february': 1, - - 'mar': 2, - 'march': 2, - - 'apr': 3, - 'april': 3, - - 'may': 4, - - 'jun': 5, - 'june': 5, - - 'jul': 6, - 'july': 6, - - 'aug': 7, - 'august': 7, - - 'sep': 8, - 'sept': 8, - 'september': 8, - - 'oct': 9, - 'october': 9, - - 'nov': 10, - 'november': 10, - - 'dec': 11, - 'december': 11 - }, - l => ({ month: l }) - ) - - // Dynamic months - .add('this month', thisMonth) - .add('previous month', previousMonth) - .add('last month', previousMonth) - .add('next month', nextMonth) - - .add([ relative ], v => v[0]) - - // Numbered months - .add([ ordinalMonth, 'month' ], v => ({ month: v[0].value - 1 })) - .add([ ordinalMonth ], v => ({ month: v[0].value - 1, })) - - .add([ 'in', GraphBuilder.result() ], v => v[0]) - .add([ relative, 'ago' ], reverse) - - .mapResults(map) - .onlyBest() - .toMatcher(); -} diff --git a/src/language/en/month.ts b/src/language/en/month.ts new file mode 100644 index 0000000..86b575d --- /dev/null +++ b/src/language/en/month.ts @@ -0,0 +1,96 @@ +import { ValueMatcherFactory } from '../value-matcher-factory'; +import { GraphBuilder } from '../../graph/builder'; + +import { ordinalMatcher } from './ordinal'; +import { integerMatcher } from './integer'; + +import { reverse } from '../../time/matching'; +import { map, thisMonth, nextMonth, previousMonth } from '../../time/months'; +import { Language } from '../language'; +import { DateTimeData } from '../../time/date-time-data'; +import { isSpecific } from '../../numbers/ordinals'; +import { OrdinalData } from '../../numbers/ordinal-data'; +import { DateValue } from '../../time/date-value'; + +export const monthMatcher: ValueMatcherFactory = { + id: 'month', + + create(language: Language) { + const integer = language.matcher(integerMatcher); + const ordinal = language.matcher(ordinalMatcher); + const ordinalMonth = GraphBuilder.result(ordinal, v => isSpecific(v) && v.value >= 1 && v.value <= 12); + + const relative = new GraphBuilder(language) + .name('relativeMonths') + + .add([ integer, 'months' ], v => ({ relativeMonths: v[0].value })) + + .toMatcher(); + + return new GraphBuilder(language) + .name('month') + + .skipPunctuation() + + // Named months + .map( + { + 'jan': 0, + 'january': 0, + + 'feb': 1, + 'february': 1, + + 'mar': 2, + 'march': 2, + + 'apr': 3, + 'april': 3, + + 'may': 4, + + 'jun': 5, + 'june': 5, + + 'jul': 6, + 'july': 6, + + 'aug': 7, + 'august': 7, + + 'sep': 8, + 'sept': 8, + 'september': 8, + + 'oct': 9, + 'october': 9, + + 'nov': 10, + 'november': 10, + + 'dec': 11, + 'december': 11 + }, + l => ({ month: l }) + ) + + // Dynamic months + .add('this month', thisMonth) + .add('previous month', previousMonth) + .add('last month', previousMonth) + .add('next month', nextMonth) + + .add([ relative ], v => v[0]) + + // Numbered months + .add([ ordinalMonth, 'month' ], v => ({ month: v[0].value - 1 })) + .add([ ordinalMonth ], v => ({ month: v[0].value - 1, })) + + .add([ 'in', GraphBuilder.result() ], v => v[0]) + .add([ relative, 'ago' ], v => reverse(v[0])) + + .mapResults(map) + .onlyBest() + .toMatcher(); + } +}; diff --git a/src/language/en/number.js b/src/language/en/number.js deleted file mode 100644 index 8ba7400..0000000 --- a/src/language/en/number.js +++ /dev/null @@ -1,35 +0,0 @@ -import GraphBuilder from '../../graph/builder'; - -import { float, combine, negative, map } from '../numbers'; - -function number(o) { - return typeof o.value !== 'undefined'; -} - -export default function(language) { - const integer = language.integer; - return new GraphBuilder(language) - .name('number') - - .add(integer, v => v[0]) - - .add([ GraphBuilder.result(number), integer ], v => combine(v[0], v[1])) - .add([ integer, '.', GraphBuilder.result(integer, v => ! v.suffix && ! v.suffixed) ], v => float(v[0], v[1])) - - .add([ GraphBuilder.result(number), 'e', /^[0-9]$/], v => combine(v[0], { - value: Math.pow(10, parseInt(v[1])), - suffix: true - })) - .add([ GraphBuilder.result(number), 'e', '-', /^[0-9]$/], v => combine(v[0], { - value: Math.pow(10, -parseInt(v[1])), - suffix: true - })) - - .add([ '-', GraphBuilder.result(number) ], v => negative(v[0])) - .add([ 'minus', GraphBuilder.result(number) ], v => negative(v[0])) - .add([ 'negative', GraphBuilder.result(number) ], v => negative(v[0])) - - .mapResults(map) - .onlyBest() - .toMatcher(); -} diff --git a/src/language/en/number.ts b/src/language/en/number.ts new file mode 100644 index 0000000..d2b66c5 --- /dev/null +++ b/src/language/en/number.ts @@ -0,0 +1,47 @@ +import { GraphBuilder } from '../../graph/builder'; + +import { float, combine, negative, map, digitNumber, isNegative } from '../../numbers/numbers'; +import { NumberData } from '../../numbers/number-data'; +import { ValueMatcherFactory } from '../value-matcher-factory'; +import { NumberValue } from '../../numbers/number-value'; +import { Language } from '../language'; +import { Matcher } from '../../graph/matching'; +import { integerMatcher } from './integer'; + +function isNumber(o: NumberData) { + return typeof o.value !== 'undefined'; +} + +export const numberMatcher: ValueMatcherFactory = { + id: 'number', + + create(language: Language): Matcher { + const integer = language.matcher(integerMatcher); + return new GraphBuilder(language) + .name('number') + + .add(integer, v => v[0]) + + .add([ GraphBuilder.result(isNumber), integer ], v => combine(v[0], v[1])) + .add([ integer, '.', GraphBuilder.result(integer, v => ! v.suffix && ! isNegative(v)) ], v => float(v[0], v[1])) + + .add([ GraphBuilder.result(isNumber), 'e', /^[0-9]$/], v => combine(v[0], digitNumber( + Math.pow(10, parseInt(v[1], 10)), + 'e' + v[1], + true + ))) + .add([ GraphBuilder.result(isNumber), 'e', '-', /^[0-9]$/], v => combine(v[0], digitNumber( + Math.pow(10, -parseInt(v[1], 10)), + 'e-' + v[1], + true + ))) + + .add([ '-', GraphBuilder.result(isNumber) ], v => negative(v[0])) + .add([ 'minus', GraphBuilder.result(isNumber) ], v => negative(v[0])) + .add([ 'negative', GraphBuilder.result(isNumber) ], v => negative(v[0])) + + .mapResults(map) + .onlyBest() + .toMatcher(); + } +}; diff --git a/src/language/en/ordinal.js b/src/language/en/ordinal.js deleted file mode 100644 index 69f7f13..0000000 --- a/src/language/en/ordinal.js +++ /dev/null @@ -1,41 +0,0 @@ -import GraphBuilder from '../../graph/builder'; - -const specific = v => ({ value: v[0].value, type: 'specific' }); - -export default function(language) { - return new GraphBuilder(language) - .name('ordinal') - - .add(language.integer, v => ({ value: v[0].value, type: 'ambigious' })) - .add([ language.integer, 'st' ], specific) - .add([ language.integer, 'nd' ], specific) - .add([ language.integer, 'rd' ], specific) - .add([ language.integer, 'th' ], specific) - - .map( - { - 'first': 1, - 'second': 2, - 'third': 3, - 'fourth': 4, - 'fifth': 5, - 'sixth': 6, - 'seventh': 7, - 'eight': 8, - 'ninth': 9, - 'tenth': 10 - }, - l => ({ value: l, type: 'specific' }) - ) - - .add([ 'the', GraphBuilder.result() ], v => v[0]) - - .onlyBest() - .mapResults(r => { - const mapped = { - value: r.value - }; - return mapped; - }) - .toMatcher(); -} diff --git a/src/language/en/ordinal.ts b/src/language/en/ordinal.ts new file mode 100644 index 0000000..af9827f --- /dev/null +++ b/src/language/en/ordinal.ts @@ -0,0 +1,51 @@ +import { Language } from '../language'; +import { ValueMatcherFactory } from '../value-matcher-factory'; +import { GraphBuilder } from '../../graph/builder'; +import { Matcher } from '../../graph/matching'; + +import { integerMatcher } from './integer'; + +import { OrdinalValue } from '../../numbers/ordinal-value'; +import { OrdinalData } from '../../numbers/ordinal-data'; +import { map, specificOrdinal, ambigiousOrdinal } from '../../numbers/ordinals'; + +const specific = (v: any) => specificOrdinal(v[0].value); + +export const ordinalMatcher: ValueMatcherFactory = { + id: 'ordinal', + + create(language: Language): Matcher { + const integer = language.matcher(integerMatcher); + + return new GraphBuilder(language) + .name('ordinal') + + .add(integer, v => ambigiousOrdinal(v[0].value)) + .add([ integer, 'st' ], specific) + .add([ integer, 'nd' ], specific) + .add([ integer, 'rd' ], specific) + .add([ integer, 'th' ], specific) + + .map( + { + 'first': 1, + 'second': 2, + 'third': 3, + 'fourth': 4, + 'fifth': 5, + 'sixth': 6, + 'seventh': 7, + 'eight': 8, + 'ninth': 9, + 'tenth': 10 + }, + l => specificOrdinal(l) + ) + + .add([ 'the', GraphBuilder.result() ], v => v[0]) + + .mapResults(map) + .onlyBest() + .toMatcher(); + } +}; diff --git a/src/language/en/quarter.js b/src/language/en/quarter.js deleted file mode 100644 index a3ce4cf..0000000 --- a/src/language/en/quarter.js +++ /dev/null @@ -1,27 +0,0 @@ -import GraphBuilder from '../../graph/builder'; - -import { map, thisQuarter, nextQuarter, previousQuarter } from '../../time/quarters'; - -export default function(language) { - const ordinal = language.ordinal; - - return new GraphBuilder(language) - .name('quarters') - - .skipPunctuation() - - // Weeks relative to current time - .add([ 'this quarter' ], thisQuarter) - .add([ 'next quarter' ], nextQuarter) - .add([ 'last quarter' ], previousQuarter) - .add([ 'previous quarter' ], previousQuarter) - - .add([ 'quarter', ordinal ], v => ({ quarter: v[0].value })) - .add([ 'q', ordinal ], v => ({ quarter: v[0].value })) - .add([ ordinal, 'quarter' ], v => ({ quarter: v[0].value })) - .add([ ordinal, 'q' ], v => ({ quarter: v[0].value })) - - .mapResults(map) - .onlyBest() - .toMatcher(); -} diff --git a/src/language/en/quarter.ts b/src/language/en/quarter.ts new file mode 100644 index 0000000..2b0ec7a --- /dev/null +++ b/src/language/en/quarter.ts @@ -0,0 +1,35 @@ +import { ValueMatcherFactory } from '../value-matcher-factory'; +import { GraphBuilder } from '../../graph/builder'; + +import { map, thisQuarter, nextQuarter, previousQuarter } from '../../time/quarters'; +import { ordinalMatcher } from './ordinal'; +import { IntervalValue } from '../../time/interval-value'; +import { DateTimeData } from '../../time/date-time-data'; + +export const quarterMatcher: ValueMatcherFactory = { + id: 'quarter', + + create(language) { + const ordinal = language.matcher(ordinalMatcher); + + return new GraphBuilder(language) + .name('quarter') + + .skipPunctuation() + + // Weeks relative to current time + .add([ 'this quarter' ], thisQuarter) + .add([ 'next quarter' ], nextQuarter) + .add([ 'last quarter' ], previousQuarter) + .add([ 'previous quarter' ], previousQuarter) + + .add([ 'quarter', ordinal ], v => ({ quarter: v[0].value })) + .add([ 'q', ordinal ], v => ({ quarter: v[0].value })) + .add([ ordinal, 'quarter' ], v => ({ quarter: v[0].value })) + .add([ ordinal, 'q' ], v => ({ quarter: v[0].value })) + + .mapResults(map) + .onlyBest() + .toMatcher(); + } +}; diff --git a/src/language/en/repeating.js b/src/language/en/repeating.ts similarity index 59% rename from src/language/en/repeating.js rename to src/language/en/repeating.ts index 6d432cb..85b4f52 100644 --- a/src/language/en/repeating.js +++ b/src/language/en/repeating.ts @@ -1,8 +1,10 @@ -import GraphBuilder from '../../graph/builder'; +import { GraphBuilder } from '../../graph/builder'; +import { Matcher } from '../../graph/matching'; +import { Language } from '../language'; -export default function(language) { - return function(graph) { - const builder = new GraphBuilder(language) +export function createRepeating(language: Language) { + return function(graph: Matcher) { + const builder = new GraphBuilder(language) .name('repeating[' + graph.options.name + ']') .skipPunctuation(); @@ -14,7 +16,8 @@ export default function(language) { if(graph.options.mapper) { // If the graph has requested that matches are mapped - map each match - builder.mapResults(values => values.map(graph.options.mapper)); + const mapper = graph.options.mapper; + builder.mapResults((values, encounter) => values.map(v => mapper(v, encounter))); } // Add the value and how it can be repeated diff --git a/src/language/en/temperature.js b/src/language/en/temperature.js deleted file mode 100644 index 36d83d0..0000000 --- a/src/language/en/temperature.js +++ /dev/null @@ -1,36 +0,0 @@ -import GraphBuilder from '../../graph/builder'; - -function withUnit(v, unit) { - return { - value: v.value, - unit: unit - }; -} - -export default function(language) { - return new GraphBuilder(language) - .name('temperature') - - .add(language.number, v => v[0]) - .add([ language.number, 'degrees' ], v => v[0]) - .add([ language.number, 'deg' ], v => v[0]) - - .add([ language.number, 'F' ], v => withUnit(v[0], 'fahrenheit')) - .add([ language.number, 'fahrenheit' ], v => withUnit(v[0], 'fahrenheit')) - - .add([ language.number, 'C' ], v => withUnit(v[0], 'celsius')) - .add([ language.number, 'celsius' ], v => withUnit(v[0], 'celsius')) - - .add(['degrees', GraphBuilder.result(() => true) ], v => v[0]) - - .mapResults((data, encounter) => { - const mapped = { - value: data.value, - unit: data.unit || encounter.options.temperature || 'unknown' - }; - return mapped; - }) - - .onlyBest() - .toMatcher(); -} diff --git a/src/language/en/time-duration.js b/src/language/en/time-duration.js deleted file mode 100644 index 8872716..0000000 --- a/src/language/en/time-duration.js +++ /dev/null @@ -1,32 +0,0 @@ -import GraphBuilder from '../../graph/builder'; - -import { combine } from '../../time/matching'; -import { map } from '../../time/durations'; - -export default function(language) { - const integer = language.integer; - - return new GraphBuilder(language) - .name('time-duration') - - .skipPunctuation() - - .add([ integer, 'hours' ], v => ({ relativeHours: v[0].value })) - .add([ integer, 'hr' ], v => ({ relativeHours: v[0].value })) - .add([ integer, 'h' ], v => ({ relativeHours: v[0].value })) - .add([ integer, 'minutes' ], v => ({ relativeMinutes: v[0].value })) - .add([ integer, 'm' ], v => ({ relativeMinutes: v[0].value })) - .add([ integer, 'seconds' ], v => ({ relativeSeconds: v[0].value })) - .add([ integer, 'sec' ], v => ({ relativeSeconds: v[0].value })) - .add([ integer, 's' ], v => ({ relativeSeconds: v[0].value })) - .add([ integer, 'milliseconds'], v => ({ relativeMilliseconds: v[0].value })) - .add([ integer, 'millis'], v => ({ relativeMilliseconds: v[0].value })) - .add([ integer, 'ms'], v => ({ relativeMilliseconds: v[0].value })) - - .add([ GraphBuilder.result(), GraphBuilder.result() ], v => combine(v[0], v[1])) - .add([ GraphBuilder.result(), 'and', GraphBuilder.result() ], v => combine(v[0], v[1])) - - .mapResults(map) - .onlyBest() - .toMatcher(); -} diff --git a/src/language/en/time-duration.ts b/src/language/en/time-duration.ts new file mode 100644 index 0000000..09c313f --- /dev/null +++ b/src/language/en/time-duration.ts @@ -0,0 +1,39 @@ +import { ValueMatcherFactory } from '../value-matcher-factory'; +import { GraphBuilder } from '../../graph/builder'; +import { DateTimeData } from '../../time/date-time-data'; + +import { integerMatcher } from './integer'; +import { combine } from '../../time/matching'; +import { map, Duration } from '../../time/durations'; + +export const timeDurationMatcher: ValueMatcherFactory = { + id: 'time-duration', + + create(language) { + const integer = language.matcher(integerMatcher); + + return new GraphBuilder(language) + .name('time-duration') + + .skipPunctuation() + + .add([ integer, 'hours' ], v => ({ relativeHours: v[0].value })) + .add([ integer, 'hr' ], v => ({ relativeHours: v[0].value })) + .add([ integer, 'h' ], v => ({ relativeHours: v[0].value })) + .add([ integer, 'minutes' ], v => ({ relativeMinutes: v[0].value })) + .add([ integer, 'm' ], v => ({ relativeMinutes: v[0].value })) + .add([ integer, 'seconds' ], v => ({ relativeSeconds: v[0].value })) + .add([ integer, 'sec' ], v => ({ relativeSeconds: v[0].value })) + .add([ integer, 's' ], v => ({ relativeSeconds: v[0].value })) + .add([ integer, 'milliseconds'], v => ({ relativeMilliseconds: v[0].value })) + .add([ integer, 'millis'], v => ({ relativeMilliseconds: v[0].value })) + .add([ integer, 'ms'], v => ({ relativeMilliseconds: v[0].value })) + + .add([ GraphBuilder.result(), GraphBuilder.result() ], v => combine(v[0], v[1])) + .add([ GraphBuilder.result(), 'and', GraphBuilder.result() ], v => combine(v[0], v[1])) + + .mapResults(map) + .onlyBest() + .toMatcher(); + } +} diff --git a/src/language/en/time.js b/src/language/en/time.js deleted file mode 100644 index 2922575..0000000 --- a/src/language/en/time.js +++ /dev/null @@ -1,109 +0,0 @@ -import GraphBuilder from '../../graph/builder'; - -import { combine, reverse } from '../../time/matching'; -import { map, time12h, time24h, toAM, toPM } from '../../time/times'; - -function hasHour(v) { - return v && typeof v.hour !== 'undefined'; -} - -function isHour(v) { - return v && typeof v.hour !== 'undefined' && typeof v.minute === 'undefined'; -} - -function adjustMinutes(time, minutes) { - return combine(time, { - relativeMinutes: minutes - }); -} - -export default function(language) { - const integer = language.integer; - const timeDuration = language.timeDuration; - - const relativeMinutes = new GraphBuilder(language) - .name('relativeMinutes') - - .add([ GraphBuilder.result(integer, v => v.value >= 1 && v.value <= 3), 'quarters' ], v => v[0].value * 15) - .add('quarter', 15) - .add('half', 30) - .add(integer, v => v[0].value) - .add([ integer, 'minutes' ], v => v[0].value) - - .toMatcher(); - - return new GraphBuilder(language) - .name('time') - - .skipPunctuation() - - // Approximate times - .add([ GraphBuilder.result(), 'ish' ], v => combine(v[0], { precision: 'approximate' })) - .add([ GraphBuilder.result(), 'approximately' ], v => combine(v[0], { precision: 'approximate' })) - .add([ 'about', GraphBuilder.result() ], v => combine(v[0], { precision: 'approximate' })) - .add([ 'around', GraphBuilder.result() ], v => combine(v[0], { precision: 'approximate' })) - .add([ 'approximately', GraphBuilder.result() ], v => combine(v[0], { precision: 'approximate' })) - - .add([ GraphBuilder.result(), 'amish' ], v => combine(toAM(v[0]), { precision: 'approximate' })) - .add([ GraphBuilder.result(), 'pmish' ], v => combine(toPM(v[0]), { precision: 'approximate' })) - - // Exact times - .add([ 'exactly', GraphBuilder.result() ], v => combine(v[0], { precision: 'exact' })) - .add([ GraphBuilder.result(), 'exactly' ], v => combine(v[0], { precision: 'exact' })) - .add([ GraphBuilder.result(), 'sharp' ], v => combine(v[0], { precision: 'exact' })) - - // Named times - .map( - { - 'midnight': 0, - 'noon': 12 - }, - v => time24h(v) - ) - - // HH, such as 4, 14 - .add(/^[0-9]{1,2}$/, v => time12h(parseInt(v[0]))) - .add([ integer ], v => time12h(v[0].value)) - - // HH:MM, such as 00:10, 9:30, 14 00 - .add([ /^[0-9]{1,2}$/, ':', /^[0-9]{1,2}$/ ], v => { - return time12h(parseInt(v[0]), parseInt(v[1])); - }) - .add([ integer, ':', integer ], v => time12h(v[0].value, v[1].value)) - .add(/^[0-9]{3,4}$/, v => { - const t = v[0]; - const h = t.length === 3 ? t.substring(0, 1) : t.substring(0, 2); - const m = t.substring(t.length-2); - return time12h(parseInt(h), parseInt(m)); - }) - - // HH:MM:SS - .add([ /^[0-9]{1,2}$/, ':', /^[0-9]{1,2}$/, ':', /^[0-9]{1,2}$/ ], v => { - return time12h(parseInt(v[0]), parseInt(v[1]), parseInt(v[2])); - }) - - .add([ GraphBuilder.result(hasHour), 'pm' ], v => toPM(v[0])) - .add([ GraphBuilder.result(hasHour), 'p.m.' ], v => toPM(v[0])) - .add([ GraphBuilder.result(hasHour), 'am' ], v => toAM(v[0])) - .add([ GraphBuilder.result(hasHour), 'a.m.' ], v => toAM(v[0])) - - - .add([ relativeMinutes, 'to', GraphBuilder.result(isHour) ], v => adjustMinutes(v[1], - v[0])) - .add([ relativeMinutes, 'til', GraphBuilder.result(isHour) ], v => adjustMinutes(v[1], - v[0])) - .add([ relativeMinutes, 'before', GraphBuilder.result(isHour) ], v => adjustMinutes(v[1], - v[0])) - .add([ relativeMinutes, 'of', GraphBuilder.result(isHour) ], v => adjustMinutes(v[1], - v[0])) - - .add([ relativeMinutes, 'past', GraphBuilder.result(isHour) ], v => adjustMinutes(v[1], v[0])) - .add([ relativeMinutes, 'after', GraphBuilder.result(isHour) ], v => adjustMinutes(v[1], v[0])) - .add([ 'half', GraphBuilder.result(isHour) ], v => adjustMinutes(v[0], 30)) - - // Qualifiers - .add([ 'in', timeDuration ], v => v[0]) - .add([ timeDuration ], v => v[0]) - .add([ timeDuration, 'ago' ], reverse) - .add([ 'at', GraphBuilder.result() ], v => v[0]) - - .mapResults(map) - .onlyBest() - .toMatcher(); -} diff --git a/src/language/en/time.ts b/src/language/en/time.ts new file mode 100644 index 0000000..e9caf4a --- /dev/null +++ b/src/language/en/time.ts @@ -0,0 +1,113 @@ +import { GraphBuilder } from '../../graph/builder'; +import { DateTimeData } from '../../time/date-time-data'; +import { ValueMatcherFactory } from '../value-matcher-factory'; + +import { integerMatcher } from './integer'; +import { timeDurationMatcher } from './time-duration'; + +import { combine, reverse, hasHour, isHour } from '../../time/matching'; +import { map, time12h, time24h, toAM, toPM } from '../../time/times'; +import { DateValue } from '../../time/date-value'; +import { Precision } from '../../time/precision'; + + +function adjustMinutes(time: DateTimeData, minutes: number) { + return combine(time, { + relativeMinutes: minutes + }); +} + +export const timeMatcher: ValueMatcherFactory = { + id: 'time', + + create(language) { + const integer = language.matcher(integerMatcher); + const timeDuration = language.matcher(timeDurationMatcher); + + const relativeMinutes = new GraphBuilder(language) + .name('relativeMinutes') + + .add([ GraphBuilder.result(integer, v => v.value >= 1 && v.value <= 3), 'quarters' ], v => v[0].value * 15) + .add('quarter', 15) + .add('half', 30) + .add(integer, v => v[0].value) + .add([ integer, 'minutes' ], v => v[0].value) + + .toMatcher(); + + return new GraphBuilder(language) + .name('time') + + .skipPunctuation() + + // Approximate times + .add([ GraphBuilder.result(), 'ish' ], v => combine(v[0], { precision: Precision.Approximate })) + .add([ GraphBuilder.result(), 'approximately' ], v => combine(v[0], { precision: Precision.Approximate })) + .add([ 'about', GraphBuilder.result() ], v => combine(v[0], { precision: Precision.Approximate })) + .add([ 'around', GraphBuilder.result() ], v => combine(v[0], { precision: Precision.Approximate })) + .add([ 'approximately', GraphBuilder.result() ], v => combine(v[0], { precision: Precision.Approximate })) + + .add([ GraphBuilder.result(), 'amish' ], v => combine(toAM(v[0]), { precision: Precision.Approximate })) + .add([ GraphBuilder.result(), 'pmish' ], v => combine(toPM(v[0]), { precision: Precision.Approximate })) + + // Exact times + .add([ 'exactly', GraphBuilder.result() ], v => combine(v[0], { precision: Precision.Exact })) + .add([ GraphBuilder.result(), 'exactly' ], v => combine(v[0], { precision: Precision.Exact })) + .add([ GraphBuilder.result(), 'sharp' ], v => combine(v[0], { precision: Precision.Exact })) + + // Named times + .map( + { + 'midnight': 0, + 'noon': 12 + }, + v => time24h(v) + ) + + // HH, such as 4, 14 + .add(/^[0-9]{1,2}$/, v => time12h(parseInt(v[0], 10))) + .add([ integer ], v => time12h(v[0].value)) + + // HH:MM, such as 00:10, 9:30, 14 00 + .add([ /^[0-9]{1,2}$/, ':', /^[0-9]{1,2}$/ ], v => { + return time12h(parseInt(v[0], 10), parseInt(v[1], 10)); + }) + .add([ integer, ':', integer ], v => time12h(v[0].value, v[1].value)) + .add(/^[0-9]{3,4}$/, v => { + const t = v[0]; + const h = t.length === 3 ? t.substring(0, 1) : t.substring(0, 2); + const m = t.substring(t.length-2); + return time12h(parseInt(h, 10), parseInt(m, 10)); + }) + + // HH:MM:SS + .add([ /^[0-9]{1,2}$/, ':', /^[0-9]{1,2}$/, ':', /^[0-9]{1,2}$/ ], v => { + return time12h(parseInt(v[0], 10), parseInt(v[1], 10), parseInt(v[2], 10)); + }) + + .add([ GraphBuilder.result(hasHour), 'pm' ], v => toPM(v[0])) + .add([ GraphBuilder.result(hasHour), 'p.m.' ], v => toPM(v[0])) + .add([ GraphBuilder.result(hasHour), 'am' ], v => toAM(v[0])) + .add([ GraphBuilder.result(hasHour), 'a.m.' ], v => toAM(v[0])) + + + .add([ relativeMinutes, 'to', GraphBuilder.result(isHour) ], v => adjustMinutes(v[1], - v[0])) + .add([ relativeMinutes, 'til', GraphBuilder.result(isHour) ], v => adjustMinutes(v[1], - v[0])) + .add([ relativeMinutes, 'before', GraphBuilder.result(isHour) ], v => adjustMinutes(v[1], - v[0])) + .add([ relativeMinutes, 'of', GraphBuilder.result(isHour) ], v => adjustMinutes(v[1], - v[0])) + + .add([ relativeMinutes, 'past', GraphBuilder.result(isHour) ], v => adjustMinutes(v[1], v[0])) + .add([ relativeMinutes, 'after', GraphBuilder.result(isHour) ], v => adjustMinutes(v[1], v[0])) + .add([ 'half', GraphBuilder.result(isHour) ], v => adjustMinutes(v[0], 30)) + + // Qualifiers + .add([ 'in', timeDuration ], v => v[0]) + .add([ timeDuration ], v => v[0]) + .add([ timeDuration, 'ago' ], v => reverse(v[0])) + .add([ 'at', GraphBuilder.result() ], v => v[0]) + + .mapResults(map) + .onlyBest() + .toMatcher(); + } +}; diff --git a/src/language/en/week.js b/src/language/en/week.js deleted file mode 100644 index 1c95846..0000000 --- a/src/language/en/week.js +++ /dev/null @@ -1,25 +0,0 @@ -import GraphBuilder from '../../graph/builder'; - -import { map, thisWeek, nextWeek, previousWeek } from '../../time/weeks'; - -export default function(language) { - const ordinal = language.ordinal; - - return new GraphBuilder(language) - .name('week') - - .skipPunctuation() - - // Weeks relative to current time - .add([ 'this week' ], thisWeek) - .add([ 'next week' ], nextWeek) - .add([ 'last week' ], previousWeek) - .add([ 'previous week' ], previousWeek) - - .add([ 'week', ordinal ], v => ({ week: v[0].value })) - .add([ GraphBuilder.result(ordinal, v => v.type === 'specific'), 'week' ], v => ({ week: v[0].value })) - - .mapResults(map) - .onlyBest() - .toMatcher(); -} diff --git a/src/language/en/week.ts b/src/language/en/week.ts new file mode 100644 index 0000000..a0f952c --- /dev/null +++ b/src/language/en/week.ts @@ -0,0 +1,34 @@ +import { ValueMatcherFactory } from '../value-matcher-factory'; +import { IntervalValue } from '../../time/interval-value'; +import { GraphBuilder } from '../../graph/builder'; +import { DateTimeData } from '../../time/date-time-data'; + +import { ordinalMatcher } from './ordinal'; +import { map, thisWeek, nextWeek, previousWeek } from '../../time/weeks'; +import { isSpecific } from '../../numbers/ordinals'; + +export const weekMatcher: ValueMatcherFactory = { + id: 'week', + + create(language) { + const ordinal = language.matcher(ordinalMatcher); + + return new GraphBuilder(language) + .name('week') + + .skipPunctuation() + + // Weeks relative to current time + .add([ 'this week' ], thisWeek) + .add([ 'next week' ], nextWeek) + .add([ 'last week' ], previousWeek) + .add([ 'previous week' ], previousWeek) + + .add([ 'week', ordinal ], v => ({ week: v[0].value })) + .add([ GraphBuilder.result(ordinal, isSpecific), 'week' ], v => ({ week: v[0].value })) + + .mapResults(map) + .onlyBest() + .toMatcher(); + } +} diff --git a/src/language/en/year.js b/src/language/en/year.js deleted file mode 100644 index 9760584..0000000 --- a/src/language/en/year.js +++ /dev/null @@ -1,34 +0,0 @@ -import GraphBuilder from '../../graph/builder'; - -import { reverse } from '../../time/matching'; -import { map, thisYear, nextYear, previousYear } from '../../time/years'; - -export default function(language) { - const integer = language.integer; - - const relative = new GraphBuilder(language) - .name('relativeYears') - - .add([ integer, 'years' ], v => ({ relativeYears: v[0].value })) - - .toMatcher(); - - return new GraphBuilder(language) - .name('year') - - .add([ /^[0-9]{4}$/ ], v => ({ year: parseInt(v[0]) })) - .add('this year', thisYear) - .add('next year', nextYear) - .add('last year', previousYear) - .add('previous year', previousYear) - - .add(relative, v => v[0]) - - .add([ 'in', GraphBuilder.result() ], v => v[0]) - .add([ 'of', GraphBuilder.result() ], v => v[0]) - .add([ relative, 'ago' ], reverse) - - .mapResults(map) - .onlyBest() - .toMatcher(); -} diff --git a/src/language/en/year.ts b/src/language/en/year.ts new file mode 100644 index 0000000..822f932 --- /dev/null +++ b/src/language/en/year.ts @@ -0,0 +1,43 @@ +import { ValueMatcherFactory } from '../value-matcher-factory'; +import { GraphBuilder } from '../../graph/builder'; +import { DateTimeData } from '../../time/date-time-data'; + +import { integerMatcher } from './integer'; + +import { reverse } from '../../time/matching'; +import { map, thisYear, nextYear, previousYear } from '../../time/years'; +import { DateValue } from '../../time/date-value'; + +export const yearMatcher: ValueMatcherFactory = { + id: 'year', + + create(language) { + const integer = language.matcher(integerMatcher); + + const relative = new GraphBuilder(language) + .name('relativeYears') + + .add([ integer, 'years' ], v => ({ relativeYears: v[0].value })) + + .toMatcher(); + + return new GraphBuilder(language) + .name('year') + + .add([ /^[0-9]{4}$/ ], v => ({ year: parseInt(v[0], 10) })) + .add('this year', thisYear) + .add('next year', nextYear) + .add('last year', previousYear) + .add('previous year', previousYear) + + .add(relative, v => v[0]) + + .add([ 'in', GraphBuilder.result() ], v => v[0]) + .add([ 'of', GraphBuilder.result() ], v => v[0]) + .add([ relative, 'ago' ], v => reverse(v[0])) + + .mapResults(map) + .onlyBest() + .toMatcher(); + } +} diff --git a/src/language/language.ts b/src/language/language.ts new file mode 100644 index 0000000..447f351 --- /dev/null +++ b/src/language/language.ts @@ -0,0 +1,66 @@ +import { Token, Tokens } from './tokens'; +import { Matcher } from '../graph/matching'; +import { ValueMatcherFactory } from './value-matcher-factory'; +import { GraphBuilder } from '../graph/builder'; + +/** + * Language usable with Ecolect. + */ +export interface Language { + /** + * The identifier of the language. + */ + readonly id: string; + + /** + * Tokenize an input string. + * + * @param input + */ + tokenize(input: string): Tokens; + + /** + * Compare the similarity of two tokens. + * + * @param a + * @param b + */ + compareTokens(a: Token, b: Token): number; + + /** + * Compare the similarity of two tokens in the case of partial matching. + * + * @param a + * @param b + */ + comparePartialTokens(a: Token, b: Token): number; + + /** + * Create and return a matcher for the given factory. + * + * @param factory + */ + matcher(factory: ValueMatcherFactory): Matcher; + + /** + * Find a matcher based on its identifier. The matcher must be available + * for the language. + * + * @param id + */ + findMatcher(id: string): Matcher | null; + + /** + * Get a matcher, throwing an error if it is not available. + * + * @param id + */ + getMatcher(id: string): Matcher; + + /** + * Create a repeating statement for the given matcher. + * + * @param matcher + */ + repeating(matcher: Matcher): GraphBuilder; +} diff --git a/src/language/matchers.js b/src/language/matchers.ts similarity index 100% rename from src/language/matchers.js rename to src/language/matchers.ts diff --git a/src/language/numbers.js b/src/language/numbers.js deleted file mode 100644 index d47b64f..0000000 --- a/src/language/numbers.js +++ /dev/null @@ -1,66 +0,0 @@ - -/** - * Combine two numbers when parsing. - */ -export function combine(a, b) { - if(a.suffix && b.suffix) { - const value = a.value * b.value; - return { - value: value, - raw: value, - integer: a.integer && b.integer, - suffix: true, - literal: true - }; - } else if(b.suffix) { - const value = a.value * b.value; - return { - value: value, - raw: value, - integer: a.integer && b.integer, - suffixed: true, - literal: true - }; - } else { - const raw = a.raw + b.raw; - const value = parseInt(a.raw + b.raw); - - return { - value: value, - raw: raw, - integer: a.integer && b.integer, - literal: a.literal || b.literal - }; - } -} - -export function negative(o) { - return { - value: - o.value, - raw: '-' + o.raw, - integer: o.integer - }; -} - -export function float(a, b) { - const raw = a.raw + '.' + b.raw; - return { - value: parseFloat(raw), - raw: raw, - integer: false - }; -} - -export function map(data) { - return new NumberValue(data); -} - -class NumberValue { - constructor(obj) { - this.value = obj.value; - } - - format() { - return String(this.value); - } -} diff --git a/src/language/tokens/index.ts b/src/language/tokens/index.ts new file mode 100644 index 0000000..7e096c6 --- /dev/null +++ b/src/language/tokens/index.ts @@ -0,0 +1,4 @@ +export * from './token-data'; +export * from './token'; +export * from './tokenizer'; +export * from './tokens'; diff --git a/src/language/tokens/token-data.ts b/src/language/tokens/token-data.ts new file mode 100644 index 0000000..a88a1c9 --- /dev/null +++ b/src/language/tokens/token-data.ts @@ -0,0 +1,29 @@ +/** + * Data for a token that can be enhanced with extra information. + */ +export interface TokenData { + /** + * Raw text of the token. + */ + raw: string; + + /** + * The normalized version of the text. + */ + normalized: string; + + /** + * Text of token but stemmed. + */ + stemmed: string; + + /** + * If the token is considered short by the language. + */ + short: boolean; + + /** + * If the token is skippable. + */ + skippable: boolean; +} diff --git a/src/language/tokens/token.ts b/src/language/tokens/token.ts new file mode 100644 index 0000000..69d6a35 --- /dev/null +++ b/src/language/tokens/token.ts @@ -0,0 +1,18 @@ +import { TokenData } from './token-data'; + +export interface Token extends TokenData { + /** + * The start position of the token. + */ + start: number; + + /** + * The stop position of the token. + */ + stop: number; + + /** + * If the token represents punctuation. + */ + punctuation: boolean; +} diff --git a/src/language/tokens/tokenizer.ts b/src/language/tokens/tokenizer.ts new file mode 100644 index 0000000..194e4f3 --- /dev/null +++ b/src/language/tokens/tokenizer.ts @@ -0,0 +1,28 @@ + +/** + * Input as given to a tokenizer. + */ +export interface TokenizerInput { + /** + * The raw text to tokenize. + */ + raw: string; + + /** + * The index in the source at which the first character in the raw text + * was pulled from. + */ + start: number; + + /** + * The index in the source at which the last character in the raw text + * was pulled from. + */ + stop: number; +} + +/** + * Tokenizer of input. A tokenizer is responsible for creating tokens, either + * full ones or simple token data. + */ +export type Tokenizer = (input: TokenizerInput) => T[]; diff --git a/src/language/tokens/tokens.ts b/src/language/tokens/tokens.ts new file mode 100644 index 0000000..339d7cb --- /dev/null +++ b/src/language/tokens/tokens.ts @@ -0,0 +1,48 @@ +import { Token } from './token'; + +export interface Tokens extends Array { + /** + * Assemble the raw string value of the tokens contained within this + * collection. + */ + raw(): string; + + slice(start?: number, end?: number): Tokens; +} + +export const Tokens = { + empty() { + return makeTokens([]); + } +}; + +const slice = function(this: Tokens, ...args: any) { + const array = Array.prototype.slice.apply(this, args); + return makeTokens(array); +}; + +function makeTokens(array: object[]): Tokens { + const result: Tokens = array as Tokens; + result.raw = tokensRawValue; + result.slice = slice; + return result; +} + +function tokensRawValue(this: Tokens): string { + if(this.length === 0) return ''; + + const result = []; + let index = this[0].start; + for(let i=0; i, result: Tokens) { + MATCHER.lastIndex = 0; + let match; + while((match = MATCHER.exec(text))) { + const offset = match.index; + const raw = match[0]; + + let offsetStart = index + offset; + + const tokens = tokenizer({ + start: offsetStart, + stop: offsetStart + raw.length, + raw: raw + }); + + for(let i=0; i) { + + // First step is to normalize the input to NFC if we can + if(text.normalize) { + text = text.normalize(); + } + + const result = Tokens.empty(); + + const NON_SPACE = /\S+/gu; + let match; + while((match = NON_SPACE.exec(text))) { + const index = match.index; + const raw = match[0]; + + tokenizeSingle(index, raw, tokenizer, result); + } + + return result; +} diff --git a/src/language/utils.js b/src/language/utils.js deleted file mode 100644 index da838e2..0000000 --- a/src/language/utils.js +++ /dev/null @@ -1,112 +0,0 @@ -import { - punctuation, - wordish, - numeric, - emoji, - emojiModifier -} from './matchers'; - -const MATCHER_PUNCTUATION = new RegExp('^(' + punctuation + ')+$'); -function isPunctuation(text) { - return MATCHER_PUNCTUATION.test(text); -} - -const MATCHER_ALPHABETIC = '(?:' + wordish + ')+'; -const MATCHER_NUMERIC = '(?:' + numeric + ')+'; -const MATCHER_EMOJI = emoji + '(?:' + emojiModifier + ')*'; -const MATCHER = new RegExp('(' + MATCHER_ALPHABETIC + '|' + MATCHER_NUMERIC + '|' + MATCHER_EMOJI + '|.)', 'gu'); -function tokenizeSingle(index, text, transformer, result) { - MATCHER.previousIndex = 0; - let match; - while((match = MATCHER.exec(text))) { - const offset = match.index; - const raw = match[0]; - - let offsetStart = index + offset; - const token = { - start: offsetStart, - stop: offsetStart + raw.length, - raw: raw - }; - - let tokens = transformer(token); - if(Array.isArray(tokens)) { - for(let i=0; i { + readonly id: string; + + create(language: Language): Matcher; +} diff --git a/src/numbers/number-data.ts b/src/numbers/number-data.ts new file mode 100644 index 0000000..7098e2b --- /dev/null +++ b/src/numbers/number-data.ts @@ -0,0 +1,12 @@ +/** + * Information about a number. + */ +export interface NumberData { + value: number; + + rawDigits: string; + + integer: boolean; + suffix: boolean; + literal: boolean; +} diff --git a/src/numbers/number-value.ts b/src/numbers/number-value.ts new file mode 100644 index 0000000..cb701b3 --- /dev/null +++ b/src/numbers/number-value.ts @@ -0,0 +1,13 @@ +import { NumberData } from './number-data'; + +export class NumberValue { + private value: number; + + constructor(obj: NumberData) { + this.value = obj.value; + } + + public format(): string { + return String(this.value); + } +} diff --git a/src/numbers/numbers.ts b/src/numbers/numbers.ts new file mode 100644 index 0000000..c9cc543 --- /dev/null +++ b/src/numbers/numbers.ts @@ -0,0 +1,101 @@ +import { NumberData } from './number-data'; +import { NumberValue } from './number-value'; + +export function isDigits(o: NumberData): boolean { + return ! o.literal; +} + +export function isDigitsCompatible(o: NumberData): boolean { + return o.suffix || ! o.literal; +} + +export function isLiteral(o: NumberData): boolean { + return o.literal; +} + +export function isNegative(o: NumberData): boolean { + return o.value < 0; +} + +export function literalNumber(value: number, raw: string, suffix=false): NumberData { + return { + value: value, + rawDigits: raw, + literal: true, + + suffix: suffix, + integer: value % 1 === 0 + }; +} + +export function digitNumber(value: number, raw: string, suffix=false): NumberData { + return { + value: value, + rawDigits: raw, + literal: false, + + suffix: suffix, + integer: value % 1 === 0 + }; +} + +/** + * Combine two numbers when parsing. + */ +export function combine(a: NumberData, b: NumberData): NumberData { + if(a.suffix && b.suffix) { + const value = a.value * b.value; + return { + value: value, + rawDigits: String(value), + integer: a.integer && b.integer, + suffix: true, + literal: true + }; + } else if(b.suffix) { + const value = a.value * b.value; + return { + value: value, + rawDigits: String(value), + integer: a.integer && b.integer, + suffix: true, + literal: true + }; + } else { + const raw = a.rawDigits + b.rawDigits; + const value = parseInt(raw, 10); + + return { + value: value, + rawDigits: raw, + integer: a.integer && b.integer, + literal: a.literal || b.literal, + suffix: false + }; + } +} + +export function negative(o: NumberData): NumberData { + return { + value: - o.value, + rawDigits: '-' + o.rawDigits, + integer: o.integer, + suffix: false, + literal: o.literal + }; +} + +export function float(a: NumberData, b: NumberData): NumberData { + const raw = a.rawDigits + '.' + b.rawDigits; + return { + value: parseFloat(raw), + rawDigits: raw, + integer: false, + literal: false, + suffix: false + }; +} + +export function map(data: NumberData) { + return new NumberValue(data); +} diff --git a/src/numbers/ordinal-data.ts b/src/numbers/ordinal-data.ts new file mode 100644 index 0000000..9b28ecb --- /dev/null +++ b/src/numbers/ordinal-data.ts @@ -0,0 +1,10 @@ +import { OrdinalPrecision } from './ordinal-precision'; + +/** + * Data that describes an ordinal. + */ +export interface OrdinalData { + value: number; + + precision: OrdinalPrecision; +} diff --git a/src/numbers/ordinal-precision.ts b/src/numbers/ordinal-precision.ts new file mode 100644 index 0000000..1fceba6 --- /dev/null +++ b/src/numbers/ordinal-precision.ts @@ -0,0 +1,8 @@ +/** + * Precision of an ordinal as expressed in text. + */ +export enum OrdinalPrecision { + Specific = 0, + + Ambiguous = 1 +} diff --git a/src/numbers/ordinal-value.ts b/src/numbers/ordinal-value.ts new file mode 100644 index 0000000..cd3a649 --- /dev/null +++ b/src/numbers/ordinal-value.ts @@ -0,0 +1,6 @@ +/** + * Ordinal. + */ +export interface OrdinalValue { + value: number; +} diff --git a/src/numbers/ordinals.ts b/src/numbers/ordinals.ts new file mode 100644 index 0000000..fef9b45 --- /dev/null +++ b/src/numbers/ordinals.ts @@ -0,0 +1,40 @@ +import { OrdinalData } from './ordinal-data'; +import { OrdinalValue } from './ordinal-value'; +import { OrdinalPrecision } from './ordinal-precision'; +import { Precision } from '../time/precision'; + +export function specificOrdinal(value: number): OrdinalData { + return { + value: value, + precision: OrdinalPrecision.Specific + }; +} + +export function ambigiousOrdinal(value: number): OrdinalData { + return { + value: value, + precision: OrdinalPrecision.Ambiguous + }; +} + +/** + * Map data collected for an ordinal into a value. + * + * @param r + */ +export function map(r: OrdinalData): OrdinalValue | null { + if(typeof r.value === 'undefined') return null; + + return { + value: r.value + }; +} + +/** + * Determine if an ordinal is specific. + * + * @param value + */ +export function isSpecific(value: OrdinalData): boolean { + return value.precision === OrdinalPrecision.Specific; +} diff --git a/src/resolver/ResolvedIntents.ts b/src/resolver/ResolvedIntents.ts new file mode 100644 index 0000000..f702b03 --- /dev/null +++ b/src/resolver/ResolvedIntents.ts @@ -0,0 +1,16 @@ +import { ResolvedIntent } from './resolved-intent'; + +/** + * + */ +export interface ResolvedIntents { + /** + * The best intent that matches. + */ + readonly best: ResolvedIntent | null; + + /** + * All of the matches. + */ + readonly matches: ReadonlyArray; +} diff --git a/src/resolver/builder.js b/src/resolver/builder.js deleted file mode 100644 index 83301af..0000000 --- a/src/resolver/builder.js +++ /dev/null @@ -1,80 +0,0 @@ -import Matcher from '../graph/matching/matcher'; -import ResolverParser from './parser'; -import ResolvedIntent from './resolved-intent'; - -/** - * This is a basic naive builder for instances of Resolver on top of the - * parser. - */ -export default class Builder { - constructor(language, data) { - this.language = language; - - this.values = {}; - - this.parser = new ResolverParser(language); - this.data = data || 'unknown'; - - this.resultHandler = (values, encounter) => { - const result = new ResolvedIntent(this.data); - - // Transfer any values that have been pushed by other parsers - const data = encounter.data(); - for(let i=0; i this.parser.outgoing.push(r)); - return this; - } - - this.parser.add(Array.prototype.slice.call(arguments), this.resultHandler); - - return this; - } - - build() { - this.parser.finalizer((results, encounter) => { - // Map so that only the data is made available - results = results.map(finalizeIntent); - - return { - best: results[0] || null, - matches: results - }; - }); - - return this.parser.toMatcher(); - } -} - -function finalizeIntent(result) { - result.data.score = result.score; - result.data._refreshExpression(); - return result.data; -} diff --git a/src/resolver/builder.ts b/src/resolver/builder.ts new file mode 100644 index 0000000..84f45e2 --- /dev/null +++ b/src/resolver/builder.ts @@ -0,0 +1,89 @@ +import { Matcher } from '../graph/matching/matcher'; +import { ResolverParser } from './parser'; +import { ResolvedIntent } from './resolved-intent'; +import { Language } from '../language/language'; +import { LanguageSpecificValue, NodeConvertable } from '../values/base'; +import { Collectable } from '../graph/collector'; +import { Match } from '../graph/matching'; +import { ResolvedIntents } from './ResolvedIntents'; +import { GraphBuildable } from '../graph/builder'; + +/** + * This is a basic naive builder for instances of Resolver on top of the + * parser. + */ +export class ResolverBuilder { + private language: Language; + private data: string; + + private parser: ResolverParser; + private resultHandler: Collectable; + + constructor(language: Language, data?: string) { + this.language = language; + + this.parser = new ResolverParser(language); + this.data = data || 'unknown'; + + this.resultHandler = (values, encounter) => { + const result = new ResolvedIntent(this.data); + + // Transfer any values that have been pushed by other parsers + const data = encounter.data(); + for(let i=0; i[]) { + if(args[0] instanceof Matcher) { + /** + * If adding another parser for resolving intent just copy all + * of its nodes as they should work just fine with our own parser. + * + * TODO: Maybe use add instead to use optimization? + */ + args[0].nodes.forEach(r => (this.parser as any).nodes.push(r)); + return this; + } + + this.parser.add(args, this.resultHandler); + + return this; + } + + public build(): Matcher { + return this.parser.reducer(({ results }) => { + // Reduce the results down to our intended structure + const actualResults = results.toArray() + .map(finalizeIntent); + + return { + best: actualResults[0] || null, + matches: actualResults + }; + }).toMatcher(); + } +} + +function finalizeIntent(result: Match): ResolvedIntent { + result.data.score = result.score; + result.data.refreshExpression(); + return result.data; +} diff --git a/src/resolver/expression/ExpressionPart.ts b/src/resolver/expression/ExpressionPart.ts new file mode 100644 index 0000000..3702b50 --- /dev/null +++ b/src/resolver/expression/ExpressionPart.ts @@ -0,0 +1,14 @@ +import { ExpressionPartType } from './ExpressionPartType'; +import { TextPosition } from './TextPosition'; + +export interface ExpressionPart { + /** + * Type of the part. + */ + type: ExpressionPartType; + + /** + * The location of this part within the source text. + */ + source: TextPosition; +} diff --git a/src/resolver/expression/ExpressionPartType.ts b/src/resolver/expression/ExpressionPartType.ts new file mode 100644 index 0000000..71813f9 --- /dev/null +++ b/src/resolver/expression/ExpressionPartType.ts @@ -0,0 +1,7 @@ +/** + * Type of expression this is. + */ +export enum ExpressionPartType { + Text = 'text', + Value = 'value' +} diff --git a/src/resolver/expression/TextPart.ts b/src/resolver/expression/TextPart.ts new file mode 100644 index 0000000..41b6770 --- /dev/null +++ b/src/resolver/expression/TextPart.ts @@ -0,0 +1,11 @@ +import { ExpressionPart } from './ExpressionPart'; +import { ExpressionPartType } from './ExpressionPartType'; + +/** + * Part within an expression that represents text. + */ +export interface TextPart extends ExpressionPart { + type: ExpressionPartType.Text; + + value: string; +} diff --git a/src/resolver/expression/TextPosition.ts b/src/resolver/expression/TextPosition.ts new file mode 100644 index 0000000..6e233a5 --- /dev/null +++ b/src/resolver/expression/TextPosition.ts @@ -0,0 +1,14 @@ +/** + * Position within a text. + */ +export interface TextPosition { + /** + * Start position, zero indexed and inclusive. + */ + start: number; + + /** + * End position, zero indexed and exclusive. + */ + end: number; +} diff --git a/src/resolver/expression/ValuePart.ts b/src/resolver/expression/ValuePart.ts new file mode 100644 index 0000000..098d86a --- /dev/null +++ b/src/resolver/expression/ValuePart.ts @@ -0,0 +1,13 @@ +import { ExpressionPart } from './ExpressionPart'; +import { ExpressionPartType } from './ExpressionPartType'; + +/** + * Part within an expression that represents a value. + */ +export interface ValuePart extends ExpressionPart { + type: ExpressionPartType.Value; + + id: string; + + value: any; +} diff --git a/src/resolver/expressions.js b/src/resolver/expressions.ts similarity index 58% rename from src/resolver/expressions.js rename to src/resolver/expressions.ts index 447bfd4..6ee1d4b 100644 --- a/src/resolver/expressions.js +++ b/src/resolver/expressions.ts @@ -1,23 +1,30 @@ -import TokenNode from '../graph/token'; -import SubNode from '../graph/sub'; -import ValueNode from './value'; -import ValueParserNode from './value-parser'; +import { TokenNode } from '../graph/token'; +import { SubNode } from '../graph/sub'; +import { ValueNode } from './value'; +import { ValueParserNode } from './value-parser'; +import { Encounter } from '../graph/matching'; +import { ExpressionPart } from './expression/ExpressionPart'; +import { ExpressionPartType } from './expression/ExpressionPartType'; +import { TextPart } from './expression/TextPart'; +import { ValuePart } from './expression/ValuePart'; +import { ResolvedIntent } from './resolved-intent'; /** * Refresh the expression by copying back values from the matches into the * expression and sub-expressions. */ -export function refresh(v) { +export function refresh(v: ResolvedIntent) { for(const e of v.expression) { - if(e.type === 'value') { - e.value = v.values[e.id]; + if(e.type === ExpressionPartType.Value) { + const part: ValuePart = e as ValuePart; + part.value = v.values.get(part.id); - if(e.value && e.value.expression) { + if(part.value && part.value.expression) { // The value has an expression - refresh it - refresh(e.value); - } else if(Array.isArray(e.value)) { + refresh(part.value); + } else if(Array.isArray(part.value)) { // The value is an array, check if entries have expressions - for(const e0 of e.value) { + for(const e0 of part.value) { if(e0.expression) { refresh(e0); } @@ -30,16 +37,16 @@ export function refresh(v) { /** * Describe the expression for the given encounter. */ -export function describe(encounter) { +export function describe(encounter: Encounter): ExpressionPart[] { // Partial matching so expose the full expression that would match - let path = []; - let text = []; + let path: (TextPart | ValuePart)[] = []; + let text: string[] = []; const nodes = encounter.currentNodes; const tokens = encounter.currentTokens; - const toPos = (c, p) => { - if(! c) c = encounter.currentIndex; + const toPos = (c: number | null, p: number) => { + if(c == null) c = encounter.currentIndex; let start = -1; let end = -1; for(let i=p; i 0) { path.push({ - type: 'text', + type: ExpressionPartType.Text, value: text.join(' '), source: toPos(tokens[i], startToken) @@ -87,8 +94,10 @@ export function describe(encounter) { } path.push({ - type: 'value', + type: ExpressionPartType.Value, + id: node.id, + value: undefined, source: toPos(tokens[i+1], tokens[i]) }); @@ -99,7 +108,7 @@ export function describe(encounter) { if(text.length > 0) { path.push({ - type: 'text', + type: ExpressionPartType.Text, value: text.join(' '), source: toPos(null, startToken) diff --git a/src/resolver/parser.js b/src/resolver/parser.js deleted file mode 100644 index 10c77d5..0000000 --- a/src/resolver/parser.js +++ /dev/null @@ -1,114 +0,0 @@ -import Builder from '../graph/builder'; -import Matcher from '../graph/matching/matcher'; - -import TokenNode from '../graph/token'; -import ValueNode from './value'; - -import { LanguageSpecificValue } from '../values/base'; -import { isDeepEqual } from '../utils/equality'; - -const VALUE = /{([a-zA-Z0-9]+)}/g; - -/** - * Extension to the normal parser that handles refering to a values by - * name in the text. - * - * TODO: Extended grammar for optional tokens and OR between tokens? - */ -export default class ResolverParser extends Builder { - constructor(language) { - super(language); - - this.values = {}; - - this.supportsFuzzy(); - this.allowPartial(); - } - - value(id, type) { - let factory = type; - if(factory instanceof LanguageSpecificValue) { - factory = factory.create(this.language); - } - - if(typeof factory === 'function') { - const matcher = factory; - factory = { - match(encounter) { - return matcher(encounter); - } - }; - } - - this.values[id] = factory; - return this; - } - - parse(text) { - let firstNode; - let node; - let parse = (from, to) => { - let sub = text.substring(from, to); - this.language.tokenize(sub).forEach(t => { - if(t.length === 0) return; - - let nextNode = new TokenNode(this.language, t); - - if(node) { - node.outgoing.push(nextNode); - } else { - firstNode = nextNode; - } - node = nextNode; - }); - }; - - let previousIndex = 0; - VALUE.lastIndex = 0; - let match; - while((match = VALUE.exec(text))) { - if(match.index !== 0) { - parse(previousIndex, match.index); - } - previousIndex = VALUE.lastIndex; - - const id = match[1]; - const value = this.values[id]; - if(! value) { - throw new Error('No type registered for ' + id); - } - - let nextNode = value.toNode - ? value.toNode(id) - : new ValueNode(id, value); - - if(node) { - node.outgoing.push(nextNode); - } else { - firstNode = nextNode; - } - node = nextNode; - } - - // Parse the remaining text - parse(previousIndex, text.length); - - return firstNode; - } - - createMatcher(language, nodes, options) { - return new ResolvingMatcher(language, nodes, options); - } -} - -class ResolvingMatcher extends Matcher { - - match(expression, options={}) { - options.matchIsEqual = options.partial - ? (a, b) => a.intent === b.intent && isDeepEqual(a.values, b.values) - : (a, b) => a.intent === b.intent; - - return super.match(expression, options); - } - -} diff --git a/src/resolver/parser.ts b/src/resolver/parser.ts new file mode 100644 index 0000000..b3a88da --- /dev/null +++ b/src/resolver/parser.ts @@ -0,0 +1,120 @@ +import { GraphBuilder } from '../graph/builder'; +import { Matcher, MatcherOptions, EncounterOptions } from '../graph/matching'; + +import { TokenNode } from '../graph/token'; +import { ValueNode } from './value'; + +import { LanguageSpecificValue, NodeConvertable } from '../values/base'; +import { isDeepEqual } from '../utils/equality'; +import { Node } from '../graph/node'; +import { Language } from '../language/language'; + +const VALUE = /{([a-zA-Z0-9]+)}/g; + +/** + * Extension to the normal parser that handles referring to values by + * name in the text. + * + * TODO: Extended grammar for optional tokens and OR between tokens? + */ +export class ResolverParser extends GraphBuilder { + private values: Map; + + constructor(language: Language) { + super(language); + + this.values = new Map(); + + this.supportsFuzzy(); + this.allowPartial(); + } + + public value(id: string, type: LanguageSpecificValue | NodeConvertable): this { + let factory = type; + if(factory instanceof LanguageSpecificValue) { + factory = factory.create(this.language); + } + + if(typeof factory === 'function') { + const matcher = factory; + factory = { + toNode(valueId: string) { + return new ValueNode(valueId, { + match: matcher + }); + } + }; + } + + this.values.set(id, factory); + return this; + } + + protected parse(text: string): Node { + let firstNode; + let node: Node | undefined; + const parse = (from: number, to: number) => { + const sub = text.substring(from, to); + for(const token of this.language.tokenize(sub)) { + const nextNode = new TokenNode(this.language, token); + + if(node) { + node.outgoing.push(nextNode); + } else { + firstNode = nextNode; + } + node = nextNode; + } + }; + + let previousIndex = 0; + VALUE.lastIndex = 0; + let match; + while((match = VALUE.exec(text))) { + if(match.index !== 0) { + parse(previousIndex, match.index); + } + previousIndex = VALUE.lastIndex; + + const id = match[1]; + const value = this.values.get(id); + if(! value) { + throw new Error('No type registered for ' + id); + } + + let nextNode = value.toNode(id); + + if(node) { + node.outgoing.push(nextNode); + } else { + firstNode = nextNode; + } + node = nextNode; + } + + // Parse the remaining text + parse(previousIndex, text.length); + + if(! firstNode) { + throw new Error('Could not parse data into nodes'); + } + + return firstNode; + } + + protected createMatcher(language: Language, nodes: Node[], options: MatcherOptions) { + return new ResolvingMatcher(language, nodes, options); + } +} + +class ResolvingMatcher extends Matcher { + + public match(expression: string, options: EncounterOptions={}) { + options.matchIsEqual = options.partial + ? (a, b) => a.intent === b.intent && isDeepEqual(a.values, b.values) + : (a, b) => a.intent === b.intent; + + return super.match(expression, options); + } + +} diff --git a/src/resolver/resolved-intent.js b/src/resolver/resolved-intent.js deleted file mode 100644 index 7ddea5c..0000000 --- a/src/resolver/resolved-intent.js +++ /dev/null @@ -1,31 +0,0 @@ -import { cloneObject } from '../utils/cloning'; -import { describe, refresh } from './expressions'; - -export default class ResolvedIntent { - - constructor(intent) { - this.intent = intent; - this.values = {}; - - Object.defineProperty(this, 'expression', { - enumerable: false, - writable: true - }); - } - - _updateExpression(encounter) { - this.expression = describe(encounter); - } - - _refreshExpression() { - refresh(this); - } - - _clone() { - const r = new ResolvedIntent(this.intent); - r.values = cloneObject(this.values); - r.expression = this.expression.map(cloneObject); - return r; - } -} - diff --git a/src/resolver/resolved-intent.ts b/src/resolver/resolved-intent.ts new file mode 100644 index 0000000..27e4468 --- /dev/null +++ b/src/resolver/resolved-intent.ts @@ -0,0 +1,39 @@ +import { describe, refresh } from './expressions'; +import { Encounter } from '../graph/matching'; +import { ExpressionPart } from './expression/ExpressionPart'; +import { clone } from '../utils/cloning'; + +export class ResolvedIntent { + public intent: string; + public values: Map; + public score: number; + public expression: ExpressionPart[]; + + constructor(intent: string) { + this.intent = intent; + this.values = new Map(); + this.score = 0; + this.expression = []; + + Object.defineProperty(this, 'expression', { + enumerable: false, + writable: true + }); + } + + public updateExpression(encounter: Encounter) { + this.expression = describe(encounter); + } + + public refreshExpression() { + refresh(this); + } + + public clone() { + const r = new ResolvedIntent(this.intent); + r.values = new Map(this.values); + r.expression = clone(this.expression); + return r; + } +} + diff --git a/src/resolver/value-parser.js b/src/resolver/value-parser.ts similarity index 57% rename from src/resolver/value-parser.js rename to src/resolver/value-parser.ts index a4d86c9..7b7978d 100644 --- a/src/resolver/value-parser.js +++ b/src/resolver/value-parser.ts @@ -1,17 +1,32 @@ import { isDeepEqual } from '../utils/equality'; -import Node from '../graph/node'; -import SubNode from '../graph/sub'; +import { Node } from '../graph/node'; +import { SubNode } from '../graph/sub'; +import { Matcher, Encounter } from '../graph/matching'; -export default class ValueParser extends Node { - constructor(id, matcher, options={}) { +export interface ValueParserOptions { + /** + * If the partial should be presented as a blank value if it is being + * matched and no more tokens are available. + */ + partialBlankWhenNoToken?: boolean; +} + +export class ValueParserNode extends Node { + public readonly id: string; + private node: SubNode; + private options: ValueParserOptions; + + private partialBlankWhenNoToken: boolean; + + constructor(id: string, matcher: Matcher, options: ValueParserOptions={}) { super(); this.id = id; this.node = new SubNode(matcher, matcher.options); this.options = options; - this.partialBlankWhenNoToken = ! this.node.supportsPartial || options.partialBlankWhenNoToken; + this.partialBlankWhenNoToken = ! this.node.supportsPartial || options.partialBlankWhenNoToken || false; /* * Make sure that the result of evaluating this sub-graph is mapped @@ -31,17 +46,17 @@ export default class ValueParser extends Node { // Map it into a value format return { id: id, - value: options.mapper ? options.mapper(r) : r + value: r//options.mapper ? options.mapper(r) : r }; }; } - equals(o) { - return o instanceof ValueParser && this.node.equals(o.node) + public equals(o: Node): boolean { + return o instanceof ValueParserNode && this.node.equals(o.node) && isDeepEqual(this.options, o.options); } - match(encounter) { + public match(encounter: Encounter) { if(! encounter.token() && encounter.options.partial && this.partialBlankWhenNoToken && (! this.node.supportsPartial || ! encounter.isJustAfterLastToken)) { /* @@ -54,7 +69,7 @@ export default class ValueParser extends Node { return this.node.match(encounter); } - toString() { + public toString() { return 'ValueParser[' + this.id + ']'; } } diff --git a/src/resolver/value-static.js b/src/resolver/value-static.js deleted file mode 100644 index ec37af6..0000000 --- a/src/resolver/value-static.js +++ /dev/null @@ -1,25 +0,0 @@ -import { isDeepEqual } from '../utils/equality'; - -import Node from '../graph/node'; - -export default class ValueStatic extends Node { - constructor(id, value) { - super(); - - this.id = id; - this.value = value; - } - - equals(o) { - return o instanceof ValueStatic && this.id.equals(o.id) - && isDeepEqual(this.value, o.value); - } - - match(encounter) { - return encounter.next(0, 0, { id: this.id, value: this.value }); - } - - toString() { - return 'ValueStatic[' + this.id + '=' + this.value + ']'; - } -} diff --git a/src/resolver/value-static.ts b/src/resolver/value-static.ts new file mode 100644 index 0000000..b94efe6 --- /dev/null +++ b/src/resolver/value-static.ts @@ -0,0 +1,33 @@ +import { isDeepEqual } from '../utils/equality'; + +import { Node } from '../graph/node'; +import { Encounter } from '../graph/matching'; + +/** + * Node that represents a value that isn't extracted from text, but instead + * is always present if a match occurs later. + */ +export class ValueStatic extends Node { + private id: string; + private value: V; + + constructor(id: string, value: V) { + super(); + + this.id = id; + this.value = value; + } + + public equals(o: Node): boolean { + return o instanceof ValueStatic && this.id === o.id + && isDeepEqual(this.value, o.value); + } + + public match(encounter: Encounter) { + return encounter.next(0, 0, { id: this.id, value: this.value }); + } + + public toString() { + return 'ValueStatic[' + this.id + '=' + this.value + ']'; + } +} diff --git a/src/resolver/value.js b/src/resolver/value.ts similarity index 50% rename from src/resolver/value.js rename to src/resolver/value.ts index a1b6cca..63f143a 100644 --- a/src/resolver/value.js +++ b/src/resolver/value.ts @@ -1,4 +1,34 @@ -import Node from '../graph/node'; +import { Node } from '../graph/node'; +import { Encounter, Match } from '../graph/matching'; +import { isDeepEqual } from '../utils/equality'; +import { Token, Tokens } from '../language/tokens'; + +/** + * Options for a ValueNode. + */ +export interface ValueNodeOptions { + /** + * Make the node try to match as much as possible and then work + * backward until it finds the smallest possible match. + */ + greedy?: boolean; + + /** + * Make the value short circuit after it has first found a value. Useful + * when remotely validating values and using them in conjunction with + * repeating things such as option values. + */ + onlySingle?: boolean; + + /** + * The maximum number of hits to match, defaults to 10. If a value + * generates more matches during a partial match the top scoring matches + * will be returned. + */ + max?: number; + + match: (encounter: ValueEncounter) => Promise; +} /** * Custom node used by resolvers to match free-text expressions. This node @@ -21,15 +51,18 @@ import Node from '../graph/node'; * generates more matches during a partial match the top scoring matches * will be returned. */ -export default class Value extends Node { - constructor(id, options) { +export class ValueNode extends Node { + public readonly id: string; + private options: ValueNodeOptions; + + constructor(id: string, options: ValueNodeOptions) { super(); this.id = id; this.options = options; } - match(encounter) { + public match(encounter: Encounter) { const tokens = encounter.tokens; const currentIndex = encounter.currentIndex; const stop = tokens.length; @@ -38,8 +71,8 @@ export default class Value extends Node { * Values always try to match as much as they can so we loop backwards * from the largest amount of tokens we could consume to only 1. */ - let valueEncounter = new ValueEncounter(encounter); - let results = []; + const valueEncounter = new ValueEncounter(encounter); + const results: Match[] = []; if(currentIndex >= stop) { /* @@ -50,21 +83,22 @@ export default class Value extends Node { return encounter.isPartial ? encounter.next(0.0, 0) : Promise.resolve(); } - const onMatch = match => { + const onMatch = (m: Match) => { + valueEncounter.matches.length = 0; return Promise.resolve(this.options.match(valueEncounter)) .then(() => { - if(valueEncounter._matches.length === 0) return; + if(valueEncounter.matches.length === 0) return; - for(const v of valueEncounter._matches) { - const matchCopy = match.copy(); - matchCopy.data.values[this.id] = v.value; + for(const v of valueEncounter.matches) { + const matchCopy = m.copy(); + matchCopy.data.values.set(this.id, v.value); matchCopy.scoreData.score += 0.9 * v.score; results.push(matchCopy); } }); }; - const match = idx => { + const match = (idx: number): Promise => { const len = idx - currentIndex; if((this.options.greedy && len === 0) @@ -74,7 +108,7 @@ export default class Value extends Node { valueEncounter._adjust(currentIndex, idx); return encounter.branchWithOnMatch(onMatch, () => encounter.next(0, len)) .then(() => { - // If request to only match to keep + // Attempting to match only a single match and already found it if(this.options.onlySingle && results.length > 0) return; if(this.options.greedy) { @@ -102,33 +136,68 @@ export default class Value extends Node { }); } - toString() { - return 'Value[' + this.id + ']'; + public equals(obj: Node): boolean { + return obj instanceof ValueNode + && isDeepEqual(this.options, obj.options); + } + + public toString() { + return 'ValueNode[' + this.id + ']'; } } -class ValueEncounter { - constructor(encounter) { - this._encounter = encounter; - this.partial = encounter.options.partial; - this._matches = []; +export class ValueEncounter { + public matches: ValueMatch[]; + private encounter: Encounter; + public partial: boolean; + public tokens: Tokens; + + constructor(encounter: Encounter) { + this.encounter = encounter; + this.partial = encounter.options.partial || false; + this.matches = []; + this.tokens = Tokens.empty(); } - _adjust(from, end) { - this.tokens = this._encounter.tokens.slice(from, end); - this._matches.length = 0; + public _adjust(from: number, end: number) { + this.tokens = this.encounter.tokens.slice(from, end); + this.matches.length = 0; } - text() { + /** + * Get the text of the value. + */ + public text() { return this.tokens.raw(); } - match(value, score=1) { - if(! this.partial && this._matches.length >= 1) { + /** + * Add a new value that has matched. + * + * @param value + * @param score + */ + public match(value: V, score=1) { + if(! this.partial && this.matches.length >= 1) { throw new Error('Multiple matches are only supported when in partial mode'); } - this._matches.push({ value, score }); + this.matches.push({ value, score }); } } + +/** + * Match as found during encounter with value. + */ +interface ValueMatch { + /** + * The value matched. + */ + value: V; + + /** + * Local score of the value. + */ + score: number; +} diff --git a/src/time/currentTime.js b/src/time/currentTime.js deleted file mode 100644 index 833d215..0000000 --- a/src/time/currentTime.js +++ /dev/null @@ -1,11 +0,0 @@ - -/** - * Resolve the current time from the given encounter. - */ -export default function(encounter) { - if(encounter.options.now) { - return encounter.options.now; - } else { - return encounter.options.now = new Date(); - } -} diff --git a/src/time/currentTime.ts b/src/time/currentTime.ts new file mode 100644 index 0000000..5064bef --- /dev/null +++ b/src/time/currentTime.ts @@ -0,0 +1,13 @@ +import { DateTimeOptions } from './options'; + +/** + * Resolve the current time from the given options. This is used so that the + * time can be set to the current time if needed. + */ +export function currentTime(options: DateTimeOptions) { + if(options.now) { + return options.now; + } else { + return options.now = new Date(); + } +} diff --git a/src/time/date-intervals.js b/src/time/date-intervals.ts similarity index 51% rename from src/time/date-intervals.js rename to src/time/date-intervals.ts index 5236d4f..10084c5 100644 --- a/src/time/date-intervals.js +++ b/src/time/date-intervals.ts @@ -1,12 +1,17 @@ import { map as mapDate, today } from './dates'; import { cloneObject } from '../utils/cloning'; -import IntervalValue from './interval-value'; +import { IntervalValue } from './interval-value'; import { adjusted } from './matching'; +import { DateTimeEncounter } from './encounter'; +import { IntervalData } from './interval-data'; +import { DateTimeData } from './date-time-data'; +import { IntervalEdge } from './edge'; +import { TimeRelationship } from './relationship'; /** * Create an interval that matches dates in the past. */ -export function inThePast(r, encounter) { +export function inThePast(r: any, encounter: DateTimeEncounter) { return { start: null, end: adjusted(today(null, encounter), -1) @@ -16,7 +21,7 @@ export function inThePast(r, encounter) { /** * Create an interval that matches dates in the future. */ -export function inTheFuture(r, encounter) { +export function inTheFuture(r: any, encounter: DateTimeEncounter) { return { start: adjusted(today(null, encounter), 1), end: null @@ -33,17 +38,17 @@ export function anyTime() { }; } -export function hasSingle(v) { +export function hasSingle(v: IntervalData) { return v && typeof v.start !== 'undefined' && v.start === v.end; } -function applyRelationAndEdge(r, edge) { +function applyRelationAndEdge(r: DateTimeData, edge: IntervalEdge) { if(! r.intervalEdge) r.intervalEdge = edge; - if(! r.relationToCurrent) r.relationToCurrent = 'current-period'; + if(! r.relationToCurrent) r.relationToCurrent = TimeRelationship.CurrentPeriod; return r; } -export function map(r, e) { +export function map(r: IntervalData, e: DateTimeEncounter): IntervalValue { let start = null; let end = null; @@ -56,20 +61,22 @@ export function map(r, e) { if(typeof r.start.year === 'undefined') r.start.year = r.end.year; if(typeof r.start.month === 'undefined') r.start.month = r.end.month; - start = mapDate(applyRelationAndEdge(cloneObject(r.start), 'start'), e); - end = mapDate(applyRelationAndEdge(r.end, 'end'), e, { now: start.toDate() }); + start = mapDate(applyRelationAndEdge(cloneObject(r.start), IntervalEdge.Start), e); + if(! start) throw new Error(); + + end = mapDate(applyRelationAndEdge(r.end, IntervalEdge.End), e, { now: start.toDate() }); } else { - end = mapDate(applyRelationAndEdge(r.end, 'end'), e); + end = mapDate(applyRelationAndEdge(r.end, IntervalEdge.End), e); } } else { // This interval has no end if(r.start) { // There is a start available - map it - start = mapDate(applyRelationAndEdge(r.start, 'start'), e); + start = mapDate(applyRelationAndEdge(r.start, IntervalEdge.Start), e); } else { // No start and no end, represents all time } } - return new IntervalValue(start, end); + return new IntervalValue(start || undefined, end || undefined); } diff --git a/src/time/date-time-data.ts b/src/time/date-time-data.ts new file mode 100644 index 0000000..eb96508 --- /dev/null +++ b/src/time/date-time-data.ts @@ -0,0 +1,53 @@ +import { TimeRelationship } from './relationship'; +import { IntervalEdge } from './edge'; +import { Weekday } from './weekday'; +import { Meridiem } from './meridiem'; +import { Precision } from './precision'; + +/** + * Data that is extracted during a parse operation. This is used to map into + * a date - which is represented by DateValue. + */ +export interface DateTimeData { + precision?: Precision; + + year?: number; + quarter?: number; + week?: number; + month?: number; + day?: number; + + /** + * Day of week requested. + */ + dayOfWeek?: Weekday; + + /** + * Ordinal describing what day of week in the current period is being + * described. + */ + dayOfWeekOrdinal?: number; + + meridiem?: Meridiem; + + hour?: number; + minute?: number; + second?: number; + millisecond?: number; + + relativeTo?: DateTimeData; + relativeYears?: number; + relativeQuarters?: number; + relativeWeeks?: number; + relativeMonths?: number; + relativeDays?: number; + relativeHours?: number; + relativeMinutes?: number; + relativeSeconds?: number; + relativeMilliseconds?: number; + + relationToCurrent?: TimeRelationship; + intervalEdge?: IntervalEdge; + + intervalAdjustment?: number; +} diff --git a/src/time/date-times.js b/src/time/date-times.js deleted file mode 100644 index 9dc51fd..0000000 --- a/src/time/date-times.js +++ /dev/null @@ -1,8 +0,0 @@ -import { map as mapDate } from './dates'; -import { map as mapTime } from './times'; - -export function map(r, e) { - const result = mapDate(r, e); - - return mapTime(r, e, result.toDate(), result); -} diff --git a/src/time/date-times.ts b/src/time/date-times.ts new file mode 100644 index 0000000..dbeaf69 --- /dev/null +++ b/src/time/date-times.ts @@ -0,0 +1,14 @@ +import { DateTimeData } from './date-time-data'; +import { DateTimeEncounter } from './encounter'; + +import { map as mapDate } from './dates'; +import { map as mapTime } from './times'; + +export function map(r: DateTimeData, e: DateTimeEncounter) { + const result = mapDate(r, e); + + // If the date doesn't map, skip time mapping + if(! result) return null; + + return mapTime(r, e, { now: result.toDate() }, result); +} diff --git a/src/time/date-value.js b/src/time/date-value.js deleted file mode 100644 index 8dbf8aa..0000000 --- a/src/time/date-value.js +++ /dev/null @@ -1,13 +0,0 @@ -import toDate from './toDate'; - -export default class DateValue { - constructor(language) { - Object.defineProperty(this, 'language', { - value: language - }); - } - - toDate(now) { - return toDate(this, now || new Date()); - } -} diff --git a/src/time/date-value.ts b/src/time/date-value.ts new file mode 100644 index 0000000..9482b32 --- /dev/null +++ b/src/time/date-value.ts @@ -0,0 +1,46 @@ +import { toDate } from './toDate'; +import { Language } from '../language/language'; +import { Period } from './period'; +import { Precision } from './precision'; + +export interface DateValue { + readonly period?: Period; + readonly precision?: Precision; + + readonly year?: number; + readonly month?: number; + readonly day?: number; + + readonly hour?: number; + readonly minute?: number; + readonly second?: number; + readonly millisecond?: number; + + /** + * Convert this value into a Date. + * + * @param now + */ + toDate(now?: Date): Date; +} + +export class MutableDateValue implements DateValue { + public period?: Period; + public precision?: Precision; + + public year?: number; + public month?: number; + public day?: number; + + public hour?: number; + public minute?: number; + public second?: number; + public millisecond?: number; + + constructor() { + } + + public toDate(now?: Date): Date { + return toDate(this, now || new Date()); + } +} diff --git a/src/time/dates.js b/src/time/dates.ts similarity index 50% rename from src/time/dates.js rename to src/time/dates.ts index f581a91..413a366 100644 --- a/src/time/dates.js +++ b/src/time/dates.ts @@ -1,34 +1,45 @@ -import addMonths from 'date-fns/addMonths'; -import addQuarters from 'date-fns/addQuarters'; -import addWeeks from 'date-fns/addWeeks'; -import addDays from 'date-fns/addDays'; -import addYears from 'date-fns/addYears'; - -import setDay from 'date-fns/setDay'; -import getDay from 'date-fns/getDay'; - -import setWeek from 'date-fns/setWeek'; -import getWeek from 'date-fns/getWeek'; - -import setQuarter from 'date-fns/setQuarter'; -import getQuarter from 'date-fns/getQuarter'; - -import setYear from 'date-fns/setYear'; -import setMonth from 'date-fns/setMonth'; -import setDate from 'date-fns/setDate'; - -import startOfYear from 'date-fns/startOfYear'; -import startOfQuarter from 'date-fns/startOfQuarter'; -import startOfWeek from 'date-fns/startOfWeek'; -import startOfMonth from 'date-fns/startOfMonth'; - -import currentTime from './currentTime'; -import DateValue from './date-value'; - +import { + addYears, + addQuarters, + addWeeks, + addMonths, + addDays, + + setDay, + getDay, + + setWeek, + getWeek, + + setQuarter, + getQuarter, + + setYear, + setMonth, + setDate, + + startOfYear, + startOfQuarter, + startOfWeek, + startOfMonth +} from 'date-fns'; + +import { DateTimeEncounter } from './encounter'; +import { DateTimeData } from './date-time-data'; +import { DateTimeOptions } from './options'; +import { MutableDateValue } from './date-value'; + +import { TimeRelationship } from './relationship'; +import { Period } from './period'; +import { IntervalEdge } from './edge'; + +import { currentTime } from './currentTime'; import { toStart, toEnd } from './intervals'; +import { combine } from './matching'; +import { Weekday } from './weekday'; -export function today(r, e) { - const time = currentTime(e); +export function today(r: any, e: DateTimeEncounter) { + const time = currentTime(e.options); return { day: time.getDate(), month: time.getMonth(), @@ -36,8 +47,8 @@ export function today(r, e) { }; } -export function tomorrow(r, e) { - const time = addDays(currentTime(e), 1); +export function tomorrow(r: any, e: DateTimeEncounter) { + const time = addDays(currentTime(e.options), 1); return { day: time.getDate(), month: time.getMonth(), @@ -45,8 +56,8 @@ export function tomorrow(r, e) { }; } -export function dayAfterTomorrow(r, e) { - const time = addDays(currentTime(e), 2); +export function dayAfterTomorrow(r: any, e: DateTimeEncounter) { + const time = addDays(currentTime(e.options), 2); return { day: time.getDate(), month: time.getMonth(), @@ -54,8 +65,8 @@ export function dayAfterTomorrow(r, e) { }; } -export function yesterday(r, e) { - const time = addDays(currentTime(e), -1); +export function yesterday(r: any, e: DateTimeEncounter) { + const time = addDays(currentTime(e.options), -1); return { day: time.getDate(), month: time.getMonth(), @@ -63,8 +74,34 @@ export function yesterday(r, e) { }; } -const QUARTER = { - field: 'quarter', +export function withDay(r: DateTimeData, day: number) { + return combine(r, { + day: day + }); +} + +export function withYear(r: DateTimeData, year: number) { + return combine(r, { + year: year < 1000 ? year + 2000 : year + }); +} + +export function nextDayOfWeek(day: Weekday) { + return { dayOfWeek: day }; +} + +interface Adjustment { + getField: (o: DateTimeData) => number; + + get: (date: Date, options?: DateTimeOptions) => number; + set: (date: Date, v: number, options?: DateTimeOptions) => Date; + + adjuster: (date: Date, v: number, options?: DateTimeOptions) => Date; + parentData: (r: DateTimeData) => boolean; +} + +const QUARTER: Adjustment = { + getField: o => o.quarter || 0, get: getQuarter, set: setQuarter, @@ -73,8 +110,8 @@ const QUARTER = { parentData: r => typeof r.year !== 'undefined' }; -const WEEK = { - field: 'week', +const WEEK: Adjustment = { + getField: o => o.week || 0, get: getWeek, set: setWeek, @@ -83,8 +120,8 @@ const WEEK = { parentData: r => typeof r.year !== 'undefined' }; -const MONTH = { - field: 'month', +const MONTH: Adjustment = { + getField: o => o.month || 0, get: d => d.getMonth(), set: setMonth, @@ -93,8 +130,8 @@ const MONTH = { parentData: r => typeof r.year !== 'undefined' }; -const DAY = { - field: 'day', +const DAY: Adjustment = { + getField: o => o.day || 0, get: d => d.getDate(), set: setDate, @@ -115,51 +152,42 @@ const DAY = { * @param {*} def * definition describing the field to modify */ -function adjust(r, e, time, def) { - const requested = r[def.field]; - const current = def.get(time, e.options); +function adjust(r: DateTimeData, options: DateTimeOptions, time: Date, def: Adjustment) { + const requested = def.getField(r); + const current = def.get(time, options); - if(r.relationToCurrent === 'auto') { + if(r.relationToCurrent === TimeRelationship.Auto) { if(requested < current) { - time = def.set(def.adjuster(time, 1, e.options), requested, e.options); + time = def.set(def.adjuster(time, 1, options), requested, options); } else { - time = def.set(time, requested, e.options); + time = def.set(time, requested, options); } - } else if(r.relationToCurrent === 'current-period') { + } else if(r.relationToCurrent === TimeRelationship.CurrentPeriod) { if(def.parentData(r) && requested < current) { - time = def.set(def.adjuster(time, 1, e.options), requested, e.options); + time = def.set(def.adjuster(time, 1, options), requested, options); } else { - time = def.set(time, requested, e.options); + time = def.set(time, requested, options); } - } else if(r.relationToCurrent === 'future') { + } else if(r.relationToCurrent === TimeRelationship.Future) { if(requested <= current) { - time = def.set(def.adjuster(time, 1, e.options), requested, e.options); + time = def.set(def.adjuster(time, 1, options), requested, options); } else { - time = def.set(time, requested, e.options); + time = def.set(time, requested, options); } - } else if(r.relationToCurrent === 'past') { + } else if(r.relationToCurrent === TimeRelationship.Past) { if(requested >= current) { - time = def.set(def.adjuster(time, -1, e.options), requested, e.options); + time = def.set(def.adjuster(time, -1, options), requested, options); } else { - time = def.set(time, requested, e.options); + time = def.set(time, requested, options); } } return time; } -export function map(r, e, options={}) { - if(r instanceof Date) { - // Special case to turn a Date into a DateValue - const result = new DateValue(e.language); - result.year = r.getFullYear(); - result.month = r.getMonth(); - result.day = r.getDate(); - return result; - } - +export function map(r: DateTimeData, e: DateTimeEncounter, options: DateTimeOptions={}): MutableDateValue | null { if(! r.relationToCurrent) { - r.relationToCurrent = 'auto'; + r.relationToCurrent = TimeRelationship.Auto; } // Resolve the current time for the encounter @@ -175,77 +203,77 @@ export function map(r, e, options={}) { time = resolvedTime.toDate(); } else { - time = options.now || currentTime(e); + time = options.now || currentTime(e.options); } // The actual result - const result = new DateValue(e.language); - result.period = 'day'; + const result = new MutableDateValue(); + result.period = Period.Day; // First resolve the year if(typeof r.relativeYears !== 'undefined') { // Relative year - add the years and keep the current month and day - result.period = 'year'; + result.period = Period.Year; time = addYears(time, r.relativeYears); } else if(typeof r.year !== 'undefined') { // Exact year - set the month and day to the start of year - result.period = 'year'; + result.period = Period.Year; time = startOfYear(setYear(time, r.year)); } // Resolve quarter if set if(typeof r.relativeQuarters !== 'undefined') { // Relative quarter - add the number of quarters, but try to keep day within quarter - result.period = 'quarter'; + result.period = Period.Quarter; time = addQuarters(time, r.relativeQuarters); } else if(typeof r.quarter !== 'undefined') { // Exact quarter - set it and reset to start of quarter - result.period = 'quarter'; + result.period = Period.Quarter; - time = adjust(r, e, time, QUARTER); - time = startOfQuarter(time, e.options); + time = adjust(r, e.options, time, QUARTER); + time = startOfQuarter(time); } // Resolve week if set if(typeof r.relativeWeeks !== 'undefined') { // Relative week - add the week, keep the week day - result.period = 'week'; + result.period = Period.Week; time = addWeeks(time, r.relativeWeeks); } else if(typeof r.week !== 'undefined') { // Exact week - set it and reset to start of week - result.period = 'week'; + result.period = Period.Week; - time = adjust(r, e, time, WEEK); + time = adjust(r, e.options, time, WEEK); time = startOfWeek(time, e.options); } // Resolve the month if(typeof r.relativeMonths !== 'undefined') { // Relative month - add the months and keep the day - result.period = 'month'; + result.period = Period.Month; time = addMonths(time, r.relativeMonths); } else if(typeof r.month !== 'undefined') { // Exact month - set the day to the start of the month - result.period = 'month'; + result.period = Period.Month; - time = adjust(r, e, time, MONTH); + time = adjust(r, e.options, time, MONTH); time = startOfMonth(time); } // Resolve the day if(typeof r.relativeDays !== 'undefined') { // Relative day - result.period = 'day'; + result.period = Period.Day; time = addDays(time, r.relativeDays); } else if(typeof r.day !== 'undefined') { // If there is an explicit day set it - result.period = 'day'; + result.period = Period.Day; - time = adjust(r, e, time, DAY); + time = adjust(r, e.options, time, DAY); } if(typeof r.dayOfWeek !== 'undefined') { - result.period = 'day'; + result.period = Period.Day; const currentDayOfWeek = getDay(time); if(currentDayOfWeek >= r.dayOfWeek) { @@ -253,22 +281,24 @@ export function map(r, e, options={}) { } time = setDay(time, r.dayOfWeek); - for(let i=1; i 24) return null; - if(minute < 0 || minute > 60) return null; - if(second < 0 || second > 60) return null; + if(typeof minute !== 'undefined' && (minute < 0 || minute > 60)) return null; + if(typeof second !== 'undefined' && (second < 0 || second > 60)) return null; return { hour: hour, minute: minute, second: second, - meridiem: hour === 0 || hour > 12 ? 'fixed' : 'auto' + meridiem: hour === 0 || hour > 12 ? Meridiem.Fixed : Meridiem.Auto }; } /** * Create a time in 24-hour clock, which will not guess AM or PM. */ -export function time24h(hour, minute, second) { +export function time24h(hour: number, minute?: number, second?: number): DateTimeData | null { if(hour < 0 || hour > 24) return null; - if(minute < 0 || minute > 60) return null; - if(second < 0 || second > 60) return null; + if(typeof minute !== 'undefined' && (minute < 0 || minute > 60)) return null; + if(typeof second !== 'undefined' && (second < 0 || second > 60)) return null; return { hour: hour, minute: minute, second: second, - meridiem: 'fixed' + meridiem: Meridiem.Fixed }; } /** * Switch the given time to PM. */ -export function toPM(time) { - time.meridiem = 'pm'; +export function toPM(time: DateTimeData) { + time.meridiem = Meridiem.Pm; return time; } /** * Switch the given time to AM. */ -export function toAM(time) { - time.meridiem = 'am'; +export function toAM(time: DateTimeData) { + time.meridiem = Meridiem.Am; return time; } -export function map(r, e, now, result) { - result = result || new DateValue(e.language); +export function map(r: DateTimeData, e: DateTimeEncounter, options?: DateTimeOptions, result?: MutableDateValue) { + result = result || new MutableDateValue(); - let current = currentTime(e); + const current = currentTime(e.options); let time = current; - if(! now) { - now = current; - } + const now = (options && options.now) ? options.now : current; if(typeof r.relativeHours !== 'undefined') { - result.period = 'hour'; + result.period = Period.Hour; time = addHours(time, r.relativeHours); } else if(typeof r.hour !== 'undefined') { - result.period = 'hour'; + result.period = Period.Hour; if(r.hour > 12) { // Always force fixed meridiem when hours are > 12 - r.meridiem = 'fixed'; + r.meridiem = Meridiem.Fixed; } // Hours are a bit special and require some special meridiem handling let hourToSet; - if(r.meridiem === 'auto') { + if(r.meridiem === Meridiem.Auto) { // Automatic meridiem const hour12 = now.getHours() % 12 || 12; if(r.hour < hour12 || (now.getHours() > 12 && r.hour === 12)) { @@ -92,10 +100,10 @@ export function map(r, e, now, result) { } else { hourToSet = now.getHours() <= 12 ? r.hour : (r.hour + 12); } - } else if(r.meridiem === 'am') { + } else if(r.meridiem === Meridiem.Am) { // AM meridiem - time set is hours directly hourToSet = r.hour === 12 ? 0 : r.hour; - } else if(r.meridiem === 'pm') { + } else if(r.meridiem === Meridiem.Pm) { // PM meridiem - time to set is hours + 12 hourToSet = r.hour === 12 ? 12 : (r.hour + 12); } else { @@ -110,13 +118,13 @@ export function map(r, e, now, result) { } if(typeof r.relativeMinutes !== 'undefined') { - result.period = 'minute'; + result.period = Period.Minute; time = addMinutes(time, r.relativeMinutes); } else if(typeof r.minute !== 'undefined') { - result.period = 'minute'; + result.period = Period.Minute; - if(r.minute < time.getMinutes() && ! r.past) { + if(r.minute < time.getMinutes() && r.relationToCurrent !== TimeRelationship.Past) { // The given minute is before the current minute - assume next hour time = setMinutes(addHours(time, 1), r.minute); } else { @@ -128,13 +136,13 @@ export function map(r, e, now, result) { } if(typeof r.relativeSeconds !== 'undefined') { - result.period = 'second'; + result.period = Period.Second; time = addSeconds(time, r.relativeSeconds); } else if(typeof r.second !== 'undefined') { - result.period = 'second'; + result.period = Period.Second; - if(r.second < time.getSeconds() && ! r.past) { + if(r.second < time.getSeconds() && r.relationToCurrent !== TimeRelationship.Past) { // The given second is before the current second - assume next minute time = setSeconds(addMinutes(time, 1), r.second); } else { @@ -146,7 +154,7 @@ export function map(r, e, now, result) { result.hour = time.getHours(); result.minute = time.getMinutes(); result.second = time.getSeconds(); - result.precision = r.precision || result.precision || 'normal'; + result.precision = r.precision || result.precision || Precision.Normal; return result; } diff --git a/src/time/toDate.js b/src/time/toDate.ts similarity index 59% rename from src/time/toDate.js rename to src/time/toDate.ts index 447474f..a4fb85c 100644 --- a/src/time/toDate.js +++ b/src/time/toDate.ts @@ -1,10 +1,13 @@ -export default function(date, now) { +import { DateValue } from './date-value'; + +export function toDate(date: DateValue, now: Date): Date { return new Date( typeof date.year !== 'undefined' ? date.year : now.getFullYear(), typeof date.month !== 'undefined' ? date.month : now.getMonth(), typeof date.day !== 'undefined' ? date.day : now.getDate(), typeof date.hour !== 'undefined' ? date.hour : 0, typeof date.minute !== 'undefined' ? date.minute : 0, - typeof date.second !== 'undefined' ? date.second : 0 + typeof date.second !== 'undefined' ? date.second : 0, + typeof date.millisecond !== 'undefined' ? date.millisecond : 0 ); } diff --git a/src/time/weekday.ts b/src/time/weekday.ts new file mode 100644 index 0000000..1255f1a --- /dev/null +++ b/src/time/weekday.ts @@ -0,0 +1,12 @@ +/** + * Enum representing the day of week. + */ +export enum Weekday { + Sunday = 0, + Monday = 1, + Tuesday = 2, + Wednesday = 3, + Thursday = 4, + Friday = 5, + Saturday = 6 +} diff --git a/src/time/weeks.js b/src/time/weeks.js deleted file mode 100644 index 716fa31..0000000 --- a/src/time/weeks.js +++ /dev/null @@ -1,35 +0,0 @@ -import addWeeks from 'date-fns/addWeeks'; -import getWeek from 'date-fns/getWeek'; - -import currentTime from './currentTime'; -import { map as mapInterval } from './date-intervals'; - -export function thisWeek(r, e) { - const time = currentTime(e); - return { - week: getWeek(time, e.options) - }; -} - -export function nextWeek(r, e) { - const time = addWeeks(currentTime(e), 1); - return { - year: time.getFullYear(), - week: getWeek(time, e.options) - }; -} - -export function previousWeek(r, e) { - const time = addWeeks(currentTime(e), -1); - return { - year: time.getFullYear(), - week: getWeek(time, e.options) - }; -} - -/** - * Map weeks as intervals. - */ -export function map(r, e) { - return mapInterval({ from: r, to: r }, e); -} diff --git a/src/time/weeks.ts b/src/time/weeks.ts new file mode 100644 index 0000000..4c0d36f --- /dev/null +++ b/src/time/weeks.ts @@ -0,0 +1,40 @@ +import { + addWeeks, + getWeek +} from 'date-fns'; + +import { DateTimeEncounter } from './encounter'; +import { DateTimeData } from './date-time-data'; + +import { map as mapInterval } from './date-intervals'; +import { currentTime } from './currentTime'; + +export function thisWeek(r: any, e: DateTimeEncounter): DateTimeData { + const time = currentTime(e.options); + return { + week: getWeek(time, e.options) + }; +} + +export function nextWeek(r: any, e: DateTimeEncounter): DateTimeData { + const time = addWeeks(currentTime(e.options), 1); + return { + year: time.getFullYear(), + week: getWeek(time, e.options) + }; +} + +export function previousWeek(r: any, e: DateTimeEncounter): DateTimeData { + const time = addWeeks(currentTime(e.options), -1); + return { + year: time.getFullYear(), + week: getWeek(time, e.options) + }; +} + +/** + * Map weeks as intervals. + */ +export function map(r: DateTimeData, e: DateTimeEncounter) { + return mapInterval({ start: r, end: r }, e); +} diff --git a/src/time/years.js b/src/time/years.js deleted file mode 100644 index cbe9326..0000000 --- a/src/time/years.js +++ /dev/null @@ -1,49 +0,0 @@ -import addYears from 'date-fns/addYears'; -import setYear from 'date-fns/setYear'; -import startOfYear from 'date-fns/startOfYear'; - -import currentTime from './currentTime'; -import DateValue from './date-value'; - -export function thisYear(r, e) { - return { - year: currentTime(e).getFullYear() - }; -} - -export function nextYear(r, e) { - return { - year: currentTime(e).getFullYear() + 1 - }; -} - -export function previousYear(r, e) { - return { - year: currentTime(e).getFullYear() - 1 - }; -} - -export function map(r, e) { - const now = currentTime(e); - - let time; - if(typeof r.relativeYears !== 'undefined') { - // Relative year - time = addYears(now, r.relativeYears); - } else if(typeof r.year !== 'undefined') { - time = setYear(now, r.year); - } else { - // No year available - skip it - return null; - } - - // Adjust the time to the start of the year - time = startOfYear(time); - - const result = new DateValue(e.language); - result.period = 'year'; - result.year = time.getFullYear(); - result.month = time.getMonth(); - result.day = time.getDate(); - return result; -} diff --git a/src/time/years.ts b/src/time/years.ts new file mode 100644 index 0000000..ac82454 --- /dev/null +++ b/src/time/years.ts @@ -0,0 +1,54 @@ +import { + addYears, + setYear, + startOfYear +} from 'date-fns'; + +import { DateTimeEncounter } from './encounter'; +import { currentTime } from './currentTime'; +import { DateTimeData } from './date-time-data'; +import { MutableDateValue } from './date-value'; +import { Period } from './period'; + +export function thisYear(r: any, e: DateTimeEncounter): DateTimeData { + return { + year: currentTime(e.options).getFullYear() + }; +} + +export function nextYear(r: any, e: DateTimeEncounter): DateTimeData { + return { + year: currentTime(e.options).getFullYear() + 1 + }; +} + +export function previousYear(r: any, e: DateTimeEncounter): DateTimeData { + return { + year: currentTime(e.options).getFullYear() - 1 + }; +} + +export function map(r: DateTimeData, e: DateTimeEncounter): MutableDateValue | null { + const now = currentTime(e.options); + + let time; + if(typeof r.relativeYears !== 'undefined') { + // Relative year + time = addYears(now, r.relativeYears); + } else if(typeof r.year !== 'undefined') { + time = setYear(now, r.year); + } else { + // No year available - skip it + return null; + } + + // Adjust the time to the start of the year + time = startOfYear(time); + + const result = new MutableDateValue(); + result.period = Period.Year; + result.year = time.getFullYear(); + result.month = time.getMonth(); + result.day = time.getDate(); + return result; +} diff --git a/src/types/index.js b/src/types/index.js deleted file mode 100644 index 3bdf081..0000000 --- a/src/types/index.js +++ /dev/null @@ -1,2 +0,0 @@ -export { default as DateTimeIntervalValue } from '../time/interval-value'; -export { default as DateTimeValue } from '../time/date-value'; diff --git a/src/types/index.ts b/src/types/index.ts new file mode 100644 index 0000000..0aae279 --- /dev/null +++ b/src/types/index.ts @@ -0,0 +1,2 @@ +export { IntervalValue as DateTimeIntervalValue } from '../time/interval-value'; +export * from '../time/date-value'; diff --git a/src/utils/cloning.js b/src/utils/cloning.js deleted file mode 100644 index 3a9d356..0000000 --- a/src/utils/cloning.js +++ /dev/null @@ -1,17 +0,0 @@ -import fastClone from 'fast-clone'; - -export function cloneObject(a) { - let result = {}; - for(const k in a) { - if(a.hasOwnProperty(k)) result[k] = a[k]; - } - return result; -} - -export function clone(r) { - if(r._clone) { - return r._clone(); - } - - return fastClone(r); -} diff --git a/src/utils/cloning.ts b/src/utils/cloning.ts new file mode 100644 index 0000000..c5b57ed --- /dev/null +++ b/src/utils/cloning.ts @@ -0,0 +1,13 @@ +import fastClone from 'fast-clone'; + +export function cloneObject(a: object): object { + return Object.assign({}, a); +} + +export function clone(r: any): any { + if(r.clone) { + return r.clone(); + } + + return fastClone(r); +} diff --git a/src/utils/equality.js b/src/utils/equality.js deleted file mode 100644 index 64cd453..0000000 --- a/src/utils/equality.js +++ /dev/null @@ -1,3 +0,0 @@ -import fastDeepEqual from 'fast-deep-equal'; - -export { fastDeepEqual as isDeepEqual }; diff --git a/src/utils/equality.ts b/src/utils/equality.ts new file mode 100644 index 0000000..f0aaffc --- /dev/null +++ b/src/utils/equality.ts @@ -0,0 +1,4 @@ +import fastDeepEqual from 'fast-deep-equal/es6'; + +export { fastDeepEqual as isDeepEqual }; + diff --git a/src/utils/predicates.ts b/src/utils/predicates.ts new file mode 100644 index 0000000..d01d2b1 --- /dev/null +++ b/src/utils/predicates.ts @@ -0,0 +1,6 @@ +/** + * Predicate that checks if a specific object matches. + */ +export type Predicate = (obj: V) => boolean; + +export const alwaysTruePredicate = () => true; diff --git a/src/values/any.js b/src/values/any.js deleted file mode 100644 index 021cb6c..0000000 --- a/src/values/any.js +++ /dev/null @@ -1,11 +0,0 @@ -import { ValueMatcher } from './base'; - -const instance = { - match(encounter) { - encounter.match(encounter.text()); - } -}; - -export default function(options) { - return new ValueMatcher(Object.assign({}, options, instance)); -} diff --git a/src/values/any.ts b/src/values/any.ts new file mode 100644 index 0000000..ed179ae --- /dev/null +++ b/src/values/any.ts @@ -0,0 +1,12 @@ +import { ValueMatcher } from './base'; +import { ValueNodeOptions, ValueEncounter } from '../resolver/value'; + +const instance: ValueNodeOptions = { + async match(encounter: ValueEncounter) { + encounter.match(encounter.text()); + } +}; + +export function anyStringValue(options?: Omit, 'match'>) { + return new ValueMatcher(Object.assign({}, options, instance)); +} diff --git a/src/values/base.js b/src/values/base.js deleted file mode 100644 index fa757a9..0000000 --- a/src/values/base.js +++ /dev/null @@ -1,52 +0,0 @@ -import ValueParserNode from '../resolver/value-parser'; -import ValueNode from '../resolver/value'; - -export class LanguageSpecificValue { - constructor(factory) { - this.factory = factory; - } - - create(language) { - return this.factory(language); - } - - /** - * Create a matcher function for this value and the specified language. - * - * @param {Language} language - */ - matcher(language) { - const parser = this.factory(language).parser; - - return function(text, options) { - if(typeof text !== 'string') return Promise.resolve(null); - - return parser.match(text, options); - }; - } -} - -export class ParsingValue { - constructor(parser, options) { - this.parser = parser; - this.options = options || {}; - } - - toNode(id) { - return new ValueParserNode(id, this.parser, this.options); - } - - toDot() { - return this.parser.toDot(); - } -} - -export class ValueMatcher { - constructor(options) { - this.options = options; - } - - toNode(id) { - return new ValueNode(id, this.options); - } -} diff --git a/src/values/base.ts b/src/values/base.ts new file mode 100644 index 0000000..38ef174 --- /dev/null +++ b/src/values/base.ts @@ -0,0 +1,72 @@ +import { ValueParserNode, ValueParserOptions } from '../resolver/value-parser'; +import { ValueNode, ValueNodeOptions } from '../resolver/value'; +import { Language } from '../language/language'; +import { Node } from '../graph/node'; +import { Matcher } from '../graph/matching'; + +/** + * Object that can be converted into a node within a graph. + */ +export interface NodeConvertable { + toNode(id: string): Node; +} + +/** + * Function that creates a convertable item for the given language. + */ +export type LanguageSpecificFactory = (language: Language) => NodeConvertable; + +export class LanguageSpecificValue { + private factory: LanguageSpecificFactory; + + constructor(factory: LanguageSpecificFactory) { + this.factory = factory; + } + + public create(language: Language): NodeConvertable { + return this.factory(language); + } + + /** + * Create a matcher function for this value and the specified language. + * + * @param {Language} language + */ + public matcher(language: Language) { + /* + const parser = this.factory(language).parser; + + return function(text, options) { + if(typeof text !== 'string') return Promise.resolve(null); + + return parser.match(text, options); + }; + */ + } +} + +export class ParsingValue { + private parser: Matcher; + private options: ValueParserOptions; + + constructor(parser: Matcher, options?: ValueParserOptions) { + this.parser = parser; + this.options = options || {}; + } + + public toNode(id: string) { + return new ValueParserNode(id, this.parser, this.options); + } +} + +export class ValueMatcher { + private options: ValueNodeOptions; + + constructor(options: ValueNodeOptions) { + this.options = options; + } + + public toNode(id: string) { + return new ValueNode(id, this.options); + } +} diff --git a/src/values/boolean.js b/src/values/boolean.ts similarity index 66% rename from src/values/boolean.js rename to src/values/boolean.ts index 618b264..bc0fd3b 100644 --- a/src/values/boolean.js +++ b/src/values/boolean.ts @@ -1,5 +1,5 @@ import { LanguageSpecificValue, ParsingValue } from './base'; -export default function(options) { - return new LanguageSpecificValue(language => new ParsingValue(language.boolean, options)); +export function booleanValue() { + return new LanguageSpecificValue(language => new ParsingValue(language.getMatcher('boolean'))); } diff --git a/src/values/custom.js b/src/values/custom.ts similarity index 56% rename from src/values/custom.js rename to src/values/custom.ts index fc4181c..9635a3f 100644 --- a/src/values/custom.js +++ b/src/values/custom.ts @@ -1,6 +1,12 @@ import { ValueMatcher } from './base'; +import { ValueNodeOptions, ValueEncounter } from '../resolver/value'; -export default function(options) { +/** + * Create a custom value that performs its own parsing of a raw textual value. + * + * @param options + */ +export function customValue(options: ValueNodeOptions | ((encounter: ValueEncounter) => Promise)) { if(typeof options === 'undefined') { throw new Error('Value matcher must be specified'); } diff --git a/src/values/date-duration.js b/src/values/date-duration.ts similarity index 62% rename from src/values/date-duration.js rename to src/values/date-duration.ts index b2f11bd..310f9fa 100644 --- a/src/values/date-duration.js +++ b/src/values/date-duration.ts @@ -1,5 +1,5 @@ import { LanguageSpecificValue, ParsingValue } from './base'; -export default function(options) { - return new LanguageSpecificValue(language => new ParsingValue(language.dateDuration, options)); +export function dateDurationValue() { + return new LanguageSpecificValue(language => new ParsingValue(language.getMatcher('date-duration'))); } diff --git a/src/values/date-interval.js b/src/values/date-interval.ts similarity index 62% rename from src/values/date-interval.js rename to src/values/date-interval.ts index 61e8fd9..09a97c6 100644 --- a/src/values/date-interval.js +++ b/src/values/date-interval.ts @@ -1,5 +1,5 @@ import { LanguageSpecificValue, ParsingValue } from './base'; -export default function(options) { - return new LanguageSpecificValue(language => new ParsingValue(language.dateInterval, options)); +export function dateIntervalValue() { + return new LanguageSpecificValue(language => new ParsingValue(language.getMatcher('date-interval'))); } diff --git a/src/values/date-time-duration.ts b/src/values/date-time-duration.ts new file mode 100644 index 0000000..eeb3244 --- /dev/null +++ b/src/values/date-time-duration.ts @@ -0,0 +1,5 @@ +import { LanguageSpecificValue, ParsingValue } from './base'; + +export function dateTimeDurationValue() { + return new LanguageSpecificValue(language => new ParsingValue(language.getMatcher('date-time-duration'))); +} diff --git a/src/values/date-time.js b/src/values/date-time.ts similarity index 66% rename from src/values/date-time.js rename to src/values/date-time.ts index 5c10cff..e474c79 100644 --- a/src/values/date-time.js +++ b/src/values/date-time.ts @@ -1,5 +1,5 @@ import { LanguageSpecificValue, ParsingValue } from './base'; -export default function(options) { - return new LanguageSpecificValue(language => new ParsingValue(language.dateTime, options)); +export function dateTime() { + return new LanguageSpecificValue(language => new ParsingValue(language.getMatcher('date-time'))); } diff --git a/src/values/date.js b/src/values/date.ts similarity index 68% rename from src/values/date.js rename to src/values/date.ts index 1f9d61a..cd1601d 100644 --- a/src/values/date.js +++ b/src/values/date.ts @@ -1,5 +1,5 @@ import { LanguageSpecificValue, ParsingValue } from './base'; -export default function(options) { - return new LanguageSpecificValue(language => new ParsingValue(language.date, options)); +export function dateValue() { + return new LanguageSpecificValue(language => new ParsingValue(language.getMatcher('date'))); } diff --git a/src/values/enumeration.js b/src/values/enumeration.ts similarity index 52% rename from src/values/enumeration.js rename to src/values/enumeration.ts index bf80ce7..29f3274 100644 --- a/src/values/enumeration.js +++ b/src/values/enumeration.ts @@ -1,22 +1,20 @@ -import GraphBuilder from '../graph/builder'; +import { GraphBuilder } from '../graph/builder'; import { LanguageSpecificValue, ParsingValue } from './base'; -const DEFAULT_MAPPER = v => v; +const DEFAULT_MAPPER = (v: V) => String(v); + +export function enumerationValue(values: V[], textMapper?: (value: V) => string) { + const mapper = textMapper ? textMapper : DEFAULT_MAPPER; -export default function(values, textMapper) { - if(! textMapper) { - textMapper = DEFAULT_MAPPER; - } return new LanguageSpecificValue(language => { const builder = new GraphBuilder(language) .allowPartial(); values.forEach(value => { - builder.add(textMapper(value), value); + builder.add(mapper(value), value); }); return new ParsingValue(builder.toMatcher(), { - supportsPartial: true, partialBlankWhenNoToken: true }); }); diff --git a/src/values/index.js b/src/values/index.js deleted file mode 100644 index bd0ed49..0000000 --- a/src/values/index.js +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Re-export all of the types of values available. - */ -export { default as any } from './any'; -export { default as boolean } from './boolean'; -export { default as custom } from './custom'; -export { default as dateDuration } from './date-duration'; -export { default as dateInterval } from './date-interval'; -export { default as dateTimeDuration } from './date-time-duration'; -export { default as dateTime } from './date-time'; -export { default as date } from './date'; -export { default as enumeration } from './enumeration'; -export { default as integer } from './integer'; -export { default as number } from './number'; -export { default as options } from './options'; -export { default as ordinal } from './ordinal'; -export { default as staticValue } from './static'; -export { default as temperature } from './temperature'; -export { default as timeDuration } from './time-duration'; -export { default as time } from './time'; diff --git a/src/values/index.ts b/src/values/index.ts new file mode 100644 index 0000000..940e0f9 --- /dev/null +++ b/src/values/index.ts @@ -0,0 +1,19 @@ +/** + * Re-export all of the types of values available. + */ +export * from './any'; +export * from './boolean'; +export * from './custom'; +export * from './date-duration'; +export * from './date-interval'; +export * from './date-time-duration'; +export * from './date-time'; +export * from './date'; +export * from './enumeration'; +export * from './integer'; +export * from './number'; +export * from './options'; +export * from './ordinal'; +export * from './static'; +export * from './time-duration'; +export * from './time'; diff --git a/src/values/integer.ts b/src/values/integer.ts new file mode 100644 index 0000000..0269508 --- /dev/null +++ b/src/values/integer.ts @@ -0,0 +1,5 @@ +import { LanguageSpecificValue, ParsingValue } from './base'; + +export function integerValue() { + return new LanguageSpecificValue(language => new ParsingValue(language.getMatcher('integer'))); +} diff --git a/src/values/number.js b/src/values/number.js deleted file mode 100644 index ac055bf..0000000 --- a/src/values/number.js +++ /dev/null @@ -1,5 +0,0 @@ -import { LanguageSpecificValue, ParsingValue } from './base'; - -export default function(options) { - return new LanguageSpecificValue(language => new ParsingValue(language.number, options)); -} diff --git a/src/values/integer.js b/src/values/number.ts similarity index 66% rename from src/values/integer.js rename to src/values/number.ts index 3213fa2..c09c646 100644 --- a/src/values/integer.js +++ b/src/values/number.ts @@ -1,5 +1,5 @@ import { LanguageSpecificValue, ParsingValue } from './base'; -export default function(options) { - return new LanguageSpecificValue(language => new ParsingValue(language.integer, options)); +export function numberValue() { + return new LanguageSpecificValue(language => new ParsingValue(language.getMatcher('number'))); } diff --git a/src/values/options.js b/src/values/options.js deleted file mode 100644 index 1f79341..0000000 --- a/src/values/options.js +++ /dev/null @@ -1,102 +0,0 @@ -import GraphBuilder from '../graph/builder'; -import { LanguageSpecificValue, ParsingValue } from './base'; -import ResolverBuilder from '../resolver/builder'; - -class Builder { - constructor(options) { - this.name = options.name; - this.options = options; - this.data = {}; - } - - option(id) { - if(typeof id !== 'string') { - throw new Error('Options require identifiers that are strings'); - } - - const result = { - values: {}, - phrases: [] - }; - - const self = this; - return { - value(id, type) { - result.values[id] = type; - return this; - }, - - add(...args) { - result.phrases.push(args); - return this; - }, - - done() { - self.data[id] = result; - return self; - } - }; - } - - build() { - return new LanguageSpecificValue(language => { - const parent = new GraphBuilder(language) - .name(this.name || 'options') - .allowPartial(); - - for(const id of Object.keys(this.data)) { - const option = this.data[id]; - const instance = new ResolverBuilder(language, id); - - // Set the name of the parser - for easier debugging - instance.parser.options.name = parent.options.name + '[' + id + ']'; - - // Transfer all of the values - for(const valueKey of Object.keys(option.values)) { - instance.value(valueKey, option.values[valueKey]); - } - - // Transfer the phrases - for(const phrase of option.phrases) { - instance.add(...phrase); - } - - const parser = instance.build(); - parent.add(parser, v => v[0]); - } - - parent.mapResults(v => new Option(v.intent, v.values, v.expression)); - - const repeating = language.repeating(parent.toMatcher()) - .onlyBest() - .toMatcher(); - - return new ParsingValue(repeating, Object.assign({ - supportsPartial: true - }, this.options)); - }); - } -} - -export default function(options={}) { - return new Builder(options); -} - -/** - * Custom option value to hide enumeration for equality checks. - */ -class Option { - - constructor(option, values, expression) { - this.option = option; - this.values = values; - - Object.defineProperty(this, 'expression', { - enumerable: false, - writable: true - }); - - this.expression = expression; - } - -} diff --git a/src/values/options.ts b/src/values/options.ts new file mode 100644 index 0000000..92b1023 --- /dev/null +++ b/src/values/options.ts @@ -0,0 +1,131 @@ +import { GraphBuilder } from '../graph/builder'; +import { ResolverBuilder } from '../resolver/builder'; + +import { LanguageSpecificValue, ParsingValue, NodeConvertable } from './base'; +import { ValueParserOptions } from '../resolver/value-parser'; +import { ResolvedIntent } from '../resolver/resolved-intent'; +import { ExpressionPart } from '../resolver/expression/ExpressionPart'; + +export interface OptionBuilderOptions extends ValueParserOptions { + name?: string; +} + +export class OptionsBuilder { + private name: string; + private options: ValueParserOptions; + private data: Record; + + constructor(options: OptionBuilderOptions) { + this.name = options.name || 'options'; + this.options = options; + this.data = {}; + } + + public option(id: string): OptionBuilder { + if(typeof id !== 'string') { + throw new Error('Options require identifiers that are strings'); + } + + const result: OptionData = { + values: {}, + phrases: [] + }; + + const self = this; + return { + value(valueId, type) { + result.values[valueId] = type; + return this; + }, + + add(...args) { + result.phrases.push(args); + return this; + }, + + done() { + self.data[id] = result; + return self; + } + }; + } + + public build() { + return new LanguageSpecificValue(language => { + const parent = new GraphBuilder(language) + .name(this.name) + .allowPartial(); + + for(const id of Object.keys(this.data)) { + const option = this.data[id]; + const instance = new ResolverBuilder(language, id); + + // Set the name of the parser - for easier debugging + //instance.parser.options.name = parent.options.name + '[' + id + ']'; + + // Transfer all of the values + for(const valueKey of Object.keys(option.values)) { + instance.value(valueKey, option.values[valueKey]); + } + + // Transfer the phrases + for(const phrase of option.phrases) { + instance.add(...phrase); + } + + const parser = instance.build(); + parent.add(parser, v => v[0]); + } + + const matcher = parent.mapResults(v => new Option(v.intent, v.values, v.expression)) + .toMatcher(); + + const repeating = language.repeating(matcher) + .onlyBest() + .toMatcher(); + + return new ParsingValue(repeating, Object.assign({ + supportsPartial: true + }, this.options)); + }); + } +} + +export function optionsValue(options: OptionBuilderOptions={}) { + return new OptionsBuilder(options); +} + +export interface OptionBuilder { + value(id: string, type: LanguageSpecificValue | NodeConvertable): this; + + add(...args: string[]): this; + + done(): OptionsBuilder; +} + +interface OptionData { + values: Record; + phrases: any[]; +} + +/** + * Custom option value to hide enumeration for equality checks. + */ +export class Option { + public readonly option: string; + public readonly values: Map; + public readonly expression: ExpressionPart[]; + + constructor(option: string, values: Map, expression: ExpressionPart[]) { + this.option = option; + this.values = values; + + Object.defineProperty(this, 'expression', { + enumerable: false, + writable: true + }); + + this.expression = expression; + } + +} diff --git a/src/values/ordinal.js b/src/values/ordinal.js deleted file mode 100644 index 46ea1bf..0000000 --- a/src/values/ordinal.js +++ /dev/null @@ -1,5 +0,0 @@ -import { LanguageSpecificValue, ParsingValue } from './base'; - -export default function(options) { - return new LanguageSpecificValue(language => new ParsingValue(language.ordinal, options)); -} diff --git a/src/values/ordinal.ts b/src/values/ordinal.ts new file mode 100644 index 0000000..5c43c52 --- /dev/null +++ b/src/values/ordinal.ts @@ -0,0 +1,5 @@ +import { LanguageSpecificValue, ParsingValue } from './base'; + +export function ordinalValue() { + return new LanguageSpecificValue(language => new ParsingValue(language.getMatcher('ordinal'))); +} diff --git a/src/values/static.js b/src/values/static.js deleted file mode 100644 index 2e091fa..0000000 --- a/src/values/static.js +++ /dev/null @@ -1,5 +0,0 @@ -import ValueStatic from '../resolver/value-static'; - -export default function(id, value) { - return new ValueStatic(id, value); -} diff --git a/src/values/static.ts b/src/values/static.ts new file mode 100644 index 0000000..086b2f5 --- /dev/null +++ b/src/values/static.ts @@ -0,0 +1,5 @@ +import { ValueStatic } from '../resolver/value-static'; + +export function staticValue(id: string, value: V) { + return new ValueStatic(id, value); +} diff --git a/src/values/temperature.js b/src/values/temperature.js deleted file mode 100644 index 7052ce6..0000000 --- a/src/values/temperature.js +++ /dev/null @@ -1,5 +0,0 @@ -import { LanguageSpecificValue, ParsingValue } from './base'; - -export default function(options) { - return new LanguageSpecificValue(language => new ParsingValue(language.temperature, options)); -} diff --git a/src/values/time-duration.js b/src/values/time-duration.js deleted file mode 100644 index 21a24ca..0000000 --- a/src/values/time-duration.js +++ /dev/null @@ -1,5 +0,0 @@ -import { LanguageSpecificValue, ParsingValue } from './base'; - -export default function(options) { - return new LanguageSpecificValue(language => new ParsingValue(language.timeDuration, options)); -} diff --git a/src/values/date-time-duration.js b/src/values/time-duration.ts similarity index 62% rename from src/values/date-time-duration.js rename to src/values/time-duration.ts index 7209210..84ae536 100644 --- a/src/values/date-time-duration.js +++ b/src/values/time-duration.ts @@ -1,5 +1,5 @@ import { LanguageSpecificValue, ParsingValue } from './base'; -export default function(options) { - return new LanguageSpecificValue(language => new ParsingValue(language.dateTimeDuration, options)); +export function timeDurationValue() { + return new LanguageSpecificValue(language => new ParsingValue(language.getMatcher('time-duration'))); } diff --git a/src/values/time.js b/src/values/time.ts similarity index 68% rename from src/values/time.js rename to src/values/time.ts index 7527eb8..c2d1214 100644 --- a/src/values/time.js +++ b/src/values/time.ts @@ -1,5 +1,5 @@ import { LanguageSpecificValue, ParsingValue } from './base'; -export default function(options) { - return new LanguageSpecificValue(language => new ParsingValue(language.time, options)); +export function timeValue() { + return new LanguageSpecificValue(language => new ParsingValue(language.getMatcher('time'))); } diff --git a/test/builder.test.js b/test/builder.test.ts similarity index 67% rename from test/builder.test.js rename to test/builder.test.ts index 98c914e..0ea6da6 100644 --- a/test/builder.test.js +++ b/test/builder.test.ts @@ -1,51 +1,43 @@ -import { expect } from 'chai'; - -import en from '../src/language/en'; -import GraphBuilder from '../src/graph/builder'; - -const map = results => results.map(r => r.data); +import { en } from '../src/language/en'; +import { GraphBuilder } from '../src/graph/builder'; describe('Graph Builder', function() { describe('Linear', function() { - const parser = new GraphBuilder(en) + const parser = new GraphBuilder(en) .add('hello world', true) .toMatcher(); it('All tokens', function() { return parser.match('hello world') - .then(map) .then(results => { - expect(results).to.deep.equal([ true ]); + expect(results).toEqual([ true ]); }); }); it('Single token', function() { return parser.match('hello') - .then(map) .then(results => { - expect(results).to.deep.equal([ ]); + expect(results).toEqual([ ]); }); }); it('Extra tokens', function() { return parser.match('hello world and more') - .then(map) .then(results => { - expect(results).to.deep.equal([]); + expect(results).toEqual([]); }); }); it('Extra tokens - partial, no match', function() { return parser.match('hello world and more', { partial: true }) - .then(map) .then(results => { - expect(results).to.deep.equal([ ]); + expect(results).toEqual([ ]); }); }); }); describe('Multiple linear', function() { - const parser = new GraphBuilder(en) + const parser = new GraphBuilder(en) .add('hello world', 1) .add('cookies', 2) .add('hello', 3) @@ -54,80 +46,73 @@ describe('Graph Builder', function() { it('Match longest - partial', function() { return parser.match('hello world', { partial: true }) - .then(map) .then(results => { - expect(results).to.deep.equal([ 1 ]); + expect(results).toEqual([ 1 ]); }); }); it('Match standalone', function() { return parser.match('cookies') - .then(map) .then(results => { - expect(results).to.deep.equal([ 2 ]); + expect(results).toEqual([ 2 ]); }); }); it('Match shortest', function() { return parser.match('hello') - .then(map) .then(results => { - expect(results).to.deep.equal([ 3 ]); + expect(results).toEqual([ 3 ]); }); }); }); describe('Parser within parser', function() { describe('Single token + Single token', function() { - const sub = new GraphBuilder(en) + const sub = new GraphBuilder(en) .add('hello', 1) .toMatcher(); - const parser = new GraphBuilder(en) + const parser = new GraphBuilder(en) .add([ sub, 'world' ], 2) .toMatcher(); it('All tokens', function() { return parser.match('hello world') - .then(map) .then(results => { - expect(results).to.deep.equal([ 2 ]); + expect(results).toEqual([ 2 ]); }); }); it('First token', function() { return parser.match('hello') - .then(map) .then(results => { - expect(results).to.deep.equal([ ]); + expect(results).toEqual([ ]); }); }); }); describe('Node factory', function() { - const parser = new GraphBuilder(en) + const parser = new GraphBuilder(en) .add(GraphBuilder.custom(t => t.raw === 'one' ? true : null), 1) .toMatcher(); it('Single token', function() { return parser.match('one') - .then(map) .then(results => { - expect(results).to.deep.equal([ 1 ]); + expect(results).toEqual([ 1 ]); }); }); it('Invalid first token', function() { return parser.match('three') - .then(map) .then(results => { - expect(results).to.deep.equal([ ]); + expect(results).toEqual([ ]); }); }); }); describe('Previous match', function() { - const parser = new GraphBuilder(en) + const parser = new GraphBuilder(en) .add('one', 1) .add('three', 3) .add([ GraphBuilder.result(v => v === 1), 'two' ], 2) @@ -136,31 +121,28 @@ describe('Graph Builder', function() { it('Single token', function() { return parser.match('one') - .then(map) .then(results => { - expect(results).to.deep.equal([ 1 ]); + expect(results).toEqual([ 1 ]); }); }); it('All tokens - partial', function() { return parser.match('one two', { partial: true }) - .then(map) .then(results => { - expect(results).to.deep.equal([ 2 ]); + expect(results).toEqual([ 2 ]); }); }); it('Invalid first token - partial', function() { return parser.match('three two', { partial: true }) - .then(map) .then(results => { - expect(results).to.deep.equal([ ]); + expect(results).toEqual([ ]); }); }); }); describe('Recursive match', function() { - const parser = new GraphBuilder(en) + const parser = new GraphBuilder(en) .add(/^[a-z]$/, v => v[0]) .add([ GraphBuilder.result(v => true), GraphBuilder.result(v => true) ], v => v[0] + v[1]) .add([ GraphBuilder.result(v => true), '-', GraphBuilder.result(v => true) ], v => { @@ -170,49 +152,43 @@ describe('Graph Builder', function() { it('a', function() { return parser.match('a') - .then(map) .then(results => { - expect(results).to.deep.equal([ 'a' ]); + expect(results).toEqual([ 'a' ]); }); }); it('a b', function() { return parser.match('a b') - .then(map) .then(results => { - expect(results).to.deep.equal([ 'ab' ]); + expect(results).toEqual([ 'ab' ]); }); }); it('a b c', function() { return parser.match('a b c') - .then(map) .then(results => { - expect(results).to.deep.equal([ 'abc' ]); + expect(results).toEqual([ 'abc' ]); }); }); it('a b c d', function() { return parser.match('a b c d') - .then(map) .then(results => { - expect(results).to.deep.equal([ 'abcd' ]); + expect(results).toEqual([ 'abcd' ]); }); }); it('a - b c', function() { return parser.match('a - b c') - .then(map) .then(results => { - expect(results).to.deep.equal([ 'abc' ]); + expect(results).toEqual([ 'abc' ]); }); }); it('abc', function() { return parser.match('abc') - .then(map) .then(results => { - expect(results).to.deep.equal([ ]); + expect(results).toEqual([ ]); }); }); }); diff --git a/test/combined.test.js b/test/intents.test.ts similarity index 57% rename from test/combined.test.js rename to test/intents.test.ts index 4111012..f05d44e 100644 --- a/test/combined.test.js +++ b/test/intents.test.ts @@ -1,27 +1,10 @@ -import { expect } from 'chai'; - -const { intentsBuilder } = require('../src'); -import en from '../src/language/en'; -import { any } from '../src/values'; +import { en } from '../src/language/en'; +import { IntentsBuilder } from '../src/intents'; +import { anyStringValue } from '../src/values'; describe('Intents', function() { - describe('Basic', function() { - it('Throws error when no language', () => { - expect(() => { - intentsBuilder(); - }).to.throw(); - }); - - it('Throws error when no intent id', () => { - expect(() => { - intentsBuilder(en) - .intent(); - }).to.throw(); - }); - }); - describe('Orders', function() { - const intents = intentsBuilder(en) + const intents = new IntentsBuilder(en) .intent('orders') .add('Orders') .add('Show orders') @@ -31,13 +14,13 @@ describe('Intents', function() { .add('Show orders that are active') .done() .intent('customer:orders') - .value('customer', any()) + .value('customer', anyStringValue()) .add('Orders for {customer}') .add('Find orders for {customer}') .add('Show orders for {customer}') .done() .intent('employee:assignments') - .value('employee', any()) + .value('employee', anyStringValue()) .add('Assignments for {employee}') .done() .build(); @@ -45,16 +28,16 @@ describe('Intents', function() { it('Match: orders', function() { return intents.match('orders') .then(results => { - expect(results.matches.length).to.equal(1); - expect(results.best.intent).to.equal('orders'); + expect(results.matches.length).toEqual(1); + expect(results.best.intent).toEqual('orders'); }); }); it('Match (skippable in input): show for orders', function() { return intents.match('show for orders', { fuzzy: true }) .then(results => { - expect(results.matches.length).to.equal(1); - expect(results.best.intent).to.equal('orders'); + expect(results.matches.length).toEqual(1); + expect(results.best.intent).toEqual('orders'); }); }); @@ -62,92 +45,92 @@ describe('Intents', function() { // Test that skipping `for` works fine return intents.match('orders Test') .then(results => { - expect(results.matches.length).to.equal(1); - expect(results.best.intent).to.equal('customer:orders'); + expect(results.matches.length).toEqual(1); + expect(results.best.intent).toEqual('customer:orders'); }); }); it('No match: show', function() { return intents.match('show') .then(results => { - expect(results.matches.length).to.equal(0); + expect(results.matches.length).toEqual(0); }); }); it('Partial: orders', function() { return intents.match('orders', { partial: true }) .then(results => { - expect(results.matches.length).to.equal(3); + expect(results.matches.length).toEqual(3); }); }); it('Partial: or', function() { return intents.match('or', { partial: true }) .then(results => { - expect(results.matches.length).to.equal(3); + expect(results.matches.length).toEqual(3); }); }); it('Partial: show orders', function() { return intents.match('show orders', { partial: true }) .then(results => { - expect(results.matches.length).to.equal(3); + expect(results.matches.length).toEqual(3); }); }); it('Partial: sh order', function() { return intents.match('sh order', { partial: true }) .then(results => { - expect(results.matches.length).to.equal(0); + expect(results.matches.length).toEqual(0); }); }); it('Partial: orders for', function() { return intents.match('orders for', { partial: true }) .then(results => { - expect(results.matches.length).to.equal(1); - expect(results.best.intent).to.equal('customer:orders'); + expect(results.matches.length).toEqual(1); + expect(results.best.intent).toEqual('customer:orders'); }); }); it('Partial: orders for Test', function() { return intents.match('orders for Test', { partial: true }) .then(results => { - expect(results.matches.length).to.equal(1); - expect(results.best.intent).to.equal('customer:orders'); - expect(results.best.values.customer).to.equal('Test'); + expect(results.matches.length).toEqual(1); + expect(results.best.intent).toEqual('customer:orders'); + expect(results.best.values.get('customer')).toEqual('Test'); }); }); it('Partial (with skippable): orders Test', function() { return intents.match('orders Test', { partial: true }) .then(results => { - expect(results.matches.length).to.equal(1); - expect(results.best.intent).to.equal('customer:orders'); - expect(results.best.values.customer).to.equal('Test'); + expect(results.matches.length).toEqual(1); + expect(results.best.intent).toEqual('customer:orders'); + expect(results.best.values.get('customer')).toEqual('Test'); }); }); it('Partial and fuzzy: orders for Test', function() { return intents.match('o Test', { partial: true, fuzzy: true }) .then(results => { - expect(results.matches.length).to.equal(1); - expect(results.best.intent).to.equal('customer:orders'); - expect(results.best.values.customer).to.equal('Test'); + expect(results.matches.length).toEqual(1); + expect(results.best.intent).toEqual('customer:orders'); + expect(results.best.values.get('customer')).toEqual('Test'); }); }); it('Partial: assign', function() { return intents.match('assign', { partial: true }) .then(results => { - expect(results.matches.length).to.equal(1); + expect(results.matches.length).toEqual(1); }); }); it('Partial: assignments', function() { return intents.match('assignments', { partial: true }) .then(results => { - expect(results.matches.length).to.equal(1); + expect(results.matches.length).toEqual(1); }); }); }); diff --git a/test/language.test.js b/test/language.test.js deleted file mode 100644 index c4ec40c..0000000 --- a/test/language.test.js +++ /dev/null @@ -1,164 +0,0 @@ -import { expect } from 'chai'; - -import { tokenize } from '../src/language/utils'; - -function checkTokens(tokens, raw) { - expect(tokens.length).to.equal(raw.length, 'Wrong number of tokens extracted'); - - for(let i=0; i t); - expect(tokens.length).to.equal(1); - expect(tokens[0].raw).to.equal('hello'); - expect(tokens[0].start).to.equal(0); - expect(tokens[0].stop).to.equal(5); - }); - - it('Multiple tokens', function() { - const tokens = tokenize('hello world', t => t); - expect(tokens.length).to.equal(2); - expect(tokens[0].raw).to.equal('hello'); - expect(tokens[1].raw).to.equal('world'); - }); - - it('Single to multiple tokens', function() { - const tokens = tokenize('can\'t', t => { - return [ - { - raw: 'ca', - normalized: 'can' - }, - { - raw: 'n\'t', - normalized: 'not' - } - ]; - }); - expect(tokens.length).to.equal(2); - expect(tokens[0].normalized).to.equal('can'); - expect(tokens[0].start).to.equal(0); - expect(tokens[0].stop).to.equal(2); - - expect(tokens[1].normalized).to.equal('not'); - expect(tokens[1].start).to.equal(2); - expect(tokens[1].stop).to.equal(5); - }); - - describe('Spliting', function() { - it('Parenthesies', function() { - const tokens = tokenize('(abc)', t => t); - checkTokens(tokens, [ '(', 'abc', ')']); - }); - - it('Brackets', function() { - const tokens = tokenize('[abc]', t => t); - checkTokens(tokens, [ '[', 'abc', ']']); - }); - - it('Exclamation marks', function() { - checkTokens( - tokenize('abc!', t => t), - [ 'abc', '!'] - ); - - checkTokens( - tokenize('a!bc', t => t), - [ 'a', '!', 'bc' ] - ); - }); - - it('Question marks', function() { - checkTokens( - tokenize('abc?', t => t), - [ 'abc', '?'] - ); - - checkTokens( - tokenize('a?bc', t => t), - [ 'a', '?', 'bc' ] - ); - }); - - it('Period', function() { - checkTokens( - tokenize('abc.', t => t), - [ 'abc', '.'] - ); - - checkTokens( - tokenize('a.bc', t => t), - [ 'a', '.', 'bc' ] - ); - }); - - it('Comma', function() { - checkTokens( - tokenize('abc,', t => t), - [ 'abc', ','] - ); - - checkTokens( - tokenize('a,bc', t => t), - [ 'a', ',', 'bc' ] - ); - }); - - it('Numbers', function() { - checkTokens( - tokenize('12', t => t), - [ '12' ] - ); - - checkTokens( - tokenize('12.20', t => t), - [ '12', '.', '20' ] - ); - - checkTokens( - tokenize('12.20SEK', t => t), - [ '12', '.', '20', 'SEK' ] - ); - - checkTokens( - tokenize('12SEK', t => t), - [ '12', 'SEK' ] - ); - - checkTokens( - tokenize('SEK12', t => t), - [ 'SEK', '12' ] - ); - - checkTokens( - tokenize('$12.20', t => t), - [ '$', '12', '.', '20' ] - ); - - checkTokens( - tokenize('€12.20', t => t), - [ '€', '12', '.', '20' ] - ); - }); - }); - }); - - describe('Utils: Raw Value', function() { - it('Single token', function() { - const tokens = tokenize('hello', t => t); - const raw = tokens.raw(); - expect(raw).to.equal('hello'); - }); - - it('Multiple tokens', function() { - const tokens = tokenize('hello world', t => t); - const raw = tokens.raw(); - expect(raw).to.equal('hello world'); - }); - }); -}); diff --git a/test/language.test.ts b/test/language.test.ts new file mode 100644 index 0000000..930856f --- /dev/null +++ b/test/language.test.ts @@ -0,0 +1,181 @@ +import { tokenize } from '../src/language/tokens/utils'; +import { TokenizerInput, TokenData, Tokens } from '../src/language/tokens'; + +function checkTokens(tokens: Tokens, raw: string[]) { + expect(tokens.length).toEqual(raw.length); + + for(let i=0; i { + return [ + { + raw: 'ca', + normalized: 'can', + stemmed: 'can', + short: false, + skippable: false + }, + { + raw: 'n\'t', + normalized: 'not', + stemmed: 'not', + short: false, + skippable: false + } + ]; + }); + expect(tokens.length).toEqual(2); + expect(tokens[0].normalized).toEqual('can'); + expect(tokens[0].start).toEqual(0); + expect(tokens[0].stop).toEqual(2); + + expect(tokens[1].normalized).toEqual('not'); + expect(tokens[1].start).toEqual(2); + expect(tokens[1].stop).toEqual(5); + }); + + describe('Spliting', function() { + it('Parenthesies', function() { + const tokens = tokenize('(abc)', testTokenizer); + checkTokens(tokens, [ '(', 'abc', ')']); + }); + + it('Brackets', function() { + const tokens = tokenize('[abc]', testTokenizer); + checkTokens(tokens, [ '[', 'abc', ']']); + }); + + it('Exclamation marks', function() { + checkTokens( + tokenize('abc!', testTokenizer), + [ 'abc', '!'] + ); + + checkTokens( + tokenize('a!bc', testTokenizer), + [ 'a', '!', 'bc' ] + ); + }); + + it('Question marks', function() { + checkTokens( + tokenize('abc?', testTokenizer), + [ 'abc', '?'] + ); + + checkTokens( + tokenize('a?bc', testTokenizer), + [ 'a', '?', 'bc' ] + ); + }); + + it('Period', function() { + checkTokens( + tokenize('abc.', testTokenizer), + [ 'abc', '.'] + ); + + checkTokens( + tokenize('a.bc', testTokenizer), + [ 'a', '.', 'bc' ] + ); + }); + + it('Comma', function() { + checkTokens( + tokenize('abc,', testTokenizer), + [ 'abc', ','] + ); + + checkTokens( + tokenize('a,bc', testTokenizer), + [ 'a', ',', 'bc' ] + ); + }); + + it('Numbers', function() { + checkTokens( + tokenize('12', testTokenizer), + [ '12' ] + ); + + checkTokens( + tokenize('12.20', testTokenizer), + [ '12', '.', '20' ] + ); + + checkTokens( + tokenize('12.20SEK', testTokenizer), + [ '12', '.', '20', 'SEK' ] + ); + + checkTokens( + tokenize('12SEK', testTokenizer), + [ '12', 'SEK' ] + ); + + checkTokens( + tokenize('SEK12', testTokenizer), + [ 'SEK', '12' ] + ); + + checkTokens( + tokenize('$12.20', testTokenizer), + [ '$', '12', '.', '20' ] + ); + + checkTokens( + tokenize('€12.20', testTokenizer), + [ '€', '12', '.', '20' ] + ); + }); + }); + }); + + describe('Utils: Raw Value', function() { + it('Single token', function() { + const tokens = tokenize('hello', testTokenizer); + const raw = tokens.raw(); + expect(raw).toEqual('hello'); + }); + + it('Multiple tokens', function() { + const tokens = tokenize('hello world', testTokenizer); + const raw = tokens.raw(); + expect(raw).toEqual('hello world'); + }); + }); +}); diff --git a/test/language/en/date-duration.test.js b/test/language/en/date-duration.test.js deleted file mode 100644 index 9543536..0000000 --- a/test/language/en/date-duration.test.js +++ /dev/null @@ -1,154 +0,0 @@ -import en from '../../../src/language/en'; -import { testRunner } from '../helpers'; - -const test = testRunner(en.dateDuration); - -describe('English', function() { - describe('Date Duration', function() { - - test('3 days', {}, { - years: 0, - quarters: 0, - weeks: 0, - months: 0, - days: 3, - hours: 0, - minutes: 0, - seconds: 0, - milliseconds: 0 - }); - - test('1 d', {}, { - years: 0, - quarters: 0, - weeks: 0, - months: 0, - days: 1, - hours: 0, - minutes: 0, - seconds: 0, - milliseconds: 0 - }); - - test('2 months and 3 days', {}, { - years: 0, - quarters: 0, - weeks: 0, - months: 2, - days: 3, - hours: 0, - minutes: 0, - seconds: 0, - milliseconds: 0 - }); - - test('1 week', {}, { - years: 0, - quarters: 0, - weeks: 1, - months: 0, - days: 0, - hours: 0, - minutes: 0, - seconds: 0, - milliseconds: 0 - }); - - test('two weeks', {}, { - years: 0, - quarters: 0, - weeks: 2, - months: 0, - days: 0, - hours: 0, - minutes: 0, - seconds: 0, - milliseconds: 0 - }); - - test('2w', {}, { - years: 0, - quarters: 0, - weeks: 2, - months: 0, - days: 0, - hours: 0, - minutes: 0, - seconds: 0, - milliseconds: 0 - }); - - test('2wks', {}, { - years: 0, - quarters: 0, - weeks: 2, - months: 0, - days: 0, - hours: 0, - minutes: 0, - seconds: 0, - milliseconds: 0 - }); - - test('2 months', {}, { - years: 0, - quarters: 0, - weeks: 0, - months: 2, - days: 0, - hours: 0, - minutes: 0, - seconds: 0, - milliseconds: 0 - }); - - test('1 year', {}, { - years: 1, - quarters: 0, - weeks: 0, - months: 0, - days: 0, - hours: 0, - minutes: 0, - seconds: 0, - milliseconds: 0 - }); - - test('1 year and 2 months', {}, { - years: 1, - quarters: 0, - weeks: 0, - months: 2, - days: 0, - hours: 0, - minutes: 0, - seconds: 0, - milliseconds: 0 - }); - - test('1 year, 2 weeks', {}, { - years: 1, - quarters: 0, - weeks: 2, - months: 0, - days: 0, - hours: 0, - minutes: 0, - seconds: 0, - milliseconds: 0 - }); - - test('1 quarter', {}, { - years: 0, - quarters: 1, - weeks: 0, - months: 0, - days: 0, - hours: 0, - minutes: 0, - seconds: 0, - milliseconds: 0 - }); - }); - -}); diff --git a/test/language/en/date-duration.test.ts b/test/language/en/date-duration.test.ts new file mode 100644 index 0000000..9cf02ba --- /dev/null +++ b/test/language/en/date-duration.test.ts @@ -0,0 +1,61 @@ +import { en } from '../../../src/language/en'; +import { testRunner } from '../helpers'; + +const test = testRunner(en, 'date-duration'); + +describe('English', function() { + describe('Date Duration', function() { + + test('3 days', {}, { + days: 3 + }); + + test('1 d', {}, { + days: 1 + }); + + test('2 months and 3 days', {}, { + months: 2, + days: 3 + }); + + test('1 week', {}, { + weeks: 1 + }); + + test('two weeks', {}, { + weeks: 2 + }); + + test('2w', {}, { + weeks: 2 + }); + + test('2wks', {}, { + weeks: 2 + }); + + test('2 months', {}, { + months: 2 + }); + + test('1 year', {}, { + years: 1 + }); + + test('1 year and 2 months', {}, { + years: 1, + months: 2 + }); + + test('1 year, 2 weeks', {}, { + years: 1, + weeks: 2 + }); + + test('1 quarter', {}, { + quarters: 1 + }); + }); + +}); diff --git a/test/language/en/date-interval.test.js b/test/language/en/date-interval.test.ts similarity index 95% rename from test/language/en/date-interval.test.js rename to test/language/en/date-interval.test.ts index 9fc2af4..31333fe 100644 --- a/test/language/en/date-interval.test.js +++ b/test/language/en/date-interval.test.ts @@ -1,7 +1,7 @@ -import en from '../../../src/language/en'; +import { en } from '../../../src/language/en'; import { testRunner } from '../helpers'; -const test = testRunner(en.dateInterval); +const test = testRunner(en, 'date-interval'); describe('English', () => { describe('Date Interval', () => { @@ -292,8 +292,6 @@ describe('English', () => { }); test('any time', { now: new Date(2012, 8, 3) }, { - start: null, - end: null }); test('in the future', { now: new Date(2012, 8, 3) }, { @@ -302,12 +300,10 @@ describe('English', () => { year: 2012, month: 8, day: 4 - }, - end: null + } }); test('in the past', { now: new Date(2012, 8, 3) }, { - start: null, end: { period: 'day', year: 2012, @@ -322,8 +318,7 @@ describe('English', () => { year: 2012, month: 8, day: 4 - }, - end: null + } }); test('from today', { now: new Date(2012, 8, 3) }, { @@ -332,8 +327,7 @@ describe('English', () => { year: 2012, month: 8, day: 3 - }, - end: null + } }); test('from 2020', { now: new Date(2012, 8, 3) }, { @@ -342,8 +336,7 @@ describe('English', () => { year: 2020, month: 0, day: 1 - }, - end: null + } }); test('from 2020 to 2030', { now: new Date(2012, 8, 3) }, { @@ -362,7 +355,6 @@ describe('English', () => { }); test('before today', { now: new Date(2012, 8, 3) }, { - start: null, end: { period: 'day', year: 2012, @@ -372,7 +364,6 @@ describe('English', () => { }); test('until today', { now: new Date(2012, 8, 3) }, { - start: null, end: { period: 'day', year: 2012, diff --git a/test/language/en/date-time-duration.test.js b/test/language/en/date-time-duration.test.js deleted file mode 100644 index e20c001..0000000 --- a/test/language/en/date-time-duration.test.js +++ /dev/null @@ -1,60 +0,0 @@ -import en from '../../../src/language/en'; -import { testRunner } from '../helpers'; - -const test = testRunner(en.dateTimeDuration); - -describe('English', function() { - - describe('Date & Time Duration', function() { - - test('1 hour', {}, { - years: 0, - quarters: 0, - weeks: 0, - months: 0, - days: 0, - hours: 1, - minutes: 0, - seconds: 0, - milliseconds: 0 - }); - - test('4 days', {}, { - years: 0, - quarters: 0, - weeks: 0, - months: 0, - days: 4, - hours: 0, - minutes: 0, - seconds: 0, - milliseconds: 0 - }); - - test('4 days and 10 minutes', {}, { - years: 0, - quarters: 0, - weeks: 0, - months: 0, - days: 4, - hours: 0, - minutes: 10, - seconds: 0, - milliseconds: 0 - }); - - test('4 days 10 minutes', {}, { - years: 0, - quarters: 0, - weeks: 0, - months: 0, - days: 4, - hours: 0, - minutes: 10, - seconds: 0, - milliseconds: 0 - }); - - }); - -}); diff --git a/test/language/en/date-time-duration.test.ts b/test/language/en/date-time-duration.test.ts new file mode 100644 index 0000000..68fae68 --- /dev/null +++ b/test/language/en/date-time-duration.test.ts @@ -0,0 +1,30 @@ +import { en } from '../../../src/language/en'; +import { testRunner } from '../helpers'; + +const test = testRunner(en, 'date-time-duration'); + +describe('English', function() { + + describe('Date & Time Duration', function() { + + test('1 hour', {}, { + hours: 1 + }); + + test('4 days', {}, { + days: 4 + }); + + test('4 days and 10 minutes', {}, { + days: 4, + minutes: 10 + }); + + test('4 days 10 minutes', {}, { + days: 4, + minutes: 10 + }); + + }); + +}); diff --git a/test/language/en/date-time.test.js b/test/language/en/date-time.test.ts similarity index 97% rename from test/language/en/date-time.test.js rename to test/language/en/date-time.test.ts index 03b5199..436ddfe 100644 --- a/test/language/en/date-time.test.js +++ b/test/language/en/date-time.test.ts @@ -1,7 +1,7 @@ -import en from '../../../src/language/en'; +import { en } from '../../../src/language/en'; import { testRunner } from '../helpers'; -const test = testRunner(en.dateTime); +const test = testRunner(en, 'date-time'); describe('English', function() { diff --git a/test/language/en/date.test.js b/test/language/en/date.test.ts similarity index 99% rename from test/language/en/date.test.js rename to test/language/en/date.test.ts index 2ec224a..698b086 100644 --- a/test/language/en/date.test.js +++ b/test/language/en/date.test.ts @@ -1,7 +1,7 @@ -import en from '../../../src/language/en'; +import { en } from '../../../src/language/en'; import { testRunner } from '../helpers'; -const test = testRunner(en.date); +const test = testRunner(en, 'date'); describe('English', function() { describe('Date', function() { diff --git a/test/language/en/day-of-week.test.ts b/test/language/en/day-of-week.test.ts new file mode 100644 index 0000000..2bd7635 --- /dev/null +++ b/test/language/en/day-of-week.test.ts @@ -0,0 +1,17 @@ +import { en } from '../../../src/language/en'; +import { testRunner } from '../helpers'; +import { Weekday } from '../../../src/time/weekday'; + +const test = testRunner(en, 'day-of-week'); + +describe('English', function() { + + describe('Day of Week', function() { + test('Friday', {}, Weekday.Friday); + + test('Tue', {}, Weekday.Tuesday); + + test('on Tue', {}, Weekday.Tuesday); + }); + +}); diff --git a/test/language/en/dayOfWeek.test.js b/test/language/en/dayOfWeek.test.js deleted file mode 100644 index 3e2b266..0000000 --- a/test/language/en/dayOfWeek.test.js +++ /dev/null @@ -1,16 +0,0 @@ -import en from '../../../src/language/en'; -import { testRunner } from '../helpers'; - -const test = testRunner(en.dayOfWeek); - -describe('English', function() { - - describe('Day of Week', function() { - test('Friday', {}, { value: 5 }); - - test('Tue', {}, { value: 2 }); - - test('on Tue', {}, { value: 2 }); - }); - -}); diff --git a/test/language/en/integer.test.js b/test/language/en/integer.test.ts similarity index 83% rename from test/language/en/integer.test.js rename to test/language/en/integer.test.ts index bc9429f..3cff023 100644 --- a/test/language/en/integer.test.js +++ b/test/language/en/integer.test.ts @@ -1,8 +1,7 @@ -import en from '../../../src/language/en'; +import { en } from '../../../src/language/en'; import { testRunner } from '../helpers'; -const test = testRunner(en.integer); - +const test = testRunner(en, 'integer'); describe('English', function() { @@ -34,5 +33,7 @@ describe('English', function() { test('1 thousand thousand', {}, { value: 1000000 }); test('one 000', {}, null); + + test('10,000', {}, { value: 10000 }); }); }); diff --git a/test/language/en/month.test.js b/test/language/en/month.test.ts similarity index 97% rename from test/language/en/month.test.js rename to test/language/en/month.test.ts index 8ba8198..470e1c6 100644 --- a/test/language/en/month.test.js +++ b/test/language/en/month.test.ts @@ -1,7 +1,7 @@ -import en from '../../../src/language/en'; +import { en } from '../../../src/language/en'; import { testRunner } from '../helpers'; -const test = testRunner(en.month); +const test = testRunner(en, 'month'); describe('English', function() { diff --git a/test/language/en/number.test.js b/test/language/en/number.test.ts similarity index 90% rename from test/language/en/number.test.js rename to test/language/en/number.test.ts index 876cf11..8f8187f 100644 --- a/test/language/en/number.test.js +++ b/test/language/en/number.test.ts @@ -1,7 +1,7 @@ -import en from '../../../src/language/en'; +import { en } from '../../../src/language/en'; import { testRunner } from '../helpers'; -const test = testRunner(en.number); +const test = testRunner(en, 'number'); describe('English', function() { diff --git a/test/language/en/ordinal.test.js b/test/language/en/ordinal.test.ts similarity index 74% rename from test/language/en/ordinal.test.js rename to test/language/en/ordinal.test.ts index 1089865..043f5e7 100644 --- a/test/language/en/ordinal.test.js +++ b/test/language/en/ordinal.test.ts @@ -1,7 +1,7 @@ -import en from '../../../src/language/en'; +import { en } from '../../../src/language/en'; import { testRunner } from '../helpers'; -const test = testRunner(en.ordinal); +const test = testRunner(en, 'ordinal'); describe('English', function() { diff --git a/test/language/en/repeating.test.js b/test/language/en/repeating.test.ts similarity index 77% rename from test/language/en/repeating.test.js rename to test/language/en/repeating.test.ts index f336f47..2d36746 100644 --- a/test/language/en/repeating.test.js +++ b/test/language/en/repeating.test.ts @@ -1,6 +1,6 @@ -import en from '../../../src/language/en'; -import { testRunner } from '../helpers'; -import GraphBuilder from '../../../src/graph/builder'; +import { en } from '../../../src/language/en'; +import { testRunnerViaMatcher } from '../helpers'; +import { GraphBuilder } from '../../../src/graph/builder'; const phrase = new GraphBuilder(en) .name('phrase') @@ -12,7 +12,7 @@ const phrase = new GraphBuilder(en) .toMatcher(); -const test = testRunner(en.repeating(phrase) +const test = testRunnerViaMatcher(en.repeating(phrase) .onlyBest() .toMatcher() ); diff --git a/test/language/en/temperature.test.js b/test/language/en/temperature.test.js deleted file mode 100644 index 7e41859..0000000 --- a/test/language/en/temperature.test.js +++ /dev/null @@ -1,27 +0,0 @@ -import en from '../../../src/language/en'; -import { testRunner } from '../helpers'; - -const test = testRunner(en.temperature); - - -describe('English', function() { - - describe('Temperature', function() { - - test('one', {}, { value: 1, unit: 'unknown' }); - - test('one degree', {}, { value: 1, unit: 'unknown' }); - - test('one degree', { temperature: 'celsius' }, { value: 1, unit: 'celsius' }); - - test('40 F', {}, { value: 40, unit: 'fahrenheit' }); - - test('40 fahrenheit', {}, { value: 40, unit: 'fahrenheit' }); - - test('40 C', {}, { value: 40, unit: 'celsius' }); - - test('40 celsius', {}, { value: 40, unit: 'celsius' }); - - }); - -}); diff --git a/test/language/en/time-duration.test.js b/test/language/en/time-duration.test.js deleted file mode 100644 index 8d2382b..0000000 --- a/test/language/en/time-duration.test.js +++ /dev/null @@ -1,156 +0,0 @@ -import en from '../../../src/language/en'; -import { testRunner } from '../helpers'; - -const test = testRunner(en.timeDuration); - -describe('English', function() { - - describe('Time Duration', function() { - - test('1 hour', {}, { - years: 0, - quarters: 0, - weeks: 0, - months: 0, - days: 0, - hours: 1, - minutes: 0, - seconds: 0, - milliseconds: 0 - }); - - test('2 hrs', {}, { - years: 0, - quarters: 0, - weeks: 0, - months: 0, - days: 0, - hours: 2, - minutes: 0, - seconds: 0, - milliseconds: 0 - }); - - test('5h', {}, { - years: 0, - quarters: 0, - weeks: 0, - months: 0, - days: 0, - hours: 5, - minutes: 0, - seconds: 0, - milliseconds: 0 - }); - - test('10 minutes', {}, { - years: 0, - quarters: 0, - weeks: 0, - months: 0, - days: 0, - hours: 0, - minutes: 10, - seconds: 0, - milliseconds: 0 - }); - - test('75 m', {}, { - years: 0, - quarters: 0, - weeks: 0, - months: 0, - days: 0, - hours: 0, - minutes: 75, - seconds: 0, - milliseconds: 0 - }); - - test('10 seconds', {}, { - years: 0, - quarters: 0, - weeks: 0, - months: 0, - days: 0, - hours: 0, - minutes: 0, - seconds: 10, - milliseconds: 0 - }); - - test('20 s', {}, { - years: 0, - quarters: 0, - weeks: 0, - months: 0, - days: 0, - hours: 0, - minutes: 0, - seconds: 20, - milliseconds: 0 - }); - - test('200 ms', {}, { - years: 0, - quarters: 0, - weeks: 0, - months: 0, - days: 0, - hours: 0, - minutes: 0, - seconds: 0, - milliseconds: 200 - }); - - test('1 ms', {}, { - years: 0, - quarters: 0, - weeks: 0, - months: 0, - days: 0, - hours: 0, - minutes: 0, - seconds: 0, - milliseconds: 1 - }); - - test('5001 millis', {}, { - years: 0, - quarters: 0, - weeks: 0, - months: 0, - days: 0, - hours: 0, - minutes: 0, - seconds: 0, - milliseconds: 5001 - }); - - test('1 h, 4 sec', {}, { - years: 0, - quarters: 0, - weeks: 0, - months: 0, - days: 0, - hours: 1, - minutes: 0, - seconds: 4, - milliseconds: 0 - }); - - test('1 hour and 4 minutes', {}, { - years: 0, - quarters: 0, - weeks: 0, - months: 0, - days: 0, - hours: 1, - minutes: 4, - seconds: 0, - milliseconds: 0 - }); - - }); - -}); diff --git a/test/language/en/time-duration.test.ts b/test/language/en/time-duration.test.ts new file mode 100644 index 0000000..08eb7ec --- /dev/null +++ b/test/language/en/time-duration.test.ts @@ -0,0 +1,62 @@ +import { en } from '../../../src/language/en'; +import { testRunner } from '../helpers'; + +const test = testRunner(en, 'time-duration'); + +describe('English', function() { + + describe('Time Duration', function() { + + test('1 hour', {}, { + hours: 1 + }); + + test('2 hrs', {}, { + hours: 2 + }); + + test('5h', {}, { + hours: 5 + }); + + test('10 minutes', {}, { + minutes: 10 + }); + + test('75 m', {}, { + minutes: 75 + }); + + test('10 seconds', {}, { + seconds: 10, + }); + + test('20 s', {}, { + seconds: 20 + }); + + test('200 ms', {}, { + milliseconds: 200 + }); + + test('1 ms', {}, { + milliseconds: 1 + }); + + test('5001 millis', {}, { + milliseconds: 5001 + }); + + test('1 h, 4 sec', {}, { + hours: 1, + seconds: 4 + }); + + test('1 hour and 4 minutes', {}, { + hours: 1, + minutes: 4 + }); + + }); + +}); diff --git a/test/language/en/time.test.js b/test/language/en/time.test.ts similarity index 98% rename from test/language/en/time.test.js rename to test/language/en/time.test.ts index de4ff6a..c9b5cd3 100644 --- a/test/language/en/time.test.js +++ b/test/language/en/time.test.ts @@ -1,7 +1,7 @@ -import en from '../../../src/language/en'; +import { en } from '../../../src/language/en'; import { testRunner } from '../helpers'; -const test = testRunner(en.time); +const test = testRunner(en, 'time'); describe('English', function() { diff --git a/test/language/en/tokenization.test.js b/test/language/en/tokenization.test.js deleted file mode 100644 index b6da814..0000000 --- a/test/language/en/tokenization.test.js +++ /dev/null @@ -1,55 +0,0 @@ -import { expect } from 'chai'; -import en from '../../../src/language/en'; - -describe('English', function() { - describe('Tokenization', function() { - it('Simple: Hello World', function() { - const tokens = en.tokenize('hello world'); - expect(tokens.length).to.equal(2); - expect(tokens[0].raw).to.equal('hello'); - expect(tokens[1].raw).to.equal('world'); - }); - - it('Contraction: Wasn\'t', function() { - const tokens = en.tokenize('Wasn\'t'); - expect(tokens.length).to.equal(2); - expect(tokens[0].normalized).to.equal('was'); - expect(tokens[1].normalized).to.equal('not'); - }); - - it('Contraction: Can\'t', function() { - const tokens = en.tokenize('Can\'t'); - expect(tokens.length).to.equal(2); - expect(tokens[0].normalized).to.equal('can'); - expect(tokens[1].normalized).to.equal('not'); - }); - - it('Contraction: I\'m', function() { - const tokens = en.tokenize('I\'m'); - expect(tokens.length).to.equal(2); - expect(tokens[0].normalized).to.equal('i'); - expect(tokens[1].normalized).to.equal('am'); - }); - - it('Contraction: You\'re', function() { - const tokens = en.tokenize('You\'re'); - expect(tokens.length).to.equal(2); - expect(tokens[0].normalized).to.equal('you'); - expect(tokens[1].normalized).to.equal('are'); - }); - - it('Contraction: They\'ll', function() { - const tokens = en.tokenize('They\'ll'); - expect(tokens.length).to.equal(2); - expect(tokens[0].normalized).to.equal('they'); - expect(tokens[1].normalized).to.equal('will'); - }); - - it('Simple: `:`', function() { - const tokens = en.tokenize(':'); - expect(tokens.length).to.equal(1); - expect(tokens[0].raw).to.equal(':'); - }); - }); - -}); diff --git a/test/language/en/tokenization.test.ts b/test/language/en/tokenization.test.ts new file mode 100644 index 0000000..3d23716 --- /dev/null +++ b/test/language/en/tokenization.test.ts @@ -0,0 +1,54 @@ +import { en } from '../../../src/language/en'; + +describe('English', function() { + describe('Tokenization', function() { + it('Simple: Hello World', function() { + const tokens = en.tokenize('hello world'); + expect(tokens.length).toEqual(2); + expect(tokens[0].raw).toEqual('hello'); + expect(tokens[1].raw).toEqual('world'); + }); + + it('Contraction: Wasn\'t', function() { + const tokens = en.tokenize('Wasn\'t'); + expect(tokens.length).toEqual(2); + expect(tokens[0].normalized).toEqual('was'); + expect(tokens[1].normalized).toEqual('not'); + }); + + it('Contraction: Can\'t', function() { + const tokens = en.tokenize('Can\'t'); + expect(tokens.length).toEqual(2); + expect(tokens[0].normalized).toEqual('can'); + expect(tokens[1].normalized).toEqual('not'); + }); + + it('Contraction: I\'m', function() { + const tokens = en.tokenize('I\'m'); + expect(tokens.length).toEqual(2); + expect(tokens[0].normalized).toEqual('i'); + expect(tokens[1].normalized).toEqual('am'); + }); + + it('Contraction: You\'re', function() { + const tokens = en.tokenize('You\'re'); + expect(tokens.length).toEqual(2); + expect(tokens[0].normalized).toEqual('you'); + expect(tokens[1].normalized).toEqual('are'); + }); + + it('Contraction: They\'ll', function() { + const tokens = en.tokenize('They\'ll'); + expect(tokens.length).toEqual(2); + expect(tokens[0].normalized).toEqual('they'); + expect(tokens[1].normalized).toEqual('will'); + }); + + it('Simple: `:`', function() { + const tokens = en.tokenize(':'); + expect(tokens.length).toEqual(1); + expect(tokens[0].raw).toEqual(':'); + }); + }); + +}); diff --git a/test/language/en/year.test.js b/test/language/en/year.test.ts similarity index 90% rename from test/language/en/year.test.js rename to test/language/en/year.test.ts index 04a7fa2..2438fb7 100644 --- a/test/language/en/year.test.js +++ b/test/language/en/year.test.ts @@ -1,7 +1,7 @@ -import en from '../../../src/language/en'; +import { en } from '../../../src/language/en'; import { testRunner } from '../helpers'; -const test = testRunner(en.year); +const test = testRunner(en, 'year'); describe('English', function() { diff --git a/test/language/helpers.js b/test/language/helpers.js deleted file mode 100644 index 55780a9..0000000 --- a/test/language/helpers.js +++ /dev/null @@ -1,40 +0,0 @@ -import { expect } from 'chai'; -import { format } from 'date-fns'; - -function formatDate(d) { - if(! d) return 'current time'; - - return format(d, 'yyyy-MM-dd HH:mm'); -} - -function formatOptions(opts) { - let t = formatDate(opts.now); - - for(const key of Object.keys(opts)) { - if(key === 'now') continue; - - t += ', ' + key + '=' + opts[key]; - } - - return t; -} - -function createTester(f, matcher) { - return function(expr, opts, v) { - f(expr + ' [' + formatOptions(opts) + ']', () => { - return matcher(expr, opts) - .then(r => { - expect(r).to.deep.equal(v); - }); - }); - }; -} - -export function testRunner(matcher) { - const r = (text, options) => matcher.match(text, options); - - const func = createTester(it, r); - func.only = createTester(it.only, r); - func.skip = createTester(it.skip, r); - return func; -} diff --git a/test/language/helpers.ts b/test/language/helpers.ts new file mode 100644 index 0000000..93b57a9 --- /dev/null +++ b/test/language/helpers.ts @@ -0,0 +1,62 @@ +import { format } from 'date-fns'; +import { EncounterOptions, Matcher } from '../../src/graph/matching'; +import { Language } from '../../src/language/language'; + +function formatDate(d?: Date) { + if(! d) return 'current time'; + + return format(d, 'yyyy-MM-dd HH:mm'); +} + +function formatOptions(opts: any) { + let t = formatDate(opts.now); + + for(const key of Object.keys(opts)) { + if(key === 'now') continue; + + t += ', ' + key + '=' + opts[key]; + } + + return t; +} + +type MatchingFunction = (text: string, options: EncounterOptions) => any; + +function createTester(f: (name: string, runner: any) => any, matcher: MatchingFunction): TestFunction { + return function(expr, opts, v) { + f(expr + ' [' + formatOptions(opts) + ']', () => { + return matcher(expr, opts) + .then((r: any) => { + expect(r).toEqual(v); + }); + }); + }; +} + +export function testRunner(lang: Language, matcherId: string): TestRunner { + const matcher = lang.findMatcher(matcherId); + if(! matcher) { + throw new Error('Matcher has not been registered on language'); + } + + return testRunnerViaMatcher(matcher); +} + +export function testRunnerViaMatcher(matcher: Matcher): TestRunner { + const r = (text: string, options: EncounterOptions) => matcher.match(text, options); + + const func = createTester(it, r) as TestRunner; + func.only = createTester(it.only, r); + func.skip = createTester(it.skip, r); + return func; +} + + +export interface TestFunction { + (name: string, options: EncounterOptions, data: any): any; +} + +export interface TestRunner extends TestFunction { + only: TestFunction; + skip: TestFunction; +} diff --git a/test/resolved-intent.test.js b/test/resolved-intent.test.ts similarity index 56% rename from test/resolved-intent.test.js rename to test/resolved-intent.test.ts index 068f791..ffa5f6f 100644 --- a/test/resolved-intent.test.js +++ b/test/resolved-intent.test.ts @@ -1,7 +1,6 @@ -import { expect } from 'chai'; - -import ResolvedIntent from '../src/resolver/resolved-intent'; +import { ResolvedIntent } from '../src/resolver/resolved-intent'; import { isDeepEqual } from '../src/utils/equality'; +import { ExpressionPartType } from '../src/resolver/expression/ExpressionPartType'; describe('Resolved Intent', () => { @@ -10,30 +9,36 @@ describe('Resolved Intent', () => { it('Same intent with no expression and values should match', () => { const a = new ResolvedIntent('test'); const b = new ResolvedIntent('test'); - expect(isDeepEqual(a, b)).is.true; + expect(isDeepEqual(a, b)).toBe(true); }); it('Different intent with no expression and values should not match', () => { const a = new ResolvedIntent('test1'); const b = new ResolvedIntent('test2'); - expect(isDeepEqual(a, b)).is.false; + expect(isDeepEqual(a, b)).toBe(false); }); it('Same intent with different expressions should match', () => { const a = new ResolvedIntent('test'); - a.expression = [ true ]; + a.expression = [ { type: ExpressionPartType.Text, source: { start: 0, end: 0} } ]; const b = new ResolvedIntent('test'); - b.expression = [ false ]; - expect(isDeepEqual(a, b)).is.true; + b.expression = [ ]; + expect(isDeepEqual(a, b)).toBe(true); }); it('Same intent with different values should not match', () => { const a = new ResolvedIntent('test'); - a.values = { one: true }; + a.values = createMap('one', true); const b = new ResolvedIntent('test'); - b.values = { one: false }; - expect(isDeepEqual(a, b)).is.false; + b.values = createMap('one', false); + expect(isDeepEqual(a, b)).toBe(false); }); }); }); + +function createMap(id: string, value: any) { + const m = new Map(); + m.set(id, value); + return m; +} diff --git a/test/resolver.test.js b/test/resolver.test.ts similarity index 65% rename from test/resolver.test.js rename to test/resolver.test.ts index a1d4023..6d707b6 100644 --- a/test/resolver.test.js +++ b/test/resolver.test.ts @@ -1,51 +1,50 @@ -import { expect } from 'chai'; +import { en } from '../src/language/en'; +import 'jest-expect-message'; -import lang from '../src/language/en'; +import { ResolverBuilder } from '../src/resolver/builder'; +import { anyStringValue, dateValue, numberValue, booleanValue, customValue } from '../src/values'; -import Builder from '../src/resolver/builder'; -import { any, date, number, boolean } from '../src/values'; - -function checkExpression(expression, expected) { - expect(expression.length, 'expression length should be the same').to.equal(expected.length); +function checkExpression(expression: any[], expected: any[]) { + expect(expression.length).toEqual(expected.length); for(let i=0; i expect(r.best).to.not.be.null); + .then(r => expect(r.best).not.toBeNull()); }); it('#2', function() { return resolver.match('one two three') - .then(r => expect(r.best).to.not.be.null); + .then(r => expect(r.best).not.toBeNull()); }); it('#3', function() { return resolver.match('one two') - .then(r => expect(r.best).to.be.null); + .then(r => expect(r.best).toBeNull()); }); }); describe('Graph with value of type any', function() { - const resolver = new Builder(lang) - .value('a', any()) + const resolver = new ResolverBuilder(en) + .value('a', anyStringValue()) .add('{a}') .add('one {a}') .add('{a} one') @@ -54,43 +53,43 @@ describe('Resolver', function() { it('#1', function() { return resolver.match('one') .then(r => { - expect(r.best).to.not.be.null; - expect(r.best.values.a).to.equal('one'); - expect(r.matches.length).to.equal(1); + expect(r.best).not.toBeNull(); + expect(r.best.values.get('a')).toEqual('one'); + expect(r.matches.length).toEqual(1); }); }); it('#2', function() { return resolver.match('one test') .then(r => { - expect(r.best).to.not.be.null; - expect(r.best.values.a).to.equal('test'); - expect(r.matches.length).to.equal(1); + expect(r.best).not.toBeNull(); + expect(r.best.values.get('a')).toEqual('test'); + expect(r.matches.length).toEqual(1); }); }); it('#3', function() { return resolver.match('test one') .then(r => { - expect(r.best).to.not.be.null; - expect(r.best.values.a).to.equal('test'); - expect(r.matches.length).to.equal(1); + expect(r.best).not.toBeNull(); + expect(r.best.values.get('a')).toEqual('test'); + expect(r.matches.length).toEqual(1); }); }); it('#4', function() { return resolver.match('one one') .then(r => { - expect(r.best).to.not.be.null; - expect(r.best.values.a).to.equal('one'); - expect(r.matches.length).to.equal(1); + expect(r.best).not.toBeNull(); + expect(r.best.values.get('a')).toEqual('one'); + expect(r.matches.length).toEqual(1); }); }); }); describe('Graph with date', function() { - const resolver = new Builder(lang) - .value('date', date()) + const resolver = new ResolverBuilder(en) + .value('date', dateValue()) .add('stuff {date}') .add('{date} stuff') .add('stuff {date} cookie') @@ -99,68 +98,68 @@ describe('Resolver', function() { it('start', function() { return resolver.match('today stuff') .then(r => { - expect(r.best).to.not.be.null; - expect(r.matches.length).to.equal(1); + expect(r.best).not.toBeNull(); + expect(r.matches.length).toEqual(1); }); }); it('middle', function() { return resolver.match('stuff today cookie') .then(r => { - expect(r.best).to.not.be.null; - expect(r.matches.length).to.equal(1); + expect(r.best).not.toBeNull(); + expect(r.matches.length).toEqual(1); }); }); it('middle (no match)', function() { return resolver.match('stuff today a b') .then(r => { - expect(r.best).to.be.null; + expect(r.best).toBeNull(); }); }); it('end', function() { return resolver.match('stuff today') .then(r => { - expect(r.best).to.not.be.null; - expect(r.matches.length).to.equal(1); + expect(r.best).not.toBeNull(); + expect(r.matches.length).toEqual(1); }); }); it('end - trailing th', function() { return resolver.match('stuff jan 12th') .then(r => { - expect(r.best).to.not.be.null; - expect(r.matches.length).to.equal(1); + expect(r.best).not.toBeNull(); + expect(r.matches.length).toEqual(1); }); }); it('end - partial, trailing th', function() { return resolver.match('stuff jan 12th', { partial: true }) .then(r => { - expect(r.best).to.not.be.null; - expect(r.matches.length).to.equal(2); + expect(r.best).not.toBeNull(); + expect(r.matches.length).toEqual(2); }); }); it('end - partial, trailing th', function() { return resolver.match('stuff j', { partial: true }) .then(r => { - expect(r.best).to.not.be.null; - expect(r.matches.length).to.equal(1); + expect(r.best).not.toBeNull(); + expect(r.matches.length).toEqual(1); }); }); it('range (no match)', function() { return resolver.match('stuff Jan 12-14') .then(r => { - expect(r.best).to.be.null; + expect(r.best).toBeNull(); }); }); }); describe('Partial matching', function() { - const resolver = new Builder(lang) + const resolver = new ResolverBuilder(en) .add('hello world') .build(); @@ -169,7 +168,7 @@ describe('Resolver', function() { return resolver.match('hello', { partial: true }).then(r => { - expect(r.matches.length).to.equal(1); + expect(r.matches.length).toEqual(1); }); }); @@ -178,20 +177,18 @@ describe('Resolver', function() { return resolver.match('he', { partial: true }).then(r => { - expect(r.matches.length).to.equal(1); + expect(r.matches.length).toEqual(1); }); }); }); describe('Partial matching with value', function() { - const resolver = new Builder(lang) - .value('test', { - match(encounter) { - if(encounter.text() === 'world') { - encounter.match(true); - } + const resolver = new ResolverBuilder(en) + .value('test', customValue(async encounter => { + if(encounter.text() === 'world') { + encounter.match(true); } - }) + })) .add('hello {test}') .build(); @@ -200,7 +197,7 @@ describe('Resolver', function() { return resolver.match('hello', { partial: true }).then(r => { - expect(r.matches.length).to.equal(1); + expect(r.matches.length).toEqual(1); }); }); @@ -208,7 +205,7 @@ describe('Resolver', function() { return resolver.match('hello world', { partial: true }).then(r => { - expect(r.matches.length).to.equal(1); + expect(r.matches.length).toEqual(1); }); }); @@ -216,14 +213,14 @@ describe('Resolver', function() { return resolver.match('hello cookie', { partial: true }).then(r => { - expect(r.matches.length).to.equal(0); + expect(r.matches.length).toEqual(0); }); }); }); describe('Graph with number', function() { - const resolver = new Builder(lang) - .value('number', number()) + const resolver = new ResolverBuilder(en) + .value('number', numberValue()) .add('stuff {number}') .add('a {number} c') .build(); @@ -231,8 +228,8 @@ describe('Resolver', function() { it('With a number', function() { return resolver.match('stuff 2') .then(results => { - expect(results.matches.length).to.equal(1); - expect(results.best.values.number).to.deep.equal({ + expect(results.matches.length).toEqual(1); + expect(results.best.values.get('number')).toEqual({ value: 2 }); }); @@ -241,22 +238,22 @@ describe('Resolver', function() { it('Without a number', function() { return resolver.match('stuff abc') .then(results => { - expect(results.matches.length).to.equal(0); + expect(results.matches.length).toEqual(0); }); }); it('With a number followed by garbage', function() { return resolver.match('stuff 2 abc') .then(results => { - expect(results.matches.length).to.equal(0); + expect(results.matches.length).toEqual(0); }); }); it('With a more complex number', function() { return resolver.match('stuff 2 thousand') .then(results => { - expect(results.matches.length).to.equal(1); - expect(results.best.values.number).to.deep.equal({ + expect(results.matches.length).toEqual(1); + expect(results.best.values.get('number')).toEqual({ value: 2000 }); }); @@ -265,8 +262,8 @@ describe('Resolver', function() { it('With a number and trailing valid token', function() { return resolver.match('a two hundred c') .then(results => { - expect(results.matches.length).to.equal(1); - expect(results.best.values.number).to.deep.equal({ + expect(results.matches.length).toEqual(1); + expect(results.best.values.get('number')).toEqual({ value: 200 }); }); @@ -274,8 +271,8 @@ describe('Resolver', function() { }); describe('Graph with boolean', function() { - const resolver = new Builder(lang) - .value('boolean', boolean()) + const resolver = new ResolverBuilder(en) + .value('boolean', booleanValue()) .add('stuff {boolean}') .add('a {boolean} c') .build(); @@ -283,38 +280,38 @@ describe('Resolver', function() { it('With a boolean', function() { return resolver.match('stuff off') .then(results => { - expect(results.matches.length).to.equal(1); - expect(results.best.values.boolean).to.equal(false); + expect(results.matches.length).toEqual(1); + expect(results.best.values.get('boolean')).toEqual(false); }); }); it('Without a boolean', function() { return resolver.match('stuff abc') .then(results => { - expect(results.matches.length).to.equal(0); + expect(results.matches.length).toEqual(0); }); }); it('With a boolean followed by garbage', function() { return resolver.match('stuff off abc') .then(results => { - expect(results.matches.length).to.equal(0); + expect(results.matches.length).toEqual(0); }); }); it('With yes', function() { return resolver.match('stuff yes') .then(results => { - expect(results.matches.length).to.equal(1); - expect(results.best.values.boolean).to.equal(true); + expect(results.matches.length).toEqual(1); + expect(results.best.values.get('boolean')).toEqual(true); }); }); it('With a boolean and trailing valid token', function() { return resolver.match('a false c') .then(results => { - expect(results.matches.length).to.equal(1); - expect(results.best.values.boolean).to.equal(false); + expect(results.matches.length).toEqual(1); + expect(results.best.values.get('boolean')).toEqual(false); }); }); }); @@ -328,8 +325,8 @@ describe('Resolver', function() { 'three', 'four five' ]; - const resolver = new Builder(lang) - .value('name', function(encounter) { + const resolver = new ResolverBuilder(en) + .value('name', customValue(async encounter => { let text = encounter.text(); if(encounter.partial) { for(const v of values) { @@ -342,15 +339,15 @@ describe('Resolver', function() { encounter.match(text); } } - }) + })) .add('do {name}') .build(); it('Match', function() { return resolver.match('do one') .then(results => { - expect(results.matches.length).to.equal(1); - expect(results.best.values.name).to.equal('one'); + expect(results.matches.length).toEqual(1); + expect(results.best.values.get('name')).toEqual('one'); // Check that the expression matches const expression = results.best.expression; @@ -376,8 +373,8 @@ describe('Resolver', function() { it('Match multiple', function() { return resolver.match('do four five') .then(results => { - expect(results.matches.length).to.equal(1); - expect(results.best.values.name).to.equal('four five'); + expect(results.matches.length).toEqual(1); + expect(results.best.values.get('name')).toEqual('four five'); // Check that the expression matches const expression = results.best.expression; @@ -403,7 +400,7 @@ describe('Resolver', function() { it('No match', function() { return resolver.match('do four') .then(results => { - expect(results.matches.length).to.equal(0); + expect(results.matches.length).toEqual(0); }); }); @@ -412,7 +409,7 @@ describe('Resolver', function() { partial: true }) .then(results => { - expect(results.matches.length).to.equal(2); + expect(results.matches.length).toEqual(2); // Check that the expressions matches checkExpression(results.matches[0].expression, [ @@ -459,8 +456,8 @@ describe('Resolver', function() { 'three', 'four five' ]; - const resolver = new Builder(lang) - .value('name', function(encounter) { + const resolver = new ResolverBuilder(en) + .value('name', customValue(async encounter => { let text = encounter.text(); if(encounter.partial) { for(const v of values) { @@ -473,15 +470,15 @@ describe('Resolver', function() { encounter.match(text); } } - }) + })) .add('{name} value') .build(); it('Match', function() { return resolver.match('one value') .then(results => { - expect(results.matches.length).to.equal(1); - expect(results.best.values.name).to.equal('one'); + expect(results.matches.length).toEqual(1); + expect(results.best.values.get('name')).toEqual('one'); // Check that the expression matches const expression = results.best.expression; @@ -507,8 +504,8 @@ describe('Resolver', function() { it('Match multiple', function() { return resolver.match('four five value') .then(results => { - expect(results.matches.length).to.equal(1); - expect(results.best.values.name).to.equal('four five'); + expect(results.matches.length).toEqual(1); + expect(results.best.values.get('name')).toEqual('four five'); // Check that the expression matches const expression = results.best.expression; @@ -534,7 +531,7 @@ describe('Resolver', function() { it('No match', function() { return resolver.match('four value') .then(results => { - expect(results.matches.length).to.equal(0); + expect(results.matches.length).toEqual(0); }); }); @@ -543,7 +540,7 @@ describe('Resolver', function() { partial: true }) .then(results => { - expect(results.matches.length).to.equal(2); + expect(results.matches.length).toEqual(2); }); }); }); @@ -556,11 +553,11 @@ describe('Resolver', function() { 'three', 'four five' ]; - const resolver = new Builder(lang) - .value('name', { + const resolver = new ResolverBuilder(en) + .value('name', customValue({ greedy: true, - match: function(encounter) { + match: async function(encounter) { let text = encounter.text(); if(encounter.partial) { for(const v of values) { @@ -574,7 +571,7 @@ describe('Resolver', function() { } } } - }) + })) .add('{name} end') .add('{name} value end') .build(); @@ -582,15 +579,15 @@ describe('Resolver', function() { it('Match', function() { return resolver.match('one value end') .then(results => { - expect(results.matches.length).to.equal(1); - expect(results.best.values.name).to.equal('one'); + expect(results.matches.length).toEqual(1); + expect(results.best.values.get('name')).toEqual('one'); }); }); it('No match', function() { return resolver.match('four value') .then(results => { - expect(results.matches.length).to.equal(0); + expect(results.matches.length).toEqual(0); }); }); @@ -599,16 +596,16 @@ describe('Resolver', function() { partial: true }) .then(results => { - expect(results.matches.length).to.equal(2); + expect(results.matches.length).toEqual(2); }); }); }); }); describe('Graph contains matching expression', function() { - const resolver = new Builder(lang) - .value('boolean', boolean()) - .value('free', any()) + const resolver = new ResolverBuilder(en) + .value('boolean', booleanValue()) + .value('free', anyStringValue()) .add('stuff {boolean}') .add('a {boolean} c') .add('longer {free} message') @@ -617,28 +614,24 @@ describe('Resolver', function() { it('Expression has source offsets', function() { return resolver.match('a yes c') .then(result => { - expect(result.best.expression).to.be.not.empty; - const e = result.best.expression; - expect(e.length).to.equal(3); - expect(e[0].source).to.deep.equal({ start: 0, end: 1 }); - expect(e[1].source).to.deep.equal({ start: 2, end: 5 }); - expect(e[2].source).to.deep.equal({ start: 6, end: 7 }); + expect(e.length).toEqual(3); + expect(e[0].source).toEqual({ start: 0, end: 1 }); + expect(e[1].source).toEqual({ start: 2, end: 5 }); + expect(e[2].source).toEqual({ start: 6, end: 7 }); }); }); it('Expression with any() has source offsets', function() { return resolver.match('longer hello world message') .then(result => { - expect(result.best.expression).to.be.not.empty; - const e = result.best.expression; - expect(e.length).to.equal(3); - expect(e[0].source).to.deep.equal({ start: 0, end: 6 }); - expect(e[1].source).to.deep.equal({ start: 7, end: 18 }); - expect(e[2].source).to.deep.equal({ start: 19, end: 26 }); + expect(e.length).toEqual(3); + expect(e[0].source).toEqual({ start: 0, end: 6 }); + expect(e[1].source).toEqual({ start: 7, end: 18 }); + expect(e[2].source).toEqual({ start: 19, end: 26 }); }); }); }); diff --git a/test/time/dates.test.js b/test/time/dates.test.ts similarity index 83% rename from test/time/dates.test.js rename to test/time/dates.test.ts index ee36c16..ff57626 100644 --- a/test/time/dates.test.js +++ b/test/time/dates.test.ts @@ -1,6 +1,5 @@ -import { expect } from 'chai'; - import { map } from '../../src/time/dates'; +import { TimeRelationship } from '../../src/time/relationship'; describe('Time', () => { describe('dates', () => { @@ -15,7 +14,7 @@ describe('Time', () => { it('relativeYears keeps month and day', () => { const r = map({ relativeYears: 0 }, e); - expect(r).to.deep.equal({ + expect(r).toEqual({ period: 'year', year: 2017, month: 2, @@ -26,7 +25,7 @@ describe('Time', () => { it('relativeYears works with positive years', () => { const r = map({ relativeYears: 2 }, e); - expect(r).to.deep.equal({ + expect(r).toEqual({ period: 'year', year: 2019, month: 2, @@ -37,7 +36,7 @@ describe('Time', () => { it('relativeYears works with negative years', () => { const r = map({ relativeYears: -2 }, e); - expect(r).to.deep.equal({ + expect(r).toEqual({ period: 'year', year: 2015, month: 2, @@ -48,7 +47,7 @@ describe('Time', () => { it('year resets month and day', () => { const r = map({ year: 2018 }, e); - expect(r).to.deep.equal({ + expect(r).toEqual({ period: 'year', year: 2018, month: 0, @@ -59,7 +58,7 @@ describe('Time', () => { it('relativeQuarters keeps day', () => { const r = map({ relativeQuarters: 0 }, e); - expect(r).to.deep.equal({ + expect(r).toEqual({ period: 'quarter', year: 2017, month: 2, @@ -70,7 +69,7 @@ describe('Time', () => { it('relativeQuarters changes quarter', () => { const r = map({ relativeQuarters: 1 }, e); - expect(r).to.deep.equal({ + expect(r).toEqual({ period: 'quarter', year: 2017, month: 5, @@ -81,7 +80,7 @@ describe('Time', () => { it('quarter after current keeps year', () => { const r = map({ quarter: 3 }, e); - expect(r).to.deep.equal({ + expect(r).toEqual({ period: 'quarter', year: 2017, month: 6, @@ -94,7 +93,7 @@ describe('Time', () => { now: new Date(2017, 4, 24) }}); - expect(r).to.deep.equal({ + expect(r).toEqual({ period: 'quarter', year: 2018, month: 0, @@ -105,7 +104,7 @@ describe('Time', () => { it('relativeWeeks keeps day', () => { const r = map({ relativeWeeks: 0 }, e); - expect(r).to.deep.equal({ + expect(r).toEqual({ period: 'week', year: 2017, month: 2, @@ -116,7 +115,7 @@ describe('Time', () => { it('relativeWeeks changes week', () => { const r = map({ relativeWeeks: 2 }, e); - expect(r).to.deep.equal({ + expect(r).toEqual({ period: 'week', year: 2017, month: 3, @@ -127,7 +126,7 @@ describe('Time', () => { it('week after current week keeps year', () => { const r = map({ week: 13 }, e); - expect(r).to.deep.equal({ + expect(r).toEqual({ period: 'week', year: 2017, month: 2, @@ -138,7 +137,7 @@ describe('Time', () => { it('week before current week is next year', () => { const r = map({ week: 11}, e); - expect(r).to.deep.equal({ + expect(r).toEqual({ period: 'week', year: 2018, month: 2, @@ -147,9 +146,9 @@ describe('Time', () => { }); it('week before current week with past=true keeps year', () => { - const r = map({ week: 11, relationToCurrent: 'past' }, e); + const r = map({ week: 11, relationToCurrent: TimeRelationship.Past }, e); - expect(r).to.deep.equal({ + expect(r).toEqual({ period: 'week', year: 2017, month: 2, @@ -160,7 +159,7 @@ describe('Time', () => { it('relativeMonths keeps day', () => { const r = map({ relativeMonths: 2 }, e); - expect(r).to.deep.equal({ + expect(r).toEqual({ period: 'month', year: 2017, month: 4, @@ -171,7 +170,7 @@ describe('Time', () => { it('month after current month is same year', () => { const r = map({ month: 4 }, e); - expect(r).to.deep.equal({ + expect(r).toEqual({ period: 'month', year: 2017, month: 4, @@ -182,7 +181,7 @@ describe('Time', () => { it('month before current month is next year', () => { const r = map({ month: 1 }, e); - expect(r).to.deep.equal({ + expect(r).toEqual({ period: 'month', year: 2018, month: 1, @@ -191,9 +190,9 @@ describe('Time', () => { }); it('month before current month with past=true is same year', () => { - const r = map({ month: 1, relationToCurrent: 'past' }, e); + const r = map({ month: 1, relationToCurrent: TimeRelationship.Past }, e); - expect(r).to.deep.equal({ + expect(r).toEqual({ period: 'month', year: 2017, month: 1, @@ -204,7 +203,7 @@ describe('Time', () => { it('month before current month with year', () => { const r = map({ month: 1, year: 2017 }, e); - expect(r).to.deep.equal({ + expect(r).toEqual({ period: 'month', year: 2017, month: 1, @@ -215,7 +214,7 @@ describe('Time', () => { it('month after current month with year', () => { const r = map({ month: 6, year: 2017 }, e); - expect(r).to.deep.equal({ + expect(r).toEqual({ period: 'month', year: 2017, month: 6, @@ -226,7 +225,7 @@ describe('Time', () => { it('day after the current day is same month', () => { const r = map({ day: 28 }, e); - expect(r).to.deep.equal({ + expect(r).toEqual({ period: 'day', year: 2017, month: 2, @@ -237,7 +236,7 @@ describe('Time', () => { it('day before the current day is next month', () => { const r = map({ day: 2 }, e); - expect(r).to.deep.equal({ + expect(r).toEqual({ period: 'day', year: 2017, month: 3, @@ -248,7 +247,7 @@ describe('Time', () => { it('relativeYears and relativeMonths keeps day', () => { const r = map({ relativeYears: 1, relativeMonths: 2 }, e); - expect(r).to.deep.equal({ + expect(r).toEqual({ period: 'month', year: 2018, month: 4, @@ -259,7 +258,7 @@ describe('Time', () => { it('relativeYears, relativeMonths and relativeDays', () => { const r = map({ relativeYears: 1, relativeMonths: 2 }, e); - expect(r).to.deep.equal({ + expect(r).toEqual({ period: 'month', year: 2018, month: 4, @@ -270,7 +269,7 @@ describe('Time', () => { it('year, month and day', () => { const r = map({ year: 2019, month: 1, day: 2 }, e); - expect(r).to.deep.equal({ + expect(r).toEqual({ period: 'day', year: 2019, month: 1, diff --git a/test/time/matching.test.js b/test/time/matching.test.ts similarity index 66% rename from test/time/matching.test.js rename to test/time/matching.test.ts index 49fb95e..905f47f 100644 --- a/test/time/matching.test.js +++ b/test/time/matching.test.ts @@ -1,5 +1,3 @@ -import { expect } from 'chai'; - import { combine } from '../../src/time/matching'; describe('Time', () => { @@ -11,7 +9,7 @@ describe('Time', () => { const r = combine(a, b); - expect(r).to.deep.equal({ + expect(r).toEqual({ year: 2018 }); }); @@ -22,7 +20,7 @@ describe('Time', () => { const r = combine(a, b); - expect(r).to.deep.equal({ + expect(r).toEqual({ year: 2018, month: 1 }); @@ -34,21 +32,10 @@ describe('Time', () => { const r = combine(a, b); - expect(r).to.deep.equal({ + expect(r).toEqual({ year: 2019 }); }); - - it('relative property accumulated', () => { - const a = { relative: 2 }; - const b = { relative: 4 }; - - const r = combine(a, b); - - expect(r).to.deep.equal({ - relative: 6 - }); - }); }); }); }); diff --git a/test/time/months.test.js b/test/time/months.test.ts similarity index 86% rename from test/time/months.test.js rename to test/time/months.test.ts index d9a710e..04b99bc 100644 --- a/test/time/months.test.js +++ b/test/time/months.test.ts @@ -1,5 +1,3 @@ -import { expect } from 'chai'; - import { map } from '../../src/time/months'; describe('Time', () => { @@ -14,7 +12,7 @@ describe('Time', () => { it('relativeMonths resolves to current year and month', () => { const r = map({ relativeMonths: 0 }, e); - expect(r).to.deep.equal({ + expect(r).toEqual({ period: 'month', year: 2017, month: 2, @@ -25,7 +23,7 @@ describe('Time', () => { it('relativeMonths resolves to current year and +2 months', () => { const r = map({ relativeMonths: 2 }, e); - expect(r).to.deep.equal({ + expect(r).toEqual({ period: 'month', year: 2017, month: 4, @@ -36,7 +34,7 @@ describe('Time', () => { it('relativeMonths resolves to current year and -2 months', () => { const r = map({ relativeMonths: -2 }, e); - expect(r).to.deep.equal({ + expect(r).toEqual({ period: 'month', year: 2017, month: 0, @@ -47,7 +45,7 @@ describe('Time', () => { it('relativeMonths resolves to previous year', () => { const r = map({ relativeMonths: -4 }, e); - expect(r).to.deep.equal({ + expect(r).toEqual({ period: 'month', year: 2016, month: 10, @@ -58,7 +56,7 @@ describe('Time', () => { it('Absolute month', () => { const r = map({ month: 5 }, e); - expect(r).to.deep.equal({ + expect(r).toEqual({ period: 'month', year: 2017, month: 5, diff --git a/test/time/times.test.js b/test/time/times.test.ts similarity index 75% rename from test/time/times.test.js rename to test/time/times.test.ts index 44c65bb..98a5ecd 100644 --- a/test/time/times.test.js +++ b/test/time/times.test.ts @@ -1,13 +1,12 @@ -import { expect } from 'chai'; - import { time12h, time24h, map } from '../../src/time/times'; +import { Meridiem } from '../../src/time/meridiem'; describe('Time', () => { describe('times', () => { describe('time12h', () => { it('Full time', () => { const r = time12h(8, 12, 42); - expect(r).to.deep.equal({ + expect(r).toEqual({ hour: 8, minute: 12, second: 42, @@ -17,7 +16,7 @@ describe('Time', () => { it('Hour + minute', () => { const r = time12h(8, 12); - expect(r).to.deep.equal({ + expect(r).toEqual({ hour: 8, minute: 12, second: undefined, @@ -27,7 +26,7 @@ describe('Time', () => { it('Hour', () => { const r = time12h(8); - expect(r).to.deep.equal({ + expect(r).toEqual({ hour: 8, minute: undefined, second: undefined, @@ -37,7 +36,7 @@ describe('Time', () => { it('Hour 0 has fixed meridiem', () => { const r = time12h(0, 12, 42); - expect(r).to.deep.equal({ + expect(r).toEqual({ hour: 0, minute: 12, second: 42, @@ -47,7 +46,7 @@ describe('Time', () => { it('Hour > 12 has fixed meridiem', () => { const r = time12h(13, 12, 42); - expect(r).to.deep.equal({ + expect(r).toEqual({ hour: 13, minute: 12, second: 42, @@ -59,7 +58,7 @@ describe('Time', () => { describe('time24h', () => { it('Full time', () => { const r = time24h(8, 12, 42); - expect(r).to.deep.equal({ + expect(r).toEqual({ hour: 8, minute: 12, second: 42, @@ -69,7 +68,7 @@ describe('Time', () => { it('Hour + minute', () => { const r = time24h(8, 12); - expect(r).to.deep.equal({ + expect(r).toEqual({ hour: 8, minute: 12, second: undefined, @@ -79,7 +78,7 @@ describe('Time', () => { it('Hour', () => { const r = time24h(8); - expect(r).to.deep.equal({ + expect(r).toEqual({ hour: 8, minute: undefined, second: undefined, @@ -89,7 +88,7 @@ describe('Time', () => { it('Hour > 12', () => { const r = time24h(13, 12, 42); - expect(r).to.deep.equal({ + expect(r).toEqual({ hour: 13, minute: 12, second: 42, @@ -106,9 +105,9 @@ describe('Time', () => { }; it('Hour 14 with fixed meridiem', () => { - const r = map({ hour: 15, meridiem: 'fixed' }, defaultE); + const r = map({ hour: 15, meridiem: Meridiem.Fixed }, defaultE); - expect(r).to.deep.equal({ + expect(r).toEqual({ period: 'hour', precision: 'normal', @@ -119,9 +118,9 @@ describe('Time', () => { }); it('Hour 8 with fixed meridiem', () => { - const r = map({ hour: 8, meridiem: 'fixed' }, defaultE); + const r = map({ hour: 8, meridiem: Meridiem.Fixed }, defaultE); - expect(r).to.deep.equal({ + expect(r).toEqual({ period: 'hour', precision: 'normal', @@ -132,9 +131,9 @@ describe('Time', () => { }); it('Hour 8 with am meridiem', () => { - const r = map({ hour: 8, meridiem: 'am' }, defaultE); + const r = map({ hour: 8, meridiem: Meridiem.Am }, defaultE); - expect(r).to.deep.equal({ + expect(r).toEqual({ period: 'hour', precision: 'normal', @@ -145,9 +144,9 @@ describe('Time', () => { }); it('Hour 12 with am meridiem', () => { - const r = map({ hour: 12, meridiem: 'am' }, defaultE); + const r = map({ hour: 12, meridiem: Meridiem.Am }, defaultE); - expect(r).to.deep.equal({ + expect(r).toEqual({ period: 'hour', precision: 'normal', @@ -158,9 +157,9 @@ describe('Time', () => { }); it('Hour 8 with pm meridiem', () => { - const r = map({ hour: 8, meridiem: 'pm' }, defaultE); + const r = map({ hour: 8, meridiem: Meridiem.Pm }, defaultE); - expect(r).to.deep.equal({ + expect(r).toEqual({ period: 'hour', precision: 'normal', @@ -171,9 +170,9 @@ describe('Time', () => { }); it('Hour 12 with pm meridiem', () => { - const r = map({ hour: 12, meridiem: 'pm' }, defaultE); + const r = map({ hour: 12, meridiem: Meridiem.Pm }, defaultE); - expect(r).to.deep.equal({ + expect(r).toEqual({ period: 'hour', precision: 'normal', @@ -189,9 +188,9 @@ describe('Time', () => { now: new Date(2010, 1, 6, 10, 0) } }; - const r = map({ hour: 8, meridiem: 'auto' }, e); + const r = map({ hour: 8, meridiem: Meridiem.Auto }, e); - expect(r).to.deep.equal({ + expect(r).toEqual({ period: 'hour', precision: 'normal', @@ -207,9 +206,9 @@ describe('Time', () => { now: new Date(2010, 1, 6, 4, 0) } }; - const r = map({ hour: 8, meridiem: 'auto' }, e); + const r = map({ hour: 8, meridiem: Meridiem.Auto }, e); - expect(r).to.deep.equal({ + expect(r).toEqual({ period: 'hour', precision: 'normal', @@ -225,9 +224,9 @@ describe('Time', () => { now: new Date(2010, 1, 6, 16, 0) } }; - const r = map({ hour: 8, meridiem: 'auto' }, e); + const r = map({ hour: 8, meridiem: Meridiem.Auto }, e); - expect(r).to.deep.equal({ + expect(r).toEqual({ period: 'hour', precision: 'normal', @@ -243,9 +242,9 @@ describe('Time', () => { now: new Date(2010, 1, 6, 4, 0) } }; - const r = map({ hour: 12, meridiem: 'auto' }, e); + const r = map({ hour: 12, meridiem: Meridiem.Auto }, e); - expect(r).to.deep.equal({ + expect(r).toEqual({ period: 'hour', precision: 'normal', @@ -261,9 +260,9 @@ describe('Time', () => { now: new Date(2010, 1, 6, 16, 0) } }; - const r = map({ hour: 12, meridiem: 'auto' }, e); + const r = map({ hour: 12, meridiem: Meridiem.Auto }, e); - expect(r).to.deep.equal({ + expect(r).toEqual({ period: 'hour', precision: 'normal', diff --git a/test/time/years.test.js b/test/time/years.test.ts similarity index 85% rename from test/time/years.test.js rename to test/time/years.test.ts index 3e2d4e1..321ffd8 100644 --- a/test/time/years.test.js +++ b/test/time/years.test.ts @@ -1,5 +1,3 @@ -import { expect } from 'chai'; - import { map } from '../../src/time/years'; describe('Time', () => { @@ -14,7 +12,7 @@ describe('Time', () => { it('relativeYears resolves to current year', () => { const r = map({ relativeYears: 0 }, e); - expect(r).to.deep.equal({ + expect(r).toEqual({ period: 'year', year: 2017, month: 0, @@ -25,7 +23,7 @@ describe('Time', () => { it('relativeYears resolves positive years', () => { const r = map({ relativeYears: 2 }, e); - expect(r).to.deep.equal({ + expect(r).toEqual({ period: 'year', year: 2019, month: 0, @@ -36,7 +34,7 @@ describe('Time', () => { it('relativeYears resolves negative years', () => { const r = map({ relativeYears: -2 }, e); - expect(r).to.deep.equal({ + expect(r).toEqual({ period: 'year', year: 2015, month: 0, @@ -47,7 +45,7 @@ describe('Time', () => { it('Absolute year', () => { const r = map({ year: 2015 }, e); - expect(r).to.deep.equal({ + expect(r).toEqual({ period: 'year', year: 2015, month: 0, diff --git a/test/value-custom.test.js b/test/value-custom.test.ts similarity index 54% rename from test/value-custom.test.js rename to test/value-custom.test.ts index bff0318..68604f6 100644 --- a/test/value-custom.test.js +++ b/test/value-custom.test.ts @@ -1,10 +1,10 @@ -import { expect } from 'chai'; - -import lang from '../src/language/en'; -import Builder from '../src/resolver/builder'; +import { en } from '../src/language/en'; +import { ResolverBuilder } from '../src/resolver/builder'; +import { ValueEncounter } from '../src/resolver/value'; +import { customValue } from '../src/values'; const items = [ 'Balloons', 'Cookie Co' ]; -function customValue(encounter) { +async function match(encounter: ValueEncounter) { const text = encounter.text().toLowerCase(); for(const v of items) { if(v.toLowerCase().startsWith(text)) { @@ -17,8 +17,8 @@ function customValue(encounter) { describe('Value: Custom', function() { describe('Full matching', function() { - const resolver = new Builder(lang) - .value('company', customValue) + const resolver = new ResolverBuilder(en) + .value('company', customValue(match)) .add('{company}') .add('{company} company') .build(); @@ -26,38 +26,38 @@ describe('Value: Custom', function() { it('Invalid company', function() { return resolver.match('ABC') .then(results => { - expect(results.matches.length).to.equal(0); + expect(results.matches.length).toEqual(0); }); }); it('Single token company', function() { return resolver.match('Balloons') .then(results => { - expect(results.matches.length).to.equal(1); - expect(results.best.values.company).to.equal('Balloons'); + expect(results.matches.length).toEqual(1); + expect(results.best.values.get('company')).toEqual('Balloons'); }); }); it('Multi token company', function() { return resolver.match('Cookie Co') .then(results => { - expect(results.matches.length).to.equal(1); - expect(results.best.values.company).to.equal('Cookie Co'); + expect(results.matches.length).toEqual(1); + expect(results.best.values.get('company')).toEqual('Cookie Co'); }); }); it('Multi token company with suffix', function() { return resolver.match('Cookie Co company') .then(results => { - expect(results.matches.length).to.equal(1); - expect(results.best.values.company).to.equal('Cookie Co'); + expect(results.matches.length).toEqual(1); + expect(results.best.values.get('company')).toEqual('Cookie Co'); }); }); }); describe('Partial matching', function() { - const resolver = new Builder(lang) - .value('company', customValue) + const resolver = new ResolverBuilder(en) + .value('company', customValue(match)) .add('{company}') .add('{company} company') .build(); @@ -65,31 +65,31 @@ describe('Value: Custom', function() { it('Invalid company', function() { return resolver.match('A', { partial: true }) .then(results => { - expect(results.matches.length).to.equal(0); + expect(results.matches.length).toEqual(0); }); }); it('Single token company', function() { return resolver.match('Ba', { partial: true }) .then(results => { - expect(results.matches.length).to.equal(1); - expect(results.best.values.company).to.equal('Balloons'); + expect(results.matches.length).toEqual(1); + expect(results.best.values.get('company')).toEqual('Balloons'); }); }); it('Multi token company', function() { return resolver.match('C', { partial: true }) .then(results => { - expect(results.matches.length).to.equal(1); - expect(results.best.values.company).to.equal('Cookie Co'); + expect(results.matches.length).toEqual(1); + expect(results.best.values.get('company')).toEqual('Cookie Co'); }); }); it('Multi token company with suffix', function() { return resolver.match('Cookie company', { partial: true }) .then(results => { - expect(results.matches.length).to.equal(1); - expect(results.best.values.company).to.equal('Cookie Co'); + expect(results.matches.length).toEqual(1); + expect(results.best.values.get('company')).toEqual('Cookie Co'); }); }); diff --git a/test/value-options.test.js b/test/value-options.test.ts similarity index 54% rename from test/value-options.test.js rename to test/value-options.test.ts index 7c0bb1f..7ec6b88 100644 --- a/test/value-options.test.js +++ b/test/value-options.test.ts @@ -1,30 +1,29 @@ -import { expect } from 'chai'; +import { en } from '../src/language/en'; +import { ResolverBuilder } from '../src/resolver/builder'; -import lang from '../src/language/en'; -import Builder from '../src/resolver/builder'; - -import { options, dateInterval, enumeration } from '../src/values'; +import { optionsValue, dateIntervalValue, enumerationValue, customValue } from '../src/values'; describe('Value: Options', function() { + /* describe('Standalone option: No values', () => { - const matcher = options() + const matcher = optionsValue() .option('deadline') .add('with deadline') .done() .build() - .matcher(lang); + .matcher(en); it('with deadline [partial=false]', () => matcher('with deadline') .then(v => { - expect(v).to.deep.equal([ + expect(v).toEqual([ { option: 'deadline', values: {}, } ]); - expect(v[0].expression).to.deep.equal([ + expect(v[0].expression).toEqual([ { type: 'text', value: 'with deadline', @@ -36,14 +35,14 @@ describe('Value: Options', function() { it('with deadline [partial=true]', () => matcher('with deadline', { partial: true }) .then(v => { - expect(v).to.deep.equal([ + expect(v).toEqual([ { option: 'deadline', values: {}, } ]); - expect(v[0].expression).to.deep.equal([ + expect(v[0].expression).toEqual([ { type: 'text', value: 'with deadline', @@ -55,14 +54,14 @@ describe('Value: Options', function() { it('with [partial=true]', () => matcher('with', { partial: true }) .then(v => { - expect(v).to.deep.equal([ + expect(v).toEqual([ { option: 'deadline', values: {}, } ]); - expect(v[0].expression).to.deep.equal([ + expect(v[0].expression).toEqual([ { type: 'text', value: 'with deadline', @@ -74,14 +73,14 @@ describe('Value: Options', function() { it('with d [partial=true]', () => matcher('with d', { partial: true }) .then(v => { - expect(v).to.deep.equal([ + expect(v).toEqual([ { option: 'deadline', values: {}, } ]); - expect(v[0].expression).to.deep.equal([ + expect(v[0].expression).toEqual([ { type: 'text', value: 'with deadline', @@ -93,7 +92,7 @@ describe('Value: Options', function() { it('with deadline and wi [partial=true]', () => matcher('with deadline and wi', { partial: true }) .then(v => { - expect(v).to.deep.equal([ + expect(v).toEqual([ { option: 'deadline', values: {}, @@ -104,7 +103,7 @@ describe('Value: Options', function() { } ]); - expect(v[0].expression).to.deep.equal([ + expect(v[0].expression).toEqual([ { type: 'text', value: 'with deadline', @@ -112,7 +111,7 @@ describe('Value: Options', function() { } ]); - expect(v[1].expression).to.deep.equal([ + expect(v[1].expression).toEqual([ { type: 'text', value: 'with deadline', @@ -124,22 +123,22 @@ describe('Value: Options', function() { }); describe('Standalone option: With value', () => { - const matcher = options() + const matcher = optionsValue() .option('deadline') - .value('deadline', dateInterval()) + .value('deadline', dateIntervalValue()) .add('with deadline {deadline}') .done() .build() - .matcher(lang); + .matcher(en); it('with deadline [partial=false]', () => matcher('with deadline jan 12th', { now: new Date(2010, 0, 1) }) .then(v => { - expect(v).to.not.be.null; - expect(v.length).to.equal(1); + expect(v).not.toBeNull(); + expect(v.length).toEqual(1); const a = v[0]; - expect(a.option).to.equal('deadline'); - expect(a.values.deadline).to.deep.equal({ + expect(a.option).toEqual('deadline'); + expect(a.values.deadline).toEqual({ start: { period: 'day', year: 2010, month: 0, day: 12 }, end: { period: 'day', year: 2010, month: 0, day: 12 } }); @@ -148,21 +147,22 @@ describe('Value: Options', function() { it('with deadline [partial=true]', () => matcher('with deadline', { partial: true }) .then(v => { - expect(v).to.not.be.null; - expect(v.length).to.equal(1); + expect(v).not.toBeNull(); + expect(v.length).toEqual(1); }) ); }); + */ describe('Single option - no value', () => { - const queryOptions = options() + const queryOptions = optionsValue() .option('deadline') .add('with deadline') .done() .build(); - const resolver = new Builder(lang) + const resolver = new ResolverBuilder(en) .value('queryOptions', queryOptions) .add('Things {queryOptions}') .build(); @@ -170,42 +170,42 @@ describe('Value: Options', function() { it('Full match', () => { return resolver.match('things with deadline', { partial: false }) .then(r => { - expect(r.best).to.not.be.null; - expect(r.best.values.queryOptions).to.be.instanceOf(Array); + expect(r.best).not.toBeNull(); + expect(r.best.values.get('queryOptions')).toBeInstanceOf(Array); - const v = r.best.values.queryOptions[0]; - expect(v.option).to.equal('deadline'); - expect(v.values).to.deep.equal({}); + const v = r.best.values.get('queryOptions')[0]; + expect(v.option).toEqual('deadline'); + expect(v.values).toEqual(new Map()); }); }); it('Partial match', () => { return resolver.match('things with d', { partial: true }) .then(r => { - expect(r.best).to.not.be.null; - expect(r.best.values.queryOptions).to.be.instanceOf(Array); + expect(r.best).not.toBeNull(); + expect(r.best.values.get('queryOptions')).toBeInstanceOf(Array); - const v = r.best.values.queryOptions[0]; - expect(v.option).to.equal('deadline'); - expect(v.values).to.deep.equal({}); + const v = r.best.values.get('queryOptions')[0]; + expect(v.option).toEqual('deadline'); + expect(v.values).toEqual(new Map()); }); }); }); describe('With values', () => { - const queryOptions = options({ min: 1 }) + const queryOptions = optionsValue() .option('deadline') - .value('deadline', dateInterval()) + .value('deadline', dateIntervalValue()) .add('with deadline {deadline}') .add('deadline {deadline}') .done() .option('completed') - .value('completed', dateInterval()) + .value('completed', dateIntervalValue()) .add('completed {completed}') .done() .build(); - const resolver = new Builder(lang) + const resolver = new ResolverBuilder(en) .value('queryOptions', queryOptions) .add('Things {queryOptions}') .build(); @@ -213,16 +213,14 @@ describe('Value: Options', function() { it('Full match', () => { return resolver.match('things with deadline jan 12th', { now: new Date(2018, 0, 2) }) .then(r => { - expect(r.best).to.not.be.null; - expect(r.best.values.queryOptions).to.be.instanceOf(Array); - - const v = r.best.values.queryOptions[0]; - expect(v.option).to.equal('deadline'); - expect(v.values).to.deep.equal({ - deadline: { - start: { period: 'day', year: 2018, month: 0, day: 12 }, - end: { period: 'day', year: 2018, month: 0, day: 12 } - } + expect(r.best).not.toBeNull(); + expect(r.best.values.get('queryOptions')).toBeInstanceOf(Array); + + const v = r.best.values.get('queryOptions')[0]; + expect(v.option).toEqual('deadline'); + expect(v.values.get('deadline')).toEqual({ + start: { period: 'day', year: 2018, month: 0, day: 12 }, + end: { period: 'day', year: 2018, month: 0, day: 12 } }); }); }); @@ -230,25 +228,21 @@ describe('Value: Options', function() { it('Multiple options', () => { return resolver.match('things with deadline jan 12th and completed today', { now: new Date(2018, 0, 2) }) .then(r => { - expect(r.best).to.not.be.null; - expect(r.best.values.queryOptions).to.be.instanceOf(Array); - - const v0 = r.best.values.queryOptions[0]; - expect(v0.option).to.equal('deadline'); - expect(v0.values).to.deep.equal({ - deadline: { - start: { period: 'day', year: 2018, month: 0, day: 12 }, - end: { period: 'day', year: 2018, month: 0, day: 12 } - } + expect(r.best).not.toBeNull(); + expect(r.best.values.get('queryOptions')).toBeInstanceOf(Array); + + const v0 = r.best.values.get('queryOptions')[0]; + expect(v0.option).toEqual('deadline'); + expect(v0.values.get('deadline')).toEqual({ + start: { period: 'day', year: 2018, month: 0, day: 12 }, + end: { period: 'day', year: 2018, month: 0, day: 12 } }); - const v1 = r.best.values.queryOptions[1]; - expect(v1.option).to.equal('completed'); - expect(v1.values).to.deep.equal({ - completed: { - start: { period: 'day', year: 2018, month: 0, day: 2 }, - end: { period: 'day', year: 2018, month: 0, day: 2 } - } + const v1 = r.best.values.get('queryOptions')[1]; + expect(v1.option).toEqual('completed'); + expect(v1.values.get('completed')).toEqual({ + start: { period: 'day', year: 2018, month: 0, day: 2 }, + end: { period: 'day', year: 2018, month: 0, day: 2 } }); }); }); @@ -262,9 +256,9 @@ describe('Value: Options', function() { 'four five' ]; - const queryOptions = options({ min: 1 }) + const queryOptions = optionsValue() .option('value') - .value('name', function(encounter) { + .value('name', customValue(async function(encounter) { let text = encounter.text(); if(encounter.partial) { for(const v of values) { @@ -277,23 +271,23 @@ describe('Value: Options', function() { encounter.match(text); } } - }) + })) .add('named {name}') .done() .option('completed') - .value('completed', dateInterval()) + .value('completed', dateIntervalValue()) .add('completed {completed}') .add('c {completed}') .done() .build(); - const resolver = new Builder(lang) + const resolver = new ResolverBuilder(en) .value('queryOptions', queryOptions) .add('Things {queryOptions}') .build(); - const resolver2 = new Builder(lang) - .value('enum', enumeration([ 'test', 'abc' ])) + const resolver2 = new ResolverBuilder(en) + .value('enum', enumerationValue([ 'test', 'abc' ])) .value('queryOptions', queryOptions) .add('{enum} {queryOptions}') .build(); @@ -301,85 +295,81 @@ describe('Value: Options', function() { it('Full match', () => { return resolver.match('things named one', { now: new Date(2018, 0, 2) }) .then(r => { - expect(r.best).to.not.be.null; - expect(r.best.values.queryOptions).to.be.instanceOf(Array); + expect(r.best).not.toBeNull(); + expect(r.best.values.get('queryOptions')).toBeInstanceOf(Array); - const v = r.best.values.queryOptions[0]; - expect(v.option).to.equal('value'); - expect(v.values).to.deep.equal({ - name: 'one' - }); + const v = r.best.values.get('queryOptions')[0]; + expect(v.option).toEqual('value'); + expect(v.values.get('name')).toEqual('one'); }); }); it('Partial match: thing', () => { return resolver.match('thing', { partial: true, now: new Date(2018, 0, 2) }) .then(r => { - expect(r.best).to.not.be.null; - expect(r.best.values.queryOptions).to.be.instanceOf(Array); + expect(r.best).not.toBeNull(); + expect(r.best.values.get('queryOptions')).toBeInstanceOf(Array); - const v = r.best.values.queryOptions[0]; - expect(v.option).to.equal('value'); + const v = r.best.values.get('queryOptions')[0]; + expect(v.option).toEqual('value'); - const v2 = r.matches[1].values.queryOptions[0]; - expect(v2.option).to.equal('completed'); + const v2 = r.matches[1].values.get('queryOptions')[0]; + expect(v2.option).toEqual('completed'); }); }); it('Partial match: thing com', () => { return resolver.match('thing com', { partial: true, now: new Date(2018, 0, 2) }) .then(r => { - expect(r.best).to.not.be.null; - expect(r.best.values.queryOptions).to.be.instanceOf(Array); + expect(r.best).not.toBeNull(); + expect(r.best.values.get('queryOptions')).toBeInstanceOf(Array); - const v = r.best.values.queryOptions[0]; - expect(v.option).to.equal('completed'); + const v = r.best.values.get('queryOptions')[0]; + expect(v.option).toEqual('completed'); }); }); it('Partial match: thing completed ja', () => { return resolver.match('thing completed ja', { partial: true, now: new Date(2018, 0, 2) }) .then(r => { - expect(r.best).to.not.be.null; - expect(r.best.values.queryOptions).to.be.instanceOf(Array); + expect(r.best).not.toBeNull(); + expect(r.best.values.get('queryOptions')).toBeInstanceOf(Array); - const v = r.best.values.queryOptions[0]; - expect(v.option).to.equal('completed'); + const v = r.best.values.get('queryOptions')[0]; + expect(v.option).toEqual('completed'); }); }); it('Match with enum first', () => { return resolver2.match('test named one', { now: new Date(2018, 0, 2) }) .then(r => { - expect(r.best).to.not.be.null; - expect(r.best.values.queryOptions).to.be.instanceOf(Array); + expect(r.best).not.toBeNull(); + expect(r.best.values.get('queryOptions')).toBeInstanceOf(Array); - const v = r.best.values.queryOptions[0]; - expect(v.option).to.equal('value'); - expect(v.values).to.deep.equal({ - name: 'one' - }); + const v = r.best.values.get('queryOptions')[0]; + expect(v.option).toEqual('value'); + expect(v.values.get('name')).toEqual('one'); }); }); it('Partial match with enum first', () => { return resolver2.match('test named one', { now: new Date(2018, 0, 2), partial: true }) .then(r => { - expect(r.best).to.not.be.null; - expect(r.matches.length).to.equal(1); + expect(r.best).not.toBeNull(); + expect(r.matches.length).toEqual(1); }); }); it('Partial match with enum first', () => { return resolver2.match('test n', { now: new Date(2018, 0, 2), partial: true }) .then(r => { - expect(r.best).to.not.be.null; - expect(r.matches.length).to.equal(1); + expect(r.best).not.toBeNull(); + expect(r.matches.length).toEqual(1); - expect(r.best.values.queryOptions).to.deep.equal([ + expect(r.best.values.get('queryOptions')).toEqual([ { option: 'value', - values: {} + values: new Map() } ]); }); @@ -388,8 +378,8 @@ describe('Value: Options', function() { it('Partial match with enum first', () => { return resolver2.match('test', { now: new Date(2018, 0, 2), partial: true }) .then(r => { - expect(r.best).to.not.be.null; - expect(r.matches.length).to.equal(2); + expect(r.best).not.toBeNull(); + expect(r.matches.length).toEqual(2); }); }); diff --git a/test/value.enum.test.js b/test/value.enum.test.ts similarity index 59% rename from test/value.enum.test.js rename to test/value.enum.test.ts index af47fbe..2754ec3 100644 --- a/test/value.enum.test.js +++ b/test/value.enum.test.ts @@ -1,14 +1,12 @@ -import { expect } from 'chai'; +import { en } from '../src/language/en'; +import { ResolverBuilder } from '../src/resolver/builder'; -import lang from '../src/language/en'; -import Builder from '../src/resolver/builder'; - -import { enumeration } from '../src/values'; +import { enumerationValue } from '../src/values'; describe('Value: Enumeration', function() { describe('No mapping', function() { - const resolver = new Builder(lang) - .value('company', enumeration([ 'Balloons', 'Cookie Co', 'Banana Inc' ])) + const resolver = new ResolverBuilder(en) + .value('company', enumerationValue([ 'Balloons', 'Cookie Co', 'Banana Inc' ])) .add('{company} orders') .add('orders for {company}') .build(); @@ -16,30 +14,30 @@ describe('Value: Enumeration', function() { it('Invalid company', function() { return resolver.match('orders for ABC') .then(results => { - expect(results.matches.length).to.equal(0); + expect(results.matches.length).toEqual(0); }); }); it('Single token company', function() { return resolver.match('orders for Ballons') .then(results => { - expect(results.matches.length).to.equal(1); - expect(results.best.values.company).to.equal('Balloons'); + expect(results.matches.length).toEqual(1); + expect(results.best.values.get('company')).toEqual('Balloons'); }); }); it('Multi token company', function() { return resolver.match('orders for Cookie Co') .then(results => { - expect(results.matches.length).to.equal(1); - expect(results.best.values.company).to.equal('Cookie Co'); + expect(results.matches.length).toEqual(1); + expect(results.best.values.get('company')).toEqual('Cookie Co'); }); }); }); describe('Mapping', function() { - const resolver = new Builder(lang) - .value('company', enumeration([ + const resolver = new ResolverBuilder(en) + .value('company', enumerationValue([ { name: 'Balloons' }, { name: 'Cookie Co' }, { name: 'Banana Inc' } @@ -51,15 +49,15 @@ describe('Value: Enumeration', function() { it('Invalid company', function() { return resolver.match('orders for ABC') .then(results => { - expect(results.matches.length).to.equal(0); + expect(results.matches.length).toEqual(0); }); }); it('Single token company', function() { return resolver.match('orders for Ballons') .then(results => { - expect(results.matches.length).to.equal(1); - expect(results.best.values.company).to.deep.equal({ + expect(results.matches.length).toEqual(1); + expect(results.best.values.get('company')).toEqual({ name: 'Balloons' }); }); @@ -68,8 +66,8 @@ describe('Value: Enumeration', function() { it('Multi token company', function() { return resolver.match('orders for Cookie Co') .then(results => { - expect(results.matches.length).to.equal(1); - expect(results.best.values.company).to.deep.equal({ + expect(results.matches.length).toEqual(1); + expect(results.best.values.get('company')).toEqual({ name: 'Cookie Co' }); }); @@ -77,8 +75,8 @@ describe('Value: Enumeration', function() { }); describe('Partial matching', function() { - const resolver = new Builder(lang) - .value('company', enumeration([ 'Balloons', 'Cookie Co', 'Banana Inc' ])) + const resolver = new ResolverBuilder(en) + .value('company', enumerationValue([ 'Balloons', 'Cookie Co', 'Banana Inc' ])) .add('{company} orders') .add('orders for {company}') .build(); @@ -87,8 +85,8 @@ describe('Value: Enumeration', function() { it('Single token', function() { return resolver.match('orders ', { partial: true }) .then(results => { - expect(results.matches.length).to.equal(1); - expect(results.best.values.company).to.be.undefined; + expect(results.matches.length).toEqual(1); + expect(results.best.values.get('company')).toBeUndefined(); }); }); @@ -96,14 +94,14 @@ describe('Value: Enumeration', function() { return resolver.match('orders for ', { partial: true }) .then(results => { // Expect all of the matches when at the start of the value - expect(results.matches.length).to.equal(3); + expect(results.matches.length).toEqual(3); }); }); - it('Typing `B`', function() { + it.only('Typing `B`', function() { return resolver.match('orders for b', { partial: true }) .then(results => { - expect(results.matches.length).to.equal(2); + expect(results.matches.length).toEqual(2); }); }); @@ -112,7 +110,7 @@ describe('Value: Enumeration', function() { partial: true }) .then(results => { - expect(results.matches.length).to.equal(0); + expect(results.matches.length).toEqual(0); }); }); @@ -121,11 +119,11 @@ describe('Value: Enumeration', function() { partial: true }) .then(results => { - expect(results.matches.length).to.equal(1); - expect(results.best.values.company).to.equal('Cookie Co'); + expect(results.matches.length).toEqual(1); + expect(results.best.values.get('company')).toEqual('Cookie Co'); const expr = results.best.expression; - expect(expr[expr.length - 1]).to.deep.equal({ + expect(expr[expr.length - 1]).toEqual({ type: 'value', id: 'company', value: 'Cookie Co', diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..f301da9 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,25 @@ +{ + "compilerOptions": { + "moduleResolution": "node", + "target": "es5", + "module":"es2015", + "lib": [ "es2015", "es2016", "es2017", "dom" ], + "strict": true, + "sourceMap": true, + "declaration": true, + "allowSyntheticDefaultImports": true, + "esModuleInterop": true, + "downlevelIteration": true, + "experimentalDecorators": true, + "emitDecoratorMetadata": true, + "declarationDir": "dist/types", + "outDir": "dist/lib", + "strictNullChecks": true, + "typeRoots": [ + "node_modules/@types" + ] + }, + "include": [ + "src" + ] +} diff --git a/tslint.json b/tslint.json new file mode 100644 index 0000000..7a41f44 --- /dev/null +++ b/tslint.json @@ -0,0 +1,81 @@ +{ + "extends": [ + ], + "rules": { + "indent": { + "options": [ "tabs" ] + }, + "ordered-imports": [ false ], + "interface-name": [ false ], + "member-ordering": [ false ], + "trailing-comma": [ false ], + "semicolon": { "options": [ "always" ] }, + "prefer-const": { + "severity": "warning" + }, + + "arrow-return-shorthand": true, + "ban-types": { + "options": [ + [ "Object", "Avoid using the `Object` type. Did you mean `object`?" ], + [ + "Function", + "Avoid using the `Function` type. Prefer a specific function type, like `() => void`." + ], + [ "Boolean", "Avoid using the `Boolean` type. Did you mean `boolean`?" ], + [ "Number", "Avoid using the `Number` type. Did you mean `number`?" ], + [ "String", "Avoid using the `String` type. Did you mean `string`?" ], + [ "Symbol", "Avoid using the `Symbol` type. Did you mean `symbol`?" ] + ] + }, + "callable-types": true, + "class-name": true, + "curly": [ true, "ignore-same-line" ], + "cyclomatic-complexity": false, + "forin": true, + "interface-over-type-literal": true, + "jsdoc-format": true, + "label-position": true, + "member-access": true, + "new-parens": true, + "no-angle-bracket-type-assertion": true, + "no-any": false, + "no-arg": true, + "no-bitwise": false, + "no-conditional-assignment": true, + "no-console": true, + "no-construct": true, + "no-debugger": true, + "no-duplicate-super": true, + "no-empty": true, + "no-empty-interface": true, + "no-eval": true, + "no-internal-module": true, + "no-invalid-this": false, + "no-misused-new": true, + "no-namespace": true, + "no-parameter-properties": false, + "no-reference": true, + "no-reference-import": true, + "no-shadowed-variable": true, + "no-string-literal": true, + "no-string-throw": true, + "no-switch-case-fall-through": false, + "no-trailing-whitespace": true, + "no-unnecessary-initializer": true, + "no-unsafe-finally": true, + "no-unused-expression": true, + "no-var-keyword": true, + "no-var-requires": true, + "object-literal-key-quotes": { "options": "consistent-as-needed" }, + "one-variable-per-declaration": { "options": [ "ignore-for-loop" ] }, + "quotemark": { + "options": [ "single", "avoid-escape" ] + }, + "radix": true, + "triple-equals": { "options": [ "allow-null-check" ] }, + "typedef": false, + "unified-signatures": true, + "use-isnan": true + } +}