From f06a6f4e789e225e86d5990b396600c000054672 Mon Sep 17 00:00:00 2001 From: jebbs Date: Tue, 14 Jan 2020 16:37:50 +0800 Subject: [PATCH] migrate to typescript, with fixes --- .gitignore | 154 +- images/extnsion.png | Bin 25109 -> 0 bytes manifest.json | 45 - package-lock.json | 4433 +++++++++++++++++ package.json | 17 + readme.md | 11 + scripts/background/helpers.js | 3 - scripts/content/content.js | 114 - scripts/shared/common.js | 10 - scripts/shared/tools.js | 69 - .../actions.js => src/background/actions.ts | 82 +- src/background/caches.ts | 15 + src/background/common.ts | 6 + .../background/extractor.ts | 41 +- src/background/index.ts | 14 + .../logger.js => src/background/logger.ts | 38 +- .../background/messaging.ts | 44 +- .../result.js => src/background/result.ts | 14 +- .../background/signiture.ts | 13 +- .../task.js => src/background/task.ts | 61 +- src/background/tools.ts | 61 + src/common.ts | 11 + src/content/actions.ts | 73 + src/content/index.ts | 45 + popup/tip.js => src/popup/index.ts | 2 + .../assets}/bootstrap.min.css | 0 {images => template/assets}/console.png | Bin popup/tip.html => template/html/popup.html | 10 +- icon.png => template/icon.png | Bin template/manifest.json | 34 + tsconfig.json | 12 + webpack.config.js | 33 + 32 files changed, 5071 insertions(+), 394 deletions(-) delete mode 100644 images/extnsion.png delete mode 100755 manifest.json create mode 100644 package-lock.json create mode 100644 package.json delete mode 100644 scripts/background/helpers.js delete mode 100644 scripts/content/content.js delete mode 100644 scripts/shared/common.js delete mode 100644 scripts/shared/tools.js rename scripts/background/actions.js => src/background/actions.ts (55%) create mode 100644 src/background/caches.ts create mode 100644 src/background/common.ts rename scripts/background/extractor.js => src/background/extractor.ts (81%) create mode 100644 src/background/index.ts rename scripts/background/logger.js => src/background/logger.ts (68%) rename scripts/background/messaging.js => src/background/messaging.ts (63%) rename scripts/background/result.js => src/background/result.ts (80%) rename scripts/background/signiture.js => src/background/signiture.ts (92%) rename scripts/background/task.js => src/background/task.ts (54%) create mode 100644 src/background/tools.ts create mode 100644 src/common.ts create mode 100644 src/content/actions.ts create mode 100644 src/content/index.ts rename popup/tip.js => src/popup/index.ts (96%) rename {popup/styles => template/assets}/bootstrap.min.css (100%) rename {images => template/assets}/console.png (100%) rename popup/tip.html => template/html/popup.html (84%) rename icon.png => template/icon.png (100%) create mode 100755 template/manifest.json create mode 100644 tsconfig.json create mode 100644 webpack.config.js diff --git a/.gitignore b/.gitignore index fafff2e..c09fa11 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,154 @@ +# File created using '.gitignore Generator' for Visual Studio Code: https://bit.ly/vscode-gig + +# Created by https://www.gitignore.io/api/visualstudiocode,macos,node +# Edit at https://www.gitignore.io/?templates=visualstudiocode,macos,node + +### macOS ### +# General .DS_Store -Thumbs.db +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### Node ### +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# 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 +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# TypeScript v1 declaration files +typings/ + +# TypeScript cache +*.tsbuildinfo + +# 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 +.env.test + +# parcel-bundler cache (https://parceljs.org/) +.cache + +# next.js build output +.next + +# nuxt.js build output +.nuxt + +# rollup.js default build output +dist/ + +# Uncomment the public line if your project uses Gatsby +# https://nextjs.org/blog/next-9-1#public-directory-support +# https://create-react-app.dev/docs/using-the-public-folder/#docsNav +# public + +# Storybook build outputs +.out +.storybook-out + +# vuepress build output +.vuepress/dist + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# Temporary folders +tmp/ +temp/ + +### VisualStudioCode ### +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json + +### VisualStudioCode Patch ### +# Ignore all local history of files +.history + +# End of https://www.gitignore.io/api/visualstudiocode,macos,node + +# Custom rules (everything added below won't be overriden by 'Generate .gitignore File' if you use 'Update' option) + diff --git a/images/extnsion.png b/images/extnsion.png deleted file mode 100644 index 1c55dacc78bc18f877df4485773455cd7664f136..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25109 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 z 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 2.1.2 < 3" + } + }, + "ignore-walk": { + "version": "3.0.3", + "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.4", + "bundled": true, + "dev": true, + "optional": true + }, + "ini": { + "version": "1.3.5", + "bundled": true, + "dev": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "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, + "optional": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true, + "optional": true + }, + "minipass": { + "version": "2.9.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.3.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.9.0" + } + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "needle": { + "version": "2.4.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "debug": "^3.2.6", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.14.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4.4.2" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "npm-normalize-package-bin": "^1.0.1" + } + }, + "npm-normalize-package-bin": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "npm-packlist": { + "version": "1.4.7", + "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, + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "optional": 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.1", + "bundled": true, + "dev": true, + "optional": true + }, + "rc": { + "version": "1.2.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "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.7.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true, + "dev": true, + "optional": 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.7.1", + "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, + "optional": 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, + "optional": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "tar": { + "version": "4.4.13", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.8.6", + "minizlib": "^1.2.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.3" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "wide-align": { + "version": "1.1.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "yallist": { + "version": "3.1.1", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "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-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" + } + } + } + }, + "global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "dev": true, + "requires": { + "global-prefix": "^3.0.0" + }, + "dependencies": { + "global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "dev": true, + "requires": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + } + } + } + }, + "global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "dev": true, + "requires": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + } + }, + "globby": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-7.1.1.tgz", + "integrity": "sha1-+yzP+UAfhgCUXfral0QMypcrhoA=", + "dev": true, + "requires": { + "array-union": "^1.0.1", + "dir-glob": "^2.0.0", + "glob": "^7.1.2", + "ignore": "^3.3.5", + "pify": "^3.0.0", + "slash": "^1.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 + } + } + }, + "graceful-fs": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", + "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 + }, + "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" + } + }, + "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": { + "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" + } + } + } + }, + "hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "dev": true, + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "homedir-polyfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "dev": true, + "requires": { + "parse-passwd": "^1.0.0" + } + }, + "https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", + "dev": true + }, + "ieee754": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", + "dev": true + }, + "iferr": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", + "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", + "dev": true + }, + "ignore": { + "version": "3.3.10", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", + "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", + "dev": true + }, + "import-local": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", + "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", + "dev": true, + "requires": { + "pkg-dir": "^3.0.0", + "resolve-cwd": "^2.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "infer-owner": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", + "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", + "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.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "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 + }, + "interpret": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz", + "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==", + "dev": true + }, + "invert-kv": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", + "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", + "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" + }, + "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-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, + "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-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" + }, + "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-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": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "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 + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "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" + } + } + } + }, + "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" + } + }, + "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-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 + }, + "is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "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": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "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-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "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 + } + } + }, + "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 + }, + "lcid": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", + "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", + "dev": true, + "requires": { + "invert-kv": "^2.0.0" + } + }, + "loader-runner": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", + "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", + "dev": true + }, + "loader-utils": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", + "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^2.0.0", + "json5": "^1.0.1" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "requires": { + "yallist": "^3.0.2" + } + }, + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "mamacro": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/mamacro/-/mamacro-0.0.3.tgz", + "integrity": "sha512-qMEwh+UujcQ+kbz3T6V+wAmO2U8veoq2w+3wY8MquqwVA3jChfwY+Tk52GZKDfACEPjuZ7r2oJLejwpt8jtwTA==", + "dev": true + }, + "map-age-cleaner": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", + "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", + "dev": true, + "requires": { + "p-defer": "^1.0.0" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, + "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" + } + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "mem": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", + "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", + "dev": true, + "requires": { + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^2.0.0", + "p-is-promise": "^2.0.0" + } + }, + "memory-fs": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", + "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", + "dev": true, + "requires": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + }, + "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" + } + }, + "miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", + "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 + }, + "mississippi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", + "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", + "dev": true, + "requires": { + "concat-stream": "^1.5.0", + "duplexify": "^3.4.2", + "end-of-stream": "^1.1.0", + "flush-write-stream": "^1.0.0", + "from2": "^2.1.0", + "parallel-transform": "^1.1.0", + "pump": "^3.0.0", + "pumpify": "^1.3.3", + "stream-each": "^1.1.0", + "through2": "^2.0.0" + } + }, + "mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "dev": true, + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "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" + } + }, + "move-concurrently": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", + "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", + "dev": true, + "requires": { + "aproba": "^1.1.1", + "copy-concurrently": "^1.0.0", + "fs-write-stream-atomic": "^1.0.8", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.3" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "nan": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", + "dev": true, + "optional": true + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + } + }, + "neo-async": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", + "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node-libs-browser": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", + "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", + "dev": true, + "requires": { + "assert": "^1.1.1", + "browserify-zlib": "^0.2.0", + "buffer": "^4.3.0", + "console-browserify": "^1.1.0", + "constants-browserify": "^1.0.0", + "crypto-browserify": "^3.11.0", + "domain-browser": "^1.1.1", + "events": "^3.0.0", + "https-browserify": "^1.0.0", + "os-browserify": "^0.3.0", + "path-browserify": "0.0.1", + "process": "^0.11.10", + "punycode": "^1.2.4", + "querystring-es3": "^0.2.0", + "readable-stream": "^2.3.3", + "stream-browserify": "^2.0.1", + "stream-http": "^2.7.2", + "string_decoder": "^1.0.0", + "timers-browserify": "^2.0.4", + "tty-browserify": "0.0.0", + "url": "^0.11.0", + "util": "^0.11.0", + "vm-browserify": "^1.0.1" + }, + "dependencies": { + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + } + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "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" + } + }, + "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" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "object-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" + } + }, + "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" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", + "dev": true + }, + "os-locale": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", + "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", + "dev": true, + "requires": { + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" + } + }, + "p-defer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", + "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", + "dev": true + }, + "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": "2.1.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", + "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==", + "dev": true + }, + "p-limit": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz", + "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "pako": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.10.tgz", + "integrity": "sha512-0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw==", + "dev": true + }, + "parallel-transform": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", + "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", + "dev": true, + "requires": { + "cyclist": "^1.0.1", + "inherits": "^2.0.3", + "readable-stream": "^2.1.5" + } + }, + "parse-asn1": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", + "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", + "dev": true, + "requires": { + "asn1.js": "^4.0.0", + "browserify-aes": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, + "parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", + "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-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", + "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", + "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": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "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.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "requires": { + "pify": "^3.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + } + } + }, + "pbkdf2": { + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", + "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", + "dev": true, + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "picomatch": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.1.tgz", + "integrity": "sha512-ISBaA8xQNmwELC7eOjqFKMESB2VIqt4PPDD0nsS95b/9dZXvVKOlz9keMSnoGGKcOHXfTvDD6WMaRoSc9UuhRA==", + "dev": true + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, + "pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "requires": { + "find-up": "^3.0.0" + } + }, + "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 + }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", + "dev": true + }, + "prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "dev": true + }, + "public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "pumpify": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", + "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", + "dev": true, + "requires": { + "duplexify": "^3.6.0", + "inherits": "^2.0.3", + "pump": "^2.0.0" + }, + "dependencies": { + "pump": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", + "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + } + } + }, + "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 + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "dev": true + }, + "querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", + "dev": true + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "dev": true, + "requires": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "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.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + } + }, + "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" + } + }, + "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.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", + "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 + }, + "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": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "resolve": { + "version": "1.14.2", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.14.2.tgz", + "integrity": "sha512-EjlOBLBO1kxsUxsKjLt7TAECyKW6fOh1VRkykQkKGzcBbjjPIxBqGh0jf7GJ3k/f5mxMqW3htMD3WdTUVtW8HQ==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "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" + } + }, + "resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", + "dev": true, + "requires": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + }, + "dependencies": { + "global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "dev": true, + "requires": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + } + } + } + }, + "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-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 + }, + "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 + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "run-queue": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", + "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", + "dev": true, + "requires": { + "aproba": "^1.1.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "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" + } + }, + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "serialize-javascript": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz", + "integrity": "sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==", + "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-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "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" + } + } + } + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", + "dev": true + }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "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 + }, + "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 + }, + "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" + } + } + } + }, + "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" + }, + "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" + } + } + } + }, + "source-list-map": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", + "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", + "dev": true + }, + "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.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "dev": true, + "requires": { + "atob": "^2.1.2", + "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.5.16", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.16.tgz", + "integrity": "sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + }, + "dependencies": { + "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-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 + }, + "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" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "ssri": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", + "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", + "dev": true, + "requires": { + "figgy-pudding": "^3.5.1" + } + }, + "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" + } + } + } + }, + "stream-browserify": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", + "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", + "dev": true, + "requires": { + "inherits": "~2.0.1", + "readable-stream": "^2.0.2" + } + }, + "stream-each": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", + "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "stream-shift": "^1.0.0" + } + }, + "stream-http": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", + "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", + "dev": true, + "requires": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "to-arraybuffer": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "stream-shift": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", + "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "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" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "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 + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "tapable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", + "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", + "dev": true + }, + "terser": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.2.tgz", + "integrity": "sha512-6FUjJdY2i3WZAtYBtnV06OOcOfzl+4hSKYE9wgac8rkLRBToPDDrBB2AcHwQD/OKDxbnvhVy2YgOPWO2SsKWqg==", + "dev": true, + "requires": { + "commander": "^2.20.0", + "source-map": "~0.6.1", + "source-map-support": "~0.5.12" + }, + "dependencies": { + "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 + } + } + }, + "terser-webpack-plugin": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz", + "integrity": "sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA==", + "dev": true, + "requires": { + "cacache": "^12.0.2", + "find-cache-dir": "^2.1.0", + "is-wsl": "^1.1.0", + "schema-utils": "^1.0.0", + "serialize-javascript": "^2.1.2", + "source-map": "^0.6.1", + "terser": "^4.1.2", + "webpack-sources": "^1.4.0", + "worker-farm": "^1.7.0" + }, + "dependencies": { + "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 + } + } + }, + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "timers-browserify": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", + "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", + "dev": true, + "requires": { + "setimmediate": "^1.0.4" + } + }, + "to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", + "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" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex": { + "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" + } + }, + "ts-loader": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-6.2.1.tgz", + "integrity": "sha512-Dd9FekWuABGgjE1g0TlQJ+4dFUfYGbYcs52/HQObE0ZmUNjQlmLAS7xXsSzy23AMaMwipsx5sNHvoEpT2CZq1g==", + "dev": true, + "requires": { + "chalk": "^2.3.0", + "enhanced-resolve": "^4.0.0", + "loader-utils": "^1.0.2", + "micromatch": "^4.0.0", + "semver": "^6.0.0" + }, + "dependencies": { + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + } + } + }, + "tslib": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", + "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", + "dev": true + }, + "tslint": { + "version": "5.20.1", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.20.1.tgz", + "integrity": "sha512-EcMxhzCFt8k+/UP5r8waCf/lzmeSyVlqxqMEDQE7rWYiQky8KpIBz1JAoYXfROHrPZ1XXd43q8yQnULOLiBRQg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "builtin-modules": "^1.1.1", + "chalk": "^2.3.0", + "commander": "^2.12.1", + "diff": "^4.0.1", + "glob": "^7.1.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "resolve": "^1.3.2", + "semver": "^5.3.0", + "tslib": "^1.8.0", + "tsutils": "^2.29.0" + } + }, + "tsutils": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", + "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + }, + "tty-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", + "dev": true + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "typescript": { + "version": "3.7.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.4.tgz", + "integrity": "sha512-A25xv5XCtarLwXpcDNZzCGvW2D1S3/bACratYBx2sax8PefsFhlYmkQicKHvpYflFS8if4zne5zT5kpJ7pzuvw==", + "dev": true + }, + "union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + } + }, + "unique-filename": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", + "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", + "dev": true, + "requires": { + "unique-slug": "^2.0.0" + } + }, + "unique-slug": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", + "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4" + } + }, + "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 + } + } + }, + "upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", + "dev": true + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, + "requires": { + "punycode": "^2.1.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": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "dev": true, + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + }, + "dependencies": { + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", + "dev": true + } + } + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true + }, + "util": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", + "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", + "dev": true, + "requires": { + "inherits": "2.0.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "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 + }, + "uuid": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz", + "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==", + "dev": true + }, + "v8-compile-cache": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz", + "integrity": "sha512-CNmdbwQMBjwr9Gsmohvm0pbL954tJrNzf6gWL3K+QMQf00PF7ERGrEiLgjuU3mKreLC2MeGhUsNV9ybTbLgd3w==", + "dev": true + }, + "vm-browserify": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", + "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", + "dev": true + }, + "watchpack": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz", + "integrity": "sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA==", + "dev": true, + "requires": { + "chokidar": "^2.0.2", + "graceful-fs": "^4.1.2", + "neo-async": "^2.5.0" + } + }, + "webpack": { + "version": "4.41.5", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.41.5.tgz", + "integrity": "sha512-wp0Co4vpyumnp3KlkmpM5LWuzvZYayDwM2n17EHFr4qxBBbRokC7DJawPJC7TfSFZ9HZ6GsdH40EBj4UV0nmpw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/helper-module-context": "1.8.5", + "@webassemblyjs/wasm-edit": "1.8.5", + "@webassemblyjs/wasm-parser": "1.8.5", + "acorn": "^6.2.1", + "ajv": "^6.10.2", + "ajv-keywords": "^3.4.1", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^4.1.0", + "eslint-scope": "^4.0.3", + "json-parse-better-errors": "^1.0.2", + "loader-runner": "^2.4.0", + "loader-utils": "^1.2.3", + "memory-fs": "^0.4.1", + "micromatch": "^3.1.10", + "mkdirp": "^0.5.1", + "neo-async": "^2.6.1", + "node-libs-browser": "^2.2.1", + "schema-utils": "^1.0.0", + "tapable": "^1.1.3", + "terser-webpack-plugin": "^1.4.3", + "watchpack": "^1.6.0", + "webpack-sources": "^1.4.1" + } + }, + "webpack-cli": { + "version": "3.3.10", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-3.3.10.tgz", + "integrity": "sha512-u1dgND9+MXaEt74sJR4PR7qkPxXUSQ0RXYq8x1L6Jg1MYVEmGPrH6Ah6C4arD4r0J1P5HKjRqpab36k0eIzPqg==", + "dev": true, + "requires": { + "chalk": "2.4.2", + "cross-spawn": "6.0.5", + "enhanced-resolve": "4.1.0", + "findup-sync": "3.0.0", + "global-modules": "2.0.0", + "import-local": "2.0.0", + "interpret": "1.2.0", + "loader-utils": "1.2.3", + "supports-color": "6.1.0", + "v8-compile-cache": "2.0.3", + "yargs": "13.2.4" + }, + "dependencies": { + "enhanced-resolve": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz", + "integrity": "sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "memory-fs": "^0.4.0", + "tapable": "^1.0.0" + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "webpack-log": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-2.0.0.tgz", + "integrity": "sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==", + "dev": true, + "requires": { + "ansi-colors": "^3.0.0", + "uuid": "^3.3.2" + } + }, + "webpack-sources": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", + "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", + "dev": true, + "requires": { + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" + }, + "dependencies": { + "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 + } + } + }, + "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" + } + }, + "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 + }, + "worker-farm": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", + "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", + "dev": true, + "requires": { + "errno": "~0.1.7" + } + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "dev": true + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "yargs": { + "version": "13.2.4", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.2.4.tgz", + "integrity": "sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "os-locale": "^3.1.0", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.0" + } + }, + "yargs-parser": { + "version": "13.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", + "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..d3e7b1d --- /dev/null +++ b/package.json @@ -0,0 +1,17 @@ +{ + "name": "data-extractor", + "scripts": { + "dev": "webpack --mode=development --devtool=inline-source-map --watch", + "prod": "webpack --mode=production" + }, + "devDependencies": { + "@types/chrome": "0.0.91", + "@types/node": "^13.1.6", + "copy-webpack-plugin": "^5.1.1", + "ts-loader": "^6.2.1", + "tslint": "^5.20.1", + "typescript": "^3.7.4", + "webpack": "^4.41.5", + "webpack-cli": "^3.3.10" + } +} diff --git a/readme.md b/readme.md index 58162f8..be9f6d9 100644 --- a/readme.md +++ b/readme.md @@ -170,4 +170,15 @@ Open the popup window, upload the saved state file. Then, and in the backgoud co ```js e = new Extractor().load(); +``` + +## Developpment + +Clone this project and execute: + +```sh +npm i +npm run prod +# or +npm run dev ``` \ No newline at end of file diff --git a/scripts/background/helpers.js b/scripts/background/helpers.js deleted file mode 100644 index ea8aea1..0000000 --- a/scripts/background/helpers.js +++ /dev/null @@ -1,3 +0,0 @@ -function $(...args) { - return new Extractor().task(...args).start(); -} \ No newline at end of file diff --git a/scripts/content/content.js b/scripts/content/content.js deleted file mode 100644 index ad874bf..0000000 --- a/scripts/content/content.js +++ /dev/null @@ -1,114 +0,0 @@ -(function () { - let asleep = false; - chrome.runtime.onMessage.addListener( - function (request, sender, sendResponse) { - if (!request.action) return; - if (asleep && ACTION_WAKEUP != request.action) { - sendResponse && sendResponse(undefined); - return; - } - // console.log("Recieved request:",request); - doAction(request, sender).then(r => sendResponse && sendResponse(r)); - // return true to indicate you wish to send a response asynchronously - return true; - } - ); - - async function doAction(request, sender) { - switch (request.action) { - case ACTION_EXTRACT: - let data = extract(request.itemsSelector, request.fieldSelectors); - return data; - case ACTION_GOTO_URL: - window.location.replace(request.url); - // should not recieve any request until the page & script reload - asleep = true; - return request.url; - case ACTION_REPORT_IN: - return request.action; - case ACTION_QUERY_URL: - return window.location.href; - case ACTION_SCROLL_BOTTOM: - return executeUntil( - () => window.scrollTo(0, document.body.clientHeight), - () => document.body.clientHeight - window.scrollY - window.innerHeight < 20, - "Scroll to page bottom...", - 1000, - 10 - ) - case ACTION_SLEEP: - asleep = true; - return "Content script is sleeping."; - case ACTION_WAKEUP: - asleep = false; - return "Content script is available."; - default: - break; - } - } - - function extract(itemsSelector, fieldSelectors) { - // since some elements may be loaded asynchronously. - // if one field is never found, we should return undefined, - // so that senders can detect to retry until elements loaded. - // If user writes wrong selectors, the task retries infinitely. - let fieldFound = {}; - let items = Array.from(document.querySelectorAll(itemsSelector)); - // items may not loaded yet, tell the sender to retry. - if (!items.length) return MSG_ELEMENT_NOT_FOUND; - let results = items.map( - item => { - return fieldSelectors.map( - selector => { - let [cls, attr] = selector.split('@').slice(0, 2); - let fieldVals = Array.from(item.querySelectorAll(cls)); - if (!fieldVals.length) { - return; - } - fieldFound[selector] = true; - return fieldVals.map(find => attr ? find[attr] : find.textContent.trim()).join('\n') - } - ) - } - ); - // if it exists a field, which is not found in any row, the sender should retry. - let shouldWait = fieldSelectors.reduce((p, c) => p || !fieldFound[c], false); - return shouldWait ? MSG_ELEMENT_NOT_FOUND : results - } - - /** - * Repeatedly execute an function until the the detector returns true. - * @param {object} fn the function to execute - * @param {object} detector the detector. - * @param {string} log messages logged to console. - * @param {number} interval interval for detecting - * @param {number} limit max execute times of a function - * @return {Promise} a promise of the response. - */ - function executeUntil(fn, detector, log, interval, limit) { - interval = interval || 500; - let count = 0; - return new Promise((resolve, reject) => { - - loop(); - - async function loop() { - fn(); - limit++; - if (limit && count >= limit) { - reject(false); - } - setTimeout(() => { - let flag = !detector || detector(); - if (log) console.log(log, flag ? '(OK)' : '(failed)'); - if (flag) { - resolve(true); - } else { - loop(); - } - }, interval); - } - }); - } - -})(); diff --git a/scripts/shared/common.js b/scripts/shared/common.js deleted file mode 100644 index 743d9b4..0000000 --- a/scripts/shared/common.js +++ /dev/null @@ -1,10 +0,0 @@ -const EXT_NAME = "DataExtracter"; - -const ACTION_EXTRACT = `${EXT_NAME}:Extract`; -const ACTION_GOTO_URL = `${EXT_NAME}:GoToTUL`; -const ACTION_REPORT_IN = `${EXT_NAME}:ReportIn`; -const ACTION_QUERY_URL = `${EXT_NAME}:QueryURL`; -const ACTION_SCROLL_BOTTOM = `${EXT_NAME}:ScrollToBottom`; -const ACTION_UPLOAD_STATE = `${EXT_NAME}:UploadStateFile`; -const ACTION_SLEEP = `${EXT_NAME}:Sleep`; -const ACTION_WAKEUP = `${EXT_NAME}:WakeUp`; diff --git a/scripts/shared/tools.js b/scripts/shared/tools.js deleted file mode 100644 index af610f0..0000000 --- a/scripts/shared/tools.js +++ /dev/null @@ -1,69 +0,0 @@ -class ConstMessage { - constructor(id, message) { - this.id = id; - this.message = message; - } - isEqual(err) { - if (!err || !err.id) return false; - return this.id == err.id; - } -} - -const URL_REG = getWebUrl(); -const MSG_ELEMENT_NOT_FOUND = new ConstMessage(1, "No element found for at least one selector, maybe it's not loaded yet"); -const MSG_URL_SKIPPED = new ConstMessage(100, "Skipped current URL"); -const MSG_USER_ABORT = new ConstMessage(100, "Tasks stopped by user."); - -function saveFile(data, mimeType, fileName) { - fileName = fileName || document.title || "result"; - var blob; - if (typeof window.Blob == "function") { - blob = new Blob([data], { - type: mimeType - }) - } else { - var BlobBuiler = window.BlobBuilder || window.MozBlobBuilder || window.WebKitBlobBuilder || window.MSBlobBuilder; - var builer = new BlobBuiler(); - builer.append(data); - blob = builer.getBlob(mimeType) - } - var URL = window.URL || window.webkitURL; - var url = URL.createObjectURL(blob); - var link = document.createElement("a"); - if ('download' in link) { - link.style.visibility = "hidden"; - link.href = url; - link.download = fileName; - document.body.appendChild(link); - var j = document.createEvent("MouseEvents"); - j.initEvent("click", true, true); - link.dispatchEvent(j); - document.body.removeChild(link) - } else if (navigator.msSaveBlob) { - navigator.msSaveBlob(blob, fileName) - } else { - location.href = url - } -} - -function getWebUrl() { - let engIriChar = "0-9a-zA-z"; - let goodIriChar = "0-9a-zA-z"; - let topLevelDomainStrForWebUrlExpand = "(?:com|net|org|gov|mil|edu|biz|info|pro|name|coop|travel|xxx|idv|aero|museum|mobi|asia|tel|int|post|jobs|cat|ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cu|cv|cx|cy|cz|de|dj|dk|dm|do|dz|ec|ee|eg|eh|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|ma|mc|md|me|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sm|sn|so|sr|st|sv|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|um|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|yu|yr|za|zm|zw|accountant|club|coach|college|company|construction|consulting|contractors|cooking|corp|credit|creditcard|dance|dealer|democrat|dental|dentist|design|diamonds|direct|doctor|drive|eco|education|energy|engineer|engineering|equipment|events|exchange|expert|express|faith|farm|farmers|fashion|finance|financial|fish|fit|fitness|flights|florist|flowers|food|football|forsale|furniture|game|games|garden|gmbh|golf|health|healthcare|hockey|holdings|holiday|home|hospital|hotel|hotels|house|inc|industries|insurance|insure|investments|islam|jewelry|justforu|kid|kids|law|lawyer|legal|lighting|limited|live|llc|llp|loft|ltd|ltda|managment|marketing|media|medical|men|money|mortgage|moto|motorcycles|music|mutualfunds|ngo|partners|party|pharmacy|photo|photography|photos|physio|pizza|plumbing|press|prod|productions|radio|rehab|rent|repair|report|republican|restaurant|room|rugby|safe|sale|sarl|save|school|secure|security|services|shoes|show|soccer|spa|sport|sports|spot|srl|storage|studio|tattoo|taxi|team|tech|technology|thai|tips|tour|tours|toys|trade|trading|travelers|university|vacations|ventures|versicherung|versicherung|vet|wedding|wine|winners|work|works|yachts|zone|archi|architect|casa|contruction|estate|haus|house|immo|immobilien|lighting|loft|mls|realty|academy|arab|bible|care|catholic|charity|christmas|church|college|community|contact|degree|education|faith|foundation|gay|halal|hiv|indiands|institute|irish|islam|kiwi|latino|mba|meet|memorial|ngo|phd|prof|school|schule|science|singles|social|swiss|thai|trust|university|uno|auction|best|bid|boutique|center|cheap|compare|coupon|coupons|deal|deals|diamonds|discount|fashion|forsale|free|gift|gold|gratis|hot|jewelry|kaufen|luxe|luxury|market|moda|pay|promo|qpon|review|reviews|rocks|sale|shoes|shop|shopping|store|tienda|top|toys|watch|zero|bar|bio|cafe|catering|coffee|cooking|diet|eat|food|kitchen|menu|organic|pizza|pub|rest|restaurant|vodka|wine|abudhabi|africa|alsace|amsterdam|barcelona|bayern|berlin|boats|booking|boston|brussels|budapest|caravan|casa|catalonia|city|club|cologne|corsica|country|cruise|cruises|deal|deals|doha|dubai|durban|earth|flights|fly|fun|gent|guide|hamburg|helsinki|holiday|hotel|hoteles|hotels|ist|istanbul|joburg|koeln|land|london|madrid|map|melbourne|miami|moscow|nagoya|nrw|nyc|osaka|paris|party|persiangulf|place|quebec|reise|reisen|rio|roma|room|ruhr|saarland|stockholm|swiss|sydney|taipei|tickets|tirol|tokyo|tour|tours|town|travelers|vacations|vegas|wales|wien|world|yokohama|zuerich|art|auto|autos|baby|band|baseball|beats|beauty|beknown|bike|book|boutique|broadway|car|cars|club|coach|contact|cool|cricket|dad|dance|date|dating|design|dog|events|family|fan|fans|fashion|film|final|fishing|football|fun|furniture|futbol|gallery|game|games|garden|gay|golf|guru|hair|hiphop|hockey|home|horse|icu|joy|kid|kids|life|lifestyle|like|living|lol|makeup|meet|men|moda|moi|mom|movie|movistar|music|party|pet|pets|photo|photography|photos|pics|pictures|play|poker|rodeo|rugby|run|salon|singles|ski|skin|smile|soccer|social|song|soy|sport|sports|star|style|surf|tatoo|tennis|theater|theatre|tunes|vip|wed|wedding|win|winners|yoga|you|analytics|antivirus|app|blog|call|camera|channel|chat|click|cloud|computer|contact|data|dev|digital|direct|docs|domains|dot|download|email|foo|forum|graphics|guide|help|home|host|hosting|idn|link|lol|mail|mobile|network|online|open|page|phone|pin|search|site|software|webcam|airforce|army|black|blue|box|buzz|casa|cool|day|discover|donuts|exposed|fast|finish|fire|fyi|global|green|help|here|how|international|ira|jetzt|jot|like|live|kim|navy|new|news|next|ninja|now|one|ooo|pink|plus|red|solar|tips|today|weather|wow|wtf|xyz|abogado|adult|anquan|aquitaine|attorney|audible|autoinsurance|banque|bargains|bcn|beer|bet|bingo|blackfriday|bom|boo|bot|broker|builders|business|bzh|cab|cal|cam|camp|cancerresearch|capetown|carinsurance|casino|ceo|cfp|circle|claims|cleaning|clothing|codes|condos|connectors|courses|cpa|cymru|dds|delivery|desi|directory|diy|dvr|ecom|enterprises|esq|eus|fail|feedback|financialaid|frontdoor|fund|gal|gifts|gives|giving|glass|gop|got|gripe|grocery|group|guitars|hangout|homegoods|homes|homesense|hotels|ing|ink|juegos|kinder|kosher|kyoto|lat|lease|lgbt|liason|loan|loans|locker|lotto|love|maison|markets|matrix|meme|mov|okinawa|ong|onl|origins|parts|patch|pid|ping|porn|progressive|properties|property|protection|racing|read|realestate|realtor|recipes|rentals|sex|sexy|shopyourway|shouji|silk|solutions|stroke|study|sucks|supplies|supply|tax|tires|total|training|translations|travelersinsurcance|ventures|viajes|villas|vin|vivo|voyage|vuelos|wang|watches|测试|集团|在线|公益|公司|移动|我爱你|商标|商城|中文网|中信|中国|中國|測試|网络|香港|台湾|台灣|机构|组织机构|世界|网址|游戏|新加坡|政务|परीक्षा|한국|ভারত|موقع|বাংলা|москва|испытание|қаз|онлайн|сайт|срб|테스트|орг|삼성|சிங்கப்பூர்|дети|мкд|טעסט|భారత్|ලංකා|ભારત|भारत|آزمایشی|பரிட்சை|संगठन|укр|δοκιμή|إختبار|мон|الجزائر|عمان|ایران|امارات|بازار|پاکستان|الاردن|بھارت|المغرب|السعودية|سودان|مليسيا|شبكة|გე|ไทย|سورية|рф|تونس|みんな|ਭਾਰਤ|مصر|قطر|இலங்கை|இந்தியா|فلسطين|テスト)\\b"; // http://www.ip138.com/yuming/ - return new RegExp("((?:(http|https|Http|Https|rtsp|Rtsp):\\/\\/(?:(?:[a-zA-Z0-9\\$\\-\\_\\.\\+\\!\\*\\'\\(\\)" - + "\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,64}(?:\\:(?:[a-zA-Z0-9\\$\\-\\_" - + "\\.\\+\\!\\*\\'\\(\\)\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,25})?\\@)?)?" - + "((?:(?:[" + engIriChar + "][" + engIriChar + "\\-]{0,64}\\.)+" // named host - + topLevelDomainStrForWebUrlExpand - + "|(?:(?:25[0-5]|2[0-4]" // or ip address - + "[0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9])\\.(?:25[0-5]|2[0-4][0-9]" - + "|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(?:25[0-5]|2[0-4][0-9]|[0-1]" - + "[0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}" - + "|[1-9][0-9]|[0-9])))" - + "(?:\\:\\d{1,5})?)" // plus option port number - + "(\\/(?:(?:[" + goodIriChar + "\\;\\/\\?\\:\\@\\&\\=\\#\\~" // plus option query params - + "\\-\\.\\+\\!\\*\\'\\(\\)\\,\\_])|(?:\\%[a-fA-F0-9]{2}))*)?" - + "(?:\\b|$))", "m"); // and finally, a word boundary or end of - // input. This is to stop foo.sure from - // matching as foo.su -} \ No newline at end of file diff --git a/scripts/background/actions.js b/src/background/actions.ts similarity index 55% rename from scripts/background/actions.js rename to src/background/actions.ts index dd39d19..f30c455 100644 --- a/scripts/background/actions.js +++ b/src/background/actions.ts @@ -1,49 +1,35 @@ -function parseUrls(...args) { - if (!args.length) return []; - let arg = args.shift(); - if (arg instanceof Array) { - return arg; - } else if (arg instanceof ExtractResult) { - return arg.squash().filter(v => URL_REG.test(v)); - } else { - let urlTempl = arg; - if (urlTempl) { - if (args[0] instanceof Array) { - return args[0].map(p => urlTempl.replace("${page}", p)); - } else if (args.length >= 3) { - let urls = []; - let from = args.shift(); - let to = args.shift(); - let interval = args.shift(); - for (let i = from; i <= to; i += interval) { - urls.push(urlTempl.replace("${page}", i)); - } - return urls; - } - } - } - return []; -} +import { ACTION_GOTO_URL, ACTION_EXTRACT, ACTION_PING as ACTION_PING, ACTION_QUERY_URL, ACTION_SCROLL_BOTTOM } from "../common"; +import { sendMessage } from "./messaging"; -function redirectTab(tab, url) { +/** + * redirect tab to url. + * @param {any} tab target tab + * @param {string} url target URL + * @returns {Promise} a promise of target URL + */ +export function redirectTab(tab: chrome.tabs.Tab, url: string) { return queryUrl(tab).then(u => { if (url !== u) { let req = { action: ACTION_GOTO_URL, url: url } - let checker = async (url, err, tryCount) => { - let newURL = await queryUrl(tab).catch(() => { }); + let checker = async (u, err, tryCount): Promise => { + let queryErr: any; + let newURL = await queryUrl(tab).catch(e => queryErr = e); + if (queryErr) { + return Promise.reject(queryErr); + } if (newURL == url) return url; if ( tryCount % 5 == 0 && !confirm('Cannot navigate to target url. \nPress OK to continue, Cancel to stop.') ) { - return MSG_USER_ABORT; + return Promise.reject("Tasks stopped by user."); } return undefined; } - return sendMessage(tab, req, `Goto url: ${url}`, checker); + return sendMessage(tab, req, `Goto url: ${url}`, checker); } }); } @@ -55,25 +41,23 @@ function redirectTab(tab, url) { * @param {Array} fieldSelectors fields selectors for selecting fields (data columns) under each item * @returns {Promise} a promise of extracted data */ -function extractTabData(tab, itemsSelector, fieldSelectors) { +export function extractTabData(tab, itemsSelector, fieldSelectors) { let req = { action: ACTION_EXTRACT, itemsSelector: itemsSelector, fieldSelectors: fieldSelectors } let checker = (result, err, tryCount) => { - if (MSG_ELEMENT_NOT_FOUND.isEqual(result)) { - if (tryCount % 20 == 0) { - if (confirm('No data found in current page. \n\nContinue to next page?')) { - return []; - } + if (!result || !result.length) { + if (tryCount % 20 == 0 && confirm('No data found in current page. \n\nContinue to next page?')) { + return []; } else { return undefined; } } return result; }; - return sendMessage(tab, req, 'Extract data from the tab...', checker); + return sendMessage(tab, req, 'Extract data from the tab...', checker); } /** @@ -81,13 +65,13 @@ function extractTabData(tab, itemsSelector, fieldSelectors) { * @param {any} tab target tab * @returns {Promise} a promise of boolean value indicates if ping success */ -async function ping(tab, count = 1) { +export async function ping(tab, count = 1) { let req = { - action: ACTION_REPORT_IN + action: ACTION_PING } - let checker = r => r == req.action ? req.action : undefined; - let pong = await sendMessage(tab, req, 'Check tab availability...', checker, 1000, count).catch(() => { }); - return pong == ACTION_REPORT_IN; + let checker = (r: string, e, c) => r == "pong" ? r : undefined; + let pong = await sendMessage(tab, req, 'Check tab availability...', checker, 1000, count).catch(() => { }); + return pong == "pong"; } /** @@ -95,11 +79,11 @@ async function ping(tab, count = 1) { * @param {any} tab target tab * @returns {Promise} a promise of the url */ -function queryUrl(tab) { +export function queryUrl(tab: chrome.tabs.Tab) { let req = { action: ACTION_QUERY_URL } - return sendMessage(tab, req); + return sendMessage(tab, req); } /** @@ -108,14 +92,14 @@ function queryUrl(tab) { * @param {string} expected if specified, queryUrl resolves only when tab url equals to expected * @returns {Promise} a promise of the url */ -function scrollToBottom(tab) { +export function scrollToBottom(tab: chrome.tabs.Tab) { let req = { action: ACTION_SCROLL_BOTTOM } return sendMessage(tab, req, 'Scroll to page bottom...'); } -async function createTab(url, active) { +export async function createTab(url: string, active: boolean) { return new Promise((resolve, reject) => { chrome.tabs.create({ 'url': url, @@ -126,7 +110,7 @@ async function createTab(url, active) { }) } -async function getActiveTab(currentWindow) { +export async function getActiveTab(currentWindow: boolean) { return new Promise((resolve, reject) => { chrome.tabs.query({ active: true, @@ -137,7 +121,7 @@ async function getActiveTab(currentWindow) { }) } -async function getTabByID(id) { +export async function getTabByID(id: number) { return new Promise((resolve, reject) => { chrome.tabs.get(id, function (tab) { chrome.runtime.lastError; diff --git a/src/background/caches.ts b/src/background/caches.ts new file mode 100644 index 0000000..0ee3be2 --- /dev/null +++ b/src/background/caches.ts @@ -0,0 +1,15 @@ +import { logger } from "./common"; + +export class Caches { + private _state: string = ""; + constructor() { } + get state(): string { + let s = this._state; + this._state = ""; + return s; + } + setState(name: string, content: string) { + this._state = content; + logger.info(`State (${name}) recieved. To load it: some_var = new Extractor().load()`); + } +} \ No newline at end of file diff --git a/src/background/common.ts b/src/background/common.ts new file mode 100644 index 0000000..9b6960f --- /dev/null +++ b/src/background/common.ts @@ -0,0 +1,6 @@ +import { Logger, LOGGER_LEVEL } from "./logger"; +import { Caches } from "./caches"; + +export const caches = new Caches(); +export const logger = new Logger(LOGGER_LEVEL.DEBUG, LOGGER_LEVEL.DISABLED); +export const URL_REG = /^\s*(https?):\/\//im; diff --git a/scripts/background/extractor.js b/src/background/extractor.ts similarity index 81% rename from scripts/background/extractor.js rename to src/background/extractor.ts index a37f89f..f8acb7c 100644 --- a/scripts/background/extractor.js +++ b/src/background/extractor.ts @@ -1,10 +1,15 @@ -var __EXTRACTOR_STATE__ = ""; +import { Task } from "./task"; +import { saveFile } from "./tools"; +import { createTab, getActiveTab, ping } from "./actions"; +import { logger, caches } from "./common"; +import { ExtractResult } from "./result"; -class Extractor { - constructor(options) { - this._tasks = []; - this._running = false; - this._options = options; +export class Extractor { + private _tasks: Task[] = []; + private _running = false; + private _options: any = {}; + constructor(options?) { + if (options) this._options = options; } /** * Save current state, in case we restore it later. @@ -16,12 +21,12 @@ class Extractor { * Restore previous state by loading from saved state. */ load() { - if (!__EXTRACTOR_STATE__) { + let content = caches.state; + if (!content) { logger.info('No state found. Please upload a saved state from the popup window first.'); return; } - let state = JSON.parse(__EXTRACTOR_STATE__); - __EXTRACTOR_STATE__ = ""; + let state = JSON.parse(content); this._options = state._options; this._tasks = state._tasks.map(t => new Task(this._options, 'whaterver', ['whaterver']).load(t)); return this; @@ -32,7 +37,7 @@ class Extractor { * If url arguments not given within later tasks, they will use previous task result as input (target url list). * @param {...any} args itemsSelector, fieldSelectors, and more args to specify target urls. */ - task(...args) { + task(...args: any) { this._tasks.push(new Task(this._options, ...args)); return this; } @@ -53,7 +58,7 @@ class Extractor { * restart from specified task, but don't restart the previous tasks. * @param {number} from where to restart the tasks, begins with 0 */ - async restart(from = 0) { + async restart(from: number = 0) { let id = this._checkTaskId(from, 0); if (id < 0) return; for (let i = id; i < this._tasks.length; i++) { @@ -61,7 +66,7 @@ class Extractor { } return this._startTasks(0); } - async _startTasks(from) { + async _startTasks(from: number) { if (this._running) { logger.info('The Extractor is running. Please wait..'); return; @@ -85,7 +90,7 @@ class Extractor { } } this._running = true; - return this._tasks.reduce((pms, task, i) => { + return this._tasks.reduce((pms, task: Task, i: number) => { return pms.then( () => { if (i < from) return; @@ -93,9 +98,9 @@ class Extractor { let prevTask = this._tasks[i - 1]; return task.execute(tab, new ExtractResult(prevTask.results)); } - return task.execute(tab, undefined); + return task.execute(tab); }); - }, Promise.resolve(undefined)).then( + }, Promise.resolve(undefined)).then( () => { this._running = false; this.export(); @@ -109,7 +114,7 @@ class Extractor { * export result of a task to CSV * @param {number} taskid which task id to save, begins with 0 */ - export(taskid) { + export(taskid?: number) { let id = this._checkTaskId(taskid, this._tasks.length - 1); if (id < 0) return; let results = this._tasks[id].results @@ -125,10 +130,10 @@ Please confirm to download (${results.length - 1} items): ${exResults.toString(50) || "- Empty -"} `.trim(); if (confirm(msg)) { - saveFile(exResults, "text/csv"); + saveFile(exResults.toString(), "text/csv"); } } - _checkTaskId(id, defaultId) { + _checkTaskId(id: number, defaultId: number) { if (!this._tasks.length) { logger.info("No task found."); return -1; diff --git a/src/background/index.ts b/src/background/index.ts new file mode 100644 index 0000000..dd6f9d1 --- /dev/null +++ b/src/background/index.ts @@ -0,0 +1,14 @@ +import { Extractor } from "./extractor"; + +declare global { + interface Window { + $: (...args: any) => void; + Extractor: any; + } +} + +window.$ = function (...args) { + return new Extractor().task(...args).start(); +} + +window.Extractor = Extractor; \ No newline at end of file diff --git a/scripts/background/logger.js b/src/background/logger.ts similarity index 68% rename from scripts/background/logger.js rename to src/background/logger.ts index e65b3e8..beceee0 100644 --- a/scripts/background/logger.js +++ b/src/background/logger.ts @@ -1,21 +1,15 @@ -const LOGGER_LEVEL = { - DEBUG: 1, - INFO: 2, - WARNING: 3, - ERROR: 4, - DISABLED: 100, - properties: { - 1: { name: "debug", value: 1, prefix: "DEBUG" }, - 2: { name: "info", value: 2, prefix: "INFO" }, - 3: { name: "warning", value: 3, prefix: "WARN" }, - 4: { name: "error", value: 3, prefix: "ERROR" } - } +export enum LOGGER_LEVEL { + DEBUG = 1, + INFO, + WARN, + ERROR, + DISABLED, }; -class Logger { - _notificationId = undefined; - _log_level = LOGGER_LEVEL.INFO; - _notify_level = LOGGER_LEVEL.ERROR; +export class Logger { + private _notificationId = undefined; + private _log_level = LOGGER_LEVEL.INFO; + private _notify_level = LOGGER_LEVEL.ERROR; constructor(logLevel, notifyLevel) { if (logLevel) this._log_level = logLevel; if (notifyLevel) this._notify_level = notifyLevel; @@ -24,19 +18,19 @@ class Logger { get logLevel() { return this._log_level; } - set logLevel(val) { + set logLevel(val: LOGGER_LEVEL) { this._log_level = val; } get notifyLevel() { return this._notify_level; } - set notifyLevel(val) { + set notifyLevel(val: LOGGER_LEVEL) { this._notify_level = val; } - log(level, loggerFn, ...msgs) { + log(level: LOGGER_LEVEL, loggerFn: Function, ...msgs) { if (level < this._log_level) return; let time = new Date().toLocaleString(); - loggerFn(`${time} [${LOGGER_LEVEL.properties[level].prefix}]`, ...msgs); + loggerFn(`${time} [${LOGGER_LEVEL[level]}]`, ...msgs); if (level < this._notify_level) return; this.notify(...msgs); } @@ -47,7 +41,7 @@ class Logger { this.log(LOGGER_LEVEL.INFO, console.info, ...msgs); } warn(...msgs) { - this.log(LOGGER_LEVEL.WARNING, console.info, ...msgs); + this.log(LOGGER_LEVEL.WARN, console.info, ...msgs); } error(...msgs) { this.log(LOGGER_LEVEL.ERROR, console.info, ...msgs); @@ -77,5 +71,3 @@ class Logger { ); } } - -const logger = new Logger(LOGGER_LEVEL.DEBUG, LOGGER_LEVEL.DISABLED); \ No newline at end of file diff --git a/scripts/background/messaging.js b/src/background/messaging.ts similarity index 63% rename from scripts/background/messaging.js rename to src/background/messaging.ts index e76c416..a49c8cb 100644 --- a/scripts/background/messaging.js +++ b/src/background/messaging.ts @@ -1,3 +1,6 @@ +import { EXT_NAME, ACTION_UPLOAD_STATE } from "../common"; +import { getTabByID } from "./actions"; +import { caches, logger } from "./common"; /** * Sending a message to target tab repeatedly until the response is not undefined. @@ -12,11 +15,18 @@ * @param {string} log messages logged to console. * @return {Promise} a promise of the response. */ -function sendMessage(tab, req, log, dataChecker, interval, limit = 0) { +export function sendMessage( + tab: chrome.tabs.Tab, + req, + log?: string, + dataChecker?: (r: T, err: chrome.runtime.LastError, count: number) => T | Promise, + interval?: number, + limit?: number +) { interval = interval || 500; - limit = limit && !isNaN(limit) ? limit : 0; + limit = isNaN(limit) ? 0 : limit; let count = 0; - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { loop(); @@ -33,18 +43,27 @@ function sendMessage(tab, req, log, dataChecker, interval, limit = 0) { return; } count++; - chrome.tabs.sendMessage(tab.id, req, async r => { - // check error but do nothing. - // do not interrupt promise chains even if error, or the task always fail when: - // a tab is newly created, and the content scripts won't have time to initialize + chrome.tabs.sendMessage(tab.id, req, async (r: T) => { + // check error but do nothing until dataChecker. let err = chrome.runtime.lastError; - let result = r; + let result: T = r; + if (dataChecker) { - result = await dataChecker(r, err, count); - if (MSG_USER_ABORT.isEqual(result)) { - reject(MSG_USER_ABORT.message); + let pms = dataChecker(r, err, count); + // don't catch if it's not a Promise + if (pms instanceof Promise) { + let checkerError: any; + pms = pms.catch(e => checkerError = e); + result = await pms; + if (checkerError) { + reject(checkerError); + return; + } + } else { + result = pms; } } + let flag = result !== undefined && result !== null; if (log) logger.info(log, flag ? '(OK)' : '(failed)'); if (flag) { @@ -66,8 +85,7 @@ chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) { switch (request.action) { case ACTION_UPLOAD_STATE: sendResponse('recieved!'); - __EXTRACTOR_STATE__ = request.state; - logger.info(`State (${request.name}) recieved. To load it: some_var = new Extractor().load()`); + caches.setState(request.name, request.state) break; default: sendResponse("Request not supported."); diff --git a/scripts/background/result.js b/src/background/result.ts similarity index 80% rename from scripts/background/result.js rename to src/background/result.ts index b17894a..b3e795a 100644 --- a/scripts/background/result.js +++ b/src/background/result.ts @@ -1,23 +1,23 @@ -class ExtractResult { +export class ExtractResult { + private _data: string[][] = []; constructor(data) { this._data = data || []; - } - row(index) { + row(index: number): string[] { return this._data[index]; } - column(index) { + column(index: number): string[] { return [...new Array(this._data.length).keys()].map( i => this._data[i][index] ); } - squash() { + squash(): string[] { return this._data.reduce((p, c) => p.concat(c), []); } - get data() { + get data(): string[][] { return this._data; } - toString(rowsCount) { + toString(rowsCount: number = 0): string { let data = rowsCount > 0 ? this._data.slice(0, rowsCount) : this._data; return data.slice().reduce( (csv, lineCells) => { diff --git a/scripts/background/signiture.js b/src/background/signiture.ts similarity index 92% rename from scripts/background/signiture.js rename to src/background/signiture.ts index 51570e2..2e3c41d 100644 --- a/scripts/background/signiture.js +++ b/src/background/signiture.ts @@ -1,4 +1,6 @@ -const signitures = ` +import { ExtractResult } from "./result"; + +export const signitures = ` ## Usage // single task $(...args); @@ -21,9 +23,10 @@ $(".item", ["a", "a@href"]); https://git.jebbs.co/jebbs/data-extracter-extesion `.trim(); -function testArgs(...args) { +export function testArgs(...args: any) { switch (args.length) { - case 0, 1: + case 0: + case 1: return false; case 2: return args[0] && args[1] && @@ -66,7 +69,3 @@ function testArgs(...args) { return arr.reduce((p, c) => p && tester(c), true); } } - -function argsToString(...args) { - return args.map(v => (v instanceof Array ? `[${v.join(', ')}]` : v.toString())).join(', '); -} \ No newline at end of file diff --git a/scripts/background/task.js b/src/background/task.ts similarity index 54% rename from scripts/background/task.js rename to src/background/task.ts index fab8302..a45b6ad 100644 --- a/scripts/background/task.js +++ b/src/background/task.ts @@ -1,14 +1,21 @@ -class Task { - _data = {}; - _data_keys = []; - /** - * Create a task. - * constructor(itemsSelector:string, fieldSelectors:string[]) - * constructor(itemsSelector:string, fieldSelectors:string[], url:string, from:number, to:number, interval:number) - * constructor(itemsSelector:string, fieldSelectors:string[], url:string, pages:number[]) - * constructor(itemsSelector:string, fieldSelectors:string[], urls:string[]) - * @param {...any} args - */ +import { parseUrls } from "./tools"; +import { queryUrl, redirectTab, scrollToBottom, extractTabData } from "./actions"; +import { testArgs, signitures } from "./signiture"; +import { ExtractResult } from "./result"; + +export class Task { + private _data: { [key: string]: string[][] } = {}; + private _data_keys: string[] = []; + private _options: any; + private _itemsSelector: string; + private _fieldSelectors: string[]; + private _urls: string[] = []; + + constructor(options: any, ...arg: any); + constructor(options: any, itemsSelector: string, fieldSelectors: string[]); + constructor(options: any, itemsSelector: string, fieldSelectors: string[], url: string, from: number, to: number, interval: number); + constructor(options: any, itemsSelector: string, fieldSelectors: string[], url: string, pages: number[]); + constructor(options: any, itemsSelector: string, fieldSelectors: string[], urls: string[]); constructor(options, ...args) { if (!testArgs(...args)) throw new Error(`Invalid call arguments.\n\n${signitures}\n\n`); @@ -17,7 +24,7 @@ class Task { this._fieldSelectors = args.shift(); this._urls = parseUrls(...args); } - load(state) { + load(state: any): Task { this._itemsSelector = state._itemsSelector; this._data = state._data; this._data_keys = state._data_keys; @@ -26,25 +33,23 @@ class Task { this._urls = state._urls; return this; } - get urls() { + get urls(): string[] { return this._urls; } - get data() { - return this._data; - } - get results() { + get results(): string[][] { return this._data_keys.reduce((p, c) => { return p.concat(this._data[c]); }, []); } - get fieldSelectors() { + get fieldSelectors(): string[] { return this._fieldSelectors; } - clean() { + clean(): Task { this._data = {}; this._data_keys = []; + return this; } - async execute(tab, upstreamData) { + async execute(tab: chrome.tabs.Tab, upstreamData?: ExtractResult): Promise { if (!tab) return Promise.reject("No tab to execute the task."); let urls = this._urls if (!urls.length) { @@ -60,14 +65,12 @@ class Task { } return urls.reduce((p, url, i) => p.then( results => { - if (i > 0) { - if (!MSG_URL_SKIPPED.isEqual(results)) { - let lastURL = urls[i - 1]; - saveResult(results, lastURL); - } + if (i > 0 && results instanceof Array) { + let lastURL = urls[i - 1]; + saveResult(results, lastURL); } - if (this._data[url]) return MSG_URL_SKIPPED; - let pms = redirectTab(tab, url); + if (this._data[url]) return; + let pms: Promise = redirectTab(tab, url); if (this._options["scrollToBottom"]) { pms = pms.then(() => scrollToBottom(tab)); } @@ -75,9 +78,9 @@ class Task { () => extractTabData(tab, this._itemsSelector, this._fieldSelectors) ); } - ), Promise.resolve(null)).then( + ), Promise.resolve(null)).then( results => { - if (!MSG_URL_SKIPPED.isEqual(results)) { + if (results && results.length) { let lastURL = urls[urls.length - 1]; saveResult(results, lastURL); return; diff --git a/src/background/tools.ts b/src/background/tools.ts new file mode 100644 index 0000000..18bfc07 --- /dev/null +++ b/src/background/tools.ts @@ -0,0 +1,61 @@ +import { URL_REG } from "./common"; +import { ExtractResult } from "./result"; + +export function parseUrls(...args) { + if (!args.length) return []; + let arg = args.shift(); + if (arg instanceof Array) { + return arg; + } else if (arg instanceof ExtractResult) { + return arg.squash().filter(v => URL_REG.test(v)); + } else { + let urlTempl = arg; + if (urlTempl) { + if (args[0] instanceof Array) { + return args[0].map(p => urlTempl.replace("${page}", p)); + } else if (args.length >= 3) { + let urls = []; + let from = args.shift(); + let to = args.shift(); + let interval = args.shift(); + for (let i = from; i <= to; i += interval) { + urls.push(urlTempl.replace("${page}", i)); + } + return urls; + } + } + } + return []; +} + +export function saveFile(data: string, mimeType: string, fileName?: string) { + fileName = fileName || document.title || "result"; + let blob: Blob; + if (typeof window.Blob == "function") { + blob = new Blob([data], { + type: mimeType + }) + } else { + var BlobBuiler = window.MSBlobBuilder; + var builer = new BlobBuiler(); + builer.append(data); + blob = builer.getBlob(mimeType) + } + var URL = window.URL || window.webkitURL; + var url = URL.createObjectURL(blob); + var link = document.createElement("a"); + if ('download' in link) { + link.style.visibility = "hidden"; + link.href = url; + link.download = fileName; + document.body.appendChild(link); + var j = document.createEvent("MouseEvents"); + j.initEvent("click", true, true); + link.dispatchEvent(j); + document.body.removeChild(link) + } else if (navigator.msSaveBlob) { + navigator.msSaveBlob(blob, fileName) + } else { + location.href = url + } +} diff --git a/src/common.ts b/src/common.ts new file mode 100644 index 0000000..88b2922 --- /dev/null +++ b/src/common.ts @@ -0,0 +1,11 @@ + +export const EXT_NAME = "DataExtracter"; + +export const ACTION_EXTRACT = `${EXT_NAME}:Extract`; +export const ACTION_GOTO_URL = `${EXT_NAME}:GoToTUL`; +export const ACTION_PING = `${EXT_NAME}:ReportIn`; +export const ACTION_QUERY_URL = `${EXT_NAME}:QueryURL`; +export const ACTION_SCROLL_BOTTOM = `${EXT_NAME}:ScrollToBottom`; +export const ACTION_UPLOAD_STATE = `${EXT_NAME}:UploadStateFile`; +export const ACTION_SLEEP = `${EXT_NAME}:Sleep`; +export const ACTION_WAKEUP = `${EXT_NAME}:WakeUp`; diff --git a/src/content/actions.ts b/src/content/actions.ts new file mode 100644 index 0000000..7041206 --- /dev/null +++ b/src/content/actions.ts @@ -0,0 +1,73 @@ +export function extract(itemsSelector: string, fieldSelectors: string[]): string[][] { + // since some elements may be loaded asynchronously. + // if one field is never found, we should return undefined, + // so that senders can detect to retry until elements loaded. + // If user writes wrong selectors, the task retries infinitely. + let fieldFound: { [key: string]: boolean } = {}; + let items: Element[] = Array.from(document.querySelectorAll(itemsSelector)); + // items may not loaded yet, tell the sender to retry. + if (!items.length) return []; + let results: string[][] = items.map( + item => { + return fieldSelectors.map( + selector => { + let [cls, attr] = selector.split('@').slice(0, 2); + let fieldVals = Array.from(item.querySelectorAll(cls)); + if (!fieldVals.length) { + return; + } + fieldFound[selector] = true; + return fieldVals.map(find => attr ? find[attr] : find.textContent.trim()).join('\n') + } + ) + } + ); + // if it exists a field, which is not found in any row, the sender should retry. + let shouldWait = fieldSelectors.reduce((p, c) => p || !fieldFound[c], false); + return shouldWait ? [] : results; +} + +export function scrollToBottom() { + return executeUntil( + () => window.scrollTo(0, document.body.clientHeight), + () => document.body.clientHeight - window.scrollY - window.innerHeight < 20, + "Scroll to page bottom...", + 1000, + 10 + ); +} + +/** + * Repeatedly execute an function until the the detector returns true. + * @param {object} fn the function to execute + * @param {object} detector the detector. + * @param {string} log messages logged to console. + * @param {number} interval interval for detecting + * @param {number} limit max execute times of a function + * @return {Promise} a promise of the response. + */ +function executeUntil(fn: () => void, detector: () => boolean, log: string, interval: number, limit: number) { + interval = interval || 500; + let count = 0; + return new Promise((resolve, reject) => { + + loop(); + + async function loop() { + fn(); + limit++; + if (limit && count >= limit) { + reject(false); + } + setTimeout(() => { + let flag = !detector || detector(); + if (log) console.log(log, flag ? '(OK)' : '(failed)'); + if (flag) { + resolve(true); + } else { + loop(); + } + }, interval); + } + }); +} \ No newline at end of file diff --git a/src/content/index.ts b/src/content/index.ts new file mode 100644 index 0000000..ad68c26 --- /dev/null +++ b/src/content/index.ts @@ -0,0 +1,45 @@ +import { ACTION_WAKEUP, ACTION_EXTRACT, ACTION_GOTO_URL, ACTION_PING, ACTION_QUERY_URL, ACTION_SCROLL_BOTTOM, ACTION_SLEEP } from '../common'; +import { scrollToBottom, extract } from './actions'; + +let asleep = false; +chrome.runtime.onMessage.addListener( + function (request, sender: chrome.runtime.MessageSender, sendResponse: (r: any) => void) { + if (!request.action) return; + if (asleep && ACTION_WAKEUP != request.action) { + sendResponse && sendResponse(undefined); + return; + } + // console.log("Recieved request:",request); + doAction(request, sender).then(r => sendResponse && sendResponse(r)); + // return true to indicate you wish to send a response asynchronously + return true; + } +); + +async function doAction(request: any, sender: chrome.runtime.MessageSender) { + switch (request.action) { + case ACTION_EXTRACT: + let data = extract(request.itemsSelector, request.fieldSelectors); + return data; + case ACTION_GOTO_URL: + window.location.replace(request.url); + // should not recieve any request until the page & script reload + asleep = true; + return request.url; + case ACTION_PING: + return "pong"; + case ACTION_QUERY_URL: + return window.location.href; + case ACTION_SCROLL_BOTTOM: + return scrollToBottom(); + case ACTION_SLEEP: + asleep = true; + return "Content script is sleeping."; + case ACTION_WAKEUP: + asleep = false; + return "Content script is available."; + default: + break; + } +} + diff --git a/popup/tip.js b/src/popup/index.ts similarity index 96% rename from popup/tip.js rename to src/popup/index.ts index 147b1e1..241ddd4 100644 --- a/popup/tip.js +++ b/src/popup/index.ts @@ -1,3 +1,5 @@ +import { ACTION_UPLOAD_STATE } from '../common'; + window.onload = function () { document.querySelector('#link-extension-detail') .addEventListener('click', () => { diff --git a/popup/styles/bootstrap.min.css b/template/assets/bootstrap.min.css similarity index 100% rename from popup/styles/bootstrap.min.css rename to template/assets/bootstrap.min.css diff --git a/images/console.png b/template/assets/console.png similarity index 100% rename from images/console.png rename to template/assets/console.png diff --git a/popup/tip.html b/template/html/popup.html similarity index 84% rename from popup/tip.html rename to template/html/popup.html index c4c3257..364aa4c 100644 --- a/popup/tip.html +++ b/template/html/popup.html @@ -3,10 +3,9 @@ Data Extractor - - + - + @@ -19,13 +18,12 @@
-

Goto Extension Detail, click "backgroud page", and type your scripts in the console.

-

@@ -66,7 +64,7 @@
- +
diff --git a/icon.png b/template/icon.png similarity index 100% rename from icon.png rename to template/icon.png diff --git a/template/manifest.json b/template/manifest.json new file mode 100755 index 0000000..eaa41c1 --- /dev/null +++ b/template/manifest.json @@ -0,0 +1,34 @@ +{ + "manifest_version": 2, + "name": "Data Extracter", + "version": "0.5.1", + "author": "jebbs", + "description": "Extract data from web page elements as sheet.", + "icons": { + "16": "icon.png", + "48": "icon.png", + "128": "icon.png" + }, + "browser_action": { + "default_icon": "icon.png", + "default_popup": "html/popup.html", + "default_title": "Data Extracter" + }, + "background": { + "scripts": [ + "scripts/background.bundle.js" + ], + "persistent": false + }, + "content_scripts": [{ + "matches": ["*://*/*"], + "js": [ + "scripts/content.bundle.js" + ], + "run_at": "document_idle" + }], + "permissions": [ + "activeTab", + "notifications" + ] +} \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..f77d333 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "module": "commonjs", + "target": "es6", + "noImplicitAny": false, + "sourceMap": true, + "rootDir": "src", + "outDir": "dist/js", + "noEmitOnError": true, + "typeRoots": [ "node_modules/@types" ] + } +} \ No newline at end of file diff --git a/webpack.config.js b/webpack.config.js new file mode 100644 index 0000000..0798a6f --- /dev/null +++ b/webpack.config.js @@ -0,0 +1,33 @@ +const path = require('path'); +const CopyPlugin = require('copy-webpack-plugin'); + +module.exports = { + mode: 'production', + entry: { + background: './src/background/index.ts', + content: './src/content/index.ts', + popup: './src/popup/index.ts', + }, + // devtool: 'inline-source-map', + output: { + path: path.resolve(__dirname, 'dist'), + filename: 'scripts/[name].bundle.js' + }, + module: { + rules: [ + { + test: /\.tsx?$/, + use: 'ts-loader', + exclude: /node_modules/ + } + ] + }, + resolve: { + extensions: ['.tsx', '.ts', '.js'] + }, + plugins: [ + new CopyPlugin([ + { from: '**/*', to: '.', toType: "dir" }, + ], { context: 'template', logLevel: 'warn' }), + ] +}; \ No newline at end of file