diff --git a/README.md b/README.md index 8a8526660c..6d93bed2f2 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ You need to set up the following on your local machine to use garden: * Node.js >= 8.x * Git * rsync +* [Watchman](https://facebook.github.io/watchman/docs/install.html) * [Docker for Mac/Windows (edge version)](https://docs.docker.com/engine/installation/) We recommend using Homebrew on Mac for everything except Docker. diff --git a/bin/bootstrap-osx b/bin/bootstrap-osx index 2b2881ee39..d9d2f58bbc 100755 --- a/bin/bootstrap-osx +++ b/bin/bootstrap-osx @@ -1,7 +1,7 @@ #!/usr/bin/env bash # install/update homebrew dependencies -BREW_DEPS="cmake git kubectl stern rsync ruby" +BREW_DEPS="cmake git kubectl stern rsync ruby watchman" brew update brew install ${BREW_DEPS} diff --git a/package-lock.json b/package-lock.json index d5eb229e7a..f4dfbb49fc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -237,12 +237,6 @@ "integrity": "sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ==", "dev": true }, - "@types/yargs": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-11.0.0.tgz", - "integrity": "sha512-vFql3tOxs6clgh+WVoLW3nOkNGCdeKsMU6mQZkOerJpV/CR9Xc1c1lZ+kYU+hNSobrQIOcNovWfPFDJIhcG5Pw==", - "dev": true - }, "JSONStream": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.2.tgz", @@ -731,6 +725,13 @@ "uuid": "3.1.0", "xml2js": "0.4.17", "xmlbuilder": "4.2.1" + }, + "dependencies": { + "uuid": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz", + "integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g==" + } } }, "aws-sign2": { @@ -1046,6 +1047,14 @@ "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", "dev": true }, + "bser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.0.0.tgz", + "integrity": "sha1-mseNPtXZFYBP2HrLFYvHlxR6Fxk=", + "requires": { + "node-int64": "^0.4.0" + } + }, "buffer": { "version": "4.9.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", @@ -2697,6 +2706,14 @@ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" }, + "fb-watchman": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.0.tgz", + "integrity": "sha1-VOmr99+i8mzZsWNsWIwa/AXeXVg=", + "requires": { + "bser": "^2.0.0" + } + }, "fd-slicer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", @@ -2925,24 +2942,28 @@ "dependencies": { "abbrev": { "version": "1.1.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", "dev": true, "optional": true }, "ansi-regex": { "version": "2.1.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", "dev": true }, "aproba": { "version": "1.2.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", "dev": true, "optional": true }, "are-we-there-yet": { "version": "1.1.4", - "bundled": true, + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz", + "integrity": "sha1-u13KOCu5TwXhUZQ3PRb9O6HKEQ0=", "dev": true, "optional": true, "requires": { @@ -2952,12 +2973,14 @@ }, "balanced-match": { "version": "1.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true }, "brace-expansion": { "version": "1.1.11", - "bundled": true, + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "requires": { "balanced-match": "^1.0.0", @@ -2966,34 +2989,40 @@ }, "chownr": { "version": "1.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.0.1.tgz", + "integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=", "dev": true, "optional": true }, "code-point-at": { "version": "1.1.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", "dev": true }, "concat-map": { "version": "0.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, "console-control-strings": { "version": "1.1.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", "dev": true }, "core-util-is": { "version": "1.0.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", "dev": true, "optional": true }, "debug": { "version": "2.6.9", - "bundled": true, + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "optional": true, "requires": { @@ -3002,25 +3031,29 @@ }, "deep-extend": { "version": "0.4.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.2.tgz", + "integrity": "sha1-SLaZwn4zS/ifEIkr5DL25MfTSn8=", "dev": true, "optional": true }, "delegates": { "version": "1.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", "dev": true, "optional": true }, "detect-libc": { "version": "1.0.3", - "bundled": true, + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", "dev": true, "optional": true }, "fs-minipass": { "version": "1.2.5", - "bundled": true, + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.5.tgz", + "integrity": "sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ==", "dev": true, "optional": true, "requires": { @@ -3029,13 +3062,15 @@ }, "fs.realpath": { "version": "1.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true, "optional": true }, "gauge": { "version": "2.7.4", - "bundled": true, + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", "dev": true, "optional": true, "requires": { @@ -3051,7 +3086,8 @@ }, "glob": { "version": "7.1.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", "dev": true, "optional": true, "requires": { @@ -3065,13 +3101,15 @@ }, "has-unicode": { "version": "2.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", "dev": true, "optional": true }, "iconv-lite": { "version": "0.4.21", - "bundled": true, + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.21.tgz", + "integrity": "sha512-En5V9za5mBt2oUA03WGD3TwDv0MKAruqsuxstbMUZaj9W9k/m1CV/9py3l0L5kw9Bln8fdHQmzHSYtvpvTLpKw==", "dev": true, "optional": true, "requires": { @@ -3080,7 +3118,8 @@ }, "ignore-walk": { "version": "3.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.1.tgz", + "integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==", "dev": true, "optional": true, "requires": { @@ -3089,7 +3128,8 @@ }, "inflight": { "version": "1.0.6", - "bundled": true, + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "dev": true, "optional": true, "requires": { @@ -3099,18 +3139,21 @@ }, "inherits": { "version": "2.0.3", - "bundled": true, + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", "dev": true }, "ini": { "version": "1.3.5", - "bundled": true, + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", "dev": true, "optional": true }, "is-fullwidth-code-point": { "version": "1.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "dev": true, "requires": { "number-is-nan": "^1.0.0" @@ -3118,13 +3161,15 @@ }, "isarray": { "version": "1.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", "dev": true, "optional": true }, "minimatch": { "version": "3.0.4", - "bundled": true, + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "requires": { "brace-expansion": "^1.1.7" @@ -3132,12 +3177,14 @@ }, "minimist": { "version": "0.0.8", - "bundled": true, + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", "dev": true }, "minipass": { "version": "2.2.4", - "bundled": true, + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.2.4.tgz", + "integrity": "sha512-hzXIWWet/BzWhYs2b+u7dRHlruXhwdgvlTMDKC6Cb1U7ps6Ac6yQlR39xsbjWJE377YTCtKwIXIpJ5oP+j5y8g==", "dev": true, "requires": { "safe-buffer": "^5.1.1", @@ -3146,7 +3193,8 @@ }, "minizlib": { "version": "1.1.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.1.0.tgz", + "integrity": "sha512-4T6Ur/GctZ27nHfpt9THOdRZNgyJ9FZchYO1ceg5S8Q3DNLCKYy44nCZzgCJgcvx2UM8czmqak5BCxJMrq37lA==", "dev": true, "optional": true, "requires": { @@ -3155,7 +3203,8 @@ }, "mkdirp": { "version": "0.5.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "dev": true, "requires": { "minimist": "0.0.8" @@ -3163,7 +3212,8 @@ }, "ms": { "version": "2.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true, "optional": true }, @@ -3176,7 +3226,8 @@ }, "needle": { "version": "2.2.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/needle/-/needle-2.2.0.tgz", + "integrity": "sha512-eFagy6c+TYayorXw/qtAdSvaUpEbBsDwDyxYFgLZ0lTojfH7K+OdBqAF7TAFwDokJaGpubpSGG0wO3iC0XPi8w==", "dev": true, "optional": true, "requires": { @@ -3187,7 +3238,8 @@ }, "node-pre-gyp": { "version": "0.9.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.9.1.tgz", + "integrity": "sha1-8RwHUW3ZL4cZnbx+GDjqt81WyeA=", "dev": true, "optional": true, "requires": { @@ -3205,7 +3257,8 @@ }, "nopt": { "version": "4.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz", + "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", "dev": true, "optional": true, "requires": { @@ -3215,13 +3268,15 @@ }, "npm-bundled": { "version": "1.0.3", - "bundled": true, + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.0.3.tgz", + "integrity": "sha512-ByQ3oJ/5ETLyglU2+8dBObvhfWXX8dtPZDMePCahptliFX2iIuhyEszyFk401PZUNQH20vvdW5MLjJxkwU80Ow==", "dev": true, "optional": true }, "npm-packlist": { "version": "1.1.10", - "bundled": true, + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.1.10.tgz", + "integrity": "sha512-AQC0Dyhzn4EiYEfIUjCdMl0JJ61I2ER9ukf/sLxJUcZHfo+VyEfz2rMJgLZSS1v30OxPQe1cN0LZA1xbcaVfWA==", "dev": true, "optional": true, "requires": { @@ -3231,7 +3286,8 @@ }, "npmlog": { "version": "4.1.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", "dev": true, "optional": true, "requires": { @@ -3243,18 +3299,21 @@ }, "number-is-nan": { "version": "1.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", "dev": true }, "object-assign": { "version": "4.1.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", "dev": true, "optional": true }, "once": { "version": "1.4.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, "requires": { "wrappy": "1" @@ -3262,19 +3321,22 @@ }, "os-homedir": { "version": "1.0.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", "dev": true, "optional": true }, "os-tmpdir": { "version": "1.0.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", "dev": true, "optional": true }, "osenv": { "version": "0.1.5", - "bundled": true, + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", "dev": true, "optional": true, "requires": { @@ -3284,19 +3346,22 @@ }, "path-is-absolute": { "version": "1.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true, "optional": true }, "process-nextick-args": { "version": "2.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", "dev": true, "optional": true }, "rc": { "version": "1.2.6", - "bundled": true, + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.6.tgz", + "integrity": "sha1-6xiYnG1PTxYsOZ953dKfODVWgJI=", "dev": true, "optional": true, "requires": { @@ -3308,7 +3373,8 @@ "dependencies": { "minimist": { "version": "1.2.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true, "optional": true } @@ -3316,7 +3382,8 @@ }, "readable-stream": { "version": "2.3.6", - "bundled": true, + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "optional": true, "requires": { @@ -3331,7 +3398,8 @@ }, "rimraf": { "version": "2.6.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", + "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", "dev": true, "optional": true, "requires": { @@ -3340,42 +3408,49 @@ }, "safe-buffer": { "version": "5.1.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", "dev": true }, "safer-buffer": { "version": "2.1.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true, "optional": true }, "sax": { "version": "1.2.4", - "bundled": true, + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", "dev": true, "optional": true }, "semver": { "version": "5.5.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", "dev": true, "optional": true }, "set-blocking": { "version": "2.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "dev": true, "optional": true }, "signal-exit": { "version": "3.0.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", "dev": true, "optional": true }, "string-width": { "version": "1.0.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "dev": true, "requires": { "code-point-at": "^1.0.0", @@ -3385,7 +3460,8 @@ }, "string_decoder": { "version": "1.1.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "optional": true, "requires": { @@ -3394,7 +3470,8 @@ }, "strip-ansi": { "version": "3.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { "ansi-regex": "^2.0.0" @@ -3402,13 +3479,15 @@ }, "strip-json-comments": { "version": "2.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", "dev": true, "optional": true }, "tar": { "version": "4.4.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.1.tgz", + "integrity": "sha512-O+v1r9yN4tOsvl90p5HAP4AEqbYhx4036AGMm075fH9F8Qwi3oJ+v4u50FkT/KkvywNGtwkk0zRI+8eYm1X/xg==", "dev": true, "optional": true, "requires": { @@ -3423,13 +3502,15 @@ }, "util-deprecate": { "version": "1.0.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", "dev": true, "optional": true }, "wide-align": { "version": "1.1.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.2.tgz", + "integrity": "sha512-ijDLlyQ7s6x1JgCLur53osjm/UXUYD9+0PbYKrBsYisYXzCxN+HC3mYDNy/dWdmf3AwqwU3CXwDCvsNgGK1S0w==", "dev": true, "optional": true, "requires": { @@ -3438,12 +3519,14 @@ }, "wrappy": { "version": "1.0.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, "yallist": { "version": "3.0.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.2.tgz", + "integrity": "sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k=", "dev": true } } @@ -6197,6 +6280,11 @@ "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.5.tgz", "integrity": "sha512-MmbQJ2MTESTjt3Gi/3yG1wGpIMhUfcIypUCGtTizFR9IiccFwxSpfp0vtIZlkFclEqERemxfnSdZEMR9VqqEFQ==" }, + "node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=" + }, "node-pty": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/node-pty/-/node-pty-0.7.4.tgz", @@ -6342,7 +6430,8 @@ "dependencies": { "align-text": { "version": "0.1.4", - "bundled": true, + "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", + "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", "dev": true, "requires": { "kind-of": "^3.0.2", @@ -6352,22 +6441,26 @@ }, "amdefine": { "version": "1.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", "dev": true }, "ansi-regex": { "version": "2.1.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", "dev": true }, "ansi-styles": { "version": "2.2.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", "dev": true }, "append-transform": { "version": "0.4.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-0.4.0.tgz", + "integrity": "sha1-126/jKlNJ24keja61EpLdKthGZE=", "dev": true, "requires": { "default-require-extensions": "^1.0.0" @@ -6375,12 +6468,14 @@ }, "archy": { "version": "1.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", + "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", "dev": true }, "arr-diff": { "version": "2.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", "dev": true, "requires": { "arr-flatten": "^1.0.1" @@ -6388,42 +6483,50 @@ }, "arr-flatten": { "version": "1.1.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", "dev": true }, "arr-union": { "version": "3.1.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", "dev": true }, "array-unique": { "version": "0.2.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", "dev": true }, "arrify": { "version": "1.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", "dev": true }, "assign-symbols": { "version": "1.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", "dev": true }, "async": { "version": "1.5.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", "dev": true }, "atob": { "version": "2.1.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.0.tgz", + "integrity": "sha512-SuiKH8vbsOyCALjA/+EINmt/Kdl+TQPrtFgW7XZZcwtryFu9e5kQoX3bjCW6mIvGH1fbeAZZuvwGR5IlBRznGw==", "dev": true }, "babel-code-frame": { "version": "6.26.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", "dev": true, "requires": { "chalk": "^1.1.3", @@ -6433,7 +6536,8 @@ }, "babel-generator": { "version": "6.26.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz", + "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==", "dev": true, "requires": { "babel-messages": "^6.23.0", @@ -6448,7 +6552,8 @@ }, "babel-messages": { "version": "6.23.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", + "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", "dev": true, "requires": { "babel-runtime": "^6.22.0" @@ -6456,7 +6561,8 @@ }, "babel-runtime": { "version": "6.26.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { "core-js": "^2.4.0", @@ -6465,7 +6571,8 @@ }, "babel-template": { "version": "6.26.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", + "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", "dev": true, "requires": { "babel-runtime": "^6.26.0", @@ -6477,7 +6584,8 @@ }, "babel-traverse": { "version": "6.26.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", + "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", "dev": true, "requires": { "babel-code-frame": "^6.26.0", @@ -6493,7 +6601,8 @@ }, "babel-types": { "version": "6.26.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", + "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", "dev": true, "requires": { "babel-runtime": "^6.26.0", @@ -6504,17 +6613,20 @@ }, "babylon": { "version": "6.18.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", + "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", "dev": true }, "balanced-match": { "version": "1.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true }, "base": { "version": "0.11.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", "dev": true, "requires": { "cache-base": "^1.0.1", @@ -6528,7 +6640,8 @@ "dependencies": { "define-property": { "version": "1.0.0", - "bundled": true, + "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" @@ -6536,7 +6649,8 @@ }, "is-accessor-descriptor": { "version": "1.0.0", - "bundled": true, + "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" @@ -6544,7 +6658,8 @@ }, "is-data-descriptor": { "version": "1.0.0", - "bundled": true, + "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" @@ -6552,7 +6667,8 @@ }, "is-descriptor": { "version": "1.0.2", - "bundled": true, + "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", @@ -6562,19 +6678,22 @@ }, "isobject": { "version": "3.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", "dev": true }, "kind-of": { "version": "6.0.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", "dev": true } } }, "brace-expansion": { "version": "1.1.11", - "bundled": true, + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "requires": { "balanced-match": "^1.0.0", @@ -6583,7 +6702,8 @@ }, "braces": { "version": "1.8.5", - "bundled": true, + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", "dev": true, "requires": { "expand-range": "^1.8.1", @@ -6593,12 +6713,14 @@ }, "builtin-modules": { "version": "1.1.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", "dev": true }, "cache-base": { "version": "1.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", "dev": true, "requires": { "collection-visit": "^1.0.0", @@ -6614,14 +6736,16 @@ "dependencies": { "isobject": { "version": "3.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", "dev": true } } }, "caching-transform": { "version": "1.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-1.0.1.tgz", + "integrity": "sha1-bb2y8g+Nj7znnz6U6dF0Lc31wKE=", "dev": true, "requires": { "md5-hex": "^1.2.0", @@ -6631,13 +6755,15 @@ }, "camelcase": { "version": "1.2.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", + "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", "dev": true, "optional": true }, "center-align": { "version": "0.1.3", - "bundled": true, + "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", + "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", "dev": true, "optional": true, "requires": { @@ -6647,7 +6773,8 @@ }, "chalk": { "version": "1.1.3", - "bundled": true, + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { "ansi-styles": "^2.2.1", @@ -6659,7 +6786,8 @@ }, "class-utils": { "version": "0.3.6", - "bundled": true, + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", "dev": true, "requires": { "arr-union": "^3.1.0", @@ -6670,7 +6798,8 @@ "dependencies": { "define-property": { "version": "0.2.5", - "bundled": true, + "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" @@ -6678,14 +6807,16 @@ }, "isobject": { "version": "3.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", "dev": true } } }, "cliui": { "version": "2.1.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", + "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", "dev": true, "optional": true, "requires": { @@ -6696,7 +6827,8 @@ "dependencies": { "wordwrap": { "version": "0.0.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", + "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", "dev": true, "optional": true } @@ -6704,12 +6836,14 @@ }, "code-point-at": { "version": "1.1.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", "dev": true }, "collection-visit": { "version": "1.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", "dev": true, "requires": { "map-visit": "^1.0.0", @@ -6718,37 +6852,44 @@ }, "commondir": { "version": "1.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", "dev": true }, "component-emitter": { "version": "1.2.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", "dev": true }, "concat-map": { "version": "0.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, "convert-source-map": { "version": "1.5.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.1.tgz", + "integrity": "sha1-uCeAl7m8IpNl3lxiz1/K7YtVmeU=", "dev": true }, "copy-descriptor": { "version": "0.1.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", "dev": true }, "core-js": { "version": "2.5.5", - "bundled": true, + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.5.tgz", + "integrity": "sha1-sU3ek2xkDAV5prUMq8wTLdYSfjs=", "dev": true }, "cross-spawn": { "version": "4.0.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", + "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=", "dev": true, "requires": { "lru-cache": "^4.0.1", @@ -6757,7 +6898,8 @@ }, "debug": { "version": "2.6.9", - "bundled": true, + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "requires": { "ms": "2.0.0" @@ -6765,22 +6907,26 @@ }, "debug-log": { "version": "1.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/debug-log/-/debug-log-1.0.1.tgz", + "integrity": "sha1-IwdjLUwEOCuN+KMvcLiVBG1SdF8=", "dev": true }, "decamelize": { "version": "1.2.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", "dev": true }, "decode-uri-component": { "version": "0.2.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", "dev": true }, "default-require-extensions": { "version": "1.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-1.0.0.tgz", + "integrity": "sha1-836hXT4T/9m0N9M+GnW1+5eHTLg=", "dev": true, "requires": { "strip-bom": "^2.0.0" @@ -6788,7 +6934,8 @@ }, "define-property": { "version": "2.0.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", "dev": true, "requires": { "is-descriptor": "^1.0.2", @@ -6797,7 +6944,8 @@ "dependencies": { "is-accessor-descriptor": { "version": "1.0.0", - "bundled": true, + "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" @@ -6805,7 +6953,8 @@ }, "is-data-descriptor": { "version": "1.0.0", - "bundled": true, + "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" @@ -6813,7 +6962,8 @@ }, "is-descriptor": { "version": "1.0.2", - "bundled": true, + "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", @@ -6823,19 +6973,22 @@ }, "isobject": { "version": "3.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", "dev": true }, "kind-of": { "version": "6.0.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", "dev": true } } }, "detect-indent": { "version": "4.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", + "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", "dev": true, "requires": { "repeating": "^2.0.0" @@ -6843,7 +6996,8 @@ }, "error-ex": { "version": "1.3.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", + "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", "dev": true, "requires": { "is-arrayish": "^0.2.1" @@ -6851,17 +7005,20 @@ }, "escape-string-regexp": { "version": "1.0.5", - "bundled": true, + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", "dev": true }, "esutils": { "version": "2.0.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", "dev": true }, "execa": { "version": "0.7.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", + "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", "dev": true, "requires": { "cross-spawn": "^5.0.1", @@ -6875,7 +7032,8 @@ "dependencies": { "cross-spawn": { "version": "5.1.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", "dev": true, "requires": { "lru-cache": "^4.0.1", @@ -6887,7 +7045,8 @@ }, "expand-brackets": { "version": "0.1.5", - "bundled": true, + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", "dev": true, "requires": { "is-posix-bracket": "^0.1.0" @@ -6895,7 +7054,8 @@ }, "expand-range": { "version": "1.8.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", + "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", "dev": true, "requires": { "fill-range": "^2.1.0" @@ -6903,7 +7063,8 @@ }, "extend-shallow": { "version": "3.0.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", "dev": true, "requires": { "assign-symbols": "^1.0.0", @@ -6912,7 +7073,8 @@ "dependencies": { "is-extendable": { "version": "1.0.1", - "bundled": true, + "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" @@ -6922,7 +7084,8 @@ }, "extglob": { "version": "0.3.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", "dev": true, "requires": { "is-extglob": "^1.0.0" @@ -6930,12 +7093,14 @@ }, "filename-regex": { "version": "2.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", + "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", "dev": true }, "fill-range": { "version": "2.2.3", - "bundled": true, + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz", + "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", "dev": true, "requires": { "is-number": "^2.1.0", @@ -6947,7 +7112,8 @@ }, "find-cache-dir": { "version": "0.1.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-0.1.1.tgz", + "integrity": "sha1-yN765XyKUqinhPnjHFfHQumToLk=", "dev": true, "requires": { "commondir": "^1.0.1", @@ -6957,7 +7123,8 @@ }, "find-up": { "version": "2.1.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", "dev": true, "requires": { "locate-path": "^2.0.0" @@ -6965,12 +7132,14 @@ }, "for-in": { "version": "1.0.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", "dev": true }, "for-own": { "version": "0.1.5", - "bundled": true, + "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", + "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", "dev": true, "requires": { "for-in": "^1.0.1" @@ -6978,7 +7147,8 @@ }, "foreground-child": { "version": "1.5.6", - "bundled": true, + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-1.5.6.tgz", + "integrity": "sha1-T9ca0t/elnibmApcCilZN8svXOk=", "dev": true, "requires": { "cross-spawn": "^4", @@ -6987,7 +7157,8 @@ }, "fragment-cache": { "version": "0.2.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", "dev": true, "requires": { "map-cache": "^0.2.2" @@ -6995,27 +7166,32 @@ }, "fs.realpath": { "version": "1.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, "get-caller-file": { "version": "1.0.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz", + "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=", "dev": true }, "get-stream": { "version": "3.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", "dev": true }, "get-value": { "version": "2.0.6", - "bundled": true, + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", "dev": true }, "glob": { "version": "7.1.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -7028,7 +7204,8 @@ }, "glob-base": { "version": "0.3.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", + "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", "dev": true, "requires": { "glob-parent": "^2.0.0", @@ -7037,7 +7214,8 @@ }, "glob-parent": { "version": "2.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", "dev": true, "requires": { "is-glob": "^2.0.0" @@ -7045,17 +7223,20 @@ }, "globals": { "version": "9.18.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", + "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", "dev": true }, "graceful-fs": { "version": "4.1.11", - "bundled": true, + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", "dev": true }, "handlebars": { "version": "4.0.11", - "bundled": true, + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.11.tgz", + "integrity": "sha1-Ywo13+ApS8KB7a5v/F0yn8eYLcw=", "dev": true, "requires": { "async": "^1.4.0", @@ -7066,7 +7247,8 @@ "dependencies": { "source-map": { "version": "0.4.4", - "bundled": true, + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", + "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", "dev": true, "requires": { "amdefine": ">=0.0.4" @@ -7076,7 +7258,8 @@ }, "has-ansi": { "version": "2.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", "dev": true, "requires": { "ansi-regex": "^2.0.0" @@ -7084,12 +7267,14 @@ }, "has-flag": { "version": "1.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", "dev": true }, "has-value": { "version": "1.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", "dev": true, "requires": { "get-value": "^2.0.6", @@ -7099,14 +7284,16 @@ "dependencies": { "isobject": { "version": "3.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", "dev": true } } }, "has-values": { "version": "1.0.0", - "bundled": true, + "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", @@ -7115,7 +7302,8 @@ "dependencies": { "is-number": { "version": "3.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, "requires": { "kind-of": "^3.0.2" @@ -7123,7 +7311,8 @@ "dependencies": { "kind-of": { "version": "3.2.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { "is-buffer": "^1.1.5" @@ -7133,7 +7322,8 @@ }, "kind-of": { "version": "4.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", "dev": true, "requires": { "is-buffer": "^1.1.5" @@ -7143,17 +7333,20 @@ }, "hosted-git-info": { "version": "2.6.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.6.0.tgz", + "integrity": "sha512-lIbgIIQA3lz5XaB6vxakj6sDHADJiZadYEJB+FgA+C4nubM1NwcuvUr9EJPmnH1skZqpqUzWborWo8EIUi0Sdw==", "dev": true }, "imurmurhash": { "version": "0.1.4", - "bundled": true, + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", "dev": true }, "inflight": { "version": "1.0.6", - "bundled": true, + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "dev": true, "requires": { "once": "^1.3.0", @@ -7162,12 +7355,14 @@ }, "inherits": { "version": "2.0.3", - "bundled": true, + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", "dev": true }, "invariant": { "version": "2.2.4", - "bundled": true, + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", "dev": true, "requires": { "loose-envify": "^1.0.0" @@ -7175,12 +7370,14 @@ }, "invert-kv": { "version": "1.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", "dev": true }, "is-accessor-descriptor": { "version": "0.1.6", - "bundled": true, + "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" @@ -7188,17 +7385,20 @@ }, "is-arrayish": { "version": "0.2.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", "dev": true }, "is-buffer": { "version": "1.1.6", - "bundled": true, + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true }, "is-builtin-module": { "version": "1.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", + "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", "dev": true, "requires": { "builtin-modules": "^1.0.0" @@ -7206,7 +7406,8 @@ }, "is-data-descriptor": { "version": "0.1.4", - "bundled": true, + "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" @@ -7214,7 +7415,8 @@ }, "is-descriptor": { "version": "0.1.6", - "bundled": true, + "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", @@ -7224,19 +7426,22 @@ "dependencies": { "kind-of": { "version": "5.1.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", "dev": true } } }, "is-dotfile": { "version": "1.0.3", - "bundled": true, + "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", + "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", "dev": true }, "is-equal-shallow": { "version": "0.1.3", - "bundled": true, + "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", + "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", "dev": true, "requires": { "is-primitive": "^2.0.0" @@ -7244,17 +7449,20 @@ }, "is-extendable": { "version": "0.1.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", "dev": true }, "is-extglob": { "version": "1.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", "dev": true }, "is-finite": { "version": "1.0.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", + "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", "dev": true, "requires": { "number-is-nan": "^1.0.0" @@ -7262,12 +7470,14 @@ }, "is-fullwidth-code-point": { "version": "2.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true }, "is-glob": { "version": "2.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", "dev": true, "requires": { "is-extglob": "^1.0.0" @@ -7275,7 +7485,8 @@ }, "is-number": { "version": "2.1.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", + "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", "dev": true, "requires": { "kind-of": "^3.0.2" @@ -7283,7 +7494,8 @@ }, "is-odd": { "version": "2.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/is-odd/-/is-odd-2.0.0.tgz", + "integrity": "sha512-OTiixgpZAT1M4NHgS5IguFp/Vz2VI3U7Goh4/HA1adtwyLtSBrxYlcSYkhpAE07s4fKEcjrFxyvtQBND4vFQyQ==", "dev": true, "requires": { "is-number": "^4.0.0" @@ -7291,14 +7503,16 @@ "dependencies": { "is-number": { "version": "4.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", + "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", "dev": true } } }, "is-plain-object": { "version": "2.0.4", - "bundled": true, + "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" @@ -7306,49 +7520,58 @@ "dependencies": { "isobject": { "version": "3.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", "dev": true } } }, "is-posix-bracket": { "version": "0.1.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", + "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", "dev": true }, "is-primitive": { "version": "2.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", + "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", "dev": true }, "is-stream": { "version": "1.1.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", "dev": true }, "is-utf8": { "version": "0.2.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", "dev": true }, "is-windows": { "version": "1.0.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", "dev": true }, "isarray": { "version": "1.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", "dev": true }, "isexe": { "version": "2.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "dev": true }, "isobject": { "version": "2.1.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", "dev": true, "requires": { "isarray": "1.0.0" @@ -7356,12 +7579,14 @@ }, "istanbul-lib-coverage": { "version": "1.2.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-1.2.0.tgz", + "integrity": "sha512-GvgM/uXRwm+gLlvkWHTjDAvwynZkL9ns15calTrmhGgowlwJBbWMYzWbKqE2DT6JDP1AFXKa+Zi0EkqNCUqY0A==", "dev": true }, "istanbul-lib-hook": { "version": "1.1.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-1.1.0.tgz", + "integrity": "sha512-U3qEgwVDUerZ0bt8cfl3dSP3S6opBoOtk3ROO5f2EfBr/SRiD9FQqzwaZBqFORu8W7O0EXpai+k7kxHK13beRg==", "dev": true, "requires": { "append-transform": "^0.4.0" @@ -7369,7 +7594,8 @@ }, "istanbul-lib-instrument": { "version": "1.10.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-1.10.1.tgz", + "integrity": "sha512-1dYuzkOCbuR5GRJqySuZdsmsNKPL3PTuyPevQfoCXJePT9C8y1ga75neU+Tuy9+yS3G/dgx8wgOmp2KLpgdoeQ==", "dev": true, "requires": { "babel-generator": "^6.18.0", @@ -7383,7 +7609,8 @@ }, "istanbul-lib-report": { "version": "1.1.3", - "bundled": true, + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-1.1.3.tgz", + "integrity": "sha512-D4jVbMDtT2dPmloPJS/rmeP626N5Pr3Rp+SovrPn1+zPChGHcggd/0sL29jnbm4oK9W0wHjCRsdch9oLd7cm6g==", "dev": true, "requires": { "istanbul-lib-coverage": "^1.1.2", @@ -7394,7 +7621,8 @@ "dependencies": { "supports-color": { "version": "3.2.3", - "bundled": true, + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", "dev": true, "requires": { "has-flag": "^1.0.0" @@ -7404,7 +7632,8 @@ }, "istanbul-lib-source-maps": { "version": "1.2.3", - "bundled": true, + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.3.tgz", + "integrity": "sha512-fDa0hwU/5sDXwAklXgAoCJCOsFsBplVQ6WBldz5UwaqOzmDhUK4nfuR7/G//G2lERlblUNJB8P6e8cXq3a7MlA==", "dev": true, "requires": { "debug": "^3.1.0", @@ -7416,7 +7645,8 @@ "dependencies": { "debug": { "version": "3.1.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "dev": true, "requires": { "ms": "2.0.0" @@ -7426,7 +7656,8 @@ }, "istanbul-reports": { "version": "1.4.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-1.4.0.tgz", + "integrity": "sha512-OPzVo1fPZ2H+owr8q/LYKLD+vquv9Pj4F+dj808MdHbuQLD7S4ACRjcX+0Tne5Vxt2lxXvdZaL7v+FOOAV281w==", "dev": true, "requires": { "handlebars": "^4.0.3" @@ -7434,17 +7665,20 @@ }, "js-tokens": { "version": "3.0.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", "dev": true }, "jsesc": { "version": "1.3.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", + "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", "dev": true }, "kind-of": { "version": "3.2.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { "is-buffer": "^1.1.5" @@ -7452,13 +7686,15 @@ }, "lazy-cache": { "version": "1.0.4", - "bundled": true, + "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", + "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", "dev": true, "optional": true }, "lcid": { "version": "1.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", "dev": true, "requires": { "invert-kv": "^1.0.0" @@ -7466,7 +7702,8 @@ }, "load-json-file": { "version": "1.1.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", "dev": true, "requires": { "graceful-fs": "^4.1.2", @@ -7478,7 +7715,8 @@ }, "locate-path": { "version": "2.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", "dev": true, "requires": { "p-locate": "^2.0.0", @@ -7487,24 +7725,28 @@ "dependencies": { "path-exists": { "version": "3.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", "dev": true } } }, "lodash": { "version": "4.17.5", - "bundled": true, + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.5.tgz", + "integrity": "sha512-svL3uiZf1RwhH+cWrfZn3A4+U58wbP0tGVTLQPbjplZxZ8ROD9VLuNgsRniTlLe7OlSqR79RUehXgpBW/s0IQw==", "dev": true }, "longest": { "version": "1.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", + "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", "dev": true }, "loose-envify": { "version": "1.3.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", + "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", "dev": true, "requires": { "js-tokens": "^3.0.0" @@ -7512,7 +7754,8 @@ }, "lru-cache": { "version": "4.1.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.2.tgz", + "integrity": "sha512-wgeVXhrDwAWnIF/yZARsFnMBtdFXOg1b8RIrhilp+0iDYN4mdQcNZElDZ0e4B64BhaxeQ5zN7PMyvu7we1kPeQ==", "dev": true, "requires": { "pseudomap": "^1.0.2", @@ -7521,12 +7764,14 @@ }, "map-cache": { "version": "0.2.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", "dev": true }, "map-visit": { "version": "1.0.0", - "bundled": true, + "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" @@ -7534,7 +7779,8 @@ }, "md5-hex": { "version": "1.3.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/md5-hex/-/md5-hex-1.3.0.tgz", + "integrity": "sha1-0sSv6YPENwZiF5uMrRRSGRNQRsQ=", "dev": true, "requires": { "md5-o-matic": "^0.1.1" @@ -7542,12 +7788,14 @@ }, "md5-o-matic": { "version": "0.1.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/md5-o-matic/-/md5-o-matic-0.1.1.tgz", + "integrity": "sha1-givM1l4RfFFPqxdrJZRdVBAKA8M=", "dev": true }, "mem": { "version": "1.1.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", + "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", "dev": true, "requires": { "mimic-fn": "^1.0.0" @@ -7555,7 +7803,8 @@ }, "merge-source-map": { "version": "1.1.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz", + "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==", "dev": true, "requires": { "source-map": "^0.6.1" @@ -7563,14 +7812,16 @@ "dependencies": { "source-map": { "version": "0.6.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true } } }, "micromatch": { "version": "2.3.11", - "bundled": true, + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", "dev": true, "requires": { "arr-diff": "^2.0.0", @@ -7590,12 +7841,14 @@ }, "mimic-fn": { "version": "1.2.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", "dev": true }, "minimatch": { "version": "3.0.4", - "bundled": true, + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "requires": { "brace-expansion": "^1.1.7" @@ -7603,12 +7856,14 @@ }, "minimist": { "version": "0.0.8", - "bundled": true, + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", "dev": true }, "mixin-deep": { "version": "1.3.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", + "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", "dev": true, "requires": { "for-in": "^1.0.2", @@ -7617,7 +7872,8 @@ "dependencies": { "is-extendable": { "version": "1.0.1", - "bundled": true, + "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" @@ -7627,7 +7883,8 @@ }, "mkdirp": { "version": "0.5.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "dev": true, "requires": { "minimist": "0.0.8" @@ -7635,12 +7892,14 @@ }, "ms": { "version": "2.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true }, "nanomatch": { "version": "1.2.9", - "bundled": true, + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.9.tgz", + "integrity": "sha512-n8R9bS8yQ6eSXaV6jHUpKzD8gLsin02w1HSFiegwrs9E098Ylhw5jdyKPaYqvHknHaSCKTPp7C8dGCQ0q9koXA==", "dev": true, "requires": { "arr-diff": "^4.0.0", @@ -7659,24 +7918,28 @@ "dependencies": { "arr-diff": { "version": "4.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", "dev": true }, "array-unique": { "version": "0.3.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", "dev": true }, "kind-of": { "version": "6.0.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", "dev": true } } }, "normalize-package-data": { "version": "2.4.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", "dev": true, "requires": { "hosted-git-info": "^2.1.4", @@ -7687,7 +7950,8 @@ }, "normalize-path": { "version": "2.1.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", "dev": true, "requires": { "remove-trailing-separator": "^1.0.1" @@ -7695,7 +7959,8 @@ }, "npm-run-path": { "version": "2.0.2", - "bundled": true, + "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" @@ -7703,17 +7968,20 @@ }, "number-is-nan": { "version": "1.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", "dev": true }, "object-assign": { "version": "4.1.1", - "bundled": true, + "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", - "bundled": true, + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", "dev": true, "requires": { "copy-descriptor": "^0.1.0", @@ -7723,7 +7991,8 @@ "dependencies": { "define-property": { "version": "0.2.5", - "bundled": true, + "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" @@ -7733,7 +8002,8 @@ }, "object-visit": { "version": "1.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", "dev": true, "requires": { "isobject": "^3.0.0" @@ -7741,14 +8011,16 @@ "dependencies": { "isobject": { "version": "3.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", "dev": true } } }, "object.omit": { "version": "2.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", + "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", "dev": true, "requires": { "for-own": "^0.1.4", @@ -7757,7 +8029,8 @@ }, "object.pick": { "version": "1.3.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", "dev": true, "requires": { "isobject": "^3.0.1" @@ -7765,14 +8038,16 @@ "dependencies": { "isobject": { "version": "3.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", "dev": true } } }, "once": { "version": "1.4.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, "requires": { "wrappy": "1" @@ -7780,7 +8055,8 @@ }, "optimist": { "version": "0.6.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", + "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", "dev": true, "requires": { "minimist": "~0.0.1", @@ -7789,12 +8065,14 @@ }, "os-homedir": { "version": "1.0.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", "dev": true }, "os-locale": { "version": "2.1.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", + "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", "dev": true, "requires": { "execa": "^0.7.0", @@ -7804,12 +8082,14 @@ }, "p-finally": { "version": "1.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", "dev": true }, "p-limit": { "version": "1.2.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.2.0.tgz", + "integrity": "sha512-Y/OtIaXtUPr4/YpMv1pCL5L5ed0rumAaAeBSj12F+bSlMdys7i8oQF/GUJmfpTS/QoaRrS/k6pma29haJpsMng==", "dev": true, "requires": { "p-try": "^1.0.0" @@ -7817,7 +8097,8 @@ }, "p-locate": { "version": "2.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", "dev": true, "requires": { "p-limit": "^1.1.0" @@ -7825,12 +8106,14 @@ }, "p-try": { "version": "1.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", "dev": true }, "parse-glob": { "version": "3.0.4", - "bundled": true, + "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", + "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", "dev": true, "requires": { "glob-base": "^0.3.0", @@ -7841,7 +8124,8 @@ }, "parse-json": { "version": "2.2.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", "dev": true, "requires": { "error-ex": "^1.2.0" @@ -7849,12 +8133,14 @@ }, "pascalcase": { "version": "0.1.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", "dev": true }, "path-exists": { "version": "2.1.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", "dev": true, "requires": { "pinkie-promise": "^2.0.0" @@ -7862,22 +8148,26 @@ }, "path-is-absolute": { "version": "1.0.1", - "bundled": true, + "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", - "bundled": true, + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", "dev": true }, "path-parse": { "version": "1.0.5", - "bundled": true, + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", + "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", "dev": true }, "path-type": { "version": "1.1.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", "dev": true, "requires": { "graceful-fs": "^4.1.2", @@ -7887,17 +8177,20 @@ }, "pify": { "version": "2.3.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true }, "pinkie": { "version": "2.0.4", - "bundled": true, + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", "dev": true }, "pinkie-promise": { "version": "2.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", "dev": true, "requires": { "pinkie": "^2.0.0" @@ -7905,7 +8198,8 @@ }, "pkg-dir": { "version": "1.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz", + "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=", "dev": true, "requires": { "find-up": "^1.0.0" @@ -7913,7 +8207,8 @@ "dependencies": { "find-up": { "version": "1.1.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", "dev": true, "requires": { "path-exists": "^2.0.0", @@ -7924,22 +8219,26 @@ }, "posix-character-classes": { "version": "0.1.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", "dev": true }, "preserve": { "version": "0.2.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", + "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", "dev": true }, "pseudomap": { "version": "1.0.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", "dev": true }, "randomatic": { "version": "1.1.7", - "bundled": true, + "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz", + "integrity": "sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how==", "dev": true, "requires": { "is-number": "^3.0.0", @@ -7948,7 +8247,8 @@ "dependencies": { "is-number": { "version": "3.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, "requires": { "kind-of": "^3.0.2" @@ -7956,7 +8256,8 @@ "dependencies": { "kind-of": { "version": "3.2.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { "is-buffer": "^1.1.5" @@ -7966,7 +8267,8 @@ }, "kind-of": { "version": "4.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", "dev": true, "requires": { "is-buffer": "^1.1.5" @@ -7976,7 +8278,8 @@ }, "read-pkg": { "version": "1.1.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", "dev": true, "requires": { "load-json-file": "^1.0.0", @@ -7986,7 +8289,8 @@ }, "read-pkg-up": { "version": "1.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", "dev": true, "requires": { "find-up": "^1.0.0", @@ -7995,7 +8299,8 @@ "dependencies": { "find-up": { "version": "1.1.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", "dev": true, "requires": { "path-exists": "^2.0.0", @@ -8006,12 +8311,14 @@ }, "regenerator-runtime": { "version": "0.11.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", "dev": true }, "regex-cache": { "version": "0.4.4", - "bundled": true, + "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", + "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", "dev": true, "requires": { "is-equal-shallow": "^0.1.3" @@ -8019,7 +8326,8 @@ }, "regex-not": { "version": "1.0.2", - "bundled": true, + "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", @@ -8028,22 +8336,26 @@ }, "remove-trailing-separator": { "version": "1.1.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", "dev": true }, "repeat-element": { "version": "1.1.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", + "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=", "dev": true }, "repeat-string": { "version": "1.6.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", "dev": true }, "repeating": { "version": "2.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", "dev": true, "requires": { "is-finite": "^1.0.0" @@ -8051,32 +8363,38 @@ }, "require-directory": { "version": "2.1.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", "dev": true }, "require-main-filename": { "version": "1.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", "dev": true }, "resolve-from": { "version": "2.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", + "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=", "dev": true }, "resolve-url": { "version": "0.2.1", - "bundled": true, + "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", - "bundled": true, + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", "dev": true }, "right-align": { "version": "0.1.3", - "bundled": true, + "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", + "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", "dev": true, "optional": true, "requires": { @@ -8085,7 +8403,8 @@ }, "rimraf": { "version": "2.6.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", + "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", "dev": true, "requires": { "glob": "^7.0.5" @@ -8093,7 +8412,8 @@ }, "safe-regex": { "version": "1.1.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", "dev": true, "requires": { "ret": "~0.1.10" @@ -8101,17 +8421,20 @@ }, "semver": { "version": "5.5.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", "dev": true }, "set-blocking": { "version": "2.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "dev": true }, "set-value": { "version": "2.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", + "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", "dev": true, "requires": { "extend-shallow": "^2.0.1", @@ -8122,7 +8445,8 @@ "dependencies": { "extend-shallow": { "version": "2.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { "is-extendable": "^0.1.0" @@ -8132,7 +8456,8 @@ }, "shebang-command": { "version": "1.2.0", - "bundled": true, + "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" @@ -8140,22 +8465,26 @@ }, "shebang-regex": { "version": "1.0.0", - "bundled": true, + "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", - "bundled": true, + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", "dev": true }, "slide": { "version": "1.1.6", - "bundled": true, + "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz", + "integrity": "sha1-VusCfWW00tzmyy4tMsTUr8nh1wc=", "dev": true }, "snapdragon": { "version": "0.8.2", - "bundled": true, + "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", @@ -8170,7 +8499,8 @@ "dependencies": { "define-property": { "version": "0.2.5", - "bundled": true, + "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" @@ -8178,7 +8508,8 @@ }, "extend-shallow": { "version": "2.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { "is-extendable": "^0.1.0" @@ -8188,7 +8519,8 @@ }, "snapdragon-node": { "version": "2.1.1", - "bundled": true, + "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", @@ -8198,7 +8530,8 @@ "dependencies": { "define-property": { "version": "1.0.0", - "bundled": true, + "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" @@ -8206,7 +8539,8 @@ }, "is-accessor-descriptor": { "version": "1.0.0", - "bundled": true, + "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" @@ -8214,7 +8548,8 @@ }, "is-data-descriptor": { "version": "1.0.0", - "bundled": true, + "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" @@ -8222,7 +8557,8 @@ }, "is-descriptor": { "version": "1.0.2", - "bundled": true, + "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", @@ -8232,19 +8568,22 @@ }, "isobject": { "version": "3.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", "dev": true }, "kind-of": { "version": "6.0.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", "dev": true } } }, "snapdragon-util": { "version": "3.0.1", - "bundled": true, + "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" @@ -8252,12 +8591,14 @@ }, "source-map": { "version": "0.5.7", - "bundled": true, + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true }, "source-map-resolve": { "version": "0.5.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.1.tgz", + "integrity": "sha512-0KW2wvzfxm8NCTb30z0LMNyPqWCdDGE2viwzUaucqJdkTRXtZiSY3I+2A6nVAjmdOy0I4gU8DwnVVGsk9jvP2A==", "dev": true, "requires": { "atob": "^2.0.0", @@ -8269,12 +8610,14 @@ }, "source-map-url": { "version": "0.4.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", "dev": true }, "spawn-wrap": { "version": "1.4.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-1.4.2.tgz", + "integrity": "sha512-vMwR3OmmDhnxCVxM8M+xO/FtIp6Ju/mNaDfCMMW7FDcLRTPFWUswec4LXJHTJE2hwTI9O0YBfygu4DalFl7Ylg==", "dev": true, "requires": { "foreground-child": "^1.5.6", @@ -8287,7 +8630,8 @@ }, "spdx-correct": { "version": "3.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.0.tgz", + "integrity": "sha512-N19o9z5cEyc8yQQPukRCZ9EUmb4HUpnrmaL/fxS2pBo2jbfcFRVuFZ/oFC+vZz0MNNk0h80iMn5/S6qGZOL5+g==", "dev": true, "requires": { "spdx-expression-parse": "^3.0.0", @@ -8296,12 +8640,14 @@ }, "spdx-exceptions": { "version": "2.1.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz", + "integrity": "sha512-4K1NsmrlCU1JJgUrtgEeTVyfx8VaYea9J9LvARxhbHtVtohPs/gFGG5yy49beySjlIMhhXZ4QqujIZEfS4l6Cg==", "dev": true }, "spdx-expression-parse": { "version": "3.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", + "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", "dev": true, "requires": { "spdx-exceptions": "^2.1.0", @@ -8310,12 +8656,14 @@ }, "spdx-license-ids": { "version": "3.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz", + "integrity": "sha512-2+EPwgbnmOIl8HjGBXXMd9NAu02vLjOO1nWw4kmeRDFyHn+M/ETfHxQUK0oXg8ctgVnl9t3rosNVsZ1jG61nDA==", "dev": true }, "split-string": { "version": "3.1.0", - "bundled": true, + "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" @@ -8323,7 +8671,8 @@ }, "static-extend": { "version": "0.1.2", - "bundled": true, + "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", @@ -8332,7 +8681,8 @@ "dependencies": { "define-property": { "version": "0.2.5", - "bundled": true, + "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" @@ -8342,7 +8692,8 @@ }, "string-width": { "version": "2.1.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", @@ -8351,12 +8702,14 @@ "dependencies": { "ansi-regex": { "version": "3.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", "dev": true }, "strip-ansi": { "version": "4.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "dev": true, "requires": { "ansi-regex": "^3.0.0" @@ -8366,7 +8719,8 @@ }, "strip-ansi": { "version": "3.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { "ansi-regex": "^2.0.0" @@ -8374,7 +8728,8 @@ }, "strip-bom": { "version": "2.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", "dev": true, "requires": { "is-utf8": "^0.2.0" @@ -8382,17 +8737,20 @@ }, "strip-eof": { "version": "1.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", "dev": true }, "supports-color": { "version": "2.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", "dev": true }, "test-exclude": { "version": "4.2.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-4.2.1.tgz", + "integrity": "sha512-qpqlP/8Zl+sosLxBcVKl9vYy26T9NPalxSzzCP/OY6K7j938ui2oKgo+kRZYfxAeIpLqpbVnsHq1tyV70E4lWQ==", "dev": true, "requires": { "arrify": "^1.0.1", @@ -8404,17 +8762,20 @@ "dependencies": { "arr-diff": { "version": "4.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", "dev": true }, "array-unique": { "version": "0.3.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", "dev": true }, "braces": { "version": "2.3.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", "dev": true, "requires": { "arr-flatten": "^1.1.0", @@ -8431,7 +8792,8 @@ "dependencies": { "extend-shallow": { "version": "2.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { "is-extendable": "^0.1.0" @@ -8441,7 +8803,8 @@ }, "expand-brackets": { "version": "2.1.4", - "bundled": true, + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", "dev": true, "requires": { "debug": "^2.3.3", @@ -8455,7 +8818,8 @@ "dependencies": { "define-property": { "version": "0.2.5", - "bundled": true, + "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" @@ -8463,7 +8827,8 @@ }, "extend-shallow": { "version": "2.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { "is-extendable": "^0.1.0" @@ -8471,7 +8836,8 @@ }, "is-accessor-descriptor": { "version": "0.1.6", - "bundled": true, + "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" @@ -8479,7 +8845,8 @@ "dependencies": { "kind-of": { "version": "3.2.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { "is-buffer": "^1.1.5" @@ -8489,7 +8856,8 @@ }, "is-data-descriptor": { "version": "0.1.4", - "bundled": true, + "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" @@ -8497,7 +8865,8 @@ "dependencies": { "kind-of": { "version": "3.2.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { "is-buffer": "^1.1.5" @@ -8507,7 +8876,8 @@ }, "is-descriptor": { "version": "0.1.6", - "bundled": true, + "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", @@ -8517,14 +8887,16 @@ }, "kind-of": { "version": "5.1.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", "dev": true } } }, "extglob": { "version": "2.0.4", - "bundled": true, + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", "dev": true, "requires": { "array-unique": "^0.3.2", @@ -8539,7 +8911,8 @@ "dependencies": { "define-property": { "version": "1.0.0", - "bundled": true, + "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" @@ -8547,7 +8920,8 @@ }, "extend-shallow": { "version": "2.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { "is-extendable": "^0.1.0" @@ -8557,7 +8931,8 @@ }, "fill-range": { "version": "4.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", "dev": true, "requires": { "extend-shallow": "^2.0.1", @@ -8568,7 +8943,8 @@ "dependencies": { "extend-shallow": { "version": "2.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { "is-extendable": "^0.1.0" @@ -8578,7 +8954,8 @@ }, "is-accessor-descriptor": { "version": "1.0.0", - "bundled": true, + "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" @@ -8586,7 +8963,8 @@ }, "is-data-descriptor": { "version": "1.0.0", - "bundled": true, + "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" @@ -8594,7 +8972,8 @@ }, "is-descriptor": { "version": "1.0.2", - "bundled": true, + "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", @@ -8604,7 +8983,8 @@ }, "is-number": { "version": "3.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, "requires": { "kind-of": "^3.0.2" @@ -8612,7 +8992,8 @@ "dependencies": { "kind-of": { "version": "3.2.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { "is-buffer": "^1.1.5" @@ -8622,17 +9003,20 @@ }, "isobject": { "version": "3.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", "dev": true }, "kind-of": { "version": "6.0.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", "dev": true }, "micromatch": { "version": "3.1.10", - "bundled": true, + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", "dev": true, "requires": { "arr-diff": "^4.0.0", @@ -8654,12 +9038,14 @@ }, "to-fast-properties": { "version": "1.0.3", - "bundled": true, + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", + "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", "dev": true }, "to-object-path": { "version": "0.3.0", - "bundled": true, + "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" @@ -8667,7 +9053,8 @@ }, "to-regex": { "version": "3.0.2", - "bundled": true, + "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", @@ -8678,7 +9065,8 @@ }, "to-regex-range": { "version": "2.1.1", - "bundled": true, + "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", @@ -8687,7 +9075,8 @@ "dependencies": { "is-number": { "version": "3.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, "requires": { "kind-of": "^3.0.2" @@ -8697,12 +9086,14 @@ }, "trim-right": { "version": "1.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", + "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", "dev": true }, "uglify-js": { "version": "2.8.29", - "bundled": true, + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", + "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", "dev": true, "optional": true, "requires": { @@ -8713,7 +9104,8 @@ "dependencies": { "yargs": { "version": "3.10.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", + "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", "dev": true, "optional": true, "requires": { @@ -8727,13 +9119,15 @@ }, "uglify-to-browserify": { "version": "1.0.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", + "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", "dev": true, "optional": true }, "union-value": { "version": "1.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", + "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", "dev": true, "requires": { "arr-union": "^3.1.0", @@ -8744,7 +9138,8 @@ "dependencies": { "extend-shallow": { "version": "2.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { "is-extendable": "^0.1.0" @@ -8752,7 +9147,8 @@ }, "set-value": { "version": "0.4.3", - "bundled": true, + "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", + "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", "dev": true, "requires": { "extend-shallow": "^2.0.1", @@ -8765,7 +9161,8 @@ }, "unset-value": { "version": "1.0.0", - "bundled": true, + "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", @@ -8774,7 +9171,8 @@ "dependencies": { "has-value": { "version": "0.3.1", - "bundled": true, + "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", @@ -8784,7 +9182,8 @@ "dependencies": { "isobject": { "version": "2.1.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", "dev": true, "requires": { "isarray": "1.0.0" @@ -8794,24 +9193,28 @@ }, "has-values": { "version": "0.1.4", - "bundled": true, + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", "dev": true }, "isobject": { "version": "3.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", "dev": true } } }, "urix": { "version": "0.1.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", "dev": true }, "use": { "version": "3.1.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/use/-/use-3.1.0.tgz", + "integrity": "sha512-6UJEQM/L+mzC3ZJNM56Q4DFGLX/evKGRg15UJHGB9X5j5Z3AFbgZvjUh2yq/UJUY4U5dh7Fal++XbNg1uzpRAw==", "dev": true, "requires": { "kind-of": "^6.0.2" @@ -8819,14 +9222,16 @@ "dependencies": { "kind-of": { "version": "6.0.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", "dev": true } } }, "validate-npm-package-license": { "version": "3.0.3", - "bundled": true, + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.3.tgz", + "integrity": "sha512-63ZOUnL4SIXj4L0NixR3L1lcjO38crAbgrTpl28t8jjrfuiOBL5Iygm+60qPs/KsZGzPNg6Smnc/oY16QTjF0g==", "dev": true, "requires": { "spdx-correct": "^3.0.0", @@ -8835,7 +9240,8 @@ }, "which": { "version": "1.3.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", + "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", "dev": true, "requires": { "isexe": "^2.0.0" @@ -8843,23 +9249,27 @@ }, "which-module": { "version": "2.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", "dev": true }, "window-size": { "version": "0.1.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", + "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=", "dev": true, "optional": true }, "wordwrap": { "version": "0.0.3", - "bundled": true, + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", "dev": true }, "wrap-ansi": { "version": "2.1.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", "dev": true, "requires": { "string-width": "^1.0.1", @@ -8868,7 +9278,8 @@ "dependencies": { "is-fullwidth-code-point": { "version": "1.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "dev": true, "requires": { "number-is-nan": "^1.0.0" @@ -8876,7 +9287,8 @@ }, "string-width": { "version": "1.0.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "dev": true, "requires": { "code-point-at": "^1.0.0", @@ -8888,12 +9300,14 @@ }, "wrappy": { "version": "1.0.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, "write-file-atomic": { "version": "1.3.4", - "bundled": true, + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-1.3.4.tgz", + "integrity": "sha1-+Aek8LHZ6ROuekgRLmzDrxmRtF8=", "dev": true, "requires": { "graceful-fs": "^4.1.11", @@ -8903,17 +9317,20 @@ }, "y18n": { "version": "3.2.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", "dev": true }, "yallist": { "version": "2.1.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", "dev": true }, "yargs": { "version": "11.1.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz", + "integrity": "sha512-NwW69J42EsCSanF8kyn5upxvjp5ds+t3+udGBeTbFnERA+lF541DDpMawzo4z6W/QrzNM18D+BPMiOBibnFV5A==", "dev": true, "requires": { "cliui": "^4.0.0", @@ -8932,17 +9349,20 @@ "dependencies": { "ansi-regex": { "version": "3.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", "dev": true }, "camelcase": { "version": "4.1.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", "dev": true }, "cliui": { "version": "4.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.0.0.tgz", + "integrity": "sha512-nY3W5Gu2racvdDk//ELReY+dHjb9PlIcVDFXP72nVIhq2Gy3LuVXYwJoPVudwQnv1shtohpgkdCKT2YaKY0CKw==", "dev": true, "requires": { "string-width": "^2.1.1", @@ -8952,7 +9372,8 @@ }, "strip-ansi": { "version": "4.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "dev": true, "requires": { "ansi-regex": "^3.0.0" @@ -8960,7 +9381,8 @@ }, "yargs-parser": { "version": "9.0.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-9.0.2.tgz", + "integrity": "sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc=", "dev": true, "requires": { "camelcase": "^4.1.0" @@ -8970,7 +9392,8 @@ }, "yargs-parser": { "version": "8.1.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-8.1.0.tgz", + "integrity": "sha512-yP+6QqN8BmrgW2ggLtTbdrOyBNSI7zBa4IykmiV5R1wl1JWNxQvWhMfMdmzIYtKU7oP3OOInY/tl2ov3BDjnJQ==", "dev": true, "requires": { "camelcase": "^4.1.0" @@ -8978,7 +9401,8 @@ "dependencies": { "camelcase": { "version": "4.1.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", "dev": true } } @@ -11833,9 +12257,9 @@ } }, "uuid": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz", - "integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g==" + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz", + "integrity": "sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA==" }, "v8flags": { "version": "3.0.1", diff --git a/package.json b/package.json index d6f0f0ddc3..25249ca5da 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ "dockerode": "^2.5.5", "elegant-spinner": "^1.0.1", "escape-string-regexp": "^1.0.5", + "fb-watchman": "^2.0.0", "fs-extra": "^5.0.0", "has-ansi": "^3.0.0", "ignore": "^3.3.7", @@ -52,7 +53,8 @@ "sywac": "^1.2.0", "ts-stream": "^1.0.1", "typescript-memoize": "^1.0.0-alpha.3", - "winston": "^3.0.0-rc5" + "uuid": "^3.2.1", + "winston": "^3.0.0-rc3" }, "devDependencies": { "@types/bluebird": "^3.5.18", @@ -70,7 +72,6 @@ "@types/node": "^8.10.10", "@types/node-emoji": "^1.8.0", "@types/prettyjson": "0.0.28", - "@types/yargs": "^11.0.0", "chai": "^4.1.2", "gulp": "^4.0.0", "gulp-cached": "^1.1.1", diff --git a/src/commands/build.ts b/src/commands/build.ts index 97a1fd7685..a5b73620e2 100644 --- a/src/commands/build.ts +++ b/src/commands/build.ts @@ -6,7 +6,6 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import chalk from "chalk" import { PluginContext } from "../plugin-context" import { BooleanParameter, Command, ParameterValues, StringParameter } from "./base" import { BuildTask } from "../tasks/build" @@ -21,6 +20,7 @@ export const buildArguments = { export const buildOptions = { force: new BooleanParameter({ help: "Force rebuild of module(s)" }), + watch: new BooleanParameter({ help: "Watch for changes in module(s) and auto-build", alias: "w" }), } export type BuildArguments = ParameterValues @@ -36,19 +36,16 @@ export class BuildCommand extends Command { await ctx.clearBuilds() const names = args.module ? args.module.split(",") : undefined - const modules = await ctx.getModules(names) - - for (const module of values(modules)) { - const task = new BuildTask(ctx, module, opts.force) - await ctx.addTask(task) - } + const modules = values(await ctx.getModules(names)) ctx.log.header({ emoji: "hammer", command: "build" }) - const result = await ctx.processTasks() + const result = await ctx.processModules(modules, opts.watch, async (module) => { + await ctx.addTask(new BuildTask(ctx, module, opts.force)) + }) ctx.log.info("") - ctx.log.info({ emoji: "heavy_check_mark", msg: chalk.green("Done!\n") }) + ctx.log.header({ emoji: "heavy_check_mark", command: `Done!` }) return result } diff --git a/src/commands/deploy.ts b/src/commands/deploy.ts index 9fda175525..3d6ad8644f 100644 --- a/src/commands/deploy.ts +++ b/src/commands/deploy.ts @@ -7,9 +7,10 @@ */ import { PluginContext } from "../plugin-context" +import { DeployTask } from "../tasks/deploy" import { BooleanParameter, Command, ParameterValues, StringParameter } from "./base" -import chalk from "chalk" import { TaskResults } from "../task-graph" +import { values } from "lodash" export const deployArgs = { service: new StringParameter({ @@ -21,6 +22,7 @@ export const deployArgs = { export const deployOpts = { force: new BooleanParameter({ help: "Force redeploy of service(s)" }), "force-build": new BooleanParameter({ help: "Force rebuild of module(s)" }), + watch: new BooleanParameter({ help: "Watch for changes in module(s) and auto-deploy", alias: "w" }), } export type Args = ParameterValues @@ -34,21 +36,34 @@ export class DeployCommand extends Command options = deployOpts async action(ctx: PluginContext, args: Args, opts: Opts): Promise { - ctx.log.header({ emoji: "rocket", command: "Deploy" }) - const names = args.service ? args.service.split(",") : undefined + const services = await ctx.getServices(names) + + if (Object.keys(services).length === 0) { + ctx.log.warn({ msg: "No services found. Aborting." }) + return {} + } + + ctx.log.header({ emoji: "rocket", command: "Deploy" }) // TODO: make this a task await ctx.configureEnvironment() - const result = await ctx.deployServices({ - names, - force: !!opts.force, - forceBuild: !!opts["force-build"], + const watch = opts.watch + const force = opts.force + const forceBuild = opts["force-build"] + + const modules = Array.from(new Set(values(services).map(s => s.module))) + + const result = await ctx.processModules(modules, watch, async (module) => { + const servicesToDeploy = values(await module.getServices()).filter(s => !!services[s.name]) + for (const service of servicesToDeploy) { + await ctx.addTask(new DeployTask(ctx, service, force, forceBuild)) + } }) ctx.log.info("") - ctx.log.info({ emoji: "heavy_check_mark", msg: chalk.green("Done!\n") }) + ctx.log.header({ emoji: "heavy_check_mark", command: `Done!` }) return result } diff --git a/src/commands/dev.ts b/src/commands/dev.ts index b4f892a8cc..2166420ba4 100644 --- a/src/commands/dev.ts +++ b/src/commands/dev.ts @@ -7,14 +7,18 @@ */ import { PluginContext } from "../plugin-context" +import { BuildTask } from "../tasks/build" +import { Task } from "../types/task" import { Command } from "./base" import { join } from "path" import { STATIC_DIR } from "../constants" import { spawnSync } from "child_process" import chalk from "chalk" -import { sleep } from "../util" +import Bluebird = require("bluebird") +import { values } from "lodash" +import moment = require("moment") -const imgcatPath = join(__dirname, "..", "..", "bin", "imgcat") +const imgcatPath = join(STATIC_DIR, "imgcat") const bannerPath = join(STATIC_DIR, "garden-banner-1-half.png") export class DevCommand extends Command { @@ -26,24 +30,48 @@ export class DevCommand extends Command { spawnSync(imgcatPath, [bannerPath], { stdio: "inherit", }) - console.log() } catch (_) { // the above fails for terminals other than iTerm2. just ignore the error and move on. } - // console.log(chalk.bold(` garden - dev\n`)) - console.log(chalk.gray.italic(` Good afternoon, Jon! Let's get your environment wired up...\n`)) + ctx.log.info(chalk.gray.italic(`\nGood ${getGreetingTime()}! Let's get your environment wired up...\n`)) await ctx.configureEnvironment() - await ctx.deployServices({}) - ctx.log.info({ msg: "" }) - const watchEntry = ctx.log.info({ emoji: "koala", msg: `Waiting for code changes...` }) + const modules = values(await ctx.getModules()) - while (true) { - // TODO: actually do stuff - await sleep(10000) - watchEntry.setState({ emoji: "koala", msg: `Waiting for code changes...` }) + if (modules.length === 0) { + if (modules.length === 0) { + ctx.log.info({ msg: "No modules found in project." }) + } + ctx.log.info({ msg: "Aborting..." }) + return } + + await ctx.processModules(modules, true, async (module) => { + const testTasks: Task[] = await module.getTestTasks({}) + const deployTasks = await module.getDeployTasks({}) + const tasks = testTasks.concat(deployTasks) + + if (tasks.length === 0) { + await ctx.addTask(new BuildTask(ctx, module, false)) + } else { + await Bluebird.map(tasks, ctx.addTask) + } + }) + } +} + +function getGreetingTime() { + const m = moment() + + const currentHour = parseFloat(m.format("HH")) + + if (currentHour >= 17) { + return "evening" + } else if (currentHour >= 12) { + return "afternoon" + } else { + return "morning" } } diff --git a/src/commands/test.ts b/src/commands/test.ts index 86cf363be4..591f961a13 100644 --- a/src/commands/test.ts +++ b/src/commands/test.ts @@ -8,11 +8,10 @@ import { PluginContext } from "../plugin-context" import { BooleanParameter, Command, ParameterValues, StringParameter } from "./base" -import { values, padEnd } from "lodash" -import { TestTask } from "../tasks/test" -import { splitFirst } from "../util" +import { values } from "lodash" import chalk from "chalk" import { TaskResults } from "../task-graph" +import Bluebird = require("bluebird") export const testArgs = { module: new StringParameter({ @@ -28,6 +27,7 @@ export const testOpts = { }), force: new BooleanParameter({ help: "Force re-test of module(s)", alias: "f" }), "force-build": new BooleanParameter({ help: "Force rebuild of module(s)" }), + watch: new BooleanParameter({ help: "Watch for changes in module(s) and auto-test", alias: "w" }), } export type Args = ParameterValues @@ -42,7 +42,7 @@ export class TestCommand extends Command { async action(ctx: PluginContext, args: Args, opts: Opts): Promise { const names = args.module ? args.module.split(",") : undefined - const modules = await ctx.getModules(names) + const modules = values(await ctx.getModules(names)) ctx.log.header({ emoji: "thermometer", @@ -51,47 +51,19 @@ export class TestCommand extends Command { await ctx.configureEnvironment() - for (const module of values(modules)) { - const config = await module.getConfig() + const group = opts.group + const force = opts.force + const forceBuild = opts["force-build"] - for (const testGroup of Object.keys(config.test)) { - if (opts.group && testGroup !== opts.group) { - continue - } - const testSpec = config.test[testGroup] - const task = new TestTask(ctx, module, testGroup, testSpec, opts.force, opts["force-build"]) - await ctx.addTask(task) - } - } - - const results = await ctx.processTasks() - let failed = 0 - - for (const key in results) { - // TODO: this is brittle, we should have a more verbose data structure coming out of the TaskGraph - const [type, taskKey] = splitFirst(key, ".") - - if (type !== "test") { - continue - } - - const result = results[key] - - if (!result.success) { - const [moduleName, testType] = splitFirst(taskKey, ".") - const divider = padEnd("—", 80) - - ctx.log.error(`${testType} tests for ${moduleName} failed. Here is the output:`) - ctx.log.error(divider) - ctx.log.error(result.output) - ctx.log.error(divider + "\n") + const results = await ctx.processModules(modules, opts.watch, async (module) => { + const tasks = await module.getTestTasks({ group, force, forceBuild }) + await Bluebird.map(tasks, ctx.addTask) + }) - failed++ - } - } + const failed = values(results).filter(r => !!r.error).length if (failed) { - ctx.log.error({ emoji: "warning", msg: `${failed} tests runs failed! See log output above.\n` }) + ctx.log.error({ emoji: "warning", msg: `${failed} test runs failed! See log output above.\n` }) } else { ctx.log.info("") ctx.log.info({ emoji: "heavy_check_mark", msg: chalk.green(` All tests passing!\n`) }) diff --git a/src/garden.ts b/src/garden.ts index cee827f19b..a3101d297b 100644 --- a/src/garden.ts +++ b/src/garden.ts @@ -59,7 +59,6 @@ import { VcsHandler } from "./vcs/base" import { GitHandler } from "./vcs/git" import { BuildDir } from "./build-dir" import { - Task, TaskGraph, TaskResults, } from "./task-graph" @@ -90,6 +89,7 @@ import { GardenConfig, loadConfig, } from "./types/config" +import { Task } from "./types/task" export interface ModuleMap { [key: string]: T diff --git a/src/plugin-context.ts b/src/plugin-context.ts index 6c26177d00..591f3c554e 100644 --- a/src/plugin-context.ts +++ b/src/plugin-context.ts @@ -16,6 +16,7 @@ import { LogEntry, } from "./logger" import { EntryStyle } from "./logger/types" +import { TaskResults } from "./task-graph" import { DeployTask } from "./tasks/deploy" import { PrimitiveMap, @@ -50,8 +51,17 @@ import { mapValues, toPairs, values, + padEnd, } from "lodash" +import { + registerCleanupFunction, + sleep, +} from "./util" import { TreeVersion } from "./vcs/base" +import { + computeAutoReloadDependants, + FSWatcher, +} from "./watch" export type PluginContextGuard = { readonly [P in keyof (PluginActionParams | ModuleActionParams)]: (...args: any[]) => Promise @@ -87,8 +97,12 @@ export interface PluginContext extends PluginContextGuard, WrappedFromGarden { module: T, buildContext: PrimitiveMap, logEntry?: LogEntry, ) => Promise pushModule: (module: T, logEntry?: LogEntry) => Promise - testModule: (module: T, testSpec: TestSpec, logEntry?: LogEntry) => Promise - getTestResult: (module: T, version: TreeVersion, logEntry?: LogEntry) => Promise + testModule: ( + module: T, testName: string, testSpec: TestSpec, logEntry?: LogEntry, + ) => Promise + getTestResult: ( + module: T, testName: string, version: TreeVersion, logEntry?: LogEntry, + ) => Promise getEnvironmentStatus: () => Promise configureEnvironment: () => Promise destroyEnvironment: () => Promise @@ -110,6 +124,9 @@ export interface PluginContext extends PluginContextGuard, WrappedFromGarden { deployServices: ( params: { names?: string[], force?: boolean, forceBuild?: boolean, logEntry?: LogEntry }, ) => Promise + processModules: ( + modules: Module[], watch: boolean, process: (module: Module) => Promise, + ) => Promise } export function createPluginContext(garden: Garden): PluginContext { @@ -183,17 +200,19 @@ export function createPluginContext(garden: Garden): PluginContext { return handler({ ...commonParams(handler), module, logEntry }) }, - testModule: async (module: T, testSpec: TestSpec, logEntry?: LogEntry) => { + testModule: async (module: T, testName: string, testSpec: TestSpec, logEntry?: LogEntry) => { const defaultHandler = garden.getModuleActionHandler("testModule", "generic") const handler = garden.getModuleActionHandler("testModule", module.type, defaultHandler) const env = garden.getEnvironment() - return handler({ ...commonParams(handler), module, testSpec, env, logEntry }) + return handler({ ...commonParams(handler), module, testName, testSpec, env, logEntry }) }, - getTestResult: async (module: T, version: TreeVersion, logEntry?: LogEntry) => { + getTestResult: async ( + module: T, testName: string, version: TreeVersion, logEntry?: LogEntry, + ) => { const handler = garden.getModuleActionHandler("getTestResult", module.type, async () => null) const env = garden.getEnvironment() - return handler({ ...commonParams(handler), module, version, env, logEntry }) + return handler({ ...commonParams(handler), module, testName, version, env, logEntry }) }, getEnvironmentStatus: async () => { @@ -332,6 +351,65 @@ export function createPluginContext(garden: Garden): PluginContext { return ctx.processTasks() }, + + processModules: async (modules: Module[], watch: boolean, process: (module: Module) => Promise) => { + // TODO: log errors as they happen, instead of after processing all tasks + const logErrors = (taskResults: TaskResults) => { + for (const result of values(taskResults).filter(r => !!r.error)) { + const divider = padEnd("", 80, "—") + + ctx.log.error(`\nFailed ${result.description}. Here is the output:`) + ctx.log.error(divider) + ctx.log.error(result.error + "") + ctx.log.error(divider + "\n") + } + } + + for (const module of modules) { + await process(module) + } + + const results = await ctx.processTasks() + logErrors(results) + + if (!watch) { + return results + } + + const autoReloadDependants = await computeAutoReloadDependants(modules) + + async function handleChanges(module: Module) { + await process(module) + + const dependantsForModule = autoReloadDependants[module.name] + if (!dependantsForModule) { + return + } + + for (const dependant of dependantsForModule) { + await handleChanges(dependant) + } + } + + const watcher = new FSWatcher(ctx.projectRoot) + + // TODO: should the prefix here be different or set explicitly per run? + await watcher.watchModules(modules, "addTasksForAutoReload/", + async (changedModule) => { + ctx.log.debug({ msg: `Files changed for module ${changedModule.name}` }) + await handleChanges(changedModule) + logErrors(await ctx.processTasks()) + }) + + registerCleanupFunction("clearAutoReloadWatches", () => { + watcher.end() + ctx.log.info({ msg: "\nDone!" }) + }) + + while (true) { + await sleep(1000) + } + }, } return ctx diff --git a/src/plugins/generic.ts b/src/plugins/generic.ts index f5e7cee2a0..18c5687058 100644 --- a/src/plugins/generic.ts +++ b/src/plugins/generic.ts @@ -67,13 +67,15 @@ export const genericPlugin = { } }, - async testModule({ module, testSpec }: TestModuleParams): Promise { + async testModule({ module, testName, testSpec }: TestModuleParams): Promise { const startedAt = new Date() const result = await spawn( testSpec.command[0], testSpec.command.slice(1), { cwd: module.path, ignoreError: true }, ) return { + moduleName: module.name, + testName, version: await module.getVersion(), success: result.code === 0, startedAt, diff --git a/src/plugins/kubernetes/actions.ts b/src/plugins/kubernetes/actions.ts index cf0af9847d..02dfe1f546 100644 --- a/src/plugins/kubernetes/actions.ts +++ b/src/plugins/kubernetes/actions.ts @@ -55,7 +55,14 @@ export async function getEnvironmentStatus({ ctx, provider }: GetEnvironmentStat } catch (err) { // TODO: catch error properly if (err.output) { - throw new DeploymentError(err.output, { output: err.output }) + throw new DeploymentError( + `Unable to connect to Kubernetes cluster. ` + + `Please make sure it is running, reachable and that you have the right context configured.`, + { + context, + kubectlOutput: err.output, + }, + ) } throw err } @@ -169,7 +176,7 @@ export async function execInService( } export async function testModule( - { ctx, provider, module, testSpec }: TestModuleParams, + { ctx, provider, module, testName, testSpec }: TestModuleParams, ): Promise { // TODO: include a service context here const context = provider.config.context @@ -203,6 +210,8 @@ export async function testModule( const res = await kubectl(context, getAppNamespace(ctx, provider)).tty(kubecmd, { ignoreError: true, timeout }) const testResult: TestResult = { + moduleName: module.name, + testName, version, success: res.code === 0, startedAt, @@ -211,7 +220,7 @@ export async function testModule( } const ns = getMetadataNamespace(ctx, provider) - const resultKey = `test-result--${module.name}--${version.versionString}` + const resultKey = getTestResultKey(module, testName, version) const body = { body: { apiVersion: "v1", @@ -233,11 +242,11 @@ export async function testModule( } export async function getTestResult( - { ctx, provider, module, version }: GetTestResultParams, + { ctx, provider, module, testName, version }: GetTestResultParams, ) { const context = provider.config.context const ns = getMetadataNamespace(ctx, provider) - const resultKey = getTestResultKey(module, version) + const resultKey = getTestResultKey(module, testName, version) const res = await apiGetOrNull(coreApi(context, ns).namespaces.configmaps, resultKey) return res && deserializeKeys(res.data) } @@ -322,6 +331,6 @@ export async function deleteConfig({ ctx, provider, key }: DeleteConfigParams) { return { found: true } } -function getTestResultKey(module: ContainerModule, version: TreeVersion) { - return `test-result--${module.name}--${version.versionString}` +function getTestResultKey(module: ContainerModule, testName: string, version: TreeVersion) { + return `test-result--${module.name}--${testName}--${version.versionString}` } diff --git a/src/task-graph.ts b/src/task-graph.ts index 6398122b21..aa3d3da113 100644 --- a/src/task-graph.ts +++ b/src/task-graph.ts @@ -9,47 +9,34 @@ import * as Bluebird from "bluebird" import chalk from "chalk" import { pick } from "lodash" +import { Task, TaskDefinitionError } from "./types/task" import { EntryStyle, LogSymbolType } from "./logger/types" import { LogEntry } from "./logger" import { PluginContext } from "./plugin-context" -class TaskDefinitionError extends Error { } class TaskGraphError extends Error { } +export interface TaskResult { + type: string + description: string + output?: any + dependencyResults?: TaskResults + error?: any +} + +/* + When multiple tasks with the same baseKey are completed during a call to processTasks, + the result from the last processed is used (hence only one key-value pair here per baseKey). + */ export interface TaskResults { - [key: string]: any + [baseKey: string]: TaskResult } interface LogEntryMap { [key: string]: LogEntry } const DEFAULT_CONCURRENCY = 4 -export abstract class Task { - abstract type: string - - key?: string - dependencies: Task[] - - constructor() { - this.dependencies = [] - } - - async getDependencies(): Promise { - return this.dependencies - } - - getKey(): string { - if (!this.key) { - throw new TaskDefinitionError("Missing key") - } - - return this.key - } - - abstract async process(dependencyResults: TaskResults): Promise -} - const taskStyle = chalk.cyan.bold function inProgressToStr(nodes) { @@ -68,51 +55,71 @@ export class TaskGraph { private inProgress: TaskNodeMap private logEntryMap: LogEntryMap + private opQueue: OperationQueue + constructor(private ctx: PluginContext, private concurrency: number = DEFAULT_CONCURRENCY) { this.roots = new TaskNodeMap() this.index = new TaskNodeMap() this.inProgress = new TaskNodeMap() + this.opQueue = new OperationQueue(this) this.logEntryMap = {} } - async addTask(task: Task) { - // TODO: Detect circular dependencies. - const node = this.getNode(task) + addTask(task: Task): Promise { + return this.opQueue.request({ type: "addTask", task }) + } - for (const d of await task.getDependencies()) { - node.addDependency(this.getNode(d)) + async addTaskInternal(task: Task) { + // TODO: Detect circular dependencies. + const predecessor = this.getPredecessor(task) + let node = this.getNode(task) + + if (predecessor) { + /* + predecessor is already in the graph, having the same baseKey as task, + but a different key (see the getPredecessor method below). + */ + if (this.inProgress.contains(predecessor)) { + this.index.addNode(node) + /* + We transition + [dependencies] > predecessor > [dependants] + to + [dependencies] > predecessor > node > [dependants] + */ + this.inherit(predecessor, node) + return + } else { + node = predecessor // No need to add a new TaskNode. + } } - const nodeDependencies = node.getDependencies() + this.index.addNode(node) + await this.addDependencies(node) - if (nodeDependencies.length === 0) { + if (node.getDependencies().length === 0) { this.roots.addNode(node) } else { - for (const d of nodeDependencies) { - await this.addTask(d.task) - d.addDependant(node) - } + await this.addDependants(node) } } private getNode(task: Task): TaskNode { const existing = this.index.getNode(task) + return existing || new TaskNode(task) + } - if (existing) { - return existing - } else { - const node = new TaskNode(task) - this.index.addNode(node) - return node - } + processTasks(): Promise { + return this.opQueue.request({ type: "processTasks" }) } /* Process the graph until it's complete */ - async processTasks(): Promise { - const results = {} + async processTasksInternal(): Promise { + const _this = this + const results: TaskResults = {} const loop = async () => { if (_this.index.length === 0) { @@ -130,16 +137,24 @@ export class TaskGraph { this.initLogging() return Bluebird.map(batch, async (node: TaskNode) => { - const key = node.getKey() + const type = node.getType() + const baseKey = node.getBaseKey() + const description = node.getDescription() try { this.logTask(node) this.logEntryMap.inProgress.setState(inProgressToStr(this.inProgress.getNodes())) - const dependencyKeys = (await node.task.getDependencies()).map(d => getIndexKey(d)) - const dependencyResults = pick(results, dependencyKeys) + const dependencyBaseKeys = (await node.task.getDependencies()) + .map(task => task.getBaseKey()) - results[key] = await node.process(dependencyResults) + const dependencyResults = pick(results, dependencyBaseKeys) + + try { + results[baseKey] = await node.process(dependencyResults) + } catch (error) { + results[baseKey] = { type, description, error } + } } finally { this.completeTask(node) } @@ -166,11 +181,54 @@ export class TaskGraph { } } + this.remove(node) + this.logTaskComplete(node) + } + + private getPredecessor(task: Task): TaskNode | null { + const key = task.getKey() + const baseKey = task.getBaseKey() + const predecessors = this.index.getNodes() + .filter(n => n.getBaseKey() === baseKey && n.getKey() !== key) + .reverse() + return predecessors[0] || null + } + + private async addDependencies(node: TaskNode) { + const task = node.task + for (const d of await task.getDependencies()) { + const dependency = this.getPredecessor(d) || this.getNode(d) + this.index.addNode(dependency) + node.addDependency(dependency) + } + } + + private async addDependants(node: TaskNode) { + const nodeDependencies = node.getDependencies() + for (const d of nodeDependencies) { + const dependant = this.getPredecessor(d.task) || d + await this.addTaskInternal(dependant.task) + dependant.addDependant(node) + } + } + + private inherit(oldNode: TaskNode, newNode: TaskNode) { + oldNode.getDependants().forEach(node => { + newNode.addDependant(node) + oldNode.removeDependant(node) + node.removeDependency(oldNode) + node.addDependency(newNode) + }) + + newNode.addDependency(oldNode) + oldNode.addDependant(newNode) + } + + // Should only be called when node is not a dependant for any task. + private remove(node: TaskNode) { this.roots.removeNode(node) this.index.removeNode(node) this.inProgress.removeNode(node) - - this.logTaskComplete(node) } // Logging @@ -215,48 +273,48 @@ function getIndexKey(task: Task) { throw new TaskDefinitionError("Tasks must define a type and a key") } - return `${task.type}.${key}` + return key } class TaskNodeMap { - index: { [key: string]: TaskNode } + // Map is used here to facilitate in-order traversal. + index: Map length: number constructor() { - this.index = {} + this.index = new Map() this.length = 0 } getNode(task: Task) { const indexKey = getIndexKey(task) - return this.index[indexKey] + const element = this.index.get(indexKey) + return element } - addNode(node: TaskNode) { - const indexKey = getIndexKey(node.task) + addNode(node: TaskNode): void { + const indexKey = node.getKey() - if (!this.index[indexKey]) { - this.index[indexKey] = node + if (!this.index.get(indexKey)) { + this.index.set(indexKey, node) this.length++ } } - removeNode(node: TaskNode) { - const indexKey = getIndexKey(node.task) - - if (this.index[indexKey]) { - delete this.index[indexKey] + removeNode(node: TaskNode): void { + if (this.index.delete(node.getKey())) { this.length-- } } - getNodes() { - return Object.keys(this.index).map(k => this.index[k]) + getNodes(): TaskNode[] { + return Array.from(this.index.values()) } - contains(node: TaskNode) { - return this.index.hasOwnProperty(node.getKey()) + contains(node: TaskNode): boolean { + return this.index.has(node.getKey()) } + } class TaskNode { @@ -283,6 +341,10 @@ class TaskNode { this.dependencies.removeNode(node) } + removeDependant(node: TaskNode) { + this.dependants.removeNode(node) + } + getDependencies() { return this.dependencies.getNodes() } @@ -291,11 +353,117 @@ class TaskNode { return this.dependants.getNodes() } + getBaseKey() { + return this.task.getBaseKey() + } + getKey() { return getIndexKey(this.task) } + getDescription() { + return this.task.getDescription() + } + + getType() { + return this.task.type + } + + // For testing/debugging purposes + inspect(): object { + return { + key: this.getKey(), + dependencies: this.getDependencies().map(d => d.getKey()), + dependants: this.getDependants().map(d => d.getKey()), + } + } + async process(dependencyResults: TaskResults) { - return await this.task.process(dependencyResults) + const output = await this.task.process(dependencyResults) + + return { + type: this.getType(), + description: this.getDescription(), + output, + dependencyResults, + } + } +} + +// TODO: Add more typing to this class. + +/* + Used by TaskGraph to prevent race conditions e.g. when calling addTask or + processTasks. +*/ +class OperationQueue { + queue: object[] + draining: boolean + + constructor(private taskGraph: TaskGraph) { + this.queue = [] + this.draining = false } + + request(opRequest): Promise { + let findFn + + switch (opRequest.type) { + + case "addTask": + findFn = (o) => o.type === "addTask" && o.task.getBaseKey() === opRequest.task.getBaseKey() + break + + case "processTasks": + findFn = (o) => o.type === "processTasks" + break + } + + const existingOp = this.queue.find(findFn) + + const prom = new Promise((resolver) => { + if (existingOp) { + existingOp["resolvers"].push(resolver) + } else { + this.queue.push({ ...opRequest, resolvers: [resolver] }) + } + }) + + if (!this.draining) { + this.process() + } + + return prom + } + + async process() { + this.draining = true + const op = this.queue.shift() + + if (!op) { + this.draining = false + return + } + + switch (op["type"]) { + + case "addTask": + const task = op["task"] + await this.taskGraph.addTaskInternal(task) + for (const resolver of op["resolvers"]) { + resolver() + } + break + + case "processTasks": + const results = await this.taskGraph.processTasksInternal() + for (const resolver of op["resolvers"]) { + resolver(results) + } + break + } + + this.process() + } + } diff --git a/src/tasks/build.ts b/src/tasks/build.ts index 93287a2c25..bd3ee0a9ee 100644 --- a/src/tasks/build.ts +++ b/src/tasks/build.ts @@ -6,13 +6,13 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +import chalk from "chalk" +import { round } from "lodash" import { PluginContext } from "../plugin-context" -import { Task } from "../task-graph" import { Module } from "../types/module" import { EntryStyle } from "../logger/types" -import chalk from "chalk" -import { round } from "lodash" import { BuildResult } from "../types/plugin" +import { Task } from "../types/task" export class BuildTask extends Task { type = "build" @@ -26,11 +26,14 @@ export class BuildTask extends Task { return deps.map((m: M) => new BuildTask(this.ctx, m, this.force)) } - getKey() { - // TODO: Include version in the task key (may need to make this method async). + protected getName() { return this.module.name } + getDescription() { + return `building ${this.module.name}` + } + async process(): Promise { if (!this.force && (await this.ctx.getModuleBuildStatus(this.module)).ready) { // this is necessary in case other modules depend on files from this one diff --git a/src/tasks/deploy.ts b/src/tasks/deploy.ts index 30d16d8eb3..dba4c63963 100644 --- a/src/tasks/deploy.ts +++ b/src/tasks/deploy.ts @@ -8,9 +8,9 @@ import { LogEntry } from "../logger" import { PluginContext } from "../plugin-context" -import { Task } from "../task-graph" import { BuildTask } from "./build" import { values } from "lodash" +import { Task } from "../types/task" import { Service, ServiceStatus, @@ -41,11 +41,14 @@ export class DeployTask> extends Task { return deps } - getKey() { - // TODO: Include version in the task key (may need to make this method async). + protected getName() { return this.service.name } + getDescription() { + return `deploying service ${this.service.name} (from module ${this.service.module.name})` + } + async process(): Promise { const entry = (this.logEntry || this.ctx.log).info({ section: this.service.name, diff --git a/src/tasks/push.ts b/src/tasks/push.ts index ef6c658e5c..637c5aad03 100644 --- a/src/tasks/push.ts +++ b/src/tasks/push.ts @@ -7,12 +7,12 @@ */ import chalk from "chalk" -import { Task } from "../task-graph" import { PluginContext } from "../plugin-context" import { BuildTask } from "./build" import { Module } from "../types/module" import { EntryStyle } from "../logger/types" import { PushResult } from "../types/plugin" +import { Task } from "../types/task" export class PushTask> extends Task { type = "push" @@ -31,11 +31,15 @@ export class PushTask> extends Task { return [new BuildTask(this.ctx, this.module, this.forceBuild)] } - getKey() { + getName() { // TODO: Include version in the task key (may need to make this method async). return this.module.name } + getDescription() { + return `pushing module ${this.module.name}` + } + async process(): Promise { if (!(await this.module.getConfig()).allowPush) { this.ctx.log.info({ diff --git a/src/tasks/test.ts b/src/tasks/test.ts index 2333546e4a..a37db72d5c 100644 --- a/src/tasks/test.ts +++ b/src/tasks/test.ts @@ -7,20 +7,26 @@ */ import { PluginContext } from "../plugin-context" -import { Task } from "../task-graph" import { Module, TestSpec } from "../types/module" import { BuildTask } from "./build" -import { TestResult } from "../types/plugin" import { DeployTask } from "./deploy" +import { TestResult } from "../types/plugin" +import { Task } from "../types/task" import { EntryStyle } from "../logger/types" import chalk from "chalk" +class TestError extends Error { + toString() { + return this.message + } +} + export class TestTask extends Task { type = "test" constructor( private ctx: PluginContext, - private module: T, private testType: string, private testSpec: TestSpec, + private module: T, private testName: string, private testSpec: TestSpec, private force: boolean, private forceBuild: boolean, ) { super() @@ -37,7 +43,7 @@ export class TestTask extends Task { const services = await this.ctx.getServices(this.testSpec.dependencies) - for (const serviceName in services) { + for (const serviceName of Object.keys(services)) { const service = services[serviceName] deps.push(new DeployTask(this.ctx, service, false, this.forceBuild)) } @@ -45,35 +51,42 @@ export class TestTask extends Task { return deps } - getKey() { - return `${this.module.name}.${this.testType}` + getName() { + return `${this.module.name}.${this.testName}` } - async process(): Promise { - // find out if module has already been tested - const testResult = await this.getTestResult() + getDescription() { + return `running ${this.testName} tests in module ${this.module.name}` + } - if (testResult && testResult.success) { - const passedEntry = this.ctx.log.info({ - section: this.module.name, - msg: `${this.testType} tests`, - }) - passedEntry.setSuccess({ msg: chalk.green("Already passed"), append: true }) - return testResult + async process(): Promise { + if (!this.force) { + // find out if module has already been tested + const testResult = await this.getTestResult() + + if (testResult && testResult.success) { + const passedEntry = this.ctx.log.info({ + section: this.module.name, + msg: `${this.testName} tests`, + }) + passedEntry.setSuccess({ msg: chalk.green("Already passed"), append: true }) + return testResult + } } const entry = this.ctx.log.info({ section: this.module.name, - msg: `Running ${this.testType} tests`, + msg: `Running ${this.testName} tests`, entryStyle: EntryStyle.activity, }) - const result = await this.ctx.testModule(this.module, this.testSpec) + const result = await this.ctx.testModule(this.module, this.testName, this.testSpec) if (result.success) { entry.setSuccess({ msg: chalk.green(`Success`), append: true }) } else { - entry.error({ msg: chalk.red(`Failed!`), append: true }) + entry.setError({ msg: chalk.red(`Failed!`), append: true }) + throw new TestError(result.output) } return result @@ -84,7 +97,7 @@ export class TestTask extends Task { return null } - const testResult = await this.ctx.getTestResult(this.module, await this.module.getVersion()) + const testResult = await this.ctx.getTestResult(this.module, this.testName, await this.module.getVersion()) return testResult && testResult.success && testResult } } diff --git a/src/types/module.ts b/src/types/module.ts index ad26472fd6..fb00fc8afb 100644 --- a/src/types/module.ts +++ b/src/types/module.ts @@ -7,15 +7,23 @@ */ import * as Joi from "joi" +import { ServiceMap } from "../garden" import { PluginContext } from "../plugin-context" +import { DeployTask } from "../tasks/deploy" +import { TestTask } from "../tasks/test" import { identifierRegex, joiIdentifier, joiVariables, PrimitiveMap } from "./common" import { ConfigurationError } from "../exceptions" import Bluebird = require("bluebird") import { extend, + keys, set, + values, } from "lodash" -import { ServiceConfig } from "./service" +import { + Service, + ServiceConfig, +} from "./service" import { resolveTemplateStrings, TemplateStringContext } from "../template-string" import { Memoize } from "typescript-memoize" import { TreeVersion } from "../vcs/base" @@ -146,6 +154,37 @@ export class Module { return deps } + + async getServices(): Promise { + const serviceNames = keys(this.services || {}) + return this.ctx.getServices(serviceNames) + } + + async getDeployTasks( + { force = false, forceBuild = false }: { force?: boolean, forceBuild?: boolean }, + ): Promise>>[]> { + const services = await this.getServices() + const module = this + + return values(services).map(s => new DeployTask(module.ctx, s, force, forceBuild)) + } + + async getTestTasks( + { group, force = false, forceBuild = false }: { group?: string, force?: boolean, forceBuild?: boolean }, + ) { + const tasks: TestTask>[] = [] + const config = await this.getConfig() + + for (const testName of Object.keys(config.test)) { + if (group && testName !== group) { + continue + } + const testSpec = config.test[testName] + tasks.push(new TestTask>(this.ctx, this, testName, testSpec, force, forceBuild)) + } + + return tasks + } } export type ModuleConfigType = T["_ConfigType"] diff --git a/src/types/plugin.ts b/src/types/plugin.ts index 054e470e0b..19c4d2f9e9 100644 --- a/src/types/plugin.ts +++ b/src/types/plugin.ts @@ -94,14 +94,16 @@ export interface PushModuleParams extends PluginActio export interface TestModuleParams extends PluginActionParamsBase { module: T - testSpec: TestSpec, - env: Environment, + testName: string + testSpec: TestSpec + env: Environment } export interface GetTestResultParams extends PluginActionParamsBase { - module: T, - version: TreeVersion, - env: Environment, + module: T + testName: string + version: TreeVersion + env: Environment } export interface GetServiceStatusParams extends PluginActionParamsBase { @@ -163,6 +165,8 @@ export interface PushResult { } export interface TestResult { + moduleName: string + testName: string version: TreeVersion success: boolean startedAt: Moment | Date diff --git a/src/types/task.ts b/src/types/task.ts new file mode 100644 index 0000000000..9e11d53258 --- /dev/null +++ b/src/types/task.ts @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2018 Garden Technologies, Inc. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +import { TaskResults } from "../task-graph" +import { v1 as uuidv1 } from "uuid" + +export class TaskDefinitionError extends Error { } + +export abstract class Task { + abstract type: string + id: string + + dependencies: Task[] + + constructor() { + this.dependencies = [] + this.id = uuidv1() // uuidv1 is timestamp-based + } + + async getDependencies(): Promise { + return this.dependencies + } + + protected abstract getName(): string + + getBaseKey(): string { + return `${this.type}.${this.getName()}` + } + + getKey(): string { + return `${this.getBaseKey()}.${this.id}` + } + + abstract getDescription(): string + + abstract async process(dependencyResults: TaskResults): Promise +} + +// Ensures that the task's version has been computed before it is used further. +export async function makeTask(taskClass, initArgs) { + const task = new taskClass(...initArgs) + await task.getVersion() + return task +} diff --git a/src/util.ts b/src/util.ts index 7ca77529a9..97f6ff3d1e 100644 --- a/src/util.ts +++ b/src/util.ts @@ -17,7 +17,6 @@ import * as Cryo from "cryo" import { spawn as _spawn } from "child_process" import { existsSync, readFileSync, writeFileSync } from "fs" import { join } from "path" -import { getLogger } from "./logger" import { TimeoutError, GardenError, @@ -32,17 +31,13 @@ import chalk from "chalk" export type HookCallback = (callback?: () => void) => void -const exitHooks: HookCallback[] = [] +const exitHookNames: string[] = [] // For debugging/testing/inspection purposes export type Nullable = { [P in keyof T]: T[P] | null } export function shutdown(code) { - if (exitHooks.length > 1) { - const signal = code === 0 ? "beforeExit" : "exitWithError" - process.emit(signal) - } else { - process.exit(code) - } + // This is a good place to log exitHookNames if needed. + process.exit(code) } export class RsyncError extends GardenError { @@ -82,37 +77,8 @@ export function execRsyncCmd(rsyncCmd: RsyncCommand, stdoutHandler?: RsyncStdIOC } export function registerCleanupFunction(name: string, func: HookCallback) { - // NOTE: this currently does not work on SIGINT in ts-node due to a bug - // (see https://github.com/TypeStrong/ts-node/pull/458) - - const log = getLogger() - - if (exitHooks.length === 0) { - exitHook.hookEvent("exitWithError", 1) - - const firstHook = () => { - log.debug({ section: "cleanup", msg: "Starting cleanup..." }) - } - - exitHook(firstHook) - exitHooks.push(firstHook) - } - - const hook = (callback) => { - if (func.length === 0) { - log.debug({ section: "cleanup", msg: name }) - func() - } else { - log.debug({ section: "cleanup", msg: `Starting ${name}` }) - func(() => { - log.debug({ section: "cleanup", msg: `Completed ${name}` }) - callback() - }) - } - } - - exitHook(hook) - exitHooks.push(hook) + exitHookNames.push(name) + exitHook(func) } export async function* scanDirectory(path: string, opts?: klaw.Options): AsyncIterableIterator { diff --git a/src/watch.ts b/src/watch.ts new file mode 100644 index 0000000000..e98a66ca69 --- /dev/null +++ b/src/watch.ts @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2018 Garden Technologies, Inc. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +import { map as bluebirdMap } from "bluebird" +import { Client } from "fb-watchman" +import { keyBy } from "lodash" +import { relative, resolve } from "path" +import { Module } from "./types/module" +import { PluginContext } from "./plugin-context" + +export type AutoReloadDependants = { [key: string]: Set } + +export interface OnChangeHandler { + (ctx: PluginContext, module: Module): Promise +} + +export async function computeAutoReloadDependants(modules: Module[]): + Promise { + let dependants = {} + + for (const module of modules) { + const deps = await module.getBuildDependencies() + for (const dep of deps) { + dependants[dep.name] = (dependants[dep.name] || new Set()).add(module) + } + } + + return dependants +} + +export type CapabilityOptions = { required?: string[], optional?: string[] } +export type CapabilityResponse = { error: Error, response: { capabilities: { string: boolean } } } + +export type ChangedFile = { + name: string, // path to the changed file or dir + size: number, + exists: boolean, + type: string, +} + +export type SubscriptionResponse = { + root: string, + subscription: string, + files: ChangedFile[], +} + +export class FSWatcher { + private readonly client + private capabilityCheckComplete: boolean + + constructor(private projectRoot: string) { + this.client = new Client() + this.capabilityCheckComplete = false + } + + /* + Wrapper around Facebook's Watchman library. + + See also: https://facebook.github.io/watchman/docs/nodejs.html + for further documentation. + */ + + command(args: any[]): Promise { + return new Promise((res, rej) => { + this.client.command(args, (error: Error, result: object) => { + if (error) { + // TODO: Error logging + console.error(error) + rej(error) + } + + res(result) + }) + }) + } + + // WIP + async watchModules( + modules: Module[], subscriptionPrefix: string, + changeHandler: (module: Module, response: SubscriptionResponse) => Promise, + ) { + if (!this.capabilityCheckComplete) { + await this.capabilityCheck({ optional: [], required: ["relative_root"] }) + } + + const modulesBySubscriptionKey = keyBy(modules, (m) => FSWatcher.subscriptionKey(subscriptionPrefix, m)) + + await bluebirdMap(modules || [], async (module) => { + const subscriptionKey = FSWatcher.subscriptionKey(subscriptionPrefix, module) + const modulePath = resolve(this.projectRoot, module.path) + + const result = await this.command(["watch-project", modulePath]) + const relModulePath = relative(result.watch, modulePath) + + const subscriptionRequest = { + expression: ["dirname", relModulePath, ["depth", "ge", 0]], + } + + await this.command([ + "subscribe", + result.watch, + subscriptionKey, + subscriptionRequest]) + }) + + this.on("subscription", async (response) => { + const changedModule = modulesBySubscriptionKey[response.subscription] + if (!changedModule) { + console.log("no module found for changed file, skipping auto-rebuild") + return + } + + await changeHandler(changedModule, response) + }) + } + + capabilityCheck(options: CapabilityOptions): Promise { + return new Promise((res, rej) => { + this.client.capabilityCheck(options, (error: Error, response: CapabilityResponse) => { + if (error) { + // TODO: Error logging + rej(error) + } + + if ("warning" in response) { + // TODO: Warning logging + } + + res(response) + }) + }) + } + + on(eventType: string, handler: (response: SubscriptionResponse) => void): void { + this.client.on(eventType, handler) + } + + end(): void { + this.client.end() + } + + private static subscriptionKey(prefix: string, module: Module) { + return `${prefix}${module.name}Subscription` + } +} diff --git a/bin/imgcat b/static/imgcat similarity index 100% rename from bin/imgcat rename to static/imgcat diff --git a/test/data/test-project-build-products/module-d/garden.yml b/test/data/test-project-build-products/module-d/garden.yml index d94df4bfd2..fe39aa8020 100644 --- a/test/data/test-project-build-products/module-d/garden.yml +++ b/test/data/test-project-build-products/module-d/garden.yml @@ -2,7 +2,7 @@ module: name: module-d type: generic build: - command: "echo D && mkdir build && touch build/d.txt" + command: "echo D && mkdir -p build && touch build/d.txt" dependencies: - name: module-a copy: diff --git a/test/helpers.ts b/test/helpers.ts index 9d81412603..40be6ff65d 100644 --- a/test/helpers.ts +++ b/test/helpers.ts @@ -1,5 +1,6 @@ import * as td from "testdouble" import { resolve } from "path" +import { TaskResults } from "../src/task-graph" import { DeleteConfigParams, GetConfigParams, @@ -13,6 +14,7 @@ import { import { Garden } from "../src/garden" import { Module } from "../src/types/module" import { expect } from "chai" +import { mapValues } from "lodash" export const dataDir = resolve(__dirname, "data") @@ -20,6 +22,14 @@ export function getDataDir(name: string) { return resolve(dataDir, name) } +export async function profileBlock(description: string, block: () => Promise) { + const startTime = new Date().getTime() + const result = await block() + const executionTime = (new Date().getTime()) - startTime + console.log(description, "took", executionTime, "ms") + return result +} + export const projectRootA = getDataDir("test-project-a") class TestModule extends Module { @@ -148,3 +158,7 @@ export async function expectError(fn: Function, typeOrCallback: string | ((err: throw new Error(`Expected error (got no error)`) } } + +export function taskResultOutputs(results: TaskResults) { + return mapValues(results, r => r.output) +} diff --git a/test/src/build-dir.ts b/test/src/build-dir.ts index eb629fbdd0..8826ba6b9c 100644 --- a/test/src/build-dir.ts +++ b/test/src/build-dir.ts @@ -4,18 +4,16 @@ import { pathExists, readdir } from "fs-extra" import { expect } from "chai" import { values } from "lodash" import { BuildTask } from "../../src/tasks/build" -import { - makeTestGarden, -} from "../helpers" +import { makeTestGarden } from "../helpers" /* Module dependency diagram for test-project-build-products - a b - \ / - d c - \ / - e + a b + \ / + d c + \ / + e */ const projectRoot = join(__dirname, "..", "data", "test-project-build-products") diff --git a/test/src/commands/build.ts b/test/src/commands/build.ts index 0346e62533..d25f796a52 100644 --- a/test/src/commands/build.ts +++ b/test/src/commands/build.ts @@ -1,15 +1,18 @@ import { BuildCommand } from "../../../src/commands/build" import { expect } from "chai" -import { makeTestContextA } from "../../helpers" +import { + makeTestContextA, + taskResultOutputs, +} from "../../helpers" describe("commands.build", () => { it("should build all modules in a project", async () => { const ctx = await makeTestContextA() const command = new BuildCommand() - const result = await command.action(ctx, { module: undefined }, { force: true }) + const result = await command.action(ctx, { module: undefined }, { watch: false, force: true }) - expect(result).to.eql({ + expect(taskResultOutputs(result)).to.eql({ "build.module-a": { fresh: true, buildLog: "A\n" }, "build.module-b": { fresh: true, buildLog: "B\n" }, "build.module-c": {}, @@ -20,9 +23,9 @@ describe("commands.build", () => { const ctx = await makeTestContextA() const command = new BuildCommand() - const result = await command.action(ctx, { module: "module-b" }, { force: true }) + const result = await command.action(ctx, { module: "module-b" }, { watch: false, force: true }) - expect(result).to.eql({ + expect(taskResultOutputs(result)).to.eql({ "build.module-a": { fresh: true, buildLog: "A\n" }, "build.module-b": { fresh: true, buildLog: "B\n" }, }) diff --git a/test/src/commands/data/auto-reload-project/garden.yml b/test/src/commands/data/auto-reload-project/garden.yml new file mode 100644 index 0000000000..70b96901ca --- /dev/null +++ b/test/src/commands/data/auto-reload-project/garden.yml @@ -0,0 +1,7 @@ +project: + name: auto-reload-project + environments: + local: + providers: + test: + type: test-plugin diff --git a/test/src/commands/data/auto-reload-project/module-a/foo b/test/src/commands/data/auto-reload-project/module-a/foo new file mode 100644 index 0000000000..1910281566 --- /dev/null +++ b/test/src/commands/data/auto-reload-project/module-a/foo @@ -0,0 +1 @@ +foo \ No newline at end of file diff --git a/test/src/commands/data/auto-reload-project/module-a/garden.yml b/test/src/commands/data/auto-reload-project/module-a/garden.yml new file mode 100644 index 0000000000..0ec39c075a --- /dev/null +++ b/test/src/commands/data/auto-reload-project/module-a/garden.yml @@ -0,0 +1,5 @@ +module: + name: module-a + type: generic + build: + command: echo A diff --git a/test/src/commands/data/auto-reload-project/module-b/foo b/test/src/commands/data/auto-reload-project/module-b/foo new file mode 100644 index 0000000000..1910281566 --- /dev/null +++ b/test/src/commands/data/auto-reload-project/module-b/foo @@ -0,0 +1 @@ +foo \ No newline at end of file diff --git a/test/src/commands/data/auto-reload-project/module-b/garden.yml b/test/src/commands/data/auto-reload-project/module-b/garden.yml new file mode 100644 index 0000000000..35ee078b3e --- /dev/null +++ b/test/src/commands/data/auto-reload-project/module-b/garden.yml @@ -0,0 +1,12 @@ +module: + name: module-b + type: generic + services: + service-b: + endpoints: + - paths: [/path-b] + containerPort: 8080 + build: + command: echo B + dependencies: + - module-a diff --git a/test/src/commands/data/auto-reload-project/module-c/foo b/test/src/commands/data/auto-reload-project/module-c/foo new file mode 100644 index 0000000000..1910281566 --- /dev/null +++ b/test/src/commands/data/auto-reload-project/module-c/foo @@ -0,0 +1 @@ +foo \ No newline at end of file diff --git a/test/src/commands/data/auto-reload-project/module-c/garden.yml b/test/src/commands/data/auto-reload-project/module-c/garden.yml new file mode 100644 index 0000000000..e5fefe9260 --- /dev/null +++ b/test/src/commands/data/auto-reload-project/module-c/garden.yml @@ -0,0 +1,10 @@ +module: + name: module-c + type: generic + services: + service-c: + endpoints: + - paths: [/path-c] + containerPort: 8080 + build: + command: echo C diff --git a/test/src/commands/data/auto-reload-project/module-d/foo b/test/src/commands/data/auto-reload-project/module-d/foo new file mode 100644 index 0000000000..1910281566 --- /dev/null +++ b/test/src/commands/data/auto-reload-project/module-d/foo @@ -0,0 +1 @@ +foo \ No newline at end of file diff --git a/test/src/commands/data/auto-reload-project/module-d/garden.yml b/test/src/commands/data/auto-reload-project/module-d/garden.yml new file mode 100644 index 0000000000..b6a2edd0ae --- /dev/null +++ b/test/src/commands/data/auto-reload-project/module-d/garden.yml @@ -0,0 +1,14 @@ +module: + name: module-d + type: generic + services: + service-d: + dependencies: + - service-b + endpoints: + - paths: [/path-d] + containerPort: 8080 + build: + command: echo D + dependencies: + - module-b diff --git a/test/src/commands/data/auto-reload-project/module-e/foo b/test/src/commands/data/auto-reload-project/module-e/foo new file mode 100644 index 0000000000..1910281566 --- /dev/null +++ b/test/src/commands/data/auto-reload-project/module-e/foo @@ -0,0 +1 @@ +foo \ No newline at end of file diff --git a/test/src/commands/data/auto-reload-project/module-e/garden.yml b/test/src/commands/data/auto-reload-project/module-e/garden.yml new file mode 100644 index 0000000000..054c493123 --- /dev/null +++ b/test/src/commands/data/auto-reload-project/module-e/garden.yml @@ -0,0 +1,16 @@ +module: + name: module-e + type: generic + services: + service-e: + dependencies: + - service-b + - service-c + endpoints: + - paths: [/path-e] + containerPort: 8080 + build: + dependencies: + - module-b + - module-c + command: echo E diff --git a/test/src/commands/data/auto-reload-project/module-f/foo b/test/src/commands/data/auto-reload-project/module-f/foo new file mode 100644 index 0000000000..1910281566 --- /dev/null +++ b/test/src/commands/data/auto-reload-project/module-f/foo @@ -0,0 +1 @@ +foo \ No newline at end of file diff --git a/test/src/commands/data/auto-reload-project/module-f/garden.yml b/test/src/commands/data/auto-reload-project/module-f/garden.yml new file mode 100644 index 0000000000..171c51fed8 --- /dev/null +++ b/test/src/commands/data/auto-reload-project/module-f/garden.yml @@ -0,0 +1,14 @@ +module: + name: module-f + type: generic + services: + service-f: + dependencies: + - service-c + endpoints: + - paths: [/path-f] + containerPort: 8080 + build: + dependencies: + - module-c + command: echo F diff --git a/test/src/commands/deploy.ts b/test/src/commands/deploy.ts index c6145f74a2..d410e1005a 100644 --- a/test/src/commands/deploy.ts +++ b/test/src/commands/deploy.ts @@ -8,6 +8,7 @@ import { PluginFactory, } from "../../../src/types/plugin" import { ServiceState, ServiceStatus } from "../../../src/types/service" +import { taskResultOutputs } from "../../helpers" const testProvider: PluginFactory = () => { const testStatuses: { [key: string]: ServiceStatus } = { @@ -54,6 +55,7 @@ describe("commands.deploy", () => { const projectRootB = join(__dirname, "..", "..", "data", "test-project-b") // TODO: Verify that services don't get redeployed when same version is already deployed. + // TODO: Test with --watch flag it("should build and deploy all modules in a project", async () => { const garden = await Garden.factory(projectRootB, { plugins: [testProvider] }) @@ -65,12 +67,13 @@ describe("commands.deploy", () => { service: "", }, { + watch: false, force: false, "force-build": true, }, ) - expect(result).to.eql({ + expect(taskResultOutputs(result)).to.eql({ "build.module-a": { fresh: true, buildLog: "A\n" }, "build.module-b": { fresh: true, buildLog: "B\n" }, "build.module-c": {}, @@ -91,12 +94,13 @@ describe("commands.deploy", () => { service: "service-b", }, { + watch: false, force: false, "force-build": true, }, ) - expect(result).to.eql({ + expect(taskResultOutputs(result)).to.eql({ "build.module-a": { fresh: true, buildLog: "A\n" }, "build.module-b": { fresh: true, buildLog: "B\n" }, "deploy.service-a": { version: "1", state: "ready" }, diff --git a/test/src/commands/push.ts b/test/src/commands/push.ts index c3b1564f11..aa87c1462c 100644 --- a/test/src/commands/push.ts +++ b/test/src/commands/push.ts @@ -11,6 +11,7 @@ import { PushCommand } from "../../../src/commands/push" import { TreeVersion } from "../../../src/vcs/base" import { expectError, + taskResultOutputs, } from "../../helpers" const projectRootB = join(__dirname, "..", "..", "data", "test-project-b") @@ -103,7 +104,7 @@ describe("PushCommand", () => { }, ) - expect(result).to.eql({ + expect(taskResultOutputs(result)).to.eql({ "build.module-a": { fresh: false }, "build.module-b": { fresh: false }, "push.module-a": { pushed: true }, @@ -127,7 +128,7 @@ describe("PushCommand", () => { }, ) - expect(result).to.eql({ + expect(taskResultOutputs(result)).to.eql({ "build.module-a": { fresh: true }, "build.module-b": { fresh: true }, "push.module-a": { pushed: true }, @@ -151,7 +152,7 @@ describe("PushCommand", () => { }, ) - expect(result).to.eql({ + expect(taskResultOutputs(result)).to.eql({ "build.module-a": { fresh: false }, "push.module-a": { pushed: true }, }) @@ -172,7 +173,7 @@ describe("PushCommand", () => { }, ) - expect(result).to.eql({ + expect(taskResultOutputs(result)).to.eql({ "push.module-c": { pushed: false }, }) }) @@ -194,7 +195,7 @@ describe("PushCommand", () => { }, ) - expect(result).to.eql({ + expect(taskResultOutputs(result)).to.eql({ "build.module-a": { fresh: false }, "push.module-a": { pushed: false, message: chalk.yellow("No push handler available for module type generic") }, }) @@ -247,7 +248,7 @@ describe("PushCommand", () => { }, ) - expect(result).to.eql({ + expect(taskResultOutputs(result)).to.eql({ "build.module-a": { fresh: true }, "push.module-a": { pushed: true }, }) diff --git a/test/src/commands/test.ts b/test/src/commands/test.ts index 82275513fe..9369d1f7a2 100644 --- a/test/src/commands/test.ts +++ b/test/src/commands/test.ts @@ -1,5 +1,8 @@ import { expect } from "chai" -import { makeTestContextA } from "../../helpers" +import { + makeTestContextA, + taskResultOutputs, +} from "../../helpers" import { TestCommand } from "../../../src/commands/test" import * as isSubset from "is-subset" @@ -11,10 +14,10 @@ describe("commands.test", () => { const result = await command.action( ctx, { module: undefined }, - { group: undefined, force: true, "force-build": true }, + { group: undefined, force: true, "force-build": true, watch: false }, ) - expect(isSubset(result, { + expect(isSubset(taskResultOutputs(result), { "build.module-a": { fresh: true, buildLog: "A\n", @@ -46,10 +49,10 @@ describe("commands.test", () => { const result = await command.action( ctx, { module: "module-a" }, - { group: undefined, force: true, "force-build": true }, + { group: undefined, force: true, "force-build": true, watch: false }, ) - expect(isSubset(result, { + expect(isSubset(taskResultOutputs(result), { "build.module-a": { fresh: true, buildLog: "A\n", diff --git a/test/src/task-graph.ts b/test/src/task-graph.ts index e7eaf95e49..598be9357b 100644 --- a/test/src/task-graph.ts +++ b/test/src/task-graph.ts @@ -1,34 +1,63 @@ import { join } from "path" import { expect } from "chai" -import { Task, TaskGraph, TaskResults } from "../../src/task-graph" import { Garden } from "../../src/garden" +import { Task } from "../../src/types/task" +import { + TaskGraph, + TaskResult, + TaskResults, +} from "../../src/task-graph" const projectRoot = join(__dirname, "..", "data", "test-project-empty") -describe("task-graph", () => { - class TestTask extends Task { - type = "test" - key: string +class TestTask extends Task { + type = "test" + name: string + id: string - constructor(key: string, dependencies?: Task[], private callback?: (key: string, result: any) => void) { - super() - this.key = key + constructor( + name: string, + dependencies?: Task[], + private callback?: (name: string, result: any) => Promise, + id: string = "", + ) { + super() + this.name = name + this.id = id - if (dependencies) { - this.dependencies = dependencies - } + if (dependencies) { + this.dependencies = dependencies } + } + + getName() { + return this.name + } - async process(dependencyResults: TaskResults) { - const result = { result: "result-" + this.key, dependencyResults } + getBaseKey(): string { + return this.name + } - if (this.callback) { - this.callback(this.key, result) - } + getKey(): string { + return this.id ? `${this.name}.${this.id}` : this.name + } - return result + getDescription() { + return this.getKey() + } + + async process(dependencyResults: TaskResults) { + const result = { result: "result-" + this.getKey(), dependencyResults } + + if (this.callback) { + await this.callback(this.getKey(), result.result) } + + return result } +} + +describe("task-graph", () => { describe("TaskGraph", () => { async function getContext() { @@ -44,9 +73,19 @@ describe("task-graph", () => { await graph.addTask(task) const results = await graph.processTasks() - expect(results).to.eql({ - "test.a": { result: "result-a", dependencyResults: {} }, - }) + const expected: TaskResults = { + a: { + type: "test", + description: "a", + output: { + result: "result-a", + dependencyResults: {}, + }, + dependencyResults: {}, + }, + } + + expect(results).to.eql(expected) }) it("should process multiple tasks in dependency order", async () => { @@ -56,9 +95,9 @@ describe("task-graph", () => { const callbackResults = {} const resultOrder: string[] = [] - const callback = (key: string, result: any) => { + const callback = async (key: string, result: any) => { resultOrder.push(key) - callbackResults["test." + key] = result + callbackResults[key] = result } const taskA = new TestTask("a", [], callback) @@ -79,36 +118,165 @@ describe("task-graph", () => { const results = await graph.processTasks() - const resultA = { result: "result-a", dependencyResults: {} } - const resultB = { - result: "result-b", - dependencyResults: { "test.a": resultA }, - } - const resultC = { - result: "result-c", - dependencyResults: { "test.b": resultB }, + const resultA: TaskResult = { + type: "test", + description: "a", + output: { + result: "result-a", + dependencyResults: {}, + }, + dependencyResults: {}, } - - expect(results).to.eql(callbackResults) - expect(results).to.eql({ - "test.a": resultA, - "test.b": { + const resultB: TaskResult = { + type: "test", + description: "b", + output: { result: "result-b", - dependencyResults: { "test.a": resultA }, + dependencyResults: { a: resultA }, }, - "test.c": { + dependencyResults: { a: resultA }, + } + const resultC: TaskResult = { + type: "test", + description: "c", + output: { result: "result-c", - dependencyResults: { "test.b": resultB }, + dependencyResults: { b: resultB }, }, - "test.d": { - result: "result-d", + dependencyResults: { b: resultB }, + } + + const expected: TaskResults = { + a: resultA, + b: resultB, + c: resultC, + d: { + type: "test", + description: "d", + output: { + result: "result-d", + dependencyResults: { + b: resultB, + c: resultC, + }, + }, dependencyResults: { - "test.b": resultB, - "test.c": resultC, + b: resultB, + c: resultC, }, }, - }) + } + + expect(results).to.eql(expected) expect(resultOrder).to.eql(["a", "b", "c", "d"]) + + expect(callbackResults).to.eql({ + a: "result-a", + b: "result-b", + c: "result-c", + d: "result-d", + }) + }) + + it.skip( + "should process a task as an inheritor of an existing, in-progress task when they have the same base key", + async () => + { + const ctx = await getContext() + const graph = new TaskGraph(ctx) + + let callbackResults = {} + let resultOrder: string[] = [] + + let parentTaskStarted = false + let inheritorAdded = false + + const intervalMs = 10 + + const inheritorAddedPromise = new Promise(resolve => { + setInterval(() => { + if (inheritorAdded) { + resolve() + } + }, intervalMs) + }) + + const parentTaskStartedPromise = new Promise(resolve => { + setInterval(() => { + if (parentTaskStarted) { + resolve() + } + }, intervalMs) + }) + + const defaultCallback = async (key: string, result: any) => { + resultOrder.push(key) + callbackResults[key] = result + } + + const parentCallback = async (key: string, result: any) => { + parentTaskStarted = true + await inheritorAddedPromise + resultOrder.push(key) + callbackResults[key] = result + } + + const dependencyA = new TestTask("dependencyA", [], defaultCallback) + const dependencyB = new TestTask("dependencyB", [], defaultCallback) + const parentTask = new TestTask("sharedName", [dependencyA, dependencyB], parentCallback, "1") + const dependantA = new TestTask("dependantA", [parentTask], defaultCallback) + const dependantB = new TestTask("dependantB", [parentTask], defaultCallback) + + const inheritorTask = new TestTask("sharedName", [dependencyA, dependencyB], defaultCallback, "2") + + await graph.addTask(dependencyA) + await graph.addTask(dependencyB) + await graph.addTask(parentTask) + await graph.addTask(dependantA) + await graph.addTask(dependantB) + + const resultsPromise = graph.processTasks() + await parentTaskStartedPromise + await graph.addTask(inheritorTask) + inheritorAdded = true + const results = await resultsPromise + + expect(resultOrder).to.eql([ + "dependencyA", + "dependencyB", + "sharedName.1", + "sharedName.2", + "dependantA", + "dependantB", + ]) + + const resultDependencyA = { + output: "result-dependencyA", + dependencyResults: {}, + } + + const resultDependencyB = { + output: "result-dependencyB", + dependencyResults: {}, + } + + const resultSharedName = { + output: "result-sharedName.2", + dependencyResults: {dependencyA: resultDependencyA, dependencyB: resultDependencyB}, + } + + expect(results).to.eql({ + dependencyA: { output: "result-dependencyA", dependencyResults: {} }, + dependencyB: { output: "result-dependencyB", dependencyResults: {} }, + sharedName: { output: "result-sharedName.2", + dependencyResults: { dependencyA: resultDependencyA, dependencyB: resultDependencyB } }, + dependantA: + { result: "result-dependantA", + dependencyResults: { sharedName: resultSharedName } }, + dependantB: + { result: "result-dependantB", + dependencyResults: { sharedName: resultSharedName } }, + }) }) }) })