From 4be45cbef7d3e2c5fbb1d1887e0fd17656e484cd Mon Sep 17 00:00:00 2001 From: Jae Bradley Date: Mon, 4 Jun 2018 08:19:18 -0400 Subject: [PATCH 01/38] Update development environment (#55) * build(babel): update Babel configuration * build(config): update config files * style(linting): temporarily turn off linting --- .babelrc | 18 +- .eslintignore | 7 + .eslintrc | 7 + .eslintrc.json | 10 - .gitignore | 63 +- .npmignore | 8 + .travis.yml | 26 +- package-lock.json | 12864 ++++++++++++++++ package.json | 64 +- test/.eslintrc.json | 17 - ...rviceTest.js => BaseSymbolService.test.js} | 25 +- 11 files changed, 13025 insertions(+), 84 deletions(-) create mode 100644 .eslintignore create mode 100644 .eslintrc delete mode 100644 .eslintrc.json create mode 100644 package-lock.json delete mode 100644 test/.eslintrc.json rename test/services/symbols/{BaseSymbolServiceTest.js => BaseSymbolService.test.js} (54%) diff --git a/.babelrc b/.babelrc index eaf3238..c3154fc 100644 --- a/.babelrc +++ b/.babelrc @@ -1,3 +1,19 @@ { - "presets": ["es2015", "stage-0"] + "presets": [ + "@babel/preset-env" + ], + "env": { + "production": { + "presets": [ + "minify" + ] + } + }, + "plugins": [ + "@babel/plugin-transform-runtime" + ], + "ignore": [ + "node_modules", + "*.test.js" + ] } diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..3f630e7 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,7 @@ +coverage/* +build +node_modules + +# Remove this to fix linting errors +src/ +test/ diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000..9b582af --- /dev/null +++ b/.eslintrc @@ -0,0 +1,7 @@ +{ + "extends": "airbnb-base", + "env": { + "jest": true + } + } + \ No newline at end of file diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index 6e508ff..0000000 --- a/.eslintrc.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "airbnb-base", - "plugins": [ - "import", - "chai-expect" - ], - "rules": { - "class-methods-use-this": "off" - } -} diff --git a/.gitignore b/.gitignore index 50902f2..b6e7612 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,60 @@ -node_modules/* -npm-debug.log -coverage/ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# Typescript v1 declaration files +typings/ + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env + build/ -package-lock.json diff --git a/.npmignore b/.npmignore index 8eba6c8..f12f2bd 100644 --- a/.npmignore +++ b/.npmignore @@ -1 +1,9 @@ +.DS_Store +.eslintcache +node_modules +npm-debug.log +.travis.yml src/ +test/ +*.test.js +coverage/ diff --git a/.travis.yml b/.travis.yml index d5f6e35..7a19e7b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,24 @@ language: node_js +cache: + directories: + - ~/.npm +notifications: + email: true node_js: -- 4.2.2 -sudo: false -script: -- npm run build + - '8' +before_install: + - npm install -g npm@5 + - npm install -g greenkeeper-lockfile@1 +jobs: + include: + - stage: test + script: + - npm run compile + - npm run lint + - npm run test + before_script: greenkeeper-lockfile-update + after_script: greenkeeper-lockfile-upload + after_success: npm run codecov + - stage: deploy + if: branch = master + script: npm run travis-deploy-once "npm run semantic-release" diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..f86825f --- /dev/null +++ b/package-lock.json @@ -0,0 +1,12864 @@ +{ + "name": "uber-cli", + "version": "0.0.3", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/cli": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.0.0-beta.49.tgz", + "integrity": "sha1-yMMTX3vEhChDb69ePydCJ6me8qg=", + "dev": true, + "requires": { + "chokidar": "^2.0.3", + "commander": "^2.8.1", + "convert-source-map": "^1.1.0", + "fs-readdir-recursive": "^1.0.0", + "glob": "^7.0.0", + "lodash": "^4.17.5", + "output-file-sync": "^2.0.0", + "slash": "^1.0.0", + "source-map": "^0.5.0" + }, + "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=", + "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.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.3.tgz", + "integrity": "sha512-zW8iXYZtXMx4kux/nuZVXjkLP+CyIK5Al5FHnj1OgTKGZfp4Oy6/ymtMSKFv3GD8DviEmUPmJg9eFdJ/JzudMg==", + "dev": true, + "optional": true, + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.0", + "braces": "^2.3.0", + "fsevents": "^1.1.2", + "glob-parent": "^3.1.0", + "inherits": "^2.0.1", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^2.1.1", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.0.0", + "upath": "^1.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=", + "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=", + "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 + }, + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "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" + } + }, + "output-file-sync": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/output-file-sync/-/output-file-sync-2.0.1.tgz", + "integrity": "sha512-mDho4qm7WgIXIGf4eYU1RHN2UU5tPfVYVSRwDJw0uTmj35DQUt/eNp19N7v6T3SrR0ESTEf2up2CGO73qI35zQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "is-plain-obj": "^1.1.0", + "mkdirp": "^0.5.1" + } + } + } + }, + "@babel/code-frame": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0-beta.49.tgz", + "integrity": "sha1-vs2AVIJzREDJ0TfkbXc0DmTX9Rs=", + "dev": true, + "requires": { + "@babel/highlight": "7.0.0-beta.49" + } + }, + "@babel/core": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.0.0-beta.49.tgz", + "integrity": "sha1-c94ggd1lJIlInwy0qpeCmhEzMU4=", + "dev": true, + "requires": { + "@babel/code-frame": "7.0.0-beta.49", + "@babel/generator": "7.0.0-beta.49", + "@babel/helpers": "7.0.0-beta.49", + "@babel/parser": "7.0.0-beta.49", + "@babel/template": "7.0.0-beta.49", + "@babel/traverse": "7.0.0-beta.49", + "@babel/types": "7.0.0-beta.49", + "convert-source-map": "^1.1.0", + "debug": "^3.1.0", + "json5": "^0.5.0", + "lodash": "^4.17.5", + "micromatch": "^2.3.11", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.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" + } + }, + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "dev": true + }, + "resolve": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.7.1.tgz", + "integrity": "sha512-c7rwLofp8g1U+h1KNyHL/jicrKg1Ek4q+Lr33AL65uZTinUZHe30D5HlyN5V9NW0JX1D5dXQ4jqW5l7Sy/kGfw==", + "dev": true, + "requires": { + "path-parse": "^1.0.5" + } + }, + "semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", + "dev": true + } + } + }, + "@babel/generator": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.0.0-beta.49.tgz", + "integrity": "sha1-6c/9qROZaszseTu8JauRvBnQv3o=", + "dev": true, + "requires": { + "@babel/types": "7.0.0-beta.49", + "jsesc": "^2.5.1", + "lodash": "^4.17.5", + "source-map": "^0.5.0", + "trim-right": "^1.0.1" + }, + "dependencies": { + "jsesc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.1.tgz", + "integrity": "sha1-5CGiqOINawgZ3yiQj3glJrlt0f4=", + "dev": true + }, + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "dev": true + } + } + }, + "@babel/helper-annotate-as-pure": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0-beta.49.tgz", + "integrity": "sha1-fZAF1U/nrWy4dnkCUedVdUGRhuk=", + "dev": true, + "requires": { + "@babel/types": "7.0.0-beta.49" + } + }, + "@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.0.0-beta.49.tgz", + "integrity": "sha1-xi3VBCtUpZDV5x5gIMRrkdbGyHU=", + "dev": true, + "requires": { + "@babel/helper-explode-assignable-expression": "7.0.0-beta.49", + "@babel/types": "7.0.0-beta.49" + } + }, + "@babel/helper-call-delegate": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/helper-call-delegate/-/helper-call-delegate-7.0.0-beta.49.tgz", + "integrity": "sha1-S11BeCpoPV3GSXg0oyMQqNAqOvk=", + "dev": true, + "requires": { + "@babel/helper-hoist-variables": "7.0.0-beta.49", + "@babel/traverse": "7.0.0-beta.49", + "@babel/types": "7.0.0-beta.49" + } + }, + "@babel/helper-define-map": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.0.0-beta.49.tgz", + "integrity": "sha1-TqBnqnIJNyQN85XNBzwk/K2cKzs=", + "dev": true, + "requires": { + "@babel/helper-function-name": "7.0.0-beta.49", + "@babel/types": "7.0.0-beta.49", + "lodash": "^4.17.5" + }, + "dependencies": { + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "dev": true + } + } + }, + "@babel/helper-explode-assignable-expression": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.0.0-beta.49.tgz", + "integrity": "sha1-K/uV337BMHNb9lXkSiF6cNOxPpM=", + "dev": true, + "requires": { + "@babel/traverse": "7.0.0-beta.49", + "@babel/types": "7.0.0-beta.49" + } + }, + "@babel/helper-function-name": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.49.tgz", + "integrity": "sha1-olwRGbnwNSeGcBJuAiXAMEHI3jI=", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "7.0.0-beta.49", + "@babel/template": "7.0.0-beta.49", + "@babel/types": "7.0.0-beta.49" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.49.tgz", + "integrity": "sha1-z1Aj8y0q2S0Ic3STnOwJUby1FEE=", + "dev": true, + "requires": { + "@babel/types": "7.0.0-beta.49" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.0.0-beta.49.tgz", + "integrity": "sha1-2XQGUck7tPp5wba6xjQFH8TQP/U=", + "dev": true, + "requires": { + "@babel/types": "7.0.0-beta.49" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.0.0-beta.49.tgz", + "integrity": "sha1-L2QrAD1FFV4KnnpK0OaI2Ru8FYM=", + "dev": true, + "requires": { + "@babel/types": "7.0.0-beta.49" + } + }, + "@babel/helper-module-imports": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.0.0-beta.49.tgz", + "integrity": "sha1-QdfVmJEBbEk0MqRvdGREZVKJDHU=", + "dev": true, + "requires": { + "@babel/types": "7.0.0-beta.49", + "lodash": "^4.17.5" + }, + "dependencies": { + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "dev": true + } + } + }, + "@babel/helper-module-transforms": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.0.0-beta.49.tgz", + "integrity": "sha1-/GYL2p1kl0EuGHdqca7ZqeLl960=", + "dev": true, + "requires": { + "@babel/helper-module-imports": "7.0.0-beta.49", + "@babel/helper-simple-access": "7.0.0-beta.49", + "@babel/helper-split-export-declaration": "7.0.0-beta.49", + "@babel/template": "7.0.0-beta.49", + "@babel/types": "7.0.0-beta.49", + "lodash": "^4.17.5" + }, + "dependencies": { + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "dev": true + } + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0-beta.49.tgz", + "integrity": "sha1-qYtDw6bFS+9I+HsQ3EVo3sC0G/c=", + "dev": true, + "requires": { + "@babel/types": "7.0.0-beta.49" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0-beta.49.tgz", + "integrity": "sha1-Dp/LuDT4eLs2XSqOqQ7uIbo8zSM=", + "dev": true + }, + "@babel/helper-regex": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.0.0-beta.49.tgz", + "integrity": "sha1-/yRPGcKi8Wf/SzFlpjawj9ZBgWs=", + "dev": true, + "requires": { + "lodash": "^4.17.5" + }, + "dependencies": { + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "dev": true + } + } + }, + "@babel/helper-remap-async-to-generator": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.0.0-beta.49.tgz", + "integrity": "sha1-s/2qtBJ4TX6GV7rKsoaSPvyUmLg=", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "7.0.0-beta.49", + "@babel/helper-wrap-function": "7.0.0-beta.49", + "@babel/template": "7.0.0-beta.49", + "@babel/traverse": "7.0.0-beta.49", + "@babel/types": "7.0.0-beta.49" + } + }, + "@babel/helper-replace-supers": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.0.0-beta.49.tgz", + "integrity": "sha1-50RMcYBX9qCjZFyvjnj7VG/7DZ8=", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "7.0.0-beta.49", + "@babel/helper-optimise-call-expression": "7.0.0-beta.49", + "@babel/traverse": "7.0.0-beta.49", + "@babel/types": "7.0.0-beta.49" + } + }, + "@babel/helper-simple-access": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.0.0-beta.49.tgz", + "integrity": "sha1-l6QeJ4mpv4psMFNqJYt550RMXYI=", + "dev": true, + "requires": { + "@babel/template": "7.0.0-beta.49", + "@babel/types": "7.0.0-beta.49", + "lodash": "^4.17.5" + }, + "dependencies": { + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "dev": true + } + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0-beta.49.tgz", + "integrity": "sha1-QNeO2glo0BGxxShm5XRs+yPldUg=", + "dev": true, + "requires": { + "@babel/types": "7.0.0-beta.49" + } + }, + "@babel/helper-wrap-function": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.0.0-beta.49.tgz", + "integrity": "sha1-OFWRRgtNk++W7jgZU5wM3Ju9R1g=", + "dev": true, + "requires": { + "@babel/helper-function-name": "7.0.0-beta.49", + "@babel/template": "7.0.0-beta.49", + "@babel/traverse": "7.0.0-beta.49", + "@babel/types": "7.0.0-beta.49" + } + }, + "@babel/helpers": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.0.0-beta.49.tgz", + "integrity": "sha1-BU2EAy1OlChqgFhlAAaOQQBaUdA=", + "dev": true, + "requires": { + "@babel/template": "7.0.0-beta.49", + "@babel/traverse": "7.0.0-beta.49", + "@babel/types": "7.0.0-beta.49" + } + }, + "@babel/highlight": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0-beta.49.tgz", + "integrity": "sha1-lr3GtD4TSCASumaRsQGEktOWIsw=", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.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 + }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@babel/parser": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.0.0-beta.49.tgz", + "integrity": "sha1-lE0MW6KBK7FZ7b0iZ0Ov0mUXm9w=", + "dev": true + }, + "@babel/plugin-proposal-async-generator-functions": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.0.0-beta.49.tgz", + "integrity": "sha1-h2Gl4ti1JR5w3yj00KpkqiillrE=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "7.0.0-beta.49", + "@babel/helper-remap-async-to-generator": "7.0.0-beta.49", + "@babel/plugin-syntax-async-generators": "7.0.0-beta.49" + } + }, + "@babel/plugin-proposal-object-rest-spread": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.0.0-beta.49.tgz", + "integrity": "sha1-bQzWD3p718REo3HE6UcL/wL1d3w=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "7.0.0-beta.49", + "@babel/plugin-syntax-object-rest-spread": "7.0.0-beta.49" + } + }, + "@babel/plugin-proposal-optional-catch-binding": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.0.0-beta.49.tgz", + "integrity": "sha1-H1PTZ4UQHV60tV1laGqis5+iHEs=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "7.0.0-beta.49", + "@babel/plugin-syntax-optional-catch-binding": "7.0.0-beta.49" + } + }, + "@babel/plugin-proposal-unicode-property-regex": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.0.0-beta.49.tgz", + "integrity": "sha1-DvX7mr2pgM0Vhe9Mjo9oC2MmPHI=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "7.0.0-beta.49", + "@babel/helper-regex": "7.0.0-beta.49", + "regexpu-core": "^4.1.4" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "dev": true + }, + "regenerate": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", + "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==", + "dev": true + }, + "regexpu-core": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.1.5.tgz", + "integrity": "sha512-3xo5pFze1F8oR4F9x3aFbdtdxAxQ9WBX6gXfLgeBt7KpDI0+oDF7WVntnhsPKqobU/GAYc2pmx+y3z0JI1+z3w==", + "dev": true, + "requires": { + "regenerate": "^1.4.0", + "regenerate-unicode-properties": "^6.0.0", + "regjsgen": "^0.4.0", + "regjsparser": "^0.3.0", + "unicode-match-property-ecmascript": "^1.0.3", + "unicode-match-property-value-ecmascript": "^1.0.1" + } + }, + "regjsgen": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.4.0.tgz", + "integrity": "sha512-X51Lte1gCYUdlwhF28+2YMO0U6WeN0GLpgpA7LK7mbdDnkQYiwvEpmpe0F/cv5L14EbxgrdayAG3JETBv0dbXA==", + "dev": true + }, + "regjsparser": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.3.0.tgz", + "integrity": "sha512-zza72oZBBHzt64G7DxdqrOo/30bhHkwMUoT0WqfGu98XLd7N+1tsy5MJ96Bk4MD0y74n629RhmrGW6XlnLLwCA==", + "dev": true, + "requires": { + "jsesc": "~0.5.0" + } + } + } + }, + "@babel/plugin-syntax-async-generators": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.0.0-beta.49.tgz", + "integrity": "sha1-UO6UMAKu3JqzqNEikr013Z7bHfg=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "7.0.0-beta.49" + } + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.0.0-beta.49.tgz", + "integrity": "sha1-R4SziAgj/xLnQsJrQemFf3AdY54=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "7.0.0-beta.49" + } + }, + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.0.0-beta.49.tgz", + "integrity": "sha1-Ph3T1drrQnDk7khjZB1Pqga7zRE=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "7.0.0-beta.49" + } + }, + "@babel/plugin-transform-arrow-functions": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.0.0-beta.49.tgz", + "integrity": "sha1-3ThFtjxoPRh9UYbuDogsQEbE8OM=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "7.0.0-beta.49" + } + }, + "@babel/plugin-transform-async-to-generator": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.0.0-beta.49.tgz", + "integrity": "sha1-kRpA65MEAYbOtpMQXKdt73/pfQM=", + "dev": true, + "requires": { + "@babel/helper-module-imports": "7.0.0-beta.49", + "@babel/helper-plugin-utils": "7.0.0-beta.49", + "@babel/helper-remap-async-to-generator": "7.0.0-beta.49" + } + }, + "@babel/plugin-transform-block-scoped-functions": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.0.0-beta.49.tgz", + "integrity": "sha1-eqn0b9+HO3IRqqLrDTfEw3Ghq9I=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "7.0.0-beta.49" + } + }, + "@babel/plugin-transform-block-scoping": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.0.0-beta.49.tgz", + "integrity": "sha1-3Vqd3ZhndciyDPW2EGWvs92eqsk=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "7.0.0-beta.49", + "lodash": "^4.17.5" + }, + "dependencies": { + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "dev": true + } + } + }, + "@babel/plugin-transform-classes": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.0.0-beta.49.tgz", + "integrity": "sha1-U0JHHS5qMzczLqJGtGwL3fX8VE0=", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "7.0.0-beta.49", + "@babel/helper-define-map": "7.0.0-beta.49", + "@babel/helper-function-name": "7.0.0-beta.49", + "@babel/helper-optimise-call-expression": "7.0.0-beta.49", + "@babel/helper-plugin-utils": "7.0.0-beta.49", + "@babel/helper-replace-supers": "7.0.0-beta.49", + "@babel/helper-split-export-declaration": "7.0.0-beta.49", + "globals": "^11.1.0" + }, + "dependencies": { + "globals": { + "version": "11.5.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.5.0.tgz", + "integrity": "sha512-hYyf+kI8dm3nORsiiXUQigOU62hDLfJ9G01uyGMxhc6BKsircrUhC4uJPQPUSuq2GrTmiiEt7ewxlMdBewfmKQ==", + "dev": true + } + } + }, + "@babel/plugin-transform-computed-properties": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.0.0-beta.49.tgz", + "integrity": "sha1-uCWdF0vwerS1ZWZWK0buZSDD39I=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "7.0.0-beta.49" + } + }, + "@babel/plugin-transform-destructuring": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.0.0-beta.49.tgz", + "integrity": "sha1-Q2Y5LJyC0SMQVsHQApQ4pg02K4I=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "7.0.0-beta.49" + } + }, + "@babel/plugin-transform-dotall-regex": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.0.0-beta.49.tgz", + "integrity": "sha1-Na4rwYe+51LQ93hdJwTlK4c3c2k=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "7.0.0-beta.49", + "@babel/helper-regex": "7.0.0-beta.49", + "regexpu-core": "^4.1.3" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "dev": true + }, + "regenerate": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", + "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==", + "dev": true + }, + "regexpu-core": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.1.5.tgz", + "integrity": "sha512-3xo5pFze1F8oR4F9x3aFbdtdxAxQ9WBX6gXfLgeBt7KpDI0+oDF7WVntnhsPKqobU/GAYc2pmx+y3z0JI1+z3w==", + "dev": true, + "requires": { + "regenerate": "^1.4.0", + "regenerate-unicode-properties": "^6.0.0", + "regjsgen": "^0.4.0", + "regjsparser": "^0.3.0", + "unicode-match-property-ecmascript": "^1.0.3", + "unicode-match-property-value-ecmascript": "^1.0.1" + } + }, + "regjsgen": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.4.0.tgz", + "integrity": "sha512-X51Lte1gCYUdlwhF28+2YMO0U6WeN0GLpgpA7LK7mbdDnkQYiwvEpmpe0F/cv5L14EbxgrdayAG3JETBv0dbXA==", + "dev": true + }, + "regjsparser": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.3.0.tgz", + "integrity": "sha512-zza72oZBBHzt64G7DxdqrOo/30bhHkwMUoT0WqfGu98XLd7N+1tsy5MJ96Bk4MD0y74n629RhmrGW6XlnLLwCA==", + "dev": true, + "requires": { + "jsesc": "~0.5.0" + } + } + } + }, + "@babel/plugin-transform-duplicate-keys": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.0.0-beta.49.tgz", + "integrity": "sha1-+sJEgJ3ey/CV43VVjMtxbaEEIxY=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "7.0.0-beta.49" + } + }, + "@babel/plugin-transform-exponentiation-operator": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.0.0-beta.49.tgz", + "integrity": "sha1-RXstCQBHlGhKpuGwQBUIC4CgihQ=", + "dev": true, + "requires": { + "@babel/helper-builder-binary-assignment-operator-visitor": "7.0.0-beta.49", + "@babel/helper-plugin-utils": "7.0.0-beta.49" + } + }, + "@babel/plugin-transform-for-of": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.0.0-beta.49.tgz", + "integrity": "sha1-PscnJr8diaDU1RG+epVJBm9Xqt4=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "7.0.0-beta.49" + } + }, + "@babel/plugin-transform-function-name": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.0.0-beta.49.tgz", + "integrity": "sha1-rzn2Dnrvzpsl60rc7dBNUIZs4hg=", + "dev": true, + "requires": { + "@babel/helper-function-name": "7.0.0-beta.49", + "@babel/helper-plugin-utils": "7.0.0-beta.49" + } + }, + "@babel/plugin-transform-literals": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.0.0-beta.49.tgz", + "integrity": "sha1-B8g4JU1l5oZ+hlE+sPItXyawpWo=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "7.0.0-beta.49" + } + }, + "@babel/plugin-transform-modules-amd": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.0.0-beta.49.tgz", + "integrity": "sha1-FtB0gJVLBBXqcPHsPtvQWXvT3f4=", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "7.0.0-beta.49", + "@babel/helper-plugin-utils": "7.0.0-beta.49" + } + }, + "@babel/plugin-transform-modules-commonjs": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.0.0-beta.49.tgz", + "integrity": "sha1-Cfs0XVknwro72J582xOlUGftOaA=", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "7.0.0-beta.49", + "@babel/helper-plugin-utils": "7.0.0-beta.49", + "@babel/helper-simple-access": "7.0.0-beta.49" + } + }, + "@babel/plugin-transform-modules-systemjs": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.0.0-beta.49.tgz", + "integrity": "sha1-aCJaOuExJ3G8Wjb3H/ENAsEkPZ8=", + "dev": true, + "requires": { + "@babel/helper-hoist-variables": "7.0.0-beta.49", + "@babel/helper-plugin-utils": "7.0.0-beta.49" + } + }, + "@babel/plugin-transform-modules-umd": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.0.0-beta.49.tgz", + "integrity": "sha1-cEjKWncYlwb0s+luS5luswWQ3WM=", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "7.0.0-beta.49", + "@babel/helper-plugin-utils": "7.0.0-beta.49" + } + }, + "@babel/plugin-transform-new-target": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.0.0-beta.49.tgz", + "integrity": "sha1-wv/vHruvckqeWN3hFOV+Pmhkpec=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "7.0.0-beta.49" + } + }, + "@babel/plugin-transform-object-super": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.0.0-beta.49.tgz", + "integrity": "sha1-swL1VwKEc0PBD/T7hDXMNXR1X+M=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "7.0.0-beta.49", + "@babel/helper-replace-supers": "7.0.0-beta.49" + } + }, + "@babel/plugin-transform-parameters": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.0.0-beta.49.tgz", + "integrity": "sha1-HK1xoqMygeXvuxpGI6lkwHPOmi0=", + "dev": true, + "requires": { + "@babel/helper-call-delegate": "7.0.0-beta.49", + "@babel/helper-get-function-arity": "7.0.0-beta.49", + "@babel/helper-plugin-utils": "7.0.0-beta.49" + } + }, + "@babel/plugin-transform-regenerator": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.0.0-beta.49.tgz", + "integrity": "sha1-1O15ZwM/T1tJNjwgNQOJm4NXyuI=", + "dev": true, + "requires": { + "regenerator-transform": "^0.12.3" + }, + "dependencies": { + "regenerator-transform": { + "version": "0.12.4", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.12.4.tgz", + "integrity": "sha512-p2I0fY+TbSLD2/VFTFb/ypEHxs3e3AjU0DzttdPqk2bSmDhfSh5E54b86Yc6XhUa5KykK1tgbvZ4Nr82oCJWkQ==", + "dev": true, + "requires": { + "private": "^0.1.6" + } + } + } + }, + "@babel/plugin-transform-runtime": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.0.0-beta.49.tgz", + "integrity": "sha1-ZaMOwLw29CSTJdvCQ4+X9WO0Hxo=", + "dev": true, + "requires": { + "@babel/helper-module-imports": "7.0.0-beta.49", + "@babel/helper-plugin-utils": "7.0.0-beta.49" + } + }, + "@babel/plugin-transform-shorthand-properties": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.0.0-beta.49.tgz", + "integrity": "sha1-SfE0295PZVg0whUk6eYaWNTheQA=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "7.0.0-beta.49" + } + }, + "@babel/plugin-transform-spread": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.0.0-beta.49.tgz", + "integrity": "sha1-arqwX8DMqCmq+eKoUES3l2Pmgco=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "7.0.0-beta.49" + } + }, + "@babel/plugin-transform-sticky-regex": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.0.0-beta.49.tgz", + "integrity": "sha1-CMxbZM9qWUKoe92bSkgY1MuhLfM=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "7.0.0-beta.49", + "@babel/helper-regex": "7.0.0-beta.49" + } + }, + "@babel/plugin-transform-template-literals": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.0.0-beta.49.tgz", + "integrity": "sha1-5gmu1rj8x+HrzKzyITimRyApQKI=", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "7.0.0-beta.49", + "@babel/helper-plugin-utils": "7.0.0-beta.49" + } + }, + "@babel/plugin-transform-typeof-symbol": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.0.0-beta.49.tgz", + "integrity": "sha1-NlFBujVb9znu/Wwrud8cO3FG5FA=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "7.0.0-beta.49" + } + }, + "@babel/plugin-transform-unicode-regex": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.0.0-beta.49.tgz", + "integrity": "sha1-w3XbVwl1diFSPUGstiqavw1DdLg=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "7.0.0-beta.49", + "@babel/helper-regex": "7.0.0-beta.49", + "regexpu-core": "^4.1.3" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "dev": true + }, + "regenerate": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", + "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==", + "dev": true + }, + "regexpu-core": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.1.5.tgz", + "integrity": "sha512-3xo5pFze1F8oR4F9x3aFbdtdxAxQ9WBX6gXfLgeBt7KpDI0+oDF7WVntnhsPKqobU/GAYc2pmx+y3z0JI1+z3w==", + "dev": true, + "requires": { + "regenerate": "^1.4.0", + "regenerate-unicode-properties": "^6.0.0", + "regjsgen": "^0.4.0", + "regjsparser": "^0.3.0", + "unicode-match-property-ecmascript": "^1.0.3", + "unicode-match-property-value-ecmascript": "^1.0.1" + } + }, + "regjsgen": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.4.0.tgz", + "integrity": "sha512-X51Lte1gCYUdlwhF28+2YMO0U6WeN0GLpgpA7LK7mbdDnkQYiwvEpmpe0F/cv5L14EbxgrdayAG3JETBv0dbXA==", + "dev": true + }, + "regjsparser": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.3.0.tgz", + "integrity": "sha512-zza72oZBBHzt64G7DxdqrOo/30bhHkwMUoT0WqfGu98XLd7N+1tsy5MJ96Bk4MD0y74n629RhmrGW6XlnLLwCA==", + "dev": true, + "requires": { + "jsesc": "~0.5.0" + } + } + } + }, + "@babel/preset-env": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.0.0-beta.49.tgz", + "integrity": "sha1-SoqLkhOfUfovkPv28frXWXUyrrw=", + "dev": true, + "requires": { + "@babel/helper-module-imports": "7.0.0-beta.49", + "@babel/helper-plugin-utils": "7.0.0-beta.49", + "@babel/plugin-proposal-async-generator-functions": "7.0.0-beta.49", + "@babel/plugin-proposal-object-rest-spread": "7.0.0-beta.49", + "@babel/plugin-proposal-optional-catch-binding": "7.0.0-beta.49", + "@babel/plugin-proposal-unicode-property-regex": "7.0.0-beta.49", + "@babel/plugin-syntax-async-generators": "7.0.0-beta.49", + "@babel/plugin-syntax-object-rest-spread": "7.0.0-beta.49", + "@babel/plugin-syntax-optional-catch-binding": "7.0.0-beta.49", + "@babel/plugin-transform-arrow-functions": "7.0.0-beta.49", + "@babel/plugin-transform-async-to-generator": "7.0.0-beta.49", + "@babel/plugin-transform-block-scoped-functions": "7.0.0-beta.49", + "@babel/plugin-transform-block-scoping": "7.0.0-beta.49", + "@babel/plugin-transform-classes": "7.0.0-beta.49", + "@babel/plugin-transform-computed-properties": "7.0.0-beta.49", + "@babel/plugin-transform-destructuring": "7.0.0-beta.49", + "@babel/plugin-transform-dotall-regex": "7.0.0-beta.49", + "@babel/plugin-transform-duplicate-keys": "7.0.0-beta.49", + "@babel/plugin-transform-exponentiation-operator": "7.0.0-beta.49", + "@babel/plugin-transform-for-of": "7.0.0-beta.49", + "@babel/plugin-transform-function-name": "7.0.0-beta.49", + "@babel/plugin-transform-literals": "7.0.0-beta.49", + "@babel/plugin-transform-modules-amd": "7.0.0-beta.49", + "@babel/plugin-transform-modules-commonjs": "7.0.0-beta.49", + "@babel/plugin-transform-modules-systemjs": "7.0.0-beta.49", + "@babel/plugin-transform-modules-umd": "7.0.0-beta.49", + "@babel/plugin-transform-new-target": "7.0.0-beta.49", + "@babel/plugin-transform-object-super": "7.0.0-beta.49", + "@babel/plugin-transform-parameters": "7.0.0-beta.49", + "@babel/plugin-transform-regenerator": "7.0.0-beta.49", + "@babel/plugin-transform-shorthand-properties": "7.0.0-beta.49", + "@babel/plugin-transform-spread": "7.0.0-beta.49", + "@babel/plugin-transform-sticky-regex": "7.0.0-beta.49", + "@babel/plugin-transform-template-literals": "7.0.0-beta.49", + "@babel/plugin-transform-typeof-symbol": "7.0.0-beta.49", + "@babel/plugin-transform-unicode-regex": "7.0.0-beta.49", + "browserslist": "^3.0.0", + "invariant": "^2.2.2", + "semver": "^5.3.0" + }, + "dependencies": { + "semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", + "dev": true + } + } + }, + "@babel/runtime": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.0.0-beta.49.tgz", + "integrity": "sha1-A7O/B+uYIHLI6FHdLd1RECguYb8=", + "requires": { + "core-js": "^2.5.6", + "regenerator-runtime": "^0.11.1" + } + }, + "@babel/template": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.0.0-beta.49.tgz", + "integrity": "sha1-44q+ghfLl5P0YaUwbXrXRdg+HSc=", + "dev": true, + "requires": { + "@babel/code-frame": "7.0.0-beta.49", + "@babel/parser": "7.0.0-beta.49", + "@babel/types": "7.0.0-beta.49", + "lodash": "^4.17.5" + }, + "dependencies": { + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "dev": true + } + } + }, + "@babel/traverse": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.0.0-beta.49.tgz", + "integrity": "sha1-TypzaCoYM07WYl0QCo0nMZ98LWg=", + "dev": true, + "requires": { + "@babel/code-frame": "7.0.0-beta.49", + "@babel/generator": "7.0.0-beta.49", + "@babel/helper-function-name": "7.0.0-beta.49", + "@babel/helper-split-export-declaration": "7.0.0-beta.49", + "@babel/parser": "7.0.0-beta.49", + "@babel/types": "7.0.0-beta.49", + "debug": "^3.1.0", + "globals": "^11.1.0", + "invariant": "^2.2.0", + "lodash": "^4.17.5" + }, + "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" + } + }, + "globals": { + "version": "11.5.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.5.0.tgz", + "integrity": "sha512-hYyf+kI8dm3nORsiiXUQigOU62hDLfJ9G01uyGMxhc6BKsircrUhC4uJPQPUSuq2GrTmiiEt7ewxlMdBewfmKQ==", + "dev": true + }, + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "dev": true + } + } + }, + "@babel/types": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.0.0-beta.49.tgz", + "integrity": "sha1-t+Oxw/TUz+Eb34yJ8e/V4WF7h6Y=", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.5", + "to-fast-properties": "^2.0.0" + }, + "dependencies": { + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "dev": true + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + } + } + }, + "@google/maps": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@google/maps/-/maps-0.3.1.tgz", + "integrity": "sha1-PxAwMDPlPT/Hu51iaN4iZoA794E=" + }, + "@mrmlnc/readdir-enhanced": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", + "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==", + "dev": true, + "requires": { + "call-me-maybe": "^1.0.1", + "glob-to-regexp": "^0.3.0" + } + }, + "@nodelib/fs.stat": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.0.tgz", + "integrity": "sha512-LAQ1d4OPfSJ/BMbI2DuizmYrrkD9JMaTdi2hQTlI53lQ4kRQPyZQRS4CYQ7O66bnBBnP/oYdRxbk++X0xuFU6A==", + "dev": true + }, + "@octokit/rest": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-15.8.1.tgz", + "integrity": "sha512-IpC/ctwwauiiSrnNTHOG4CyAPz5YwEX8wSSGuTBb0M1mJcAYJCaYZr11dSZTB4K2p2XFY4AY5+SZcW5aub3hSQ==", + "dev": true, + "requires": { + "before-after-hook": "^1.1.0", + "btoa-lite": "^1.0.0", + "debug": "^3.1.0", + "http-proxy-agent": "^2.1.0", + "https-proxy-agent": "^2.2.0", + "lodash": "^4.17.4", + "node-fetch": "^2.1.1", + "url-template": "^2.0.8" + }, + "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" + } + }, + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "dev": true + } + } + }, + "@semantic-release/commit-analyzer": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@semantic-release/commit-analyzer/-/commit-analyzer-5.0.3.tgz", + "integrity": "sha512-4GLFDmp8Up+f4GQGPIzLVd8X9a3yqbZjl761sEdfCH4e5FkEO3I9XRlTEfKSueeCt5OA1lZBb9IHGpZ6Ot0+BQ==", + "dev": true, + "requires": { + "conventional-changelog-angular": "^3.0.0", + "conventional-commits-parser": "^2.0.0", + "debug": "^3.1.0", + "import-from": "^2.1.0", + "lodash": "^4.17.4" + }, + "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" + } + }, + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "dev": true + } + } + }, + "@semantic-release/error": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-2.2.0.tgz", + "integrity": "sha512-9Tj/qn+y2j+sjCI3Jd+qseGtHjOAeg7dU2/lVcqIQ9TV3QDaDXDYXcoOHU+7o2Hwh8L8ymL4gfuO7KxDs3q2zg==", + "dev": true + }, + "@semantic-release/github": { + "version": "4.2.17", + "resolved": "https://registry.npmjs.org/@semantic-release/github/-/github-4.2.17.tgz", + "integrity": "sha512-oLDvwvOkX+WNG2IXEg2UAGh4hiabJbmz+JsK1Vs+q39A2rLwmDYqmkppA+bUq8xokY6W8xEpdw1EHIhZNqsQ8w==", + "dev": true, + "requires": { + "@octokit/rest": "^15.2.0", + "@semantic-release/error": "^2.2.0", + "aggregate-error": "^1.0.0", + "bottleneck": "^2.0.1", + "debug": "^3.1.0", + "fs-extra": "^6.0.0", + "globby": "^8.0.0", + "issue-parser": "^2.0.0", + "lodash": "^4.17.4", + "mime": "^2.0.3", + "p-filter": "^1.0.0", + "p-retry": "^2.0.0", + "parse-github-url": "^1.0.1", + "url-join": "^4.0.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" + } + }, + "globby": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-8.0.1.tgz", + "integrity": "sha512-oMrYrJERnKBLXNLVTqhm3vPEdJ/b2ZE28xN4YARiix1NOIOBPEpOUnm844K1iu/BkphCaf2WNFwMszv8Soi1pw==", + "dev": true, + "requires": { + "array-union": "^1.0.1", + "dir-glob": "^2.0.0", + "fast-glob": "^2.0.2", + "glob": "^7.1.2", + "ignore": "^3.3.5", + "pify": "^3.0.0", + "slash": "^1.0.0" + } + }, + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "dev": true + }, + "mime": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.3.1.tgz", + "integrity": "sha512-OEUllcVoydBHGN1z84yfQDimn58pZNNNXgZlHXSboxMlFvgI6MXSWpWKpFRra7H1HxpVhHTkrghfRW49k6yjeg==", + "dev": true + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + } + } + }, + "@semantic-release/npm": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@semantic-release/npm/-/npm-3.3.1.tgz", + "integrity": "sha512-cSTxtCmLRk1SO3spR/4JPXWtnMLP/K79AqaQYhHVVUleRcKdlrxu1A1hO3ADlZ6MVTf1iDPe+lXm4FJ139Neeg==", + "dev": true, + "requires": { + "@semantic-release/error": "^2.2.0", + "aggregate-error": "^1.0.0", + "detect-indent": "^5.0.0", + "detect-newline": "^2.1.0", + "execa": "^0.10.0", + "fs-extra": "^6.0.0", + "lodash": "^4.17.4", + "nerf-dart": "^1.0.0", + "normalize-url": "^3.0.0", + "parse-json": "^4.0.0", + "read-pkg": "^3.0.0", + "registry-auth-token": "^3.3.1" + }, + "dependencies": { + "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" + } + }, + "detect-indent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-5.0.0.tgz", + "integrity": "sha1-OHHMCmoALow+Wzz38zYmRnXwa50=", + "dev": true + }, + "execa": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.10.0.tgz", + "integrity": "sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "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" + } + }, + "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" + } + }, + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "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-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": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "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" + } + }, + "semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", + "dev": true + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + } + } + }, + "@semantic-release/release-notes-generator": { + "version": "6.0.10", + "resolved": "https://registry.npmjs.org/@semantic-release/release-notes-generator/-/release-notes-generator-6.0.10.tgz", + "integrity": "sha512-8eigxfGSy36+mv4rUIbGZAGZkUVZYNXOyRpcG+ZHSeGTqG6hu9uUxmzkfQ2hvK3zSxqrzKPg3MxnhvZL1Qqmrg==", + "dev": true, + "requires": { + "conventional-changelog-angular": "^3.0.6", + "conventional-changelog-writer": "^3.0.9", + "conventional-commits-parser": "^2.1.7", + "debug": "^3.1.0", + "get-stream": "^3.0.0", + "git-url-parse": "^9.0.0", + "import-from": "^2.1.0", + "into-stream": "^3.1.0", + "lodash": "^4.17.4" + }, + "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" + } + }, + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "dev": true + } + } + }, + "@sindresorhus/is": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.7.0.tgz", + "integrity": "sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow==", + "dev": true + }, + "JSONStream": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.3.tgz", + "integrity": "sha512-3Sp6WZZ/lXl+nTDoGpGWHEpTnnC6X5fnkolYZR6nwIfzbxxvA8utPWe1gCt7i0m9uVGsSz2IS8K8mJ7HmlduMg==", + "dev": true, + "requires": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + } + }, + "abab": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/abab/-/abab-1.0.4.tgz", + "integrity": "sha1-X6rZwsB/YN12dw9xzwJbYqY8/U4=", + "dev": true + }, + "acorn": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.6.1.tgz", + "integrity": "sha512-XH4o5BK5jmw9PzSGK7mNf+/xV+mPxQxGZoeC36OVsJZYV77JAG9NnI7T90hoUpI/C1TOfXWTvugRdZ9ZR3iE2Q==", + "dev": true + }, + "acorn-globals": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.1.0.tgz", + "integrity": "sha512-KjZwU26uG3u6eZcfGbTULzFcsoz6pegNKtHPksZPOUsiKo5bUmiBPa38FuHZ/Eun+XYh/JCCkS9AS3Lu4McQOQ==", + "dev": true, + "requires": { + "acorn": "^5.0.0" + } + }, + "acorn-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", + "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", + "dev": true, + "requires": { + "acorn": "^3.0.4" + }, + "dependencies": { + "acorn": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", + "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", + "dev": true + } + } + }, + "agent-base": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.0.tgz", + "integrity": "sha512-c+R/U5X+2zz2+UCrCFv6odQzJdoqI+YecuhnAJLa1zYaMc13zPfwMwZrr91Pd1DYNo/yPRbiM4WVf9whgwFsIg==", + "dev": true, + "requires": { + "es6-promisify": "^5.0.0" + } + }, + "aggregate-error": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-1.0.0.tgz", + "integrity": "sha1-iINE2tAiCnLjr1CQYRf0h3GSX6w=", + "dev": true, + "requires": { + "clean-stack": "^1.0.0", + "indent-string": "^3.0.0" + }, + "dependencies": { + "indent-string": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", + "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=", + "dev": true + } + } + }, + "ajv": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", + "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", + "requires": { + "co": "^4.6.0", + "fast-deep-equal": "^1.0.0", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.3.0" + } + }, + "ajv-keywords": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz", + "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=", + "dev": true + }, + "align-text": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", + "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", + "dev": true, + "requires": { + "kind-of": "^3.0.2", + "longest": "^1.0.1", + "repeat-string": "^1.5.2" + } + }, + "amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", + "dev": true + }, + "ansi-align": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz", + "integrity": "sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=", + "dev": true, + "requires": { + "string-width": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "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 + }, + "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": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "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" + } + } + } + }, + "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": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "ansicolors": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.2.1.tgz", + "integrity": "sha1-vgiVmQl7dKXJxKhKDNvNtivYeu8=", + "dev": true + }, + "append-transform": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-0.4.0.tgz", + "integrity": "sha1-126/jKlNJ24keja61EpLdKthGZE=", + "dev": true, + "requires": { + "default-require-extensions": "^1.0.0" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "argv": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/argv/-/argv-0.0.2.tgz", + "integrity": "sha1-7L0W+JSbFXGDcRsb2jNPN4QBhas=", + "dev": true + }, + "argv-formatter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/argv-formatter/-/argv-formatter-1.0.0.tgz", + "integrity": "sha1-oMoMvCmltz6Dbuvhy/bF4OTrgvk=", + "dev": true + }, + "arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "dev": true, + "requires": { + "arr-flatten": "^1.0.1" + } + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true + }, + "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-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", + "dev": true + }, + "array-ify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", + "integrity": "sha1-nlKHYrSpBmrRY6aWKjZEGOlibs4=", + "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=", + "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 + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + }, + "asn1": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", + "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=" + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + }, + "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 + }, + "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": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "dev": true + }, + "async-each": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", + "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", + "dev": true, + "optional": true + }, + "async-limiter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", + "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==", + "dev": true + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "atob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.1.tgz", + "integrity": "sha1-ri1acpR38onWDdf5amMUoi3Wwio=", + "dev": true + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + }, + "aws4": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.7.0.tgz", + "integrity": "sha512-32NDda82rhwD9/JBCCkB+MRYDp0oSvlo2IL6rQWA10PQi7tDUM3eqMSltXmY+Oyl/7N3P3qNtAlv7X0d9bI28w==" + }, + "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=", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + } + }, + "babel-core": { + "version": "7.0.0-bridge.0", + "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-7.0.0-bridge.0.tgz", + "integrity": "sha512-poPX9mZH/5CSanm50Q+1toVci6pv5KSRv/5TWCwtzQS5XEwn40BcCrgIeMFWP9CKKIniKXNxoIOnOq4VVlGXhg==", + "dev": true + }, + "babel-generator": { + "version": "6.26.1", + "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz", + "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==", + "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" + }, + "dependencies": { + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "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=", + "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" + } + }, + "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=", + "dev": true, + "requires": { + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" + }, + "dependencies": { + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "dev": true + } + } + }, + "babel-helper-evaluate-path": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/babel-helper-evaluate-path/-/babel-helper-evaluate-path-0.4.3.tgz", + "integrity": "sha1-ComvcCwGshcCf6NxkI3UmJ0+Yz8=", + "dev": true + }, + "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" + } + }, + "babel-helper-flip-expressions": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/babel-helper-flip-expressions/-/babel-helper-flip-expressions-0.4.3.tgz", + "integrity": "sha1-NpZzahKKwYvCUlS19AoizrPB0/0=", + "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" + } + }, + "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=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "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" + } + }, + "babel-helper-is-nodes-equiv": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/babel-helper-is-nodes-equiv/-/babel-helper-is-nodes-equiv-0.0.1.tgz", + "integrity": "sha1-NOmzALFHnd2Y7HfqC76TQt/jloQ=", + "dev": true + }, + "babel-helper-is-void-0": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/babel-helper-is-void-0/-/babel-helper-is-void-0-0.4.3.tgz", + "integrity": "sha1-fZwBtFYee5Xb2g9u7kj1tg5nMT4=", + "dev": true + }, + "babel-helper-mark-eval-scopes": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/babel-helper-mark-eval-scopes/-/babel-helper-mark-eval-scopes-0.4.3.tgz", + "integrity": "sha1-0kSjvvmESHJgP/tG4izorN9VFWI=", + "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" + } + }, + "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=", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" + }, + "dependencies": { + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "dev": true + } + } + }, + "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" + } + }, + "babel-helper-remove-or-void": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/babel-helper-remove-or-void/-/babel-helper-remove-or-void-0.4.3.tgz", + "integrity": "sha1-pPA7QAd6D/6I5F0HAQ3uJB/1rmA=", + "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=", + "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" + } + }, + "babel-helper-to-multiple-sequence-expressions": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/babel-helper-to-multiple-sequence-expressions/-/babel-helper-to-multiple-sequence-expressions-0.4.3.tgz", + "integrity": "sha1-W1GLESf0ezA4dzOGoVYaK0jmMrY=", + "dev": true + }, + "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" + } + }, + "babel-jest": { + "version": "23.0.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-23.0.1.tgz", + "integrity": "sha1-u6079SP7IC2gXtCmVAtIyE7tE6Y=", + "dev": true, + "requires": { + "babel-plugin-istanbul": "^4.1.6", + "babel-preset-jest": "^23.0.1" + } + }, + "babel-messages": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", + "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "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": "4.1.6", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-4.1.6.tgz", + "integrity": "sha512-PWP9FQ1AhZhS01T/4qLSKoHGY/xvkZdVBGlKM/HuxxS3+sC66HhTNR7+MpbO/so/cz/wY94MeSWJuP1hXIPfwQ==", + "dev": true, + "requires": { + "babel-plugin-syntax-object-rest-spread": "^6.13.0", + "find-up": "^2.1.0", + "istanbul-lib-instrument": "^1.10.1", + "test-exclude": "^4.2.1" + }, + "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" + } + } + } + }, + "babel-plugin-jest-hoist": { + "version": "23.0.1", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-23.0.1.tgz", + "integrity": "sha1-6qEclkVjrqnCG+zvK994U/fzwUg=", + "dev": true + }, + "babel-plugin-minify-builtins": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-builtins/-/babel-plugin-minify-builtins-0.4.3.tgz", + "integrity": "sha1-nqPVn0rEp7uVjXEtKVVqH4b3+B4=", + "dev": true, + "requires": { + "babel-helper-evaluate-path": "^0.4.3" + } + }, + "babel-plugin-minify-constant-folding": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-constant-folding/-/babel-plugin-minify-constant-folding-0.4.3.tgz", + "integrity": "sha1-MA+d6N2ghEoXaxk2U5YOJK0z4ZE=", + "dev": true, + "requires": { + "babel-helper-evaluate-path": "^0.4.3" + } + }, + "babel-plugin-minify-dead-code-elimination": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-dead-code-elimination/-/babel-plugin-minify-dead-code-elimination-0.4.3.tgz", + "integrity": "sha1-c2KCZYZPkAjQAnUG9Yq+s8HQLZg=", + "dev": true, + "requires": { + "babel-helper-evaluate-path": "^0.4.3", + "babel-helper-mark-eval-scopes": "^0.4.3", + "babel-helper-remove-or-void": "^0.4.3", + "lodash.some": "^4.6.0" + } + }, + "babel-plugin-minify-flip-comparisons": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-flip-comparisons/-/babel-plugin-minify-flip-comparisons-0.4.3.tgz", + "integrity": "sha1-AMqHDLjxO0XAOLPB68DyJyk8llo=", + "dev": true, + "requires": { + "babel-helper-is-void-0": "^0.4.3" + } + }, + "babel-plugin-minify-guarded-expressions": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-guarded-expressions/-/babel-plugin-minify-guarded-expressions-0.4.3.tgz", + "integrity": "sha1-zHCbRFP9IbHzAod0RMifiEJ845c=", + "dev": true, + "requires": { + "babel-helper-flip-expressions": "^0.4.3" + } + }, + "babel-plugin-minify-infinity": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-infinity/-/babel-plugin-minify-infinity-0.4.3.tgz", + "integrity": "sha1-37h2obCKBldjhO8/kuZTumB7Oco=", + "dev": true + }, + "babel-plugin-minify-mangle-names": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-mangle-names/-/babel-plugin-minify-mangle-names-0.4.3.tgz", + "integrity": "sha1-FvG/90t6fJPfwkHngx3V+0sCPvc=", + "dev": true, + "requires": { + "babel-helper-mark-eval-scopes": "^0.4.3" + } + }, + "babel-plugin-minify-numeric-literals": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-numeric-literals/-/babel-plugin-minify-numeric-literals-0.4.3.tgz", + "integrity": "sha1-jk/VYcefeAEob/YOjF/Z3u6TwLw=", + "dev": true + }, + "babel-plugin-minify-replace": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-replace/-/babel-plugin-minify-replace-0.4.3.tgz", + "integrity": "sha1-nSifS6FdTmAR6HmfpfG6d+yBIZ0=", + "dev": true + }, + "babel-plugin-minify-simplify": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-simplify/-/babel-plugin-minify-simplify-0.4.3.tgz", + "integrity": "sha1-N3VthcYURktLCSfytOQXGR1Vc4o=", + "dev": true, + "requires": { + "babel-helper-flip-expressions": "^0.4.3", + "babel-helper-is-nodes-equiv": "^0.0.1", + "babel-helper-to-multiple-sequence-expressions": "^0.4.3" + } + }, + "babel-plugin-minify-type-constructors": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-type-constructors/-/babel-plugin-minify-type-constructors-0.4.3.tgz", + "integrity": "sha1-G8bxW4f3qxCF1CszC3F2V6IVZQA=", + "dev": true, + "requires": { + "babel-helper-is-void-0": "^0.4.3" + } + }, + "babel-plugin-syntax-async-functions": { + "version": "6.13.0", + "resolved": "https://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": "https://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-object-rest-spread": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz", + "integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=", + "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=", + "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=", + "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" + } + }, + "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=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "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" + } + }, + "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=", + "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" + }, + "dependencies": { + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "dev": true + } + } + }, + "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" + } + }, + "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" + } + }, + "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" + } + }, + "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=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "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" + } + }, + "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" + } + }, + "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=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.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=", + "dev": true, + "requires": { + "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "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" + } + }, + "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=", + "dev": true, + "requires": { + "babel-helper-hoist-variables": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "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=", + "dev": true, + "requires": { + "babel-plugin-transform-es2015-modules-amd": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "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=", + "dev": true, + "requires": { + "babel-helper-replace-supers": "^6.24.1", + "babel-runtime": "^6.22.0" + } + }, + "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" + } + }, + "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=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "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=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "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=", + "dev": true, + "requires": { + "babel-helper-regex": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "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=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "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=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.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=", + "dev": true, + "requires": { + "babel-helper-regex": "^6.24.1", + "babel-runtime": "^6.22.0", + "regexpu-core": "^2.0.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=", + "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" + } + }, + "babel-plugin-transform-inline-consecutive-adds": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-inline-consecutive-adds/-/babel-plugin-transform-inline-consecutive-adds-0.4.3.tgz", + "integrity": "sha1-Mj1Ho+pjqDp6w8gRro5pQfrysNE=", + "dev": true + }, + "babel-plugin-transform-member-expression-literals": { + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-member-expression-literals/-/babel-plugin-transform-member-expression-literals-6.9.4.tgz", + "integrity": "sha1-NwOcmgwzE6OUlfqsL/OmtbnQOL8=", + "dev": true + }, + "babel-plugin-transform-merge-sibling-variables": { + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-merge-sibling-variables/-/babel-plugin-transform-merge-sibling-variables-6.9.4.tgz", + "integrity": "sha1-hbQi/DN3tEnJ0c3kQIcgNTJAHa4=", + "dev": true + }, + "babel-plugin-transform-minify-booleans": { + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-minify-booleans/-/babel-plugin-transform-minify-booleans-6.9.4.tgz", + "integrity": "sha1-rLs+VqNVXdI5KOS1gtKFFi3SsZg=", + "dev": true + }, + "babel-plugin-transform-property-literals": { + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-property-literals/-/babel-plugin-transform-property-literals-6.9.4.tgz", + "integrity": "sha1-mMHSHiVXNlc/k+zlRFn2ziSYXTk=", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "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=", + "dev": true, + "requires": { + "regenerator-transform": "^0.10.0" + } + }, + "babel-plugin-transform-regexp-constructors": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-regexp-constructors/-/babel-plugin-transform-regexp-constructors-0.4.3.tgz", + "integrity": "sha1-WLd3W2OvzzMyj66aX4j71PsLSWU=", + "dev": true + }, + "babel-plugin-transform-remove-console": { + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-remove-console/-/babel-plugin-transform-remove-console-6.9.4.tgz", + "integrity": "sha1-uYA2DAZzhOJLNXpYjYB9PINSd4A=", + "dev": true + }, + "babel-plugin-transform-remove-debugger": { + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-remove-debugger/-/babel-plugin-transform-remove-debugger-6.9.4.tgz", + "integrity": "sha1-QrcnYxyXl44estGZp67IShgznvI=", + "dev": true + }, + "babel-plugin-transform-remove-undefined": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-remove-undefined/-/babel-plugin-transform-remove-undefined-0.4.3.tgz", + "integrity": "sha1-1AsNp/kcCMBsxyt2dHTAHEiU3gI=", + "dev": true, + "requires": { + "babel-helper-evaluate-path": "^0.4.3" + } + }, + "babel-plugin-transform-simplify-comparison-operators": { + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-simplify-comparison-operators/-/babel-plugin-transform-simplify-comparison-operators-6.9.4.tgz", + "integrity": "sha1-9ir+CWyrDh9ootdT/fKDiIRxzrk=", + "dev": true + }, + "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=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-undefined-to-void": { + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-undefined-to-void/-/babel-plugin-transform-undefined-to-void-6.9.4.tgz", + "integrity": "sha1-viQcqBQEAwZ4t0hxcyK4nQyP4oA=", + "dev": true + }, + "babel-polyfill": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz", + "integrity": "sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "core-js": "^2.5.0", + "regenerator-runtime": "^0.10.5" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.10.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", + "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=", + "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" + }, + "dependencies": { + "semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", + "dev": true + } + } + }, + "babel-preset-jest": { + "version": "23.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-23.0.1.tgz", + "integrity": "sha1-YxzFRcbPAhlDATvK8i9F2H/mIZg=", + "dev": true, + "requires": { + "babel-plugin-jest-hoist": "^23.0.1", + "babel-plugin-syntax-object-rest-spread": "^6.13.0" + } + }, + "babel-preset-minify": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/babel-preset-minify/-/babel-preset-minify-0.4.3.tgz", + "integrity": "sha1-spw91pGJBThFmPCSuVUVLiah/g8=", + "dev": true, + "requires": { + "babel-plugin-minify-builtins": "^0.4.3", + "babel-plugin-minify-constant-folding": "^0.4.3", + "babel-plugin-minify-dead-code-elimination": "^0.4.3", + "babel-plugin-minify-flip-comparisons": "^0.4.3", + "babel-plugin-minify-guarded-expressions": "^0.4.3", + "babel-plugin-minify-infinity": "^0.4.3", + "babel-plugin-minify-mangle-names": "^0.4.3", + "babel-plugin-minify-numeric-literals": "^0.4.3", + "babel-plugin-minify-replace": "^0.4.3", + "babel-plugin-minify-simplify": "^0.4.3", + "babel-plugin-minify-type-constructors": "^0.4.3", + "babel-plugin-transform-inline-consecutive-adds": "^0.4.3", + "babel-plugin-transform-member-expression-literals": "^6.9.4", + "babel-plugin-transform-merge-sibling-variables": "^6.9.4", + "babel-plugin-transform-minify-booleans": "^6.9.4", + "babel-plugin-transform-property-literals": "^6.9.4", + "babel-plugin-transform-regexp-constructors": "^0.4.3", + "babel-plugin-transform-remove-console": "^6.9.4", + "babel-plugin-transform-remove-debugger": "^6.9.4", + "babel-plugin-transform-remove-undefined": "^0.4.3", + "babel-plugin-transform-simplify-comparison-operators": "^6.9.4", + "babel-plugin-transform-undefined-to-void": "^6.9.4", + "lodash.isplainobject": "^4.0.6" + } + }, + "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" + }, + "dependencies": { + "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" + } + }, + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "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" + } + }, + "babel-template": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", + "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", + "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" + }, + "dependencies": { + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "dev": true + } + } + }, + "babel-traverse": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", + "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", + "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" + }, + "dependencies": { + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "dev": true + } + } + }, + "babel-types": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", + "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "esutils": "^2.0.2", + "lodash": "^4.17.4", + "to-fast-properties": "^1.0.3" + }, + "dependencies": { + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "dev": true + } + } + }, + "babylon": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", + "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", + "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 + }, + "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": { + "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": { + "is-descriptor": "^1.0.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, + "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" + } + }, + "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.1", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", + "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", + "optional": true, + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "before-after-hook": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-1.1.0.tgz", + "integrity": "sha512-VOMDtYPwLbIncTxNoSzRyvaMxtXmLWLUqr8k5AfC1BzLk34HvBXaQX8snOwQZ4c0aX8aSERqtJSiI9/m2u5kuA==", + "dev": true + }, + "binary-extensions": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz", + "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=", + "dev": true, + "optional": true + }, + "bluebird": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", + "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==" + }, + "boom": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz", + "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=", + "requires": { + "hoek": "4.x.x" + } + }, + "bottleneck": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.3.1.tgz", + "integrity": "sha512-6Ktg80l6qMLlNeRpJjtBsBT8UqYXK7ei4eMwUwk9Q4xOEhmP/MTvmjrd+kQ+EMgLiQFkV4HbZp4cUkMn/Yl0nw==", + "dev": true + }, + "boxen": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz", + "integrity": "sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==", + "dev": true, + "requires": { + "ansi-align": "^2.0.0", + "camelcase": "^4.0.0", + "chalk": "^2.0.1", + "cli-boxes": "^1.0.0", + "string-width": "^2.0.0", + "term-size": "^1.2.0", + "widest-line": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.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 + }, + "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 + }, + "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": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "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" + } + }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "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": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "dev": true, + "requires": { + "expand-range": "^1.8.1", + "preserve": "^0.2.0", + "repeat-element": "^1.1.2" + } + }, + "browser-process-hrtime": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-0.1.2.tgz", + "integrity": "sha1-Ql1opY00R/AqBKqJQYf86K+Le44=", + "dev": true + }, + "browser-resolve": { + "version": "1.11.2", + "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.2.tgz", + "integrity": "sha1-j/CbCixCFxihBRwmCzLkj0QpOM4=", + "dev": true, + "requires": { + "resolve": "1.1.7" + } + }, + "browser-stdout": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", + "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", + "dev": true + }, + "browserslist": { + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-3.2.8.tgz", + "integrity": "sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30000844", + "electron-to-chromium": "^1.3.47" + } + }, + "bser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.0.0.tgz", + "integrity": "sha1-mseNPtXZFYBP2HrLFYvHlxR6Fxk=", + "dev": true, + "requires": { + "node-int64": "^0.4.0" + } + }, + "btoa-lite": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/btoa-lite/-/btoa-lite-1.0.0.tgz", + "integrity": "sha1-M3dm2hWAEhD92VbCLpxokaudAzc=", + "dev": true + }, + "buffer-from": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.0.tgz", + "integrity": "sha512-c5mRlguI/Pe2dSZmpER62rSCu0ryKmWddzRYsuXc50U2/g8jMOulc31VZMa4mYx31U5xsmSOpDCgH88Vl9cDGQ==", + "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 + }, + "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": { + "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" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + } + } + }, + "cacheable-request": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-2.1.4.tgz", + "integrity": "sha1-DYCIAbY0KtM8kd+dC0TcCbkeXD0=", + "dev": true, + "requires": { + "clone-response": "1.0.2", + "get-stream": "3.0.0", + "http-cache-semantics": "3.8.1", + "keyv": "3.0.0", + "lowercase-keys": "1.0.0", + "normalize-url": "2.0.1", + "responselike": "1.0.2" + }, + "dependencies": { + "lowercase-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz", + "integrity": "sha1-TjNms55/VFfjXxMkvfb4jQv8cwY=", + "dev": true + }, + "normalize-url": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-2.0.1.tgz", + "integrity": "sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw==", + "dev": true, + "requires": { + "prepend-http": "^2.0.0", + "query-string": "^5.0.1", + "sort-keys": "^2.0.0" + } + } + } + }, + "call-me-maybe": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz", + "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms=", + "dev": true + }, + "caller-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", + "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", + "dev": true, + "requires": { + "callsites": "^0.2.0" + } + }, + "callsites": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", + "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", + "dev": true + }, + "camelcase": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", + "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", + "dev": true, + "optional": true + }, + "caniuse-lite": { + "version": "1.0.30000847", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000847.tgz", + "integrity": "sha512-Weo+tRtVWcN2da782Ebx/27hFNEb+KP+uP6tdqAa+2S5bp1zOJhVH9tEpDygagrfvU4QjeuPwi/5VGsgT4SLaA==", + "dev": true + }, + "capture-exit": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-1.2.0.tgz", + "integrity": "sha1-HF/MSJ/QqwDU8ax64QcuMXP7q28=", + "dev": true, + "requires": { + "rsvp": "^3.3.3" + } + }, + "capture-stack-trace": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.0.tgz", + "integrity": "sha1-Sm+gc5nCa7pH8LJJa00PtAjFVQ0=", + "dev": true + }, + "cardinal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-1.0.0.tgz", + "integrity": "sha1-UOIcGwqjdyn5N33vGWtanOyTLuk=", + "dev": true, + "requires": { + "ansicolors": "~0.2.1", + "redeyed": "~1.0.0" + } + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + }, + "center-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", + "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", + "dev": true, + "optional": true, + "requires": { + "align-text": "^0.1.3", + "lazy-cache": "^1.0.3" + } + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://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" + } + }, + "chardet": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", + "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=", + "dev": true + }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "dev": true + }, + "ci-info": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.1.3.tgz", + "integrity": "sha512-SK/846h/Rcy8q9Z9CAwGBLfCJ6EkjJWdpelWDufQpqVDYq2Wnnv8zlSO6AMQap02jvhVruKKpEtQOufo3pFhLg==", + "dev": true + }, + "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" + }, + "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" + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + } + } + }, + "clean-stack": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-1.3.0.tgz", + "integrity": "sha1-noIVAa6XmYbEax1m0tQy2y/UrjE=", + "dev": true + }, + "cli-boxes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz", + "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM=", + "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-table": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cli-table/-/cli-table-0.3.1.tgz", + "integrity": "sha1-9TsFJmqLGguTSz0IIebi3FkUriM=", + "dev": true, + "requires": { + "colors": "1.0.3" + }, + "dependencies": { + "colors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", + "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=", + "dev": true + } + } + }, + "cli-table2": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/cli-table2/-/cli-table2-0.2.0.tgz", + "integrity": "sha1-LR738hig54biFFQFYtS9F3/jLZc=", + "requires": { + "colors": "^1.1.2", + "lodash": "^3.10.1", + "string-width": "^1.0.1" + } + }, + "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 + }, + "cliui": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", + "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", + "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", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", + "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", + "dev": true, + "optional": true + } + } + }, + "clone-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", + "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "dev": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" + }, + "codecov": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/codecov/-/codecov-3.0.2.tgz", + "integrity": "sha512-9ljtIROIjPIUmMRqO+XuDITDoV8xRrZmA0jcEq6p2hg2+wY9wGmLfreAZGIL72IzUfdEDZaU8+Vjidg1fBQ8GQ==", + "dev": true, + "requires": { + "argv": "0.0.2", + "request": "^2.81.0", + "urlgrey": "0.4.4" + } + }, + "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.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", + "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", + "dev": true, + "requires": { + "color-name": "^1.1.1" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "colors": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.2.4.tgz", + "integrity": "sha512-6Y+iBnWmXL+AWtlOp2Vr6R2w5MUlNJRwR0ShVFaAb1CqWzhPOpQg4L0jxD+xpw/Nc8QJwaq3KM79QUCriY8CWQ==" + }, + "combined-stream": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", + "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commander": { + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", + "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==" + }, + "compare-func": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-1.3.2.tgz", + "integrity": "sha1-md0LpFfh+bxyKxLAjsM+6rMfpkg=", + "dev": true, + "requires": { + "array-ify": "^1.0.0", + "dot-prop": "^3.0.0" + } + }, + "compare-versions": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.1.0.tgz", + "integrity": "sha512-4hAxDSBypT/yp2ySFD346So6Ragw5xmBn/e/agIGl3bZr6DLUqnoRZPusxKrXdYRZpgexO9daejmIenlq/wrIQ==", + "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 + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "configstore": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.2.tgz", + "integrity": "sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw==", + "dev": true, + "requires": { + "dot-prop": "^4.1.0", + "graceful-fs": "^4.1.2", + "make-dir": "^1.0.0", + "unique-string": "^1.0.0", + "write-file-atomic": "^2.0.0", + "xdg-basedir": "^3.0.0" + }, + "dependencies": { + "dot-prop": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", + "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==", + "dev": true, + "requires": { + "is-obj": "^1.0.0" + } + } + } + }, + "contains-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", + "dev": true + }, + "conventional-changelog-angular": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-3.0.7.tgz", + "integrity": "sha512-I1W7Vr/2AFlwhrjvjhp8Tz61qsRWc/dL96kgMmAwkJw/eVLLTokbuYnyYQ8k+/Loy2na8C18yD0SOkE/1AmIsw==", + "dev": true, + "requires": { + "compare-func": "^1.3.1", + "q": "^1.5.1" + } + }, + "conventional-changelog-writer": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-3.0.9.tgz", + "integrity": "sha512-n9KbsxlJxRQsUnK6wIBRnARacvNnN4C/nxnxCkH+B/R1JS2Fa+DiP1dU4I59mEDEjgnFaN2+9wr1P1s7GYB5/Q==", + "dev": true, + "requires": { + "compare-func": "^1.3.1", + "conventional-commits-filter": "^1.1.6", + "dateformat": "^3.0.0", + "handlebars": "^4.0.2", + "json-stringify-safe": "^5.0.1", + "lodash": "^4.2.1", + "meow": "^4.0.0", + "semver": "^5.5.0", + "split": "^1.0.0", + "through2": "^2.0.0" + }, + "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 + }, + "camelcase-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-4.2.0.tgz", + "integrity": "sha1-oqpfsa9oh1glnDLBQUJteJI7m3c=", + "dev": true, + "requires": { + "camelcase": "^4.1.0", + "map-obj": "^2.0.0", + "quick-lru": "^1.0.0" + } + }, + "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" + } + }, + "indent-string": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", + "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=", + "dev": true + }, + "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" + } + }, + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "dev": true + }, + "map-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-2.0.0.tgz", + "integrity": "sha1-plzSkIepJZi4eRJXpSPgISIqwfk=", + "dev": true + }, + "meow": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/meow/-/meow-4.0.1.tgz", + "integrity": "sha512-xcSBHD5Z86zaOc+781KrupuHAzeGXSLtiAOmBsiLDiPSaYSB6hdew2ng9EBAnZ62jagG9MHAOdxpDi/lWBFJ/A==", + "dev": true, + "requires": { + "camelcase-keys": "^4.0.0", + "decamelize-keys": "^1.0.0", + "loud-rejection": "^1.0.0", + "minimist": "^1.1.3", + "minimist-options": "^3.0.1", + "normalize-package-data": "^2.3.4", + "read-pkg-up": "^3.0.0", + "redent": "^2.0.0", + "trim-newlines": "^2.0.0" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "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-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": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "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": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", + "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^3.0.0" + } + }, + "redent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-2.0.0.tgz", + "integrity": "sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo=", + "dev": true, + "requires": { + "indent-string": "^3.0.0", + "strip-indent": "^2.0.0" + } + }, + "semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", + "dev": true + }, + "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-indent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", + "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=", + "dev": true + }, + "trim-newlines": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-2.0.0.tgz", + "integrity": "sha1-tAPQuRvlDDMd/EuC7s6yLD3hbSA=", + "dev": true + } + } + }, + "conventional-commits-filter": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-1.1.6.tgz", + "integrity": "sha512-KcDgtCRKJCQhyk6VLT7zR+ZOyCnerfemE/CsR3iQpzRRFbLEs0Y6rwk3mpDvtOh04X223z+1xyJ582Stfct/0Q==", + "dev": true, + "requires": { + "is-subset": "^0.1.1", + "modify-values": "^1.0.0" + } + }, + "conventional-commits-parser": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-2.1.7.tgz", + "integrity": "sha512-BoMaddIEJ6B4QVMSDu9IkVImlGOSGA1I2BQyOZHeLQ6qVOJLcLKn97+fL6dGbzWEiqDzfH4OkcveULmeq2MHFQ==", + "dev": true, + "requires": { + "JSONStream": "^1.0.4", + "is-text-path": "^1.0.0", + "lodash": "^4.2.1", + "meow": "^4.0.0", + "split2": "^2.0.0", + "through2": "^2.0.0", + "trim-off-newlines": "^1.0.0" + }, + "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 + }, + "camelcase-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-4.2.0.tgz", + "integrity": "sha1-oqpfsa9oh1glnDLBQUJteJI7m3c=", + "dev": true, + "requires": { + "camelcase": "^4.1.0", + "map-obj": "^2.0.0", + "quick-lru": "^1.0.0" + } + }, + "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" + } + }, + "indent-string": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", + "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=", + "dev": true + }, + "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" + } + }, + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "dev": true + }, + "map-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-2.0.0.tgz", + "integrity": "sha1-plzSkIepJZi4eRJXpSPgISIqwfk=", + "dev": true + }, + "meow": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/meow/-/meow-4.0.1.tgz", + "integrity": "sha512-xcSBHD5Z86zaOc+781KrupuHAzeGXSLtiAOmBsiLDiPSaYSB6hdew2ng9EBAnZ62jagG9MHAOdxpDi/lWBFJ/A==", + "dev": true, + "requires": { + "camelcase-keys": "^4.0.0", + "decamelize-keys": "^1.0.0", + "loud-rejection": "^1.0.0", + "minimist": "^1.1.3", + "minimist-options": "^3.0.1", + "normalize-package-data": "^2.3.4", + "read-pkg-up": "^3.0.0", + "redent": "^2.0.0", + "trim-newlines": "^2.0.0" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "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-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": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "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": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", + "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^3.0.0" + } + }, + "redent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-2.0.0.tgz", + "integrity": "sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo=", + "dev": true, + "requires": { + "indent-string": "^3.0.0", + "strip-indent": "^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-indent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", + "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=", + "dev": true + }, + "trim-newlines": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-2.0.0.tgz", + "integrity": "sha1-tAPQuRvlDDMd/EuC7s6yLD3hbSA=", + "dev": true + } + } + }, + "convert-source-map": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.1.tgz", + "integrity": "sha1-uCeAl7m8IpNl3lxiz1/K7YtVmeU=", + "dev": true + }, + "convert-units": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/convert-units/-/convert-units-2.3.4.tgz", + "integrity": "sha512-ERHfdA0UhHJp1IpwE6PnFJx8LqG7B1ZjJ20UvVCmopEnVCfER68Tbe3kvN63dLbYXDA2xFWRE6zd4Wsf0w7POg==", + "requires": { + "lodash.foreach": "2.3.x", + "lodash.keys": "2.3.x" + } + }, + "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.6", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.6.tgz", + "integrity": "sha512-lQUVfQi0aLix2xpyjrrJEvfuYCqPc/HwmTKsC/VNf8q0zsjX7SQZtp4+oRONN5Tsur9GDETPjj+Ub2iDiGZfSQ==" + }, + "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=" + }, + "cosmiconfig": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.0.5.tgz", + "integrity": "sha512-94j37OtvxS5w7qr7Ta6dt67tWdnOxigBVN4VnSxNXFez9o18PGQ0D33SchKP17r9LAcWVTYV72G6vDayAUBFIg==", + "dev": true, + "requires": { + "is-directory": "^0.3.1", + "js-yaml": "^3.9.0", + "parse-json": "^4.0.0" + }, + "dependencies": { + "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" + } + } + } + }, + "create-error-class": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz", + "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=", + "dev": true, + "requires": { + "capture-stack-trace": "^1.0.0" + } + }, + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "dev": true, + "requires": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "dependencies": { + "lru-cache": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz", + "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==", + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + } + } + }, + "cryptiles": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz", + "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=", + "requires": { + "boom": "5.x.x" + }, + "dependencies": { + "boom": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz", + "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==", + "requires": { + "hoek": "4.x.x" + } + } + } + }, + "crypto-random-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz", + "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=", + "dev": true + }, + "cssom": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.2.tgz", + "integrity": "sha1-uANhcMefB6kP8vFuIihAJ6JDhIs=", + "dev": true + }, + "cssstyle": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-0.3.1.tgz", + "integrity": "sha512-tNvaxM5blOnxanyxI6panOsnfiyLRj3HV4qjqqS45WPNS1usdYWRUQjqTEEELK73lpeP/1KoIGYUwrBn/VcECA==", + "dev": true, + "requires": { + "cssom": "0.3.x" + } + }, + "currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "dev": true, + "requires": { + "array-find-index": "^1.0.1" + } + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "data-urls": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.0.0.tgz", + "integrity": "sha512-ai40PPQR0Fn1lD2PPie79CibnlMN2AYiDhwFX/rZHVsxbs5kNJSjegqXIprhouGXlRdEnfybva7kqRGnB6mypA==", + "dev": true, + "requires": { + "abab": "^1.0.4", + "whatwg-mimetype": "^2.0.0", + "whatwg-url": "^6.4.0" + } + }, + "dateformat": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", + "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", + "dev": true + }, + "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" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "decamelize-keys": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz", + "integrity": "sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=", + "dev": true, + "requires": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + } + }, + "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 + }, + "decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "dev": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, + "deep-extend": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.5.1.tgz", + "integrity": "sha512-N8vBdOa+DF7zkRrDCsaOXoCs/E2fJfx9B9MrKnnSiHNh4ws7eSys6YQE4KvT1cecKmOASYQBhbKjeuDD9lT81w==", + "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 + }, + "default-require-extensions": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-1.0.0.tgz", + "integrity": "sha1-836hXT4T/9m0N9M+GnW1+5eHTLg=", + "dev": true, + "requires": { + "strip-bom": "^2.0.0" + } + }, + "define-properties": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", + "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=", + "dev": true, + "requires": { + "foreach": "^2.0.5", + "object-keys": "^1.0.8" + } + }, + "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==", + "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" + } + }, + "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 + } + } + }, + "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=" + }, + "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" + } + }, + "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 + }, + "dir-glob": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.0.0.tgz", + "integrity": "sha512-37qirFDz8cA5fimp9feo43fSuRo2gHwaIn6dXL8Ber1dGwUosDrGZeCCXq57WnIqE4aQ+u3eQZzsk1yOzhdwag==", + "dev": true, + "requires": { + "arrify": "^1.0.1", + "path-type": "^3.0.0" + }, + "dependencies": { + "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": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "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" + } + }, + "domexception": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz", + "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==", + "dev": true, + "requires": { + "webidl-conversions": "^4.0.2" + } + }, + "dot-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-3.0.0.tgz", + "integrity": "sha1-G3CK8JSknJoOfbyteQq6U52sEXc=", + "dev": true, + "requires": { + "is-obj": "^1.0.0" + } + }, + "duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", + "dev": true, + "requires": { + "readable-stream": "^2.0.2" + } + }, + "duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", + "dev": true + }, + "ecc-jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", + "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", + "optional": true, + "requires": { + "jsbn": "~0.1.0" + } + }, + "electron-to-chromium": { + "version": "1.3.48", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.48.tgz", + "integrity": "sha1-07DYWTgUBE4JLs4hCPw6ya6kuQA=", + "dev": true + }, + "enumify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/enumify/-/enumify-1.0.4.tgz", + "integrity": "sha1-K7YmMHHdRVHlTFV1Vwf60kpAzX4=" + }, + "env-ci": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/env-ci/-/env-ci-2.1.0.tgz", + "integrity": "sha512-ekorGVu0ubSzShUdyALj9y/4GRyaupvf8yKgbUDvR8FClHpVmg36v0oYzZj2MsZh44T80PcUWzcwkhbsR+eyvw==", + "dev": true, + "requires": { + "execa": "^0.10.0", + "java-properties": "^0.2.9" + }, + "dependencies": { + "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" + } + }, + "execa": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.10.0.tgz", + "integrity": "sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "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" + } + }, + "semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", + "dev": true + } + } + }, + "error-ex": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", + "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es-abstract": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.12.0.tgz", + "integrity": "sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA==", + "dev": true, + "requires": { + "es-to-primitive": "^1.1.1", + "function-bind": "^1.1.1", + "has": "^1.0.1", + "is-callable": "^1.1.3", + "is-regex": "^1.0.4" + } + }, + "es-to-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz", + "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=", + "dev": true, + "requires": { + "is-callable": "^1.1.1", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.1" + } + }, + "es6-promise": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.4.tgz", + "integrity": "sha512-/NdNZVJg+uZgtm9eS3O6lrOLYmQag2DjdEXuPaHlZ6RuVqgqaVZfgYCepEIKsLqwdQArOPtC3XzRLqGGfT8KQQ==", + "dev": true + }, + "es6-promisify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", + "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", + "dev": true, + "requires": { + "es6-promise": "^4.0.3" + } + }, + "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": "4.19.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.19.1.tgz", + "integrity": "sha512-bT3/1x1EbZB7phzYu7vCr1v3ONuzDtX8WjuM9c0iYxe+cq+pwcKEoQjl7zd3RpC6YOLgnSy3cTN58M2jcoPDIQ==", + "dev": true, + "requires": { + "ajv": "^5.3.0", + "babel-code-frame": "^6.22.0", + "chalk": "^2.1.0", + "concat-stream": "^1.6.0", + "cross-spawn": "^5.1.0", + "debug": "^3.1.0", + "doctrine": "^2.1.0", + "eslint-scope": "^3.7.1", + "eslint-visitor-keys": "^1.0.0", + "espree": "^3.5.4", + "esquery": "^1.0.0", + "esutils": "^2.0.2", + "file-entry-cache": "^2.0.0", + "functional-red-black-tree": "^1.0.1", + "glob": "^7.1.2", + "globals": "^11.0.1", + "ignore": "^3.3.3", + "imurmurhash": "^0.1.4", + "inquirer": "^3.0.6", + "is-resolvable": "^1.0.0", + "js-yaml": "^3.9.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.4", + "minimatch": "^3.0.2", + "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": "^1.0.1", + "require-uncached": "^1.0.3", + "semver": "^5.3.0", + "strip-ansi": "^4.0.0", + "strip-json-comments": "~2.0.1", + "table": "4.0.2", + "text-table": "~0.2.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "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" + } + }, + "globals": { + "version": "11.5.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.5.0.tgz", + "integrity": "sha512-hYyf+kI8dm3nORsiiXUQigOU62hDLfJ9G01uyGMxhc6BKsircrUhC4uJPQPUSuq2GrTmiiEt7ewxlMdBewfmKQ==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "dev": true + }, + "semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", + "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" + } + }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "eslint-config-airbnb-base": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-12.1.0.tgz", + "integrity": "sha512-/vjm0Px5ZCpmJqnjIzcFb9TKZrKWz0gnuG/7Gfkt0Db1ELJR51xkZth+t14rYdqWgX836XbuxtArbIHlVhbLBA==", + "dev": true, + "requires": { + "eslint-restricted-globals": "^0.1.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": { + "resolve": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.7.1.tgz", + "integrity": "sha512-c7rwLofp8g1U+h1KNyHL/jicrKg1Ek4q+Lr33AL65uZTinUZHe30D5HlyN5V9NW0JX1D5dXQ4jqW5l7Sy/kGfw==", + "dev": true, + "requires": { + "path-parse": "^1.0.5" + } + } + } + }, + "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" + } + }, + "eslint-plugin-import": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.11.0.tgz", + "integrity": "sha1-Fa7qN6Z0mdhI6OmBgG1GJ7VQOBY=", + "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": { + "doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "isarray": "^1.0.0" + } + }, + "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" + } + }, + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "dev": true + }, + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "requires": { + "pify": "^2.0.0" + } + }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "requires": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.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=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" + } + }, + "resolve": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.7.1.tgz", + "integrity": "sha512-c7rwLofp8g1U+h1KNyHL/jicrKg1Ek4q+Lr33AL65uZTinUZHe30D5HlyN5V9NW0JX1D5dXQ4jqW5l7Sy/kGfw==", + "dev": true, + "requires": { + "path-parse": "^1.0.5" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + } + } + }, + "eslint-restricted-globals": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/eslint-restricted-globals/-/eslint-restricted-globals-0.1.1.tgz", + "integrity": "sha1-NfDVy8ZMLj7WLpO0saevBbp+1Nc=", + "dev": true + }, + "eslint-scope": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz", + "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + }, + "dependencies": { + "estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "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": "3.5.4", + "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", + "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", + "dev": true, + "requires": { + "acorn": "^5.5.0", + "acorn-jsx": "^3.0.0" + } + }, + "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" + }, + "dependencies": { + "estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "dev": true + } + } + }, + "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" + }, + "dependencies": { + "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 + }, + "exec-sh": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.2.1.tgz", + "integrity": "sha512-aLt95pexaugVtQerpmE51+4QfWrNc304uez7jvj6fWnN8GeEHpttB8F36n8N7uVhUMbH/1enbxQ9HImZ4w/9qg==", + "dev": true, + "requires": { + "merge": "^1.1.3" + } + }, + "execa": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", + "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "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" + } + }, + "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": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "dev": 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, + "requires": { + "fill-range": "^2.1.0" + } + }, + "expect": { + "version": "22.4.3", + "resolved": "https://registry.npmjs.org/expect/-/expect-22.4.3.tgz", + "integrity": "sha512-XcNXEPehqn8b/jm8FYotdX0YrXn36qp4HWlrVT4ktwQas1l1LPxiVWncYnnL2eyMtKAmVIaG0XAp0QlrqJaxaA==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "jest-diff": "^22.4.3", + "jest-get-type": "^22.4.3", + "jest-matcher-utils": "^22.4.3", + "jest-message-util": "^22.4.3", + "jest-regex-util": "^22.4.3" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + } + } + }, + "extend": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", + "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=" + }, + "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" + } + } + } + }, + "external-editor": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz", + "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==", + "dev": true, + "requires": { + "chardet": "^0.4.0", + "iconv-lite": "^0.4.17", + "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, + "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=" + }, + "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=" + }, + "fast-glob": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.2.tgz", + "integrity": "sha512-TR6zxCKftDQnUAPvkrCWdBgDq/gbqx8A3ApnBrR5rMvpp6+KMJI0Igw7fkWPgeVK0uhRXTXdvO3O+YP0CaUX2g==", + "dev": true, + "requires": { + "@mrmlnc/readdir-enhanced": "^2.2.1", + "@nodelib/fs.stat": "^1.0.1", + "glob-parent": "^3.1.0", + "is-glob": "^4.0.0", + "merge2": "^1.2.1", + "micromatch": "^3.1.10" + }, + "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 + }, + "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" + } + } + } + }, + "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": { + "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, + "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, + "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, + "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-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, + "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-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, + "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 + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": 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, + "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, + "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, + "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, + "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, + "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" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "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, + "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=", + "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 + }, + "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" + } + } + } + }, + "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=" + }, + "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 + }, + "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": { + "bser": "^2.0.0" + } + }, + "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 + }, + "fill-range": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz", + "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", + "dev": true, + "requires": { + "is-number": "^2.1.0", + "isobject": "^2.0.0", + "randomatic": "^1.1.3", + "repeat-element": "^1.1.2", + "repeat-string": "^1.5.2" + } + }, + "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" + } + }, + "find-versions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-2.0.0.tgz", + "integrity": "sha1-KtkNSQ9oKMGqQCks9wmsMxghDDw=", + "dev": true, + "requires": { + "array-uniq": "^1.0.0", + "semver-regex": "^1.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, + "requires": { + "for-in": "^1.0.1" + } + }, + "foreach": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", + "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", + "dev": true + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + }, + "form-data": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz", + "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "1.0.6", + "mime-types": "^2.1.12" + } + }, + "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" + } + }, + "from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + } + }, + "fs-copy-file-sync": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/fs-copy-file-sync/-/fs-copy-file-sync-1.1.1.tgz", + "integrity": "sha512-2QY5eeqVv4m2PfyMiEuy9adxNP+ajf+8AR05cEi+OAzPcOj90hvFImeZhTmKLBgSd9EvG33jsD7ZRxsx9dThkQ==", + "dev": true + }, + "fs-extra": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-6.0.1.tgz", + "integrity": "sha512-GnyIkKhhzXZUWFCaJzvyDLEEgDkPfb4/TPvJCJVuS8MWZgoSsErf++QpiAlDnKFcqhRlm+tIOcencCjyJE6ZCA==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "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", + "bundled": true, + "dev": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "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" + } + }, + "chownr": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": 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", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ms": "2.0.0" + } + }, + "deep-extend": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "optional": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "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": { + "minipass": "^2.2.1" + } + }, + "fs.realpath": { + "version": "1.0.0", + "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", + "bundled": true, + "dev": true, + "optional": true + }, + "iconv-lite": { + "version": "0.4.21", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safer-buffer": "^2.1.0" + } + }, + "ignore-walk": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "dev": true + }, + "ini": { + "version": "1.3.5", + "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", + "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", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "^5.1.1", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "needle": { + "version": "2.2.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "debug": "^2.1.2", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.10.0", + "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" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.0.3", + "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", + "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" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "os-tmpdir": { + "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", + "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 + } + } + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "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=", + "dev": true + }, + "get-caller-file": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz", + "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=", + "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": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "git-log-parser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/git-log-parser/-/git-log-parser-1.2.0.tgz", + "integrity": "sha1-LmpMGxP8AAKCB7p5WnrDFme5/Uo=", + "dev": true, + "requires": { + "argv-formatter": "~1.0.0", + "spawn-error-forwarder": "~1.0.0", + "split2": "~1.0.0", + "stream-combiner2": "~1.1.1", + "through2": "~2.0.0", + "traverse": "~0.6.6" + }, + "dependencies": { + "split2": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-1.0.0.tgz", + "integrity": "sha1-UuLiIdiMdfmnP5BVbiY/+WdysxQ=", + "dev": true, + "requires": { + "through2": "~2.0.0" + } + } + } + }, + "git-up": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/git-up/-/git-up-2.0.10.tgz", + "integrity": "sha512-2v4UN3qV2RGypD9QpmUjpk+4+RlYpW8GFuiZqQnKmvei08HsFPd0RfbDvEhnE4wBvnYs8ORVtYpOFuuCEmBVBw==", + "dev": true, + "requires": { + "is-ssh": "^1.3.0", + "parse-url": "^1.3.0" + } + }, + "git-url-parse": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/git-url-parse/-/git-url-parse-9.0.1.tgz", + "integrity": "sha512-HDXfw3X5PZaPBRFxELatfoYCV4EaYkAGmIApnnAaVPFCJBkpfWTB2/hhQcK0dVX+MsKnkL5uAn30Lfu2KUKLmg==", + "dev": true, + "requires": { + "git-up": "^2.0.0", + "parse-domain": "^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" + } + }, + "glob-base": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", + "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", + "dev": 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" + } + }, + "glob-to-regexp": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz", + "integrity": "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=", + "dev": true + }, + "global-dirs": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", + "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=", + "dev": true, + "requires": { + "ini": "^1.3.4" + } + }, + "globals": { + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", + "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", + "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" + } + }, + "got": { + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/got/-/got-8.3.1.tgz", + "integrity": "sha512-tiLX+bnYm5A56T5N/n9Xo89vMaO1mrS9qoDqj3u/anVooqGozvY/HbXzEpDfbNeKsHCBpK40gSbz8wGYSp3i1w==", + "dev": true, + "requires": { + "@sindresorhus/is": "^0.7.0", + "cacheable-request": "^2.1.1", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "into-stream": "^3.1.0", + "is-retry-allowed": "^1.1.0", + "isurl": "^1.0.0-alpha5", + "lowercase-keys": "^1.0.0", + "mimic-response": "^1.0.0", + "p-cancelable": "^0.4.0", + "p-timeout": "^2.0.1", + "pify": "^3.0.0", + "safe-buffer": "^5.1.1", + "timed-out": "^4.0.1", + "url-parse-lax": "^3.0.0", + "url-to-options": "^1.0.1" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + } + } + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "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.0.11", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.11.tgz", + "integrity": "sha1-Ywo13+ApS8KB7a5v/F0yn8eYLcw=", + "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", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", + "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", + "dev": true, + "requires": { + "amdefine": ">=0.0.4" + } + } + } + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" + }, + "har-validator": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", + "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", + "requires": { + "ajv": "^5.1.0", + "har-schema": "^2.0.0" + } + }, + "has": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz", + "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=", + "dev": true, + "requires": { + "function-bind": "^1.0.2" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true + }, + "has-symbol-support-x": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz", + "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==", + "dev": true + }, + "has-to-string-tag-x": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz", + "integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==", + "dev": true, + "requires": { + "has-symbol-support-x": "^1.4.1" + } + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "requires": { + "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": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "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", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "hawk": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz", + "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==", + "requires": { + "boom": "4.x.x", + "cryptiles": "3.x.x", + "hoek": "4.x.x", + "sntp": "2.x.x" + } + }, + "he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", + "dev": true + }, + "hoek": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz", + "integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==" + }, + "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=", + "dev": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.1" + } + }, + "hook-std": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/hook-std/-/hook-std-0.4.0.tgz", + "integrity": "sha1-+osvhNNYdjE3y30X4zCLKHFL0XQ=", + "dev": true + }, + "hosted-git-info": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.6.0.tgz", + "integrity": "sha512-lIbgIIQA3lz5XaB6vxakj6sDHADJiZadYEJB+FgA+C4nubM1NwcuvUr9EJPmnH1skZqpqUzWborWo8EIUi0Sdw==", + "dev": true + }, + "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": { + "whatwg-encoding": "^1.0.1" + } + }, + "http-cache-semantics": { + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz", + "integrity": "sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==", + "dev": true + }, + "http-proxy-agent": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", + "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", + "dev": true, + "requires": { + "agent-base": "4", + "debug": "3.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" + } + } + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "https-proxy-agent": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz", + "integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==", + "dev": true, + "requires": { + "agent-base": "^4.1.0", + "debug": "^3.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" + } + } + } + }, + "husky": { + "version": "0.14.3", + "resolved": "https://registry.npmjs.org/husky/-/husky-0.14.3.tgz", + "integrity": "sha512-e21wivqHpstpoiWA/Yi8eFti8E+sQDSS53cpJsPptPs295QTOQR0ZwnHo2TXy1XOpZFD9rPOd3NpmqTK6uMLJA==", + "dev": true, + "requires": { + "is-ci": "^1.0.10", + "normalize-path": "^1.0.0", + "strip-indent": "^2.0.0" + }, + "dependencies": { + "normalize-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-1.0.0.tgz", + "integrity": "sha1-MtDkcvkf80VwHBWoMRAY07CpA3k=", + "dev": true + }, + "strip-indent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", + "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=", + "dev": true + } + } + }, + "iconv-lite": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", + "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==", + "dev": true + }, + "ignore": { + "version": "3.3.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.8.tgz", + "integrity": "sha512-pUh+xUQQhQzevjRHHFqqcTy0/dP/kS9I8HSrUydhihjuD09W6ldVWFtIrwhXdUJHis3i2rZNqEHpZH/cbinFbg==", + "dev": true + }, + "immutable": { + "version": "3.8.2", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.8.2.tgz", + "integrity": "sha1-wkOZUUVbs5kT2vKBN28VMOEErfM=" + }, + "import-from": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-from/-/import-from-2.1.0.tgz", + "integrity": "sha1-M1238qev/VOqpHHUuAId7ja387E=", + "dev": true, + "requires": { + "resolve-from": "^3.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true + } + } + }, + "import-lazy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", + "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", + "dev": true + }, + "import-local": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-1.0.0.tgz", + "integrity": "sha512-vAaZHieK9qjGo58agRBg+bhHX3hoTZU/Oa3GESWLz7t1U62fk63aHuDJJEteXoDeTCcPmUT+z38gkHPZkkmpmQ==", + "dev": true, + "requires": { + "pkg-dir": "^2.0.0", + "resolve-cwd": "^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" + } + }, + "pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dev": true, + "requires": { + "find-up": "^2.1.0" + } + } + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "dev": true + }, + "inquirer": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", + "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", + "dev": true, + "requires": { + "ansi-escapes": "^3.0.0", + "chalk": "^2.0.0", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^2.0.4", + "figures": "^2.0.0", + "lodash": "^4.3.0", + "mute-stream": "0.0.7", + "run-async": "^2.2.0", + "rx-lite": "^4.0.8", + "rx-lite-aggregates": "^4.0.8", + "string-width": "^2.1.0", + "strip-ansi": "^4.0.0", + "through": "^2.3.6" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.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 + }, + "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 + }, + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "dev": true + }, + "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": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "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" + } + }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "into-stream": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-3.1.0.tgz", + "integrity": "sha1-lvsKk2wSur1v8XUqF9BWFqvQlMY=", + "dev": true, + "requires": { + "from2": "^2.1.1", + "p-is-promise": "^1.1.0" + } + }, + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dev": true, + "requires": { + "loose-envify": "^1.0.0" + } + }, + "invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", + "dev": true + }, + "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, + "requires": { + "kind-of": "^3.0.2" + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "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": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", + "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", + "dev": true, + "requires": { + "builtin-modules": "^1.0.0" + } + }, + "is-callable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.3.tgz", + "integrity": "sha1-hut1OSgF3cM69xySoO7fdO52BLI=", + "dev": true + }, + "is-ci": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.1.0.tgz", + "integrity": "sha512-c7TnwxLePuqIlxHgr7xtxzycJPegNHFuIrBkwbf8hc58//+Op1CqFkyS+xnIMkwn9UsJIwc174BIjkyBmSpjKg==", + "dev": true, + "requires": { + "ci-info": "^1.0.0" + } + }, + "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, + "requires": { + "kind-of": "^3.0.2" + } + }, + "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", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "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 + } + } + }, + "is-directory": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", + "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", + "dev": true + }, + "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 + }, + "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, + "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": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "is-generator-fn": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-1.0.0.tgz", + "integrity": "sha1-lp1J4bszKfa7fwkIm+JleLLd1Go=", + "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-installed-globally": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz", + "integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=", + "dev": true, + "requires": { + "global-dirs": "^0.1.0", + "is-path-inside": "^1.0.0" + } + }, + "is-npm": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz", + "integrity": "sha1-8vtjpl5JBbQGyGBydloaTceTufQ=", + "dev": true + }, + "is-number": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", + "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", + "dev": true + }, + "is-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.1.tgz", + "integrity": "sha1-iVJojF7C/9awPsyF52ngKQMINHA=", + "dev": true + }, + "is-odd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-odd/-/is-odd-2.0.0.tgz", + "integrity": "sha512-OTiixgpZAT1M4NHgS5IguFp/Vz2VI3U7Goh4/HA1adtwyLtSBrxYlcSYkhpAE07s4fKEcjrFxyvtQBND4vFQyQ==", + "dev": true, + "requires": { + "is-number": "^4.0.0" + }, + "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 + } + } + }, + "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=", + "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=", + "dev": true, + "requires": { + "path-is-inside": "^1.0.1" + } + }, + "is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "dev": true + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "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 + }, + "is-primitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", + "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", + "dev": 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 + }, + "is-redirect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", + "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=", + "dev": true + }, + "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, + "requires": { + "has": "^1.0.1" + } + }, + "is-resolvable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", + "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", + "dev": true + }, + "is-retry-allowed": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz", + "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=", + "dev": true + }, + "is-ssh": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/is-ssh/-/is-ssh-1.3.0.tgz", + "integrity": "sha1-6+oRaaJhTaOSpjdANmw84EnY3/Y=", + "dev": true, + "requires": { + "protocols": "^1.1.0" + } + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "is-subset": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-subset/-/is-subset-0.1.1.tgz", + "integrity": "sha1-ilkRfZMt4d4A8kX83TnOQ/HpOaY=", + "dev": true + }, + "is-symbol": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz", + "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=", + "dev": true + }, + "is-text-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz", + "integrity": "sha1-Thqg+1G/vLPpJogAE5cgLBd1tm4=", + "dev": true, + "requires": { + "text-extensions": "^1.0.0" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + }, + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", + "dev": true + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "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, + "requires": { + "isarray": "1.0.0" + } + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + }, + "issue-parser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/issue-parser/-/issue-parser-2.0.0.tgz", + "integrity": "sha512-+dBeNWTdqfC4GX+xJMFmLuzYxY/ve9tUxU1V1INcdq+7c2bbTEojrk14vli1JcGzI0tFCXrF8Ys3hX8J+1NVjw==", + "dev": true, + "requires": { + "lodash": "^4.17.4" + }, + "dependencies": { + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "dev": true + } + } + }, + "istanbul-api": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/istanbul-api/-/istanbul-api-1.3.1.tgz", + "integrity": "sha512-duj6AlLcsWNwUpfyfHt0nWIeRiZpuShnP40YTxOGQgtaN8fd6JYSxsvxUphTDy8V5MfDXo4s/xVCIIvVCO808g==", + "dev": true, + "requires": { + "async": "^2.1.4", + "compare-versions": "^3.1.0", + "fileset": "^2.0.2", + "istanbul-lib-coverage": "^1.2.0", + "istanbul-lib-hook": "^1.2.0", + "istanbul-lib-instrument": "^1.10.1", + "istanbul-lib-report": "^1.1.4", + "istanbul-lib-source-maps": "^1.2.4", + "istanbul-reports": "^1.3.0", + "js-yaml": "^3.7.0", + "mkdirp": "^0.5.1", + "once": "^1.4.0" + }, + "dependencies": { + "async": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", + "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", + "dev": true, + "requires": { + "lodash": "^4.14.0" + } + }, + "fileset": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/fileset/-/fileset-2.0.3.tgz", + "integrity": "sha1-jnVIqW08wjJ+5eZ0FocjozO7oqA=", + "dev": true, + "requires": { + "glob": "^7.0.3", + "minimatch": "^3.0.3" + } + }, + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "dev": true + } + } + }, + "istanbul-lib-coverage": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-1.2.0.tgz", + "integrity": "sha512-GvgM/uXRwm+gLlvkWHTjDAvwynZkL9ns15calTrmhGgowlwJBbWMYzWbKqE2DT6JDP1AFXKa+Zi0EkqNCUqY0A==", + "dev": true + }, + "istanbul-lib-hook": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-1.2.0.tgz", + "integrity": "sha512-p3En6/oGkFQV55Up8ZPC2oLxvgSxD8CzA0yBrhRZSh3pfv3OFj9aSGVC0yoerAi/O4u7jUVnOGVX1eVFM+0tmQ==", + "dev": true, + "requires": { + "append-transform": "^0.4.0" + } + }, + "istanbul-lib-instrument": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-1.10.1.tgz", + "integrity": "sha512-1dYuzkOCbuR5GRJqySuZdsmsNKPL3PTuyPevQfoCXJePT9C8y1ga75neU+Tuy9+yS3G/dgx8wgOmp2KLpgdoeQ==", + "dev": true, + "requires": { + "babel-generator": "^6.18.0", + "babel-template": "^6.16.0", + "babel-traverse": "^6.18.0", + "babel-types": "^6.18.0", + "babylon": "^6.18.0", + "istanbul-lib-coverage": "^1.2.0", + "semver": "^5.3.0" + }, + "dependencies": { + "semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", + "dev": true + } + } + }, + "istanbul-lib-report": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-1.1.4.tgz", + "integrity": "sha512-Azqvq5tT0U09nrncK3q82e/Zjkxa4tkFZv7E6VcqP0QCPn6oNljDPfrZEC/umNXds2t7b8sRJfs6Kmpzt8m2kA==", + "dev": true, + "requires": { + "istanbul-lib-coverage": "^1.2.0", + "mkdirp": "^0.5.1", + "path-parse": "^1.0.5", + "supports-color": "^3.1.2" + }, + "dependencies": { + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, + "requires": { + "has-flag": "^1.0.0" + } + } + } + }, + "istanbul-lib-source-maps": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.4.tgz", + "integrity": "sha512-UzuK0g1wyQijiaYQxj/CdNycFhAd2TLtO2obKQMTZrZ1jzEMRY3rvpASEKkaxbRR6brvdovfA03znPa/pXcejg==", + "dev": true, + "requires": { + "debug": "^3.1.0", + "istanbul-lib-coverage": "^1.2.0", + "mkdirp": "^0.5.1", + "rimraf": "^2.6.1", + "source-map": "^0.5.3" + }, + "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" + } + }, + "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" + } + } + } + }, + "istanbul-reports": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-1.3.0.tgz", + "integrity": "sha512-y2Z2IMqE1gefWUaVjrBm0mSKvUkaBy9Vqz8iwr/r40Y9hBbIteH5wqHG/9DLTfJ9xUnUT2j7A3+VVJ6EaYBllA==", + "dev": true, + "requires": { + "handlebars": "^4.0.3" + } + }, + "isurl": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz", + "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==", + "dev": true, + "requires": { + "has-to-string-tag-x": "^1.2.0", + "is-object": "^1.0.1" + } + }, + "java-properties": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/java-properties/-/java-properties-0.2.10.tgz", + "integrity": "sha512-CpKJh9VRNhS+XqZtg1UMejETGEiqwCGDC/uwPEEQwc2nfdbSm73SIE29TplG2gLYuBOOTNDqxzG6A9NtEPLt0w==", + "dev": true + }, + "jest": { + "version": "22.4.4", + "resolved": "https://registry.npmjs.org/jest/-/jest-22.4.4.tgz", + "integrity": "sha512-eBhhW8OS/UuX3HxgzNBSVEVhSuRDh39Z1kdYkQVWna+scpgsrD7vSeBI7tmEvsguPDMnfJodW28YBnhv/BzSew==", + "dev": true, + "requires": { + "import-local": "^1.0.0", + "jest-cli": "^22.4.4" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "cliui": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", + "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", + "dev": true, + "requires": { + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0", + "wrap-ansi": "^2.0.0" + } + }, + "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" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "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 + }, + "jest-cli": { + "version": "22.4.4", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-22.4.4.tgz", + "integrity": "sha512-I9dsgkeyjVEEZj9wrGrqlH+8OlNob9Iptyl+6L5+ToOLJmHm4JwOPatin1b2Bzp5R5YRQJ+oiedx7o1H7wJzhA==", + "dev": true, + "requires": { + "ansi-escapes": "^3.0.0", + "chalk": "^2.0.1", + "exit": "^0.1.2", + "glob": "^7.1.2", + "graceful-fs": "^4.1.11", + "import-local": "^1.0.0", + "is-ci": "^1.0.10", + "istanbul-api": "^1.1.14", + "istanbul-lib-coverage": "^1.1.1", + "istanbul-lib-instrument": "^1.8.0", + "istanbul-lib-source-maps": "^1.2.1", + "jest-changed-files": "^22.2.0", + "jest-config": "^22.4.4", + "jest-environment-jsdom": "^22.4.1", + "jest-get-type": "^22.1.0", + "jest-haste-map": "^22.4.2", + "jest-message-util": "^22.4.0", + "jest-regex-util": "^22.1.0", + "jest-resolve-dependencies": "^22.1.0", + "jest-runner": "^22.4.4", + "jest-runtime": "^22.4.4", + "jest-snapshot": "^22.4.0", + "jest-util": "^22.4.1", + "jest-validate": "^22.4.4", + "jest-worker": "^22.2.2", + "micromatch": "^2.3.11", + "node-notifier": "^5.2.1", + "realpath-native": "^1.0.0", + "rimraf": "^2.5.4", + "slash": "^1.0.0", + "string-length": "^2.0.0", + "strip-ansi": "^4.0.0", + "which": "^1.2.12", + "yargs": "^10.0.3" + } + }, + "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" + } + }, + "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": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "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" + } + }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "yargs": { + "version": "10.1.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-10.1.2.tgz", + "integrity": "sha512-ivSoxqBGYOqQVruxD35+EyCFDYNEFL/Uo6FcOnz+9xZdZzK0Zzw4r4KhbrME1Oo2gOggwJod2MnsdamSG7H9ig==", + "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": "^8.1.0" + } + } + } + }, + "jest-changed-files": { + "version": "22.4.3", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-22.4.3.tgz", + "integrity": "sha512-83Dh0w1aSkUNFhy5d2dvqWxi/y6weDwVVLU6vmK0cV9VpRxPzhTeGimbsbRDSnEoszhF937M4sDLLeS7Cu/Tmw==", + "dev": true, + "requires": { + "throat": "^4.0.0" + } + }, + "jest-config": { + "version": "22.4.4", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-22.4.4.tgz", + "integrity": "sha512-9CKfo1GC4zrXSoMLcNeDvQBfgtqGTB1uP8iDIZ97oB26RCUb886KkKWhVcpyxVDOUxbhN+uzcBCeFe7w+Iem4A==", + "dev": true, + "requires": { + "chalk": "^2.0.1", + "glob": "^7.1.1", + "jest-environment-jsdom": "^22.4.1", + "jest-environment-node": "^22.4.1", + "jest-get-type": "^22.1.0", + "jest-jasmine2": "^22.4.4", + "jest-regex-util": "^22.1.0", + "jest-resolve": "^22.4.2", + "jest-util": "^22.4.1", + "jest-validate": "^22.4.4", + "pretty-format": "^22.4.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.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 + }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "jest-diff": { + "version": "22.4.3", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-22.4.3.tgz", + "integrity": "sha512-/QqGvCDP5oZOF6PebDuLwrB2BMD8ffJv6TAGAdEVuDx1+uEgrHpSFrfrOiMRx2eJ1hgNjlQrOQEHetVwij90KA==", + "dev": true, + "requires": { + "chalk": "^2.0.1", + "diff": "^3.2.0", + "jest-get-type": "^22.4.3", + "pretty-format": "^22.4.3" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "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==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "jest-docblock": { + "version": "22.4.3", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-22.4.3.tgz", + "integrity": "sha512-uPKBEAw7YrEMcXueMKZXn/rbMxBiSv48fSqy3uEnmgOlQhSX+lthBqHb1fKWNVmFqAp9E/RsSdBfiV31LbzaOg==", + "dev": true, + "requires": { + "detect-newline": "^2.1.0" + } + }, + "jest-environment-jsdom": { + "version": "22.4.3", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-22.4.3.tgz", + "integrity": "sha512-FviwfR+VyT3Datf13+ULjIMO5CSeajlayhhYQwpzgunswoaLIPutdbrnfUHEMyJCwvqQFaVtTmn9+Y8WCt6n1w==", + "dev": true, + "requires": { + "jest-mock": "^22.4.3", + "jest-util": "^22.4.3", + "jsdom": "^11.5.1" + } + }, + "jest-environment-node": { + "version": "22.4.3", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-22.4.3.tgz", + "integrity": "sha512-reZl8XF6t/lMEuPWwo9OLfttyC26A5AMgDyEQ6DBgZuyfyeNUzYT8BFo6uxCCP/Av/b7eb9fTi3sIHFPBzmlRA==", + "dev": true, + "requires": { + "jest-mock": "^22.4.3", + "jest-util": "^22.4.3" + } + }, + "jest-get-type": { + "version": "22.4.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-22.4.3.tgz", + "integrity": "sha512-/jsz0Y+V29w1chdXVygEKSz2nBoHoYqNShPe+QgxSNjAuP1i8+k4LbQNrfoliKej0P45sivkSCh7yiD6ubHS3w==", + "dev": true + }, + "jest-haste-map": { + "version": "22.4.3", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-22.4.3.tgz", + "integrity": "sha512-4Q9fjzuPVwnaqGKDpIsCSoTSnG3cteyk2oNVjBX12HHOaF1oxql+uUiqZb5Ndu7g/vTZfdNwwy4WwYogLh29DQ==", + "dev": true, + "requires": { + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.1.11", + "jest-docblock": "^22.4.3", + "jest-serializer": "^22.4.3", + "jest-worker": "^22.4.3", + "micromatch": "^2.3.11", + "sane": "^2.0.0" + } + }, + "jest-jasmine2": { + "version": "22.4.4", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-22.4.4.tgz", + "integrity": "sha512-nK3vdUl50MuH7vj/8at7EQVjPGWCi3d5+6aCi7Gxy/XMWdOdbH1qtO/LjKbqD8+8dUAEH+BVVh7HkjpCWC1CSw==", + "dev": true, + "requires": { + "chalk": "^2.0.1", + "co": "^4.6.0", + "expect": "^22.4.0", + "graceful-fs": "^4.1.11", + "is-generator-fn": "^1.0.0", + "jest-diff": "^22.4.0", + "jest-matcher-utils": "^22.4.0", + "jest-message-util": "^22.4.0", + "jest-snapshot": "^22.4.0", + "jest-util": "^22.4.1", + "source-map-support": "^0.5.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.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 + }, + "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.6", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.6.tgz", + "integrity": "sha512-N4KXEz7jcKqPf2b2vZF11lQIz9W5ZMuUcIOGj243lduidkf2fjkVKJS9vNxVWn3u/uxX38AcE8U9nnH9FPcq+g==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "jest-leak-detector": { + "version": "22.4.3", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-22.4.3.tgz", + "integrity": "sha512-NZpR/Ls7+ndO57LuXROdgCGz2RmUdC541tTImL9bdUtU3WadgFGm0yV+Ok4Fuia/1rLAn5KaJ+i76L6e3zGJYQ==", + "dev": true, + "requires": { + "pretty-format": "^22.4.3" + } + }, + "jest-matcher-utils": { + "version": "22.4.3", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-22.4.3.tgz", + "integrity": "sha512-lsEHVaTnKzdAPR5t4B6OcxXo9Vy4K+kRRbG5gtddY8lBEC+Mlpvm1CJcsMESRjzUhzkz568exMV1hTB76nAKbA==", + "dev": true, + "requires": { + "chalk": "^2.0.1", + "jest-get-type": "^22.4.3", + "pretty-format": "^22.4.3" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.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 + }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "jest-message-util": { + "version": "22.4.3", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-22.4.3.tgz", + "integrity": "sha512-iAMeKxhB3Se5xkSjU0NndLLCHtP4n+GtCqV0bISKA5dmOXQfEbdEmYiu2qpnWBDCQdEafNDDU6Q+l6oBMd/+BA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0-beta.35", + "chalk": "^2.0.1", + "micromatch": "^2.3.11", + "slash": "^1.0.0", + "stack-utils": "^1.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.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 + }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "jest-mock": { + "version": "22.4.3", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-22.4.3.tgz", + "integrity": "sha512-+4R6mH5M1G4NK16CKg9N1DtCaFmuxhcIqF4lQK/Q1CIotqMs/XBemfpDPeVZBFow6iyUNu6EBT9ugdNOTT5o5Q==", + "dev": true + }, + "jest-regex-util": { + "version": "22.4.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-22.4.3.tgz", + "integrity": "sha512-LFg1gWr3QinIjb8j833bq7jtQopiwdAs67OGfkPrvy7uNUbVMfTXXcOKXJaeY5GgjobELkKvKENqq1xrUectWg==", + "dev": true + }, + "jest-resolve": { + "version": "22.4.3", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-22.4.3.tgz", + "integrity": "sha512-u3BkD/MQBmwrOJDzDIaxpyqTxYH+XqAXzVJP51gt29H8jpj3QgKof5GGO2uPGKGeA1yTMlpbMs1gIQ6U4vcRhw==", + "dev": true, + "requires": { + "browser-resolve": "^1.11.2", + "chalk": "^2.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.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 + }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "jest-resolve-dependencies": { + "version": "22.4.3", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-22.4.3.tgz", + "integrity": "sha512-06czCMVToSN8F2U4EvgSB1Bv/56gc7MpCftZ9z9fBgUQM7dzHGCMBsyfVA6dZTx8v0FDcnALf7hupeQxaBCvpA==", + "dev": true, + "requires": { + "jest-regex-util": "^22.4.3" + } + }, + "jest-runner": { + "version": "22.4.4", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-22.4.4.tgz", + "integrity": "sha512-5S/OpB51igQW9xnkM5Tgd/7ZjiAuIoiJAVtvVTBcEBiXBIFzWM3BAMPBM19FX68gRV0KWyFuGKj0EY3M3aceeQ==", + "dev": true, + "requires": { + "exit": "^0.1.2", + "jest-config": "^22.4.4", + "jest-docblock": "^22.4.0", + "jest-haste-map": "^22.4.2", + "jest-jasmine2": "^22.4.4", + "jest-leak-detector": "^22.4.0", + "jest-message-util": "^22.4.0", + "jest-runtime": "^22.4.4", + "jest-util": "^22.4.1", + "jest-worker": "^22.2.2", + "throat": "^4.0.0" + } + }, + "jest-runtime": { + "version": "22.4.4", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-22.4.4.tgz", + "integrity": "sha512-WRTj9m///npte1YjuphCYX7GRY/c2YvJImU9t7qOwFcqHr4YMzmX6evP/3Sehz5DKW2Vi8ONYPCFWe36JVXxfw==", + "dev": true, + "requires": { + "babel-core": "^6.0.0", + "babel-jest": "^22.4.4", + "babel-plugin-istanbul": "^4.1.5", + "chalk": "^2.0.1", + "convert-source-map": "^1.4.0", + "exit": "^0.1.2", + "graceful-fs": "^4.1.11", + "jest-config": "^22.4.4", + "jest-haste-map": "^22.4.2", + "jest-regex-util": "^22.1.0", + "jest-resolve": "^22.4.2", + "jest-util": "^22.4.1", + "jest-validate": "^22.4.4", + "json-stable-stringify": "^1.0.1", + "micromatch": "^2.3.11", + "realpath-native": "^1.0.0", + "slash": "^1.0.0", + "strip-bom": "3.0.0", + "write-file-atomic": "^2.1.0", + "yargs": "^10.0.3" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "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-jest": { + "version": "22.4.4", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-22.4.4.tgz", + "integrity": "sha512-A9NB6/lZhYyypR9ATryOSDcqBaqNdzq4U+CN+/wcMsLcmKkPxQEoTKLajGfd3IkxNyVBT8NewUK2nWyGbSzHEQ==", + "dev": true, + "requires": { + "babel-plugin-istanbul": "^4.1.5", + "babel-preset-jest": "^22.4.4" + } + }, + "babel-plugin-jest-hoist": { + "version": "22.4.4", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-22.4.4.tgz", + "integrity": "sha512-DUvGfYaAIlkdnygVIEl0O4Av69NtuQWcrjMOv6DODPuhuGLDnbsARz3AwiiI/EkIMMlxQDUcrZ9yoyJvTNjcVQ==", + "dev": true + }, + "babel-preset-jest": { + "version": "22.4.4", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-22.4.4.tgz", + "integrity": "sha512-+dxMtOFwnSYWfum0NaEc0O03oSdwBsjx4tMSChRDPGwu/4wSY6Q6ANW3wkjKpJzzguaovRs/DODcT4hbSN8yiA==", + "dev": true, + "requires": { + "babel-plugin-jest-hoist": "^22.4.4", + "babel-plugin-syntax-object-rest-spread": "^6.13.0" + } + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "cliui": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", + "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", + "dev": true, + "requires": { + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0", + "wrap-ansi": "^2.0.0" + } + }, + "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" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "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 + }, + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "dev": true + }, + "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": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "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" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "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==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "yargs": { + "version": "10.1.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-10.1.2.tgz", + "integrity": "sha512-ivSoxqBGYOqQVruxD35+EyCFDYNEFL/Uo6FcOnz+9xZdZzK0Zzw4r4KhbrME1Oo2gOggwJod2MnsdamSG7H9ig==", + "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": "^8.1.0" + } + } + } + }, + "jest-serializer": { + "version": "22.4.3", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-22.4.3.tgz", + "integrity": "sha512-uPaUAppx4VUfJ0QDerpNdF43F68eqKWCzzhUlKNDsUPhjOon7ZehR4C809GCqh765FoMRtTVUVnGvIoskkYHiw==", + "dev": true + }, + "jest-snapshot": { + "version": "22.4.3", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-22.4.3.tgz", + "integrity": "sha512-JXA0gVs5YL0HtLDCGa9YxcmmV2LZbwJ+0MfyXBBc5qpgkEYITQFJP7XNhcHFbUvRiniRpRbGVfJrOoYhhGE0RQ==", + "dev": true, + "requires": { + "chalk": "^2.0.1", + "jest-diff": "^22.4.3", + "jest-matcher-utils": "^22.4.3", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "pretty-format": "^22.4.3" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.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 + }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "jest-util": { + "version": "22.4.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-22.4.3.tgz", + "integrity": "sha512-rfDfG8wyC5pDPNdcnAlZgwKnzHvZDu8Td2NJI/jAGKEGxJPYiE4F0ss/gSAkG4778Y23Hvbz+0GMrDJTeo7RjQ==", + "dev": true, + "requires": { + "callsites": "^2.0.0", + "chalk": "^2.0.1", + "graceful-fs": "^4.1.11", + "is-ci": "^1.0.10", + "jest-message-util": "^22.4.3", + "mkdirp": "^0.5.1", + "source-map": "^0.6.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "callsites": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", + "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", + "dev": true + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.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 + }, + "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 + }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "jest-validate": { + "version": "22.4.4", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-22.4.4.tgz", + "integrity": "sha512-dmlf4CIZRGvkaVg3fa0uetepcua44DHtktHm6rcoNVtYlpwe6fEJRkMFsaUVcFHLzbuBJ2cPw9Gl9TKfnzMVwg==", + "dev": true, + "requires": { + "chalk": "^2.0.1", + "jest-config": "^22.4.4", + "jest-get-type": "^22.1.0", + "leven": "^2.1.0", + "pretty-format": "^22.4.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.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 + }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "jest-worker": { + "version": "22.4.3", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-22.4.3.tgz", + "integrity": "sha512-B1ucW4fI8qVAuZmicFxI1R3kr2fNeYJyvIQ1rKcuLYnenFV5K5aMbxFj6J0i00Ju83S8jP2d7Dz14+AvbIHRYQ==", + "dev": true, + "requires": { + "merge-stream": "^1.0.1" + } + }, + "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 + }, + "js-yaml": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.11.0.tgz", + "integrity": "sha512-saJstZWv7oNeOyBh3+Dx1qWzhW0+e6/8eDzo7p5rDFqxntSztloLtuKu+Ejhtq82jsilwOIZYsCz+lIjthg1Hw==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "dependencies": { + "esprima": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", + "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==", + "dev": true + } + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "optional": true + }, + "jsdom": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-11.11.0.tgz", + "integrity": "sha512-ou1VyfjwsSuWkudGxb03FotDajxAto6USAlmMZjE2lc0jCznt7sBWkhfRBRaWwbnmDqdMSTKTLT5d9sBFkkM7A==", + "dev": true, + "requires": { + "abab": "^1.0.4", + "acorn": "^5.3.0", + "acorn-globals": "^4.1.0", + "array-equal": "^1.0.0", + "cssom": ">= 0.3.2 < 0.4.0", + "cssstyle": ">= 0.3.1 < 0.4.0", + "data-urls": "^1.0.0", + "domexception": "^1.0.0", + "escodegen": "^1.9.0", + "html-encoding-sniffer": "^1.0.2", + "left-pad": "^1.2.0", + "nwsapi": "^2.0.0", + "parse5": "4.0.0", + "pn": "^1.1.0", + "request": "^2.83.0", + "request-promise-native": "^1.0.5", + "sax": "^1.2.4", + "symbol-tree": "^3.2.2", + "tough-cookie": "^2.3.3", + "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": "^4.0.0", + "xml-name-validator": "^3.0.0" + }, + "dependencies": { + "escodegen": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.9.1.tgz", + "integrity": "sha512-6hTjO1NAWkHnDk3OqQ4YrCuwwmGHL9S3nPlzBOUG/R44rda3wLNrfvQ5fkSGjyhHFKM7ALPKcKGrwvCLe0lC7Q==", + "dev": true, + "requires": { + "esprima": "^3.1.3", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + } + }, + "esprima": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", + "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", + "dev": true + }, + "estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "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, + "optional": true + }, + "ws": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-4.1.0.tgz", + "integrity": "sha512-ZGh/8kF9rrRNffkLFV4AzhvooEclrOH0xaugmqGsIfFgOE/pIz4fMc4Ef+5HSQqTEug2S9JZIWDR47duDSLfaA==", + "dev": true, + "requires": { + "async-limiter": "~1.0.0", + "safe-buffer": "~5.1.0" + } + } + } + }, + "jsesc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", + "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", + "dev": true + }, + "json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", + "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=" + }, + "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=" + }, + "json-stable-stringify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", + "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", + "dev": true, + "requires": { + "jsonify": "~0.0.0" + } + }, + "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=" + }, + "json5": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", + "dev": true + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "jsonify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", + "dev": true + }, + "jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", + "dev": true + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "keyv": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.0.0.tgz", + "integrity": "sha512-eguHnq22OE3uVoSYG0LVWNP+4ppamWr9+zWBe1bsNcovIMy6huUJFPgy4mGwCd/rnl3vOLGW1MTlu4c57CT1xA==", + "dev": true, + "requires": { + "json-buffer": "3.0.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" + } + }, + "latest-version": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz", + "integrity": "sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=", + "dev": true, + "requires": { + "package-json": "^4.0.0" + } + }, + "lazy-cache": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", + "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", + "dev": true, + "optional": true + }, + "lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "dev": true, + "requires": { + "invert-kv": "^1.0.0" + } + }, + "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 + }, + "leven": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", + "integrity": "sha1-wuep93IJTe6dNCAq6KzORoeHVYA=", + "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": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "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 + } + } + }, + "lodash": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", + "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=" + }, + "lodash._basebind": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/lodash._basebind/-/lodash._basebind-2.3.0.tgz", + "integrity": "sha1-K1vEUqDhBhQ7IYafIzvbWHQX0kg=", + "requires": { + "lodash._basecreate": "~2.3.0", + "lodash._setbinddata": "~2.3.0", + "lodash.isobject": "~2.3.0" + } + }, + "lodash._basecreate": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/lodash._basecreate/-/lodash._basecreate-2.3.0.tgz", + "integrity": "sha1-m4ioak3P97fzxh2Dovz8BnHsneA=", + "requires": { + "lodash._renative": "~2.3.0", + "lodash.isobject": "~2.3.0", + "lodash.noop": "~2.3.0" + } + }, + "lodash._basecreatecallback": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/lodash._basecreatecallback/-/lodash._basecreatecallback-2.3.0.tgz", + "integrity": "sha1-N7KrF1kaM56YjbMln81GAZ16w2I=", + "requires": { + "lodash._setbinddata": "~2.3.0", + "lodash.bind": "~2.3.0", + "lodash.identity": "~2.3.0", + "lodash.support": "~2.3.0" + } + }, + "lodash._basecreatewrapper": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/lodash._basecreatewrapper/-/lodash._basecreatewrapper-2.3.0.tgz", + "integrity": "sha1-qgxhrZYETDkzN2ExSDqXWcNlEkc=", + "requires": { + "lodash._basecreate": "~2.3.0", + "lodash._setbinddata": "~2.3.0", + "lodash._slice": "~2.3.0", + "lodash.isobject": "~2.3.0" + } + }, + "lodash._createwrapper": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/lodash._createwrapper/-/lodash._createwrapper-2.3.0.tgz", + "integrity": "sha1-0arhEC2t9EDo4G/BM6bt1/4UYHU=", + "requires": { + "lodash._basebind": "~2.3.0", + "lodash._basecreatewrapper": "~2.3.0", + "lodash.isfunction": "~2.3.0" + } + }, + "lodash._objecttypes": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/lodash._objecttypes/-/lodash._objecttypes-2.3.0.tgz", + "integrity": "sha1-aj6jmH3W7rgCGy1cnDA1Scwrrh4=" + }, + "lodash._renative": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/lodash._renative/-/lodash._renative-2.3.0.tgz", + "integrity": "sha1-d9jt1M7SbdWXH54Vpfdy5OMX+9M=" + }, + "lodash._setbinddata": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/lodash._setbinddata/-/lodash._setbinddata-2.3.0.tgz", + "integrity": "sha1-5WEEkKzRMnfVmFjZW18nJ/FQjwQ=", + "requires": { + "lodash._renative": "~2.3.0", + "lodash.noop": "~2.3.0" + } + }, + "lodash._shimkeys": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/lodash._shimkeys/-/lodash._shimkeys-2.3.0.tgz", + "integrity": "sha1-YR+TFJ4+bHIQlrSHae8pU3rai6k=", + "requires": { + "lodash._objecttypes": "~2.3.0" + } + }, + "lodash._slice": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/lodash._slice/-/lodash._slice-2.3.0.tgz", + "integrity": "sha1-FHGYEyhZly5GgMoppZkshVZpqlw=" + }, + "lodash.assign": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", + "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=", + "dev": true + }, + "lodash.bind": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/lodash.bind/-/lodash.bind-2.3.0.tgz", + "integrity": "sha1-wqjhi2jl7MFS4rFoJmEW/qWwFsw=", + "requires": { + "lodash._createwrapper": "~2.3.0", + "lodash._renative": "~2.3.0", + "lodash._slice": "~2.3.0" + } + }, + "lodash.foreach": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/lodash.foreach/-/lodash.foreach-2.3.0.tgz", + "integrity": "sha1-CDQEyR6EbudyRf3512UZxosq8Wg=", + "requires": { + "lodash._basecreatecallback": "~2.3.0", + "lodash.forown": "~2.3.0" + } + }, + "lodash.forown": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/lodash.forown/-/lodash.forown-2.3.0.tgz", + "integrity": "sha1-JPtKr4ANRfwtxgv+w84EyDajrX8=", + "requires": { + "lodash._basecreatecallback": "~2.3.0", + "lodash._objecttypes": "~2.3.0", + "lodash.keys": "~2.3.0" + } + }, + "lodash.identity": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/lodash.identity/-/lodash.identity-2.3.0.tgz", + "integrity": "sha1-awGiEMlIU1XCqRO0i2cRIZoXPe0=" + }, + "lodash.isfunction": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-2.3.0.tgz", + "integrity": "sha1-aylz5HpkfPEucNZ2rqE2Q3BuUmc=" + }, + "lodash.isobject": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-2.3.0.tgz", + "integrity": "sha1-LhbT/Fg9qYMZaJU/LY5tc0NPZ5k=", + "requires": { + "lodash._objecttypes": "~2.3.0" + } + }, + "lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", + "dev": true + }, + "lodash.keys": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-2.3.0.tgz", + "integrity": "sha1-s1D0+Syqn0WkouzwGEVM8vKK4lM=", + "requires": { + "lodash._renative": "~2.3.0", + "lodash._shimkeys": "~2.3.0", + "lodash.isobject": "~2.3.0" + } + }, + "lodash.noop": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/lodash.noop/-/lodash.noop-2.3.0.tgz", + "integrity": "sha1-MFnWKNUbv5N80qC2/Dp/ISpmnCw=" + }, + "lodash.some": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.some/-/lodash.some-4.6.0.tgz", + "integrity": "sha1-G7nzFO9ri63tE7VJFpsqlF62jk0=", + "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 + }, + "lodash.support": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/lodash.support/-/lodash.support-2.3.0.tgz", + "integrity": "sha1-fq8DivTw1qq3drRKptz8gDNMm/0=", + "requires": { + "lodash._renative": "~2.3.0" + } + }, + "lodash.toarray": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.toarray/-/lodash.toarray-4.4.0.tgz", + "integrity": "sha1-JMS/zWsvuji/0FlNsRedjptlZWE=" + }, + "longest": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", + "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", + "dev": true + }, + "loose-envify": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", + "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", + "dev": true, + "requires": { + "js-tokens": "^3.0.0" + } + }, + "loud-rejection": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", + "dev": true, + "requires": { + "currently-unhandled": "^0.4.1", + "signal-exit": "^3.0.0" + } + }, + "lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "dev": true + }, + "make-dir": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", + "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "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 + } + } + }, + "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-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "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" + } + }, + "marked": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-0.4.0.tgz", + "integrity": "sha512-tMsdNBgOsrUophCAFQl0XPe6Zqk/uy9gnue+jIIKhykO51hxyu6uNx7zBPy0+y/WKYVZZMspV9YeXLNdKk+iYw==", + "dev": true + }, + "marked-terminal": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/marked-terminal/-/marked-terminal-3.0.0.tgz", + "integrity": "sha512-7gWHPxQlWNeqjVgW72gwxLeJBj0T/RmurVs2qHPm90f7kuu7CMcZVTmtqk1dogourkAtopZNnp2DUpTIJZKZ4w==", + "dev": true, + "requires": { + "cardinal": "^1.0.0", + "chalk": "^1.1.3", + "cli-table": "^0.3.1", + "lodash.assign": "^4.2.0", + "node-emoji": "^1.4.1" + } + }, + "mem": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", + "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", + "dev": true, + "requires": { + "mimic-fn": "^1.0.0" + } + }, + "merge": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/merge/-/merge-1.2.0.tgz", + "integrity": "sha1-dTHjnUlJwoGma4xabgJl6LBYlNo=", + "dev": true + }, + "merge-stream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-1.0.1.tgz", + "integrity": "sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE=", + "dev": true, + "requires": { + "readable-stream": "^2.0.1" + } + }, + "merge2": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.2.2.tgz", + "integrity": "sha512-bgM8twH86rWni21thii6WCMQMRMmwqqdW3sGWi9IipnVAszdLXRjwDwAnyrVXo6DuP3AjRMMttZKUB48QWIFGg==", + "dev": true + }, + "micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "dev": 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" + } + }, + "mime-db": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", + "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==" + }, + "mime-types": { + "version": "2.1.18", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", + "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", + "requires": { + "mime-db": "~1.33.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 + }, + "mimic-response": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.0.tgz", + "integrity": "sha1-3z02Uqc/3ta5sLJBRub9BSNTRY4=", + "dev": true + }, + "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": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "minimist-options": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-3.0.2.tgz", + "integrity": "sha512-FyBrT/d0d4+uiZRbqznPXqw3IpZZG3gl3wKWiX784FycUKVwBt0uLBFkQrtE4tZOrgo78nZp2jnKz3L65T5LdQ==", + "dev": true, + "requires": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.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==", + "dev": true, + "requires": { + "for-in": "^1.0.2", + "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" + } + } + } + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "modify-values": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz", + "integrity": "sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==", + "dev": true + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", + "dev": true + }, + "nan": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", + "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==", + "dev": true, + "optional": true + }, + "nanomatch": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.9.tgz", + "integrity": "sha512-n8R9bS8yQ6eSXaV6jHUpKzD8gLsin02w1HSFiegwrs9E098Ylhw5jdyKPaYqvHknHaSCKTPp7C8dGCQ0q9koXA==", + "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-odd": "^2.0.0", + "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 + } + } + }, + "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 + }, + "nerf-dart": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/nerf-dart/-/nerf-dart-1.0.0.tgz", + "integrity": "sha1-5tq3/r9a2Bbqgc9cYpxaDr3nLBo=", + "dev": true + }, + "nice-try": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.4.tgz", + "integrity": "sha512-2NpiFHqC87y/zFke0fC0spBXL3bBsoh/p5H1EFhshxjCR5+0g2d6BiXbUFz9v1sAcxsk2htp2eQnNIci2dIYcA==", + "dev": true + }, + "node-emoji": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.8.1.tgz", + "integrity": "sha512-+ktMAh1Jwas+TnGodfCfjUbJKoANqPaJFN0z0iqh41eqD8dvguNzcitVSBSVK1pidz0AqGbLKcoVuVLRVZ/aVg==", + "requires": { + "lodash.toarray": "^4.4.0" + } + }, + "node-fetch": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.1.2.tgz", + "integrity": "sha1-q4hOjn5X44qUR1POxwb3iNF2i7U=", + "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-notifier": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.2.1.tgz", + "integrity": "sha512-MIBs+AAd6dJ2SklbbE8RUDRlIVhU8MaNLh1A9SUZDUHPiZkWLFde6UNwG41yQHZEToHgJMXqyVZ9UcS/ReOVTg==", + "dev": true, + "requires": { + "growly": "^1.3.0", + "semver": "^5.4.1", + "shellwords": "^0.1.1", + "which": "^1.3.0" + }, + "dependencies": { + "semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", + "dev": true + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "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" + } + }, + "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" + } + }, + "normalize-url": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.0.1.tgz", + "integrity": "sha512-yFWAVAB0JJ4oIcuheItBDajxG8hqWJUPu4yh5yAQNYxL4SBwn3Xm6TYBPgdMSGRKKV8SqBbLBrGyt1e2UFcW4Q==", + "dev": true + }, + "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" + } + }, + "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=" + }, + "nwsapi": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.0.1.tgz", + "integrity": "sha512-xOJJb7kAAGy6UOklbaIPA0iu/27VMHfAbMUgYJlXz4qRXytIkPGM2vwfbxa+tbaqcqHNsP6RN4eDZlePelWKpQ==", + "dev": true + }, + "oauth-sign": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", + "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=" + }, + "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", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "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" + } + } + } + }, + "object-keys": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz", + "integrity": "sha1-xUYBd4rVYPEULODgG8yotW0TQm0=", + "dev": true + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "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.getownpropertydescriptors": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz", + "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.5.1" + } + }, + "object.omit": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", + "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", + "dev": true, + "requires": { + "for-own": "^0.1.4", + "is-extendable": "^0.1.1" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "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 + } + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, + "requires": { + "mimic-fn": "^1.0.0" + } + }, + "optimist": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", + "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", + "dev": true, + "requires": { + "minimist": "~0.0.1", + "wordwrap": "~0.0.2" + }, + "dependencies": { + "wordwrap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", + "dev": true + } + } + }, + "optionator": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.4", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "wordwrap": "~1.0.0" + } + }, + "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-locale": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", + "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", + "dev": true, + "requires": { + "execa": "^0.7.0", + "lcid": "^1.0.0", + "mem": "^1.1.0" + } + }, + "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 + }, + "p-cancelable": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.4.1.tgz", + "integrity": "sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ==", + "dev": true + }, + "p-filter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-1.0.0.tgz", + "integrity": "sha1-Yp0xcVAgnI/VCLoTdxPvS7kg6ds=", + "dev": true, + "requires": { + "p-map": "^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-is-promise": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz", + "integrity": "sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4=", + "dev": true + }, + "p-limit": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.2.0.tgz", + "integrity": "sha512-Y/OtIaXtUPr4/YpMv1pCL5L5ed0rumAaAeBSj12F+bSlMdys7i8oQF/GUJmfpTS/QoaRrS/k6pma29haJpsMng==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-map": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-1.2.0.tgz", + "integrity": "sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA==", + "dev": true + }, + "p-reduce": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-1.0.0.tgz", + "integrity": "sha1-GMKw3ZNqRpClKfgjH1ig/bakffo=", + "dev": true + }, + "p-retry": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-2.0.0.tgz", + "integrity": "sha512-ZbCuzAmiwJ45q4evp/IG9D+5MUllGSUeCWwPt3j/tdYSi1KPkSD+46uqmAA1LhccDhOXv8kYZKNb8x78VflzfA==", + "dev": true, + "requires": { + "retry": "^0.12.0" + } + }, + "p-timeout": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-2.0.1.tgz", + "integrity": "sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA==", + "dev": true, + "requires": { + "p-finally": "^1.0.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "package-json": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz", + "integrity": "sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=", + "dev": true, + "requires": { + "got": "^6.7.1", + "registry-auth-token": "^3.0.1", + "registry-url": "^3.0.3", + "semver": "^5.1.0" + }, + "dependencies": { + "got": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz", + "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=", + "dev": true, + "requires": { + "create-error-class": "^3.0.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "is-redirect": "^1.0.0", + "is-retry-allowed": "^1.0.0", + "is-stream": "^1.0.0", + "lowercase-keys": "^1.0.0", + "safe-buffer": "^5.0.1", + "timed-out": "^4.0.0", + "unzip-response": "^2.0.1", + "url-parse-lax": "^1.0.0" + } + }, + "prepend-http": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", + "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", + "dev": true + }, + "semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", + "dev": true + }, + "url-parse-lax": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", + "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", + "dev": true, + "requires": { + "prepend-http": "^1.0.1" + } + } + } + }, + "parse-domain": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/parse-domain/-/parse-domain-2.1.1.tgz", + "integrity": "sha512-xOQ/B+pnS8uzqFMHcS7VS9J7Cn+rFyPlGIoDMFL2e5g/tPhlpa8MSHQmFAlABHBKPCXgOOxFt5PFNdEmwtwvqQ==", + "dev": true, + "requires": { + "chai": "^4.1.2", + "fs-copy-file-sync": "^1.1.1", + "got": "^8.0.1", + "mkdirp": "^0.5.1", + "mocha": "^4.0.1" + }, + "dependencies": { + "chai": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.1.2.tgz", + "integrity": "sha1-D2RYS6ZC8PKs4oBiefTwbKI61zw=", + "dev": true, + "requires": { + "assertion-error": "^1.0.1", + "check-error": "^1.0.1", + "deep-eql": "^3.0.0", + "get-func-name": "^2.0.0", + "pathval": "^1.0.0", + "type-detect": "^4.0.0" + } + }, + "commander": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", + "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", + "dev": true + }, + "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" + } + }, + "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" + } + }, + "diff": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", + "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==", + "dev": true + }, + "growl": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", + "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", + "dev": true + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "mocha": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz", + "integrity": "sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA==", + "dev": true, + "requires": { + "browser-stdout": "1.3.0", + "commander": "2.11.0", + "debug": "3.1.0", + "diff": "3.3.1", + "escape-string-regexp": "1.0.5", + "glob": "7.1.2", + "growl": "1.10.3", + "he": "1.1.1", + "mkdirp": "0.5.1", + "supports-color": "4.4.0" + } + }, + "supports-color": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "dev": true, + "requires": { + "has-flag": "^2.0.0" + } + }, + "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==", + "dev": true + } + } + }, + "parse-github-url": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/parse-github-url/-/parse-github-url-1.0.2.tgz", + "integrity": "sha512-kgBf6avCbO3Cn6+RnzRGLkUsv4ZVqv/VfAYkRsyBcgkshNvVBkRn1FEZcW0Jb+npXQWm2vHPnnOqFteZxRRGNw==", + "dev": true + }, + "parse-glob": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", + "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", + "dev": 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=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, + "parse-url": { + "version": "1.3.11", + "resolved": "https://registry.npmjs.org/parse-url/-/parse-url-1.3.11.tgz", + "integrity": "sha1-V8FUKKuKiSsfQ4aWRccR0OFEtVQ=", + "dev": true, + "requires": { + "is-ssh": "^1.3.0", + "protocols": "^1.4.0" + } + }, + "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", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true + }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", + "dev": 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" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "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", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "path-parse": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", + "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", + "dev": true + }, + "path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.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", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + }, + "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" + } + }, + "pkg-dir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz", + "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=", + "dev": true, + "requires": { + "find-up": "^1.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==", + "dev": true + }, + "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": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "prepend-http": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", + "dev": true + }, + "preserve": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", + "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", + "dev": true + }, + "pretty-format": { + "version": "22.4.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-22.4.3.tgz", + "integrity": "sha512-S4oT9/sT6MN7/3COoOy+ZJeA92VmOnveLHgrwBE3Z1W5N9S2A1QGNYiE1z75DAENbJrXXUb+OWXhpJcg05QKQQ==", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0", + "ansi-styles": "^3.2.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + } + } + }, + "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==", + "dev": true + }, + "progress": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz", + "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=", + "dev": true + }, + "protocols": { + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/protocols/-/protocols-1.4.6.tgz", + "integrity": "sha1-+LsmPqG1/Xp2BNJri+Ob13Z4v4o=", + "dev": true + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + }, + "q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", + "dev": true + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + }, + "query-string": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", + "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==", + "dev": true, + "requires": { + "decode-uri-component": "^0.2.0", + "object-assign": "^4.1.0", + "strict-uri-encode": "^1.0.0" + } + }, + "quick-lru": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-1.1.0.tgz", + "integrity": "sha1-Q2CxfGETatOAeDl/8RQW4Ybc+7g=", + "dev": true + }, + "randomatic": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz", + "integrity": "sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how==", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "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", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "rc": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.7.tgz", + "integrity": "sha512-LdLD8xD4zzLsAT5xyushXDNscEjB7+2ulnl8+r1pnESlYtlJtVSoCMBGr30eDRJ3+2Gq89jK9P9e4tCEH1+ywA==", + "dev": 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", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "dev": true, + "requires": { + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" + } + }, + "read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "dev": true, + "requires": { + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" + } + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": 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" + } + }, + "readdirp": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz", + "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=", + "dev": true, + "optional": true, + "requires": { + "graceful-fs": "^4.1.2", + "minimatch": "^3.0.2", + "readable-stream": "^2.0.2", + "set-immediate-shim": "^1.0.1" + } + }, + "realpath-native": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-1.0.0.tgz", + "integrity": "sha512-XJtlRJ9jf0E1H1SLeJyQ9PGzQD7S65h1pRXEcAeK48doKOnKxcgPeNohJvD5u/2sI9J1oke6E8bZHS/fmW1UiQ==", + "dev": true, + "requires": { + "util.promisify": "^1.0.0" + } + }, + "redeyed": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-1.0.1.tgz", + "integrity": "sha1-6WwZO0DAgWsArshCaY5hGF5VSYo=", + "dev": true, + "requires": { + "esprima": "~3.0.0" + }, + "dependencies": { + "esprima": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.0.0.tgz", + "integrity": "sha1-U88kes2ncxPlUcOqLnM0LT+099k=", + "dev": true + } + } + }, + "regenerate": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.3.3.tgz", + "integrity": "sha512-jVpo1GadrDAK59t/0jRx5VxYWQEDkkEKi6+HjE3joFVLfDOh9Xrdh0dF1eSq+BI/SwvTQ44gSscJ8N5zYL61sg==", + "dev": true + }, + "regenerate-unicode-properties": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-6.0.0.tgz", + "integrity": "sha512-BvXxRS7RfVWxtm7vrq+0I0j7sqZ1zeSC+yzf5HS0qLnKcZPX541gFEGB39LvGuKHrkyKXrzXug+oC7xkM1Zovw==", + "dev": true, + "requires": { + "regenerate": "^1.3.3" + } + }, + "regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" + }, + "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, + "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": "1.1.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-1.1.0.tgz", + "integrity": "sha512-LOPw8FpgdQF9etWMaAfG/WRthIdXJGYp4mJ2Jgn/2lpkbod9jPn0t9UqN7AxBOKNfzRbYyVfgc7Vk4t/MpnXgw==", + "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" + } + }, + "registry-auth-token": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.2.tgz", + "integrity": "sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ==", + "dev": true, + "requires": { + "rc": "^1.1.6", + "safe-buffer": "^5.0.1" + } + }, + "registry-url": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", + "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=", + "dev": true, + "requires": { + "rc": "^1.0.1" + } + }, + "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 + } + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "repeat-element": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", + "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "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.85.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.85.0.tgz", + "integrity": "sha512-8H7Ehijd4js+s6wuVPLjwORxD4zeuyjYugprdOXlPSqaApmL/QOy+EB/beICHVCHkGMKNh5rvihb5ov+IDw4mg==", + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.6.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.5", + "extend": "~3.0.1", + "forever-agent": "~0.6.1", + "form-data": "~2.3.1", + "har-validator": "~5.0.3", + "hawk": "~6.0.2", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.17", + "oauth-sign": "~0.8.2", + "performance-now": "^2.1.0", + "qs": "~6.5.1", + "safe-buffer": "^5.1.1", + "stringstream": "~0.0.5", + "tough-cookie": "~2.3.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.1.0" + } + }, + "request-promise": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/request-promise/-/request-promise-4.1.1.tgz", + "integrity": "sha1-JgIeT29W/Uwwn2vx69jJepWsH7U=", + "requires": { + "bluebird": "^3.4.1", + "request-promise-core": "1.1.1", + "stealthy-require": "^1.0.0" + } + }, + "request-promise-core": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.1.tgz", + "integrity": "sha1-Pu4AssWqgyOc+wTFcA2jb4HNCLY=", + "requires": { + "lodash": "^4.13.1" + }, + "dependencies": { + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==" + } + } + }, + "request-promise-native": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.5.tgz", + "integrity": "sha1-UoF3D2jgyXGeUWP9P6tIIhX0/aU=", + "dev": true, + "requires": { + "request-promise-core": "1.1.1", + "stealthy-require": "^1.1.0", + "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=", + "dev": true + }, + "require-uncached": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", + "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", + "dev": true, + "requires": { + "caller-path": "^0.1.0", + "resolve-from": "^1.0.0" + } + }, + "resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", + "dev": true + }, + "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": { + "resolve-from": "^3.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true + } + } + }, + "resolve-from": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", + "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", + "dev": true + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "dev": true + }, + "responselike": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", + "dev": true, + "requires": { + "lowercase-keys": "^1.0.0" + } + }, + "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", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true + }, + "retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", + "dev": true + }, + "right-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", + "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", + "dev": true, + "optional": true, + "requires": { + "align-text": "^0.1.1" + } + }, + "rimraf": { + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz", + "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=", + "dev": true + }, + "rsvp": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-3.6.2.tgz", + "integrity": "sha512-OfWGQTb9vnwRjwtA2QwpG2ICclHC3pgXZO5xt8H2EfgDquO0qVdSb5T88L4qJVAEugbS56pAuV4XZM58UX8ulw==", + "dev": true + }, + "run-async": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", + "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "dev": true, + "requires": { + "is-promise": "^2.1.0" + } + }, + "rx-lite": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", + "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=", + "dev": true + }, + "rx-lite-aggregates": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", + "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", + "dev": true, + "requires": { + "rx-lite": "*" + } + }, + "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==" + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "requires": { + "ret": "~0.1.10" + } + }, + "sane": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/sane/-/sane-2.5.2.tgz", + "integrity": "sha1-tNwYYcIbQn6SlQej51HiosuKs/o=", + "dev": true, + "requires": { + "anymatch": "^2.0.0", + "capture-exit": "^1.2.0", + "exec-sh": "^0.2.0", + "fb-watchman": "^2.0.0", + "fsevents": "^1.2.3", + "micromatch": "^3.1.4", + "minimist": "^1.1.1", + "walker": "~1.0.5", + "watch": "~0.18.0" + }, + "dependencies": { + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": 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 + }, + "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, + "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" + } + } + } + }, + "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": { + "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, + "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, + "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, + "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-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, + "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-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, + "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 + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": 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, + "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, + "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" + } + } + } + }, + "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" + } + }, + "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=", + "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 + }, + "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" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "dev": true + }, + "semantic-release": { + "version": "15.5.0", + "resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-15.5.0.tgz", + "integrity": "sha512-yNpFG5dNJ0G0knQbQVfqNufc0x39w/qVDnocc+hp9yykrpJPNfOoALYS+K7o9Ekxjj/M9HD11FsOUqMsLnhuzA==", + "dev": true, + "requires": { + "@semantic-release/commit-analyzer": "^5.0.0", + "@semantic-release/error": "^2.2.0", + "@semantic-release/github": "^4.1.0", + "@semantic-release/npm": "^3.2.0", + "@semantic-release/release-notes-generator": "^6.0.0", + "aggregate-error": "^1.0.0", + "chalk": "^2.3.0", + "cosmiconfig": "^5.0.1", + "debug": "^3.1.0", + "env-ci": "^2.0.0", + "execa": "^0.10.0", + "find-versions": "^2.0.0", + "get-stream": "^3.0.0", + "git-log-parser": "^1.2.0", + "git-url-parse": "^9.0.0", + "hook-std": "^0.4.0", + "hosted-git-info": "^2.6.0", + "lodash": "^4.17.4", + "marked": "^0.4.0", + "marked-terminal": "^3.0.0", + "p-locate": "^2.0.0", + "p-reduce": "^1.0.0", + "read-pkg-up": "^3.0.0", + "resolve-from": "^4.0.0", + "semver": "^5.4.1", + "yargs": "^11.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "cliui": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", + "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", + "dev": true, + "requires": { + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0", + "wrap-ansi": "^2.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" + } + }, + "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" + } + }, + "execa": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.10.0.tgz", + "integrity": "sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "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" + } + }, + "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" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "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 + }, + "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" + } + }, + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "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-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": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "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": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", + "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^3.0.0" + } + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, + "semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", + "dev": true + }, + "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": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "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" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "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==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "yargs": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-11.0.0.tgz", + "integrity": "sha512-Rjp+lMYQOWtgqojx1dEWorjCofi1YN7AoFvYV7b1gx/7dAAeuI4kN5SZiEvr0ZmsZTOpDRcCqrpI10L31tFkBw==", + "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" + } + }, + "yargs-parser": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-9.0.2.tgz", + "integrity": "sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc=", + "dev": true, + "requires": { + "camelcase": "^4.1.0" + } + } + } + }, + "semver": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz", + "integrity": "sha1-MAvG4OhjdPe6YQaLWx7NV/xlMto=", + "dev": true + }, + "semver-diff": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz", + "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=", + "dev": true, + "requires": { + "semver": "^5.0.3" + }, + "dependencies": { + "semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", + "dev": true + } + } + }, + "semver-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-1.0.0.tgz", + "integrity": "sha1-kqSWkGX5xwxpR1PVUkj8aPj2Usk=", + "dev": true + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "set-immediate-shim": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", + "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", + "dev": true, + "optional": true + }, + "set-value": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", + "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^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" + } + } + } + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "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=", + "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" + }, + "dependencies": { + "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 + } + } + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.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=", + "dev": 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, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^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, + "requires": { + "is-descriptor": "^1.0.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, + "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" + } + }, + "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 + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "requires": { + "kind-of": "^3.2.0" + } + }, + "sntp": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz", + "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==", + "requires": { + "hoek": "4.x.x" + } + }, + "sort-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz", + "integrity": "sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg=", + "dev": true, + "requires": { + "is-plain-obj": "^1.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 + }, + "source-map-resolve": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", + "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", + "dev": true, + "requires": { + "atob": "^2.1.1", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "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==", + "dev": true, + "requires": { + "source-map": "^0.5.6" + } + }, + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "dev": true + }, + "spawn-error-forwarder": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/spawn-error-forwarder/-/spawn-error-forwarder-1.0.0.tgz", + "integrity": "sha1-Gv2Uc46ZmwNG17n8NzvlXgdXcCk=", + "dev": true + }, + "spdx-correct": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.0.tgz", + "integrity": "sha512-N19o9z5cEyc8yQQPukRCZ9EUmb4HUpnrmaL/fxS2pBo2jbfcFRVuFZ/oFC+vZz0MNNk0h80iMn5/S6qGZOL5+g==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz", + "integrity": "sha512-4K1NsmrlCU1JJgUrtgEeTVyfx8VaYea9J9LvARxhbHtVtohPs/gFGG5yy49beySjlIMhhXZ4QqujIZEfS4l6Cg==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", + "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz", + "integrity": "sha512-2+EPwgbnmOIl8HjGBXXMd9NAu02vLjOO1nWw4kmeRDFyHn+M/ETfHxQUK0oXg8ctgVnl9t3rosNVsZ1jG61nDA==", + "dev": true + }, + "split": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", + "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "dev": true, + "requires": { + "through": "2" + } + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "split2": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-2.2.0.tgz", + "integrity": "sha512-RAb22TG39LhI31MbreBgIuKiIKhVsawfTgEGqKHTK87aG+ul/PB8Sqoi3I7kVdRWiCfrKxK3uo4/YUkpNvhPbw==", + "dev": true, + "requires": { + "through2": "^2.0.2" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "sshpk": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.1.tgz", + "integrity": "sha1-Ew9Zde3a2WPx1W+SuaxsUfqfg+s=", + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "tweetnacl": "~0.14.0" + } + }, + "stack-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.1.tgz", + "integrity": "sha1-1PM6tU6OOHeLDKXP07OvsS22hiA=", + "dev": true + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.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=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "stealthy-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=" + }, + "stream-combiner2": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz", + "integrity": "sha1-+02KFCDqNidk4hrUeAOXvry0HL4=", + "dev": true, + "requires": { + "duplexer2": "~0.1.0", + "readable-stream": "^2.0.2" + } + }, + "strict-uri-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", + "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=", + "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": { + "astral-regex": "^1.0.0", + "strip-ansi": "^4.0.0" + }, + "dependencies": { + "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" + } + } + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "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", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "stringstream": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", + "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=" + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dev": true, + "requires": { + "is-utf8": "^0.2.0" + } + }, + "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 + }, + "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": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + }, + "symbol-tree": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.2.tgz", + "integrity": "sha1-rifbOPZgp64uHDt9G8KQgZuFGeY=", + "dev": true + }, + "table": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz", + "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", + "dev": true, + "requires": { + "ajv": "^5.2.3", + "ajv-keywords": "^2.1.0", + "chalk": "^2.1.0", + "lodash": "^4.17.4", + "slice-ansi": "1.0.0", + "string-width": "^2.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.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 + }, + "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 + }, + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "dev": true + }, + "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": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "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" + } + }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "term-size": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz", + "integrity": "sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=", + "dev": true, + "requires": { + "execa": "^0.7.0" + } + }, + "test-exclude": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-4.2.1.tgz", + "integrity": "sha512-qpqlP/8Zl+sosLxBcVKl9vYy26T9NPalxSzzCP/OY6K7j938ui2oKgo+kRZYfxAeIpLqpbVnsHq1tyV70E4lWQ==", + "dev": true, + "requires": { + "arrify": "^1.0.1", + "micromatch": "^3.1.8", + "object-assign": "^4.1.0", + "read-pkg-up": "^1.0.1", + "require-main-filename": "^1.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 + }, + "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" + } + } + } + }, + "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": { + "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, + "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, + "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, + "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-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, + "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-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, + "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 + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": 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, + "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, + "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" + } + } + } + }, + "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" + } + }, + "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=", + "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 + }, + "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" + } + } + } + }, + "text-extensions": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-1.7.0.tgz", + "integrity": "sha512-AKXZeDq230UaSzaO5s3qQUZOaC7iKbzq0jOFL614R7d9R593HLqAOL0cYoqLdkNrjBSOdmoQI06yigq1TSBXAg==", + "dev": true + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "throat": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/throat/-/throat-4.1.0.tgz", + "integrity": "sha1-iQN8vJLFarGJJua6TLsgDhVnKmo=", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "through2": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", + "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "dev": true, + "requires": { + "readable-stream": "^2.1.5", + "xtend": "~4.0.1" + } + }, + "timed-out": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", + "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=", + "dev": true + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.2" + } + }, + "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": "1.0.3", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", + "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", + "dev": true + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "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": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", + "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", + "requires": { + "punycode": "^1.4.1" + } + }, + "tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", + "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 + } + } + }, + "traverse": { + "version": "0.6.6", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.6.tgz", + "integrity": "sha1-y99WD9e5r2MlAv7UD5GMFX6pcTc=", + "dev": true + }, + "travis-deploy-once": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/travis-deploy-once/-/travis-deploy-once-5.0.0.tgz", + "integrity": "sha512-SUELtUqzseE0oKU9a1dwntytnudYcNX8v2lK3vdJw93ASqj7QRC+t+4Sx3lW9Jy9n3maXPHMQtsFkKw7XGG3/w==", + "dev": true, + "requires": { + "babel-polyfill": "^6.26.0", + "babel-preset-env": "^1.6.1", + "babel-register": "^6.26.0", + "chalk": "^2.1.0", + "execa": "^0.10.0", + "got": "^8.0.1", + "p-retry": "^2.0.0", + "semver": "^5.4.1", + "update-notifier": "^2.3.0", + "url-join": "^4.0.0", + "yargs": "^11.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "cliui": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", + "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", + "dev": true, + "requires": { + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0", + "wrap-ansi": "^2.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" + } + }, + "execa": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.10.0.tgz", + "integrity": "sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "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" + } + }, + "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" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "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 + }, + "semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", + "dev": true + }, + "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": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "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" + } + }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "yargs": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-11.0.0.tgz", + "integrity": "sha512-Rjp+lMYQOWtgqojx1dEWorjCofi1YN7AoFvYV7b1gx/7dAAeuI4kN5SZiEvr0ZmsZTOpDRcCqrpI10L31tFkBw==", + "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" + } + }, + "yargs-parser": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-9.0.2.tgz", + "integrity": "sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc=", + "dev": true, + "requires": { + "camelcase": "^4.1.0" + } + } + } + }, + "trim-off-newlines": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/trim-off-newlines/-/trim-off-newlines-1.0.1.tgz", + "integrity": "sha1-n5up2e+odkw4dpi8v+sshI8RrbM=", + "dev": true + }, + "trim-right": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", + "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", + "dev": true + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "optional": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "uber-client": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/uber-client/-/uber-client-0.0.4.tgz", + "integrity": "sha1-SbuxIw/bWcd/rfmPAbUKkekcdrw=", + "requires": { + "enumify": "1.0.4", + "immutable": "3.8.1", + "request": "^2.79.0", + "request-promise": "4.1.1" + }, + "dependencies": { + "immutable": { + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.8.1.tgz", + "integrity": "sha1-IAgH8Rqw9ycQ6khVQt4IgHX2jNI=" + } + } + }, + "uglify-js": { + "version": "2.8.29", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", + "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", + "dev": true, + "optional": true, + "requires": { + "source-map": "~0.5.1", + "uglify-to-browserify": "~1.0.0", + "yargs": "~3.10.0" + } + }, + "uglify-to-browserify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", + "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", + "dev": true, + "optional": true + }, + "unicode-canonical-property-names-ecmascript": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.3.tgz", + "integrity": "sha512-iG/2t0F2LAU8aZYPkX5gi7ebukHnr3sWFESpb+zPQeeaQwOkfoO6ZW17YX7MdRPNG9pCy+tjzGill+Ah0Em0HA==", + "dev": true + }, + "unicode-match-property-ecmascript": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.3.tgz", + "integrity": "sha512-nFcaBFcr08UQNF15ZgI5ISh3yUnQm7SJRRxwYrL5VYX46pS+6Q7TCTv4zbK+j6/l7rQt0mMiTL2zpmeygny6rA==", + "dev": true, + "requires": { + "unicode-canonical-property-names-ecmascript": "^1.0.2", + "unicode-property-aliases-ecmascript": "^1.0.3" + } + }, + "unicode-match-property-value-ecmascript": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.0.1.tgz", + "integrity": "sha512-lM8B0FDZQh9yYGgiabRQcyWicB27VLOolSBRIxsO7FeQPtg+79Oe7sC8Mzr8BObDs+G9CeYmC/shHo6OggNEog==", + "dev": true + }, + "unicode-property-aliases-ecmascript": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.3.tgz", + "integrity": "sha512-TdDmDOTxEf2ad1g3ZBpM6cqKIb2nJpVlz1Q++casDryKz18tpeMBhSng9hjC1CTQCkOV9Rw2knlSB6iRo7ad1w==", + "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=", + "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" + } + } + } + }, + "unique-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz", + "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=", + "dev": true, + "requires": { + "crypto-random-string": "^1.0.0" + } + }, + "universalify": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.1.tgz", + "integrity": "sha1-+nG63UQ3r0wUiEHjs7Fl+enlkLc=", + "dev": true + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "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 + } + } + }, + "unzip-response": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz", + "integrity": "sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c=", + "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 + }, + "update-notifier": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-2.5.0.tgz", + "integrity": "sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw==", + "dev": true, + "requires": { + "boxen": "^1.2.1", + "chalk": "^2.0.1", + "configstore": "^3.0.0", + "import-lazy": "^2.1.0", + "is-ci": "^1.0.10", + "is-installed-globally": "^0.1.0", + "is-npm": "^1.0.0", + "latest-version": "^3.0.0", + "semver-diff": "^2.0.0", + "xdg-basedir": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.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 + }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "dev": true + }, + "url-join": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.0.tgz", + "integrity": "sha1-TTNA6AfTdzvamZH4MFrNzCpmXSo=", + "dev": true + }, + "url-parse-lax": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", + "dev": true, + "requires": { + "prepend-http": "^2.0.0" + } + }, + "url-template": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", + "integrity": "sha1-/FZaPMy/93MMd19WQflVV5FDnyE=", + "dev": true + }, + "url-to-options": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz", + "integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=", + "dev": true + }, + "urlgrey": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/urlgrey/-/urlgrey-0.4.4.tgz", + "integrity": "sha1-iS/pWWCAXoVRnxzUOJ8stMu3ZS8=", + "dev": true + }, + "use": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.0.tgz", + "integrity": "sha512-6UJEQM/L+mzC3ZJNM56Q4DFGLX/evKGRg15UJHGB9X5j5Z3AFbgZvjUh2yq/UJUY4U5dh7Fal++XbNg1uzpRAw==", + "dev": true, + "requires": { + "kind-of": "^6.0.2" + }, + "dependencies": { + "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 + } + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "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, + "requires": { + "define-properties": "^1.1.2", + "object.getownpropertydescriptors": "^2.0.3" + } + }, + "uuid": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz", + "integrity": "sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA==" + }, + "validate-npm-package-license": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.3.tgz", + "integrity": "sha512-63ZOUnL4SIXj4L0NixR3L1lcjO38crAbgrTpl28t8jjrfuiOBL5Iygm+60qPs/KsZGzPNg6Smnc/oY16QTjF0g==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "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" + } + }, + "watch": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/watch/-/watch-0.18.0.tgz", + "integrity": "sha1-KAlUdsbffJDJYxOJkMClQj60uYY=", + "dev": true, + "requires": { + "exec-sh": "^0.2.0", + "minimist": "^1.2.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "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.3", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.3.tgz", + "integrity": "sha512-jLBwwKUhi8WtBfsMQlL4bUUcT8sMkAtQinscJAe/M4KHCkHuUJAF6vuB0tueNIw4c8ziO6AkRmgY+jL3a0iiPw==", + "dev": true, + "requires": { + "iconv-lite": "0.4.19" + } + }, + "whatwg-mimetype": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.1.0.tgz", + "integrity": "sha512-FKxhYLytBQiUKjkYteN71fAUA3g6KpNXoho1isLiLSB3N1G4F35Q5vUxWfKFhBwi5IWF27VE6WxhrnnC+m0Mew==", + "dev": true + }, + "whatwg-url": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.4.1.tgz", + "integrity": "sha512-FwygsxsXx27x6XXuExA/ox3Ktwcbf+OAvrKmLulotDAiO1Q6ixchPFaHYsis2zZBZSJTR0+dR+JVtf7MlbqZjw==", + "dev": true, + "requires": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, + "which": { + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz", + "integrity": "sha1-mofEN48D6CfOyvGs31bHNsAcFOU=", + "dev": true, + "requires": { + "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 + }, + "widest-line": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.0.tgz", + "integrity": "sha1-AUKk6KJD+IgsAjOqDgKBqnYVInM=", + "dev": true, + "requires": { + "string-width": "^2.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "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 + }, + "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": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "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" + } + } + } + }, + "window-size": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", + "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=", + "dev": true, + "optional": true + }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + } + }, + "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=", + "dev": true, + "requires": { + "mkdirp": "^0.5.1" + } + }, + "write-file-atomic": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.3.0.tgz", + "integrity": "sha512-xuPeK4OdjWqtfi59ylvVL0Yn35SF3zgcAcv7rBPFHVaEapaDr4GdGgm3j7ckTwH9wHL7fGmgfAnb0+THrHb8tA==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } + }, + "xdg-basedir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz", + "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=", + "dev": true + }, + "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 + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true + }, + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", + "dev": true + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + }, + "yargs": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", + "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", + "dev": true, + "optional": true, + "requires": { + "camelcase": "^1.0.2", + "cliui": "^2.1.0", + "decamelize": "^1.0.0", + "window-size": "0.1.0" + } + }, + "yargs-parser": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-8.1.0.tgz", + "integrity": "sha512-yP+6QqN8BmrgW2ggLtTbdrOyBNSI7zBa4IykmiV5R1wl1JWNxQvWhMfMdmzIYtKU7oP3OOInY/tl2ov3BDjnJQ==", + "dev": true, + "requires": { + "camelcase": "^4.1.0" + }, + "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 + } + } + } + } +} diff --git a/package.json b/package.json index 1bf1614..fc13d75 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,7 @@ "uber": "build/executables/uber.js" }, "dependencies": { + "@babel/runtime": "^7.0.0-beta.47", "@google/maps": "^0.3.1", "cli-table2": "^0.2.0", "colors": "^1.1.2 ", @@ -18,37 +19,31 @@ "uber-client": "^0.0.4" }, "devDependencies": { - "babel-cli": "^6.7.7", - "babel-core": "^6.8.0", - "babel-istanbul": "^0.8.0", - "babel-node-debug": "^2.0.0", - "babel-polyfill": "^6.8.0", - "babel-preset-es2015": "^6.6.0", - "babel-preset-stage-0": "^6.5.0", - "babel-register": "^6.8.0", - "chai": "^3.5.0", - "chai-as-promised": "^6.0.0", - "chai-immutable": "^1.6.0", - "coveralls": "^2.11.9", - "eslint": "^3.19.0", - "eslint-config-airbnb-base": "^11.2.0", - "eslint-plugin-chai-expect": "^1.1.1", - "eslint-plugin-import": "^2.3.0", - "eslint-plugin-mocha": "^4.10.1", - "istanbul": "^1.0.0-alpha.2", - "mocha": "^2.5.3", - "mocha-lcov-reporter": "^1.2.0 ", - "sinon": "^2.1.0", - "sinon-chai": "^2.9.0" - }, - "directories": { - "lib": "build", - "test": "test" + "@babel/cli": "^7.0.0-beta.49", + "@babel/core": "^7.0.0-beta.49", + "@babel/plugin-transform-async-to-generator": "^7.0.0-beta.49", + "@babel/plugin-transform-runtime": "^7.0.0-beta.49", + "@babel/preset-env": "^7.0.0-beta.49", + "babel-core": "^7.0.0-bridge.0", + "babel-jest": "^23.0.1", + "babel-preset-minify": "^0.4.2", + "codecov": "^3.0.2", + "eslint": "^4.12.0", + "eslint-config-airbnb-base": "^12.1.0", + "eslint-plugin-import": "^2.8.0", + "husky": "^0.14.3", + "jest": "^22.1.1", + "semantic-release": "^15.0.0", + "travis-deploy-once": "^5.0.0" }, "homepage": "https://github.com/jaebradley/uber-cli", "keywords": [ "uber" ], + "jest": { + "testEnvironment": "node", + "collectCoverage": true + }, "license": "MIT", "main": "./build/executables/uber.js", "preferGlobal": true, @@ -57,12 +52,15 @@ "url": "https://github.com/jaebradley/uber-cli/tree/master" }, "scripts": { - "compile": "./node_modules/.bin/babel --presets es2015,stage-0 -d build/ src/", - "coverage": "babel-node ./node_modules/istanbul/lib/cli cover node_modules/mocha/bin/_mocha test -- --recursive --compilers js:babel-core/register", - "coveralls": "npm run compile && npm run coverage && node_modules/.bin/coveralls < coverage/lcov.info", - "prepublish": "npm run compile", - "lint": "eslint src && eslint test", - "test": "npm run compile && mocha --recursive --compilers js:babel-core/register", - "build": "npm run lint && npm run coveralls" + "codecov": "codecov", + "commitmsg": "commitlint -e $GIT_PARAMS", + "compile": "babel src/ -d build/ --delete-dir-on-start", + "compile:prod": "BABEL_ENV=production npm run compile", + "lint": "eslint --ext .js .", + "test": "jest", + "prepublishOnly": "npm run compile:prod", + "semantic-commit": "commit", + "semantic-release": "semantic-release", + "travis-deploy-once": "travis-deploy-once" } } diff --git a/test/.eslintrc.json b/test/.eslintrc.json deleted file mode 100644 index 9e6d41f..0000000 --- a/test/.eslintrc.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "plugins": [ - "mocha" - ], - "rules": { - "mocha/no-exclusive-tests": "error", - "import/no-extraneous-dependencies": [ - "error", - { - "devDependencies": true - } - ] - }, - "env": { - "mocha": true - } -} diff --git a/test/services/symbols/BaseSymbolServiceTest.js b/test/services/symbols/BaseSymbolService.test.js similarity index 54% rename from test/services/symbols/BaseSymbolServiceTest.js rename to test/services/symbols/BaseSymbolService.test.js index 1c26d34..48a7cd5 100644 --- a/test/services/symbols/BaseSymbolServiceTest.js +++ b/test/services/symbols/BaseSymbolService.test.js @@ -1,50 +1,45 @@ -import chai from 'chai'; - import BaseSymbolService from '../../../src/services/symbols/BaseSymbolService'; -const expect = chai.expect; - - describe('BaseSymbolService Test', () => { const service = new BaseSymbolService(); it('should throw when getting vehicle symbol', () => { - expect(() => service.getVehicleSymbol()).to.throw(Error); + expect(() => service.getVehicleSymbol()).toThrow(); }); it('should throw when getting price symbol', () => { - expect(() => service.getPriceSymbol()).to.throw(Error); + expect(() => service.getPriceSymbol()).toThrow(); }); it('should throw when getting trip distance symbol', () => { - expect(() => service.getTripDistanceSymbol()).to.throw(Error); + expect(() => service.getTripDistanceSymbol()).toThrow(); }); it('should throw when getting duration symbol', () => { - expect(() => service.getDurationSymbol()).to.throw(Error); + expect(() => service.getDurationSymbol()).toThrow(); }); it('should throw when getting surge symbol', () => { - expect(() => service.getSurgeSymbol()).to.throw(Error); + expect(() => service.getSurgeSymbol()).toThrow(); }); it('should throw when getting not applicable symbol', () => { - expect(() => service.getNotApplicableSymbol()).to.throw(Error); + expect(() => service.getNotApplicableSymbol()).toThrow(); }); it('should throw when getting surge present symbol', () => { - expect(() => service.getSurgePresentSymbol()).to.throw(Error); + expect(() => service.getSurgePresentSymbol()).toThrow(); }); it('should throw when getting destination symbol', () => { - expect(() => service.getDestinationSymbol()).to.throw(Error); + expect(() => service.getDestinationSymbol()).toThrow(); }); it('should throw when getting origin symbol', () => { - expect(() => service.getOriginSymbol()).to.throw(Error); + expect(() => service.getOriginSymbol()).toThrow(); }); it('should throw when getting maximum distance symbol', () => { - expect(() => service.getMaximumDistanceSymbol()).to.throw(Error); + expect(() => service.getMaximumDistanceSymbol()).toThrow(); }); }); From 0958d62afdde81810c5a305d70d08474ae06100c Mon Sep 17 00:00:00 2001 From: Jae Bradley Date: Mon, 4 Jun 2018 08:24:03 -0400 Subject: [PATCH 02/38] refactor(coordinate): remove Coordinate data class --- .gitignore | 2 ++ src/data/Coordinate.js | 9 --------- src/data/Location.js | 7 ++++--- src/services/translators/geocode/LocationTranslator.js | 5 ++--- test/GeocodeServiceTest.js | 5 ++--- .../translators/geocode/LocationTranslatorTest.js | 5 ++--- 6 files changed, 12 insertions(+), 21 deletions(-) delete mode 100644 src/data/Coordinate.js diff --git a/.gitignore b/.gitignore index b6e7612..a04ac2a 100644 --- a/.gitignore +++ b/.gitignore @@ -58,3 +58,5 @@ typings/ .env build/ + +.DS_Store diff --git a/src/data/Coordinate.js b/src/data/Coordinate.js deleted file mode 100644 index c048c61..0000000 --- a/src/data/Coordinate.js +++ /dev/null @@ -1,9 +0,0 @@ -import { Record } from 'immutable'; - -const defaults = { - latitude: 0, - longitude: 0, -}; - -export default class Coordinate extends Record(defaults) { -} diff --git a/src/data/Location.js b/src/data/Location.js index f502e9b..8563125 100644 --- a/src/data/Location.js +++ b/src/data/Location.js @@ -1,10 +1,11 @@ import { Record } from 'immutable'; -import Coordinate from './Coordinate'; - const defaults = { name: '', - coordinate: new Coordinate(), + coordinate: { + latitude: 0, + longitude: 0, + }, }; export default class Location extends Record(defaults) { diff --git a/src/services/translators/geocode/LocationTranslator.js b/src/services/translators/geocode/LocationTranslator.js index bdb594b..59e4e17 100644 --- a/src/services/translators/geocode/LocationTranslator.js +++ b/src/services/translators/geocode/LocationTranslator.js @@ -1,4 +1,3 @@ -import Coordinate from '../../../data/Coordinate'; import Location from '../../../data/Location'; import Utilities from '../../Utilities'; @@ -19,10 +18,10 @@ export default class LocationTranslator { const location = json[this.GEOMETRY_ADDRESS_FIELD_NAME][this.LOCATION_FIELD_NAME]; return new Location({ name: json[this.FORMATTED_ADDRESS_FIELD_NAME], - coordinate: new Coordinate({ + coordinate: { latitude: location[this.LATITUDE_FIELD_NAME], longitude: location[this.LONGITUDE_FIELD_NAME], - }), + }, }); } diff --git a/test/GeocodeServiceTest.js b/test/GeocodeServiceTest.js index ac73613..1df5fa4 100644 --- a/test/GeocodeServiceTest.js +++ b/test/GeocodeServiceTest.js @@ -4,7 +4,6 @@ import chaiImmutable from 'chai-immutable'; import { List } from 'immutable'; -import Coordinate from '../src/data/Coordinate'; import GeocodeService from '../src/services/GeocodeService'; import Location from '../src/data/Location'; @@ -19,10 +18,10 @@ describe('Test Geocode Service', () => { const address = '25 first street cambridge ma'; const location = new Location({ name: '25 First St, Cambridge, MA 02141, USA', - coordinate: new Coordinate({ + coordinate: { latitude: 42.369695, longitude: -71.07800569999999, - }), + }, }); const locations = List.of(location); diff --git a/test/services/translators/geocode/LocationTranslatorTest.js b/test/services/translators/geocode/LocationTranslatorTest.js index 3a7bc19..6a14fcf 100644 --- a/test/services/translators/geocode/LocationTranslatorTest.js +++ b/test/services/translators/geocode/LocationTranslatorTest.js @@ -4,7 +4,6 @@ import chai from 'chai'; import sinon from 'sinon'; import sinonChai from 'sinon-chai'; -import Coordinate from '../../../../src/data/Coordinate'; import Location from '../../../../src/data/Location'; import LocationTranslator from '../../../../src/services/translators/geocode/LocationTranslator'; @@ -78,10 +77,10 @@ describe('Location Translation', () => { it('translates valid json', () => { const expected = new Location({ name: 'foo', - coordinate: new Coordinate({ + coordinate: { latitude: 1.234, longitude: 5.678, - }), + }, }); const isValid = sinon.stub(translator, 'isValid').returns(true); expect(translator.translate(json)).to.eql(expected); From c4d43b4937f56d4a8cb53d95aa6f4289f1589e9b Mon Sep 17 00:00:00 2001 From: Jae Bradley Date: Mon, 4 Jun 2018 08:32:33 -0400 Subject: [PATCH 03/38] Remove Coordinate and Distance classes (#56) * refactor(coordinate): remove Coordinate data class * refactor(distance): remove Distance class --- .gitignore | 2 ++ src/data/Coordinate.js | 9 --------- src/data/Distance.js | 10 ---------- src/data/Location.js | 7 ++++--- src/data/PriceEstimate.js | 7 +++++-- src/data/TripPriceEstimate.js | 7 +++++-- src/services/DistanceConverter.js | 9 ++++----- .../estimates/TripPriceEstimateTranslator.js | 5 ++--- src/services/translators/geocode/LocationTranslator.js | 5 ++--- test/DistanceConverterTest.js | 9 ++++----- test/GeocodeServiceTest.js | 5 ++--- .../estimates/TripPriceEstimateTranslatorTest.js | 5 ++--- .../translators/geocode/LocationTranslatorTest.js | 5 ++--- 13 files changed, 34 insertions(+), 51 deletions(-) delete mode 100644 src/data/Coordinate.js delete mode 100644 src/data/Distance.js diff --git a/.gitignore b/.gitignore index b6e7612..a04ac2a 100644 --- a/.gitignore +++ b/.gitignore @@ -58,3 +58,5 @@ typings/ .env build/ + +.DS_Store diff --git a/src/data/Coordinate.js b/src/data/Coordinate.js deleted file mode 100644 index c048c61..0000000 --- a/src/data/Coordinate.js +++ /dev/null @@ -1,9 +0,0 @@ -import { Record } from 'immutable'; - -const defaults = { - latitude: 0, - longitude: 0, -}; - -export default class Coordinate extends Record(defaults) { -} diff --git a/src/data/Distance.js b/src/data/Distance.js deleted file mode 100644 index 7c66d70..0000000 --- a/src/data/Distance.js +++ /dev/null @@ -1,10 +0,0 @@ -import { Record } from 'immutable'; - -import DistanceUnit from './DistanceUnit'; - -const defaults = { - value: 0, - unit: DistanceUnit.MILE, -}; - -export default class Distance extends Record(defaults) {} diff --git a/src/data/Location.js b/src/data/Location.js index f502e9b..8563125 100644 --- a/src/data/Location.js +++ b/src/data/Location.js @@ -1,10 +1,11 @@ import { Record } from 'immutable'; -import Coordinate from './Coordinate'; - const defaults = { name: '', - coordinate: new Coordinate(), + coordinate: { + latitude: 0, + longitude: 0, + }, }; export default class Location extends Record(defaults) { diff --git a/src/data/PriceEstimate.js b/src/data/PriceEstimate.js index 346dba5..9a03b31 100644 --- a/src/data/PriceEstimate.js +++ b/src/data/PriceEstimate.js @@ -1,12 +1,15 @@ import { Record } from 'immutable'; -import Distance from './Distance'; +import DistanceUnit from './DistanceUnit'; import Duration from './Duration'; import PriceRange from './PriceRange'; const defaults = { productName: '', - distance: new Distance(), + distance: { + value: 0, + unit: DistanceUnit.MILE, + }, range: new PriceRange(), duration: new Duration(), // wont show up unless > 1 diff --git a/src/data/TripPriceEstimate.js b/src/data/TripPriceEstimate.js index ace8494..3e7d344 100644 --- a/src/data/TripPriceEstimate.js +++ b/src/data/TripPriceEstimate.js @@ -1,12 +1,15 @@ import { Record } from 'immutable'; -import Distance from './Distance'; +import DistanceUnit from './DistanceUnit'; import Duration from './Duration'; import PriceRange from './PriceRange'; const defaults = { productName: '', - distance: new Distance(), + distance: { + value: 0, + unit: DistanceUnit.MILE, + }, range: new PriceRange(), duration: new Duration(), // wont show up unless > 1 diff --git a/src/services/DistanceConverter.js b/src/services/DistanceConverter.js index 73f794a..40d42e5 100644 --- a/src/services/DistanceConverter.js +++ b/src/services/DistanceConverter.js @@ -1,7 +1,6 @@ import convert from 'convert-units'; import { Map } from 'immutable'; -import Distance from '../data/Distance'; import DistanceUnit from '../data/DistanceUnit'; export default class DistanceConverter { @@ -21,17 +20,17 @@ export default class DistanceConverter { switch (toUnit) { case DistanceUnit.KILOMETER: { // Note divided by 1000 because convert library does not have kilometers, so using meters - return new Distance({ + return { value: convertedValue / 1000, unit: DistanceUnit.KILOMETER, - }); + }; } case DistanceUnit.MILE: { - return new Distance({ + return { value: convertedValue, unit: DistanceUnit.MILE, - }); + }; } default: { diff --git a/src/services/translators/estimates/TripPriceEstimateTranslator.js b/src/services/translators/estimates/TripPriceEstimateTranslator.js index 28efcf9..a273fd8 100644 --- a/src/services/translators/estimates/TripPriceEstimateTranslator.js +++ b/src/services/translators/estimates/TripPriceEstimateTranslator.js @@ -1,6 +1,5 @@ import { Map } from 'immutable'; -import Distance from '../../../data/Distance'; import DistanceUnit from '../../../data/DistanceUnit'; import Duration from '../../../data/Duration'; import PriceRange from '../../../data/PriceRange'; @@ -14,10 +13,10 @@ export default class TripPriceEstimateTranslator { throw new Error(`invalid estimate: ${estimate}`); } - const distance = new Distance({ + const distance = { value: estimate[TripPriceEstimateTranslator.getDistanceFieldName()], unit: DistanceUnit.MILE, - }); + }; // Uber returns duration in seconds const duration = new Duration({ diff --git a/src/services/translators/geocode/LocationTranslator.js b/src/services/translators/geocode/LocationTranslator.js index bdb594b..59e4e17 100644 --- a/src/services/translators/geocode/LocationTranslator.js +++ b/src/services/translators/geocode/LocationTranslator.js @@ -1,4 +1,3 @@ -import Coordinate from '../../../data/Coordinate'; import Location from '../../../data/Location'; import Utilities from '../../Utilities'; @@ -19,10 +18,10 @@ export default class LocationTranslator { const location = json[this.GEOMETRY_ADDRESS_FIELD_NAME][this.LOCATION_FIELD_NAME]; return new Location({ name: json[this.FORMATTED_ADDRESS_FIELD_NAME], - coordinate: new Coordinate({ + coordinate: { latitude: location[this.LATITUDE_FIELD_NAME], longitude: location[this.LONGITUDE_FIELD_NAME], - }), + }, }); } diff --git a/test/DistanceConverterTest.js b/test/DistanceConverterTest.js index c5bb978..542b84d 100644 --- a/test/DistanceConverterTest.js +++ b/test/DistanceConverterTest.js @@ -2,7 +2,6 @@ import chai from 'chai'; import sinon from 'sinon'; import sinonChai from 'sinon-chai'; -import Distance from '../src/data/Distance'; import DistanceUnit from '../src/data/DistanceUnit'; import DistanceConverter from '../src/services/DistanceConverter'; @@ -34,14 +33,14 @@ describe('Distance converter', () => { }); const distance = 1.234; - const distanceInMiles = new Distance({ + const distanceInMiles = { value: distance, unit: DistanceUnit.MILE, - }); - const distanceInKilometers = new Distance({ + }; + const distanceInKilometers = { value: distance / 1000, unit: DistanceUnit.KILOMETER, - }); + }; describe('converts successfully', () => { it('converts miles', () => { diff --git a/test/GeocodeServiceTest.js b/test/GeocodeServiceTest.js index ac73613..1df5fa4 100644 --- a/test/GeocodeServiceTest.js +++ b/test/GeocodeServiceTest.js @@ -4,7 +4,6 @@ import chaiImmutable from 'chai-immutable'; import { List } from 'immutable'; -import Coordinate from '../src/data/Coordinate'; import GeocodeService from '../src/services/GeocodeService'; import Location from '../src/data/Location'; @@ -19,10 +18,10 @@ describe('Test Geocode Service', () => { const address = '25 first street cambridge ma'; const location = new Location({ name: '25 First St, Cambridge, MA 02141, USA', - coordinate: new Coordinate({ + coordinate: { latitude: 42.369695, longitude: -71.07800569999999, - }), + }, }); const locations = List.of(location); diff --git a/test/services/translators/estimates/TripPriceEstimateTranslatorTest.js b/test/services/translators/estimates/TripPriceEstimateTranslatorTest.js index a9dfc5e..8a360c0 100644 --- a/test/services/translators/estimates/TripPriceEstimateTranslatorTest.js +++ b/test/services/translators/estimates/TripPriceEstimateTranslatorTest.js @@ -4,7 +4,6 @@ import sinonChai from 'sinon-chai'; import { Map } from 'immutable'; -import Distance from '../../../../src/data/Distance'; import DistanceUnit from '../../../../src/data/DistanceUnit'; import Duration from '../../../../src/data/Duration'; import PriceRange from '../../../../src/data/PriceRange'; @@ -133,10 +132,10 @@ describe('Trip Price Estimate Translation', () => { describe('Translate Estimate', () => { const args = Map({ productName, - distance: new Distance({ + distance: { value: distance, unit: DistanceUnit.MILE, - }), + }, duration: new Duration({ length: duration, unit: TimeUnit.SECOND, diff --git a/test/services/translators/geocode/LocationTranslatorTest.js b/test/services/translators/geocode/LocationTranslatorTest.js index 3a7bc19..6a14fcf 100644 --- a/test/services/translators/geocode/LocationTranslatorTest.js +++ b/test/services/translators/geocode/LocationTranslatorTest.js @@ -4,7 +4,6 @@ import chai from 'chai'; import sinon from 'sinon'; import sinonChai from 'sinon-chai'; -import Coordinate from '../../../../src/data/Coordinate'; import Location from '../../../../src/data/Location'; import LocationTranslator from '../../../../src/services/translators/geocode/LocationTranslator'; @@ -78,10 +77,10 @@ describe('Location Translation', () => { it('translates valid json', () => { const expected = new Location({ name: 'foo', - coordinate: new Coordinate({ + coordinate: { latitude: 1.234, longitude: 5.678, - }), + }, }); const isValid = sinon.stub(translator, 'isValid').returns(true); expect(translator.translate(json)).to.eql(expected); From 74dfd29a1b52ba47df31c4c76040ec6a0cf413e6 Mon Sep 17 00:00:00 2001 From: Jae Bradley Date: Mon, 4 Jun 2018 08:39:39 -0400 Subject: [PATCH 04/38] refactor(location): remove Location class (#57) --- src/data/Location.js | 12 ------------ src/data/PriceEstimates.js | 18 ++++++++++++++---- src/data/TimeEstimates.js | 10 +++++++--- .../translators/geocode/LocationTranslator.js | 5 ++--- test/GeocodeServiceTest.js | 5 ++--- .../geocode/LocationTranslatorTest.js | 6 ++---- 6 files changed, 27 insertions(+), 29 deletions(-) delete mode 100644 src/data/Location.js diff --git a/src/data/Location.js b/src/data/Location.js deleted file mode 100644 index 8563125..0000000 --- a/src/data/Location.js +++ /dev/null @@ -1,12 +0,0 @@ -import { Record } from 'immutable'; - -const defaults = { - name: '', - coordinate: { - latitude: 0, - longitude: 0, - }, -}; - -export default class Location extends Record(defaults) { -} diff --git a/src/data/PriceEstimates.js b/src/data/PriceEstimates.js index 4621053..e7775e8 100644 --- a/src/data/PriceEstimates.js +++ b/src/data/PriceEstimates.js @@ -1,10 +1,20 @@ import { List, Record } from 'immutable'; -import Location from './Location'; - const defaults = { - start: new Location(), - end: new Location(), + start: { + name: '', + coordinate: { + latitude: 0, + longitude: 0, + }, + }, + end: { + name: '', + coordinate: { + latitude: 0, + longitude: 0, + }, + }, estimates: List(), }; diff --git a/src/data/TimeEstimates.js b/src/data/TimeEstimates.js index 29ab187..6106f6b 100644 --- a/src/data/TimeEstimates.js +++ b/src/data/TimeEstimates.js @@ -1,9 +1,13 @@ import { List, Record } from 'immutable'; -import Location from './Location'; - const defaults = { - location: new Location(), + location: { + name: '', + coordinate: { + latitude: 0, + longitude: 0, + }, + }, estimates: List(), }; diff --git a/src/services/translators/geocode/LocationTranslator.js b/src/services/translators/geocode/LocationTranslator.js index 59e4e17..c29b5c5 100644 --- a/src/services/translators/geocode/LocationTranslator.js +++ b/src/services/translators/geocode/LocationTranslator.js @@ -1,4 +1,3 @@ -import Location from '../../../data/Location'; import Utilities from '../../Utilities'; export default class LocationTranslator { @@ -16,13 +15,13 @@ export default class LocationTranslator { } const location = json[this.GEOMETRY_ADDRESS_FIELD_NAME][this.LOCATION_FIELD_NAME]; - return new Location({ + return { name: json[this.FORMATTED_ADDRESS_FIELD_NAME], coordinate: { latitude: location[this.LATITUDE_FIELD_NAME], longitude: location[this.LONGITUDE_FIELD_NAME], }, - }); + }; } isValid(json) { diff --git a/test/GeocodeServiceTest.js b/test/GeocodeServiceTest.js index 1df5fa4..e91679c 100644 --- a/test/GeocodeServiceTest.js +++ b/test/GeocodeServiceTest.js @@ -5,7 +5,6 @@ import chaiImmutable from 'chai-immutable'; import { List } from 'immutable'; import GeocodeService from '../src/services/GeocodeService'; -import Location from '../src/data/Location'; import geocodeFile from './files/geocode.json'; @@ -16,13 +15,13 @@ chai.should(); describe('Test Geocode Service', () => { const service = new GeocodeService(); const address = '25 first street cambridge ma'; - const location = new Location({ + const location = { name: '25 First St, Cambridge, MA 02141, USA', coordinate: { latitude: 42.369695, longitude: -71.07800569999999, }, - }); + }; const locations = List.of(location); it('tests data fetching', () => service.getData(address).should.eventually.eql(geocodeFile)); diff --git a/test/services/translators/geocode/LocationTranslatorTest.js b/test/services/translators/geocode/LocationTranslatorTest.js index 6a14fcf..ceea187 100644 --- a/test/services/translators/geocode/LocationTranslatorTest.js +++ b/test/services/translators/geocode/LocationTranslatorTest.js @@ -4,8 +4,6 @@ import chai from 'chai'; import sinon from 'sinon'; import sinonChai from 'sinon-chai'; -import Location from '../../../../src/data/Location'; - import LocationTranslator from '../../../../src/services/translators/geocode/LocationTranslator'; chai.use(sinonChai); @@ -75,13 +73,13 @@ describe('Location Translation', () => { }); it('translates valid json', () => { - const expected = new Location({ + const expected = { name: 'foo', coordinate: { latitude: 1.234, longitude: 5.678, }, - }); + }; const isValid = sinon.stub(translator, 'isValid').returns(true); expect(translator.translate(json)).to.eql(expected); isValid.restore(); From 469e84d7c109bf0d84fd7fcb49ff1f5749a3793f Mon Sep 17 00:00:00 2001 From: Jae Bradley Date: Mon, 4 Jun 2018 08:46:06 -0400 Subject: [PATCH 05/38] refactor(price-range): remove PriceRange data class (#58) --- src/data/PriceEstimate.js | 7 +++++-- src/data/PriceRange.js | 9 --------- src/data/TripPriceEstimate.js | 7 +++++-- .../translators/estimates/TripPriceEstimateTranslator.js | 5 ++--- .../estimates/TripPriceEstimateTranslatorTest.js | 5 ++--- 5 files changed, 14 insertions(+), 19 deletions(-) delete mode 100644 src/data/PriceRange.js diff --git a/src/data/PriceEstimate.js b/src/data/PriceEstimate.js index 9a03b31..7f5d61f 100644 --- a/src/data/PriceEstimate.js +++ b/src/data/PriceEstimate.js @@ -2,7 +2,6 @@ import { Record } from 'immutable'; import DistanceUnit from './DistanceUnit'; import Duration from './Duration'; -import PriceRange from './PriceRange'; const defaults = { productName: '', @@ -10,7 +9,11 @@ const defaults = { value: 0, unit: DistanceUnit.MILE, }, - range: new PriceRange(), + range: { + low: 0, + high: 0, + currencyCode: 'USD', + }, duration: new Duration(), // wont show up unless > 1 surgeMultiplier: 1, diff --git a/src/data/PriceRange.js b/src/data/PriceRange.js deleted file mode 100644 index 110d4c5..0000000 --- a/src/data/PriceRange.js +++ /dev/null @@ -1,9 +0,0 @@ -import { Record } from 'immutable'; - -const defaults = { - low: 0, - high: 0, - currencyCode: 'USD', -}; - -export default class PriceRange extends Record(defaults) {} diff --git a/src/data/TripPriceEstimate.js b/src/data/TripPriceEstimate.js index 3e7d344..ef48eb0 100644 --- a/src/data/TripPriceEstimate.js +++ b/src/data/TripPriceEstimate.js @@ -2,7 +2,6 @@ import { Record } from 'immutable'; import DistanceUnit from './DistanceUnit'; import Duration from './Duration'; -import PriceRange from './PriceRange'; const defaults = { productName: '', @@ -10,7 +9,11 @@ const defaults = { value: 0, unit: DistanceUnit.MILE, }, - range: new PriceRange(), + range: { + low: 0, + high: 0, + currencyCode: 'USD', + }, duration: new Duration(), // wont show up unless > 1 surgeMultiplier: 1, diff --git a/src/services/translators/estimates/TripPriceEstimateTranslator.js b/src/services/translators/estimates/TripPriceEstimateTranslator.js index a273fd8..60faab8 100644 --- a/src/services/translators/estimates/TripPriceEstimateTranslator.js +++ b/src/services/translators/estimates/TripPriceEstimateTranslator.js @@ -2,7 +2,6 @@ import { Map } from 'immutable'; import DistanceUnit from '../../../data/DistanceUnit'; import Duration from '../../../data/Duration'; -import PriceRange from '../../../data/PriceRange'; import TimeUnit from '../../../data/TimeUnit'; import TripPriceEstimate from '../../../data/TripPriceEstimate'; import Utilities from '../../Utilities'; @@ -24,11 +23,11 @@ export default class TripPriceEstimateTranslator { unit: TimeUnit.SECOND, }); - const range = new PriceRange({ + const range = { high: estimate[TripPriceEstimateTranslator.getHighEstimateFieldName()], low: estimate[TripPriceEstimateTranslator.getLowEstimateFieldName()], currencyCode: estimate[TripPriceEstimateTranslator.getCurrencyCodeFieldName()], - }); + }; let args = Map({ productName: estimate[TripPriceEstimateTranslator.getProductNameFieldName()], diff --git a/test/services/translators/estimates/TripPriceEstimateTranslatorTest.js b/test/services/translators/estimates/TripPriceEstimateTranslatorTest.js index 8a360c0..88c0b05 100644 --- a/test/services/translators/estimates/TripPriceEstimateTranslatorTest.js +++ b/test/services/translators/estimates/TripPriceEstimateTranslatorTest.js @@ -6,7 +6,6 @@ import { Map } from 'immutable'; import DistanceUnit from '../../../../src/data/DistanceUnit'; import Duration from '../../../../src/data/Duration'; -import PriceRange from '../../../../src/data/PriceRange'; import TimeUnit from '../../../../src/data/TimeUnit'; import TripPriceEstimate from '../../../../src/data/TripPriceEstimate'; @@ -140,11 +139,11 @@ describe('Trip Price Estimate Translation', () => { length: duration, unit: TimeUnit.SECOND, }), - range: new PriceRange({ + range: { high: highEstimate, low: lowEstimate, currencyCode, - }), + }, }); const argsWithSurgeMultiplier = args.set('surgeMultiplier', surgeMultiplier); From ed3ccad03b12dc0f4e31acf3fa6d43f3a755e008 Mon Sep 17 00:00:00 2001 From: Jae Bradley Date: Mon, 4 Jun 2018 08:51:28 -0400 Subject: [PATCH 06/38] refactor(duration): remove Duration class (#59) --- src/data/Duration.js | 11 ------ src/data/PickupTimeEstimate.js | 7 +++- src/data/PriceEstimate.js | 7 +++- src/data/TripPriceEstimate.js | 7 +++- src/services/DurationConverter.js | 5 +-- .../estimates/PickupTimeEstimateTranslator.js | 5 +-- .../estimates/TripPriceEstimateTranslator.js | 5 +-- test/DurationConverterTest.js | 5 +-- test/services/DurationFormatterTest.js | 37 +++++++++---------- .../PickupTimeEstimateTranslatorTest.js | 5 +-- .../TripPriceEstimateTranslatorTest.js | 5 +-- 11 files changed, 45 insertions(+), 54 deletions(-) delete mode 100644 src/data/Duration.js diff --git a/src/data/Duration.js b/src/data/Duration.js deleted file mode 100644 index f6dafb5..0000000 --- a/src/data/Duration.js +++ /dev/null @@ -1,11 +0,0 @@ -import { Record } from 'immutable'; - -import TimeUnit from './TimeUnit'; - -const defaults = { - length: 0, - unit: TimeUnit.SECOND, -}; - -export default class Duration extends Record(defaults) { -} diff --git a/src/data/PickupTimeEstimate.js b/src/data/PickupTimeEstimate.js index c48a2d7..3da035f 100644 --- a/src/data/PickupTimeEstimate.js +++ b/src/data/PickupTimeEstimate.js @@ -1,10 +1,13 @@ import { Record } from 'immutable'; -import Duration from './Duration'; +import TimeUnit from './TimeUnit'; const defaults = { productName: '', - estimatedDuration: new Duration(), + estimatedDuration: { + length: 0, + unit: TimeUnit.SECOND, + }, }; export default class PickupTimeEstimate extends Record(defaults) {} diff --git a/src/data/PriceEstimate.js b/src/data/PriceEstimate.js index 7f5d61f..a7c798f 100644 --- a/src/data/PriceEstimate.js +++ b/src/data/PriceEstimate.js @@ -1,7 +1,7 @@ import { Record } from 'immutable'; import DistanceUnit from './DistanceUnit'; -import Duration from './Duration'; +import TimeUnit from './TimeUnit'; const defaults = { productName: '', @@ -14,7 +14,10 @@ const defaults = { high: 0, currencyCode: 'USD', }, - duration: new Duration(), + duration: { + length: 0, + unit: TimeUnit.SECOND, + }, // wont show up unless > 1 surgeMultiplier: 1, }; diff --git a/src/data/TripPriceEstimate.js b/src/data/TripPriceEstimate.js index ef48eb0..a0d3433 100644 --- a/src/data/TripPriceEstimate.js +++ b/src/data/TripPriceEstimate.js @@ -1,7 +1,7 @@ import { Record } from 'immutable'; import DistanceUnit from './DistanceUnit'; -import Duration from './Duration'; +import TimeUnit from './TimeUnit'; const defaults = { productName: '', @@ -14,7 +14,10 @@ const defaults = { high: 0, currencyCode: 'USD', }, - duration: new Duration(), + duration: { + length: 0, + unit: TimeUnit.SECOND, + }, // wont show up unless > 1 surgeMultiplier: 1, }; diff --git a/src/services/DurationConverter.js b/src/services/DurationConverter.js index b378f02..bc89817 100644 --- a/src/services/DurationConverter.js +++ b/src/services/DurationConverter.js @@ -1,7 +1,6 @@ import convert from 'convert-units'; import { Map } from 'immutable'; -import Duration from '../data/Duration'; import TimeUnit from '../data/TimeUnit'; export default class DurationConverter { @@ -17,10 +16,10 @@ export default class DurationConverter { const fromUnitIdentifier = this.getUnitConversionIdentifier(duration.unit); const toUnitIdentifier = this.getUnitConversionIdentifier(toUnit); const convertedLength = convert(duration.length).from(fromUnitIdentifier).to(toUnitIdentifier); - return new Duration({ + return { length: convertedLength, unit: toUnit, - }); + }; } getUnitConversionIdentifier(unit) { diff --git a/src/services/translators/estimates/PickupTimeEstimateTranslator.js b/src/services/translators/estimates/PickupTimeEstimateTranslator.js index b3996d0..6b335c8 100644 --- a/src/services/translators/estimates/PickupTimeEstimateTranslator.js +++ b/src/services/translators/estimates/PickupTimeEstimateTranslator.js @@ -1,4 +1,3 @@ -import Duration from '../../../data/Duration'; import TimeUnit from '../../../data/TimeUnit'; import PickupTimeEstimate from '../../../data/PickupTimeEstimate'; @@ -10,10 +9,10 @@ export default class PickupTimeEstimateTranslator { return new PickupTimeEstimate({ productName: estimate[PickupTimeEstimateTranslator.getProductNameFieldName()], - estimatedDuration: new Duration({ + estimatedDuration: { length: estimate[PickupTimeEstimateTranslator.getEstimateFieldName()], unit: TimeUnit.SECOND, - }), + }, }); } diff --git a/src/services/translators/estimates/TripPriceEstimateTranslator.js b/src/services/translators/estimates/TripPriceEstimateTranslator.js index 60faab8..66aeeb9 100644 --- a/src/services/translators/estimates/TripPriceEstimateTranslator.js +++ b/src/services/translators/estimates/TripPriceEstimateTranslator.js @@ -1,7 +1,6 @@ import { Map } from 'immutable'; import DistanceUnit from '../../../data/DistanceUnit'; -import Duration from '../../../data/Duration'; import TimeUnit from '../../../data/TimeUnit'; import TripPriceEstimate from '../../../data/TripPriceEstimate'; import Utilities from '../../Utilities'; @@ -18,10 +17,10 @@ export default class TripPriceEstimateTranslator { }; // Uber returns duration in seconds - const duration = new Duration({ + const duration = { length: estimate[TripPriceEstimateTranslator.getDurationFieldName()], unit: TimeUnit.SECOND, - }); + }; const range = { high: estimate[TripPriceEstimateTranslator.getHighEstimateFieldName()], diff --git a/test/DurationConverterTest.js b/test/DurationConverterTest.js index dc68d4c..a502f97 100644 --- a/test/DurationConverterTest.js +++ b/test/DurationConverterTest.js @@ -3,7 +3,6 @@ import chaiImmutable from 'chai-immutable'; import { Map } from 'immutable'; -import Duration from '../src/data/Duration'; import TimeUnit from '../src/data/TimeUnit'; import DurationConverter from '../src/services/DurationConverter'; @@ -15,10 +14,10 @@ const expect = chai.expect; describe('Duration converter', () => { const converter = new DurationConverter(); const length = 60; - const durationInSeconds = new Duration({ + const durationInSeconds = { length, unit: TimeUnit.SECOND, - }); + }; it('validates construction', () => { const expected = {}; diff --git a/test/services/DurationFormatterTest.js b/test/services/DurationFormatterTest.js index c6ad200..17657f6 100644 --- a/test/services/DurationFormatterTest.js +++ b/test/services/DurationFormatterTest.js @@ -4,7 +4,6 @@ import sinon from 'sinon'; import sinonChai from 'sinon-chai'; import TimeUnit from '../../src/data/TimeUnit'; -import Duration from '../../src/data/Duration'; import DurationConverter from '../../src/services/DurationConverter'; import DurationFormatter from '../../src/services/DurationFormatter'; @@ -19,10 +18,10 @@ describe('Duration Formatter', () => { const formatter = new DurationFormatter(converter); describe('throws exception', () => { - const negativeDuration = new Duration({ + const negativeDuration = { length: -1, unit: TimeUnit.SECOND, - }); + }; it('throws exception', () => { const durationConversion = sinon.stub(converter, 'convert').returns(negativeDuration); @@ -32,10 +31,10 @@ describe('Duration Formatter', () => { }); describe('0 seconds', () => { - const zeroSeconds = new Duration({ + const zeroSeconds = { length: 0, unit: TimeUnit.SECOND, - }); + }; it('returns 0 sec.', () => { const durationConversion = sinon.stub(converter, 'convert').returns(zeroSeconds); @@ -45,70 +44,70 @@ describe('Duration Formatter', () => { }); describe('formats', () => { - const underAMinute = new Duration({ + const underAMinute = { length: 59, unit: TimeUnit.SECOND, - }); + }; it('under a minute', () => { const durationConversion = sinon.stub(converter, 'convert').returns(underAMinute); expect(formatter.format()).to.eql('59 sec.'); durationConversion.restore(); }); - const aMinute = new Duration({ + const aMinute = { length: 60, unit: TimeUnit.SECOND, - }); + }; it('a minute', () => { const durationConversion = sinon.stub(converter, 'convert').returns(aMinute); expect(formatter.format()).to.eql('1 min.'); durationConversion.restore(); }); - const overAMinute = new Duration({ + const overAMinute = { length: 61, unit: TimeUnit.SECOND, - }); + }; it('over a minute', () => { const durationConversion = sinon.stub(converter, 'convert').returns(overAMinute); expect(formatter.format()).to.eql('1 min. 1 sec.'); durationConversion.restore(); }); - const underAnHour = new Duration({ + const underAnHour = { length: 3599, unit: TimeUnit.SECOND, - }); + }; it('under an hour', () => { const durationConversion = sinon.stub(converter, 'convert').returns(underAnHour); expect(formatter.format()).to.eql('59 min. 59 sec.'); durationConversion.restore(); }); - const anHour = new Duration({ + const anHour = { length: 3600, unit: TimeUnit.SECOND, - }); + }; it('an hour', () => { const durationConversion = sinon.stub(converter, 'convert').returns(anHour); expect(formatter.format()).to.eql('1 hrs.'); durationConversion.restore(); }); - const underADay = new Duration({ + const underADay = { length: 86399, unit: TimeUnit.SECOND, - }); + }; it('under a day', () => { const durationConversion = sinon.stub(converter, 'convert').returns(underADay); expect(formatter.format()).to.eql('23 hrs. 59 min. 59 sec.'); durationConversion.restore(); }); - const aDay = new Duration({ + const aDay = { length: 86400, unit: TimeUnit.SECOND, - }); + }; it('a day', () => { const durationConversion = sinon.stub(converter, 'convert').returns(aDay); expect(formatter.format()).to.eql('1 days'); diff --git a/test/services/translators/estimates/PickupTimeEstimateTranslatorTest.js b/test/services/translators/estimates/PickupTimeEstimateTranslatorTest.js index 6224aa7..f9634bb 100644 --- a/test/services/translators/estimates/PickupTimeEstimateTranslatorTest.js +++ b/test/services/translators/estimates/PickupTimeEstimateTranslatorTest.js @@ -2,7 +2,6 @@ import chai from 'chai'; import sinon from 'sinon'; import sinonChai from 'sinon-chai'; -import Duration from '../../../../src/data/Duration'; import TimeUnit from '../../../../src/data/TimeUnit'; import PickupTimeEstimate from '../../../../src/data/PickupTimeEstimate'; @@ -55,10 +54,10 @@ describe('Pickup Time Estimate Translation', () => { it('translates valid json', () => { const expected = new PickupTimeEstimate({ productName, - estimatedDuration: new Duration({ + estimatedDuration: { length: estimateSeconds, unit: TimeUnit.SECOND, - }), + }, }); const isValid = sinon.stub(translator, 'isValid').returns(true); expect(translator.translate(estimate)).to.eql(expected); diff --git a/test/services/translators/estimates/TripPriceEstimateTranslatorTest.js b/test/services/translators/estimates/TripPriceEstimateTranslatorTest.js index 88c0b05..35df767 100644 --- a/test/services/translators/estimates/TripPriceEstimateTranslatorTest.js +++ b/test/services/translators/estimates/TripPriceEstimateTranslatorTest.js @@ -5,7 +5,6 @@ import sinonChai from 'sinon-chai'; import { Map } from 'immutable'; import DistanceUnit from '../../../../src/data/DistanceUnit'; -import Duration from '../../../../src/data/Duration'; import TimeUnit from '../../../../src/data/TimeUnit'; import TripPriceEstimate from '../../../../src/data/TripPriceEstimate'; @@ -135,10 +134,10 @@ describe('Trip Price Estimate Translation', () => { value: distance, unit: DistanceUnit.MILE, }, - duration: new Duration({ + duration: { length: duration, unit: TimeUnit.SECOND, - }), + }, range: { high: highEstimate, low: lowEstimate, From bbee7d7eabefdda6036107a407f5352e61667c85 Mon Sep 17 00:00:00 2001 From: Jae Bradley Date: Mon, 4 Jun 2018 08:58:22 -0400 Subject: [PATCH 07/38] refactor(price-estimate-query): remove PriceEstimateQuery class (#60) --- src/data/PriceEstimateQuery.js | 8 -------- src/services/CommandExecutionService.js | 5 ++--- test/UberServiceIntegrationTest.js | 5 ++--- 3 files changed, 4 insertions(+), 14 deletions(-) delete mode 100644 src/data/PriceEstimateQuery.js diff --git a/src/data/PriceEstimateQuery.js b/src/data/PriceEstimateQuery.js deleted file mode 100644 index 0e60982..0000000 --- a/src/data/PriceEstimateQuery.js +++ /dev/null @@ -1,8 +0,0 @@ -import { Record } from 'immutable'; - -const defaults = { - startAddress: '', - endAddress: '', -}; - -export default class PriceEstimateQuery extends Record(defaults) {} diff --git a/src/services/CommandExecutionService.js b/src/services/CommandExecutionService.js index ed7097a..df6ed07 100644 --- a/src/services/CommandExecutionService.js +++ b/src/services/CommandExecutionService.js @@ -1,5 +1,4 @@ import DistanceUnit from '../data/DistanceUnit'; -import PriceEstimateQuery from '../data/PriceEstimateQuery'; import UberService from './UberService'; import DistanceConverter from './DistanceConverter'; import DurationConverter from './DurationConverter'; @@ -41,10 +40,10 @@ export default class CommandExecutionService { throw new TypeError(`Unknown distance unit: ${distanceUnitName}`); } - const query = new PriceEstimateQuery({ + const query = { startAddress, endAddress, - }); + }; return this.uberService.getPriceEstimates(query) .then(estimates => this.tripPriceEstimatesTableBuilder.build(estimates, distanceUnit)); diff --git a/test/UberServiceIntegrationTest.js b/test/UberServiceIntegrationTest.js index e1ccf0b..658a3d9 100644 --- a/test/UberServiceIntegrationTest.js +++ b/test/UberServiceIntegrationTest.js @@ -4,7 +4,6 @@ import chai from 'chai'; import chaiAsPromised from 'chai-as-promised'; import chaiImmutable from 'chai-immutable'; -import PriceEstimateQuery from '../src/data/PriceEstimateQuery'; import UberService from '../src/services/UberService'; import DistanceUnit from '../src/data/DistanceUnit'; @@ -16,11 +15,11 @@ describe('Test Uber Service', () => { const service = new UberService(); const address = '25 first street cambridge ma'; const address2 = '114 line street somerville ma'; - const priceEstimateQuery = new PriceEstimateQuery({ + const priceEstimateQuery = { startAddress: address, endAddress: address2, distanceUnit: DistanceUnit.MILE, - }); + }; it('tests time estimates fulfillment', () => service.getTimeEstimates(address).should.be.fulfilled); From 6890a1f5b1e74b7cf8343153b65e0d11a1cd1a45 Mon Sep 17 00:00:00 2001 From: Jae Bradley Date: Mon, 4 Jun 2018 09:07:33 -0400 Subject: [PATCH 08/38] Remove time, pickup time, and price estimates classes (#61) * refactor(time-estimate): remove TimeEstimate class * refactor(pickup-time-estimate): remove PickupTimeEstimate class * refactor(price-estimates): remove PriceEstimates class --- src/data/PickupTimeEstimate.js | 13 ------------ src/data/PriceEstimates.js | 21 ------------------- src/data/TimeEstimate.js | 8 ------- src/services/UberService.js | 3 +-- .../estimates/PickupTimeEstimateTranslator.js | 5 ++--- test/services/UberServiceTest.js | 5 ++--- .../PickupTimeEstimateTranslatorTest.js | 5 ++--- 7 files changed, 7 insertions(+), 53 deletions(-) delete mode 100644 src/data/PickupTimeEstimate.js delete mode 100644 src/data/PriceEstimates.js delete mode 100644 src/data/TimeEstimate.js diff --git a/src/data/PickupTimeEstimate.js b/src/data/PickupTimeEstimate.js deleted file mode 100644 index 3da035f..0000000 --- a/src/data/PickupTimeEstimate.js +++ /dev/null @@ -1,13 +0,0 @@ -import { Record } from 'immutable'; - -import TimeUnit from './TimeUnit'; - -const defaults = { - productName: '', - estimatedDuration: { - length: 0, - unit: TimeUnit.SECOND, - }, -}; - -export default class PickupTimeEstimate extends Record(defaults) {} diff --git a/src/data/PriceEstimates.js b/src/data/PriceEstimates.js deleted file mode 100644 index e7775e8..0000000 --- a/src/data/PriceEstimates.js +++ /dev/null @@ -1,21 +0,0 @@ -import { List, Record } from 'immutable'; - -const defaults = { - start: { - name: '', - coordinate: { - latitude: 0, - longitude: 0, - }, - }, - end: { - name: '', - coordinate: { - latitude: 0, - longitude: 0, - }, - }, - estimates: List(), -}; - -export default class PriceEstimates extends Record(defaults) {} diff --git a/src/data/TimeEstimate.js b/src/data/TimeEstimate.js deleted file mode 100644 index 000c6f0..0000000 --- a/src/data/TimeEstimate.js +++ /dev/null @@ -1,8 +0,0 @@ -import { Record } from 'immutable'; - -const defaults = { - productName: '', - estimateSeconds: 0, -}; - -export default class TimeEstimate extends Record(defaults) {} diff --git a/src/services/UberService.js b/src/services/UberService.js index 580afee..85315f6 100644 --- a/src/services/UberService.js +++ b/src/services/UberService.js @@ -1,7 +1,6 @@ import { UberClient } from 'uber-client'; import GeocodeService from './GeocodeService'; -import PriceEstimates from '../data/PriceEstimates'; import TimeEstimates from '../data/TimeEstimates'; import PickupTimeEstimateTranslator from './translators/estimates/PickupTimeEstimateTranslator'; import PickupTimeEstimatesTranslator from './translators/estimates/PickupTimeEstimatesTranslator'; @@ -43,7 +42,7 @@ export default class UberService { .then(([start, end]) => this.client .getPriceEstimates({ start: start.coordinate, end: end.coordinate }) - .then(response => new PriceEstimates({ + .then(response => ({ start, end, estimates: this.tripPriceEstimatesTranslator.translate(response), diff --git a/src/services/translators/estimates/PickupTimeEstimateTranslator.js b/src/services/translators/estimates/PickupTimeEstimateTranslator.js index 6b335c8..6700700 100644 --- a/src/services/translators/estimates/PickupTimeEstimateTranslator.js +++ b/src/services/translators/estimates/PickupTimeEstimateTranslator.js @@ -1,5 +1,4 @@ import TimeUnit from '../../../data/TimeUnit'; -import PickupTimeEstimate from '../../../data/PickupTimeEstimate'; export default class PickupTimeEstimateTranslator { translate(estimate) { @@ -7,13 +6,13 @@ export default class PickupTimeEstimateTranslator { throw new Error(`Invalid estimate: ${JSON.stringify(estimate)}`); } - return new PickupTimeEstimate({ + return { productName: estimate[PickupTimeEstimateTranslator.getProductNameFieldName()], estimatedDuration: { length: estimate[PickupTimeEstimateTranslator.getEstimateFieldName()], unit: TimeUnit.SECOND, }, - }); + }; } isValid(estimate) { diff --git a/test/services/UberServiceTest.js b/test/services/UberServiceTest.js index 7700165..0651410 100644 --- a/test/services/UberServiceTest.js +++ b/test/services/UberServiceTest.js @@ -9,7 +9,6 @@ import sinonChai from 'sinon-chai'; import { List } from 'immutable'; import TimeEstimates from '../../src/data/TimeEstimates'; -import PriceEstimates from '../../src/data/PriceEstimates'; import UberService from '../../src/services/UberService'; @@ -63,11 +62,11 @@ describe('Uber Service', () => { const firstLocation = sinon.stub(uberService, 'getFirstLocation').returns(Promise.resolve('jaebaebae')); const clientPriceEstimation = sinon.stub(uberService.client, 'getPriceEstimates').returns(Promise.resolve({})); const priceEstimatesTranslation = sinon.stub(uberService.tripPriceEstimatesTranslator, 'translate').returns(Promise.resolve('bae jadley')); - const expected = new PriceEstimates({ + const expected = { start: 'jaebaebae', end: 'jaebaebae', estimates: 'bae jadley', - }); + }; expect(uberService.getPriceEstimates({ startAddress: 'jae', endAddress: 'baebae' })).to.eventually.eql(expected); firstLocation.restore(); diff --git a/test/services/translators/estimates/PickupTimeEstimateTranslatorTest.js b/test/services/translators/estimates/PickupTimeEstimateTranslatorTest.js index f9634bb..3ddf891 100644 --- a/test/services/translators/estimates/PickupTimeEstimateTranslatorTest.js +++ b/test/services/translators/estimates/PickupTimeEstimateTranslatorTest.js @@ -3,7 +3,6 @@ import sinon from 'sinon'; import sinonChai from 'sinon-chai'; import TimeUnit from '../../../../src/data/TimeUnit'; -import PickupTimeEstimate from '../../../../src/data/PickupTimeEstimate'; import PickupTimeEstimateTranslator from '../../../../src/services/translators/estimates/PickupTimeEstimateTranslator'; @@ -52,13 +51,13 @@ describe('Pickup Time Estimate Translation', () => { }); it('translates valid json', () => { - const expected = new PickupTimeEstimate({ + const expected = { productName, estimatedDuration: { length: estimateSeconds, unit: TimeUnit.SECOND, }, - }); + }; const isValid = sinon.stub(translator, 'isValid').returns(true); expect(translator.translate(estimate)).to.eql(expected); isValid.restore(); From af79e63550a834570c80d96279e69508ceaf334b Mon Sep 17 00:00:00 2001 From: Jae Bradley Date: Mon, 4 Jun 2018 09:15:39 -0400 Subject: [PATCH 09/38] refactor(time-estimates): remove TimeEstimates class (#62) --- src/data/TimeEstimates.js | 14 -------------- src/services/UberService.js | 3 +-- test/services/UberServiceTest.js | 6 ++---- 3 files changed, 3 insertions(+), 20 deletions(-) delete mode 100644 src/data/TimeEstimates.js diff --git a/src/data/TimeEstimates.js b/src/data/TimeEstimates.js deleted file mode 100644 index 6106f6b..0000000 --- a/src/data/TimeEstimates.js +++ /dev/null @@ -1,14 +0,0 @@ -import { List, Record } from 'immutable'; - -const defaults = { - location: { - name: '', - coordinate: { - latitude: 0, - longitude: 0, - }, - }, - estimates: List(), -}; - -export default class TimeEstimates extends Record(defaults) {} diff --git a/src/services/UberService.js b/src/services/UberService.js index 85315f6..514e577 100644 --- a/src/services/UberService.js +++ b/src/services/UberService.js @@ -1,7 +1,6 @@ import { UberClient } from 'uber-client'; import GeocodeService from './GeocodeService'; -import TimeEstimates from '../data/TimeEstimates'; import PickupTimeEstimateTranslator from './translators/estimates/PickupTimeEstimateTranslator'; import PickupTimeEstimatesTranslator from './translators/estimates/PickupTimeEstimatesTranslator'; import TripPriceEstimateTranslator from './translators/estimates/TripPriceEstimateTranslator'; @@ -29,7 +28,7 @@ export default class UberService { getTimeEstimates(address) { return this.getFirstLocation(address) .then(location => this.client.getTimeEstimates({ start: location.coordinate }) - .then(estimates => new TimeEstimates({ + .then(estimates => ({ location, estimates: this.pickupTimeEstimatesTranslator.translate(estimates), }))); diff --git a/test/services/UberServiceTest.js b/test/services/UberServiceTest.js index 0651410..968fea6 100644 --- a/test/services/UberServiceTest.js +++ b/test/services/UberServiceTest.js @@ -8,8 +8,6 @@ import sinonChai from 'sinon-chai'; import { List } from 'immutable'; -import TimeEstimates from '../../src/data/TimeEstimates'; - import UberService from '../../src/services/UberService'; chai.use(chaiAsPromised); @@ -44,10 +42,10 @@ describe('Uber Service', () => { const firstLocation = sinon.stub(uberService, 'getFirstLocation').returns(Promise.resolve('jaebaebae')); const clientTimeEstimation = sinon.stub(uberService.client, 'getTimeEstimates').returns(Promise.resolve({})); const pickupTimeTranslation = sinon.stub(uberService.pickupTimeEstimatesTranslator, 'translate').returns(Promise.resolve('bae jadley')); - const expected = new TimeEstimates({ + const expected = { location: 'jaebaebae', estimates: 'baejadley', - }); + }; expect(uberService.getTimeEstimates()).to.eventually.eql(expected); From 80077ee98adddc006c7b95f2b76b9ad33a8156d8 Mon Sep 17 00:00:00 2001 From: Jae Bradley Date: Mon, 4 Jun 2018 09:22:02 -0400 Subject: [PATCH 10/38] Remove time and price estimates classes (#63) * refactor(time-estimates): remove TimeEstimates class * refactor(price-estimate): remove PriceEstimate class * refactor(trip-price-estimate): remove TripPriceEsimate class --- src/data/PriceEstimate.js | 25 ------------------- src/data/TripPriceEstimate.js | 25 ------------------- .../estimates/TripPriceEstimateTranslator.js | 3 +-- .../TripPriceEstimateTranslatorTest.js | 5 ++-- 4 files changed, 3 insertions(+), 55 deletions(-) delete mode 100644 src/data/PriceEstimate.js delete mode 100644 src/data/TripPriceEstimate.js diff --git a/src/data/PriceEstimate.js b/src/data/PriceEstimate.js deleted file mode 100644 index a7c798f..0000000 --- a/src/data/PriceEstimate.js +++ /dev/null @@ -1,25 +0,0 @@ -import { Record } from 'immutable'; - -import DistanceUnit from './DistanceUnit'; -import TimeUnit from './TimeUnit'; - -const defaults = { - productName: '', - distance: { - value: 0, - unit: DistanceUnit.MILE, - }, - range: { - low: 0, - high: 0, - currencyCode: 'USD', - }, - duration: { - length: 0, - unit: TimeUnit.SECOND, - }, - // wont show up unless > 1 - surgeMultiplier: 1, -}; - -export default class PriceEstimate extends Record(defaults) {} diff --git a/src/data/TripPriceEstimate.js b/src/data/TripPriceEstimate.js deleted file mode 100644 index a0d3433..0000000 --- a/src/data/TripPriceEstimate.js +++ /dev/null @@ -1,25 +0,0 @@ -import { Record } from 'immutable'; - -import DistanceUnit from './DistanceUnit'; -import TimeUnit from './TimeUnit'; - -const defaults = { - productName: '', - distance: { - value: 0, - unit: DistanceUnit.MILE, - }, - range: { - low: 0, - high: 0, - currencyCode: 'USD', - }, - duration: { - length: 0, - unit: TimeUnit.SECOND, - }, - // wont show up unless > 1 - surgeMultiplier: 1, -}; - -export default class TripPriceEstimate extends Record(defaults) {} diff --git a/src/services/translators/estimates/TripPriceEstimateTranslator.js b/src/services/translators/estimates/TripPriceEstimateTranslator.js index 66aeeb9..bc82e43 100644 --- a/src/services/translators/estimates/TripPriceEstimateTranslator.js +++ b/src/services/translators/estimates/TripPriceEstimateTranslator.js @@ -2,7 +2,6 @@ import { Map } from 'immutable'; import DistanceUnit from '../../../data/DistanceUnit'; import TimeUnit from '../../../data/TimeUnit'; -import TripPriceEstimate from '../../../data/TripPriceEstimate'; import Utilities from '../../Utilities'; export default class TripPriceEstimateTranslator { @@ -39,7 +38,7 @@ export default class TripPriceEstimateTranslator { args = args.set('surgeMultiplier', estimate[TripPriceEstimateTranslator.getSurgeMultiplierFieldName()]); } - return new TripPriceEstimate(args); + return args; } isValid(estimate) { diff --git a/test/services/translators/estimates/TripPriceEstimateTranslatorTest.js b/test/services/translators/estimates/TripPriceEstimateTranslatorTest.js index 35df767..285fd9d 100644 --- a/test/services/translators/estimates/TripPriceEstimateTranslatorTest.js +++ b/test/services/translators/estimates/TripPriceEstimateTranslatorTest.js @@ -6,7 +6,6 @@ import { Map } from 'immutable'; import DistanceUnit from '../../../../src/data/DistanceUnit'; import TimeUnit from '../../../../src/data/TimeUnit'; -import TripPriceEstimate from '../../../../src/data/TripPriceEstimate'; import TripPriceEstimateTranslator from '../../../../src/services/translators/estimates/TripPriceEstimateTranslator'; @@ -156,13 +155,13 @@ describe('Trip Price Estimate Translation', () => { describe('Valid', () => { it('translates valid estimate without surge multiplier', () => { sandbox.stub(translator, 'isValid').returns(true); - const expected = new TripPriceEstimate(args); + const expected = args; expect(translator.translate(estimateWithoutSurgeMultiplier)).to.eql(expected); }); it('translates valid estimate with surge multiplier', () => { sandbox.stub(translator, 'isValid').returns(true); - const expected = new TripPriceEstimate(argsWithSurgeMultiplier); + const expected = argsWithSurgeMultiplier; expect(translator.translate(estimateWithSurgeMultiplier)).to.eql(expected); }); }); From fe15cf3f316412603fdfcef21f1de3ab23342f78 Mon Sep 17 00:00:00 2001 From: Jae Bradley Date: Mon, 4 Jun 2018 09:41:53 -0400 Subject: [PATCH 11/38] refactor(immutable): remove immutable js (#64) --- package-lock.json | 5 ---- package.json | 1 - src/services/DistanceConverter.js | 3 +-- src/services/DurationConverter.js | 3 +-- src/services/symbols/SymbolService.js | 4 +-- .../PickupTimeEstimatesTableRowsBuilder.js | 6 ++--- .../tables/TripPriceEstimateRowFormatter.js | 8 +++--- .../PickupTimeEstimatesTableBuilder.js | 25 +++++++++---------- .../TripPriceEstimatesTableBuilder.js | 23 ++++++++--------- .../PickupTimeEstimatesTranslator.js | 4 +-- .../estimates/TripPriceEstimateTranslator.js | 6 ++--- .../estimates/TripPriceEstimatesTranslator.js | 4 +-- .../geocode/LocationsTranslator.js | 4 +-- test/DurationConverterTest.js | 10 -------- test/GeocodeServiceTest.js | 11 -------- test/UberServiceIntegrationTest.js | 8 ------ test/services/DurationFormatterTest.js | 10 -------- test/services/UberServiceTest.js | 16 ------------ test/services/symbols/SymbolServiceTest.js | 11 -------- ...PickupTimeEstimatesTableRowsBuilderTest.js | 12 --------- .../TripPriceEstimateRowFormatterTest.js | 12 --------- .../PickupTimeEstimatesTableBuilderTest.js | 6 ----- .../TripPriceEstimatesTableBuilderTest.js | 11 -------- .../PickupTimeEstimatesTranslatorTest.js | 9 ------- .../TripPriceEstimateTranslatorTest.js | 10 -------- .../TripPriceEstimatesTranslatorTest.js | 10 -------- .../geocode/LocationsTranslatorTest.js | 12 --------- 27 files changed, 36 insertions(+), 208 deletions(-) diff --git a/package-lock.json b/package-lock.json index f86825f..aa8e371 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6675,11 +6675,6 @@ "integrity": "sha512-pUh+xUQQhQzevjRHHFqqcTy0/dP/kS9I8HSrUydhihjuD09W6ldVWFtIrwhXdUJHis3i2rZNqEHpZH/cbinFbg==", "dev": true }, - "immutable": { - "version": "3.8.2", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.8.2.tgz", - "integrity": "sha1-wkOZUUVbs5kT2vKBN28VMOEErfM=" - }, "import-from": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/import-from/-/import-from-2.1.0.tgz", diff --git a/package.json b/package.json index fc13d75..9c2ea76 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,6 @@ "commander": "^2.9.0", "convert-units": "^2.0.1", "enumify": "^1.0.4", - "immutable": "^3.8.1", "node-emoji": "^1.4.3", "uber-client": "^0.0.4" }, diff --git a/src/services/DistanceConverter.js b/src/services/DistanceConverter.js index 40d42e5..fab2249 100644 --- a/src/services/DistanceConverter.js +++ b/src/services/DistanceConverter.js @@ -1,5 +1,4 @@ import convert from 'convert-units'; -import { Map } from 'immutable'; import DistanceUnit from '../data/DistanceUnit'; @@ -9,7 +8,7 @@ export default class DistanceConverter { unitConversionIdentifier[DistanceUnit.MILE.name] = 'mi'; unitConversionIdentifier[DistanceUnit.KILOMETER.name] = 'm'; - this.unitConversionIdentifier = Map(unitConversionIdentifier); + this.unitConversionIdentifier = unitConversionIdentifier; } convert(distance, toUnit) { diff --git a/src/services/DurationConverter.js b/src/services/DurationConverter.js index bc89817..bf0b9cd 100644 --- a/src/services/DurationConverter.js +++ b/src/services/DurationConverter.js @@ -1,5 +1,4 @@ import convert from 'convert-units'; -import { Map } from 'immutable'; import TimeUnit from '../data/TimeUnit'; @@ -9,7 +8,7 @@ export default class DurationConverter { durationUnitAbbreviations[TimeUnit.SECOND.name] = 's'; durationUnitAbbreviations[TimeUnit.MINUTE.name] = 'min'; - this.durationUnitAbbreviations = Map(durationUnitAbbreviations); + this.durationUnitAbbreviations = durationUnitAbbreviations; } convert(duration, toUnit) { diff --git a/src/services/symbols/SymbolService.js b/src/services/symbols/SymbolService.js index f5f309a..dd3de83 100644 --- a/src/services/symbols/SymbolService.js +++ b/src/services/symbols/SymbolService.js @@ -1,5 +1,3 @@ -import { List } from 'immutable'; - import BaseSymbolService from './BaseSymbolService'; import EmojiService from './EmojiService'; import TextSymbolService from './TextSymbolService'; @@ -17,7 +15,7 @@ export default class SymbolService extends BaseSymbolService { } static getEmojiSupportedOperatingSystems() { - return List.of('darwin'); + return ['darwin']; } getVehicleSymbol() { diff --git a/src/services/tables/PickupTimeEstimatesTableRowsBuilder.js b/src/services/tables/PickupTimeEstimatesTableRowsBuilder.js index 560e5cc..045d133 100644 --- a/src/services/tables/PickupTimeEstimatesTableRowsBuilder.js +++ b/src/services/tables/PickupTimeEstimatesTableRowsBuilder.js @@ -1,5 +1,3 @@ -import { List, Map } from 'immutable'; - export default class PickupTimeEstimatesTableRowsBuilder { constructor(durationFormatter) { this.durationFormatter = durationFormatter; @@ -7,11 +5,11 @@ export default class PickupTimeEstimatesTableRowsBuilder { build(estimates) { const estimatesGroupedByTime = this.groupByTime(estimates); - return List(estimatesGroupedByTime.entrySeq().map(entry => List.of(entry[0], entry[1].join(', ')))); + return estimatesGroupedByTime.entrySeq().map(entry => [entry[0], entry[1]].join(', ')); } groupByTime(estimates) { - let rows = Map(); + let rows = {}; estimates.forEach((estimate) => { const formattedDuration = this.durationFormatter.format(estimate.estimatedDuration); diff --git a/src/services/tables/TripPriceEstimateRowFormatter.js b/src/services/tables/TripPriceEstimateRowFormatter.js index 41aac88..8c69cb2 100644 --- a/src/services/tables/TripPriceEstimateRowFormatter.js +++ b/src/services/tables/TripPriceEstimateRowFormatter.js @@ -1,5 +1,3 @@ -import { List, Map } from 'immutable'; - import DistanceUnit from '../../data/DistanceUnit'; export default class TripPriceEstimateRowFormatter { @@ -8,20 +6,20 @@ export default class TripPriceEstimateRowFormatter { distanceUnitAbbreviations[DistanceUnit.MILE.name] = 'mi'; distanceUnitAbbreviations[DistanceUnit.KILOMETER.name] = 'km'; - this.distanceUnitAbbreviations = Map(distanceUnitAbbreviations); + this.distanceUnitAbbreviations = distanceUnitAbbreviations; this.distanceConverter = distanceConverter; this.durationFormatter = durationFormatter; this.symbolService = symbolService; } format(estimate, rowDistanceUnit) { - return List.of( + return [ estimate.productName, this.formatRange(estimate.range), this.formatDistance(estimate.distance, rowDistanceUnit), this.durationFormatter.format(estimate.duration), this.formatSurgeMultiplier(estimate.surgeMultiplier), - ); + ]; } formatRange(range) { diff --git a/src/services/tables/builders/PickupTimeEstimatesTableBuilder.js b/src/services/tables/builders/PickupTimeEstimatesTableBuilder.js index 85c6e1b..7b1eff3 100644 --- a/src/services/tables/builders/PickupTimeEstimatesTableBuilder.js +++ b/src/services/tables/builders/PickupTimeEstimatesTableBuilder.js @@ -1,5 +1,4 @@ import Table from 'cli-table2'; -import { List, Map } from 'immutable'; export default class PickupTimeEstimatesTableBuilder { constructor(rowsBuilder, symbolService) { @@ -9,39 +8,39 @@ export default class PickupTimeEstimatesTableBuilder { build(estimates) { const table = this.buildInitialTable(estimates.location.name); - this.rowsBuilder.build(estimates.estimates).forEach(row => table.push(row.toJS())); + this.rowsBuilder.build(estimates.estimates).forEach(row => table.push(row)); return table.toString(); } getTableHeaders() { - return List.of( + return [ this.symbolService.getDurationSymbol(), this.symbolService.getVehicleSymbol(), - ); + ]; } getFormattedLocation(locationName) { - return List.of( - Map({ + return [ + { colSpan: 2, content: `${this.symbolService.getOriginSymbol()} ${locationName}`, hAlign: 'center', - }), - ); + }, + ]; } getFormattedHeaders() { - return List(this.getTableHeaders() - .map(header => Map({ + return this.getTableHeaders() + .map(header => ({ content: header, hAlign: 'center', - }))); + })); } buildInitialTable(locationName) { const table = new Table(); - table.push(this.getFormattedLocation(locationName).toJS()); - table.push(this.getFormattedHeaders().toJS()); + table.push(this.getFormattedLocation(locationName)); + table.push(this.getFormattedHeaders()); return table; } } diff --git a/src/services/tables/builders/TripPriceEstimatesTableBuilder.js b/src/services/tables/builders/TripPriceEstimatesTableBuilder.js index 29760dc..0a6a9dd 100644 --- a/src/services/tables/builders/TripPriceEstimatesTableBuilder.js +++ b/src/services/tables/builders/TripPriceEstimatesTableBuilder.js @@ -1,5 +1,4 @@ import Table from 'cli-table2'; -import { List, Map } from 'immutable'; export default class TripPriceEstimatesTableBuilder { constructor(rowFormatter, symbolService) { @@ -11,11 +10,11 @@ export default class TripPriceEstimatesTableBuilder { const table = this.buildInitialTable(); estimates.estimates.forEach((estimate) => { if (estimate.productName !== 'TAXI') { - table.push(this.rowFormatter.format(estimate, presentationDistanceUnit).toJS()); + table.push(this.rowFormatter.format(estimate, presentationDistanceUnit)); } }); - table.push(this.buildLocationRow(estimates.start.name, false).toJS()); - table.push(this.buildLocationRow(estimates.end.name, true).toJS()); + table.push(this.buildLocationRow(estimates.start.name, false)); + table.push(this.buildLocationRow(estimates.end.name, true)); return table.toString(); } @@ -31,23 +30,23 @@ export default class TripPriceEstimatesTableBuilder { buildInitialTable() { const table = new Table(); - const formattedHeaders = List(this.getTableHeaders().map(header => Map({ content: header, hAlign: 'center' }))); - table.push(formattedHeaders.toJS()); + const formattedHeaders = this.getTableHeaders().map(header => ({ content: header, hAlign: 'center' })); + table.push(formattedHeaders); return table; } buildLocationRow(name, isEnd) { - return List.of( - Map({ + return [ + { colSpan: 1, content: this.getEndSymbol(isEnd), hAlign: 'center', - }), - Map({ + }, + { colSpan: 4, content: name, - }), - ); + }, + ]; } getEndSymbol(isEnd) { diff --git a/src/services/translators/estimates/PickupTimeEstimatesTranslator.js b/src/services/translators/estimates/PickupTimeEstimatesTranslator.js index ff1e98d..89c029c 100644 --- a/src/services/translators/estimates/PickupTimeEstimatesTranslator.js +++ b/src/services/translators/estimates/PickupTimeEstimatesTranslator.js @@ -1,5 +1,3 @@ -import { List } from 'immutable'; - export default class PickupTimeEstimatesTranslator { constructor(estimateTranslator) { this.estimateTranslator = estimateTranslator; @@ -12,7 +10,7 @@ export default class PickupTimeEstimatesTranslator { const estimatedDurations = estimates[PickupTimeEstimatesTranslator.getEstimatedDurationsFieldName()]; // eslint-disable-line max-len - return List(estimatedDurations.map(estimatedDuration => this.estimateTranslator.translate(estimatedDuration))); // eslint-disable-line max-len + return estimatedDurations.map(estimatedDuration => this.estimateTranslator.translate(estimatedDuration)); // eslint-disable-line max-len } isValid(estimates) { diff --git a/src/services/translators/estimates/TripPriceEstimateTranslator.js b/src/services/translators/estimates/TripPriceEstimateTranslator.js index bc82e43..8a946e2 100644 --- a/src/services/translators/estimates/TripPriceEstimateTranslator.js +++ b/src/services/translators/estimates/TripPriceEstimateTranslator.js @@ -1,5 +1,3 @@ -import { Map } from 'immutable'; - import DistanceUnit from '../../../data/DistanceUnit'; import TimeUnit from '../../../data/TimeUnit'; import Utilities from '../../Utilities'; @@ -27,12 +25,12 @@ export default class TripPriceEstimateTranslator { currencyCode: estimate[TripPriceEstimateTranslator.getCurrencyCodeFieldName()], }; - let args = Map({ + let args = { productName: estimate[TripPriceEstimateTranslator.getProductNameFieldName()], distance, duration, range, - }); + }; if (TripPriceEstimateTranslator.getSurgeMultiplierFieldName() in estimate) { args = args.set('surgeMultiplier', estimate[TripPriceEstimateTranslator.getSurgeMultiplierFieldName()]); diff --git a/src/services/translators/estimates/TripPriceEstimatesTranslator.js b/src/services/translators/estimates/TripPriceEstimatesTranslator.js index 97b2f74..66c79e9 100644 --- a/src/services/translators/estimates/TripPriceEstimatesTranslator.js +++ b/src/services/translators/estimates/TripPriceEstimatesTranslator.js @@ -1,5 +1,3 @@ -import { List } from 'immutable'; - export default class TripPriceEstimatesTranslator { constructor(tripPriceEstimateTranslator) { this.tripPriceEstimateTranslator = tripPriceEstimateTranslator; @@ -12,7 +10,7 @@ export default class TripPriceEstimatesTranslator { const priceEstimates = estimates[TripPriceEstimatesTranslator.getPricesFieldName()]; - return List(priceEstimates.map(priceEstimate => this.tripPriceEstimateTranslator.translate(priceEstimate))); // eslint-disable-line max-len + return priceEstimates.map(priceEstimate => this.tripPriceEstimateTranslator.translate(priceEstimate)); // eslint-disable-line max-len } isValid(estimates) { diff --git a/src/services/translators/geocode/LocationsTranslator.js b/src/services/translators/geocode/LocationsTranslator.js index 04e8ab5..81619e6 100644 --- a/src/services/translators/geocode/LocationsTranslator.js +++ b/src/services/translators/geocode/LocationsTranslator.js @@ -1,5 +1,3 @@ -import { List } from 'immutable'; - export default class LocationsTranslator { constructor(locationTranslator) { this.STATUS_FIELD_NAME = 'status'; @@ -15,7 +13,7 @@ export default class LocationsTranslator { const results = json[this.RESULTS_FIELD_NAME]; - return List(results.map(result => this.locationTranslator.translate(result))); + return results.map(result => this.locationTranslator.translate(result)); } isValid(json) { diff --git a/test/DurationConverterTest.js b/test/DurationConverterTest.js index a502f97..6df1f2b 100644 --- a/test/DurationConverterTest.js +++ b/test/DurationConverterTest.js @@ -1,16 +1,6 @@ -import chai from 'chai'; -import chaiImmutable from 'chai-immutable'; - -import { Map } from 'immutable'; - import TimeUnit from '../src/data/TimeUnit'; - import DurationConverter from '../src/services/DurationConverter'; -chai.use(chaiImmutable); - -const expect = chai.expect; - describe('Duration converter', () => { const converter = new DurationConverter(); const length = 60; diff --git a/test/GeocodeServiceTest.js b/test/GeocodeServiceTest.js index e91679c..40c457a 100644 --- a/test/GeocodeServiceTest.js +++ b/test/GeocodeServiceTest.js @@ -1,17 +1,6 @@ -import chai from 'chai'; -import chaiAsPromised from 'chai-as-promised'; -import chaiImmutable from 'chai-immutable'; - -import { List } from 'immutable'; - import GeocodeService from '../src/services/GeocodeService'; - import geocodeFile from './files/geocode.json'; -chai.use(chaiAsPromised); -chai.use(chaiImmutable); -chai.should(); - describe('Test Geocode Service', () => { const service = new GeocodeService(); const address = '25 first street cambridge ma'; diff --git a/test/UberServiceIntegrationTest.js b/test/UberServiceIntegrationTest.js index 658a3d9..5db9660 100644 --- a/test/UberServiceIntegrationTest.js +++ b/test/UberServiceIntegrationTest.js @@ -1,16 +1,8 @@ /* eslint-disable no-console */ -import chai from 'chai'; -import chaiAsPromised from 'chai-as-promised'; -import chaiImmutable from 'chai-immutable'; - import UberService from '../src/services/UberService'; import DistanceUnit from '../src/data/DistanceUnit'; -chai.use(chaiAsPromised); -chai.use(chaiImmutable); -chai.should(); - describe('Test Uber Service', () => { const service = new UberService(); const address = '25 first street cambridge ma'; diff --git a/test/services/DurationFormatterTest.js b/test/services/DurationFormatterTest.js index 17657f6..ba3df12 100644 --- a/test/services/DurationFormatterTest.js +++ b/test/services/DurationFormatterTest.js @@ -1,18 +1,8 @@ -import chai from 'chai'; -import chaiImmutable from 'chai-immutable'; -import sinon from 'sinon'; -import sinonChai from 'sinon-chai'; - import TimeUnit from '../../src/data/TimeUnit'; import DurationConverter from '../../src/services/DurationConverter'; import DurationFormatter from '../../src/services/DurationFormatter'; -chai.use(chaiImmutable); -chai.use(sinonChai); - -const expect = chai.expect; - describe('Duration Formatter', () => { const converter = new DurationConverter(); const formatter = new DurationFormatter(converter); diff --git a/test/services/UberServiceTest.js b/test/services/UberServiceTest.js index 968fea6..dd987f6 100644 --- a/test/services/UberServiceTest.js +++ b/test/services/UberServiceTest.js @@ -1,21 +1,5 @@ -'use es6'; - -import chai from 'chai'; -import chaiAsPromised from 'chai-as-promised'; -import chaiImmutable from 'chai-immutable'; -import sinon from 'sinon'; -import sinonChai from 'sinon-chai'; - -import { List } from 'immutable'; - import UberService from '../../src/services/UberService'; -chai.use(chaiAsPromised); -chai.use(chaiImmutable); -chai.use(sinonChai); - -const expect = chai.expect; - describe('Uber Service', () => { const uberService = new UberService(); diff --git a/test/services/symbols/SymbolServiceTest.js b/test/services/symbols/SymbolServiceTest.js index 6973788..633f8eb 100644 --- a/test/services/symbols/SymbolServiceTest.js +++ b/test/services/symbols/SymbolServiceTest.js @@ -1,18 +1,7 @@ -import chai from 'chai'; -import chaiImmutable from 'chai-immutable'; -import sinon from 'sinon'; -import sinonChai from 'sinon-chai'; - -import { List } from 'immutable'; - import EmojiService from '../../../src/services/symbols/EmojiService'; import TextSymbolService from '../../../src/services/symbols/TextSymbolService'; import SymbolService from '../../../src/services/symbols/SymbolService'; -chai.use(chaiImmutable); -chai.use(sinonChai); - -const expect = chai.expect; describe('SymbolService Test', () => { let originalPlatform; diff --git a/test/services/tables/PickupTimeEstimatesTableRowsBuilderTest.js b/test/services/tables/PickupTimeEstimatesTableRowsBuilderTest.js index bc0a4e0..d5615a1 100644 --- a/test/services/tables/PickupTimeEstimatesTableRowsBuilderTest.js +++ b/test/services/tables/PickupTimeEstimatesTableRowsBuilderTest.js @@ -1,19 +1,7 @@ -import chai from 'chai'; -import chaiImmutable from 'chai-immutable'; -import sinon from 'sinon'; -import sinonChai from 'sinon-chai'; - -import { List, Map } from 'immutable'; - import DurationConverter from '../../../src/services/DurationConverter'; import DurationFormatter from '../../../src/services/DurationFormatter'; import PickupTimeEstimatesTableRowsBuilder from '../../../src/services/tables/PickupTimeEstimatesTableRowsBuilder'; -chai.use(chaiImmutable); -chai.use(sinonChai); - -const expect = chai.expect; - describe('Pickup Time Estimates Table Rows Builder', () => { const durationConverter = new DurationConverter(); const durationFormatter = new DurationFormatter(durationConverter); diff --git a/test/services/tables/TripPriceEstimateRowFormatterTest.js b/test/services/tables/TripPriceEstimateRowFormatterTest.js index 8055a3f..97034b9 100644 --- a/test/services/tables/TripPriceEstimateRowFormatterTest.js +++ b/test/services/tables/TripPriceEstimateRowFormatterTest.js @@ -1,10 +1,3 @@ -import chai from 'chai'; -import chaiImmutable from 'chai-immutable'; -import sinon from 'sinon'; -import sinonChai from 'sinon-chai'; - -import { List, Map } from 'immutable'; - import DistanceUnit from '../../../src/data/DistanceUnit'; import DistanceConverter from '../../../src/services/DistanceConverter'; @@ -13,11 +6,6 @@ import DurationFormatter from '../../../src/services/DurationFormatter'; import TripPriceEstimateRowFormatter from '../../../src/services/tables/TripPriceEstimateRowFormatter'; import SymbolService from '../../../src/services/symbols/SymbolService'; -chai.use(chaiImmutable); -chai.use(sinonChai); - -const expect = chai.expect; - describe('Trip Price Estimate Row Formatter', () => { let sandbox; diff --git a/test/services/tables/builders/PickupTimeEstimatesTableBuilderTest.js b/test/services/tables/builders/PickupTimeEstimatesTableBuilderTest.js index cd219dd..5a6179a 100644 --- a/test/services/tables/builders/PickupTimeEstimatesTableBuilderTest.js +++ b/test/services/tables/builders/PickupTimeEstimatesTableBuilderTest.js @@ -1,12 +1,6 @@ /* eslint-disable no-console */ -import chai from 'chai'; -import chaiImmutable from 'chai-immutable'; -import sinon from 'sinon'; -import sinonChai from 'sinon-chai'; - import Table from 'cli-table2'; -import { List, Map } from 'immutable'; import PickupTimeEstimatesTableRowsBuilder from '../../../../src/services/tables/PickupTimeEstimatesTableRowsBuilder'; import PickupTimeEstimatesTableBuilder from '../../../../src/services/tables/builders/PickupTimeEstimatesTableBuilder'; diff --git a/test/services/tables/builders/TripPriceEstimatesTableBuilderTest.js b/test/services/tables/builders/TripPriceEstimatesTableBuilderTest.js index 366089f..788b87c 100644 --- a/test/services/tables/builders/TripPriceEstimatesTableBuilderTest.js +++ b/test/services/tables/builders/TripPriceEstimatesTableBuilderTest.js @@ -1,23 +1,12 @@ /* eslint-disable no-console */ -import chai from 'chai'; -import chaiImmutable from 'chai-immutable'; -import sinon from 'sinon'; -import sinonChai from 'sinon-chai'; - import Table from 'cli-table2'; -import { List, Map } from 'immutable'; import TripPriceEstimateRowFormatter from '../../../../src/services/tables/TripPriceEstimateRowFormatter'; import TripPriceEstimatesTableBuilder from '../../../../src/services/tables/builders/TripPriceEstimatesTableBuilder'; import SymbolService from '../../../../src/services/symbols/SymbolService'; -chai.use(chaiImmutable); -chai.use(sinonChai); - -const expect = chai.expect; - describe('Trip Price Estimates Table Builder', () => { let sandbox; diff --git a/test/services/translators/estimates/PickupTimeEstimatesTranslatorTest.js b/test/services/translators/estimates/PickupTimeEstimatesTranslatorTest.js index 7a22993..d8478c1 100644 --- a/test/services/translators/estimates/PickupTimeEstimatesTranslatorTest.js +++ b/test/services/translators/estimates/PickupTimeEstimatesTranslatorTest.js @@ -1,15 +1,6 @@ -import chai from 'chai'; -import sinon from 'sinon'; -import sinonChai from 'sinon-chai'; - -import { List } from 'immutable'; - import PickupTimeEstimateTranslator from '../../../../src/services/translators/estimates/PickupTimeEstimateTranslator'; import PickupTimeEstimatesTranslator from '../../../../src/services/translators/estimates/PickupTimeEstimatesTranslator'; -chai.use(sinonChai); - -const expect = chai.expect; describe('Trip Duration Estimats Translation', () => { const testValue = 'jaebaebae'; diff --git a/test/services/translators/estimates/TripPriceEstimateTranslatorTest.js b/test/services/translators/estimates/TripPriceEstimateTranslatorTest.js index 285fd9d..346875d 100644 --- a/test/services/translators/estimates/TripPriceEstimateTranslatorTest.js +++ b/test/services/translators/estimates/TripPriceEstimateTranslatorTest.js @@ -1,18 +1,8 @@ -import chai from 'chai'; -import sinon from 'sinon'; -import sinonChai from 'sinon-chai'; - -import { Map } from 'immutable'; - import DistanceUnit from '../../../../src/data/DistanceUnit'; import TimeUnit from '../../../../src/data/TimeUnit'; import TripPriceEstimateTranslator from '../../../../src/services/translators/estimates/TripPriceEstimateTranslator'; -chai.use(sinonChai); - -const expect = chai.expect; - describe('Trip Price Estimate Translation', () => { let sandbox; diff --git a/test/services/translators/estimates/TripPriceEstimatesTranslatorTest.js b/test/services/translators/estimates/TripPriceEstimatesTranslatorTest.js index 630da63..7869b77 100644 --- a/test/services/translators/estimates/TripPriceEstimatesTranslatorTest.js +++ b/test/services/translators/estimates/TripPriceEstimatesTranslatorTest.js @@ -1,16 +1,6 @@ -import chai from 'chai'; -import sinon from 'sinon'; -import sinonChai from 'sinon-chai'; - -import { List } from 'immutable'; - import TripPriceEstimateTranslator from '../../../../src/services/translators/estimates/TripPriceEstimateTranslator'; import TripPriceEstimatesTranslator from '../../../../src/services/translators/estimates/TripPriceEstimatesTranslator'; -chai.use(sinonChai); - -const expect = chai.expect; - describe('Trip Price Estimates Translation', () => { let sandbox; diff --git a/test/services/translators/geocode/LocationsTranslatorTest.js b/test/services/translators/geocode/LocationsTranslatorTest.js index 78dd492..9ecc2e7 100644 --- a/test/services/translators/geocode/LocationsTranslatorTest.js +++ b/test/services/translators/geocode/LocationsTranslatorTest.js @@ -1,18 +1,6 @@ -'use es6'; - -import chai from 'chai'; -import sinon from 'sinon'; -import sinonChai from 'sinon-chai'; - -import { List } from 'immutable'; - import LocationTranslator from '../../../../src/services/translators/geocode/LocationTranslator'; import LocationsTranslator from '../../../../src/services/translators/geocode/LocationsTranslator'; -chai.use(sinonChai); - -const expect = chai.expect; - describe('Locations Translation', () => { const testValue = 'jaebaebae'; From 9fd88f692d63d4b027176e9dd026679f0cc6a99d Mon Sep 17 00:00:00 2001 From: Jae Bradley Date: Mon, 4 Jun 2018 10:20:16 -0400 Subject: [PATCH 12/38] refactor(location-translators): remove Location Translators (#65) --- src/services/GeocodeService.js | 14 +-- .../translators/geocode/LocationTranslator.js | 66 -------------- .../geocode/LocationsTranslator.js | 39 -------- .../geocode/LocationTranslatorTest.js | 88 ------------------- .../geocode/LocationsTranslatorTest.js | 57 ------------ 5 files changed, 9 insertions(+), 255 deletions(-) delete mode 100644 src/services/translators/geocode/LocationTranslator.js delete mode 100644 src/services/translators/geocode/LocationsTranslator.js delete mode 100644 test/services/translators/geocode/LocationTranslatorTest.js delete mode 100644 test/services/translators/geocode/LocationsTranslatorTest.js diff --git a/src/services/GeocodeService.js b/src/services/GeocodeService.js index 89e655a..372a55e 100644 --- a/src/services/GeocodeService.js +++ b/src/services/GeocodeService.js @@ -1,11 +1,7 @@ import GoogleMapsClient from '@google/maps'; -import LocationTranslator from './translators/geocode/LocationTranslator'; -import LocationsTranslator from './translators/geocode/LocationsTranslator'; - export default class GeocodeService { constructor() { - this.translator = new LocationsTranslator(new LocationTranslator()); this.googleMapsClient = GoogleMapsClient.createClient({ key: 'AIzaSyBfyXZ3kDp03V_o7_mak0wxVU4B2Zcl0Ak', }); @@ -24,6 +20,14 @@ export default class GeocodeService { } getLocations(address) { - return this.getData(address).then(response => this.translator.translate(response)); + return this.getData(address) + .then(response => response.results.map(result => ({ + name: result['formatted_address'], + coordinate: { + latitude: result.geometry.location.lat, + longitude: result.geometry.location.lng, + }, + })) + ); } } diff --git a/src/services/translators/geocode/LocationTranslator.js b/src/services/translators/geocode/LocationTranslator.js deleted file mode 100644 index c29b5c5..0000000 --- a/src/services/translators/geocode/LocationTranslator.js +++ /dev/null @@ -1,66 +0,0 @@ -import Utilities from '../../Utilities'; - -export default class LocationTranslator { - constructor() { - this.FORMATTED_ADDRESS_FIELD_NAME = 'formatted_address'; - this.GEOMETRY_ADDRESS_FIELD_NAME = 'geometry'; - this.LOCATION_FIELD_NAME = 'location'; - this.LATITUDE_FIELD_NAME = 'lat'; - this.LONGITUDE_FIELD_NAME = 'lng'; - } - - translate(json) { - if (!this.isValid(json)) { - throw new Error(`Invalid json: ${JSON.stringify(json)}`); - } - - const location = json[this.GEOMETRY_ADDRESS_FIELD_NAME][this.LOCATION_FIELD_NAME]; - return { - name: json[this.FORMATTED_ADDRESS_FIELD_NAME], - coordinate: { - latitude: location[this.LATITUDE_FIELD_NAME], - longitude: location[this.LONGITUDE_FIELD_NAME], - }, - }; - } - - isValid(json) { - if (!(this.FORMATTED_ADDRESS_FIELD_NAME in json)) { - return false; - } - - if (!(this.GEOMETRY_ADDRESS_FIELD_NAME in json)) { - return false; - } - - const geometry = json[this.GEOMETRY_ADDRESS_FIELD_NAME]; - - if (!(this.LOCATION_FIELD_NAME in geometry)) { - return false; - } - - const location = geometry[this.LOCATION_FIELD_NAME]; - - if (!(this.LATITUDE_FIELD_NAME in location)) { - return false; - } - - if (!(this.LONGITUDE_FIELD_NAME in location)) { - return false; - } - - if (typeof json[this.FORMATTED_ADDRESS_FIELD_NAME] !== 'string') { - return false; - } - - if (!Utilities.isFloat(location[this.LATITUDE_FIELD_NAME])) { - return false; - } - - if (!Utilities.isFloat(location[this.LONGITUDE_FIELD_NAME])) { - return false; - } - - return true; - } -} diff --git a/src/services/translators/geocode/LocationsTranslator.js b/src/services/translators/geocode/LocationsTranslator.js deleted file mode 100644 index 81619e6..0000000 --- a/src/services/translators/geocode/LocationsTranslator.js +++ /dev/null @@ -1,39 +0,0 @@ -export default class LocationsTranslator { - constructor(locationTranslator) { - this.STATUS_FIELD_NAME = 'status'; - this.EXPECTED_STATUS = 'OK'; - this.RESULTS_FIELD_NAME = 'results'; - this.locationTranslator = locationTranslator; - } - - translate(json) { - if (!this.isValid(json)) { - throw new Error(`Invalid json: ${json}`); - } - - const results = json[this.RESULTS_FIELD_NAME]; - - return results.map(result => this.locationTranslator.translate(result)); - } - - isValid(json) { - if (!(this.STATUS_FIELD_NAME in json)) { - return false; - } - - if (json[this.STATUS_FIELD_NAME] !== this.EXPECTED_STATUS) { - return false; - } - - if (!(this.RESULTS_FIELD_NAME in json)) { - return false; - } - - const results = json[this.RESULTS_FIELD_NAME]; - if (!Array.isArray(results)) { - return false; - } - - return true; - } -} diff --git a/test/services/translators/geocode/LocationTranslatorTest.js b/test/services/translators/geocode/LocationTranslatorTest.js deleted file mode 100644 index ceea187..0000000 --- a/test/services/translators/geocode/LocationTranslatorTest.js +++ /dev/null @@ -1,88 +0,0 @@ -'use es6'; - -import chai from 'chai'; -import sinon from 'sinon'; -import sinonChai from 'sinon-chai'; - -import LocationTranslator from '../../../../src/services/translators/geocode/LocationTranslator'; - -chai.use(sinonChai); - -const expect = chai.expect; - -describe('Location Translation', () => { - const translator = new LocationTranslator(); - const location = {}; - location[translator.LATITUDE_FIELD_NAME] = 1.234; - location[translator.LONGITUDE_FIELD_NAME] = 5.678; - - const address = {}; - address[translator.LOCATION_FIELD_NAME] = location; - - const json = {}; - json[translator.FORMATTED_ADDRESS_FIELD_NAME] = 'foo'; - json[translator.GEOMETRY_ADDRESS_FIELD_NAME] = address; - - describe('JSON Validation', () => { - describe('Valid', () => { - it('should be valid', () => expect(translator.isValid(json)).to.be.true); - }); - - describe('Invalid', () => { - const test = {}; - - afterEach(() => expect(translator.isValid(test)).to.be.false); - - it('invalid due to missing formatted address field', () => {}); - - it('invalid due to missing geometry address field', () => { - test[translator.FORMATTED_ADDRESS_FIELD_NAME] = {}; - }); - - it('invalid due to missing location field', () => { - test[translator.GEOMETRY_ADDRESS_FIELD_NAME] = {}; - }); - - it('invalid due to missing latitude field', () => { - test[translator.GEOMETRY_ADDRESS_FIELD_NAME][translator.LOCATION_FIELD_NAME] = {}; - }); - - it('invalid due to missing longitude field', () => { - test[translator.GEOMETRY_ADDRESS_FIELD_NAME][translator.LOCATION_FIELD_NAME][translator.LATITUDE_FIELD_NAME] = 'foo'; - }); - - it('invalid due to invalid address type', () => { - test[translator.GEOMETRY_ADDRESS_FIELD_NAME][translator.LOCATION_FIELD_NAME][translator.LONGITUDE_FIELD_NAME] = 'foo'; - }); - - it('invalid due to invalid latitude type', () => { - test[translator.FORMATTED_ADDRESS_FIELD_NAME] = 'foo'; - }); - - it('invalid due to invalid longitude type', () => { - test[translator.GEOMETRY_ADDRESS_FIELD_NAME][translator.LOCATION_FIELD_NAME][translator.LATITUDE_FIELD_NAME] = 1.234; // eslint-disable-line max-len - }); - }); - }); - - describe('Invalid', () => { - it('throws for invalid json', () => { - const isValid = sinon.stub(translator, 'isValid').returns(false); - expect(() => translator.translate({})).to.throw(Error); - isValid.restore(); - }); - - it('translates valid json', () => { - const expected = { - name: 'foo', - coordinate: { - latitude: 1.234, - longitude: 5.678, - }, - }; - const isValid = sinon.stub(translator, 'isValid').returns(true); - expect(translator.translate(json)).to.eql(expected); - isValid.restore(); - }); - }); -}); diff --git a/test/services/translators/geocode/LocationsTranslatorTest.js b/test/services/translators/geocode/LocationsTranslatorTest.js deleted file mode 100644 index 9ecc2e7..0000000 --- a/test/services/translators/geocode/LocationsTranslatorTest.js +++ /dev/null @@ -1,57 +0,0 @@ -import LocationTranslator from '../../../../src/services/translators/geocode/LocationTranslator'; -import LocationsTranslator from '../../../../src/services/translators/geocode/LocationsTranslator'; - -describe('Locations Translation', () => { - const testValue = 'jaebaebae'; - - const locationTranslator = new LocationTranslator(); - const translator = new LocationsTranslator(locationTranslator); - const validJson = {}; - validJson[translator.STATUS_FIELD_NAME] = translator.EXPECTED_STATUS; - validJson[translator.RESULTS_FIELD_NAME] = [1, 2, 3]; - - describe('JSON Validation', () => { - describe('Valid JSON', () => { - it('is valid', () => expect(translator.isValid(validJson)).to.be.true); - }); - - describe('Invalid JSON', () => { - const invalidJson = {}; - - afterEach(() => expect(translator.isValid(invalidJson)).to.be.false); - - it('is invalid due to missing status field', () => {}); - - it('is invalid due to incorrect status field', () => { - invalidJson[translator.STATUS_FIELD_NAME] = testValue; - }); - - it('is invalid due to missing results field', () => { - invalidJson[translator.STATUS_FIELD_NAME] = translator.EXPECTED_STATUS; - }); - - it('is invalid due to invalid results field value type', () => { - invalidJson[translator.RESULTS_FIELD_NAME] = testValue; - }); - }); - }); - - describe('Translation', () => { - it('Throws when JSON is invalid', () => { - const isValid = sinon.stub(translator, 'isValid').returns(false); - expect(() => translator.translate({})).to.throw(Error); - isValid.restore(); - }); - - it('Returns list when JSON is Valid', () => { - const translateLocation = sinon.stub(locationTranslator, 'translate') - .returns(testValue); - const isValid = sinon.stub(translator, 'isValid') - .returns(true); - const expected = List.of(testValue, testValue, testValue); - expect(expected).to.eql(translator.translate(validJson)); - translateLocation.restore(); - isValid.restore(); - }); - }); -}); From 47a9bf269c486efa1fa63145d0154ba1af9f6472 Mon Sep 17 00:00:00 2001 From: Jae Bradley Date: Mon, 4 Jun 2018 14:40:30 -0400 Subject: [PATCH 13/38] refactor(trip-price-estimate-translators): refactor translators --- src/services/UberService.js | 5 +- .../estimates/TripPriceEstimateTranslator.js | 135 --------------- .../estimates/TripPriceEstimatesTranslator.js | 31 ---- .../estimates/translateTripPriceEstimate.js | 22 +++ .../TripPriceEstimateTranslatorTest.js | 159 ------------------ .../TripPriceEstimatesTranslatorTest.js | 56 ------ 6 files changed, 24 insertions(+), 384 deletions(-) delete mode 100644 src/services/translators/estimates/TripPriceEstimateTranslator.js delete mode 100644 src/services/translators/estimates/TripPriceEstimatesTranslator.js create mode 100644 src/services/translators/estimates/translateTripPriceEstimate.js delete mode 100644 test/services/translators/estimates/TripPriceEstimateTranslatorTest.js delete mode 100644 test/services/translators/estimates/TripPriceEstimatesTranslatorTest.js diff --git a/src/services/UberService.js b/src/services/UberService.js index 514e577..ec52244 100644 --- a/src/services/UberService.js +++ b/src/services/UberService.js @@ -4,14 +4,13 @@ import GeocodeService from './GeocodeService'; import PickupTimeEstimateTranslator from './translators/estimates/PickupTimeEstimateTranslator'; import PickupTimeEstimatesTranslator from './translators/estimates/PickupTimeEstimatesTranslator'; import TripPriceEstimateTranslator from './translators/estimates/TripPriceEstimateTranslator'; -import TripPriceEstimatesTranslator from './translators/estimates/TripPriceEstimatesTranslator'; +import translateTripPriceEstimate from './translators/estimates/translateTripPriceEstimate'; export default class UberService { constructor() { this.client = new UberClient('We0MNCaIpx00F_TUopt4jgL9BzW3bWWt16aYM4mh'); this.geocodeService = new GeocodeService(); this.pickupTimeEstimatesTranslator = new PickupTimeEstimatesTranslator(new PickupTimeEstimateTranslator()); // eslint-disable-line max-len - this.tripPriceEstimatesTranslator = new TripPriceEstimatesTranslator(new TripPriceEstimateTranslator()); // eslint-disable-line max-len } getFirstLocation(address) { @@ -44,7 +43,7 @@ export default class UberService { .then(response => ({ start, end, - estimates: this.tripPriceEstimatesTranslator.translate(response), + estimates: response.prices.map(estimate => translateTripPriceEstimate(estimate)), }))); } } diff --git a/src/services/translators/estimates/TripPriceEstimateTranslator.js b/src/services/translators/estimates/TripPriceEstimateTranslator.js deleted file mode 100644 index 8a946e2..0000000 --- a/src/services/translators/estimates/TripPriceEstimateTranslator.js +++ /dev/null @@ -1,135 +0,0 @@ -import DistanceUnit from '../../../data/DistanceUnit'; -import TimeUnit from '../../../data/TimeUnit'; -import Utilities from '../../Utilities'; - -export default class TripPriceEstimateTranslator { - translate(estimate) { - if (!this.isValid(estimate)) { - throw new Error(`invalid estimate: ${estimate}`); - } - - const distance = { - value: estimate[TripPriceEstimateTranslator.getDistanceFieldName()], - unit: DistanceUnit.MILE, - }; - - // Uber returns duration in seconds - const duration = { - length: estimate[TripPriceEstimateTranslator.getDurationFieldName()], - unit: TimeUnit.SECOND, - }; - - const range = { - high: estimate[TripPriceEstimateTranslator.getHighEstimateFieldName()], - low: estimate[TripPriceEstimateTranslator.getLowEstimateFieldName()], - currencyCode: estimate[TripPriceEstimateTranslator.getCurrencyCodeFieldName()], - }; - - let args = { - productName: estimate[TripPriceEstimateTranslator.getProductNameFieldName()], - distance, - duration, - range, - }; - - if (TripPriceEstimateTranslator.getSurgeMultiplierFieldName() in estimate) { - args = args.set('surgeMultiplier', estimate[TripPriceEstimateTranslator.getSurgeMultiplierFieldName()]); - } - - return args; - } - - isValid(estimate) { - if (!(TripPriceEstimateTranslator.getProductNameFieldName() in estimate)) { - return false; - } - - if (!(TripPriceEstimateTranslator.getDistanceFieldName() in estimate)) { - return false; - } - - if (!(TripPriceEstimateTranslator.getHighEstimateFieldName() in estimate)) { - return false; - } - - if (!(TripPriceEstimateTranslator.getLowEstimateFieldName() in estimate)) { - return false; - } - - if (!(TripPriceEstimateTranslator.getDurationFieldName() in estimate)) { - return false; - } - - if (!(TripPriceEstimateTranslator.getCurrencyCodeFieldName() in estimate)) { - return false; - } - - const productName = estimate[TripPriceEstimateTranslator.getProductNameFieldName()]; - if (typeof productName !== 'string') { - return false; - } - - const distance = estimate[TripPriceEstimateTranslator.getDistanceFieldName()]; - if (!Utilities.isFloat(distance)) { - return false; - } - - const duration = estimate[TripPriceEstimateTranslator.getDurationFieldName()]; - if (!Number.isInteger(duration)) { - return false; - } - - // estimates can be null for non-applicable products like Taxi - const highEstimate = estimate[TripPriceEstimateTranslator.getHighEstimateFieldName()]; - if (highEstimate !== null && !Number.isInteger(highEstimate)) { - return false; - } - - const lowEstimate = estimate[TripPriceEstimateTranslator.getLowEstimateFieldName()]; - if (lowEstimate !== null && !Number.isInteger(lowEstimate)) { - return false; - } - - // currency code can be null for non-applicable products like Taxi - const currencyCode = estimate[TripPriceEstimateTranslator.getCurrencyCodeFieldName()]; - if (currencyCode !== null && typeof currencyCode !== 'string') { - return false; - } - - if (TripPriceEstimateTranslator.getSurgeMultiplierFieldName() in estimate) { - if (!Utilities.isFloat(estimate[TripPriceEstimateTranslator.getSurgeMultiplierFieldName()])) { - return false; - } - } - - return true; - } - - static getProductNameFieldName() { - return 'localized_display_name'; - } - - static getDistanceFieldName() { - return 'distance'; - } - - static getHighEstimateFieldName() { - return 'high_estimate'; - } - - static getLowEstimateFieldName() { - return 'low_estimate'; - } - - static getDurationFieldName() { - return 'duration'; - } - - static getCurrencyCodeFieldName() { - return 'currency_code'; - } - - static getSurgeMultiplierFieldName() { - return 'surgeMultiplier'; - } -} diff --git a/src/services/translators/estimates/TripPriceEstimatesTranslator.js b/src/services/translators/estimates/TripPriceEstimatesTranslator.js deleted file mode 100644 index 66c79e9..0000000 --- a/src/services/translators/estimates/TripPriceEstimatesTranslator.js +++ /dev/null @@ -1,31 +0,0 @@ -export default class TripPriceEstimatesTranslator { - constructor(tripPriceEstimateTranslator) { - this.tripPriceEstimateTranslator = tripPriceEstimateTranslator; - } - - translate(estimates) { - if (!this.isValid(estimates)) { - throw new Error(`Invalid estimates: ${estimates}`); - } - - const priceEstimates = estimates[TripPriceEstimatesTranslator.getPricesFieldName()]; - - return priceEstimates.map(priceEstimate => this.tripPriceEstimateTranslator.translate(priceEstimate)); // eslint-disable-line max-len - } - - isValid(estimates) { - if (!(TripPriceEstimatesTranslator.getPricesFieldName() in estimates)) { - return false; - } - - if (!Array.isArray(estimates[TripPriceEstimatesTranslator.getPricesFieldName()])) { - return false; - } - - return true; - } - - static getPricesFieldName() { - return 'prices'; - } -} diff --git a/src/services/translators/estimates/translateTripPriceEstimate.js b/src/services/translators/estimates/translateTripPriceEstimate.js new file mode 100644 index 0000000..e710189 --- /dev/null +++ b/src/services/translators/estimates/translateTripPriceEstimate.js @@ -0,0 +1,22 @@ +import DistanceUnit from '../../../data/DistanceUnit'; +import TimeUnit from '../../../data/TimeUnit'; + +const translateTripPriceEstimate = estimate => ({ + productName: estimate['localized_display_name'], + distance: { + value: estimate.distance, + unit: DistanceUnit.MILE, + }, + duration: { + length: estimate.duration, + unit: TimeUnit.SECOND, + }, + range: { + high: estimate['high_estimate'], + low: estimate['low_estimate'], + currencyCode: estimate['currency_code'], + }, + surgeMultiplier: estimate.surgeMultiplier ? estimate.surgeMultiplier : null, +}); + +export default translateTripPriceEstimate; diff --git a/test/services/translators/estimates/TripPriceEstimateTranslatorTest.js b/test/services/translators/estimates/TripPriceEstimateTranslatorTest.js deleted file mode 100644 index 346875d..0000000 --- a/test/services/translators/estimates/TripPriceEstimateTranslatorTest.js +++ /dev/null @@ -1,159 +0,0 @@ -import DistanceUnit from '../../../../src/data/DistanceUnit'; -import TimeUnit from '../../../../src/data/TimeUnit'; - -import TripPriceEstimateTranslator from '../../../../src/services/translators/estimates/TripPriceEstimateTranslator'; - -describe('Trip Price Estimate Translation', () => { - let sandbox; - - const productName = 'foo'; - const distance = 1.234; - const duration = 2; - const highEstimate = 3; - const lowEstimate = 4; - const currencyCode = 'bar'; - const surgeMultiplier = 2.345; - const translator = new TripPriceEstimateTranslator(); - - const estimateWithoutSurgeMultiplier = {}; - estimateWithoutSurgeMultiplier[TripPriceEstimateTranslator.getProductNameFieldName()] = productName; // eslint-disable-line max-len - estimateWithoutSurgeMultiplier[TripPriceEstimateTranslator.getDistanceFieldName()] = distance; - estimateWithoutSurgeMultiplier[TripPriceEstimateTranslator.getDurationFieldName()] = duration; - estimateWithoutSurgeMultiplier[TripPriceEstimateTranslator.getHighEstimateFieldName()] = highEstimate; // eslint-disable-line max-len - estimateWithoutSurgeMultiplier[TripPriceEstimateTranslator.getLowEstimateFieldName()] = lowEstimate; // eslint-disable-line max-len - estimateWithoutSurgeMultiplier[TripPriceEstimateTranslator.getCurrencyCodeFieldName()] = currencyCode; // eslint-disable-line max-len - - const estimateWithSurgeMultiplier = {}; - estimateWithSurgeMultiplier[TripPriceEstimateTranslator.getProductNameFieldName()] = productName; - estimateWithSurgeMultiplier[TripPriceEstimateTranslator.getDistanceFieldName()] = distance; - estimateWithSurgeMultiplier[TripPriceEstimateTranslator.getDurationFieldName()] = duration; - estimateWithSurgeMultiplier[TripPriceEstimateTranslator.getHighEstimateFieldName()] = highEstimate; // eslint-disable-line max-len - estimateWithSurgeMultiplier[TripPriceEstimateTranslator.getLowEstimateFieldName()] = lowEstimate; - estimateWithSurgeMultiplier[TripPriceEstimateTranslator.getCurrencyCodeFieldName()] = currencyCode; // eslint-disable-line max-len - estimateWithSurgeMultiplier[TripPriceEstimateTranslator.getSurgeMultiplierFieldName()] = surgeMultiplier; // eslint-disable-line max-len - - beforeEach(() => { - sandbox = sinon.sandbox.create(); - }); - - afterEach(() => { - sandbox.restore(); - }); - - describe('JSON Validation', () => { - describe('Valid', () => { - it('should be valid for estimate without surge', () => expect(translator.isValid(estimateWithoutSurgeMultiplier)).to.be.true); - it('should be valid for estimate with surge', () => expect(translator.isValid(estimateWithSurgeMultiplier)).to.be.true); - }); - - describe('Invalid', () => { - const invalid = {}; - - afterEach(() => expect(translator.isValid(invalid)).to.be.false); - - it('invalid due to missing product name field', () => {}); - - it('invalid due to missing distance field', () => { - invalid[TripPriceEstimateTranslator.getProductNameFieldName()] = 1; - }); - - it('invalid due to missing high estimate field', () => { - invalid[TripPriceEstimateTranslator.getDistanceFieldName()] = 'distance'; - }); - - it('invalid due to missing low estimate', () => { - invalid[TripPriceEstimateTranslator.getHighEstimateFieldName()] = 'highEstimate'; - }); - - it('invalid due to missing duration', () => { - invalid[TripPriceEstimateTranslator.getLowEstimateFieldName()] = 'lowEstimate'; - }); - - it('invalid due to missing currency code', () => { - invalid[TripPriceEstimateTranslator.getDurationFieldName()] = 'duration'; - }); - - it('invalid due to product name type', () => { - invalid[TripPriceEstimateTranslator.getCurrencyCodeFieldName()] = 2; - }); - - it('invalid due to distance type', () => { - invalid[TripPriceEstimateTranslator.getProductNameFieldName()] = productName; - }); - - it('invalid due to duration type', () => { - invalid[TripPriceEstimateTranslator.getDistanceFieldName()] = distance; - }); - - it('invalid due to null high estimate', () => { - invalid[TripPriceEstimateTranslator.getDurationFieldName()] = duration; - invalid[TripPriceEstimateTranslator.getHighEstimateFieldName()] = null; - }); - - it('invalid due to non-integer high estimate', () => { - invalid[TripPriceEstimateTranslator.getHighEstimateFieldName()] = 'highEstimate'; - }); - - it('invalid due to null low estimate', () => { - invalid[TripPriceEstimateTranslator.getLowEstimateFieldName()] = null; - }); - - it('invalid due to non-integer low estimate', () => { - invalid[TripPriceEstimateTranslator.getLowEstimateFieldName()] = 'lowEstimate'; - }); - - it('invalid due to null currency code', () => { - invalid[TripPriceEstimateTranslator.getCurrencyCodeFieldName()] = null; - }); - - it('invalid due to non-string currency code', () => { - invalid[TripPriceEstimateTranslator.getCurrencyCodeFieldName()] = 1; - }); - - it('invalid due to non-float surge multiplier', () => { - invalid[TripPriceEstimateTranslator.getSurgeMultiplierFieldName()] = 'surgeMultiplier'; - }); - }); - }); - - describe('Translate Estimate', () => { - const args = Map({ - productName, - distance: { - value: distance, - unit: DistanceUnit.MILE, - }, - duration: { - length: duration, - unit: TimeUnit.SECOND, - }, - range: { - high: highEstimate, - low: lowEstimate, - currencyCode, - }, - }); - const argsWithSurgeMultiplier = args.set('surgeMultiplier', surgeMultiplier); - - describe('Invalid', () => { - it('throws for invalid estimate', () => { - sandbox.stub(translator, 'isValid').returns(false); - expect(() => translator.translate({})).to.throw(Error); - }); - }); - - describe('Valid', () => { - it('translates valid estimate without surge multiplier', () => { - sandbox.stub(translator, 'isValid').returns(true); - const expected = args; - expect(translator.translate(estimateWithoutSurgeMultiplier)).to.eql(expected); - }); - - it('translates valid estimate with surge multiplier', () => { - sandbox.stub(translator, 'isValid').returns(true); - const expected = argsWithSurgeMultiplier; - expect(translator.translate(estimateWithSurgeMultiplier)).to.eql(expected); - }); - }); - }); -}); diff --git a/test/services/translators/estimates/TripPriceEstimatesTranslatorTest.js b/test/services/translators/estimates/TripPriceEstimatesTranslatorTest.js deleted file mode 100644 index 7869b77..0000000 --- a/test/services/translators/estimates/TripPriceEstimatesTranslatorTest.js +++ /dev/null @@ -1,56 +0,0 @@ -import TripPriceEstimateTranslator from '../../../../src/services/translators/estimates/TripPriceEstimateTranslator'; -import TripPriceEstimatesTranslator from '../../../../src/services/translators/estimates/TripPriceEstimatesTranslator'; - -describe('Trip Price Estimates Translation', () => { - let sandbox; - - const estimateTranslator = new TripPriceEstimateTranslator(); - const translator = new TripPriceEstimatesTranslator(estimateTranslator); - const valid = { prices: [] }; - - beforeEach(() => { - sandbox = sinon.sandbox.create(); - }); - - afterEach(() => { - sandbox.restore(); - }); - - describe('JSON Validation', () => { - describe('Valid', () => { - it('should be valid', () => expect(translator.isValid(valid)).to.be.true); - }); - - describe('Invalid', () => { - const invalid = {}; - - afterEach(() => expect(translator.isValid(invalid)).to.be.false); - - it('invalid due to missing prices name field', () => {}); - - it('invalid due to wrong prices type', () => { - invalid[TripPriceEstimatesTranslator.getPricesFieldName()] = 1; - }); - }); - }); - - describe('Translate Estimates', () => { - const estimates = { prices: [1, 2, 3] }; - - describe('Invalid', () => { - it('throws for invalid estimate', () => { - sandbox.stub(translator, 'isValid').returns(false); - expect(() => translator.translate({})).to.throw(Error); - }); - }); - - describe('Valid', () => { - it('translates valid estimates', () => { - sandbox.stub(translator, 'isValid').returns(true); - sandbox.stub(estimateTranslator, 'translate').callsFake(() => 'bar'); - const expected = List.of('bar', 'bar', 'bar'); - expect(translator.translate(estimates)).to.eql(expected); - }); - }); - }); -}); From 8f92d06f6fc0b271f3500bba2a9e53e581a00360 Mon Sep 17 00:00:00 2001 From: Jae Bradley Date: Mon, 4 Jun 2018 14:49:03 -0400 Subject: [PATCH 14/38] refactor(pickup-time-estimate): refactor Pickup Time Estimate --- src/services/UberService.js | 6 +- .../estimates/PickupTimeEstimateTranslator.js | 47 ------------- .../PickupTimeEstimatesTranslator.js | 31 --------- .../estimates/translatePickupTimeEstimate.js | 11 ++++ .../PickupTimeEstimateTranslatorTest.js | 66 ------------------- .../PickupTimeEstimatesTranslatorTest.js | 48 -------------- 6 files changed, 13 insertions(+), 196 deletions(-) delete mode 100644 src/services/translators/estimates/PickupTimeEstimateTranslator.js delete mode 100644 src/services/translators/estimates/PickupTimeEstimatesTranslator.js create mode 100644 src/services/translators/estimates/translatePickupTimeEstimate.js delete mode 100644 test/services/translators/estimates/PickupTimeEstimateTranslatorTest.js delete mode 100644 test/services/translators/estimates/PickupTimeEstimatesTranslatorTest.js diff --git a/src/services/UberService.js b/src/services/UberService.js index ec52244..6a9d087 100644 --- a/src/services/UberService.js +++ b/src/services/UberService.js @@ -1,16 +1,14 @@ import { UberClient } from 'uber-client'; import GeocodeService from './GeocodeService'; -import PickupTimeEstimateTranslator from './translators/estimates/PickupTimeEstimateTranslator'; -import PickupTimeEstimatesTranslator from './translators/estimates/PickupTimeEstimatesTranslator'; import TripPriceEstimateTranslator from './translators/estimates/TripPriceEstimateTranslator'; import translateTripPriceEstimate from './translators/estimates/translateTripPriceEstimate'; +import translatePickupTimeEstimate from './translators/estimates/translatePickupTimeEstimate'; export default class UberService { constructor() { this.client = new UberClient('We0MNCaIpx00F_TUopt4jgL9BzW3bWWt16aYM4mh'); this.geocodeService = new GeocodeService(); - this.pickupTimeEstimatesTranslator = new PickupTimeEstimatesTranslator(new PickupTimeEstimateTranslator()); // eslint-disable-line max-len } getFirstLocation(address) { @@ -29,7 +27,7 @@ export default class UberService { .then(location => this.client.getTimeEstimates({ start: location.coordinate }) .then(estimates => ({ location, - estimates: this.pickupTimeEstimatesTranslator.translate(estimates), + estimates: estimates.times.map(estimate => translatePickupTimeEstimate(estimate)), }))); } diff --git a/src/services/translators/estimates/PickupTimeEstimateTranslator.js b/src/services/translators/estimates/PickupTimeEstimateTranslator.js deleted file mode 100644 index 6700700..0000000 --- a/src/services/translators/estimates/PickupTimeEstimateTranslator.js +++ /dev/null @@ -1,47 +0,0 @@ -import TimeUnit from '../../../data/TimeUnit'; - -export default class PickupTimeEstimateTranslator { - translate(estimate) { - if (!this.isValid(estimate)) { - throw new Error(`Invalid estimate: ${JSON.stringify(estimate)}`); - } - - return { - productName: estimate[PickupTimeEstimateTranslator.getProductNameFieldName()], - estimatedDuration: { - length: estimate[PickupTimeEstimateTranslator.getEstimateFieldName()], - unit: TimeUnit.SECOND, - }, - }; - } - - isValid(estimate) { - if (!(PickupTimeEstimateTranslator.getProductNameFieldName() in estimate)) { - return false; - } - - if (!(PickupTimeEstimateTranslator.getEstimateFieldName() in estimate)) { - return false; - } - - const productName = estimate[PickupTimeEstimateTranslator.getProductNameFieldName()]; - if (typeof productName !== 'string') { - return false; - } - - const estimateSeconds = estimate[PickupTimeEstimateTranslator.getEstimateFieldName()]; - if (!Number.isInteger(estimateSeconds)) { - return false; - } - - return true; - } - - static getProductNameFieldName() { - return 'localized_display_name'; - } - - static getEstimateFieldName() { - return 'estimate'; - } -} diff --git a/src/services/translators/estimates/PickupTimeEstimatesTranslator.js b/src/services/translators/estimates/PickupTimeEstimatesTranslator.js deleted file mode 100644 index 89c029c..0000000 --- a/src/services/translators/estimates/PickupTimeEstimatesTranslator.js +++ /dev/null @@ -1,31 +0,0 @@ -export default class PickupTimeEstimatesTranslator { - constructor(estimateTranslator) { - this.estimateTranslator = estimateTranslator; - } - - translate(estimates) { - if (!this.isValid(estimates)) { - throw new Error(`Invalid estimates: ${JSON.stringify(estimates)}`); - } - - const estimatedDurations = estimates[PickupTimeEstimatesTranslator.getEstimatedDurationsFieldName()]; // eslint-disable-line max-len - - return estimatedDurations.map(estimatedDuration => this.estimateTranslator.translate(estimatedDuration)); // eslint-disable-line max-len - } - - isValid(estimates) { - if (!(PickupTimeEstimatesTranslator.getEstimatedDurationsFieldName() in estimates)) { - return false; - } - - if (!Array.isArray(estimates[PickupTimeEstimatesTranslator.getEstimatedDurationsFieldName()])) { - return false; - } - - return true; - } - - static getEstimatedDurationsFieldName() { - return 'times'; - } -} diff --git a/src/services/translators/estimates/translatePickupTimeEstimate.js b/src/services/translators/estimates/translatePickupTimeEstimate.js new file mode 100644 index 0000000..812fdbb --- /dev/null +++ b/src/services/translators/estimates/translatePickupTimeEstimate.js @@ -0,0 +1,11 @@ +import TimeUnit from '../../../data/TimeUnit'; + +const translatePickupTimeEstimate = estimate => ({ + productName: estimate['localized_display_name'], + estimatedDuration: { + length: estimate.estimate, + unit: TimeUnit.SECOND, + }, +}); + +export default translatePickupTimeEstimate; diff --git a/test/services/translators/estimates/PickupTimeEstimateTranslatorTest.js b/test/services/translators/estimates/PickupTimeEstimateTranslatorTest.js deleted file mode 100644 index 3ddf891..0000000 --- a/test/services/translators/estimates/PickupTimeEstimateTranslatorTest.js +++ /dev/null @@ -1,66 +0,0 @@ -import chai from 'chai'; -import sinon from 'sinon'; -import sinonChai from 'sinon-chai'; - -import TimeUnit from '../../../../src/data/TimeUnit'; - -import PickupTimeEstimateTranslator from '../../../../src/services/translators/estimates/PickupTimeEstimateTranslator'; - -chai.use(sinonChai); - -const expect = chai.expect; - -describe('Pickup Time Estimate Translation', () => { - const productName = 'foo'; - const estimateSeconds = 1234; - const translator = new PickupTimeEstimateTranslator(); - - const estimate = {}; - estimate[PickupTimeEstimateTranslator.getProductNameFieldName()] = productName; - estimate[PickupTimeEstimateTranslator.getEstimateFieldName()] = estimateSeconds; - - describe('JSON Validation', () => { - describe('Valid', () => { - it('should be valid', () => expect(translator.isValid(estimate)).to.be.true); - }); - - describe('Invalid', () => { - const invalid = {}; - - afterEach(() => expect(translator.isValid(invalid)).to.be.false); - - it('invalid due to missing product name field', () => {}); - - it('invalid due to missing estimate field', () => {}); - - it('invalid due to invalid product name type', () => { - invalid[PickupTimeEstimateTranslator.getProductNameFieldName()] = 1.234; - }); - - it('invalid due to invalid estimate type', () => { - invalid[PickupTimeEstimateTranslator.getEstimateFieldName()] = 'bar'; - }); - }); - }); - - describe('Invalid', () => { - it('throws for invalid json', () => { - const isValid = sinon.stub(translator, 'isValid').returns(false); - expect(() => translator.translate({})).to.throw(Error); - isValid.restore(); - }); - - it('translates valid json', () => { - const expected = { - productName, - estimatedDuration: { - length: estimateSeconds, - unit: TimeUnit.SECOND, - }, - }; - const isValid = sinon.stub(translator, 'isValid').returns(true); - expect(translator.translate(estimate)).to.eql(expected); - isValid.restore(); - }); - }); -}); diff --git a/test/services/translators/estimates/PickupTimeEstimatesTranslatorTest.js b/test/services/translators/estimates/PickupTimeEstimatesTranslatorTest.js deleted file mode 100644 index d8478c1..0000000 --- a/test/services/translators/estimates/PickupTimeEstimatesTranslatorTest.js +++ /dev/null @@ -1,48 +0,0 @@ -import PickupTimeEstimateTranslator from '../../../../src/services/translators/estimates/PickupTimeEstimateTranslator'; -import PickupTimeEstimatesTranslator from '../../../../src/services/translators/estimates/PickupTimeEstimatesTranslator'; - - -describe('Trip Duration Estimats Translation', () => { - const testValue = 'jaebaebae'; - - const estimateTranslator = new PickupTimeEstimateTranslator(); - const translator = new PickupTimeEstimatesTranslator(estimateTranslator); - - const valid = {}; - valid[PickupTimeEstimatesTranslator.getEstimatedDurationsFieldName()] = [1, 2, 3]; - - describe('Estimates Validation', () => { - describe('Valid Estimates', () => { - it('is valid', () => expect(translator.isValid(valid)).to.be.true); - }); - - describe('Invalid Estimates', () => { - const invalid = {}; - - afterEach(() => expect(translator.isValid(invalid)).to.be.false); - - it('is invalid due to missing estimated durations field', () => {}); - - it('is invalid due to invalid type for estimated durations field', () => { - invalid[PickupTimeEstimatesTranslator.getEstimatedDurationsFieldName()] = testValue; - }); - }); - }); - - describe('Translation', () => { - it('Throws when JSON is invalid', () => { - const isValid = sinon.stub(translator, 'isValid').returns(false); - expect(() => translator.translate({})).to.throw(Error); - isValid.restore(); - }); - - it('Returns list when JSON is Valid', () => { - const translateEstimate = sinon.stub(estimateTranslator, 'translate').callsFake(() => 'bar'); - const isValid = sinon.stub(translator, 'isValid').returns(true); - const expected = List.of('bar', 'bar', 'bar'); - expect(translator.translate(valid)).to.eql(expected); - translateEstimate.restore(); - isValid.restore(); - }); - }); -}); From d2d81dde51ac24e2a82bc53b36bd1123c36f0f3b Mon Sep 17 00:00:00 2001 From: Jae Bradley Date: Mon, 4 Jun 2018 14:52:46 -0400 Subject: [PATCH 15/38] build(enumify): remove enumify dependency --- package.json | 1 - src/data/DistanceUnit.js | 9 +++++---- src/data/TimeUnit.js | 9 +++++---- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/package.json b/package.json index 9c2ea76..f195e96 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,6 @@ "colors": "^1.1.2 ", "commander": "^2.9.0", "convert-units": "^2.0.1", - "enumify": "^1.0.4", "node-emoji": "^1.4.3", "uber-client": "^0.0.4" }, diff --git a/src/data/DistanceUnit.js b/src/data/DistanceUnit.js index 21fdf06..29c2574 100644 --- a/src/data/DistanceUnit.js +++ b/src/data/DistanceUnit.js @@ -1,5 +1,6 @@ -import { Enum } from 'enumify'; +const DistanceUnit = Object.freeze({ + MILE: 'MILE', + KILOMETER: 'KILOMETER', +}); -export default class DistanceUnit extends Enum {} - -DistanceUnit.initEnum(['MILE', 'KILOMETER']); +export default DistanceUnit; diff --git a/src/data/TimeUnit.js b/src/data/TimeUnit.js index 3e0d827..716c2bd 100644 --- a/src/data/TimeUnit.js +++ b/src/data/TimeUnit.js @@ -1,5 +1,6 @@ -import { Enum } from 'enumify'; +const TimeUnit = Object.freeze({ + SECOND: 'SECOND', + MINUTE: 'MINUTE', +}); -export default class TimeUnit extends Enum {} - -TimeUnit.initEnum(['SECOND', 'MINUTE']); +export default TimeUnit; From fc7f428ae07c774b4fc062b8605dc6a110b798f0 Mon Sep 17 00:00:00 2001 From: Jae Bradley Date: Mon, 4 Jun 2018 15:05:16 -0400 Subject: [PATCH 16/38] refactor(uber-service): convert UberService methods to async/await --- src/services/GeocodeService.js | 23 +++++++-------- src/services/UberService.js | 51 +++++++++++++++------------------- 2 files changed, 34 insertions(+), 40 deletions(-) diff --git a/src/services/GeocodeService.js b/src/services/GeocodeService.js index 372a55e..f818beb 100644 --- a/src/services/GeocodeService.js +++ b/src/services/GeocodeService.js @@ -1,6 +1,6 @@ import GoogleMapsClient from '@google/maps'; -export default class GeocodeService { +class GeocodeService { constructor() { this.googleMapsClient = GoogleMapsClient.createClient({ key: 'AIzaSyBfyXZ3kDp03V_o7_mak0wxVU4B2Zcl0Ak', @@ -19,15 +19,16 @@ export default class GeocodeService { }); } - getLocations(address) { - return this.getData(address) - .then(response => response.results.map(result => ({ - name: result['formatted_address'], - coordinate: { - latitude: result.geometry.location.lat, - longitude: result.geometry.location.lng, - }, - })) - ); + async getLocations(address) { + const { results } = await this.getData(address); + return results.map(result => ({ + name: result['formatted_address'], + coordinate: { + latitude: result.geometry.location.lat, + longitude: result.geometry.location.lng, + }, + })); } } + +export default GeocodeService; diff --git a/src/services/UberService.js b/src/services/UberService.js index 6a9d087..6e990ef 100644 --- a/src/services/UberService.js +++ b/src/services/UberService.js @@ -1,47 +1,40 @@ import { UberClient } from 'uber-client'; import GeocodeService from './GeocodeService'; -import TripPriceEstimateTranslator from './translators/estimates/TripPriceEstimateTranslator'; import translateTripPriceEstimate from './translators/estimates/translateTripPriceEstimate'; import translatePickupTimeEstimate from './translators/estimates/translatePickupTimeEstimate'; export default class UberService { constructor() { - this.client = new UberClient('We0MNCaIpx00F_TUopt4jgL9BzW3bWWt16aYM4mh'); + this.uberClient = new UberClient('We0MNCaIpx00F_TUopt4jgL9BzW3bWWt16aYM4mh'); this.geocodeService = new GeocodeService(); } - getFirstLocation(address) { - return this.geocodeService.getLocations(address) - .then((locations) => { - if (locations.isEmpty()) { - throw new RangeError(`no locations for address: ${address}`); - } + async getFirstLocation(address) { + const locations = await this.geocodeService.getLocations(address); + if (locations.length > 0) { + return locations[0]; + } - return locations.first(); - }); + throw new RangeError(`No locations for address: ${address}`); } - getTimeEstimates(address) { - return this.getFirstLocation(address) - .then(location => this.client.getTimeEstimates({ start: location.coordinate }) - .then(estimates => ({ - location, - estimates: estimates.times.map(estimate => translatePickupTimeEstimate(estimate)), - }))); + async getTimeEstimates(address) { + const location = await this.getFirstLocation(address); + const timeEstimates = await this.uberClient.getTimeEstimates({ start: location.coordinate }); + return { + location, + estimates: timeEstimates.times.map(estimate => translatePickupTimeEstimate(estimate)), + }; } - getPriceEstimates(query) { - const startLocation = this.getFirstLocation(query.startAddress); - const endLocation = this.getFirstLocation(query.endAddress); - return Promise.all([startLocation, endLocation]) - .then(([start, end]) => - this.client - .getPriceEstimates({ start: start.coordinate, end: end.coordinate }) - .then(response => ({ - start, - end, - estimates: response.prices.map(estimate => translateTripPriceEstimate(estimate)), - }))); + async getPriceEstimates({ startAddress, endAddress }) { + const [ start, end ] = await Promise.all(this.getFirstLocation(startAddress), this.getFirstLocation(endAddress)); + const estimates = await this.uberClient.getPriceEstimates({ start: start.coordinate, end: end.coordinate }); + return { + start, + end, + estimates: estimates.prices.map(estimate => translateTripPriceEstimate(estimate)), + }; } } From ce35cd7e0f895ba241f2420a90a393635374bbab Mon Sep 17 00:00:00 2001 From: Jae Bradley Date: Wed, 6 Jun 2018 15:08:59 -0400 Subject: [PATCH 17/38] refactor(cli): refactor services Renaming services. Converting to functional from class-based. --- .travis.yml | 2 +- package-lock.json | 983 ++++++++++++++++++ package.json | 10 +- src/executables/uber-price.js | 39 +- src/executables/uber-time.js | 27 +- src/executables/uber.js | 2 +- src/index.js | 37 + src/services/CommandExecutionService.js | 60 -- src/services/DistanceConverter.js | 48 - src/services/DurationConverter.js | 32 - src/services/DurationFormatter.js | 49 - src/services/UberService.js | 2 +- src/services/Utilities.js | 5 - src/services/converters.js | 38 + src/services/formatDuration.js | 46 + src/services/symbols.js | 29 + src/services/symbols/BaseSymbolService.js | 41 - src/services/symbols/EmojiService.js | 46 - src/services/symbols/SymbolService.js | 60 -- src/services/symbols/TextSymbolService.js | 43 - .../PickupTimeEstimatesTableRowsBuilder.js | 26 - .../tables/TripPriceEstimateRowFormatter.js | 58 -- .../buildPickupTimeEstimatesTableRows.js | 27 + .../PickupTimeEstimatesTableBuilder.js | 46 - .../TripPriceEstimatesTableBuilder.js | 57 - .../builders/buildPickupTimeEstimatesTable.js | 29 + .../builders/buildTripPriceEstimatesTable.js | 59 ++ .../tables/formatTripPriceEstimateRow.js | 50 + 28 files changed, 1318 insertions(+), 633 deletions(-) create mode 100644 src/index.js delete mode 100644 src/services/CommandExecutionService.js delete mode 100644 src/services/DistanceConverter.js delete mode 100644 src/services/DurationConverter.js delete mode 100644 src/services/DurationFormatter.js delete mode 100644 src/services/Utilities.js create mode 100644 src/services/converters.js create mode 100644 src/services/formatDuration.js create mode 100644 src/services/symbols.js delete mode 100644 src/services/symbols/BaseSymbolService.js delete mode 100644 src/services/symbols/EmojiService.js delete mode 100644 src/services/symbols/SymbolService.js delete mode 100644 src/services/symbols/TextSymbolService.js delete mode 100644 src/services/tables/PickupTimeEstimatesTableRowsBuilder.js delete mode 100644 src/services/tables/TripPriceEstimateRowFormatter.js create mode 100644 src/services/tables/buildPickupTimeEstimatesTableRows.js delete mode 100644 src/services/tables/builders/PickupTimeEstimatesTableBuilder.js delete mode 100644 src/services/tables/builders/TripPriceEstimatesTableBuilder.js create mode 100644 src/services/tables/builders/buildPickupTimeEstimatesTable.js create mode 100644 src/services/tables/builders/buildTripPriceEstimatesTable.js create mode 100644 src/services/tables/formatTripPriceEstimateRow.js diff --git a/.travis.yml b/.travis.yml index 7a19e7b..d40cf03 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,7 +13,7 @@ jobs: include: - stage: test script: - - npm run compile + - npm run build - npm run lint - npm run test before_script: greenkeeper-lockfile-update diff --git a/package-lock.json b/package-lock.json index aa8e371..32cdc2a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1446,11 +1446,513 @@ } } }, + "@commitlint/cli": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-6.2.0.tgz", + "integrity": "sha1-svgZDrCMzXjuplEUuGTzxl7KRmo=", + "dev": true, + "requires": { + "@commitlint/format": "^6.1.3", + "@commitlint/lint": "^6.2.0", + "@commitlint/load": "^6.1.3", + "@commitlint/read": "^6.1.3", + "babel-polyfill": "6.26.0", + "chalk": "2.3.1", + "get-stdin": "5.0.1", + "lodash.merge": "4.6.1", + "lodash.pick": "4.4.0", + "meow": "4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz", + "integrity": "sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.2.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 + }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@commitlint/config-angular": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/@commitlint/config-angular/-/config-angular-6.1.3.tgz", + "integrity": "sha1-aPRnhv08PveAjEztQuBXIerY9gQ=", + "dev": true, + "requires": { + "@commitlint/config-angular-type-enum": "^6.1.3" + } + }, + "@commitlint/config-angular-type-enum": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/@commitlint/config-angular-type-enum/-/config-angular-type-enum-6.1.3.tgz", + "integrity": "sha1-8xDcHCTIvp7TIMJikajRjPoRpF8=", + "dev": true + }, + "@commitlint/ensure": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-6.1.3.tgz", + "integrity": "sha1-gTtYyf364VNRty/mRqFi69tx6io=", + "dev": true, + "requires": { + "lodash.camelcase": "4.3.0", + "lodash.kebabcase": "4.1.1", + "lodash.snakecase": "4.1.1", + "lodash.startcase": "4.4.0", + "lodash.upperfirst": "4.3.1" + } + }, + "@commitlint/execute-rule": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-6.1.3.tgz", + "integrity": "sha1-SJKOc27xXocQ0zKhXHyJlVXk4Qs=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0" + } + }, + "@commitlint/format": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-6.1.3.tgz", + "integrity": "sha1-QUuQSKmvVFh9qWIicXujMjR6veM=", + "dev": true, + "requires": { + "babel-runtime": "^6.23.0", + "chalk": "^2.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.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 + }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@commitlint/is-ignored": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-6.1.3.tgz", + "integrity": "sha1-icm5ZKTWIoh1pXnCv1UtADc0t+g=", + "dev": true, + "requires": { + "semver": "5.5.0" + }, + "dependencies": { + "semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", + "dev": true + } + } + }, + "@commitlint/lint": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-6.2.0.tgz", + "integrity": "sha1-148hl0W3c2LhuBTV9M7C7MMmZhk=", + "dev": true, + "requires": { + "@commitlint/is-ignored": "^6.1.3", + "@commitlint/parse": "^6.1.3", + "@commitlint/rules": "^6.2.0", + "babel-runtime": "^6.23.0", + "lodash.topairs": "4.3.0" + } + }, + "@commitlint/load": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-6.1.3.tgz", + "integrity": "sha1-G+QHETl5WPMWz0BXepyHmhbwClQ=", + "dev": true, + "requires": { + "@commitlint/execute-rule": "^6.1.3", + "@commitlint/resolve-extends": "^6.1.3", + "babel-runtime": "^6.23.0", + "cosmiconfig": "^4.0.0", + "lodash.merge": "4.6.1", + "lodash.mergewith": "4.6.1", + "lodash.pick": "4.4.0", + "lodash.topairs": "4.3.0", + "resolve-from": "4.0.0" + }, + "dependencies": { + "cosmiconfig": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-4.0.0.tgz", + "integrity": "sha512-6e5vDdrXZD+t5v0L8CrurPeybg4Fmf+FCSYxXKYVAqLUtyCSbuyqE059d0kDthTNRzKVjL7QMgNpEUlsoYH3iQ==", + "dev": true, + "requires": { + "is-directory": "^0.3.1", + "js-yaml": "^3.9.0", + "parse-json": "^4.0.0", + "require-from-string": "^2.0.1" + } + }, + "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" + } + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + } + } + }, + "@commitlint/message": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-6.1.3.tgz", + "integrity": "sha1-XgRzMwyIcBYBDExWJwcjuAARRdI=", + "dev": true + }, + "@commitlint/parse": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-6.1.3.tgz", + "integrity": "sha1-/x5NksJ81naBK7a512zYhTwNlAc=", + "dev": true, + "requires": { + "conventional-changelog-angular": "^1.3.3", + "conventional-commits-parser": "^2.1.0" + }, + "dependencies": { + "conventional-changelog-angular": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-1.6.6.tgz", + "integrity": "sha512-suQnFSqCxRwyBxY68pYTsFkG0taIdinHLNEAX5ivtw8bCRnIgnpvcHmlR/yjUyZIrNPYAoXlY1WiEKWgSE4BNg==", + "dev": true, + "requires": { + "compare-func": "^1.3.1", + "q": "^1.5.1" + } + } + } + }, + "@commitlint/prompt": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/@commitlint/prompt/-/prompt-6.1.3.tgz", + "integrity": "sha1-yk3uWCocJClyZta7b16w7UWh20Y=", + "dev": true, + "requires": { + "@commitlint/load": "^6.1.3", + "babel-runtime": "^6.23.0", + "chalk": "^2.0.0", + "lodash.camelcase": "4.3.0", + "lodash.kebabcase": "4.1.1", + "lodash.snakecase": "4.1.1", + "lodash.startcase": "4.4.0", + "lodash.topairs": "4.3.0", + "lodash.upperfirst": "4.3.1", + "throat": "^4.1.0", + "vorpal": "^1.10.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.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 + }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@commitlint/prompt-cli": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/@commitlint/prompt-cli/-/prompt-cli-6.1.3.tgz", + "integrity": "sha1-pptfmH2siFZvYQ3sMesn5Ya5xJU=", + "dev": true, + "requires": { + "@commitlint/prompt": "^6.1.3", + "execa": "0.9.0", + "meow": "3.7.0" + }, + "dependencies": { + "camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", + "dev": true + }, + "camelcase-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", + "dev": true, + "requires": { + "camelcase": "^2.0.0", + "map-obj": "^1.0.0" + } + }, + "execa": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.9.0.tgz", + "integrity": "sha512-BbUMBiX4hqiHZUA5+JujIjNb6TyAlp2D5KLheMjMluwOuzcnylDL4AxZYLLn1n2AGB49eSWwyKvvEQoRpnAtmA==", + "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" + } + }, + "get-stdin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", + "dev": true + }, + "indent-string": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", + "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", + "dev": true, + "requires": { + "repeating": "^2.0.0" + } + }, + "meow": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", + "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", + "dev": true, + "requires": { + "camelcase-keys": "^2.0.0", + "decamelize": "^1.1.2", + "loud-rejection": "^1.0.0", + "map-obj": "^1.0.1", + "minimist": "^1.1.3", + "normalize-package-data": "^2.3.4", + "object-assign": "^4.0.1", + "read-pkg-up": "^1.0.1", + "redent": "^1.0.0", + "trim-newlines": "^1.0.0" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "redent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", + "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", + "dev": true, + "requires": { + "indent-string": "^2.1.0", + "strip-indent": "^1.0.1" + } + }, + "strip-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", + "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", + "dev": true, + "requires": { + "get-stdin": "^4.0.1" + } + }, + "trim-newlines": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", + "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", + "dev": true + } + } + }, + "@commitlint/read": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-6.1.3.tgz", + "integrity": "sha1-n52NtQ+/Z/MACSFlftbvrbjPnxo=", + "dev": true, + "requires": { + "@commitlint/top-level": "^6.1.3", + "@marionebl/sander": "^0.6.0", + "babel-runtime": "^6.23.0", + "git-raw-commits": "^1.3.0" + } + }, + "@commitlint/resolve-extends": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-6.1.3.tgz", + "integrity": "sha1-9F/P5Dhg4F4489lNVMrtfdqkHiU=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "lodash.merge": "4.6.1", + "lodash.omit": "4.5.0", + "require-uncached": "^1.0.3", + "resolve-from": "^4.0.0", + "resolve-global": "^0.1.0" + }, + "dependencies": { + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + } + } + }, + "@commitlint/rules": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-6.2.0.tgz", + "integrity": "sha1-k5H2WhZVKCIEjUWjOrbON0aG4Gs=", + "dev": true, + "requires": { + "@commitlint/ensure": "^6.1.3", + "@commitlint/message": "^6.1.3", + "@commitlint/to-lines": "^6.1.3", + "babel-runtime": "^6.23.0" + } + }, + "@commitlint/to-lines": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-6.1.3.tgz", + "integrity": "sha1-erFqAsrtjapH6Vkmm5YWRhCinQw=", + "dev": true + }, + "@commitlint/top-level": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-6.1.3.tgz", + "integrity": "sha1-Em3LbeFnY0LGnNQiYUg/RHhUcpk=", + "dev": true, + "requires": { + "find-up": "^2.1.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" + } + } + } + }, "@google/maps": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/@google/maps/-/maps-0.3.1.tgz", "integrity": "sha1-PxAwMDPlPT/Hu51iaN4iZoA794E=" }, + "@marionebl/sander": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@marionebl/sander/-/sander-0.6.1.tgz", + "integrity": "sha1-GViWWHTyS8Ub5Ih1/rUNZC/EH3s=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.3", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.2" + }, + "dependencies": { + "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" + } + } + } + }, "@mrmlnc/readdir-enhanced": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", @@ -3476,6 +3978,31 @@ "dev": true, "optional": true }, + "camelcase-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-4.2.0.tgz", + "integrity": "sha1-oqpfsa9oh1glnDLBQUJteJI7m3c=", + "dev": true, + "requires": { + "camelcase": "^4.1.0", + "map-obj": "^2.0.0", + "quick-lru": "^1.0.0" + }, + "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 + }, + "map-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-2.0.0.tgz", + "integrity": "sha1-plzSkIepJZi4eRJXpSPgISIqwfk=", + "dev": true + } + } + }, "caniuse-lite": { "version": "1.0.30000847", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000847.tgz", @@ -4311,6 +4838,15 @@ "array-find-index": "^1.0.1" } }, + "dargs": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/dargs/-/dargs-4.1.0.tgz", + "integrity": "sha1-A6nbtLXC8Tm/FK5T8LiipqhvThc=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, "dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", @@ -5061,6 +5597,12 @@ "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", "dev": true }, + "exit-hook": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", + "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=", + "dev": true + }, "expand-brackets": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", @@ -6213,6 +6755,12 @@ "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", "dev": true }, + "get-stdin": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-5.0.1.tgz", + "integrity": "sha1-Ei4WFZHiH/TFJTAwVpPyDmOTo5g=", + "dev": true + }, "get-stream": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", @@ -6258,6 +6806,19 @@ } } }, + "git-raw-commits": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-1.3.6.tgz", + "integrity": "sha512-svsK26tQ8vEKnMshTDatSIQSMDdz8CxIIqKsvPqbtV23Etmw6VNaFAitu8zwZ0VrOne7FztwPyRLxK7/DIUTQg==", + "dev": true, + "requires": { + "dargs": "^4.0.1", + "lodash.template": "^4.0.2", + "meow": "^4.0.0", + "split2": "^2.0.0", + "through2": "^2.0.0" + } + }, "git-up": { "version": "2.0.10", "resolved": "https://registry.npmjs.org/git-up/-/git-up-2.0.10.tgz", @@ -6734,6 +7295,18 @@ "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", "dev": true }, + "in-publish": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.0.tgz", + "integrity": "sha1-4g/146KvwmkDILbcVSaCqcf631E=", + "dev": true + }, + "indent-string": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", + "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=", + "dev": true + }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -8778,6 +9351,12 @@ "resolved": "https://registry.npmjs.org/lodash._objecttypes/-/lodash._objecttypes-2.3.0.tgz", "integrity": "sha1-aj6jmH3W7rgCGy1cnDA1Scwrrh4=" }, + "lodash._reinterpolate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", + "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", + "dev": true + }, "lodash._renative": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/lodash._renative/-/lodash._renative-2.3.0.tgz", @@ -8821,6 +9400,12 @@ "lodash._slice": "~2.3.0" } }, + "lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=", + "dev": true + }, "lodash.foreach": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/lodash.foreach/-/lodash.foreach-2.3.0.tgz", @@ -8864,6 +9449,12 @@ "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", "dev": true }, + "lodash.kebabcase": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz", + "integrity": "sha1-hImxyw0p/4gZXM7KRI/21swpXDY=", + "dev": true + }, "lodash.keys": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-2.3.0.tgz", @@ -8874,11 +9465,41 @@ "lodash.isobject": "~2.3.0" } }, + "lodash.merge": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.1.tgz", + "integrity": "sha512-AOYza4+Hf5z1/0Hztxpm2/xiPZgi/cjMqdnKTUWTBSKchJlxXXuUSxCCl8rJlf4g6yww/j6mA8nC8Hw/EZWxKQ==", + "dev": true + }, + "lodash.mergewith": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz", + "integrity": "sha512-eWw5r+PYICtEBgrBE5hhlT6aAa75f411bgDz/ZL2KZqYV03USvucsxcHUIlGTDTECs1eunpI7HOV7U+WLDvNdQ==", + "dev": true + }, "lodash.noop": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/lodash.noop/-/lodash.noop-2.3.0.tgz", "integrity": "sha1-MFnWKNUbv5N80qC2/Dp/ISpmnCw=" }, + "lodash.omit": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.omit/-/lodash.omit-4.5.0.tgz", + "integrity": "sha1-brGa5aHuHdnfC5aeZs4Lf6MLXmA=", + "dev": true + }, + "lodash.pick": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", + "integrity": "sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM=", + "dev": true + }, + "lodash.snakecase": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz", + "integrity": "sha1-OdcUo1NXFHg3rv1ktdy7Fr7Nj40=", + "dev": true + }, "lodash.some": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/lodash.some/-/lodash.some-4.6.0.tgz", @@ -8891,6 +9512,12 @@ "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", "dev": true }, + "lodash.startcase": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.startcase/-/lodash.startcase-4.4.0.tgz", + "integrity": "sha1-lDbjTtJgk+1/+uGTYUQ1CRXZrdg=", + "dev": true + }, "lodash.support": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/lodash.support/-/lodash.support-2.3.0.tgz", @@ -8899,11 +9526,85 @@ "lodash._renative": "~2.3.0" } }, + "lodash.template": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.4.0.tgz", + "integrity": "sha1-5zoDhcg1VZF0bgILmWecaQ5o+6A=", + "dev": true, + "requires": { + "lodash._reinterpolate": "~3.0.0", + "lodash.templatesettings": "^4.0.0" + } + }, + "lodash.templatesettings": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.1.0.tgz", + "integrity": "sha1-K01OlbpEDZFf8IvImeRVNmZxMxY=", + "dev": true, + "requires": { + "lodash._reinterpolate": "~3.0.0" + } + }, "lodash.toarray": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.toarray/-/lodash.toarray-4.4.0.tgz", "integrity": "sha1-JMS/zWsvuji/0FlNsRedjptlZWE=" }, + "lodash.topairs": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.topairs/-/lodash.topairs-4.3.0.tgz", + "integrity": "sha1-O23qo31g+xFnE8RsXxfqGQ7EjWQ=", + "dev": true + }, + "lodash.upperfirst": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz", + "integrity": "sha1-E2Xt9DFIBIHvDRxolXpe2Z1J984=", + "dev": true + }, + "log-update": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-1.0.2.tgz", + "integrity": "sha1-GZKfZMQJPS0ucHWh2tivWcKWuNE=", + "dev": true, + "requires": { + "ansi-escapes": "^1.0.0", + "cli-cursor": "^1.0.2" + }, + "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 + }, + "cli-cursor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", + "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", + "dev": true, + "requires": { + "restore-cursor": "^1.0.1" + } + }, + "onetime": { + "version": "1.1.0", + "resolved": "http://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", + "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", + "dev": true + }, + "restore-cursor": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", + "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", + "dev": true, + "requires": { + "exit-hook": "^1.0.0", + "onetime": "^1.0.0" + } + } + } + }, "longest": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", @@ -9010,6 +9711,104 @@ "mimic-fn": "^1.0.0" } }, + "meow": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-4.0.0.tgz", + "integrity": "sha512-Me/kel335m6vMKmEmA6c87Z6DUFW3JqkINRnxkbC+A/PUm0D5Fl2dEBQrPKnqCL9Te/CIa1MUt/0InMJhuC/sw==", + "dev": true, + "requires": { + "camelcase-keys": "^4.0.0", + "decamelize-keys": "^1.0.0", + "loud-rejection": "^1.0.0", + "minimist": "^1.1.3", + "minimist-options": "^3.0.1", + "normalize-package-data": "^2.3.4", + "read-pkg-up": "^3.0.0", + "redent": "^2.0.0", + "trim-newlines": "^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" + } + }, + "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" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "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-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": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "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": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", + "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^3.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 + } + } + }, "merge": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/merge/-/merge-1.2.0.tgz", @@ -9235,6 +10034,12 @@ "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", "dev": true }, + "node-localstorage": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/node-localstorage/-/node-localstorage-0.6.0.tgz", + "integrity": "sha1-RaBgHGky395mRKIzYfG+Fzx1068=", + "dev": true + }, "node-notifier": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.2.1.tgz", @@ -10092,6 +10897,25 @@ "set-immediate-shim": "^1.0.1" } }, + "readline2": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz", + "integrity": "sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "mute-stream": "0.0.5" + }, + "dependencies": { + "mute-stream": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz", + "integrity": "sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA=", + "dev": true + } + } + }, "realpath-native": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-1.0.0.tgz", @@ -10101,6 +10925,16 @@ "util.promisify": "^1.0.0" } }, + "redent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-2.0.0.tgz", + "integrity": "sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo=", + "dev": true, + "requires": { + "indent-string": "^3.0.0", + "strip-indent": "^2.0.0" + } + }, "redeyed": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-1.0.1.tgz", @@ -10325,6 +11159,12 @@ "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", "dev": true }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true + }, "require-main-filename": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", @@ -10370,6 +11210,15 @@ "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", "dev": true }, + "resolve-global": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/resolve-global/-/resolve-global-0.1.0.tgz", + "integrity": "sha1-j7As/Vt9sgEY6IYxHxWvlb0V+9k=", + "dev": true, + "requires": { + "global-dirs": "^0.1.0" + } + }, "resolve-url": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", @@ -11540,6 +12389,12 @@ "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", "dev": true }, + "strip-indent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", + "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=", + "dev": true + }, "strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", @@ -12254,6 +13109,12 @@ } } }, + "trim-newlines": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-2.0.0.tgz", + "integrity": "sha1-tAPQuRvlDDMd/EuC7s6yLD3hbSA=", + "dev": true + }, "trim-off-newlines": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/trim-off-newlines/-/trim-off-newlines-1.0.1.tgz", @@ -12621,6 +13482,128 @@ "extsprintf": "^1.2.0" } }, + "vorpal": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/vorpal/-/vorpal-1.12.0.tgz", + "integrity": "sha1-S+eypOSPj8/JzzZIxBnTEcUiFZ0=", + "dev": true, + "requires": { + "babel-polyfill": "^6.3.14", + "chalk": "^1.1.0", + "in-publish": "^2.0.0", + "inquirer": "0.11.0", + "lodash": "^4.5.1", + "log-update": "^1.0.2", + "minimist": "^1.2.0", + "node-localstorage": "^0.6.0", + "strip-ansi": "^3.0.0", + "wrap-ansi": "^2.0.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 + }, + "cli-cursor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", + "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", + "dev": true, + "requires": { + "restore-cursor": "^1.0.1" + } + }, + "cli-width": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-1.1.1.tgz", + "integrity": "sha1-pNKT72frt7iNSk1CwMzwDE0eNm0=", + "dev": true + }, + "figures": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", + "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5", + "object-assign": "^4.1.0" + } + }, + "inquirer": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.11.0.tgz", + "integrity": "sha1-dEi/qSQJKvMR1HFzu6uZDK4rsCc=", + "dev": true, + "requires": { + "ansi-escapes": "^1.1.0", + "ansi-regex": "^2.0.0", + "chalk": "^1.0.0", + "cli-cursor": "^1.0.1", + "cli-width": "^1.0.1", + "figures": "^1.3.5", + "lodash": "^3.3.1", + "readline2": "^1.0.1", + "run-async": "^0.1.0", + "rx-lite": "^3.1.2", + "strip-ansi": "^3.0.0", + "through": "^2.3.6" + }, + "dependencies": { + "lodash": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", + "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=", + "dev": true + } + } + }, + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "dev": true + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "onetime": { + "version": "1.1.0", + "resolved": "http://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", + "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", + "dev": true + }, + "restore-cursor": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", + "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", + "dev": true, + "requires": { + "exit-hook": "^1.0.0", + "onetime": "^1.0.0" + } + }, + "run-async": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz", + "integrity": "sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=", + "dev": true, + "requires": { + "once": "^1.3.0" + } + }, + "rx-lite": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz", + "integrity": "sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI=", + "dev": true + } + } + }, "w3c-hr-time": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz", diff --git a/package.json b/package.json index f195e96..477d53f 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,10 @@ "@babel/plugin-transform-async-to-generator": "^7.0.0-beta.49", "@babel/plugin-transform-runtime": "^7.0.0-beta.49", "@babel/preset-env": "^7.0.0-beta.49", + "@commitlint/cli": "^6.0.2", + "@commitlint/config-angular": "^6.0.2", + "@commitlint/prompt": "^6.0.2", + "@commitlint/prompt-cli": "^6.0.2", "babel-core": "^7.0.0-bridge.0", "babel-jest": "^23.0.1", "babel-preset-minify": "^0.4.2", @@ -52,12 +56,12 @@ "scripts": { "codecov": "codecov", "commitmsg": "commitlint -e $GIT_PARAMS", - "compile": "babel src/ -d build/ --delete-dir-on-start", - "compile:prod": "BABEL_ENV=production npm run compile", + "build": "babel src/ -d build/ --delete-dir-on-start", + "build:prod": "BABEL_ENV=production npm run compile", "lint": "eslint --ext .js .", "test": "jest", "prepublishOnly": "npm run compile:prod", - "semantic-commit": "commit", + "gc": "commit", "semantic-release": "semantic-release", "travis-deploy-once": "travis-deploy-once" } diff --git a/src/executables/uber-price.js b/src/executables/uber-price.js index 31c3820..25ee7d9 100644 --- a/src/executables/uber-price.js +++ b/src/executables/uber-price.js @@ -4,23 +4,7 @@ import program from 'commander'; -import CommandExecutionService from '../services/CommandExecutionService'; -import SymbolService from '../services/symbols/SymbolService'; - -const isUberError = error => - error.name === 'Uber Error' && - typeof (error.code) !== 'undefined' && - typeof (error.error) !== 'undefined'; - -const isDistanceExceededError = error => - isUberError(error) && - error.code === 422 && - 'code' in error.error && - error.error.code === 'distance_exceeded'; - -const service = new CommandExecutionService(); - -const symbolService = new SymbolService(); +import { buildPriceEstimates } from '..'; program .option('-s, --start ', 'specify start address') @@ -28,22 +12,7 @@ program .option('-u, --unit [unit]', 'specify distance unit') .parse(process.argv); +const { start, end, unit } = program; -if (typeof program.start !== 'string' && typeof program.end !== 'string') { - // Output help if there are no arguments or flags. - program.outputHelp(); -} else { - try { - service.executePriceEstimates(program.start, program.end, program.unit) - .then(table => console.log(table)) - .catch((e) => { - if (isDistanceExceededError(e)) { - console.log(`Maximum distance of ${symbolService.getMaximumDistanceSymbol()} miles exceeded between start address: ${program.start} and end address: ${program.end}`); - } else { - console.error('Could not get price estimates:\n', e.message); - } - }); - } catch (e) { - console.error('Could not get price estimates:\n', e.message); - } -} +buildPriceEstimates({ startAddress: start, endAddress: end, distanceUnitName: unit }) + .catch(e => console.error('Could not get price estimates:\n', e)); diff --git a/src/executables/uber-time.js b/src/executables/uber-time.js index 4524b62..1db6e79 100644 --- a/src/executables/uber-time.js +++ b/src/executables/uber-time.js @@ -3,28 +3,13 @@ /* eslint-disable no-console */ import program from 'commander'; - -import CommandExecutionService from '../services/CommandExecutionService'; - -const service = new CommandExecutionService(); +import { buildTimeEstimates } from '../'; program - .usage('
') .description('Get Time-To-Pickup Estimates') + .arguments('
') + .action((address) => { + buildTimeEstimates(address) + .catch(e => console.error('Could not get time estimates:\n', e)); + }) .parse(process.argv); - -const address = program.args.toString(); - -if (!address) { - program.outputHelp(); -} else { - try { - service.executeTimeEstimates(address) - .then(table => console.log(table)) - .catch((e) => { - console.error('Could not get time estimates:\n', e.message); - }); - } catch (e) { - console.error('Could not get time estimates:\n', e.message); - } -} diff --git a/src/executables/uber.js b/src/executables/uber.js index 675f1ea..ddb2c42 100644 --- a/src/executables/uber.js +++ b/src/executables/uber.js @@ -7,6 +7,6 @@ import pkg from '../../package.json'; program.version(pkg.version) .description('Figure out if you should order a car to pick you up and drive you to where you want to go') .command('price', 'get price estimate') - .command('time [address]', 'get time to pickup estimate') + .command('time', 'get time to pickup estimate') .parse(process.argv); diff --git a/src/index.js b/src/index.js new file mode 100644 index 0000000..58cadb3 --- /dev/null +++ b/src/index.js @@ -0,0 +1,37 @@ +import DistanceUnit from './data/DistanceUnit'; +import UberService from './services/UberService'; +import { + convertDistance, + convertDuration, +} from './services/converters'; +import buildTripPriceEstimatesTable from './services/tables/builders/buildTripPriceEstimatesTable'; +import buildPickupTimeEstimatesTable from './services/tables/builders/buildPickupTimeEstimatesTable'; +import symbols from './services/symbols'; + +const buildPriceEstimates = async ({ startAddress, endAddress, distanceUnitName }) => { + if (typeof startAddress !== 'string' || typeof endAddress !== 'string') { + throw new TypeError( + 'Start and End addresses (-s \'
\' -e \'
\') are required.', + ); + } + + const distanceUnit = distanceUnitName ? DistanceUnit[distanceUnitName.toUpperCase()] : DistanceUnit.MILE; + const uberService = new UberService(); + const estimates = await uberService.getPriceEstimates({ startAddress, endAddress }); + console.log(buildTripPriceEstimatesTable({ estimates, presentationUnits: distanceUnit })); +} + +const buildTimeEstimates = async (address) => { + if (typeof address !== 'string') { + throw new TypeError('Address should be a string'); + } + + const uberService = new UberService(); + const estimates = await uberService.getTimeEstimates(address); + console.log(buildPickupTimeEstimatesTable({ estimates: estimates.estimates, location: estimates.location })); +} + +export { + buildPriceEstimates, + buildTimeEstimates, +}; diff --git a/src/services/CommandExecutionService.js b/src/services/CommandExecutionService.js deleted file mode 100644 index df6ed07..0000000 --- a/src/services/CommandExecutionService.js +++ /dev/null @@ -1,60 +0,0 @@ -import DistanceUnit from '../data/DistanceUnit'; -import UberService from './UberService'; -import DistanceConverter from './DistanceConverter'; -import DurationConverter from './DurationConverter'; -import DurationFormatter from './DurationFormatter'; -import TripPriceEstimateRowFormatter from './tables/TripPriceEstimateRowFormatter'; -import TripPriceEstimatesTableBuilder from './tables/builders/TripPriceEstimatesTableBuilder'; -import PickupTimeEstimatesTableRowsBuilder from './tables/PickupTimeEstimatesTableRowsBuilder'; -import PickupTimeEstimatesTableBuilder from './tables/builders/PickupTimeEstimatesTableBuilder'; -import SymbolService from './symbols/SymbolService'; - -export default class CommandExecutionService { - constructor() { - this.uberService = new UberService(); - this.distanceConverter = new DistanceConverter(); - this.durationConverter = new DurationConverter(); - this.symbolService = new SymbolService(); - this.durationFormatter = new DurationFormatter(this.durationConverter); - this.tripPriceEstimateRowFormatter = new TripPriceEstimateRowFormatter(this.distanceConverter, this.durationFormatter, this.symbolService); // eslint-disable-line max-len - this.tripPriceEstimatesTableBuilder = new TripPriceEstimatesTableBuilder(this.tripPriceEstimateRowFormatter, this.symbolService); // eslint-disable-line max-len - this.pickupTimeEstimatesTableRowsBuilder = new PickupTimeEstimatesTableRowsBuilder(this.durationFormatter, this.symbolService); // eslint-disable-line max-len - this.pickupTimeEstimatesTableBuilder = new PickupTimeEstimatesTableBuilder(this.pickupTimeEstimatesTableRowsBuilder, this.symbolService); // eslint-disable-line max-len - } - - executePriceEstimates(startAddress, endAddress, distanceUnitName) { - // commander.js doesn't support required arguments, and will always - // interpolate arguments into strings. - if (typeof startAddress !== 'string' || typeof endAddress !== 'string') { - throw new TypeError( - 'Start and End addresses (-s \'
\' -e \'
\') are required.', - ); - } - - let distanceUnit = DistanceUnit.MILE; - if (typeof distanceUnitName === 'string') { - distanceUnit = DistanceUnit.enumValueOf(distanceUnitName.toUpperCase()); - } - - if (typeof distanceUnit === 'undefined') { - throw new TypeError(`Unknown distance unit: ${distanceUnitName}`); - } - - const query = { - startAddress, - endAddress, - }; - - return this.uberService.getPriceEstimates(query) - .then(estimates => this.tripPriceEstimatesTableBuilder.build(estimates, distanceUnit)); - } - - executeTimeEstimates(address) { - if (typeof address !== 'string') { - throw new TypeError('Address should be a string'); - } - - return this.uberService.getTimeEstimates(address) - .then(estimates => this.pickupTimeEstimatesTableBuilder.build(estimates)); - } -} diff --git a/src/services/DistanceConverter.js b/src/services/DistanceConverter.js deleted file mode 100644 index fab2249..0000000 --- a/src/services/DistanceConverter.js +++ /dev/null @@ -1,48 +0,0 @@ -import convert from 'convert-units'; - -import DistanceUnit from '../data/DistanceUnit'; - -export default class DistanceConverter { - constructor() { - const unitConversionIdentifier = {}; - unitConversionIdentifier[DistanceUnit.MILE.name] = 'mi'; - unitConversionIdentifier[DistanceUnit.KILOMETER.name] = 'm'; - - this.unitConversionIdentifier = unitConversionIdentifier; - } - - convert(distance, toUnit) { - const fromUnitIdentifier = this.getUnitConversionIdentifier(distance.unit); - const toUnitIdentifier = this.getUnitConversionIdentifier(toUnit); - const convertedValue = convert(distance.value).from(fromUnitIdentifier).to(toUnitIdentifier); - - switch (toUnit) { - case DistanceUnit.KILOMETER: { - // Note divided by 1000 because convert library does not have kilometers, so using meters - return { - value: convertedValue / 1000, - unit: DistanceUnit.KILOMETER, - }; - } - - case DistanceUnit.MILE: { - return { - value: convertedValue, - unit: DistanceUnit.MILE, - }; - } - - default: { - throw new TypeError(`Unknown unit: ${toUnit}`); - } - } - } - - getUnitConversionIdentifier(unit) { - const identifier = this.unitConversionIdentifier.get(unit.name); - if (typeof identifier === 'undefined') { - throw new TypeError('Unknown unit'); - } - return identifier; - } -} diff --git a/src/services/DurationConverter.js b/src/services/DurationConverter.js deleted file mode 100644 index bf0b9cd..0000000 --- a/src/services/DurationConverter.js +++ /dev/null @@ -1,32 +0,0 @@ -import convert from 'convert-units'; - -import TimeUnit from '../data/TimeUnit'; - -export default class DurationConverter { - constructor() { - const durationUnitAbbreviations = {}; - durationUnitAbbreviations[TimeUnit.SECOND.name] = 's'; - durationUnitAbbreviations[TimeUnit.MINUTE.name] = 'min'; - - this.durationUnitAbbreviations = durationUnitAbbreviations; - } - - convert(duration, toUnit) { - const fromUnitIdentifier = this.getUnitConversionIdentifier(duration.unit); - const toUnitIdentifier = this.getUnitConversionIdentifier(toUnit); - const convertedLength = convert(duration.length).from(fromUnitIdentifier).to(toUnitIdentifier); - return { - length: convertedLength, - unit: toUnit, - }; - } - - getUnitConversionIdentifier(unit) { - const durationUnitAbbreviation = this.durationUnitAbbreviations.get(unit.name); - if (typeof durationUnitAbbreviation === 'undefined') { - throw new TypeError(`Unknown unit: ${unit}`); - } - - return durationUnitAbbreviation; - } -} diff --git a/src/services/DurationFormatter.js b/src/services/DurationFormatter.js deleted file mode 100644 index 5e33e58..0000000 --- a/src/services/DurationFormatter.js +++ /dev/null @@ -1,49 +0,0 @@ -import TimeUnit from '../data/TimeUnit'; - -export default class DurationFormatter { - constructor(durationConverter) { - this.durationConverter = durationConverter; - } - - format(duration) { - const convertedDuration = this.durationConverter.convert(duration, TimeUnit.SECOND); - let seconds = convertedDuration.length; - - if (seconds < 0) { - throw new RangeError('Cannot generate formatted time for negative seconds'); - } - - if (seconds === 0) { - return '0 sec.'; - } - - const days = Math.floor(seconds / 86400); - seconds %= 86400; - - const hours = Math.floor(seconds / 3600); - seconds %= 3600; - - const minutes = Math.floor(seconds / 60); - seconds %= 60; - - let formattedTime = ''; - if (days !== 0) { - formattedTime += ` ${days} days`; - } - - if (hours !== 0) { - formattedTime += ` ${hours} hrs.`; - } - - if (minutes !== 0) { - formattedTime += ` ${minutes} min.`; - } - - if (seconds !== 0) { - formattedTime += ` ${seconds} sec.`; - } - - // GAWD THIS IS SO FUCKING HACKY I HATE EVERYTHING - return formattedTime.trim(); - } -} diff --git a/src/services/UberService.js b/src/services/UberService.js index 6e990ef..e13db85 100644 --- a/src/services/UberService.js +++ b/src/services/UberService.js @@ -29,7 +29,7 @@ export default class UberService { } async getPriceEstimates({ startAddress, endAddress }) { - const [ start, end ] = await Promise.all(this.getFirstLocation(startAddress), this.getFirstLocation(endAddress)); + const [ start, end ] = await Promise.all([this.getFirstLocation(startAddress), this.getFirstLocation(endAddress)]); const estimates = await this.uberClient.getPriceEstimates({ start: start.coordinate, end: end.coordinate }); return { start, diff --git a/src/services/Utilities.js b/src/services/Utilities.js deleted file mode 100644 index e1e05cc..0000000 --- a/src/services/Utilities.js +++ /dev/null @@ -1,5 +0,0 @@ -export default class Utilities { - static isFloat(n) { - return Number(n) === n && n % 1 !== 0; - } -} diff --git a/src/services/converters.js b/src/services/converters.js new file mode 100644 index 0000000..f05a876 --- /dev/null +++ b/src/services/converters.js @@ -0,0 +1,38 @@ +import convert from 'convert-units'; +import TimeUnit from '../data/TimeUnit'; +import DistanceUnit from '../data/DistanceUnit'; + +const DURATION_UNIT_ABBREVIATIONS = Object.freeze({ + [TimeUnit.SECOND]: 's', + [TimeUnit.MINUTE]: 'min', +}); + +const DISTANCE_UNIT_ABBREVIATIONS = Object.freeze({ + [DistanceUnit.MILE]: 'mi', + [DistanceUnit.KILOMETER]: 'km', +}); + +const DISTANCE_UNIT_MULTIPLIER = Object.freeze({ + [DistanceUnit.KILOMETER]: 0.0001, + [DistanceUnit.MILE]: 1, +}); + +const convertDuration = ({ duration, toUnit }) => ({ + length: convert(duration.length) + .from(DURATION_UNIT_ABBREVIATIONS[duration.unit]) + .to(DURATION_UNIT_ABBREVIATIONS[toUnit]), + unit: toUnit, +}); + +const convertDistance = ({ distance, toUnit }) => ({ + value: (convert(distance.value) + .from(DISTANCE_UNIT_ABBREVIATIONS[distance.unit]) + .to(DISTANCE_UNIT_ABBREVIATIONS[toUnit])) * DISTANCE_UNIT_MULTIPLIER[toUnit], + unit: toUnit, +}) + +export { + convertDuration, + convertDistance, + DISTANCE_UNIT_ABBREVIATIONS, +} diff --git a/src/services/formatDuration.js b/src/services/formatDuration.js new file mode 100644 index 0000000..3e7a76e --- /dev/null +++ b/src/services/formatDuration.js @@ -0,0 +1,46 @@ +import TimeUnit from '../data/TimeUnit'; +import { convertDuration } from './converters'; + +const formatDuration = duration => { + const convertedDuration = convertDuration({ duration, toUnit: TimeUnit.SECOND }); + let seconds = convertedDuration.length; + + if (seconds < 0) { + throw new RangeError('Cannot generate formatted time for negative seconds'); + } + + if (seconds === 0) { + return '0 sec.'; + } + + const days = Math.floor(seconds / 86400); + seconds %= 86400; + + const hours = Math.floor(seconds / 3600); + seconds %= 3600; + + const minutes = Math.floor(seconds / 60); + seconds %= 60; + + let formattedTime = ''; + if (days !== 0) { + formattedTime += ` ${days} days`; + } + + if (hours !== 0) { + formattedTime += ` ${hours} hrs.`; + } + + if (minutes !== 0) { + formattedTime += ` ${minutes} min.`; + } + + if (seconds !== 0) { + formattedTime += ` ${seconds} sec.`; + } + + // GAWD THIS IS SO FUCKING HACKY I HATE EVERYTHING + return formattedTime.trim(); +}; + +export default formatDuration; diff --git a/src/services/symbols.js b/src/services/symbols.js new file mode 100644 index 0000000..4126c6a --- /dev/null +++ b/src/services/symbols.js @@ -0,0 +1,29 @@ +const EMOJIS = Object.freeze({ + VEHICLE: '🚘', + PRICE: '💸', + TRIP_DISTANCE: '🔃', + DURATION: '⏳', + SURGE_MULTIPLIER: '💥', + NOT_APPLICABLE: '🚫', + SURGE_EXISTS: '😬', + DESTINATION: '🔚', + ORIGIN: '📍', + MAXIMUM_DISTANCE: '💯', +}); + +const TEXT = Object.freeze({ + VEHICLE: 'Vehicle', + PRICE: 'Price', + TRIP_DISTANCE: 'Distance', + DURATION: 'Duration', + SURGE_MULTIPLIER: ' *', + NOT_APPLICABLE: 'N/A', + SURGE_EXISTS: ':-(', + DESTINATION: 'Destination', + ORIGIN: 'Origin', + MAXIMUM_DISTANCE: '100', +}); + +const symbols = ['darwin'].indexOf(process.platform) >= 0 ? EMOJIS : TEXT; + +export default symbols; diff --git a/src/services/symbols/BaseSymbolService.js b/src/services/symbols/BaseSymbolService.js deleted file mode 100644 index 7198555..0000000 --- a/src/services/symbols/BaseSymbolService.js +++ /dev/null @@ -1,41 +0,0 @@ -export default class BaseSymbolService { - getVehicleSymbol() { - throw new Error('Not implemented'); - } - - getPriceSymbol() { - throw new Error('Not implemented'); - } - - getTripDistanceSymbol() { - throw new Error('Not implemented'); - } - - getDurationSymbol() { - throw new Error('Not implemented'); - } - - getSurgeSymbol() { - throw new Error('Not implemented'); - } - - getNotApplicableSymbol() { - throw new Error('Not implemented'); - } - - getSurgePresentSymbol() { - throw new Error('Not implemented'); - } - - getDestinationSymbol() { - throw new Error('Not implemented'); - } - - getOriginSymbol() { - throw new Error('Not implemented'); - } - - getMaximumDistanceSymbol() { - throw new Error('Not implemented'); - } -} diff --git a/src/services/symbols/EmojiService.js b/src/services/symbols/EmojiService.js deleted file mode 100644 index 9a9b787..0000000 --- a/src/services/symbols/EmojiService.js +++ /dev/null @@ -1,46 +0,0 @@ -import emoji from 'node-emoji'; - -import BaseSymbolService from './BaseSymbolService'; - - -export default class EmojiService extends BaseSymbolService { - getVehicleSymbol() { - return emoji.get('oncoming_automobile'); - } - - getPriceSymbol() { - return emoji.get('money_with_wings'); - } - - getTripDistanceSymbol() { - return emoji.get('arrows_clockwise'); - } - - getDurationSymbol() { - return emoji.get('hourglass_flowing_sand'); - } - - getSurgeSymbol() { - return emoji.get('boom'); - } - - getNotApplicableSymbol() { - return emoji.get('no_entry_sign'); - } - - getSurgePresentSymbol() { - return emoji.get('grimacing'); - } - - getDestinationSymbol() { - return emoji.get('end'); - } - - getOriginSymbol() { - return emoji.get('round_pushpin'); - } - - getMaximumDistanceSymbol() { - return emoji.get('100'); - } -} diff --git a/src/services/symbols/SymbolService.js b/src/services/symbols/SymbolService.js deleted file mode 100644 index dd3de83..0000000 --- a/src/services/symbols/SymbolService.js +++ /dev/null @@ -1,60 +0,0 @@ -import BaseSymbolService from './BaseSymbolService'; -import EmojiService from './EmojiService'; -import TextSymbolService from './TextSymbolService'; - -export default class SymbolService extends BaseSymbolService { - constructor() { - super(); - this.client = SymbolService.areEmojisSupported() ? - new EmojiService() : - new TextSymbolService(); - } - - static areEmojisSupported() { - return SymbolService.getEmojiSupportedOperatingSystems().contains(process.platform); - } - - static getEmojiSupportedOperatingSystems() { - return ['darwin']; - } - - getVehicleSymbol() { - return this.client.getVehicleSymbol(); - } - - getPriceSymbol() { - return this.client.getPriceSymbol(); - } - - getTripDistanceSymbol() { - return this.client.getTripDistanceSymbol(); - } - - getDurationSymbol() { - return this.client.getDurationSymbol(); - } - - getSurgeSymbol() { - return this.client.getSurgeSymbol(); - } - - getNotApplicableSymbol() { - return this.client.getNotApplicableSymbol(); - } - - getSurgePresentSymbol() { - return this.client.getSurgePresentSymbol(); - } - - getDestinationSymbol() { - return this.client.getDestinationSymbol(); - } - - getOriginSymbol() { - return this.client.getOriginSymbol(); - } - - getMaximumDistanceSymbol() { - return this.client.getMaximumDistanceSymbol(); - } -} diff --git a/src/services/symbols/TextSymbolService.js b/src/services/symbols/TextSymbolService.js deleted file mode 100644 index efeb915..0000000 --- a/src/services/symbols/TextSymbolService.js +++ /dev/null @@ -1,43 +0,0 @@ -import BaseSymbolService from './BaseSymbolService'; - -export default class TextSymbolService extends BaseSymbolService { - getVehicleSymbol() { - return 'Vehicle'; - } - - getPriceSymbol() { - return 'Price'; - } - - getTripDistanceSymbol() { - return 'Distance'; - } - - getDurationSymbol() { - return 'Duration'; - } - - getSurgeSymbol() { - return ' *'; - } - - getNotApplicableSymbol() { - return 'N/A'; - } - - getSurgePresentSymbol() { - return ':-('; - } - - getDestinationSymbol() { - return 'Destination'; - } - - getOriginSymbol() { - return 'Origin'; - } - - getMaximumDistanceSymbol() { - return '100'; - } -} diff --git a/src/services/tables/PickupTimeEstimatesTableRowsBuilder.js b/src/services/tables/PickupTimeEstimatesTableRowsBuilder.js deleted file mode 100644 index 045d133..0000000 --- a/src/services/tables/PickupTimeEstimatesTableRowsBuilder.js +++ /dev/null @@ -1,26 +0,0 @@ -export default class PickupTimeEstimatesTableRowsBuilder { - constructor(durationFormatter) { - this.durationFormatter = durationFormatter; - } - - build(estimates) { - const estimatesGroupedByTime = this.groupByTime(estimates); - return estimatesGroupedByTime.entrySeq().map(entry => [entry[0], entry[1]].join(', ')); - } - - groupByTime(estimates) { - let rows = {}; - estimates.forEach((estimate) => { - const formattedDuration = this.durationFormatter.format(estimate.estimatedDuration); - - if (rows.has(formattedDuration)) { - const productNames = rows.get(formattedDuration); - productNames.push(estimate.productName); - rows = rows.set(formattedDuration, productNames); - } else { - rows = rows.set(formattedDuration, [estimate.productName]); - } - }); - return rows; - } -} diff --git a/src/services/tables/TripPriceEstimateRowFormatter.js b/src/services/tables/TripPriceEstimateRowFormatter.js deleted file mode 100644 index 8c69cb2..0000000 --- a/src/services/tables/TripPriceEstimateRowFormatter.js +++ /dev/null @@ -1,58 +0,0 @@ -import DistanceUnit from '../../data/DistanceUnit'; - -export default class TripPriceEstimateRowFormatter { - constructor(distanceConverter, durationFormatter, symbolService) { - const distanceUnitAbbreviations = {}; - distanceUnitAbbreviations[DistanceUnit.MILE.name] = 'mi'; - distanceUnitAbbreviations[DistanceUnit.KILOMETER.name] = 'km'; - - this.distanceUnitAbbreviations = distanceUnitAbbreviations; - this.distanceConverter = distanceConverter; - this.durationFormatter = durationFormatter; - this.symbolService = symbolService; - } - - format(estimate, rowDistanceUnit) { - return [ - estimate.productName, - this.formatRange(estimate.range), - this.formatDistance(estimate.distance, rowDistanceUnit), - this.durationFormatter.format(estimate.duration), - this.formatSurgeMultiplier(estimate.surgeMultiplier), - ]; - } - - formatRange(range) { - return `${this.formatCurrencyValue(range.low, range.currencyCode)}-${this.formatCurrencyValue(range.high, range.currencyCode)}`; - } - - formatCurrencyValue(value, currencyCode) { - return Intl.NumberFormat('en-US', { - style: 'currency', - maximumFractionDigits: 0, - currency: currencyCode, - }).format(value); - } - - formatDistance(distance, rowDistanceUnit) { - // 2 decimal places - const convertedDistance = this.distanceConverter.convert(distance, rowDistanceUnit); - const roundedDistanceValue = Math.round(convertedDistance.value * 100) / 100; - return `${roundedDistanceValue} ${this.getDistanceUnitAbbreviation(convertedDistance.unit)}.`; - } - - formatSurgeMultiplier(surgeMultiplier) { - return surgeMultiplier > 1 ? - `${surgeMultiplier}x ${this.symbolService.getSurgePresentSymbol()}` : - this.symbolService.getNotApplicableSymbol(); - } - - getDistanceUnitAbbreviation(unit) { - const abbreviation = this.distanceUnitAbbreviations.get(unit.name); - if (abbreviation == null) { - throw new TypeError(`Unknown unit: ${unit}`); - } - - return abbreviation; - } -} diff --git a/src/services/tables/buildPickupTimeEstimatesTableRows.js b/src/services/tables/buildPickupTimeEstimatesTableRows.js new file mode 100644 index 0000000..646e5c4 --- /dev/null +++ b/src/services/tables/buildPickupTimeEstimatesTableRows.js @@ -0,0 +1,27 @@ +import formatDuration from '../formatDuration'; + +const buildPickupTimeEstimatesTableRows = estimates => { + estimates.sort((firstEstimate, secondEstimate) => (firstEstimate.estimatedDuration.length - secondEstimate.estimatedDuration.length)); + const groupedEstimates = groupEstimatesByTime(estimates); + return Object.keys(groupedEstimates).map(key => [ key, groupedEstimates[key].join(', ') ]); +}; + +const groupEstimatesByTime = estimates => { + const rows = {}; + + estimates.forEach(({ estimatedDuration, productName }) => { + const formattedDuration = formatDuration(estimatedDuration); + let productsWithSameDuration = rows[formattedDuration]; + + if (!productsWithSameDuration) { + productsWithSameDuration = []; + } + + productsWithSameDuration.push(productName); + rows[formattedDuration] = productsWithSameDuration; + }); + + return rows; +}; + +export default buildPickupTimeEstimatesTableRows; diff --git a/src/services/tables/builders/PickupTimeEstimatesTableBuilder.js b/src/services/tables/builders/PickupTimeEstimatesTableBuilder.js deleted file mode 100644 index 7b1eff3..0000000 --- a/src/services/tables/builders/PickupTimeEstimatesTableBuilder.js +++ /dev/null @@ -1,46 +0,0 @@ -import Table from 'cli-table2'; - -export default class PickupTimeEstimatesTableBuilder { - constructor(rowsBuilder, symbolService) { - this.rowsBuilder = rowsBuilder; - this.symbolService = symbolService; - } - - build(estimates) { - const table = this.buildInitialTable(estimates.location.name); - this.rowsBuilder.build(estimates.estimates).forEach(row => table.push(row)); - return table.toString(); - } - - getTableHeaders() { - return [ - this.symbolService.getDurationSymbol(), - this.symbolService.getVehicleSymbol(), - ]; - } - - getFormattedLocation(locationName) { - return [ - { - colSpan: 2, - content: `${this.symbolService.getOriginSymbol()} ${locationName}`, - hAlign: 'center', - }, - ]; - } - - getFormattedHeaders() { - return this.getTableHeaders() - .map(header => ({ - content: header, - hAlign: 'center', - })); - } - - buildInitialTable(locationName) { - const table = new Table(); - table.push(this.getFormattedLocation(locationName)); - table.push(this.getFormattedHeaders()); - return table; - } -} diff --git a/src/services/tables/builders/TripPriceEstimatesTableBuilder.js b/src/services/tables/builders/TripPriceEstimatesTableBuilder.js deleted file mode 100644 index 0a6a9dd..0000000 --- a/src/services/tables/builders/TripPriceEstimatesTableBuilder.js +++ /dev/null @@ -1,57 +0,0 @@ -import Table from 'cli-table2'; - -export default class TripPriceEstimatesTableBuilder { - constructor(rowFormatter, symbolService) { - this.rowFormatter = rowFormatter; - this.symbolService = symbolService; - } - - build(estimates, presentationDistanceUnit) { - const table = this.buildInitialTable(); - estimates.estimates.forEach((estimate) => { - if (estimate.productName !== 'TAXI') { - table.push(this.rowFormatter.format(estimate, presentationDistanceUnit)); - } - }); - table.push(this.buildLocationRow(estimates.start.name, false)); - table.push(this.buildLocationRow(estimates.end.name, true)); - return table.toString(); - } - - getTableHeaders() { - return List.of( - this.symbolService.getVehicleSymbol(), - this.symbolService.getPriceSymbol(), - this.symbolService.getTripDistanceSymbol(), - this.symbolService.getDurationSymbol(), - `${this.symbolService.getSurgeSymbol()} Surge${this.symbolService.getSurgeSymbol()}`, - ); - } - - buildInitialTable() { - const table = new Table(); - const formattedHeaders = this.getTableHeaders().map(header => ({ content: header, hAlign: 'center' })); - table.push(formattedHeaders); - return table; - } - - buildLocationRow(name, isEnd) { - return [ - { - colSpan: 1, - content: this.getEndSymbol(isEnd), - hAlign: 'center', - }, - { - colSpan: 4, - content: name, - }, - ]; - } - - getEndSymbol(isEnd) { - return isEnd ? - this.symbolService.getDestinationSymbol() : - this.symbolService.getOriginSymbol(); - } -} diff --git a/src/services/tables/builders/buildPickupTimeEstimatesTable.js b/src/services/tables/builders/buildPickupTimeEstimatesTable.js new file mode 100644 index 0000000..9ade04b --- /dev/null +++ b/src/services/tables/builders/buildPickupTimeEstimatesTable.js @@ -0,0 +1,29 @@ +import Table from 'cli-table2'; + +import symbols from '../../symbols'; +import buildPickupTimeEstimatesTableRows from '../buildPickupTimeEstimatesTableRows'; + +const headers = [ symbols.DURATION, symbols.VEHICLE ] + .map(symbol => ({ + content: symbol, + hAlign: 'center', + })); + +const buildPickupTimeEstimatesTable = ({ estimates, location }) => { + const table = new Table(); + + table.push([ + { + colSpan: 2, + content: `${symbols.ORIGIN} ${location.name}`, + hAlign: 'center', + }, + ]); + table.push(headers); + + buildPickupTimeEstimatesTableRows(estimates).forEach(row => table.push(row)); + + return table.toString(); +}; + +export default buildPickupTimeEstimatesTable; diff --git a/src/services/tables/builders/buildTripPriceEstimatesTable.js b/src/services/tables/builders/buildTripPriceEstimatesTable.js new file mode 100644 index 0000000..12ce5cc --- /dev/null +++ b/src/services/tables/builders/buildTripPriceEstimatesTable.js @@ -0,0 +1,59 @@ +import Table from 'cli-table2'; + +import formatTripPriceEstimateRow from '../formatTripPriceEstimateRow'; +import symbols from '../../symbols'; + +const headers = [ + symbols.VEHICLE, + symbols.PRICE, + symbols.TRIP_DISTANCE, + symbols.DURATION, + `${symbols.SURGE_EXISTS} Surge${symbols.SURGE_EXISTS}`, +].map(symbol => ({ content: symbol, hAlign: 'center' })); + +const buildTripPriceEstimatesTable = ({ estimates, presentationUnits }) => { + estimates.estimates.sort((firstEstimate, secondEstimate) => (firstEstimate.range.low - secondEstimate.range.low)); + + const { + estimates: priceEstimates, + start, + end, + } = estimates; + + const table = new Table(); + table.push(headers); + + priceEstimates.forEach((estimate) => { + if (estimate.productName.toUpperCase() !== 'TAXI') { + table.push(formatTripPriceEstimateRow({ estimate, presentationUnits })); + } + }); + + table.push([ + { + colSpan: 1, + content: symbols.ORIGIN, + hAlign: 'center', + }, + { + colSpan: 4, + content: start.name, + }, + ]); + + table.push([ + { + colSpan: 1, + content: symbols.DESTINATION, + hAlign: 'center', + }, + { + colSpan: 4, + content: end.name, + }, + ]); + + return table.toString(); +}; + +export default buildTripPriceEstimatesTable; diff --git a/src/services/tables/formatTripPriceEstimateRow.js b/src/services/tables/formatTripPriceEstimateRow.js new file mode 100644 index 0000000..07c93eb --- /dev/null +++ b/src/services/tables/formatTripPriceEstimateRow.js @@ -0,0 +1,50 @@ +import DistanceUnit from '../../data/DistanceUnit'; +import { + convertDistance, + DISTANCE_UNIT_ABBREVIATIONS, +} from '../converters'; +import formatDuration from '../formatDuration'; +import symbols from '../symbols'; + +const formatSurgeMultiplier = (surgeMultiplier) => ( + surgeMultiplier > 1 ? + `${surgeMultiplier}x ${symbols.SURGE_EXISTS}` : + symbols.NOT_APPLICABLE +); + +const formatDistance = ({ distance, presentationUnits }) => { + // 2 decimal places + const convertedDistance = convertDistance({ distance, toUnit: presentationUnits }); + const roundedDistanceValue = Math.round(convertedDistance.value * 100) / 100; + return `${roundedDistanceValue} ${DISTANCE_UNIT_ABBREVIATIONS[convertedDistance.unit]}.`; +} + +const formatPrice = ({ price, currencyCode }) => ( + Intl.NumberFormat('en-US', { + style: 'currency', + maximumFractionDigits: 0, + minimumFractionDigits: 0, + currency: currencyCode, + }).format(price) +) + +const formatPriceRange = ({ low, high, currencyCode }) => `${formatPrice({ price: low, currencyCode })}-${formatPrice({ price: high, currencyCode })}`; + +const formatTripPriceEstimateRow = ({ estimate, presentationUnits }) => { + const { + productName, + range, + distance, + duration, + surgeMultiplier + } = estimate; + return [ + productName, + formatPriceRange(range), + formatDistance({ distance, presentationUnits }), + formatDuration(duration), + formatSurgeMultiplier(surgeMultiplier), + ]; +} + +export default formatTripPriceEstimateRow; From 2db12ef8ca9dc66c57df7114b0f2217df088e576 Mon Sep 17 00:00:00 2001 From: Jae Bradley Date: Sat, 9 Jun 2018 16:13:47 -0400 Subject: [PATCH 18/38] refactor(table-builders): simplify table building logic --- src/index.js | 8 +-- src/services/formatters.js | 36 +++++++++++++ src/services/tables/price/build.js | 82 ++++++++++++++++++++++++++++++ src/services/tables/time/build.js | 53 +++++++++++++++++++ 4 files changed, 175 insertions(+), 4 deletions(-) create mode 100644 src/services/formatters.js create mode 100644 src/services/tables/price/build.js create mode 100644 src/services/tables/time/build.js diff --git a/src/index.js b/src/index.js index 58cadb3..eb5992e 100644 --- a/src/index.js +++ b/src/index.js @@ -4,8 +4,8 @@ import { convertDistance, convertDuration, } from './services/converters'; -import buildTripPriceEstimatesTable from './services/tables/builders/buildTripPriceEstimatesTable'; -import buildPickupTimeEstimatesTable from './services/tables/builders/buildPickupTimeEstimatesTable'; +import { default as buildPriceEstimatesTable } from './services/tables/price/build'; +import { default as buildTimeEstimatesTable } from './services/tables/time/build'; import symbols from './services/symbols'; const buildPriceEstimates = async ({ startAddress, endAddress, distanceUnitName }) => { @@ -18,7 +18,7 @@ const buildPriceEstimates = async ({ startAddress, endAddress, distanceUnitName const distanceUnit = distanceUnitName ? DistanceUnit[distanceUnitName.toUpperCase()] : DistanceUnit.MILE; const uberService = new UberService(); const estimates = await uberService.getPriceEstimates({ startAddress, endAddress }); - console.log(buildTripPriceEstimatesTable({ estimates, presentationUnits: distanceUnit })); + console.log(buildPriceEstimatesTable({ estimates, presentationUnits: distanceUnit })); } const buildTimeEstimates = async (address) => { @@ -28,7 +28,7 @@ const buildTimeEstimates = async (address) => { const uberService = new UberService(); const estimates = await uberService.getTimeEstimates(address); - console.log(buildPickupTimeEstimatesTable({ estimates: estimates.estimates, location: estimates.location })); + console.log(buildTimeEstimatesTable({ estimates: estimates.estimates, location: estimates.location })); } export { diff --git a/src/services/formatters.js b/src/services/formatters.js new file mode 100644 index 0000000..b6be141 --- /dev/null +++ b/src/services/formatters.js @@ -0,0 +1,36 @@ +import DistanceUnit from '../data/DistanceUnit'; +import { + DISTANCE_UNIT_ABBREVIATIONS, +} from './converters'; +import symbols from './symbols'; +import { convertDistance } from './converters'; + +const formatSurgeMultiplier = (surgeMultiplier) => ( + surgeMultiplier > 1 ? + `${surgeMultiplier}x ${symbols.SURGE_EXISTS}` : + symbols.NOT_APPLICABLE +); + +const formatDistance = ({ distance, presentationUnits }) => { + // 2 decimal places + const convertedDistance = convertDistance({ distance, toUnit: presentationUnits }); + const roundedDistanceValue = Math.round(convertedDistance.value * 100) / 100; + return `${roundedDistanceValue} ${DISTANCE_UNIT_ABBREVIATIONS[convertedDistance.unit]}.`; +} + +const formatPrice = ({ price, currencyCode }) => ( + Intl.NumberFormat('en-US', { + style: 'currency', + maximumFractionDigits: 0, + minimumFractionDigits: 0, + currency: currencyCode, + }).format(price) +) + +const formatPriceRange = ({ low, high, currencyCode }) => `${formatPrice({ price: low, currencyCode })}-${formatPrice({ price: high, currencyCode })}`; + +export { + formatSurgeMultiplier, + formatDistance, + formatPriceRange, +}; diff --git a/src/services/tables/price/build.js b/src/services/tables/price/build.js new file mode 100644 index 0000000..d054998 --- /dev/null +++ b/src/services/tables/price/build.js @@ -0,0 +1,82 @@ +import Table from 'cli-table2'; + +import symbols from '../../symbols'; +import { + formatSurgeMultiplier, + formatDistance, + formatPriceRange, +} from '../../formatters'; +import formatDuration from '../../formatDuration'; + +const headers = [ + symbols.VEHICLE, + symbols.PRICE, + symbols.TRIP_DISTANCE, + symbols.DURATION, + `${symbols.SURGE_EXISTS} Surge${symbols.SURGE_EXISTS}`, +].map(symbol => ({ content: symbol, hAlign: 'center' })); + +const buildRow = ({ estimate, presentationUnits }) => { + const { + productName, + range, + distance, + duration, + surgeMultiplier, + } = estimate; + + return [ + productName, + formatPriceRange(range), + formatDistance({ distance, presentationUnits }), + formatDuration(duration), + formatSurgeMultiplier(surgeMultiplier), + ]; +}; + +const build = ({ estimates, presentationUnits }) => { + estimates.estimates.sort((firstEstimate, secondEstimate) => (firstEstimate.range.low - secondEstimate.range.low)); + + const { + estimates: priceEstimates, + start, + end, + } = estimates; + + const table = new Table(); + table.push(headers); + + priceEstimates.forEach((estimate) => { + if (estimate.productName.toUpperCase() !== 'TAXI') { + table.push(buildRow({ estimate, presentationUnits })); + } + }); + + table.push([ + { + colSpan: 1, + content: symbols.ORIGIN, + hAlign: 'center', + }, + { + colSpan: 4, + content: start.name, + }, + ]); + + table.push([ + { + colSpan: 1, + content: symbols.DESTINATION, + hAlign: 'center', + }, + { + colSpan: 4, + content: end.name, + }, + ]); + + return table.toString(); +}; + +export default build; diff --git a/src/services/tables/time/build.js b/src/services/tables/time/build.js new file mode 100644 index 0000000..aa8fa2b --- /dev/null +++ b/src/services/tables/time/build.js @@ -0,0 +1,53 @@ +import Table from 'cli-table2'; + +import formatDuration from '../../formatDuration'; +import symbols from '../../symbols'; + +const headers = [ symbols.DURATION, symbols.VEHICLE ] + .map(symbol => ({ + content: symbol, + hAlign: 'center', + })); + +const buildRows = estimates => { + estimates.sort((firstEstimate, secondEstimate) => (firstEstimate.estimatedDuration.length - secondEstimate.estimatedDuration.length)); + const groupedEstimates = groupEstimatesByTime(estimates); + return Object.keys(groupedEstimates).map(key => [ key, groupedEstimates[key].join(', ') ]); +}; + +const groupEstimatesByTime = estimates => { + const rows = {}; + + estimates.forEach(({ estimatedDuration, productName }) => { + const formattedDuration = formatDuration(estimatedDuration); + let productsWithSameDuration = rows[formattedDuration]; + + if (!productsWithSameDuration) { + productsWithSameDuration = []; + } + + productsWithSameDuration.push(productName); + rows[formattedDuration] = productsWithSameDuration; + }); + + return rows; +}; + +const build = ({ estimates, location }) => { + const table = new Table(); + + table.push([ + { + colSpan: 2, + content: `${symbols.ORIGIN} ${location.name}`, + hAlign: 'center', + }, + ]); + table.push(headers); + + buildRows(estimates).forEach(row => table.push(row)); + + return table.toString(); +}; + +export default build; From 7e409f0186033279d8d9205e12d6767b1dff460c Mon Sep 17 00:00:00 2001 From: Jae Bradley Date: Sat, 9 Jun 2018 16:17:41 -0400 Subject: [PATCH 19/38] refactor(format-duration): move duration formatting to formatters --- src/services/formatters.js | 47 +++++++++++++++++++++++++++++- src/services/tables/price/build.js | 2 +- src/services/tables/time/build.js | 2 +- 3 files changed, 48 insertions(+), 3 deletions(-) diff --git a/src/services/formatters.js b/src/services/formatters.js index b6be141..e4cf9cf 100644 --- a/src/services/formatters.js +++ b/src/services/formatters.js @@ -1,9 +1,11 @@ import DistanceUnit from '../data/DistanceUnit'; +import TimeUnit from '../data/TimeUnit'; import { DISTANCE_UNIT_ABBREVIATIONS, + convertDuration, + convertDistance, } from './converters'; import symbols from './symbols'; -import { convertDistance } from './converters'; const formatSurgeMultiplier = (surgeMultiplier) => ( surgeMultiplier > 1 ? @@ -29,8 +31,51 @@ const formatPrice = ({ price, currencyCode }) => ( const formatPriceRange = ({ low, high, currencyCode }) => `${formatPrice({ price: low, currencyCode })}-${formatPrice({ price: high, currencyCode })}`; +const formatDuration = duration => { + const convertedDuration = convertDuration({ duration, toUnit: TimeUnit.SECOND }); + let seconds = convertedDuration.length; + + if (seconds < 0) { + throw new RangeError('Cannot generate formatted time for negative seconds'); + } + + if (seconds === 0) { + return '0 sec.'; + } + + const days = Math.floor(seconds / 86400); + seconds %= 86400; + + const hours = Math.floor(seconds / 3600); + seconds %= 3600; + + const minutes = Math.floor(seconds / 60); + seconds %= 60; + + let formattedTime = ''; + if (days !== 0) { + formattedTime += ` ${days} days`; + } + + if (hours !== 0) { + formattedTime += ` ${hours} hrs.`; + } + + if (minutes !== 0) { + formattedTime += ` ${minutes} min.`; + } + + if (seconds !== 0) { + formattedTime += ` ${seconds} sec.`; + } + + // GAWD THIS IS SO FUCKING HACKY I HATE EVERYTHING + return formattedTime.trim(); +}; + export { formatSurgeMultiplier, formatDistance, formatPriceRange, + formatDuration, }; diff --git a/src/services/tables/price/build.js b/src/services/tables/price/build.js index d054998..6d66d37 100644 --- a/src/services/tables/price/build.js +++ b/src/services/tables/price/build.js @@ -5,8 +5,8 @@ import { formatSurgeMultiplier, formatDistance, formatPriceRange, + formatDuration, } from '../../formatters'; -import formatDuration from '../../formatDuration'; const headers = [ symbols.VEHICLE, diff --git a/src/services/tables/time/build.js b/src/services/tables/time/build.js index aa8fa2b..30d31b7 100644 --- a/src/services/tables/time/build.js +++ b/src/services/tables/time/build.js @@ -1,6 +1,6 @@ import Table from 'cli-table2'; -import formatDuration from '../../formatDuration'; +import { formatDuration } from '../../formatters'; import symbols from '../../symbols'; const headers = [ symbols.DURATION, symbols.VEHICLE ] From f2e3effb484fe5fb91aaf6d7b017f871110b7360 Mon Sep 17 00:00:00 2001 From: Jae Bradley Date: Sat, 9 Jun 2018 16:19:46 -0400 Subject: [PATCH 20/38] refactor(table-builders): remove old table builders --- src/services/formatDuration.js | 46 --------------- .../buildPickupTimeEstimatesTableRows.js | 27 --------- .../builders/buildPickupTimeEstimatesTable.js | 29 --------- .../builders/buildTripPriceEstimatesTable.js | 59 ------------------- .../tables/formatTripPriceEstimateRow.js | 50 ---------------- 5 files changed, 211 deletions(-) delete mode 100644 src/services/formatDuration.js delete mode 100644 src/services/tables/buildPickupTimeEstimatesTableRows.js delete mode 100644 src/services/tables/builders/buildPickupTimeEstimatesTable.js delete mode 100644 src/services/tables/builders/buildTripPriceEstimatesTable.js delete mode 100644 src/services/tables/formatTripPriceEstimateRow.js diff --git a/src/services/formatDuration.js b/src/services/formatDuration.js deleted file mode 100644 index 3e7a76e..0000000 --- a/src/services/formatDuration.js +++ /dev/null @@ -1,46 +0,0 @@ -import TimeUnit from '../data/TimeUnit'; -import { convertDuration } from './converters'; - -const formatDuration = duration => { - const convertedDuration = convertDuration({ duration, toUnit: TimeUnit.SECOND }); - let seconds = convertedDuration.length; - - if (seconds < 0) { - throw new RangeError('Cannot generate formatted time for negative seconds'); - } - - if (seconds === 0) { - return '0 sec.'; - } - - const days = Math.floor(seconds / 86400); - seconds %= 86400; - - const hours = Math.floor(seconds / 3600); - seconds %= 3600; - - const minutes = Math.floor(seconds / 60); - seconds %= 60; - - let formattedTime = ''; - if (days !== 0) { - formattedTime += ` ${days} days`; - } - - if (hours !== 0) { - formattedTime += ` ${hours} hrs.`; - } - - if (minutes !== 0) { - formattedTime += ` ${minutes} min.`; - } - - if (seconds !== 0) { - formattedTime += ` ${seconds} sec.`; - } - - // GAWD THIS IS SO FUCKING HACKY I HATE EVERYTHING - return formattedTime.trim(); -}; - -export default formatDuration; diff --git a/src/services/tables/buildPickupTimeEstimatesTableRows.js b/src/services/tables/buildPickupTimeEstimatesTableRows.js deleted file mode 100644 index 646e5c4..0000000 --- a/src/services/tables/buildPickupTimeEstimatesTableRows.js +++ /dev/null @@ -1,27 +0,0 @@ -import formatDuration from '../formatDuration'; - -const buildPickupTimeEstimatesTableRows = estimates => { - estimates.sort((firstEstimate, secondEstimate) => (firstEstimate.estimatedDuration.length - secondEstimate.estimatedDuration.length)); - const groupedEstimates = groupEstimatesByTime(estimates); - return Object.keys(groupedEstimates).map(key => [ key, groupedEstimates[key].join(', ') ]); -}; - -const groupEstimatesByTime = estimates => { - const rows = {}; - - estimates.forEach(({ estimatedDuration, productName }) => { - const formattedDuration = formatDuration(estimatedDuration); - let productsWithSameDuration = rows[formattedDuration]; - - if (!productsWithSameDuration) { - productsWithSameDuration = []; - } - - productsWithSameDuration.push(productName); - rows[formattedDuration] = productsWithSameDuration; - }); - - return rows; -}; - -export default buildPickupTimeEstimatesTableRows; diff --git a/src/services/tables/builders/buildPickupTimeEstimatesTable.js b/src/services/tables/builders/buildPickupTimeEstimatesTable.js deleted file mode 100644 index 9ade04b..0000000 --- a/src/services/tables/builders/buildPickupTimeEstimatesTable.js +++ /dev/null @@ -1,29 +0,0 @@ -import Table from 'cli-table2'; - -import symbols from '../../symbols'; -import buildPickupTimeEstimatesTableRows from '../buildPickupTimeEstimatesTableRows'; - -const headers = [ symbols.DURATION, symbols.VEHICLE ] - .map(symbol => ({ - content: symbol, - hAlign: 'center', - })); - -const buildPickupTimeEstimatesTable = ({ estimates, location }) => { - const table = new Table(); - - table.push([ - { - colSpan: 2, - content: `${symbols.ORIGIN} ${location.name}`, - hAlign: 'center', - }, - ]); - table.push(headers); - - buildPickupTimeEstimatesTableRows(estimates).forEach(row => table.push(row)); - - return table.toString(); -}; - -export default buildPickupTimeEstimatesTable; diff --git a/src/services/tables/builders/buildTripPriceEstimatesTable.js b/src/services/tables/builders/buildTripPriceEstimatesTable.js deleted file mode 100644 index 12ce5cc..0000000 --- a/src/services/tables/builders/buildTripPriceEstimatesTable.js +++ /dev/null @@ -1,59 +0,0 @@ -import Table from 'cli-table2'; - -import formatTripPriceEstimateRow from '../formatTripPriceEstimateRow'; -import symbols from '../../symbols'; - -const headers = [ - symbols.VEHICLE, - symbols.PRICE, - symbols.TRIP_DISTANCE, - symbols.DURATION, - `${symbols.SURGE_EXISTS} Surge${symbols.SURGE_EXISTS}`, -].map(symbol => ({ content: symbol, hAlign: 'center' })); - -const buildTripPriceEstimatesTable = ({ estimates, presentationUnits }) => { - estimates.estimates.sort((firstEstimate, secondEstimate) => (firstEstimate.range.low - secondEstimate.range.low)); - - const { - estimates: priceEstimates, - start, - end, - } = estimates; - - const table = new Table(); - table.push(headers); - - priceEstimates.forEach((estimate) => { - if (estimate.productName.toUpperCase() !== 'TAXI') { - table.push(formatTripPriceEstimateRow({ estimate, presentationUnits })); - } - }); - - table.push([ - { - colSpan: 1, - content: symbols.ORIGIN, - hAlign: 'center', - }, - { - colSpan: 4, - content: start.name, - }, - ]); - - table.push([ - { - colSpan: 1, - content: symbols.DESTINATION, - hAlign: 'center', - }, - { - colSpan: 4, - content: end.name, - }, - ]); - - return table.toString(); -}; - -export default buildTripPriceEstimatesTable; diff --git a/src/services/tables/formatTripPriceEstimateRow.js b/src/services/tables/formatTripPriceEstimateRow.js deleted file mode 100644 index 07c93eb..0000000 --- a/src/services/tables/formatTripPriceEstimateRow.js +++ /dev/null @@ -1,50 +0,0 @@ -import DistanceUnit from '../../data/DistanceUnit'; -import { - convertDistance, - DISTANCE_UNIT_ABBREVIATIONS, -} from '../converters'; -import formatDuration from '../formatDuration'; -import symbols from '../symbols'; - -const formatSurgeMultiplier = (surgeMultiplier) => ( - surgeMultiplier > 1 ? - `${surgeMultiplier}x ${symbols.SURGE_EXISTS}` : - symbols.NOT_APPLICABLE -); - -const formatDistance = ({ distance, presentationUnits }) => { - // 2 decimal places - const convertedDistance = convertDistance({ distance, toUnit: presentationUnits }); - const roundedDistanceValue = Math.round(convertedDistance.value * 100) / 100; - return `${roundedDistanceValue} ${DISTANCE_UNIT_ABBREVIATIONS[convertedDistance.unit]}.`; -} - -const formatPrice = ({ price, currencyCode }) => ( - Intl.NumberFormat('en-US', { - style: 'currency', - maximumFractionDigits: 0, - minimumFractionDigits: 0, - currency: currencyCode, - }).format(price) -) - -const formatPriceRange = ({ low, high, currencyCode }) => `${formatPrice({ price: low, currencyCode })}-${formatPrice({ price: high, currencyCode })}`; - -const formatTripPriceEstimateRow = ({ estimate, presentationUnits }) => { - const { - productName, - range, - distance, - duration, - surgeMultiplier - } = estimate; - return [ - productName, - formatPriceRange(range), - formatDistance({ distance, presentationUnits }), - formatDuration(duration), - formatSurgeMultiplier(surgeMultiplier), - ]; -} - -export default formatTripPriceEstimateRow; From be5dddfe17c0b16f08121f837c97d0c7d60ba669 Mon Sep 17 00:00:00 2001 From: Jae Bradley Date: Sat, 9 Jun 2018 23:18:25 -0400 Subject: [PATCH 21/38] refactor(translators): remove translators --- src/services/UberService.js | 32 ++++++++++++++++--- .../estimates/translatePickupTimeEstimate.js | 11 ------- .../estimates/translateTripPriceEstimate.js | 22 ------------- 3 files changed, 27 insertions(+), 38 deletions(-) delete mode 100644 src/services/translators/estimates/translatePickupTimeEstimate.js delete mode 100644 src/services/translators/estimates/translateTripPriceEstimate.js diff --git a/src/services/UberService.js b/src/services/UberService.js index e13db85..97f3f9a 100644 --- a/src/services/UberService.js +++ b/src/services/UberService.js @@ -1,8 +1,8 @@ import { UberClient } from 'uber-client'; import GeocodeService from './GeocodeService'; -import translateTripPriceEstimate from './translators/estimates/translateTripPriceEstimate'; -import translatePickupTimeEstimate from './translators/estimates/translatePickupTimeEstimate'; +import TimeUnit from '../data/TimeUnit'; +import DistanceUnit from '../data/DistanceUnit'; export default class UberService { constructor() { @@ -24,17 +24,39 @@ export default class UberService { const timeEstimates = await this.uberClient.getTimeEstimates({ start: location.coordinate }); return { location, - estimates: timeEstimates.times.map(estimate => translatePickupTimeEstimate(estimate)), + estimates: timeEstimates.times.map(estimate => ({ + productName: estimate['localized_display_name'], + estimatedDuration: { + length: estimate.estimate, + unit: TimeUnit.SECOND, + }, + })), }; } async getPriceEstimates({ startAddress, endAddress }) { - const [ start, end ] = await Promise.all([this.getFirstLocation(startAddress), this.getFirstLocation(endAddress)]); + const [ start, end ] = await Promise.all([ this.getFirstLocation(startAddress), this.getFirstLocation(endAddress) ]); const estimates = await this.uberClient.getPriceEstimates({ start: start.coordinate, end: end.coordinate }); return { start, end, - estimates: estimates.prices.map(estimate => translateTripPriceEstimate(estimate)), + estimates: estimates.prices.map(estimate => ({ + productName: estimate['localized_display_name'], + distance: { + value: estimate.distance, + unit: DistanceUnit.MILE, + }, + duration: { + length: estimate.duration, + unit: TimeUnit.SECOND, + }, + range: { + high: estimate['high_estimate'], + low: estimate['low_estimate'], + currencyCode: estimate['currency_code'], + }, + surgeMultiplier: estimate.surgeMultiplier ? estimate.surgeMultiplier : null, + })), }; } } diff --git a/src/services/translators/estimates/translatePickupTimeEstimate.js b/src/services/translators/estimates/translatePickupTimeEstimate.js deleted file mode 100644 index 812fdbb..0000000 --- a/src/services/translators/estimates/translatePickupTimeEstimate.js +++ /dev/null @@ -1,11 +0,0 @@ -import TimeUnit from '../../../data/TimeUnit'; - -const translatePickupTimeEstimate = estimate => ({ - productName: estimate['localized_display_name'], - estimatedDuration: { - length: estimate.estimate, - unit: TimeUnit.SECOND, - }, -}); - -export default translatePickupTimeEstimate; diff --git a/src/services/translators/estimates/translateTripPriceEstimate.js b/src/services/translators/estimates/translateTripPriceEstimate.js deleted file mode 100644 index e710189..0000000 --- a/src/services/translators/estimates/translateTripPriceEstimate.js +++ /dev/null @@ -1,22 +0,0 @@ -import DistanceUnit from '../../../data/DistanceUnit'; -import TimeUnit from '../../../data/TimeUnit'; - -const translateTripPriceEstimate = estimate => ({ - productName: estimate['localized_display_name'], - distance: { - value: estimate.distance, - unit: DistanceUnit.MILE, - }, - duration: { - length: estimate.duration, - unit: TimeUnit.SECOND, - }, - range: { - high: estimate['high_estimate'], - low: estimate['low_estimate'], - currencyCode: estimate['currency_code'], - }, - surgeMultiplier: estimate.surgeMultiplier ? estimate.surgeMultiplier : null, -}); - -export default translateTripPriceEstimate; From e9ad0ad6ab43d909a2b157efc7567ccc18a2b681 Mon Sep 17 00:00:00 2001 From: Jae Bradley Date: Mon, 11 Jun 2018 16:22:15 -0400 Subject: [PATCH 22/38] style(eslint): fix eslint errors --- .eslintignore | 1 - src/index.js | 26 ++++++++++++-------------- src/services/GeocodeService.js | 2 +- src/services/UberService.js | 21 ++++++++++++++------- src/services/converters.js | 4 ++-- src/services/formatters.js | 9 ++++----- src/services/tables/price/build.js | 5 ++++- src/services/tables/time/build.js | 19 +++++++++++-------- 8 files changed, 48 insertions(+), 39 deletions(-) diff --git a/.eslintignore b/.eslintignore index 3f630e7..630c4e4 100644 --- a/.eslintignore +++ b/.eslintignore @@ -3,5 +3,4 @@ build node_modules # Remove this to fix linting errors -src/ test/ diff --git a/src/index.js b/src/index.js index eb5992e..20ef4e6 100644 --- a/src/index.js +++ b/src/index.js @@ -1,25 +1,20 @@ import DistanceUnit from './data/DistanceUnit'; import UberService from './services/UberService'; -import { - convertDistance, - convertDuration, -} from './services/converters'; -import { default as buildPriceEstimatesTable } from './services/tables/price/build'; -import { default as buildTimeEstimatesTable } from './services/tables/time/build'; -import symbols from './services/symbols'; +import buildPriceEstimatesTable from './services/tables/price/build'; +import buildTimeEstimatesTable from './services/tables/time/build'; const buildPriceEstimates = async ({ startAddress, endAddress, distanceUnitName }) => { if (typeof startAddress !== 'string' || typeof endAddress !== 'string') { - throw new TypeError( - 'Start and End addresses (-s \'
\' -e \'
\') are required.', - ); + throw new TypeError('Start and End addresses (-s \'
\' -e \'
\') are required.'); } - const distanceUnit = distanceUnitName ? DistanceUnit[distanceUnitName.toUpperCase()] : DistanceUnit.MILE; + const distanceUnit = distanceUnitName + ? DistanceUnit[distanceUnitName.toUpperCase()] + : DistanceUnit.MILE; const uberService = new UberService(); const estimates = await uberService.getPriceEstimates({ startAddress, endAddress }); console.log(buildPriceEstimatesTable({ estimates, presentationUnits: distanceUnit })); -} +}; const buildTimeEstimates = async (address) => { if (typeof address !== 'string') { @@ -28,8 +23,11 @@ const buildTimeEstimates = async (address) => { const uberService = new UberService(); const estimates = await uberService.getTimeEstimates(address); - console.log(buildTimeEstimatesTable({ estimates: estimates.estimates, location: estimates.location })); -} + console.log(buildTimeEstimatesTable({ + estimates: estimates.estimates, + location: estimates.location, + })); +}; export { buildPriceEstimates, diff --git a/src/services/GeocodeService.js b/src/services/GeocodeService.js index f818beb..974a85a 100644 --- a/src/services/GeocodeService.js +++ b/src/services/GeocodeService.js @@ -22,7 +22,7 @@ class GeocodeService { async getLocations(address) { const { results } = await this.getData(address); return results.map(result => ({ - name: result['formatted_address'], + name: result.formatted_address, coordinate: { latitude: result.geometry.location.lat, longitude: result.geometry.location.lng, diff --git a/src/services/UberService.js b/src/services/UberService.js index 97f3f9a..8a5987c 100644 --- a/src/services/UberService.js +++ b/src/services/UberService.js @@ -25,7 +25,7 @@ export default class UberService { return { location, estimates: timeEstimates.times.map(estimate => ({ - productName: estimate['localized_display_name'], + productName: estimate.localized_display_name, estimatedDuration: { length: estimate.estimate, unit: TimeUnit.SECOND, @@ -35,13 +35,20 @@ export default class UberService { } async getPriceEstimates({ startAddress, endAddress }) { - const [ start, end ] = await Promise.all([ this.getFirstLocation(startAddress), this.getFirstLocation(endAddress) ]); - const estimates = await this.uberClient.getPriceEstimates({ start: start.coordinate, end: end.coordinate }); + const [start, end] = await Promise.all([ + this.getFirstLocation(startAddress), + this.getFirstLocation(endAddress), + ]); + const estimates = await this.uberClient.getPriceEstimates({ + start: start.coordinate, + end: end.coordinate, + }); + return { start, end, estimates: estimates.prices.map(estimate => ({ - productName: estimate['localized_display_name'], + productName: estimate.localized_display_name, distance: { value: estimate.distance, unit: DistanceUnit.MILE, @@ -51,9 +58,9 @@ export default class UberService { unit: TimeUnit.SECOND, }, range: { - high: estimate['high_estimate'], - low: estimate['low_estimate'], - currencyCode: estimate['currency_code'], + high: estimate.high_estimate, + low: estimate.low_estimate, + currencyCode: estimate.currency_code, }, surgeMultiplier: estimate.surgeMultiplier ? estimate.surgeMultiplier : null, })), diff --git a/src/services/converters.js b/src/services/converters.js index f05a876..dfbb17f 100644 --- a/src/services/converters.js +++ b/src/services/converters.js @@ -29,10 +29,10 @@ const convertDistance = ({ distance, toUnit }) => ({ .from(DISTANCE_UNIT_ABBREVIATIONS[distance.unit]) .to(DISTANCE_UNIT_ABBREVIATIONS[toUnit])) * DISTANCE_UNIT_MULTIPLIER[toUnit], unit: toUnit, -}) +}); export { convertDuration, convertDistance, DISTANCE_UNIT_ABBREVIATIONS, -} +}; diff --git a/src/services/formatters.js b/src/services/formatters.js index e4cf9cf..f9fb49c 100644 --- a/src/services/formatters.js +++ b/src/services/formatters.js @@ -1,4 +1,3 @@ -import DistanceUnit from '../data/DistanceUnit'; import TimeUnit from '../data/TimeUnit'; import { DISTANCE_UNIT_ABBREVIATIONS, @@ -7,7 +6,7 @@ import { } from './converters'; import symbols from './symbols'; -const formatSurgeMultiplier = (surgeMultiplier) => ( +const formatSurgeMultiplier = surgeMultiplier => ( surgeMultiplier > 1 ? `${surgeMultiplier}x ${symbols.SURGE_EXISTS}` : symbols.NOT_APPLICABLE @@ -18,7 +17,7 @@ const formatDistance = ({ distance, presentationUnits }) => { const convertedDistance = convertDistance({ distance, toUnit: presentationUnits }); const roundedDistanceValue = Math.round(convertedDistance.value * 100) / 100; return `${roundedDistanceValue} ${DISTANCE_UNIT_ABBREVIATIONS[convertedDistance.unit]}.`; -} +}; const formatPrice = ({ price, currencyCode }) => ( Intl.NumberFormat('en-US', { @@ -27,11 +26,11 @@ const formatPrice = ({ price, currencyCode }) => ( minimumFractionDigits: 0, currency: currencyCode, }).format(price) -) +); const formatPriceRange = ({ low, high, currencyCode }) => `${formatPrice({ price: low, currencyCode })}-${formatPrice({ price: high, currencyCode })}`; -const formatDuration = duration => { +const formatDuration = (duration) => { const convertedDuration = convertDuration({ duration, toUnit: TimeUnit.SECOND }); let seconds = convertedDuration.length; diff --git a/src/services/tables/price/build.js b/src/services/tables/price/build.js index 6d66d37..c50b785 100644 --- a/src/services/tables/price/build.js +++ b/src/services/tables/price/build.js @@ -35,7 +35,10 @@ const buildRow = ({ estimate, presentationUnits }) => { }; const build = ({ estimates, presentationUnits }) => { - estimates.estimates.sort((firstEstimate, secondEstimate) => (firstEstimate.range.low - secondEstimate.range.low)); + estimates.estimates.sort(( + firstEstimate, + secondEstimate, + ) => (firstEstimate.range.low - secondEstimate.range.low)); const { estimates: priceEstimates, diff --git a/src/services/tables/time/build.js b/src/services/tables/time/build.js index 30d31b7..34d7264 100644 --- a/src/services/tables/time/build.js +++ b/src/services/tables/time/build.js @@ -3,19 +3,13 @@ import Table from 'cli-table2'; import { formatDuration } from '../../formatters'; import symbols from '../../symbols'; -const headers = [ symbols.DURATION, symbols.VEHICLE ] +const headers = [symbols.DURATION, symbols.VEHICLE] .map(symbol => ({ content: symbol, hAlign: 'center', })); -const buildRows = estimates => { - estimates.sort((firstEstimate, secondEstimate) => (firstEstimate.estimatedDuration.length - secondEstimate.estimatedDuration.length)); - const groupedEstimates = groupEstimatesByTime(estimates); - return Object.keys(groupedEstimates).map(key => [ key, groupedEstimates[key].join(', ') ]); -}; - -const groupEstimatesByTime = estimates => { +const groupEstimatesByTime = (estimates) => { const rows = {}; estimates.forEach(({ estimatedDuration, productName }) => { @@ -33,6 +27,15 @@ const groupEstimatesByTime = estimates => { return rows; }; +const buildRows = (estimates) => { + estimates.sort(( + firstEstimate, + secondEstimate, + ) => (firstEstimate.estimatedDuration.length - secondEstimate.estimatedDuration.length)); + const groupedEstimates = groupEstimatesByTime(estimates); + return Object.keys(groupedEstimates).map(key => [key, groupedEstimates[key].join(', ')]); +}; + const build = ({ estimates, location }) => { const table = new Table(); From c0ef592a90377fb917111a1aeed6b265faa8bf07 Mon Sep 17 00:00:00 2001 From: Jae Bradley Date: Mon, 11 Jun 2018 17:43:52 -0400 Subject: [PATCH 23/38] test(symbols): add symbols tests --- src/services/symbols.emojis.test.js | 32 +++++++++++++ src/services/symbols.text.test.js | 32 +++++++++++++ .../symbols/BaseSymbolService.test.js | 45 ------------------- 3 files changed, 64 insertions(+), 45 deletions(-) create mode 100644 src/services/symbols.emojis.test.js create mode 100644 src/services/symbols.text.test.js delete mode 100644 test/services/symbols/BaseSymbolService.test.js diff --git a/src/services/symbols.emojis.test.js b/src/services/symbols.emojis.test.js new file mode 100644 index 0000000..ba665a2 --- /dev/null +++ b/src/services/symbols.emojis.test.js @@ -0,0 +1,32 @@ +describe('symbols', () => { + const realProcess = global.process; + const mockedProcess = { platform: 'darwin' }; + let symbols; + + beforeEach(() => { + global.process = mockedProcess; + // eslint-disable-next-line + symbols = require('./symbols'); + }); + + afterEach(() => { + global.process = realProcess; + }); + + describe('text', () => { + it('gets text', () => { + expect(symbols.default).toEqual({ + VEHICLE: '🚘', + PRICE: '💸', + TRIP_DISTANCE: '🔃', + DURATION: '⏳', + SURGE_MULTIPLIER: '💥', + NOT_APPLICABLE: '🚫', + SURGE_EXISTS: '😬', + DESTINATION: '🔚', + ORIGIN: '📍', + MAXIMUM_DISTANCE: '💯', + }); + }); + }); +}); diff --git a/src/services/symbols.text.test.js b/src/services/symbols.text.test.js new file mode 100644 index 0000000..98ec641 --- /dev/null +++ b/src/services/symbols.text.test.js @@ -0,0 +1,32 @@ +describe('symbols', () => { + const realProcess = global.process; + const mockedProcess = { platform: 'foobar' }; + let symbols; + + beforeEach(() => { + global.process = mockedProcess; + // eslint-disable-next-line + symbols = require('./symbols'); + }); + + afterEach(() => { + global.process = realProcess; + }); + + describe('text', () => { + it('gets text', () => { + expect(symbols.default).toEqual({ + VEHICLE: 'Vehicle', + PRICE: 'Price', + TRIP_DISTANCE: 'Distance', + DURATION: 'Duration', + SURGE_MULTIPLIER: ' *', + NOT_APPLICABLE: 'N/A', + SURGE_EXISTS: ':-(', + DESTINATION: 'Destination', + ORIGIN: 'Origin', + MAXIMUM_DISTANCE: '100', + }); + }); + }); +}); diff --git a/test/services/symbols/BaseSymbolService.test.js b/test/services/symbols/BaseSymbolService.test.js deleted file mode 100644 index 48a7cd5..0000000 --- a/test/services/symbols/BaseSymbolService.test.js +++ /dev/null @@ -1,45 +0,0 @@ -import BaseSymbolService from '../../../src/services/symbols/BaseSymbolService'; - -describe('BaseSymbolService Test', () => { - const service = new BaseSymbolService(); - - it('should throw when getting vehicle symbol', () => { - expect(() => service.getVehicleSymbol()).toThrow(); - }); - - it('should throw when getting price symbol', () => { - expect(() => service.getPriceSymbol()).toThrow(); - }); - - it('should throw when getting trip distance symbol', () => { - expect(() => service.getTripDistanceSymbol()).toThrow(); - }); - - it('should throw when getting duration symbol', () => { - expect(() => service.getDurationSymbol()).toThrow(); - }); - - it('should throw when getting surge symbol', () => { - expect(() => service.getSurgeSymbol()).toThrow(); - }); - - it('should throw when getting not applicable symbol', () => { - expect(() => service.getNotApplicableSymbol()).toThrow(); - }); - - it('should throw when getting surge present symbol', () => { - expect(() => service.getSurgePresentSymbol()).toThrow(); - }); - - it('should throw when getting destination symbol', () => { - expect(() => service.getDestinationSymbol()).toThrow(); - }); - - it('should throw when getting origin symbol', () => { - expect(() => service.getOriginSymbol()).toThrow(); - }); - - it('should throw when getting maximum distance symbol', () => { - expect(() => service.getMaximumDistanceSymbol()).toThrow(); - }); -}); From b7807c09ed3f9a4874796e3ccedf7621a3289f60 Mon Sep 17 00:00:00 2001 From: Jae Bradley Date: Mon, 11 Jun 2018 19:52:09 -0400 Subject: [PATCH 24/38] refactor(format-seconds): rename formatDuration to formatSeconds --- src/services/formatters.js | 41 ++++------ src/services/formatters.test.js | 41 ++++++++++ src/services/tables/price/build.js | 15 +++- src/services/tables/time/build.js | 11 ++- test/services/DurationFormatterTest.js | 107 ------------------------- 5 files changed, 79 insertions(+), 136 deletions(-) create mode 100644 src/services/formatters.test.js delete mode 100644 test/services/DurationFormatterTest.js diff --git a/src/services/formatters.js b/src/services/formatters.js index f9fb49c..4fa9791 100644 --- a/src/services/formatters.js +++ b/src/services/formatters.js @@ -1,9 +1,4 @@ -import TimeUnit from '../data/TimeUnit'; -import { - DISTANCE_UNIT_ABBREVIATIONS, - convertDuration, - convertDistance, -} from './converters'; +import { DISTANCE_UNIT_ABBREVIATIONS } from './converters'; import symbols from './symbols'; const formatSurgeMultiplier = surgeMultiplier => ( @@ -12,11 +7,10 @@ const formatSurgeMultiplier = surgeMultiplier => ( symbols.NOT_APPLICABLE ); -const formatDistance = ({ distance, presentationUnits }) => { +const formatDistance = ({ value, unit }) => { // 2 decimal places - const convertedDistance = convertDistance({ distance, toUnit: presentationUnits }); - const roundedDistanceValue = Math.round(convertedDistance.value * 100) / 100; - return `${roundedDistanceValue} ${DISTANCE_UNIT_ABBREVIATIONS[convertedDistance.unit]}.`; + const roundedDistanceValue = Math.round(value * 100) / 100; + return `${roundedDistanceValue} ${DISTANCE_UNIT_ABBREVIATIONS[unit]}.`; }; const formatPrice = ({ price, currencyCode }) => ( @@ -30,26 +24,25 @@ const formatPrice = ({ price, currencyCode }) => ( const formatPriceRange = ({ low, high, currencyCode }) => `${formatPrice({ price: low, currencyCode })}-${formatPrice({ price: high, currencyCode })}`; -const formatDuration = (duration) => { - const convertedDuration = convertDuration({ duration, toUnit: TimeUnit.SECOND }); - let seconds = convertedDuration.length; +const formatSeconds = (seconds) => { + let value = seconds; - if (seconds < 0) { + if (value < 0) { throw new RangeError('Cannot generate formatted time for negative seconds'); } - if (seconds === 0) { + if (value === 0) { return '0 sec.'; } - const days = Math.floor(seconds / 86400); - seconds %= 86400; + const days = Math.floor(value / 86400); + value %= 86400; - const hours = Math.floor(seconds / 3600); - seconds %= 3600; + const hours = Math.floor(value / 3600); + value %= 3600; - const minutes = Math.floor(seconds / 60); - seconds %= 60; + const minutes = Math.floor(value / 60); + value %= 60; let formattedTime = ''; if (days !== 0) { @@ -64,8 +57,8 @@ const formatDuration = (duration) => { formattedTime += ` ${minutes} min.`; } - if (seconds !== 0) { - formattedTime += ` ${seconds} sec.`; + if (value !== 0) { + formattedTime += ` ${value} sec.`; } // GAWD THIS IS SO FUCKING HACKY I HATE EVERYTHING @@ -76,5 +69,5 @@ export { formatSurgeMultiplier, formatDistance, formatPriceRange, - formatDuration, + formatSeconds, }; diff --git a/src/services/formatters.test.js b/src/services/formatters.test.js new file mode 100644 index 0000000..fd140ed --- /dev/null +++ b/src/services/formatters.test.js @@ -0,0 +1,41 @@ +import { formatSeconds } from './formatters'; + +describe('formatters', () => { + describe('#formatSeconds', () => { + it('throws RangeError when negative duration', () => { + expect(() => formatSeconds(-1)).toThrow(RangeError); + }); + + it('returns 0 sec.', () => { + expect(formatSeconds(0)).toEqual('0 sec.'); + }); + + it('returns 59 sec.', () => { + expect(formatSeconds(59)).toEqual('59 sec.'); + }); + + it('returns 1 min.', () => { + expect(formatSeconds(60)).toEqual('1 min.'); + }); + + it('returns 1 min. 1 sec.', () => { + expect(formatSeconds(61)).toEqual('1 min. 1 sec.'); + }); + + it('returns 59 min. 59 sec.', () => { + expect(formatSeconds(3599)).toEqual('59 min. 59 sec.'); + }); + + it('returns an hour', () => { + expect(formatSeconds(3600)).toEqual('1 hrs.'); + }); + + it('returns 23 hrs. 59 min. 59 sec.', () => { + expect(formatSeconds(86399)).toEqual('23 hrs. 59 min. 59 sec.'); + }); + + it('returns 1 days', () => { + expect(formatSeconds(86400)).toEqual('1 days'); + }); + }); +}); diff --git a/src/services/tables/price/build.js b/src/services/tables/price/build.js index c50b785..27d9533 100644 --- a/src/services/tables/price/build.js +++ b/src/services/tables/price/build.js @@ -1,13 +1,19 @@ import Table from 'cli-table2'; +import TimeUnit from '../../../data/TimeUnit'; import symbols from '../../symbols'; import { formatSurgeMultiplier, formatDistance, formatPriceRange, - formatDuration, + formatSeconds, } from '../../formatters'; +import { + convertDuration, + convertDistance, +} from '../../converters'; + const headers = [ symbols.VEHICLE, symbols.PRICE, @@ -25,11 +31,14 @@ const buildRow = ({ estimate, presentationUnits }) => { surgeMultiplier, } = estimate; + const { length: seconds } = convertDuration({ duration, toUnit: TimeUnit.SECOND }); + const convertedDistance = convertDistance({ distance, toUnit: presentationUnits }); + return [ productName, formatPriceRange(range), - formatDistance({ distance, presentationUnits }), - formatDuration(duration), + formatDistance(convertedDistance), + formatSeconds(seconds), formatSurgeMultiplier(surgeMultiplier), ]; }; diff --git a/src/services/tables/time/build.js b/src/services/tables/time/build.js index 34d7264..ee437f5 100644 --- a/src/services/tables/time/build.js +++ b/src/services/tables/time/build.js @@ -1,6 +1,8 @@ import Table from 'cli-table2'; -import { formatDuration } from '../../formatters'; +import TimeUnit from '../../../data/TimeUnit'; +import { formatSeconds } from '../../formatters'; +import { convertDuration } from '../../converters'; import symbols from '../../symbols'; const headers = [symbols.DURATION, symbols.VEHICLE] @@ -13,7 +15,12 @@ const groupEstimatesByTime = (estimates) => { const rows = {}; estimates.forEach(({ estimatedDuration, productName }) => { - const formattedDuration = formatDuration(estimatedDuration); + const durationInSeconds = convertDuration({ + duration: estimatedDuration, + toUnit: TimeUnit.SECOND, + }); + const seconds = durationInSeconds.length; + const formattedDuration = formatSeconds(seconds); let productsWithSameDuration = rows[formattedDuration]; if (!productsWithSameDuration) { diff --git a/test/services/DurationFormatterTest.js b/test/services/DurationFormatterTest.js deleted file mode 100644 index ba3df12..0000000 --- a/test/services/DurationFormatterTest.js +++ /dev/null @@ -1,107 +0,0 @@ -import TimeUnit from '../../src/data/TimeUnit'; - -import DurationConverter from '../../src/services/DurationConverter'; -import DurationFormatter from '../../src/services/DurationFormatter'; - -describe('Duration Formatter', () => { - const converter = new DurationConverter(); - const formatter = new DurationFormatter(converter); - - describe('throws exception', () => { - const negativeDuration = { - length: -1, - unit: TimeUnit.SECOND, - }; - - it('throws exception', () => { - const durationConversion = sinon.stub(converter, 'convert').returns(negativeDuration); - expect(() => formatter.format({})).to.throw(RangeError); - durationConversion.restore(); - }); - }); - - describe('0 seconds', () => { - const zeroSeconds = { - length: 0, - unit: TimeUnit.SECOND, - }; - - it('returns 0 sec.', () => { - const durationConversion = sinon.stub(converter, 'convert').returns(zeroSeconds); - expect(formatter.format({})).to.eql('0 sec.'); - durationConversion.restore(); - }); - }); - - describe('formats', () => { - const underAMinute = { - length: 59, - unit: TimeUnit.SECOND, - }; - it('under a minute', () => { - const durationConversion = sinon.stub(converter, 'convert').returns(underAMinute); - expect(formatter.format()).to.eql('59 sec.'); - durationConversion.restore(); - }); - - const aMinute = { - length: 60, - unit: TimeUnit.SECOND, - }; - it('a minute', () => { - const durationConversion = sinon.stub(converter, 'convert').returns(aMinute); - expect(formatter.format()).to.eql('1 min.'); - durationConversion.restore(); - }); - - const overAMinute = { - length: 61, - unit: TimeUnit.SECOND, - }; - it('over a minute', () => { - const durationConversion = sinon.stub(converter, 'convert').returns(overAMinute); - expect(formatter.format()).to.eql('1 min. 1 sec.'); - durationConversion.restore(); - }); - - const underAnHour = { - length: 3599, - unit: TimeUnit.SECOND, - }; - it('under an hour', () => { - const durationConversion = sinon.stub(converter, 'convert').returns(underAnHour); - expect(formatter.format()).to.eql('59 min. 59 sec.'); - durationConversion.restore(); - }); - - const anHour = { - length: 3600, - unit: TimeUnit.SECOND, - }; - it('an hour', () => { - const durationConversion = sinon.stub(converter, 'convert').returns(anHour); - expect(formatter.format()).to.eql('1 hrs.'); - durationConversion.restore(); - }); - - const underADay = { - length: 86399, - unit: TimeUnit.SECOND, - }; - it('under a day', () => { - const durationConversion = sinon.stub(converter, 'convert').returns(underADay); - expect(formatter.format()).to.eql('23 hrs. 59 min. 59 sec.'); - durationConversion.restore(); - }); - - const aDay = { - length: 86400, - unit: TimeUnit.SECOND, - }; - it('a day', () => { - const durationConversion = sinon.stub(converter, 'convert').returns(aDay); - expect(formatter.format()).to.eql('1 days'); - durationConversion.restore(); - }); - }); -}); From ed8260ad24a355769137e0da7e994bb2e94431e7 Mon Sep 17 00:00:00 2001 From: Jae Bradley Date: Mon, 11 Jun 2018 20:14:25 -0400 Subject: [PATCH 25/38] test(formatters): add tests for formatters --- package.json | 4 +++ src/services/formatters.test.js | 43 ++++++++++++++++++++++++++++++++- 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 477d53f..f793333 100644 --- a/package.json +++ b/package.json @@ -44,6 +44,10 @@ ], "jest": { "testEnvironment": "node", + "testPathIgnorePatterns": [ + "/build/", + "/node_modules/" + ], "collectCoverage": true }, "license": "MIT", diff --git a/src/services/formatters.test.js b/src/services/formatters.test.js index fd140ed..b72a58a 100644 --- a/src/services/formatters.test.js +++ b/src/services/formatters.test.js @@ -1,6 +1,47 @@ -import { formatSeconds } from './formatters'; +import { formatSeconds, formatSurgeMultiplier, formatDistance, formatPriceRange } from './formatters'; +import DistanceUnit from '../data/DistanceUnit'; +import symbols from './symbols'; + +jest.mock('./symbols', () => ({ + SURGE_EXISTS: 'surge exists', + NOT_APPLICABLE: 'not applicable', +})); describe('formatters', () => { + describe('#formatSurgeMultiplier', () => { + it('returns formatted surge multiplier when multiplier is 2', () => { + expect(formatSurgeMultiplier(2)).toEqual(`2x ${symbols.SURGE_EXISTS}`); + }); + + it('does not format surge multiplier when multiplier is 1', () => { + expect(formatSurgeMultiplier(1)).toEqual(symbols.NOT_APPLICABLE); + }); + + it('does not format surge multiplier when multiplier is null', () => { + expect(formatSurgeMultiplier(null)).toEqual(symbols.NOT_APPLICABLE); + }); + }); + + describe('#formatDistance', () => { + it('returns 12 mi. for a value of 12', () => { + expect(formatDistance({ value: 12, unit: DistanceUnit.MILE })).toEqual('12 mi.'); + }); + + it('returns 12.35 mi. for a value of 12.345', () => { + expect(formatDistance({ value: 12.345, unit: DistanceUnit.MILE })).toEqual('12.35 mi.'); + }); + }); + + describe('#formatPriceRange', () => { + it('returns $1-$2 when low is 1, high is 2, and currencyCode is USD', () => { + expect(formatPriceRange({ low: 1, high: 2, currencyCode: 'USD' })); + }); + + it('returns $1-$2 when low is 1.23 and high is 2.34 and currencyCode is USD', () => { + expect(formatPriceRange({ low: 1.23, high: 2.34, currencyCode: 'USD' })); + }); + }); + describe('#formatSeconds', () => { it('throws RangeError when negative duration', () => { expect(() => formatSeconds(-1)).toThrow(RangeError); From c21a73d9d4e0d368f1c0d400e0ed4effbc3887e3 Mon Sep 17 00:00:00 2001 From: Jae Bradley Date: Mon, 11 Jun 2018 20:56:09 -0400 Subject: [PATCH 26/38] test(converters): add tests for distance and duration converters --- __mocks__/convert-units.js | 14 ++ src/services/converters.test.js | 44 ++++++ test/services/UtilitiesTest.js | 15 -- test/services/symbols/EmojiServiceTest.js | 51 ------- test/services/symbols/SymbolServiceTest.js | 133 ------------------ .../services/symbols/TextSymbolServiceTest.js | 50 ------- 6 files changed, 58 insertions(+), 249 deletions(-) create mode 100644 __mocks__/convert-units.js create mode 100644 src/services/converters.test.js delete mode 100644 test/services/UtilitiesTest.js delete mode 100644 test/services/symbols/EmojiServiceTest.js delete mode 100644 test/services/symbols/SymbolServiceTest.js delete mode 100644 test/services/symbols/TextSymbolServiceTest.js diff --git a/__mocks__/convert-units.js b/__mocks__/convert-units.js new file mode 100644 index 0000000..4fd658d --- /dev/null +++ b/__mocks__/convert-units.js @@ -0,0 +1,14 @@ +const to = jest.fn(() => 1234); + +const from = jest.fn(() => ({ to })); + +const constructor = jest.fn(() => ({ from })); + +const convert = constructor; + +export default convert; + +export { + to, + from, +}; diff --git a/src/services/converters.test.js b/src/services/converters.test.js new file mode 100644 index 0000000..0c82398 --- /dev/null +++ b/src/services/converters.test.js @@ -0,0 +1,44 @@ +import convert, { to, from } from 'convert-units'; +import TimeUnit from '../data/TimeUnit'; +import DistanceUnit from '../data/DistanceUnit'; + +import { + convertDuration, + convertDistance, +} from './converters'; + +describe('converters', () => { + describe('#convertDuration', () => { + it('converts from seconds to minutes', () => { + const { length, unit } = convertDuration({ + duration: { + length: 1, + unit: TimeUnit.SECOND, + }, + toUnit: TimeUnit.MINUTE, + }); + expect(convert).toHaveBeenCalledWith(1); + expect(from).toHaveBeenCalledWith('s'); + expect(to).toHaveBeenCalledWith('min'); + expect(length).toEqual(1234); + expect(unit).toEqual(TimeUnit.MINUTE); + }); + }); + + describe('#convertDistance', () => { + it('converts from miles to kilometers', () => { + const { value, unit } = convertDistance({ + distance: { + value: 1, + unit: DistanceUnit.MILE, + }, + toUnit: DistanceUnit.KILOMETER, + }); + expect(convert).toHaveBeenCalledWith(1); + expect(from).toHaveBeenCalledWith('mi'); + expect(to).toHaveBeenCalledWith('km'); + expect(value).toEqual(0.12340000000000001); + expect(unit).toEqual(DistanceUnit.KILOMETER); + }); + }); +}); diff --git a/test/services/UtilitiesTest.js b/test/services/UtilitiesTest.js deleted file mode 100644 index 6546035..0000000 --- a/test/services/UtilitiesTest.js +++ /dev/null @@ -1,15 +0,0 @@ -import chai from 'chai'; - -import Utilities from '../../src/services/Utilities'; - -const expect = chai.expect; - -describe('Tests Utilities', () => { - describe('#isFloat', () => { - it('returns false for undefined', () => expect(Utilities.isFloat(undefined)).to.be.false); - it('returns false for null', () => expect(Utilities.isFloat(undefined)).to.be.false); - it('returns false for object', () => expect(Utilities.isFloat([])).to.be.false); - it('returns false for integer', () => expect(Utilities.isFloat(1)).to.be.false); - it('returns true for float', () => expect(Utilities.isFloat(-1.2345)).to.be.true); - }); -}); diff --git a/test/services/symbols/EmojiServiceTest.js b/test/services/symbols/EmojiServiceTest.js deleted file mode 100644 index b6e951e..0000000 --- a/test/services/symbols/EmojiServiceTest.js +++ /dev/null @@ -1,51 +0,0 @@ -import chai from 'chai'; -import emoji from 'node-emoji'; - -import EmojiService from '../../../src/services/symbols/EmojiService'; - -const expect = chai.expect; - - -describe('EmojiService Test', () => { - const service = new EmojiService(); - - it('should get vehicle symbol', () => { - expect(service.getVehicleSymbol()).to.eql(emoji.get('oncoming_automobile')); - }); - - it('should get price symbol', () => { - expect(service.getPriceSymbol()).to.eql(emoji.get('money_with_wings')); - }); - - it('should get trip distance symbol', () => { - expect(service.getTripDistanceSymbol()).to.eql(emoji.get('arrows_clockwise')); - }); - - it('should get duration symbol', () => { - expect(service.getDurationSymbol()).to.eql(emoji.get('hourglass_flowing_sand')); - }); - - it('should get surge symbol', () => { - expect(service.getSurgeSymbol()).to.eql(emoji.get('boom')); - }); - - it('should get not applicable symbol', () => { - expect(service.getNotApplicableSymbol()).to.eql(emoji.get('no_entry_sign')); - }); - - it('should get surge present symbol', () => { - expect(service.getSurgePresentSymbol()).to.eql(emoji.get('grimacing')); - }); - - it('should get destination symbol', () => { - expect(service.getDestinationSymbol()).to.eql(emoji.get('end')); - }); - - it('should get origin symbol', () => { - expect(service.getOriginSymbol()).to.eql(emoji.get('round_pushpin')); - }); - - it('should get maximum distance symbol', () => { - expect(service.getMaximumDistanceSymbol()).to.eql(emoji.get('100')); - }); -}); diff --git a/test/services/symbols/SymbolServiceTest.js b/test/services/symbols/SymbolServiceTest.js deleted file mode 100644 index 633f8eb..0000000 --- a/test/services/symbols/SymbolServiceTest.js +++ /dev/null @@ -1,133 +0,0 @@ -import EmojiService from '../../../src/services/symbols/EmojiService'; -import TextSymbolService from '../../../src/services/symbols/TextSymbolService'; -import SymbolService from '../../../src/services/symbols/SymbolService'; - - -describe('SymbolService Test', () => { - let originalPlatform; - let sandbox; - - let service = new SymbolService(); - - describe('#getEmojiSupportedOperatingSystems', () => { - it('should return operated systems that support emojis', () => { - expect(SymbolService.getEmojiSupportedOperatingSystems()).to.eql(List.of('darwin')); - }); - }); - - describe('#areEmojisSupported', () => { - before(() => { - originalPlatform = Object.getOwnPropertyDescriptor(process, 'platform'); - - Object.defineProperty(process, 'platform', { - value: 'any-platform', - }); - }); - - after(() => { - Object.defineProperty(process, 'platform', originalPlatform); - }); - - it('should return if emojis are supported', () => { - expect(SymbolService.areEmojisSupported()).to.eql(false); - }); - }); - - describe('#constructor', () => { - beforeEach(() => { - sandbox = sinon.sandbox.create(); - }); - - afterEach(() => { - sandbox.restore(); - }); - - describe('when emojis are supported', () => { - it('client should be emoji service', () => { - sandbox.stub(SymbolService, 'areEmojisSupported').returns(true); - service = new SymbolService(); - return expect(service.client instanceof EmojiService).to.be.true; - }); - }); - - describe('when emojis are not supported', () => { - it('client should be text service', () => { - sandbox.stub(SymbolService, 'areEmojisSupported').returns(false); - service = new SymbolService(); - return expect(service.client instanceof TextSymbolService).to.be.true; - }); - }); - }); - - describe('#getVehicleSymbol', () => { - it('should forward to client method', () => { - const clientSpy = sinon.spy(service.client, 'getVehicleSymbol'); - service.getVehicleSymbol(); - return expect(clientSpy.calledOnce).to.be.true; - }); - }); - - describe('#getPriceSymbol', () => { - it('should forward to client method', () => { - const clientSpy = sinon.spy(service.client, 'getPriceSymbol'); - service.getPriceSymbol(); - return expect(clientSpy.calledOnce).to.be.true; - }); - }); - - describe('#getTripDistanceSymbol', () => { - it('should forward to client method', () => { - const clientSpy = sinon.spy(service.client, 'getTripDistanceSymbol'); - service.getTripDistanceSymbol(); - return expect(clientSpy.calledOnce).to.be.true; - }); - }); - - describe('#getDurationSymbol', () => { - it('should forward to client method', () => { - const clientSpy = sinon.spy(service.client, 'getDurationSymbol'); - service.getDurationSymbol(); - return expect(clientSpy.calledOnce).to.be.true; - }); - }); - - describe('#getSurgeSymbol', () => { - it('should forward to client method', () => { - const clientSpy = sinon.spy(service.client, 'getSurgeSymbol'); - service.getSurgeSymbol(); - return expect(clientSpy.calledOnce).to.be.true; - }); - }); - - describe('#getNotApplicableSymbol', () => { - it('should forward to client method', () => { - const clientSpy = sinon.spy(service.client, 'getNotApplicableSymbol'); - service.getNotApplicableSymbol(); - return expect(clientSpy.calledOnce).to.be.true; - }); - }); - - describe('#getDestinationSymbol', () => { - it('should forward to client method', () => { - const clientSpy = sinon.spy(service.client, 'getDestinationSymbol'); - service.getDestinationSymbol(); - return expect(clientSpy.calledOnce).to.be.true; - }); - }); - - describe('#getOriginSymbol', () => { - it('should forward to client method', () => { - const clientSpy = sinon.spy(service.client, 'getOriginSymbol'); - service.getOriginSymbol(); - return expect(clientSpy.calledOnce).to.be.true; - }); - }); - - describe('#getMaximumDistanceSymbol', () => { - it('should forward to client method', () => { - const clientSpy = sinon.spy(service.client, 'getMaximumDistanceSymbol'); - service.getMaximumDistanceSymbol(); - return expect(clientSpy.calledOnce).to.be.true; - }); - }); -}); diff --git a/test/services/symbols/TextSymbolServiceTest.js b/test/services/symbols/TextSymbolServiceTest.js deleted file mode 100644 index 5d0037d..0000000 --- a/test/services/symbols/TextSymbolServiceTest.js +++ /dev/null @@ -1,50 +0,0 @@ -import chai from 'chai'; - -import TextSymbolService from '../../../src/services/symbols/TextSymbolService'; - -const expect = chai.expect; - - -describe('TextSymbolService Test', () => { - const service = new TextSymbolService(); - - it('should get vehicle symbol', () => { - expect(service.getVehicleSymbol()).to.eql('Vehicle'); - }); - - it('should get price symbol', () => { - expect(service.getPriceSymbol()).to.eql('Price'); - }); - - it('should get trip distance symbol', () => { - expect(service.getTripDistanceSymbol()).to.eql('Distance'); - }); - - it('should get duration symbol', () => { - expect(service.getDurationSymbol()).to.eql('Duration'); - }); - - it('should get surge symbol', () => { - expect(service.getSurgeSymbol()).to.eql(' *'); - }); - - it('should get not applicable symbol', () => { - expect(service.getNotApplicableSymbol()).to.eql('N/A'); - }); - - it('should get surge present symbol', () => { - expect(service.getSurgePresentSymbol()).to.eql(':-('); - }); - - it('should get destination symbol', () => { - expect(service.getDestinationSymbol()).to.eql('Destination'); - }); - - it('should get origin symbol', () => { - expect(service.getOriginSymbol()).to.eql('Origin'); - }); - - it('should get maximum distance symbol', () => { - expect(service.getMaximumDistanceSymbol()).to.eql('100'); - }); -}); From edf516ff3c6c91dad228207c8e89f4d54dfc6152 Mon Sep 17 00:00:00 2001 From: Jae Bradley Date: Mon, 11 Jun 2018 21:03:20 -0400 Subject: [PATCH 27/38] refactor(test): remove unnecessary tests Remove test directory, update .npmignore, update .eslintignore, update .travis.yml --- .eslintignore | 3 - .npmignore | 19 ++- .travis.yml | 1 + test/DistanceConverterTest.js | 63 -------- test/DurationConverterTest.js | 34 ---- test/GeocodeServiceTest.js | 19 --- test/UberServiceIntegrationTest.js | 29 ---- test/files/geocode.json | 102 ------------ test/files/price-estimates.json | 81 ---------- test/files/time-estimates.json | 40 ----- test/services/CommandExecutionServiceTest.js | 56 ------- test/services/UberServiceTest.js | 59 ------- ...PickupTimeEstimatesTableRowsBuilderTest.js | 51 ------ .../TripPriceEstimateRowFormatterTest.js | 111 ------------- .../PickupTimeEstimatesTableBuilderTest.js | 115 -------------- .../TripPriceEstimatesTableBuilderTest.js | 150 ------------------ 16 files changed, 14 insertions(+), 919 deletions(-) delete mode 100644 test/DistanceConverterTest.js delete mode 100644 test/DurationConverterTest.js delete mode 100644 test/GeocodeServiceTest.js delete mode 100644 test/UberServiceIntegrationTest.js delete mode 100644 test/files/geocode.json delete mode 100644 test/files/price-estimates.json delete mode 100644 test/files/time-estimates.json delete mode 100644 test/services/CommandExecutionServiceTest.js delete mode 100644 test/services/UberServiceTest.js delete mode 100644 test/services/tables/PickupTimeEstimatesTableRowsBuilderTest.js delete mode 100644 test/services/tables/TripPriceEstimateRowFormatterTest.js delete mode 100644 test/services/tables/builders/PickupTimeEstimatesTableBuilderTest.js delete mode 100644 test/services/tables/builders/TripPriceEstimatesTableBuilderTest.js diff --git a/.eslintignore b/.eslintignore index 630c4e4..94d3f3e 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,6 +1,3 @@ coverage/* build node_modules - -# Remove this to fix linting errors -test/ diff --git a/.npmignore b/.npmignore index f12f2bd..6b98dd7 100644 --- a/.npmignore +++ b/.npmignore @@ -1,9 +1,16 @@ +node_modules/** + +src/** +test/** +coverage/** + +npm-debug.log +commitlint.config.js +*.test.js + .DS_Store .eslintcache -node_modules -npm-debug.log .travis.yml -src/ -test/ -*.test.js -coverage/ +.babelrc +.eslintignore +.eslintrc diff --git a/.travis.yml b/.travis.yml index d40cf03..1f82ff5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,6 +6,7 @@ notifications: email: true node_js: - '8' +install: npm install before_install: - npm install -g npm@5 - npm install -g greenkeeper-lockfile@1 diff --git a/test/DistanceConverterTest.js b/test/DistanceConverterTest.js deleted file mode 100644 index 542b84d..0000000 --- a/test/DistanceConverterTest.js +++ /dev/null @@ -1,63 +0,0 @@ -import chai from 'chai'; -import sinon from 'sinon'; -import sinonChai from 'sinon-chai'; - -import DistanceUnit from '../src/data/DistanceUnit'; - -import DistanceConverter from '../src/services/DistanceConverter'; - -chai.use(sinonChai); - -const expect = chai.expect; - -describe('Distance converter', () => { - let sandbox; - const converter = new DistanceConverter(); - - beforeEach(() => { - sandbox = sinon.sandbox.create(); - }); - - afterEach(() => { - sandbox.restore(); - }); - - describe('Unit identifier', () => { - it('identifies successfully', () => { - expect(converter.getUnitConversionIdentifier(DistanceUnit.MILE)).to.equal('mi'); - }); - - it('identifies unsuccessfully', () => { - expect(() => converter.getUnitConversionIdentifier('foo')).to.throw(TypeError); - }); - }); - - const distance = 1.234; - const distanceInMiles = { - value: distance, - unit: DistanceUnit.MILE, - }; - const distanceInKilometers = { - value: distance / 1000, - unit: DistanceUnit.KILOMETER, - }; - - describe('converts successfully', () => { - it('converts miles', () => { - sandbox.stub(converter, 'getUnitConversionIdentifier').returns('mi'); - expect(converter.convert(distanceInMiles, DistanceUnit.MILE)).to.eql(distanceInMiles); - }); - - it('converts kilometer', () => { - sandbox.stub(converter, 'getUnitConversionIdentifier').returns('mi'); - expect(converter.convert(distanceInMiles, DistanceUnit.KILOMETER)).to.eql(distanceInKilometers); // eslint-disable-line max-len - }); - }); - - describe('converts unsuccessfully', () => { - it('converts unsuccessfully', () => { - sandbox.stub(converter, 'getUnitConversionIdentifier').returns('mi'); - expect(() => converter.convert(distanceInMiles, 'foo')).to.throw(TypeError); - }); - }); -}); diff --git a/test/DurationConverterTest.js b/test/DurationConverterTest.js deleted file mode 100644 index 6df1f2b..0000000 --- a/test/DurationConverterTest.js +++ /dev/null @@ -1,34 +0,0 @@ -import TimeUnit from '../src/data/TimeUnit'; -import DurationConverter from '../src/services/DurationConverter'; - -describe('Duration converter', () => { - const converter = new DurationConverter(); - const length = 60; - const durationInSeconds = { - length, - unit: TimeUnit.SECOND, - }; - - it('validates construction', () => { - const expected = {}; - expected[TimeUnit.SECOND.name] = 's'; - expected[TimeUnit.MINUTE.name] = 'min'; - expect(converter.durationUnitAbbreviations).to.eql(Map(expected)); - }); - - describe('unit identification', () => { - it('successfully', () => { - expect(converter.getUnitConversionIdentifier(TimeUnit.SECOND)).to.equal('s'); - }); - - it('throws for unknown unit', () => { - expect(() => converter.getUnitConversionIdentifier('foo')).to.throw(TypeError); - }); - }); - - describe('conversion', () => { - it('converts', () => { - expect(converter.convert(durationInSeconds, TimeUnit.SECOND)).to.eql(durationInSeconds); - }); - }); -}); diff --git a/test/GeocodeServiceTest.js b/test/GeocodeServiceTest.js deleted file mode 100644 index 40c457a..0000000 --- a/test/GeocodeServiceTest.js +++ /dev/null @@ -1,19 +0,0 @@ -import GeocodeService from '../src/services/GeocodeService'; -import geocodeFile from './files/geocode.json'; - -describe('Test Geocode Service', () => { - const service = new GeocodeService(); - const address = '25 first street cambridge ma'; - const location = { - name: '25 First St, Cambridge, MA 02141, USA', - coordinate: { - latitude: 42.369695, - longitude: -71.07800569999999, - }, - }; - const locations = List.of(location); - - it('tests data fetching', () => service.getData(address).should.eventually.eql(geocodeFile)); - - it('tests location fetching', () => service.getLocations(address).should.eventually.eql(locations)); -}); diff --git a/test/UberServiceIntegrationTest.js b/test/UberServiceIntegrationTest.js deleted file mode 100644 index 5db9660..0000000 --- a/test/UberServiceIntegrationTest.js +++ /dev/null @@ -1,29 +0,0 @@ -/* eslint-disable no-console */ - -import UberService from '../src/services/UberService'; -import DistanceUnit from '../src/data/DistanceUnit'; - -describe('Test Uber Service', () => { - const service = new UberService(); - const address = '25 first street cambridge ma'; - const address2 = '114 line street somerville ma'; - const priceEstimateQuery = { - startAddress: address, - endAddress: address2, - distanceUnit: DistanceUnit.MILE, - }; - - it('tests time estimates fulfillment', () => service.getTimeEstimates(address).should.be.fulfilled); - - it('tests time estimates fetching', () => - service.getTimeEstimates(address) - .then(results => console.log(results)), - ); - - it('tests price estimates fulfillment', () => service.getPriceEstimates(priceEstimateQuery).should.be.fulfilled); - - it('tests price estimates fetching', () => - service.getPriceEstimates(priceEstimateQuery) - .then(results => console.log(results)), - ); -}); diff --git a/test/files/geocode.json b/test/files/geocode.json deleted file mode 100644 index 33c0c81..0000000 --- a/test/files/geocode.json +++ /dev/null @@ -1,102 +0,0 @@ -{ - "results": [ - { - "address_components": [ - { - "long_name": "25", - "short_name": "25", - "types": [ - "street_number" - ] - }, - { - "long_name": "First Street", - "short_name": "First St", - "types": [ - "route" - ] - }, - { - "long_name": "East Cambridge", - "short_name": "East Cambridge", - "types": [ - "neighborhood", - "political" - ] - }, - { - "long_name": "Cambridge", - "short_name": "Cambridge", - "types": [ - "locality", - "political" - ] - }, - { - "long_name": "Middlesex County", - "short_name": "Middlesex County", - "types": [ - "administrative_area_level_2", - "political" - ] - }, - { - "long_name": "Massachusetts", - "short_name": "MA", - "types": [ - "administrative_area_level_1", - "political" - ] - }, - { - "long_name": "United States", - "short_name": "US", - "types": [ - "country", - "political" - ] - }, - { - "long_name": "02141", - "short_name": "02141", - "types": [ - "postal_code" - ] - } - ], - "formatted_address": "25 First St, Cambridge, MA 02141, USA", - "geometry": { - "bounds": { - "northeast": { - "lat": 42.3700367, - "lng": -71.07720950000001 - }, - "southwest": { - "lat": 42.3693533, - "lng": -71.0788019 - } - }, - "location": { - "lat": 42.369695, - "lng": -71.07800569999999 - }, - "location_type": "ROOFTOP", - "viewport": { - "northeast": { - "lat": 42.3710439802915, - "lng": -71.07665671970851 - }, - "southwest": { - "lat": 42.3683460197085, - "lng": -71.07935468029152 - } - } - }, - "place_id": "ChIJjVr9Ibxw44kR0o0vVgwOUAU", - "types": [ - "premise" - ] - } - ], - "status": "OK" -} diff --git a/test/files/price-estimates.json b/test/files/price-estimates.json deleted file mode 100644 index 92a94ee..0000000 --- a/test/files/price-estimates.json +++ /dev/null @@ -1,81 +0,0 @@ -{ - "prices": [ - { - "localized_display_name": "uberPOOL", - "distance": 5.76, - "display_name": "uberPOOL", - "product_id": "929fcc19-8cb4-4007-a54f-3ab34473700f", - "high_estimate": 19, - "low_estimate": 13, - "duration": 960, - "estimate": "$13-18", - "currency_code": "USD" - }, - { - "localized_display_name": "uberX", - "distance": 5.76, - "display_name": "uberX", - "product_id": "b8e5c464-5de2-4539-a35a-986d6e58f186", - "high_estimate": 27, - "low_estimate": 21, - "duration": 960, - "estimate": "$21-27", - "currency_code": "USD" - }, - { - "localized_display_name": "uberXL", - "distance": 5.76, - "display_name": "uberXL", - "product_id": "1e0ce2df-4a1e-4333-86dd-dc0c67aaabe1", - "high_estimate": 41, - "low_estimate": 32, - "duration": 960, - "estimate": "$32-41", - "currency_code": "USD" - }, - { - "localized_display_name": "WAV", - "distance": 5.76, - "display_name": "WAV", - "product_id": "3bca1cd3-df15-49d8-bd4f-93e014fc26ff", - "high_estimate": 27, - "low_estimate": 21, - "duration": 960, - "estimate": "$21-27", - "currency_code": "USD" - }, - { - "localized_display_name": "uberFAMILY", - "distance": 5.76, - "display_name": "uberFAMILY", - "product_id": "d6d6d7ad-67f9-43ef-a8de-86bd6224613a", - "high_estimate": 39, - "low_estimate": 31, - "duration": 960, - "estimate": "$31-39", - "currency_code": "USD" - }, - { - "localized_display_name": "UberBLACK", - "distance": 5.76, - "display_name": "UberBLACK", - "product_id": "0e9d8dd3-ffec-4c2b-9714-537e6174bb88", - "high_estimate": 47, - "low_estimate": 37, - "duration": 960, - "estimate": "$37-47", - "currency_code": "USD" - }, - { - "localized_display_name": "SUV", - "distance": 5.76, - "display_name": "SUV", - "product_id": "56487469-0d3d-4f19-b662-234b7576a562", - "high_estimate": 63, - "low_estimate": 51, - "duration": 960, - "estimate": "$51-63", - "currency_code": "USD" - } - ] -} diff --git a/test/files/time-estimates.json b/test/files/time-estimates.json deleted file mode 100644 index f84826f..0000000 --- a/test/files/time-estimates.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "times": [ - { - "localized_display_name": "uberPOOL", - "estimate": 240, - "display_name": "uberPOOL", - "product_id": "929fcc19-8cb4-4007-a54f-3ab34473700f" - }, - { - "localized_display_name": "uberX", - "estimate": 240, - "display_name": "uberX", - "product_id": "b8e5c464-5de2-4539-a35a-986d6e58f186" - }, - { - "localized_display_name": "uberXL", - "estimate": 300, - "display_name": "uberXL", - "product_id": "1e0ce2df-4a1e-4333-86dd-dc0c67aaabe1" - }, - { - "localized_display_name": "uberFAMILY", - "estimate": 300, - "display_name": "uberFAMILY", - "product_id": "d6d6d7ad-67f9-43ef-a8de-86bd6224613a" - }, - { - "localized_display_name": "UberBLACK", - "estimate": 180, - "display_name": "UberBLACK", - "product_id": "0e9d8dd3-ffec-4c2b-9714-537e6174bb88" - }, - { - "localized_display_name": "SUV", - "estimate": 300, - "display_name": "SUV", - "product_id": "56487469-0d3d-4f19-b662-234b7576a562" - } - ] -} diff --git a/test/services/CommandExecutionServiceTest.js b/test/services/CommandExecutionServiceTest.js deleted file mode 100644 index 8d98dda..0000000 --- a/test/services/CommandExecutionServiceTest.js +++ /dev/null @@ -1,56 +0,0 @@ -'use es6'; - -import chai from 'chai'; -import chaiAsPromised from 'chai-as-promised'; -import sinon from 'sinon'; -import sinonChai from 'sinon-chai'; - -import CommandExecutionService from '../../src/services/CommandExecutionService'; -import DistanceUnit from '../../src/data/DistanceUnit'; - -chai.use(chaiAsPromised); -chai.use(sinonChai); - -const expect = chai.expect; - -describe('Command Execution Service', () => { - const service = new CommandExecutionService(); - - describe('Price estimates', () => { - it('throws for empty start address type', () => { - expect(() => service.executePriceEstimates(1, '', DistanceUnit.MILE)).to.throw(TypeError, 'Start and End addresses (-s \'
\' -e \'
\') are required.'); - }); - - it('throws for empty end address type', () => { - expect(() => service.executePriceEstimates('foo', null, DistanceUnit.MILE)).to.throw(TypeError, 'Start and End addresses (-s \'
\' -e \'
\') are required.'); - }); - - it('throws for undefined distance unit name', () => { - expect(() => service.executePriceEstimates('foo', 'bar', 'baz')).to.throw(TypeError); - }); - - it('returns a value', () => { - const priceEstimates = new Promise((resolve, reject) => resolve('foo')); // eslint-disable-line no-unused-vars - const priceEstimater = sinon.stub(service.uberService, 'getPriceEstimates').returns(priceEstimates); - const tableBuilder = sinon.stub(service.tripPriceEstimatesTableBuilder, 'build').returns('jaebaebae'); - expect(service.executePriceEstimates('foo', 'bar', undefined)).to.eventually.equal('jaebaebae'); - priceEstimater.restore(); - tableBuilder.restore(); - }); - }); - - describe('Time estimates', () => { - it('throws for invalid address type', () => { - expect(() => service.executeTimeEstimates(1)).to.throw(TypeError, 'Address should be a string'); - }); - - it('returns a value', () => { - const timeEstimates = new Promise((resolve, reject) => resolve('foo')); // eslint-disable-line no-unused-vars - const tableBuilder = sinon.stub(service.pickupTimeEstimatesTableBuilder, 'build').returns('baz'); - const timeEstimation = sinon.stub(service.uberService, 'getTimeEstimates').returns(timeEstimates); - expect(service.executeTimeEstimates('bar')).to.eventually.equal('baz'); - tableBuilder.restore(); - timeEstimation.restore(); - }); - }); -}); diff --git a/test/services/UberServiceTest.js b/test/services/UberServiceTest.js deleted file mode 100644 index dd987f6..0000000 --- a/test/services/UberServiceTest.js +++ /dev/null @@ -1,59 +0,0 @@ -import UberService from '../../src/services/UberService'; - -describe('Uber Service', () => { - const uberService = new UberService(); - - describe('first location', () => { - it('throws', () => { - const geocodeLocations = sinon.stub(uberService.geocodeService, 'getLocations').returns(Promise.resolve(List())); - - expect(uberService.getFirstLocation()).to.be.rejectedWith(RangeError); - - geocodeLocations.restore(); - }); - - it('succeeds', () => { - const geocodeLocations = sinon.stub(uberService.geocodeService, 'getLocations').returns(Promise.resolve(List.of(1, 2, 3))); - - expect(uberService.getFirstLocation()).to.eventually.eql(1); - - geocodeLocations.restore(); - }); - }); - - describe('time estimates', () => { - it('succeeds', () => { - const firstLocation = sinon.stub(uberService, 'getFirstLocation').returns(Promise.resolve('jaebaebae')); - const clientTimeEstimation = sinon.stub(uberService.client, 'getTimeEstimates').returns(Promise.resolve({})); - const pickupTimeTranslation = sinon.stub(uberService.pickupTimeEstimatesTranslator, 'translate').returns(Promise.resolve('bae jadley')); - const expected = { - location: 'jaebaebae', - estimates: 'baejadley', - }; - - expect(uberService.getTimeEstimates()).to.eventually.eql(expected); - - firstLocation.restore(); - clientTimeEstimation.restore(); - pickupTimeTranslation.restore(); - }); - }); - - describe('price estimates', () => { - it('succeeds', () => { - const firstLocation = sinon.stub(uberService, 'getFirstLocation').returns(Promise.resolve('jaebaebae')); - const clientPriceEstimation = sinon.stub(uberService.client, 'getPriceEstimates').returns(Promise.resolve({})); - const priceEstimatesTranslation = sinon.stub(uberService.tripPriceEstimatesTranslator, 'translate').returns(Promise.resolve('bae jadley')); - const expected = { - start: 'jaebaebae', - end: 'jaebaebae', - estimates: 'bae jadley', - }; - expect(uberService.getPriceEstimates({ startAddress: 'jae', endAddress: 'baebae' })).to.eventually.eql(expected); - - firstLocation.restore(); - clientPriceEstimation.restore(); - priceEstimatesTranslation.restore(); - }); - }); -}); diff --git a/test/services/tables/PickupTimeEstimatesTableRowsBuilderTest.js b/test/services/tables/PickupTimeEstimatesTableRowsBuilderTest.js deleted file mode 100644 index d5615a1..0000000 --- a/test/services/tables/PickupTimeEstimatesTableRowsBuilderTest.js +++ /dev/null @@ -1,51 +0,0 @@ -import DurationConverter from '../../../src/services/DurationConverter'; -import DurationFormatter from '../../../src/services/DurationFormatter'; -import PickupTimeEstimatesTableRowsBuilder from '../../../src/services/tables/PickupTimeEstimatesTableRowsBuilder'; - -describe('Pickup Time Estimates Table Rows Builder', () => { - const durationConverter = new DurationConverter(); - const durationFormatter = new DurationFormatter(durationConverter); - const rowsBuilder = new PickupTimeEstimatesTableRowsBuilder(durationFormatter); - const estimate = { productName: 'jaebaebae', duration: 1 }; - const anotherEstimate = { productName: 'bae jadley', duration: 2 }; - const estimates = List.of(estimate, anotherEstimate); - - describe('groups by row', () => { - it('empty estimates', () => { - expect(rowsBuilder.groupByTime(List())).to.eql(Map()); - }); - - it('one estimate', () => { - const durationFormatting = sinon.stub(durationFormatter, 'format').returns('foo'); - const expectedJS = { foo: ['jaebaebae'] }; - - expect(rowsBuilder.groupByTime(List.of(estimate)).toJS()).to.eql(expectedJS); - - durationFormatting.restore(); - }); - - it('duplicate estimates', () => { - const durationFormatting = sinon.stub(durationFormatter, 'format').returns('foo'); - const expectedJS = { foo: ['jaebaebae', 'bae jadley'] }; - - expect(rowsBuilder.groupByTime(estimates).toJS()).to.eql(expectedJS); - - durationFormatting.restore(); - }); - }); - - describe('builds', () => { - it('succeeds', () => { - const groups = Map({ foo: ['bar', 'baz'], jae: ['bae'] }); - const rowGrouping = sinon.stub(rowsBuilder, 'groupByTime').returns(groups); - const expected = List.of( - List.of('foo', 'bar, baz'), - List.of('jae', 'bae'), - ); - - expect(rowsBuilder.build(estimates)).to.eql(expected); - - rowGrouping.restore(); - }); - }); -}); diff --git a/test/services/tables/TripPriceEstimateRowFormatterTest.js b/test/services/tables/TripPriceEstimateRowFormatterTest.js deleted file mode 100644 index 97034b9..0000000 --- a/test/services/tables/TripPriceEstimateRowFormatterTest.js +++ /dev/null @@ -1,111 +0,0 @@ -import DistanceUnit from '../../../src/data/DistanceUnit'; - -import DistanceConverter from '../../../src/services/DistanceConverter'; -import DurationConverter from '../../../src/services/DurationConverter'; -import DurationFormatter from '../../../src/services/DurationFormatter'; -import TripPriceEstimateRowFormatter from '../../../src/services/tables/TripPriceEstimateRowFormatter'; -import SymbolService from '../../../src/services/symbols/SymbolService'; - -describe('Trip Price Estimate Row Formatter', () => { - let sandbox; - - const distanceConverter = new DistanceConverter(); - const durationConverter = new DurationConverter(); - const durationFormatter = new DurationFormatter(durationConverter); - const symbolService = new SymbolService(); - const rowFormatter = new TripPriceEstimateRowFormatter(distanceConverter, durationFormatter, symbolService); // eslint-disable-line max-len - - beforeEach(() => { - sandbox = sinon.sandbox.create(); - }); - - afterEach(() => { - sandbox.restore(); - }); - - it('construction', () => { - const abbreviations = {}; - abbreviations[DistanceUnit.MILE.name] = 'mi'; - abbreviations[DistanceUnit.KILOMETER.name] = 'km'; - const expected = Map(abbreviations); - expect(rowFormatter.distanceUnitAbbreviations).to.eql(expected); - }); - - describe('fetches distance unit abbreviation', () => { - it('succeeds', () => expect(rowFormatter.getDistanceUnitAbbreviation(DistanceUnit.MILE)).to.eql('mi')); - - it('throws exception', () => expect(() => rowFormatter.getDistanceUnitAbbreviation('foo')).to.throw(TypeError)); - }); - - describe('#formatRange', () => { - const range = { - currencyCode: 'USD', - low: 'foo', - high: 'bar', - }; - - it('successfully', () => { - sandbox.stub(rowFormatter, 'formatCurrencyValue').callsFake((value, currencyCode) => `${value}-${currencyCode}`); - const expected = 'foo-USD-bar-USD'; - expect(rowFormatter.formatRange(range)).to.eql(expected); - }); - }); - - describe('#formatCurrencyValue', () => { - it('succeeds', () => { - expect(rowFormatter.formatCurrencyValue(1234.567, 'USD')).to.eql('$1,235'); - }); - }); - - describe('format distance', () => { - it('succeeds', () => { - const distanceConversion = sinon.stub(distanceConverter, 'convert').returns({ value: 1 }); - const distanceUnitAbbreviation = sinon.stub(rowFormatter, 'getDistanceUnitAbbreviation').returns('bar'); - const expected = '1 bar.'; - - expect(rowFormatter.formatDistance({})).to.eql(expected); - - distanceConversion.restore(); - distanceUnitAbbreviation.restore(); - }); - }); - - describe('format surge multiplier', () => { - beforeEach(() => { - sandbox = sinon.sandbox.create(); - }); - - afterEach(() => { - sandbox.restore(); - }); - - it('for no surge multiplier', () => { - const notApplicableSymbol = 'not applicable symbol'; - sandbox.stub(rowFormatter.symbolService, 'getNotApplicableSymbol').returns(notApplicableSymbol); - expect(rowFormatter.formatSurgeMultiplier(1)).to.eql(notApplicableSymbol); - }); - - it('for surge multiplier', () => { - const surgePresentSymbol = 'surge present symbol'; - sandbox.stub(rowFormatter.symbolService, 'getSurgePresentSymbol').returns(surgePresentSymbol); - const expected = `1.1x ${surgePresentSymbol}`; - expect(rowFormatter.formatSurgeMultiplier(1.1)).to.eql(expected); - }); - }); - - describe('format', () => { - it('succeeds', () => { - const formattedRange = 'formatted range'; - const formattedDistance = 'formatted distance'; - const formattedDuration = 'formatted duration'; - const formattedSurgeMultiplier = 'formatted surge multiplier'; - sandbox.stub(rowFormatter, 'formatRange').returns(formattedRange); - sandbox.stub(rowFormatter, 'formatDistance').returns(formattedDistance); - sandbox.stub(rowFormatter.durationFormatter, 'format').returns(formattedDuration); - sandbox.stub(rowFormatter, 'formatSurgeMultiplier').returns(formattedSurgeMultiplier); - const expected = List.of('productName', formattedRange, formattedDistance, formattedDuration, formattedSurgeMultiplier); - - expect(rowFormatter.format({ productName: 'productName' }, {})).to.eql(expected); - }); - }); -}); diff --git a/test/services/tables/builders/PickupTimeEstimatesTableBuilderTest.js b/test/services/tables/builders/PickupTimeEstimatesTableBuilderTest.js deleted file mode 100644 index 5a6179a..0000000 --- a/test/services/tables/builders/PickupTimeEstimatesTableBuilderTest.js +++ /dev/null @@ -1,115 +0,0 @@ -/* eslint-disable no-console */ - -import Table from 'cli-table2'; - -import PickupTimeEstimatesTableRowsBuilder from '../../../../src/services/tables/PickupTimeEstimatesTableRowsBuilder'; -import PickupTimeEstimatesTableBuilder from '../../../../src/services/tables/builders/PickupTimeEstimatesTableBuilder'; -import SymbolService from '../../../../src/services/symbols/SymbolService'; - -chai.use(chaiImmutable); -chai.use(sinonChai); - -const expect = chai.expect; - -describe('Pickup Time Estimates Table Builder', () => { - let sandbox; - - const symbolService = new SymbolService(); - const rowsBuilder = new PickupTimeEstimatesTableRowsBuilder(); - const tableBuilder = new PickupTimeEstimatesTableBuilder(rowsBuilder, symbolService); - - beforeEach(() => { - sandbox = sinon.sandbox.create(); - }); - - afterEach(() => { - sandbox.restore(); - }); - - describe('table headers', () => { - it('fetch succeeds', () => { - const durationSymbol = 'duration symbol'; - const vehicleSymbol = 'vehicle symbol'; - sandbox.stub(tableBuilder.symbolService, 'getDurationSymbol').returns(durationSymbol); - sandbox.stub(tableBuilder.symbolService, 'getVehicleSymbol').returns(vehicleSymbol); - - const expected = List.of( - durationSymbol, - vehicleSymbol, - ); - - expect(tableBuilder.getTableHeaders()).to.eql(expected); - }); - }); - - describe('formatted location', () => { - it('fetch succeeds', () => { - const originSymbol = 'origin symbol'; - sandbox.stub(tableBuilder.symbolService, 'getOriginSymbol').returns(originSymbol); - const locationName = 'jaebaebae'; - const expected = List.of( - Map({ - colSpan: 2, - content: `${originSymbol} ${locationName}`, - hAlign: 'center', - }), - ); - expect(tableBuilder.getFormattedLocation(locationName)).to.eql(expected); - }); - }); - - describe('formatted headers', () => { - it('fetch succeeds', () => { - const tableHeadersFetching = sinon.stub(tableBuilder, 'getTableHeaders').returns(List.of(1, 2, 3)); - const expected = List.of( - Map({ - content: 1, - hAlign: 'center', - }), - Map({ - content: 2, - hAlign: 'center', - }), - Map({ - content: 3, - hAlign: 'center', - }), - ); - expect(tableBuilder.getFormattedHeaders()).to.eql(expected); - - tableHeadersFetching.restore(); - }); - }); - - describe('initial table', () => { - it('build succeeds', () => { - const tableLocationFormatting = sinon.stub(tableBuilder, 'getFormattedLocation').returns(List.of(1, 2, 3)); - const tableHeadersFetching = sinon.stub(tableBuilder, 'getFormattedHeaders').returns(List.of('jae', 'baebae')); - const expected = new Table(); - expected.push([1, 2, 3]); - expected.push(['jae', 'baebae']); - const initialTable = tableBuilder.buildInitialTable(); - - console.log(`Expect initial table to look like:\n${expected}`); - console.log(`Initial table actually looks like:\n${initialTable}`); - - expect(initialTable).to.eql(expected); - - tableLocationFormatting.restore(); - tableHeadersFetching.restore(); - }); - }); - - describe('build table', () => { - it('succeeds', () => { - const initalTableBuilding = sinon.stub(tableBuilder, 'buildInitialTable').returns([]); - const rowsBuilding = sinon.stub(rowsBuilder, 'build').returns(List.of(List.of(1), List.of(2), List.of(3))); - const expected = '1,2,3'; - - expect(tableBuilder.build({ location: { name: 'foobar' } })).to.eql(expected); - - initalTableBuilding.restore(); - rowsBuilding.restore(); - }); - }); -}); diff --git a/test/services/tables/builders/TripPriceEstimatesTableBuilderTest.js b/test/services/tables/builders/TripPriceEstimatesTableBuilderTest.js deleted file mode 100644 index 788b87c..0000000 --- a/test/services/tables/builders/TripPriceEstimatesTableBuilderTest.js +++ /dev/null @@ -1,150 +0,0 @@ -/* eslint-disable no-console */ - -import Table from 'cli-table2'; - -import TripPriceEstimateRowFormatter from '../../../../src/services/tables/TripPriceEstimateRowFormatter'; -import TripPriceEstimatesTableBuilder from '../../../../src/services/tables/builders/TripPriceEstimatesTableBuilder'; - -import SymbolService from '../../../../src/services/symbols/SymbolService'; - -describe('Trip Price Estimates Table Builder', () => { - let sandbox; - - const rowFormatter = new TripPriceEstimateRowFormatter(); - const symbolService = new SymbolService(); - const tableBuilder = new TripPriceEstimatesTableBuilder(rowFormatter, symbolService); - - beforeEach(() => { - sandbox = sinon.sandbox.create(); - }); - - afterEach(() => { - sandbox.restore(); - }); - - describe('#getTableHeaders', () => { - it('succeeds', () => { - const vehicleSymbol = 'vehicle symbol'; - const priceSymbol = 'price symbol'; - const tripDistanceSymbol = 'trip distance symbol'; - const durationSymbol = 'duration symbol'; - const surgeSymbol = 'surge symbol'; - sandbox.stub(tableBuilder.symbolService, 'getVehicleSymbol').returns(vehicleSymbol); - sandbox.stub(tableBuilder.symbolService, 'getPriceSymbol').returns(priceSymbol); - sandbox.stub(tableBuilder.symbolService, 'getTripDistanceSymbol').returns(tripDistanceSymbol); - sandbox.stub(tableBuilder.symbolService, 'getDurationSymbol').returns(durationSymbol); - sandbox.stub(tableBuilder.symbolService, 'getSurgeSymbol').returns(surgeSymbol); - const expected = List.of( - vehicleSymbol, - priceSymbol, - tripDistanceSymbol, - durationSymbol, - `${surgeSymbol} Surge${surgeSymbol}`, - ); - - expect(tableBuilder.getTableHeaders()).to.eql(expected); - }); - }); - - describe('initial table', () => { - it('build succeeds', () => { - const tableHeadersFetching = sinon.stub(tableBuilder, 'getTableHeaders').returns(List.of(1, 2, 3)); - const expected = new Table(); - expected.push([ - { - content: 1, - hAlign: 'center', - }, - { - content: 2, - hAlign: 'center', - }, - { - content: 3, - hAlign: 'center', - }, - ]); - expect(tableBuilder.buildInitialTable()).to.eql(expected); - tableHeadersFetching.restore(); - }); - }); - - describe('location row', () => { - const name = 'jaebaebae'; - - it('builds', () => { - const endSymbol = 'end symbol'; - sandbox.stub(tableBuilder, 'getEndSymbol').returns(endSymbol); - const expected = List.of( - Map({ - colSpan: 1, - content: endSymbol, - hAlign: 'center', - }), - Map({ - colSpan: 4, - content: name, - }), - ); - expect(tableBuilder.buildLocationRow(name, true)).to.eql(expected); - }); - }); - - describe('builds table', () => { - it('without taxi', () => { - const rowFormatting = sinon.stub(rowFormatter, 'format').callsFake((estimate, distanceUnit) => List.of(`foo_${estimate.productName}`)); // eslint-disable-line no-unused-vars - const initialTableBuilding = sinon.stub(tableBuilder, 'buildInitialTable').returns(new Table()); - const locationRowBuilding = sinon.stub(tableBuilder, 'buildLocationRow').returns(List.of('bar')); - const withoutTaxi = { - start: 'jae', - end: 'baebae', - estimates: [ - { productName: 1 }, - { productName: 2 }, - { productName: 3 }, - ], - }; - const expected = '\u001b[90m┌───────┐\u001b[39m\n\u001b[90m│\u001b[39m foo_1 \u001b[90m│\u001b[39m\n\u001b[90m├───────┤\u001b[39m\n\u001b[90m│\u001b[39m foo_2 \u001b[90m│\u001b[39m\n\u001b[90m├───────┤\u001b[39m\n\u001b[90m│\u001b[39m foo_3 \u001b[90m│\u001b[39m\n\u001b[90m├───────┤\u001b[39m\n\u001b[90m│\u001b[39m bar \u001b[90m│\u001b[39m\n\u001b[90m├───────┤\u001b[39m\n\u001b[90m│\u001b[39m bar \u001b[90m│\u001b[39m\n\u001b[90m└───────┘\u001b[39m'; - console.log(`expected without taxi: ${expected}`); - expect(tableBuilder.build(withoutTaxi, {})).to.eql(expected); - rowFormatting.restore(); - initialTableBuilding.restore(); - locationRowBuilding.restore(); - }); - - it('with taxi', () => { - const rowFormatting = sinon.stub(rowFormatter, 'format').callsFake((estimate, distanceUnit) => List.of(`foo_${estimate.productName}`)); // eslint-disable-line no-unused-vars - const initialTableBuilding = sinon.stub(tableBuilder, 'buildInitialTable').returns(new Table()); - const locationRowBuilding = sinon.stub(tableBuilder, 'buildLocationRow').returns(List.of('bar')); - const withTaxi = { - start: 'jae', - end: 'baebae', - estimates: [ - { productName: 1 }, - { productName: 'TAXI' }, - { productName: 3 }, - ], - }; - const expected = '\u001b[90m┌───────┐\u001b[39m\n\u001b[90m│\u001b[39m foo_1 \u001b[90m│\u001b[39m\n\u001b[90m├───────┤\u001b[39m\n\u001b[90m│\u001b[39m foo_3 \u001b[90m│\u001b[39m\n\u001b[90m├───────┤\u001b[39m\n\u001b[90m│\u001b[39m bar \u001b[90m│\u001b[39m\n\u001b[90m├───────┤\u001b[39m\n\u001b[90m│\u001b[39m bar \u001b[90m│\u001b[39m\n\u001b[90m└───────┘\u001b[39m'; - console.log(`expected with taxi: ${expected}`); - expect(tableBuilder.build(withTaxi, {})).to.eql(expected); - rowFormatting.restore(); - initialTableBuilding.restore(); - locationRowBuilding.restore(); - }); - }); - - describe('#getEndSymbol', () => { - it('should return destination symbol', () => { - const destinationSymbol = 'destination symbol'; - sandbox.stub(tableBuilder.symbolService, 'getDestinationSymbol').returns(destinationSymbol); - expect(tableBuilder.getEndSymbol(true)).to.eql(destinationSymbol); - }); - - it('should return origin symbol', () => { - const originSymbol = 'origin symbol'; - sandbox.stub(tableBuilder.symbolService, 'getOriginSymbol').returns(originSymbol); - expect(tableBuilder.getEndSymbol(false)).to.eql(originSymbol); - }); - }); -}); From a08de8c34629f46b6cb935fdc2a770ff2cc32a18 Mon Sep 17 00:00:00 2001 From: Jae Bradley Date: Mon, 11 Jun 2018 21:04:33 -0400 Subject: [PATCH 28/38] build(commitlint): add commitlint.config.js --- commitlint.config.js | 1 + 1 file changed, 1 insertion(+) create mode 100644 commitlint.config.js diff --git a/commitlint.config.js b/commitlint.config.js new file mode 100644 index 0000000..69b18d9 --- /dev/null +++ b/commitlint.config.js @@ -0,0 +1 @@ +module.exports = { extends: ['@commitlint/config-angular'] }; From c741817acbb30605659916883705740b07c57b4e Mon Sep 17 00:00:00 2001 From: Jae Bradley Date: Mon, 11 Jun 2018 21:36:02 -0400 Subject: [PATCH 29/38] refactor(google-maps): upgrade google-maps and consolidate logic --- package-lock.json | 6 +++--- package.json | 2 +- src/services/AddressLocator.js | 30 ++++++++++++++++++++++++++++++ src/services/GeocodeService.js | 34 ---------------------------------- src/services/UberService.js | 19 +++++-------------- 5 files changed, 39 insertions(+), 52 deletions(-) create mode 100644 src/services/AddressLocator.js delete mode 100644 src/services/GeocodeService.js diff --git a/package-lock.json b/package-lock.json index 32cdc2a..68ae544 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1927,9 +1927,9 @@ } }, "@google/maps": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@google/maps/-/maps-0.3.1.tgz", - "integrity": "sha1-PxAwMDPlPT/Hu51iaN4iZoA794E=" + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/@google/maps/-/maps-0.4.6.tgz", + "integrity": "sha512-eoLrzOc2/IYqce0Tw1dxuHEqabbPS5jsuhbGHMkJETI5eA1Ls+1BlRigjbljgnbH77f5P9wfFgaoolXIhMYg8Q==" }, "@marionebl/sander": { "version": "0.6.1", diff --git a/package.json b/package.json index f793333..7375264 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ }, "dependencies": { "@babel/runtime": "^7.0.0-beta.47", - "@google/maps": "^0.3.1", + "@google/maps": "^0.4.6", "cli-table2": "^0.2.0", "colors": "^1.1.2 ", "commander": "^2.9.0", diff --git a/src/services/AddressLocator.js b/src/services/AddressLocator.js new file mode 100644 index 0000000..673da38 --- /dev/null +++ b/src/services/AddressLocator.js @@ -0,0 +1,30 @@ +import GoogleMapsClient from '@google/maps'; + +class AddressLocator { + constructor() { + this.googleMapsClient = GoogleMapsClient.createClient({ + key: 'AIzaSyBfyXZ3kDp03V_o7_mak0wxVU4B2Zcl0Ak', + Promise, + }); + } + + async getFirstLocation(address) { + const { json } = await this.googleMapsClient.geocode({ address }).asPromise(); + const { results: locations } = json; + + if (locations.length > 0) { + const location = locations[0]; + return { + name: location.formatted_address, + coordinate: { + latitude: location.geometry.location.lat, + longitude: location.geometry.location.lng, + }, + }; + } + + throw new RangeError(`No locations for address: ${address}`); + } +} + +export default AddressLocator; diff --git a/src/services/GeocodeService.js b/src/services/GeocodeService.js deleted file mode 100644 index 974a85a..0000000 --- a/src/services/GeocodeService.js +++ /dev/null @@ -1,34 +0,0 @@ -import GoogleMapsClient from '@google/maps'; - -class GeocodeService { - constructor() { - this.googleMapsClient = GoogleMapsClient.createClient({ - key: 'AIzaSyBfyXZ3kDp03V_o7_mak0wxVU4B2Zcl0Ak', - }); - } - - getData(address) { - return new Promise((resolve, reject) => { - this.googleMapsClient.geocode({ address }, (err, data) => { - if (err !== null) { - return reject(err); - } - - return resolve(data.json); - }); - }); - } - - async getLocations(address) { - const { results } = await this.getData(address); - return results.map(result => ({ - name: result.formatted_address, - coordinate: { - latitude: result.geometry.location.lat, - longitude: result.geometry.location.lng, - }, - })); - } -} - -export default GeocodeService; diff --git a/src/services/UberService.js b/src/services/UberService.js index 8a5987c..3dcc8b8 100644 --- a/src/services/UberService.js +++ b/src/services/UberService.js @@ -1,26 +1,17 @@ import { UberClient } from 'uber-client'; -import GeocodeService from './GeocodeService'; +import AddressLocator from './AddressLocator'; import TimeUnit from '../data/TimeUnit'; import DistanceUnit from '../data/DistanceUnit'; export default class UberService { constructor() { this.uberClient = new UberClient('We0MNCaIpx00F_TUopt4jgL9BzW3bWWt16aYM4mh'); - this.geocodeService = new GeocodeService(); - } - - async getFirstLocation(address) { - const locations = await this.geocodeService.getLocations(address); - if (locations.length > 0) { - return locations[0]; - } - - throw new RangeError(`No locations for address: ${address}`); + this.addressLocator = new AddressLocator(); } async getTimeEstimates(address) { - const location = await this.getFirstLocation(address); + const location = await this.addressLocator.getFirstLocation(address); const timeEstimates = await this.uberClient.getTimeEstimates({ start: location.coordinate }); return { location, @@ -36,8 +27,8 @@ export default class UberService { async getPriceEstimates({ startAddress, endAddress }) { const [start, end] = await Promise.all([ - this.getFirstLocation(startAddress), - this.getFirstLocation(endAddress), + this.addressLocator.getFirstLocation(startAddress), + this.addressLocator.getFirstLocation(endAddress), ]); const estimates = await this.uberClient.getPriceEstimates({ start: start.coordinate, From 45b53b488ac517a9c5544294caf631ad03e30cc2 Mon Sep 17 00:00:00 2001 From: Jae Bradley Date: Mon, 11 Jun 2018 22:04:38 -0400 Subject: [PATCH 30/38] test(address-locator): add tests for address locator --- __mocks__/@google/maps.js | 26 ++++++++++++++++++++++ src/services/AddressLocator.test.js | 34 +++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 __mocks__/@google/maps.js create mode 100644 src/services/AddressLocator.test.js diff --git a/__mocks__/@google/maps.js b/__mocks__/@google/maps.js new file mode 100644 index 0000000..81ee81b --- /dev/null +++ b/__mocks__/@google/maps.js @@ -0,0 +1,26 @@ +const geocode = jest.fn(({ address }) => ({ + asPromise: () => { + if (address === 'jaebaebae') { + return Promise.resolve({ + json: { + results: [{ + formatted_address: 'formatted address', + geometry: { + location: { + lat: 'latitude', + lng: 'longitude', + }, + }, + }], + }, + }); + } + + return Promise.resolve({ json: { results: [] } }); + }, +})); + +const createClient = jest.fn(() => ({ geocode })); + +export default { createClient }; +export { geocode }; diff --git a/src/services/AddressLocator.test.js b/src/services/AddressLocator.test.js new file mode 100644 index 0000000..ff29a33 --- /dev/null +++ b/src/services/AddressLocator.test.js @@ -0,0 +1,34 @@ +import { geocode } from '@google/maps'; + +import AddressLocator from './AddressLocator'; + +jest.mock('@google/maps'); + +describe('AddressLocator', () => { + beforeEach(() => { + geocode.mockClear(); + }); + + describe('#getFirstLocation', () => { + it('gets first address', async () => { + const address = 'jaebaebae'; + const locator = new AddressLocator(); + const firstLocation = await locator.getFirstLocation(address); + expect(firstLocation.name).toEqual('formatted address'); + expect(firstLocation.coordinate.latitude).toEqual('latitude'); + expect(firstLocation.coordinate.longitude).toEqual('longitude'); + expect(geocode).toHaveBeenCalledTimes(1); + expect(geocode).toHaveBeenCalledWith({ address }); + }); + + it('throws RangeError when no addresses are found', async () => { + const address = 'address'; + const locator = new AddressLocator(); + try { + await locator.getFirstLocation(address); + } catch (e) { + expect(e).toBeInstanceOf(RangeError); + } + }); + }); +}); From 3c28ac3e072acb1ff44e9e99833f67de3690dcc9 Mon Sep 17 00:00:00 2001 From: Jae Bradley Date: Mon, 11 Jun 2018 23:47:54 -0400 Subject: [PATCH 31/38] refactor(uber-client): replace Uber estimates client --- package-lock.json | 190 +++++++++++++++++++++++------------- package.json | 2 +- src/services/UberService.js | 8 +- 3 files changed, 125 insertions(+), 75 deletions(-) diff --git a/package-lock.json b/package-lock.json index 68ae544..b70bd00 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2345,6 +2345,7 @@ "version": "5.5.2", "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", + "dev": true, "requires": { "co": "^4.6.0", "fast-deep-equal": "^1.0.0", @@ -2539,12 +2540,14 @@ "asn1": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", - "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=" + "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=", + "dev": true }, "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true }, "assertion-error": { "version": "1.1.0", @@ -2586,7 +2589,8 @@ "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true }, "atob": { "version": "2.1.1", @@ -2597,12 +2601,23 @@ "aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true }, "aws4": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.7.0.tgz", - "integrity": "sha512-32NDda82rhwD9/JBCCkB+MRYDp0oSvlo2IL6rQWA10PQi7tDUM3eqMSltXmY+Oyl/7N3P3qNtAlv7X0d9bI28w==" + "integrity": "sha512-32NDda82rhwD9/JBCCkB+MRYDp0oSvlo2IL6rQWA10PQi7tDUM3eqMSltXmY+Oyl/7N3P3qNtAlv7X0d9bI28w==", + "dev": true + }, + "axios": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.18.0.tgz", + "integrity": "sha1-MtU+SFHv3AoRmTts0AB4nXDAUQI=", + "requires": { + "follow-redirects": "^1.3.0", + "is-buffer": "^1.1.5" + } }, "babel-code-frame": { "version": "6.26.0", @@ -3686,6 +3701,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", + "dev": true, "optional": true, "requires": { "tweetnacl": "^0.14.3" @@ -3704,15 +3720,11 @@ "dev": true, "optional": true }, - "bluebird": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", - "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==" - }, "boom": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz", "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=", + "dev": true, "requires": { "hoek": "4.x.x" } @@ -4037,7 +4049,8 @@ "caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true }, "center-align": { "version": "0.1.3", @@ -4203,7 +4216,8 @@ "co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true }, "code-point-at": { "version": "1.1.0", @@ -4255,6 +4269,7 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", + "dev": true, "requires": { "delayed-stream": "~1.0.0" } @@ -4733,7 +4748,8 @@ "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=" + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true }, "cosmiconfig": { "version": "5.0.5", @@ -4794,6 +4810,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz", "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=", + "dev": true, "requires": { "boom": "5.x.x" }, @@ -4802,6 +4819,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz", "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==", + "dev": true, "requires": { "hoek": "4.x.x" } @@ -4851,6 +4869,7 @@ "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" } @@ -5014,7 +5033,8 @@ "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true }, "detect-indent": { "version": "4.0.0", @@ -5104,6 +5124,7 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", + "dev": true, "optional": true, "requires": { "jsbn": "~0.1.0" @@ -5115,11 +5136,6 @@ "integrity": "sha1-07DYWTgUBE4JLs4hCPw6ya6kuQA=", "dev": true }, - "enumify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/enumify/-/enumify-1.0.4.tgz", - "integrity": "sha1-K7YmMHHdRVHlTFV1Vwf60kpAzX4=" - }, "env-ci": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/env-ci/-/env-ci-2.1.0.tgz", @@ -5649,7 +5665,8 @@ "extend": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", - "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=" + "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=", + "dev": true }, "extend-shallow": { "version": "3.0.2", @@ -5695,12 +5712,14 @@ "extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true }, "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=" + "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", + "dev": true }, "fast-glob": { "version": "2.2.2", @@ -6031,7 +6050,8 @@ "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=" + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", + "dev": true }, "fast-levenshtein": { "version": "2.0.6", @@ -6118,6 +6138,24 @@ "write": "^0.2.1" } }, + "follow-redirects": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.0.tgz", + "integrity": "sha512-fdrt472/9qQ6Kgjvb935ig6vJCuofpBUD14f9Vb+SLlm7xIe4Qva5gey8EKtv8lp7ahE1wilg3xL1znpVGtZIA==", + "requires": { + "debug": "^3.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==", + "requires": { + "ms": "2.0.0" + } + } + } + }, "for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", @@ -6142,12 +6180,14 @@ "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + "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", @@ -6777,6 +6817,7 @@ "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, "requires": { "assert-plus": "^1.0.0" } @@ -6978,12 +7019,14 @@ "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true }, "har-validator": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", + "dev": true, "requires": { "ajv": "^5.1.0", "har-schema": "^2.0.0" @@ -7092,6 +7135,7 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz", "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==", + "dev": true, "requires": { "boom": "4.x.x", "cryptiles": "3.x.x", @@ -7108,7 +7152,8 @@ "hoek": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz", - "integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==" + "integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==", + "dev": true }, "home-or-tmp": { "version": "2.0.0", @@ -7172,6 +7217,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, "requires": { "assert-plus": "^1.0.0", "jsprim": "^1.2.2", @@ -7478,8 +7524,7 @@ "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 + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" }, "is-builtin-module": { "version": "1.0.0", @@ -7789,7 +7834,8 @@ "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true }, "is-utf8": { "version": "0.2.1", @@ -7827,7 +7873,8 @@ "isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true }, "issue-parser": { "version": "2.0.0", @@ -9027,6 +9074,7 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true, "optional": true }, "jsdom": { @@ -9128,12 +9176,14 @@ "json-schema": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + "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=" + "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", + "dev": true }, "json-stable-stringify": { "version": "1.0.1", @@ -9153,7 +9203,8 @@ "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=" + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true }, "json5": { "version": "0.5.1", @@ -9186,6 +9237,7 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "dev": true, "requires": { "assert-plus": "1.0.0", "extsprintf": "1.3.0", @@ -9854,12 +9906,14 @@ "mime-db": { "version": "1.33.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", - "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==" + "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", + "dev": true }, "mime-types": { "version": "2.1.18", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", + "dev": true, "requires": { "mime-db": "~1.33.0" } @@ -9940,8 +9994,7 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, "mute-stream": { "version": "0.0.7", @@ -10119,7 +10172,8 @@ "oauth-sign": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", - "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=" + "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", + "dev": true }, "object-assign": { "version": "4.1.1", @@ -10629,7 +10683,8 @@ "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true }, "pify": { "version": "2.3.0", @@ -10757,7 +10812,8 @@ "punycode": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true }, "q": { "version": "1.5.1", @@ -10768,7 +10824,8 @@ "qs": { "version": "6.5.2", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true }, "query-string": { "version": "5.1.1", @@ -11092,6 +11149,7 @@ "version": "2.85.0", "resolved": "https://registry.npmjs.org/request/-/request-2.85.0.tgz", "integrity": "sha512-8H7Ehijd4js+s6wuVPLjwORxD4zeuyjYugprdOXlPSqaApmL/QOy+EB/beICHVCHkGMKNh5rvihb5ov+IDw4mg==", + "dev": true, "requires": { "aws-sign2": "~0.7.0", "aws4": "^1.6.0", @@ -11117,20 +11175,11 @@ "uuid": "^3.1.0" } }, - "request-promise": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/request-promise/-/request-promise-4.1.1.tgz", - "integrity": "sha1-JgIeT29W/Uwwn2vx69jJepWsH7U=", - "requires": { - "bluebird": "^3.4.1", - "request-promise-core": "1.1.1", - "stealthy-require": "^1.0.0" - } - }, "request-promise-core": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.1.tgz", "integrity": "sha1-Pu4AssWqgyOc+wTFcA2jb4HNCLY=", + "dev": true, "requires": { "lodash": "^4.13.1" }, @@ -11138,7 +11187,8 @@ "lodash": { "version": "4.17.10", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", - "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==" + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "dev": true } } }, @@ -11305,7 +11355,8 @@ "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==" + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true }, "safe-regex": { "version": "1.1.0", @@ -12134,6 +12185,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz", "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==", + "dev": true, "requires": { "hoek": "4.x.x" } @@ -12256,6 +12308,7 @@ "version": "1.14.1", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.1.tgz", "integrity": "sha1-Ew9Zde3a2WPx1W+SuaxsUfqfg+s=", + "dev": true, "requires": { "asn1": "~0.2.3", "assert-plus": "^1.0.0", @@ -12297,7 +12350,8 @@ "stealthy-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", - "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=" + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", + "dev": true }, "stream-combiner2": { "version": "1.1.1", @@ -12364,7 +12418,8 @@ "stringstream": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", - "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=" + "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=", + "dev": true }, "strip-ansi": { "version": "3.0.1", @@ -12906,6 +12961,7 @@ "version": "2.3.4", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", + "dev": true, "requires": { "punycode": "^1.4.1" } @@ -13131,6 +13187,7 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, "requires": { "safe-buffer": "^5.0.1" } @@ -13139,6 +13196,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 }, "type-check": { @@ -13156,22 +13214,12 @@ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", "dev": true }, - "uber-client": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/uber-client/-/uber-client-0.0.4.tgz", - "integrity": "sha1-SbuxIw/bWcd/rfmPAbUKkekcdrw=", + "uber-estimates-client": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/uber-estimates-client/-/uber-estimates-client-1.0.0.tgz", + "integrity": "sha512-7JT4mNezE7m8gt7ZdeuY4iZpjAWz903Crrk3R7SE25LkLSf+ImFVIYHoyVLQemmrJ23LpgfW9PrFhnXN+mkbww==", "requires": { - "enumify": "1.0.4", - "immutable": "3.8.1", - "request": "^2.79.0", - "request-promise": "4.1.1" - }, - "dependencies": { - "immutable": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.8.1.tgz", - "integrity": "sha1-IAgH8Rqw9ycQ6khVQt4IgHX2jNI=" - } + "axios": "^0.18.0" } }, "uglify-js": { @@ -13460,7 +13508,8 @@ "uuid": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz", - "integrity": "sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA==" + "integrity": "sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA==", + "dev": true }, "validate-npm-package-license": { "version": "3.0.3", @@ -13476,6 +13525,7 @@ "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, "requires": { "assert-plus": "^1.0.0", "core-util-is": "1.0.2", diff --git a/package.json b/package.json index 7375264..df80569 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "commander": "^2.9.0", "convert-units": "^2.0.1", "node-emoji": "^1.4.3", - "uber-client": "^0.0.4" + "uber-estimates-client": "^1.0.0" }, "devDependencies": { "@babel/cli": "^7.0.0-beta.49", diff --git a/src/services/UberService.js b/src/services/UberService.js index 3dcc8b8..95ad5ba 100644 --- a/src/services/UberService.js +++ b/src/services/UberService.js @@ -1,4 +1,4 @@ -import { UberClient } from 'uber-client'; +import UberEstimatesClient from 'uber-estimates-client'; import AddressLocator from './AddressLocator'; import TimeUnit from '../data/TimeUnit'; @@ -6,13 +6,13 @@ import DistanceUnit from '../data/DistanceUnit'; export default class UberService { constructor() { - this.uberClient = new UberClient('We0MNCaIpx00F_TUopt4jgL9BzW3bWWt16aYM4mh'); + this.uberClient = new UberEstimatesClient({ serverToken: 'We0MNCaIpx00F_TUopt4jgL9BzW3bWWt16aYM4mh' }); this.addressLocator = new AddressLocator(); } async getTimeEstimates(address) { const location = await this.addressLocator.getFirstLocation(address); - const timeEstimates = await this.uberClient.getTimeEstimates({ start: location.coordinate }); + const timeEstimates = await this.uberClient.getExpectedTimeOfArrival({ start: location.coordinate }); return { location, estimates: timeEstimates.times.map(estimate => ({ @@ -30,7 +30,7 @@ export default class UberService { this.addressLocator.getFirstLocation(startAddress), this.addressLocator.getFirstLocation(endAddress), ]); - const estimates = await this.uberClient.getPriceEstimates({ + const estimates = await this.uberClient.getPrices({ start: start.coordinate, end: end.coordinate, }); From b8cc1baa761f7d054194b5476501044bdc1d795c Mon Sep 17 00:00:00 2001 From: Jae Bradley Date: Mon, 11 Jun 2018 23:53:42 -0400 Subject: [PATCH 32/38] refactor(uber-service): rename uber client class variable --- src/services/UberService.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/services/UberService.js b/src/services/UberService.js index 95ad5ba..05d1f9c 100644 --- a/src/services/UberService.js +++ b/src/services/UberService.js @@ -6,13 +6,15 @@ import DistanceUnit from '../data/DistanceUnit'; export default class UberService { constructor() { - this.uberClient = new UberEstimatesClient({ serverToken: 'We0MNCaIpx00F_TUopt4jgL9BzW3bWWt16aYM4mh' }); + this.uberEstimatesClient = new UberEstimatesClient({ serverToken: 'We0MNCaIpx00F_TUopt4jgL9BzW3bWWt16aYM4mh' }); this.addressLocator = new AddressLocator(); } async getTimeEstimates(address) { const location = await this.addressLocator.getFirstLocation(address); - const timeEstimates = await this.uberClient.getExpectedTimeOfArrival({ start: location.coordinate }); + const timeEstimates = await this.uberEstimatesClient.getExpectedTimeOfArrival({ + start: location.coordinate, + }); return { location, estimates: timeEstimates.times.map(estimate => ({ @@ -30,7 +32,7 @@ export default class UberService { this.addressLocator.getFirstLocation(startAddress), this.addressLocator.getFirstLocation(endAddress), ]); - const estimates = await this.uberClient.getPrices({ + const estimates = await this.uberEstimatesClient.getPrices({ start: start.coordinate, end: end.coordinate, }); From 44f37abb43ed34d8c7943aa8adc99352a0e3ef0c Mon Sep 17 00:00:00 2001 From: Jae Bradley Date: Tue, 12 Jun 2018 10:22:41 -0400 Subject: [PATCH 33/38] test(uber-service): add basic tests for UberService --- __mocks__/uber-estimates-client.js | 48 ++++++++++++++++++++++++ src/services/UberService.test.js | 45 ++++++++++++++++++++++ src/services/__mocks__/AddressLocator.js | 28 ++++++++++++++ 3 files changed, 121 insertions(+) create mode 100644 __mocks__/uber-estimates-client.js create mode 100644 src/services/UberService.test.js create mode 100644 src/services/__mocks__/AddressLocator.js diff --git a/__mocks__/uber-estimates-client.js b/__mocks__/uber-estimates-client.js new file mode 100644 index 0000000..c511ff4 --- /dev/null +++ b/__mocks__/uber-estimates-client.js @@ -0,0 +1,48 @@ +const getExpectedTimeOfArrival = jest.fn(() => ({ + times: [ + { + localized_display_name: 'first localized display name', + estimate: 'first estimate', + }, + { + localized_display_name: 'second localized display name', + estimate: 'second estimate', + }, + ], +})); + +const getPrices = jest.fn(() => ({ + prices: [ + { + localized_display_name: 'first localized display name', + distance: 'first distance', + duration: 'first duration', + high_estimate: 'first high estimate', + low_estimate: 'first low estimate', + currency_code: 'first currency code', + surgeMultiplier: undefined, + }, + { + localized_display_name: 'second localized display name', + distance: 'second distance', + duration: 'second duration', + high_estimate: 'second high estimate', + low_estimate: 'second low estimate', + currency_code: 'second currency code', + surgeMultiplier: 'surgeMultiplier', + }, + ], +})); + +const constructor = jest.fn(() => ({ + getExpectedTimeOfArrival, + getPrices, +})); + +const UberEstimatesClient = constructor; + +export default UberEstimatesClient; +export { + getExpectedTimeOfArrival, + getPrices, +}; diff --git a/src/services/UberService.test.js b/src/services/UberService.test.js new file mode 100644 index 0000000..2f9e806 --- /dev/null +++ b/src/services/UberService.test.js @@ -0,0 +1,45 @@ +import UberEstimatesClient from 'uber-estimates-client'; + +import AddressLocator from './AddressLocator'; +import UberService from './UberService'; + +jest.mock('uber-estimates-client'); +jest.mock('./AddressLocator'); + +describe('UberService', () => { + let service; + + beforeEach(() => { + UberEstimatesClient.mockClear(); + AddressLocator.mockClear(); + service = new UberService(); + }); + + describe('#constructor', () => { + it('constructs service', () => { + expect(service).toBeDefined(); + expect(UberEstimatesClient).toHaveBeenCalledTimes(1); + expect(AddressLocator).toHaveBeenCalledTimes(1); + }); + }); + + describe('#getTimeEstimates', () => { + it('gets time estimates', async () => { + const timeEstimates = await service.getTimeEstimates('firstjaebaebae'); + expect(timeEstimates.location).toEqual({ coordinate: { latitude: 'firstjaebaebaelatitude', longitude: 'firstjaebaebaelongitude' } }); + expect(timeEstimates.estimates[0].productName).toEqual('first localized display name'); + }); + }); + + describe('#getPriceEstimates', () => { + it('gets price estimates', async () => { + const priceEstimates = await service.getPriceEstimates({ + startAddress: 'firstjaebaebae', + endAddress: 'secondjaebaebae', + }); + expect(priceEstimates).toBeDefined(); + expect(priceEstimates.start).toEqual({ coordinate: { latitude: 'firstjaebaebaelatitude', longitude: 'firstjaebaebaelongitude' } }); + expect(priceEstimates.estimates[0].productName).toEqual('first localized display name'); + }); + }); +}); diff --git a/src/services/__mocks__/AddressLocator.js b/src/services/__mocks__/AddressLocator.js new file mode 100644 index 0000000..95e2a76 --- /dev/null +++ b/src/services/__mocks__/AddressLocator.js @@ -0,0 +1,28 @@ +const getFirstLocation = jest.fn((address) => { + if (address === 'firstjaebaebae') { + return Promise.resolve({ + coordinate: { + latitude: 'firstjaebaebaelatitude', + longitude: 'firstjaebaebaelongitude', + }, + }); + } + + if (address === 'secondjaebaebae') { + return Promise.resolve({ + coordinate: { + latitude: 'secondjaebaebaelatitude', + longitude: 'secondjaebaebaelongitude', + }, + }); + } + + throw new Error(`Unknown address: ${address}`); +}); + +const constructor = jest.fn(() => ({ getFirstLocation })); + +const AddressLocator = constructor; + +export default AddressLocator; +export { getFirstLocation }; From 77f04735fc239e88ad5a5943f667410952a2ee36 Mon Sep 17 00:00:00 2001 From: Jae Bradley Date: Tue, 12 Jun 2018 13:14:12 -0400 Subject: [PATCH 34/38] test(time-table): add tests for time estimates table --- src/services/converters.test.js | 2 ++ src/services/tables/time/build.test.js | 50 ++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 src/services/tables/time/build.test.js diff --git a/src/services/converters.test.js b/src/services/converters.test.js index 0c82398..ddc2c83 100644 --- a/src/services/converters.test.js +++ b/src/services/converters.test.js @@ -7,6 +7,8 @@ import { convertDistance, } from './converters'; +jest.mock('convert-units'); + describe('converters', () => { describe('#convertDuration', () => { it('converts from seconds to minutes', () => { diff --git a/src/services/tables/time/build.test.js b/src/services/tables/time/build.test.js new file mode 100644 index 0000000..27233f1 --- /dev/null +++ b/src/services/tables/time/build.test.js @@ -0,0 +1,50 @@ +import TimeUnit from '../../../data/TimeUnit'; + +import build from './build'; + +jest.unmock('convert-units'); + +describe('#build', () => { + const location = { name: 'foobar' }; + + // both tests use emojis and assumes process.platform = darwin + // apologies in advance if this causes problems + + it('builds table for products that do not share same formatted duration', () => { + const estimates = [ + { + estimatedDuration: { length: 120, unit: TimeUnit.SECOND }, + productName: 'first product', + }, + { + estimatedDuration: { length: 60, unit: TimeUnit.SECOND }, + productName: 'second product', + }, + { + estimatedDuration: { length: 0, unit: TimeUnit.SECOND }, + productName: 'third product', + }, + ]; + const expected = '\u001b[90m┌─────────────────────────┐\u001b[39m\n\u001b[90m│\u001b[39m 📍 foobar \u001b[90m│\u001b[39m\n\u001b[90m├────────\u001b[39m\u001b[90m┬────────────────┤\u001b[39m\n\u001b[90m│\u001b[39m ⏳ \u001b[90m│\u001b[39m 🚘 \u001b[90m│\u001b[39m\n\u001b[90m├────────\u001b[39m\u001b[90m┼────────────────┤\u001b[39m\n\u001b[90m│\u001b[39m 0 sec. \u001b[90m│\u001b[39m third product \u001b[90m│\u001b[39m\n\u001b[90m├────────\u001b[39m\u001b[90m┼────────────────┤\u001b[39m\n\u001b[90m│\u001b[39m 1 min. \u001b[90m│\u001b[39m second product \u001b[90m│\u001b[39m\n\u001b[90m├────────\u001b[39m\u001b[90m┼────────────────┤\u001b[39m\n\u001b[90m│\u001b[39m 2 min. \u001b[90m│\u001b[39m first product \u001b[90m│\u001b[39m\n\u001b[90m└────────\u001b[39m\u001b[90m┴────────────────┘\u001b[39m'; + expect(build({ estimates, location })).toEqual(expected); + }); + + it('builds table for products that do share same formatted duration', () => { + const estimates = [ + { + estimatedDuration: { length: 120, unit: TimeUnit.SECOND }, + productName: 'first product', + }, + { + estimatedDuration: { length: 120, unit: TimeUnit.SECOND }, + productName: 'second product', + }, + { + estimatedDuration: { length: 120, unit: TimeUnit.SECOND }, + productName: 'third product', + }, + ]; + const expected = '\u001b[90m┌───────────────────────────────────────────────────────┐\u001b[39m\n\u001b[90m│\u001b[39m 📍 foobar \u001b[90m│\u001b[39m\n\u001b[90m├────────\u001b[39m\u001b[90m┬──────────────────────────────────────────────┤\u001b[39m\n\u001b[90m│\u001b[39m ⏳ \u001b[90m│\u001b[39m 🚘 \u001b[90m│\u001b[39m\n\u001b[90m├────────\u001b[39m\u001b[90m┼──────────────────────────────────────────────┤\u001b[39m\n\u001b[90m│\u001b[39m 2 min. \u001b[90m│\u001b[39m first product, second product, third product \u001b[90m│\u001b[39m\n\u001b[90m└────────\u001b[39m\u001b[90m┴──────────────────────────────────────────────┘\u001b[39m'; + expect(build({ estimates, location })).toEqual(expected); + }); +}); From f7ba7d5df1eaded295b7269591923b7e71f803f3 Mon Sep 17 00:00:00 2001 From: Jae Bradley Date: Tue, 12 Jun 2018 14:09:28 -0400 Subject: [PATCH 35/38] test(price-table): add tests for price estimates table --- src/services/converters.js | 7 +- src/services/converters.test.js | 2 +- src/services/tables/price/build.test.js | 167 ++++++++++++++++++++++++ 3 files changed, 169 insertions(+), 7 deletions(-) create mode 100644 src/services/tables/price/build.test.js diff --git a/src/services/converters.js b/src/services/converters.js index dfbb17f..967a619 100644 --- a/src/services/converters.js +++ b/src/services/converters.js @@ -12,11 +12,6 @@ const DISTANCE_UNIT_ABBREVIATIONS = Object.freeze({ [DistanceUnit.KILOMETER]: 'km', }); -const DISTANCE_UNIT_MULTIPLIER = Object.freeze({ - [DistanceUnit.KILOMETER]: 0.0001, - [DistanceUnit.MILE]: 1, -}); - const convertDuration = ({ duration, toUnit }) => ({ length: convert(duration.length) .from(DURATION_UNIT_ABBREVIATIONS[duration.unit]) @@ -27,7 +22,7 @@ const convertDuration = ({ duration, toUnit }) => ({ const convertDistance = ({ distance, toUnit }) => ({ value: (convert(distance.value) .from(DISTANCE_UNIT_ABBREVIATIONS[distance.unit]) - .to(DISTANCE_UNIT_ABBREVIATIONS[toUnit])) * DISTANCE_UNIT_MULTIPLIER[toUnit], + .to(DISTANCE_UNIT_ABBREVIATIONS[toUnit])), unit: toUnit, }); diff --git a/src/services/converters.test.js b/src/services/converters.test.js index ddc2c83..6b83bcb 100644 --- a/src/services/converters.test.js +++ b/src/services/converters.test.js @@ -39,7 +39,7 @@ describe('converters', () => { expect(convert).toHaveBeenCalledWith(1); expect(from).toHaveBeenCalledWith('mi'); expect(to).toHaveBeenCalledWith('km'); - expect(value).toEqual(0.12340000000000001); + expect(value).toEqual(1234); expect(unit).toEqual(DistanceUnit.KILOMETER); }); }); diff --git a/src/services/tables/price/build.test.js b/src/services/tables/price/build.test.js new file mode 100644 index 0000000..00e1593 --- /dev/null +++ b/src/services/tables/price/build.test.js @@ -0,0 +1,167 @@ +import build from './build'; + +import TimeUnit from '../../../data/TimeUnit'; +import DistanceUnit from '../../../data/DistanceUnit'; + +jest.unmock('convert-units'); + +let expected; +let table; +let estimates; + +const validateTable = (presentationUnits) => { + console.log('expected table'); + console.log(expected); + + table = build({ estimates, presentationUnits }); + + console.log('built table'); + console.log(table); + + expect(table).toEqual(expected); +}; + +describe('#build', () => { + // tests use emojis and assumes process.platform = darwin + // apologies in advance if this causes problems + + const distance = { + value: 12.34, + unit: DistanceUnit.MILE, + }; + const duration = { + length: 5678, + unit: TimeUnit.SECOND, + }; + const currencyCode = 'USD'; + const start = { name: 'jae' }; + const end = { name: 'baebae' }; + const firstProduct = { + productName: 'first product', + range: { + low: 10, + high: 20, + currencyCode, + }, + distance, + duration, + }; + const secondProduct = { + productName: 'second product', + range: { + low: 8, + high: 16, + currencyCode, + }, + distance, + duration, + }; + const thirdProduct = { + productName: 'third product', + range: { + low: 6, + high: 12, + currencyCode, + }, + distance, + duration, + }; + const taxiProduct = { + productName: 'TAXI', + range: { + low: 4, + high: 8, + currencyCode, + }, + distance, + duration, + }; + + const defaultEstimates = { + estimates: [ + firstProduct, + secondProduct, + thirdProduct, + ], + start, + end, + }; + + it('should build sorted table', () => { + estimates = defaultEstimates; + expected = '\u001b[90m┌────────────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬────────────────────────\u001b[39m\u001b[90m┬──────────┐\u001b[39m\n\u001b[90m│\u001b[39m 🚘 \u001b[90m│\u001b[39m 💸 \u001b[90m│\u001b[39m 🔃 \u001b[90m│\u001b[39m ⏳ \u001b[90m│\u001b[39m 😬 Surge😬 \u001b[90m│\u001b[39m\n\u001b[90m├────────────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼────────────────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m third product \u001b[90m│\u001b[39m $6-$12 \u001b[90m│\u001b[39m 12.34 mi. \u001b[90m│\u001b[39m 1 hrs. 34 min. 38 sec. \u001b[90m│\u001b[39m 🚫 \u001b[90m│\u001b[39m\n\u001b[90m├────────────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼────────────────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m second product \u001b[90m│\u001b[39m $8-$16 \u001b[90m│\u001b[39m 12.34 mi. \u001b[90m│\u001b[39m 1 hrs. 34 min. 38 sec. \u001b[90m│\u001b[39m 🚫 \u001b[90m│\u001b[39m\n\u001b[90m├────────────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼────────────────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m first product \u001b[90m│\u001b[39m $10-$20 \u001b[90m│\u001b[39m 12.34 mi. \u001b[90m│\u001b[39m 1 hrs. 34 min. 38 sec. \u001b[90m│\u001b[39m 🚫 \u001b[90m│\u001b[39m\n\u001b[90m├────────────────\u001b[39m\u001b[90m┼─────────┴───────────┴────────────────────────┴──────────┤\u001b[39m\n\u001b[90m│\u001b[39m 📍 \u001b[90m│\u001b[39m jae \u001b[90m│\u001b[39m\n\u001b[90m├────────────────\u001b[39m\u001b[90m┼─────────────────────────────────────────────────────────┤\u001b[39m\n\u001b[90m│\u001b[39m 🔚 \u001b[90m│\u001b[39m baebae \u001b[90m│\u001b[39m\n\u001b[90m└────────────────\u001b[39m\u001b[90m┴─────────────────────────────────────────────────────────┘\u001b[39m'; + validateTable(DistanceUnit.MILE); + }); + + it('should build table without TAXI product', () => { + estimates = { + estimates: [ + firstProduct, + secondProduct, + thirdProduct, + taxiProduct, + ], + start, + end, + }; + + expected = '\u001b[90m┌────────────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬────────────────────────\u001b[39m\u001b[90m┬──────────┐\u001b[39m\n\u001b[90m│\u001b[39m 🚘 \u001b[90m│\u001b[39m 💸 \u001b[90m│\u001b[39m 🔃 \u001b[90m│\u001b[39m ⏳ \u001b[90m│\u001b[39m 😬 Surge😬 \u001b[90m│\u001b[39m\n\u001b[90m├────────────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼────────────────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m third product \u001b[90m│\u001b[39m $6-$12 \u001b[90m│\u001b[39m 12.34 mi. \u001b[90m│\u001b[39m 1 hrs. 34 min. 38 sec. \u001b[90m│\u001b[39m 🚫 \u001b[90m│\u001b[39m\n\u001b[90m├────────────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼────────────────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m second product \u001b[90m│\u001b[39m $8-$16 \u001b[90m│\u001b[39m 12.34 mi. \u001b[90m│\u001b[39m 1 hrs. 34 min. 38 sec. \u001b[90m│\u001b[39m 🚫 \u001b[90m│\u001b[39m\n\u001b[90m├────────────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼────────────────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m first product \u001b[90m│\u001b[39m $10-$20 \u001b[90m│\u001b[39m 12.34 mi. \u001b[90m│\u001b[39m 1 hrs. 34 min. 38 sec. \u001b[90m│\u001b[39m 🚫 \u001b[90m│\u001b[39m\n\u001b[90m├────────────────\u001b[39m\u001b[90m┼─────────┴───────────┴────────────────────────┴──────────┤\u001b[39m\n\u001b[90m│\u001b[39m 📍 \u001b[90m│\u001b[39m jae \u001b[90m│\u001b[39m\n\u001b[90m├────────────────\u001b[39m\u001b[90m┼─────────────────────────────────────────────────────────┤\u001b[39m\n\u001b[90m│\u001b[39m 🔚 \u001b[90m│\u001b[39m baebae \u001b[90m│\u001b[39m\n\u001b[90m└────────────────\u001b[39m\u001b[90m┴─────────────────────────────────────────────────────────┘\u001b[39m'; + validateTable(DistanceUnit.MILE); + }); + + it('should build table converting to kilometers', () => { + estimates = defaultEstimates; + expected = '\u001b[90m┌────────────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬────────────────────────\u001b[39m\u001b[90m┬──────────┐\u001b[39m\n\u001b[90m│\u001b[39m 🚘 \u001b[90m│\u001b[39m 💸 \u001b[90m│\u001b[39m 🔃 \u001b[90m│\u001b[39m ⏳ \u001b[90m│\u001b[39m 😬 Surge😬 \u001b[90m│\u001b[39m\n\u001b[90m├────────────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼────────────────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m third product \u001b[90m│\u001b[39m $6-$12 \u001b[90m│\u001b[39m 19.86 km. \u001b[90m│\u001b[39m 1 hrs. 34 min. 38 sec. \u001b[90m│\u001b[39m 🚫 \u001b[90m│\u001b[39m\n\u001b[90m├────────────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼────────────────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m second product \u001b[90m│\u001b[39m $8-$16 \u001b[90m│\u001b[39m 19.86 km. \u001b[90m│\u001b[39m 1 hrs. 34 min. 38 sec. \u001b[90m│\u001b[39m 🚫 \u001b[90m│\u001b[39m\n\u001b[90m├────────────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼────────────────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m first product \u001b[90m│\u001b[39m $10-$20 \u001b[90m│\u001b[39m 19.86 km. \u001b[90m│\u001b[39m 1 hrs. 34 min. 38 sec. \u001b[90m│\u001b[39m 🚫 \u001b[90m│\u001b[39m\n\u001b[90m├────────────────\u001b[39m\u001b[90m┼─────────┴───────────┴────────────────────────┴──────────┤\u001b[39m\n\u001b[90m│\u001b[39m 📍 \u001b[90m│\u001b[39m jae \u001b[90m│\u001b[39m\n\u001b[90m├────────────────\u001b[39m\u001b[90m┼─────────────────────────────────────────────────────────┤\u001b[39m\n\u001b[90m│\u001b[39m 🔚 \u001b[90m│\u001b[39m baebae \u001b[90m│\u001b[39m\n\u001b[90m└────────────────\u001b[39m\u001b[90m┴─────────────────────────────────────────────────────────┘\u001b[39m'; + validateTable(DistanceUnit.KILOMETER); + }); + + it('should build table with surge multiplier', () => { + // probably a better way to do this but quick and dirty for now + + const firstProductWithSurge = { + productName: 'first product with surge', + range: { + low: 10, + high: 20, + currencyCode, + }, + distance, + duration, + surgeMultiplier: 1.23, + }; + const secondProductWithSurge = { + productName: 'second product with surge', + range: { + low: 8, + high: 16, + currencyCode, + }, + distance, + duration, + surgeMultiplier: 2.34, + }; + const thirdProductWithSurge = { + productName: 'third product with surge', + range: { + low: 6, + high: 12, + currencyCode, + }, + distance, + duration, + surgeMultiplier: 3.45, + }; + estimates = { + estimates: [ + firstProductWithSurge, + secondProductWithSurge, + thirdProductWithSurge, + ], + start, + end, + }; + + expected = '\u001b[90m┌───────────────────────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬────────────────────────\u001b[39m\u001b[90m┬──────────┐\u001b[39m\n\u001b[90m│\u001b[39m 🚘 \u001b[90m│\u001b[39m 💸 \u001b[90m│\u001b[39m 🔃 \u001b[90m│\u001b[39m ⏳ \u001b[90m│\u001b[39m 😬 Surge😬 \u001b[90m│\u001b[39m\n\u001b[90m├───────────────────────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼────────────────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m third product with surge \u001b[90m│\u001b[39m $6-$12 \u001b[90m│\u001b[39m 19.86 km. \u001b[90m│\u001b[39m 1 hrs. 34 min. 38 sec. \u001b[90m│\u001b[39m 3.45x 😬 \u001b[90m│\u001b[39m\n\u001b[90m├───────────────────────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼────────────────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m second product with surge \u001b[90m│\u001b[39m $8-$16 \u001b[90m│\u001b[39m 19.86 km. \u001b[90m│\u001b[39m 1 hrs. 34 min. 38 sec. \u001b[90m│\u001b[39m 2.34x 😬 \u001b[90m│\u001b[39m\n\u001b[90m├───────────────────────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼────────────────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m first product with surge \u001b[90m│\u001b[39m $10-$20 \u001b[90m│\u001b[39m 19.86 km. \u001b[90m│\u001b[39m 1 hrs. 34 min. 38 sec. \u001b[90m│\u001b[39m 1.23x 😬 \u001b[90m│\u001b[39m\n\u001b[90m├───────────────────────────\u001b[39m\u001b[90m┼─────────┴───────────┴────────────────────────┴──────────┤\u001b[39m\n\u001b[90m│\u001b[39m 📍 \u001b[90m│\u001b[39m jae \u001b[90m│\u001b[39m\n\u001b[90m├───────────────────────────\u001b[39m\u001b[90m┼─────────────────────────────────────────────────────────┤\u001b[39m\n\u001b[90m│\u001b[39m 🔚 \u001b[90m│\u001b[39m baebae \u001b[90m│\u001b[39m\n\u001b[90m└───────────────────────────\u001b[39m\u001b[90m┴─────────────────────────────────────────────────────────┘\u001b[39m'; + validateTable(DistanceUnit.KILOMETER); + }); +}); From c6c2ff8399dfe1a98910ba41e55fc8ee3b8f1322 Mon Sep 17 00:00:00 2001 From: Jae Bradley Date: Tue, 12 Jun 2018 14:20:24 -0400 Subject: [PATCH 36/38] refactor(package): fix package generation scripts and version --- .npmignore | 1 + package.json | 13 ++++++++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/.npmignore b/.npmignore index 6b98dd7..9ab56da 100644 --- a/.npmignore +++ b/.npmignore @@ -7,6 +7,7 @@ coverage/** npm-debug.log commitlint.config.js *.test.js +**/__mocks__/** .DS_Store .eslintcache diff --git a/package.json b/package.json index df80569..636e90e 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "uber-cli", - "description": "Uber CLI", - "version": "0.0.3", + "description": "CLI for Uber price and time estimates", + "version": "0.0.0-development", "author": "Jae Bradley", "bin": { "uber": "build/executables/uber.js" @@ -40,7 +40,10 @@ }, "homepage": "https://github.com/jaebradley/uber-cli", "keywords": [ - "uber" + "uber", + "uber cli", + "uber price", + "uber time" ], "jest": { "testEnvironment": "node", @@ -61,10 +64,10 @@ "codecov": "codecov", "commitmsg": "commitlint -e $GIT_PARAMS", "build": "babel src/ -d build/ --delete-dir-on-start", - "build:prod": "BABEL_ENV=production npm run compile", + "build:prod": "BABEL_ENV=production npm run build", "lint": "eslint --ext .js .", "test": "jest", - "prepublishOnly": "npm run compile:prod", + "prepublishOnly": "npm run build:prod", "gc": "commit", "semantic-release": "semantic-release", "travis-deploy-once": "travis-deploy-once" From dac893dd8cf28f0742310a8982f222f122596f7c Mon Sep 17 00:00:00 2001 From: Jae Bradley Date: Tue, 12 Jun 2018 14:39:14 -0400 Subject: [PATCH 37/38] test(tables): fix failing table tests --- package-lock.json | 2 +- src/services/tables/price/build.test.js | 19 +++++++++++++++---- src/services/tables/time/build.test.js | 14 ++++++++++++-- 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index b70bd00..a2e4450 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "uber-cli", - "version": "0.0.3", + "version": "0.0.0-development", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/src/services/tables/price/build.test.js b/src/services/tables/price/build.test.js index 00e1593..f8e6532 100644 --- a/src/services/tables/price/build.test.js +++ b/src/services/tables/price/build.test.js @@ -25,6 +25,9 @@ describe('#build', () => { // tests use emojis and assumes process.platform = darwin // apologies in advance if this causes problems + const realProcess = global.process; + const mockedProcess = { platform: 'darwin' }; + const distance = { value: 12.34, unit: DistanceUnit.MILE, @@ -87,9 +90,17 @@ describe('#build', () => { end, }; + beforeEach(() => { + global.process = mockedProcess; + }); + + afterEach(() => { + global.process = realProcess; + }); + it('should build sorted table', () => { estimates = defaultEstimates; - expected = '\u001b[90m┌────────────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬────────────────────────\u001b[39m\u001b[90m┬──────────┐\u001b[39m\n\u001b[90m│\u001b[39m 🚘 \u001b[90m│\u001b[39m 💸 \u001b[90m│\u001b[39m 🔃 \u001b[90m│\u001b[39m ⏳ \u001b[90m│\u001b[39m 😬 Surge😬 \u001b[90m│\u001b[39m\n\u001b[90m├────────────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼────────────────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m third product \u001b[90m│\u001b[39m $6-$12 \u001b[90m│\u001b[39m 12.34 mi. \u001b[90m│\u001b[39m 1 hrs. 34 min. 38 sec. \u001b[90m│\u001b[39m 🚫 \u001b[90m│\u001b[39m\n\u001b[90m├────────────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼────────────────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m second product \u001b[90m│\u001b[39m $8-$16 \u001b[90m│\u001b[39m 12.34 mi. \u001b[90m│\u001b[39m 1 hrs. 34 min. 38 sec. \u001b[90m│\u001b[39m 🚫 \u001b[90m│\u001b[39m\n\u001b[90m├────────────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼────────────────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m first product \u001b[90m│\u001b[39m $10-$20 \u001b[90m│\u001b[39m 12.34 mi. \u001b[90m│\u001b[39m 1 hrs. 34 min. 38 sec. \u001b[90m│\u001b[39m 🚫 \u001b[90m│\u001b[39m\n\u001b[90m├────────────────\u001b[39m\u001b[90m┼─────────┴───────────┴────────────────────────┴──────────┤\u001b[39m\n\u001b[90m│\u001b[39m 📍 \u001b[90m│\u001b[39m jae \u001b[90m│\u001b[39m\n\u001b[90m├────────────────\u001b[39m\u001b[90m┼─────────────────────────────────────────────────────────┤\u001b[39m\n\u001b[90m│\u001b[39m 🔚 \u001b[90m│\u001b[39m baebae \u001b[90m│\u001b[39m\n\u001b[90m└────────────────\u001b[39m\u001b[90m┴─────────────────────────────────────────────────────────┘\u001b[39m'; + expected = '┌────────────────┬─────────┬───────────┬────────────────────────┬──────────┐\n│ 🚘 │ 💸 │ 🔃 │ ⏳ │ 😬 Surge😬 │\n├────────────────┼─────────┼───────────┼────────────────────────┼──────────┤\n│ third product │ $6-$12 │ 12.34 mi. │ 1 hrs. 34 min. 38 sec. │ 🚫 │\n├────────────────┼─────────┼───────────┼────────────────────────┼──────────┤\n│ second product │ $8-$16 │ 12.34 mi. │ 1 hrs. 34 min. 38 sec. │ 🚫 │\n├────────────────┼─────────┼───────────┼────────────────────────┼──────────┤\n│ first product │ $10-$20 │ 12.34 mi. │ 1 hrs. 34 min. 38 sec. │ 🚫 │\n├────────────────┼─────────┴───────────┴────────────────────────┴──────────┤\n│ 📍 │ jae │\n├────────────────┼─────────────────────────────────────────────────────────┤\n│ 🔚 │ baebae │\n└────────────────┴─────────────────────────────────────────────────────────┘'; validateTable(DistanceUnit.MILE); }); @@ -105,13 +116,13 @@ describe('#build', () => { end, }; - expected = '\u001b[90m┌────────────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬────────────────────────\u001b[39m\u001b[90m┬──────────┐\u001b[39m\n\u001b[90m│\u001b[39m 🚘 \u001b[90m│\u001b[39m 💸 \u001b[90m│\u001b[39m 🔃 \u001b[90m│\u001b[39m ⏳ \u001b[90m│\u001b[39m 😬 Surge😬 \u001b[90m│\u001b[39m\n\u001b[90m├────────────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼────────────────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m third product \u001b[90m│\u001b[39m $6-$12 \u001b[90m│\u001b[39m 12.34 mi. \u001b[90m│\u001b[39m 1 hrs. 34 min. 38 sec. \u001b[90m│\u001b[39m 🚫 \u001b[90m│\u001b[39m\n\u001b[90m├────────────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼────────────────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m second product \u001b[90m│\u001b[39m $8-$16 \u001b[90m│\u001b[39m 12.34 mi. \u001b[90m│\u001b[39m 1 hrs. 34 min. 38 sec. \u001b[90m│\u001b[39m 🚫 \u001b[90m│\u001b[39m\n\u001b[90m├────────────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼────────────────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m first product \u001b[90m│\u001b[39m $10-$20 \u001b[90m│\u001b[39m 12.34 mi. \u001b[90m│\u001b[39m 1 hrs. 34 min. 38 sec. \u001b[90m│\u001b[39m 🚫 \u001b[90m│\u001b[39m\n\u001b[90m├────────────────\u001b[39m\u001b[90m┼─────────┴───────────┴────────────────────────┴──────────┤\u001b[39m\n\u001b[90m│\u001b[39m 📍 \u001b[90m│\u001b[39m jae \u001b[90m│\u001b[39m\n\u001b[90m├────────────────\u001b[39m\u001b[90m┼─────────────────────────────────────────────────────────┤\u001b[39m\n\u001b[90m│\u001b[39m 🔚 \u001b[90m│\u001b[39m baebae \u001b[90m│\u001b[39m\n\u001b[90m└────────────────\u001b[39m\u001b[90m┴─────────────────────────────────────────────────────────┘\u001b[39m'; + expected = '┌────────────────┬─────────┬───────────┬────────────────────────┬──────────┐\n│ 🚘 │ 💸 │ 🔃 │ ⏳ │ 😬 Surge😬 │\n├────────────────┼─────────┼───────────┼────────────────────────┼──────────┤\n│ third product │ $6-$12 │ 12.34 mi. │ 1 hrs. 34 min. 38 sec. │ 🚫 │\n├────────────────┼─────────┼───────────┼────────────────────────┼──────────┤\n│ second product │ $8-$16 │ 12.34 mi. │ 1 hrs. 34 min. 38 sec. │ 🚫 │\n├────────────────┼─────────┼───────────┼────────────────────────┼──────────┤\n│ first product │ $10-$20 │ 12.34 mi. │ 1 hrs. 34 min. 38 sec. │ 🚫 │\n├────────────────┼─────────┴───────────┴────────────────────────┴──────────┤\n│ 📍 │ jae │\n├────────────────┼─────────────────────────────────────────────────────────┤\n│ 🔚 │ baebae │\n└────────────────┴─────────────────────────────────────────────────────────┘'; validateTable(DistanceUnit.MILE); }); it('should build table converting to kilometers', () => { estimates = defaultEstimates; - expected = '\u001b[90m┌────────────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬────────────────────────\u001b[39m\u001b[90m┬──────────┐\u001b[39m\n\u001b[90m│\u001b[39m 🚘 \u001b[90m│\u001b[39m 💸 \u001b[90m│\u001b[39m 🔃 \u001b[90m│\u001b[39m ⏳ \u001b[90m│\u001b[39m 😬 Surge😬 \u001b[90m│\u001b[39m\n\u001b[90m├────────────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼────────────────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m third product \u001b[90m│\u001b[39m $6-$12 \u001b[90m│\u001b[39m 19.86 km. \u001b[90m│\u001b[39m 1 hrs. 34 min. 38 sec. \u001b[90m│\u001b[39m 🚫 \u001b[90m│\u001b[39m\n\u001b[90m├────────────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼────────────────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m second product \u001b[90m│\u001b[39m $8-$16 \u001b[90m│\u001b[39m 19.86 km. \u001b[90m│\u001b[39m 1 hrs. 34 min. 38 sec. \u001b[90m│\u001b[39m 🚫 \u001b[90m│\u001b[39m\n\u001b[90m├────────────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼────────────────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m first product \u001b[90m│\u001b[39m $10-$20 \u001b[90m│\u001b[39m 19.86 km. \u001b[90m│\u001b[39m 1 hrs. 34 min. 38 sec. \u001b[90m│\u001b[39m 🚫 \u001b[90m│\u001b[39m\n\u001b[90m├────────────────\u001b[39m\u001b[90m┼─────────┴───────────┴────────────────────────┴──────────┤\u001b[39m\n\u001b[90m│\u001b[39m 📍 \u001b[90m│\u001b[39m jae \u001b[90m│\u001b[39m\n\u001b[90m├────────────────\u001b[39m\u001b[90m┼─────────────────────────────────────────────────────────┤\u001b[39m\n\u001b[90m│\u001b[39m 🔚 \u001b[90m│\u001b[39m baebae \u001b[90m│\u001b[39m\n\u001b[90m└────────────────\u001b[39m\u001b[90m┴─────────────────────────────────────────────────────────┘\u001b[39m'; + expected = '┌────────────────┬─────────┬───────────┬────────────────────────┬──────────┐\n│ 🚘 │ 💸 │ 🔃 │ ⏳ │ 😬 Surge😬 │\n├────────────────┼─────────┼───────────┼────────────────────────┼──────────┤\n│ third product │ $6-$12 │ 19.86 km. │ 1 hrs. 34 min. 38 sec. │ 🚫 │\n├────────────────┼─────────┼───────────┼────────────────────────┼──────────┤\n│ second product │ $8-$16 │ 19.86 km. │ 1 hrs. 34 min. 38 sec. │ 🚫 │\n├────────────────┼─────────┼───────────┼────────────────────────┼──────────┤\n│ first product │ $10-$20 │ 19.86 km. │ 1 hrs. 34 min. 38 sec. │ 🚫 │\n├────────────────┼─────────┴───────────┴────────────────────────┴──────────┤\n│ 📍 │ jae │\n├────────────────┼─────────────────────────────────────────────────────────┤\n│ 🔚 │ baebae │\n└────────────────┴─────────────────────────────────────────────────────────┘'; validateTable(DistanceUnit.KILOMETER); }); @@ -161,7 +172,7 @@ describe('#build', () => { end, }; - expected = '\u001b[90m┌───────────────────────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬────────────────────────\u001b[39m\u001b[90m┬──────────┐\u001b[39m\n\u001b[90m│\u001b[39m 🚘 \u001b[90m│\u001b[39m 💸 \u001b[90m│\u001b[39m 🔃 \u001b[90m│\u001b[39m ⏳ \u001b[90m│\u001b[39m 😬 Surge😬 \u001b[90m│\u001b[39m\n\u001b[90m├───────────────────────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼────────────────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m third product with surge \u001b[90m│\u001b[39m $6-$12 \u001b[90m│\u001b[39m 19.86 km. \u001b[90m│\u001b[39m 1 hrs. 34 min. 38 sec. \u001b[90m│\u001b[39m 3.45x 😬 \u001b[90m│\u001b[39m\n\u001b[90m├───────────────────────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼────────────────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m second product with surge \u001b[90m│\u001b[39m $8-$16 \u001b[90m│\u001b[39m 19.86 km. \u001b[90m│\u001b[39m 1 hrs. 34 min. 38 sec. \u001b[90m│\u001b[39m 2.34x 😬 \u001b[90m│\u001b[39m\n\u001b[90m├───────────────────────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼────────────────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m first product with surge \u001b[90m│\u001b[39m $10-$20 \u001b[90m│\u001b[39m 19.86 km. \u001b[90m│\u001b[39m 1 hrs. 34 min. 38 sec. \u001b[90m│\u001b[39m 1.23x 😬 \u001b[90m│\u001b[39m\n\u001b[90m├───────────────────────────\u001b[39m\u001b[90m┼─────────┴───────────┴────────────────────────┴──────────┤\u001b[39m\n\u001b[90m│\u001b[39m 📍 \u001b[90m│\u001b[39m jae \u001b[90m│\u001b[39m\n\u001b[90m├───────────────────────────\u001b[39m\u001b[90m┼─────────────────────────────────────────────────────────┤\u001b[39m\n\u001b[90m│\u001b[39m 🔚 \u001b[90m│\u001b[39m baebae \u001b[90m│\u001b[39m\n\u001b[90m└───────────────────────────\u001b[39m\u001b[90m┴─────────────────────────────────────────────────────────┘\u001b[39m'; + expected = '┌───────────────────────────┬─────────┬───────────┬────────────────────────┬──────────┐\n│ 🚘 │ 💸 │ 🔃 │ ⏳ │ 😬 Surge😬 │\n├───────────────────────────┼─────────┼───────────┼────────────────────────┼──────────┤\n│ third product with surge │ $6-$12 │ 19.86 km. │ 1 hrs. 34 min. 38 sec. │ 3.45x 😬 │\n├───────────────────────────┼─────────┼───────────┼────────────────────────┼──────────┤\n│ second product with surge │ $8-$16 │ 19.86 km. │ 1 hrs. 34 min. 38 sec. │ 2.34x 😬 │\n├───────────────────────────┼─────────┼───────────┼────────────────────────┼──────────┤\n│ first product with surge │ $10-$20 │ 19.86 km. │ 1 hrs. 34 min. 38 sec. │ 1.23x 😬 │\n├───────────────────────────┼─────────┴───────────┴────────────────────────┴──────────┤\n│ 📍 │ jae │\n├───────────────────────────┼─────────────────────────────────────────────────────────┤\n│ 🔚 │ baebae │\n└───────────────────────────┴─────────────────────────────────────────────────────────┘'; validateTable(DistanceUnit.KILOMETER); }); }); diff --git a/src/services/tables/time/build.test.js b/src/services/tables/time/build.test.js index 27233f1..22a43c9 100644 --- a/src/services/tables/time/build.test.js +++ b/src/services/tables/time/build.test.js @@ -5,8 +5,18 @@ import build from './build'; jest.unmock('convert-units'); describe('#build', () => { + const realProcess = global.process; + const mockedProcess = { platform: 'darwin' }; const location = { name: 'foobar' }; + beforeEach(() => { + global.process = mockedProcess; + }); + + afterEach(() => { + global.process = realProcess; + }); + // both tests use emojis and assumes process.platform = darwin // apologies in advance if this causes problems @@ -25,7 +35,7 @@ describe('#build', () => { productName: 'third product', }, ]; - const expected = '\u001b[90m┌─────────────────────────┐\u001b[39m\n\u001b[90m│\u001b[39m 📍 foobar \u001b[90m│\u001b[39m\n\u001b[90m├────────\u001b[39m\u001b[90m┬────────────────┤\u001b[39m\n\u001b[90m│\u001b[39m ⏳ \u001b[90m│\u001b[39m 🚘 \u001b[90m│\u001b[39m\n\u001b[90m├────────\u001b[39m\u001b[90m┼────────────────┤\u001b[39m\n\u001b[90m│\u001b[39m 0 sec. \u001b[90m│\u001b[39m third product \u001b[90m│\u001b[39m\n\u001b[90m├────────\u001b[39m\u001b[90m┼────────────────┤\u001b[39m\n\u001b[90m│\u001b[39m 1 min. \u001b[90m│\u001b[39m second product \u001b[90m│\u001b[39m\n\u001b[90m├────────\u001b[39m\u001b[90m┼────────────────┤\u001b[39m\n\u001b[90m│\u001b[39m 2 min. \u001b[90m│\u001b[39m first product \u001b[90m│\u001b[39m\n\u001b[90m└────────\u001b[39m\u001b[90m┴────────────────┘\u001b[39m'; + const expected = '┌─────────────────────────┐\n│ 📍 foobar │\n├────────┬────────────────┤\n│ ⏳ │ 🚘 │\n├────────┼────────────────┤\n│ 0 sec. │ third product │\n├────────┼────────────────┤\n│ 1 min. │ second product │\n├────────┼────────────────┤\n│ 2 min. │ first product │\n└────────┴────────────────┘'; expect(build({ estimates, location })).toEqual(expected); }); @@ -44,7 +54,7 @@ describe('#build', () => { productName: 'third product', }, ]; - const expected = '\u001b[90m┌───────────────────────────────────────────────────────┐\u001b[39m\n\u001b[90m│\u001b[39m 📍 foobar \u001b[90m│\u001b[39m\n\u001b[90m├────────\u001b[39m\u001b[90m┬──────────────────────────────────────────────┤\u001b[39m\n\u001b[90m│\u001b[39m ⏳ \u001b[90m│\u001b[39m 🚘 \u001b[90m│\u001b[39m\n\u001b[90m├────────\u001b[39m\u001b[90m┼──────────────────────────────────────────────┤\u001b[39m\n\u001b[90m│\u001b[39m 2 min. \u001b[90m│\u001b[39m first product, second product, third product \u001b[90m│\u001b[39m\n\u001b[90m└────────\u001b[39m\u001b[90m┴──────────────────────────────────────────────┘\u001b[39m'; + const expected = '┌───────────────────────────────────────────────────────┐\n│ 📍 foobar │\n├────────┬──────────────────────────────────────────────┤\n│ ⏳ │ 🚘 │\n├────────┼──────────────────────────────────────────────┤\n│ 2 min. │ first product, second product, third product │\n└────────┴──────────────────────────────────────────────┘'; expect(build({ estimates, location })).toEqual(expected); }); }); From 22f4f4135bf112d6de1869dd32e5bacc2d0a1180 Mon Sep 17 00:00:00 2001 From: Jae Bradley Date: Tue, 12 Jun 2018 14:52:32 -0400 Subject: [PATCH 38/38] test(tables): fix failing table tests --- src/services/symbols.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/symbols.js b/src/services/symbols.js index 4126c6a..b3619de 100644 --- a/src/services/symbols.js +++ b/src/services/symbols.js @@ -24,6 +24,6 @@ const TEXT = Object.freeze({ MAXIMUM_DISTANCE: '100', }); -const symbols = ['darwin'].indexOf(process.platform) >= 0 ? EMOJIS : TEXT; +const symbols = ['darwin', 'linux'].indexOf(process.platform) >= 0 ? EMOJIS : TEXT; export default symbols;