diff --git a/.depcheckrc.yml b/.depcheckrc.yml index 50c309973..2652ffb2b 100644 --- a/.depcheckrc.yml +++ b/.depcheckrc.yml @@ -17,6 +17,7 @@ ignores: # used in testing + ci - '@metamask/auto-changelog' # invoked as `auto-changelog` - '@metamask/forwarder' + - '@metamask/phishing-warning' # statically hosted as part of some e2e tests - '@metamask/test-dapp' - '@metamask/design-tokens' # Only imported in index.css - '@tsconfig/node14' # required dynamically by TS, used in tsconfig.json diff --git a/.metamaskrc.dist b/.metamaskrc.dist index 29dbcb2f7..d3bff3b46 100644 --- a/.metamaskrc.dist +++ b/.metamaskrc.dist @@ -6,3 +6,6 @@ ONBOARDING_V2= SWAPS_USE_DEV_APIS= COLLECTIBLES_V1= TOKEN_DETECTION_V2= + +; Set this to test changes to the phishing warning page. +PHISHING_WARNING_PAGE_URL= diff --git a/CHANGELOG.md b/CHANGELOG.md index d271b47a3..c30bf6edb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,39 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [10.14.7] +### Changed +- Make JavaScript bundles more reproducible between environments. + - The bundles no longer include absolute paths to each module included. + +## [10.14.6] +### Changed +- Move phishing warning page to external site. + - The page shown when a site is blocked has been extracted from the extension and moved to an external site. This site is eagerly cached with a service worker upon extension startup, so it should continue to work even while offline. +- Make build .zip files reproducible (#14623) + - The ordering of files within each .zip file was non-deterministic before this change. We fixed this to comply with Firefox store policies. + +## [10.14.5] +### Fixed +- This release was deployed to fix a configuration issue. + +## [10.14.4] +### Fixed +- This release was deployed to fix a configuration issue. + +## [10.14.3] +### Fixed +- This release was deployed to fix a configuration issue. + +## [10.14.2] +### Fixed +- Make build deterministic (#14610) + - The ordering of modules within each bundle was non-deterministic before this change. We fixed this to comply with Firefox store policies. + +## [10.14.1] +### Changed +- This version was used to rollback from v10.14.0 to v10.13.0. + ## [10.14.0] ### Added - **[FLASK]** Add snap version to details page ([#14110](https://github.com/MetaMask/metamask-extension/pull/14110)) @@ -2908,7 +2941,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Uncategorized - Added the ability to restore accounts from seed words. -[Unreleased]: https://github.com/MetaMask/metamask-extension/compare/v10.14.0...HEAD +[Unreleased]: https://github.com/MetaMask/metamask-extension/compare/v10.14.7...HEAD +[10.14.7]: https://github.com/MetaMask/metamask-extension/compare/v10.14.6...v10.14.7 +[10.14.6]: https://github.com/MetaMask/metamask-extension/compare/v10.14.5...v10.14.6 +[10.14.5]: https://github.com/MetaMask/metamask-extension/compare/v10.14.4...v10.14.5 +[10.14.4]: https://github.com/MetaMask/metamask-extension/compare/v10.14.3...v10.14.4 +[10.14.3]: https://github.com/MetaMask/metamask-extension/compare/v10.14.2...v10.14.3 +[10.14.2]: https://github.com/MetaMask/metamask-extension/compare/v10.14.1...v10.14.2 +[10.14.1]: https://github.com/MetaMask/metamask-extension/compare/v10.14.0...v10.14.1 [10.14.0]: https://github.com/MetaMask/metamask-extension/compare/v10.13.0...v10.14.0 [10.13.0]: https://github.com/MetaMask/metamask-extension/compare/v10.12.4...v10.13.0 [10.12.4]: https://github.com/MetaMask/metamask-extension/compare/v10.12.3...v10.12.4 diff --git a/app/manifest/v2/_base.json b/app/manifest/v2/_base.json index c2b20b4db..87bed959d 100644 --- a/app/manifest/v2/_base.json +++ b/app/manifest/v2/_base.json @@ -72,6 +72,5 @@ "*://*.eth/", "notifications" ], - "short_name": "__MSG_appName__", - "web_accessible_resources": ["inpage.js", "phishing.html"] + "short_name": "__MSG_appName__" } diff --git a/app/phishing.html b/app/phishing.html deleted file mode 100644 index e854d79fa..000000000 --- a/app/phishing.html +++ /dev/null @@ -1,150 +0,0 @@ - - - - MetaMask Phishing Detection - - - - - - - - - - -
-
- MetaMask Logo -

- - MetaMask Phishing Detection -

-
-
-

- This domain is currently on the MetaMask domain warning list. This - means that based on information available to us, MetaMask believes - this domain could currently compromise your security and, as an added - safety feature, MetaMask has restricted access to the site. To - override this, please read the rest of this warning for instructions - on how to continue at your own risk. -

-

- There are many reasons sites can appear on our warning list, and our - warning list compiles from other widely used industry lists. Such - reasons can include known fraud or security risks, such as domains - that test positive on the - Ethereum Phishing Detector. Domains on these warning lists may include outright malicious - websites and legitimate websites that have been compromised by a - malicious actor. -

-

- To read more about this site - please search for the domain on CryptoScamDB. -

-

- Note that this warning list is compiled on a voluntary basis. This - list may be inaccurate or incomplete. Just because a domain does not - appear on this list is not an implicit guarantee of that domain's - safety. As always, your transactions are your own responsibility. If - you wish to interact with any domain on our warning list, you can do - so by continuing at your own risk. -

-

- If you think this domain is incorrectly flagged or if a blocked - legitimate website has resolved its security issues, - please file an issue. -

-
-
- - diff --git a/app/scripts/background.js b/app/scripts/background.js index 119af9e87..311cd2781 100644 --- a/app/scripts/background.js +++ b/app/scripts/background.js @@ -76,6 +76,12 @@ if (inTest || process.env.METAMASK_DEBUG) { global.metamaskGetState = localStore.get.bind(localStore); } +const phishingPageUrl = new URL(process.env.PHISHING_WARNING_PAGE_URL); + +const ONE_SECOND_IN_MILLISECONDS = 1_000; +// Timeout for initializing phishing warning page. +const PHISHING_WARNING_PAGE_TIMEOUT = ONE_SECOND_IN_MILLISECONDS; + /** * In case of MV3 we attach a "onConnect" event listener as soon as the application is initialised. * Reason is that in case of MV3 a delay in doing this was resulting in missing first connect event after service worker is re-activated. @@ -159,9 +165,76 @@ async function initialize(remotePort) { const initState = await loadStateFromPersistence(); const initLangCode = await getFirstPreferredLangCode(); await setupController(initState, initLangCode, remotePort); + await loadPhishingWarningPage(); log.info('MetaMask initialization complete.'); } +/** + * An error thrown if the phishing warning page takes too long to load. + */ +class PhishingWarningPageTimeoutError extends Error { + constructor() { + super('Timeout failed'); + } +} + +/** + * Load the phishing warning page temporarily to ensure the service + * worker has been registered, so that the warning page works offline. + */ +async function loadPhishingWarningPage() { + let iframe; + try { + const extensionStartupPhishingPageUrl = new URL( + process.env.PHISHING_WARNING_PAGE_URL, + ); + // The `extensionStartup` hash signals to the phishing warning page that it should not bother + // setting up streams for user interaction. Otherwise this page load would cause a console + // error. + extensionStartupPhishingPageUrl.hash = '#extensionStartup'; + + iframe = window.document.createElement('iframe'); + iframe.setAttribute('src', extensionStartupPhishingPageUrl.href); + iframe.setAttribute('sandbox', 'allow-scripts allow-same-origin'); + + // Create "deferred Promise" to allow passing resolve/reject to event handlers + let deferredResolve; + let deferredReject; + const loadComplete = new Promise((resolve, reject) => { + deferredResolve = resolve; + deferredReject = reject; + }); + + // The load event is emitted once loading has completed, even if the loading failed. + // If loading failed we can't do anything about it, so we don't need to check. + iframe.addEventListener('load', deferredResolve); + + // This step initiates the page loading. + window.document.body.appendChild(iframe); + + // This timeout ensures that this iframe gets cleaned up in a reasonable + // timeframe, and ensures that the "initialization complete" message + // doesn't get delayed too long. + setTimeout( + () => deferredReject(new PhishingWarningPageTimeoutError()), + PHISHING_WARNING_PAGE_TIMEOUT, + ); + await loadComplete; + } catch (error) { + if (error instanceof PhishingWarningPageTimeoutError) { + console.warn( + 'Phishing warning page timeout; page not guaraneteed to work offline.', + ); + } else { + console.error('Failed to initialize phishing warning page', error); + } + } finally { + if (iframe) { + iframe.remove(); + } + } +} + // // State and Persistence // @@ -384,6 +457,10 @@ function setupController(initState, initLangCode, remoteSourcePort) { remotePort.sender.origin === `chrome-extension://${browser.runtime.id}`; } + const senderUrl = remotePort.sender?.url + ? new URL(remotePort.sender.url) + : null; + if (isMetaMaskInternalProcess) { const portStream = new PortStream(remotePort); // communication with popup @@ -435,6 +512,15 @@ function setupController(initState, initLangCode, remoteSourcePort) { ); }); } + } else if ( + senderUrl && + senderUrl.origin === phishingPageUrl.origin && + senderUrl.pathname === phishingPageUrl.pathname + ) { + const portStream = new PortStream(remotePort); + controller.setupPhishingCommunication({ + connectionStream: portStream, + }); } else { if (remotePort.sender && remotePort.sender.tab && remotePort.sender.url) { const tabId = remotePort.sender.tab.id; diff --git a/app/scripts/contentscript.js b/app/scripts/contentscript.js index a3a2dd3dd..9cc350d6d 100644 --- a/app/scripts/contentscript.js +++ b/app/scripts/contentscript.js @@ -19,8 +19,13 @@ const inpageContent = fs.readFileSync( const inpageSuffix = `//# sourceURL=${browser.runtime.getURL('inpage.js')}\n`; const inpageBundle = inpageContent + inpageSuffix; +// contexts const CONTENT_SCRIPT = 'metamask-contentscript'; const INPAGE = 'metamask-inpage'; +const PHISHING_WARNING_PAGE = 'metamask-phishing-warning-page'; + +// stream channels +const PHISHING_SAFELIST = 'metamask-phishing-safelist'; const PROVIDER = 'metamask-provider'; // TODO:LegacyProvider: Delete @@ -29,7 +34,14 @@ const LEGACY_INPAGE = 'inpage'; const LEGACY_PROVIDER = 'provider'; const LEGACY_PUBLIC_CONFIG = 'publicConfig'; -if (shouldInjectProvider()) { +const phishingPageUrl = new URL(process.env.PHISHING_WARNING_PAGE_URL); + +if ( + window.location.origin === phishingPageUrl.origin && + window.location.pathname === phishingPageUrl.pathname +) { + setupPhishingStream(); +} else if (shouldInjectProvider()) { injectScript(inpageBundle); setupStreams(); } @@ -57,6 +69,47 @@ function injectScript(content) { } } +async function setupPhishingStream() { + // the transport-specific streams for communication between inpage and background + const pageStream = new WindowPostMessageStream({ + name: CONTENT_SCRIPT, + target: PHISHING_WARNING_PAGE, + }); + const extensionPort = browser.runtime.connect({ name: CONTENT_SCRIPT }); + const extensionStream = new PortStream(extensionPort); + + // create and connect channel muxers + // so we can handle the channels individually + const pageMux = new ObjectMultiplex(); + pageMux.setMaxListeners(25); + const extensionMux = new ObjectMultiplex(); + extensionMux.setMaxListeners(25); + + pump(pageMux, pageStream, pageMux, (err) => + logStreamDisconnectWarning('MetaMask Inpage Multiplex', err), + ); + pump(extensionMux, extensionStream, extensionMux, (err) => { + logStreamDisconnectWarning('MetaMask Background Multiplex', err); + window.postMessage( + { + target: PHISHING_WARNING_PAGE, // the post-message-stream "target" + data: { + // this object gets passed to obj-multiplex + name: PHISHING_SAFELIST, // the obj-multiplex channel name + data: { + jsonrpc: '2.0', + method: 'METAMASK_STREAM_FAILURE', + }, + }, + }, + window.location.origin, + ); + }); + + // forward communication across inpage-background for these channels only + forwardTrafficBetweenMuxes(PHISHING_SAFELIST, pageMux, extensionMux); +} + /** * Sets up two-way communication streams between the * browser extension and local per-page browser context. @@ -307,9 +360,9 @@ function blockedDomainCheck() { * Redirects the current page to a phishing information page */ function redirectToPhishingWarning() { - console.debug('MetaMask: Routing to Phishing Warning component.'); - const extensionURL = browser.runtime.getURL('phishing.html'); - window.location.href = `${extensionURL}#${querystring.stringify({ + console.debug('MetaMask: Routing to Phishing Warning page.'); + const baseUrl = process.env.PHISHING_WARNING_PAGE_URL; + window.location.href = `${baseUrl}#${querystring.stringify({ hostname: window.location.hostname, href: window.location.href, })}`; diff --git a/app/scripts/lib/util.js b/app/scripts/lib/util.js index 9800666af..b7fdf0521 100644 --- a/app/scripts/lib/util.js +++ b/app/scripts/lib/util.js @@ -27,7 +27,7 @@ const getEnvironmentTypeMemo = memoize((url) => { const parsedUrl = new URL(url); if (parsedUrl.pathname === '/popup.html') { return ENVIRONMENT_TYPE_POPUP; - } else if (['/home.html', '/phishing.html'].includes(parsedUrl.pathname)) { + } else if (['/home.html'].includes(parsedUrl.pathname)) { return ENVIRONMENT_TYPE_FULLSCREEN; } else if (parsedUrl.pathname === '/notification.html') { return ENVIRONMENT_TYPE_NOTIFICATION; diff --git a/app/scripts/lib/util.test.js b/app/scripts/lib/util.test.js index 62c33b5a5..0892a4e3d 100644 --- a/app/scripts/lib/util.test.js +++ b/app/scripts/lib/util.test.js @@ -34,13 +34,6 @@ describe('app utils', () => { expect(environmentType).toStrictEqual(ENVIRONMENT_TYPE_FULLSCREEN); }); - it('should return fullscreen type for phishing.html', () => { - const environmentType = getEnvironmentType( - 'http://extension-id/phishing.html', - ); - expect(environmentType).toStrictEqual(ENVIRONMENT_TYPE_FULLSCREEN); - }); - it('should return background type', () => { const environmentType = getEnvironmentType( 'http://extension-id/_generated_background_page.html', diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index f1af3eb3d..f7e513caa 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -155,6 +155,9 @@ export const METAMASK_CONTROLLER_EVENTS = { APPROVAL_STATE_CHANGE: 'ApprovalController:stateChange', }; +// stream channels +const PHISHING_SAFELIST = 'metamask-phishing-safelist'; + export default class MetamaskController extends EventEmitter { /** * @param {Object} opts @@ -1503,7 +1506,6 @@ export default class MetamaskController extends EventEmitter { ), markPasswordForgotten: this.markPasswordForgotten.bind(this), unMarkPasswordForgotten: this.unMarkPasswordForgotten.bind(this), - safelistPhishingDomain: this.safelistPhishingDomain.bind(this), getRequestAccountTabIds: this.getRequestAccountTabIds, getOpenMetamaskTabsIds: this.getOpenMetamaskTabsIds, markNotificationPopupAsAutomaticallyClosed: () => @@ -3309,6 +3311,33 @@ export default class MetamaskController extends EventEmitter { ); } + /** + * Used to create a multiplexed stream for connecting to the phishing warning page. + * + * @param options - Options bag. + * @param {ReadableStream} options.connectionStream - The Duplex stream to connect to. + */ + setupPhishingCommunication({ connectionStream }) { + const { usePhishDetect } = this.preferencesController.store.getState(); + + if (!usePhishDetect) { + return; + } + + // setup multiplexing + const mux = setupMultiplex(connectionStream); + const phishingStream = mux.createStream(PHISHING_SAFELIST); + + // set up postStream transport + phishingStream.on( + 'data', + createMetaRPCHandler( + { safelistPhishingDomain: this.safelistPhishingDomain.bind(this) }, + phishingStream, + ), + ); + } + /** * Called when we detect a suspicious domain. Requests the browser redirects * to our anti-phishing page. diff --git a/app/scripts/phishing-detect.js b/app/scripts/phishing-detect.js deleted file mode 100644 index 68c30d501..000000000 --- a/app/scripts/phishing-detect.js +++ /dev/null @@ -1,40 +0,0 @@ -import querystring from 'querystring'; -import PortStream from 'extension-port-stream'; -import browser from 'webextension-polyfill'; -import createRandomId from '../../shared/modules/random-id'; -import { setupMultiplex } from './lib/stream-utils'; -import { getEnvironmentType } from './lib/util'; -import ExtensionPlatform from './platforms/extension'; - -document.addEventListener('DOMContentLoaded', start); - -function start() { - const hash = window.location.hash.substring(1); - const suspect = querystring.parse(hash); - - const newIssueLink = document.getElementById('new-issue-link'); - const newIssueUrl = `https://github.com/MetaMask/eth-phishing-detect/issues/new`; - const newIssueParams = `?title=[Legitimate%20Site%20Blocked]%20${encodeURIComponent( - suspect.hostname, - )}&body=${encodeURIComponent(suspect.href)}`; - newIssueLink.href = `${newIssueUrl}${newIssueParams}`; - - global.platform = new ExtensionPlatform(); - - const extensionPort = browser.runtime.connect({ - name: getEnvironmentType(), - }); - const connectionStream = new PortStream(extensionPort); - const mx = setupMultiplex(connectionStream); - const backgroundConnection = mx.createStream('controller'); - const continueLink = document.getElementById('unsafe-continue'); - continueLink.addEventListener('click', () => { - backgroundConnection.write({ - jsonrpc: '2.0', - method: 'safelistPhishingDomain', - params: [suspect.hostname], - id: createRandomId(), - }); - window.location.href = suspect.href; - }); -} diff --git a/development/build/scripts.js b/development/build/scripts.js index b3f62b75e..044551399 100644 --- a/development/build/scripts.js +++ b/development/build/scripts.js @@ -34,6 +34,7 @@ const metamaskrc = require('rc')('metamask', { INFURA_PROD_PROJECT_ID: process.env.INFURA_PROD_PROJECT_ID, ONBOARDING_V2: process.env.ONBOARDING_V2, COLLECTIBLES_V1: process.env.COLLECTIBLES_V1, + PHISHING_WARNING_PAGE_URL: process.env.PHISHING_WARNING_PAGE_URL, TOKEN_DETECTION_V2: process.env.TOKEN_DETECTION_V2, SEGMENT_HOST: process.env.SEGMENT_HOST, SEGMENT_WRITE_KEY: process.env.SEGMENT_WRITE_KEY, @@ -133,6 +134,48 @@ function getSegmentWriteKey({ buildType, environment }) { throw new Error(`Invalid build type: '${buildType}'`); } +/** + * Get the URL for the phishing warning page, if it has been set. + * + * @param {object} options - The phishing warning page options. + * @param {boolean} options.testing - Whether this is a test build or not. + * @returns {string} The URL for the phishing warning page, or `undefined` if no URL is set. + */ +function getPhishingWarningPageUrl({ testing }) { + let phishingWarningPageUrl = metamaskrc.PHISHING_WARNING_PAGE_URL; + + if (!phishingWarningPageUrl) { + phishingWarningPageUrl = testing + ? 'http://localhost:9999/' + : 'https://metamask.github.io/phishing-warning/v1.1.0/'; + } + + // We add a hash/fragment to the URL dynamically, so we need to ensure it + // has a valid pathname to append a hash to. + const normalizedUrl = phishingWarningPageUrl.endsWith('/') + ? phishingWarningPageUrl + : `${phishingWarningPageUrl}/`; + + let phishingWarningPageUrlObject; + try { + // eslint-disable-next-line no-new + phishingWarningPageUrlObject = new URL(normalizedUrl); + } catch (error) { + throw new Error( + `Invalid phishing warning page URL: '${normalizedUrl}'`, + error, + ); + } + if (phishingWarningPageUrlObject.hash) { + // The URL fragment must be set dynamically + throw new Error( + `URL fragment not allowed in phishing warning page URL: '${normalizedUrl}'`, + ); + } + + return normalizedUrl; +} + const noopWriteStream = through.obj((_file, _fileEncoding, callback) => callback(), ); @@ -218,11 +261,6 @@ function createScriptTasks({ createTaskForBundleSentry({ devMode, testing }), ); - const phishingDetectSubtask = createTask( - `${taskPrefix}:phishing-detect`, - createTaskForBundlePhishingDetect({ devMode, testing }), - ); - // task for initiating browser livereload const initiateLiveReload = async () => { if (devMode) { @@ -245,7 +283,6 @@ function createScriptTasks({ contentscriptSubtask, disableConsoleSubtask, installSentrySubtask, - phishingDetectSubtask, ].map((subtask) => runInChildProcess(subtask, { applyLavaMoat, @@ -293,23 +330,6 @@ function createScriptTasks({ }); } - function createTaskForBundlePhishingDetect({ devMode, testing }) { - const label = 'phishing-detect'; - return createNormalBundle({ - buildType, - browserPlatforms, - destFilepath: `${label}.js`, - devMode, - entryFilepath: `./app/scripts/${label}.js`, - ignoredFiles, - label, - testing, - policyOnly, - shouldLintFenceFiles, - version, - }); - } - // the "contentscript" bundle contains the "inpage" bundle function createTaskForBundleContentscript({ devMode, testing }) { const inpage = 'inpage'; @@ -882,6 +902,7 @@ function getEnvironmentVariables({ buildType, devMode, testing, version }) { METAMASK_BUILD_TYPE: buildType, NODE_ENV: devMode ? ENVIRONMENT.DEVELOPMENT : ENVIRONMENT.PRODUCTION, IN_TEST: testing, + PHISHING_WARNING_PAGE_URL: getPhishingWarningPageUrl({ testing }), PUBNUB_SUB_KEY: process.env.PUBNUB_SUB_KEY || '', PUBNUB_PUB_KEY: process.env.PUBNUB_PUB_KEY || '', CONF: devMode ? metamaskrc : {}, diff --git a/development/build/static.js b/development/build/static.js index 7efde5a72..d1f024fbc 100644 --- a/development/build/static.js +++ b/development/build/static.js @@ -174,10 +174,6 @@ function getCopyTargets(shouldIncludeLockdown) { src: require.resolve('@lavamoat/lavapack/src/runtime.js'), dest: `runtime-lavamoat.js`, }, - { - src: `./app/phishing.html`, - dest: `phishing.html`, - }, ]; const languageTags = new Set(); diff --git a/development/sourcemap-validator.js b/development/sourcemap-validator.js index 01861e229..0531a03ce 100644 --- a/development/sourcemap-validator.js +++ b/development/sourcemap-validator.js @@ -24,7 +24,6 @@ async function start() { `common-0.js`, `background-0.js`, `ui-0.js`, - 'phishing-detect.js', // `contentscript.js`, skipped because the validator is erroneously sampling the inlined `inpage.js` script `inpage.js`, ]; diff --git a/lavamoat/build-system/policy.json b/lavamoat/build-system/policy.json index b0da8c0bb..2e1f4b6b2 100644 --- a/lavamoat/build-system/policy.json +++ b/lavamoat/build-system/policy.json @@ -4090,7 +4090,6 @@ "gulp-watch>chokidar>anymatch": true, "gulp-watch>chokidar>async-each": true, "gulp-watch>chokidar>braces": true, - "gulp-watch>chokidar>fsevents": true, "gulp-watch>chokidar>is-binary-path": true, "gulp-watch>chokidar>is-glob": true, "gulp-watch>chokidar>normalize-path": true, @@ -4240,1319 +4239,552 @@ "webpack>micromatch>braces>fill-range>repeat-string": true } }, - "gulp-watch>chokidar>fsevents": { + "gulp-watch>chokidar>is-binary-path": { "builtin": { - "events.EventEmitter": true, - "fs.stat": true, - "path.join": true, - "util.inherits": true - }, - "globals": { - "__dirname": true, - "process.nextTick": true, - "process.platform": true, - "setImmediate": true + "path.extname": true }, "packages": { - "gulp-watch>chokidar>fsevents>node-pre-gyp": true + "gulp-watch>chokidar>is-binary-path>binary-extensions": true + } + }, + "gulp-watch>chokidar>is-glob": { + "packages": { + "gulp-watch>chokidar>is-glob>is-extglob": true } }, - "gulp-watch>chokidar>fsevents>node-pre-gyp": { + "gulp-watch>chokidar>readdirp": { "builtin": { - "events.EventEmitter": true, - "fs.existsSync": true, - "fs.readFileSync": true, - "fs.renameSync": true, - "path.dirname": true, - "path.existsSync": true, "path.join": true, - "path.resolve": true, - "url.parse": true, - "url.resolve": true, + "path.relative": true, "util.inherits": true }, "globals": { - "__dirname": true, - "console.log": true, - "process.arch": true, - "process.cwd": true, - "process.env": true, - "process.platform": true, - "process.version.substr": true, - "process.versions": true + "setImmediate": true }, "packages": { - "gulp-watch>chokidar>fsevents>node-pre-gyp>detect-libc": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>nopt": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>rimraf": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>semver": true - } - }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>detect-libc": { - "builtin": { - "child_process.spawnSync": true, - "fs.readdirSync": true, - "os.platform": true - }, - "globals": { - "process.env": true + "fs-extra>graceful-fs": true, + "gulp-watch>chokidar>readdirp>micromatch": true, + "readable-stream": true } }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>nopt": { + "gulp-watch>chokidar>readdirp>micromatch": { "builtin": { - "path": true, - "stream.Stream": true, - "url": true + "path.basename": true, + "path.sep": true, + "util.inspect": true }, "globals": { - "console": true, - "process.argv": true, - "process.env.DEBUG_NOPT": true, - "process.env.NOPT_DEBUG": true, "process.platform": true }, "packages": { - "gulp-watch>chokidar>fsevents>node-pre-gyp>nopt>abbrev": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>nopt>osenv": true + "gulp-watch>chokidar>braces": true, + "gulp-watch>chokidar>readdirp>micromatch>arr-diff": true, + "gulp-watch>chokidar>readdirp>micromatch>array-unique": true, + "gulp-watch>chokidar>readdirp>micromatch>define-property": true, + "gulp-watch>chokidar>readdirp>micromatch>extend-shallow": true, + "gulp-watch>chokidar>readdirp>micromatch>extglob": true, + "gulp-watch>chokidar>readdirp>micromatch>kind-of": true, + "webpack>micromatch>fragment-cache": true, + "webpack>micromatch>nanomatch": true, + "webpack>micromatch>object.pick": true, + "webpack>micromatch>regex-not": true, + "webpack>micromatch>snapdragon": true, + "webpack>micromatch>to-regex": true + } + }, + "gulp-watch>chokidar>readdirp>micromatch>define-property": { + "packages": { + "gulp>gulp-cli>isobject": true, + "webpack>micromatch>define-property>is-descriptor": true } }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>nopt>osenv": { - "builtin": { - "child_process.exec": true, - "path": true - }, - "globals": { - "process.env.COMPUTERNAME": true, - "process.env.ComSpec": true, - "process.env.EDITOR": true, - "process.env.HOSTNAME": true, - "process.env.PATH": true, - "process.env.PROMPT": true, - "process.env.PS1": true, - "process.env.Path": true, - "process.env.SHELL": true, - "process.env.USER": true, - "process.env.USERDOMAIN": true, - "process.env.USERNAME": true, - "process.env.VISUAL": true, - "process.env.path": true, - "process.nextTick": true, - "process.platform": true - }, + "gulp-watch>chokidar>readdirp>micromatch>extend-shallow": { "packages": { - "gulp-watch>chokidar>fsevents>node-pre-gyp>nopt>osenv>os-homedir": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>nopt>osenv>os-tmpdir": true + "gulp-watch>chokidar>readdirp>micromatch>extend-shallow>is-extendable": true, + "webpack>micromatch>extend-shallow>assign-symbols": true } }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>nopt>osenv>os-homedir": { - "builtin": { - "os.homedir": true - }, - "globals": { - "process.env": true, - "process.getuid": true, - "process.platform": true + "gulp-watch>chokidar>readdirp>micromatch>extend-shallow>is-extendable": { + "packages": { + "gulp>gulp-cli>liftoff>is-plain-object": true } }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>nopt>osenv>os-tmpdir": { - "globals": { - "process.env.SystemRoot": true, - "process.env.TEMP": true, - "process.env.TMP": true, - "process.env.TMPDIR": true, - "process.env.windir": true, - "process.platform": true + "gulp-watch>chokidar>readdirp>micromatch>extglob": { + "packages": { + "gulp-watch>chokidar>readdirp>micromatch>array-unique": true, + "gulp-watch>chokidar>readdirp>micromatch>extglob>define-property": true, + "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets": true, + "gulp-watch>chokidar>readdirp>micromatch>extglob>extend-shallow": true, + "webpack>micromatch>fragment-cache": true, + "webpack>micromatch>regex-not": true, + "webpack>micromatch>snapdragon": true, + "webpack>micromatch>to-regex": true } }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog": { - "builtin": { - "events.EventEmitter": true, - "util": true - }, - "globals": { - "process.nextTick": true, - "process.stderr": true - }, + "gulp-watch>chokidar>readdirp>micromatch>extglob>define-property": { "packages": { - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>are-we-there-yet": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>console-control-strings": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>gauge": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>set-blocking": true + "webpack>micromatch>define-property>is-descriptor": true } }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>are-we-there-yet": { - "builtin": { - "events.EventEmitter": true, - "util.inherits": true + "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets": { + "globals": { + "__filename": true }, "packages": { - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>are-we-there-yet>delegates": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>are-we-there-yet>readable-stream": true + "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets>debug": true, + "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets>define-property": true, + "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets>extend-shallow": true, + "webpack>micromatch>extglob>expand-brackets>posix-character-classes": true, + "webpack>micromatch>regex-not": true, + "webpack>micromatch>snapdragon": true, + "webpack>micromatch>to-regex": true } }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>are-we-there-yet>readable-stream": { + "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets>debug": { "builtin": { - "events.EventEmitter": true, - "stream": true, + "fs.SyncWriteStream": true, + "net.Socket": true, + "tty.WriteStream": true, + "tty.isatty": true, "util": true }, "globals": { - "process.browser": true, - "process.env.READABLE_STREAM": true, - "process.stderr": true, - "process.stdout": true, - "process.version.slice": true, - "setImmediate": true + "chrome": true, + "console": true, + "document": true, + "localStorage": true, + "navigator": true, + "process": true }, "packages": { - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>are-we-there-yet>readable-stream>core-util-is": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>are-we-there-yet>readable-stream>isarray": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>are-we-there-yet>readable-stream>process-nextick-args": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>are-we-there-yet>readable-stream>string_decoder": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>are-we-there-yet>readable-stream>util-deprecate": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>rimraf>glob>inherits": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>tar>safe-buffer": true + "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets>debug>ms": true } }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>are-we-there-yet>readable-stream>core-util-is": { - "globals": { - "Buffer.isBuffer": true + "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets>define-property": { + "packages": { + "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets>define-property>is-descriptor": true } }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>are-we-there-yet>readable-stream>process-nextick-args": { - "globals": { - "process": true + "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets>define-property>is-descriptor": { + "packages": { + "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets>define-property>is-descriptor>is-accessor-descriptor": true, + "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets>define-property>is-descriptor>is-data-descriptor": true, + "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets>define-property>is-descriptor>kind-of": true } }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>are-we-there-yet>readable-stream>string_decoder": { + "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets>define-property>is-descriptor>is-accessor-descriptor": { "packages": { - "gulp-watch>chokidar>fsevents>node-pre-gyp>tar>safe-buffer": true + "gulp-watch>anymatch>micromatch>kind-of": true } }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>are-we-there-yet>readable-stream>util-deprecate": { - "builtin": { - "util.deprecate": true + "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets>define-property>is-descriptor>is-data-descriptor": { + "packages": { + "gulp-watch>anymatch>micromatch>kind-of": true } }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>gauge": { - "builtin": { - "util.format": true - }, - "globals": { - "clearInterval": true, - "process": true, - "setImmediate": true, - "setInterval": true - }, + "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets>extend-shallow": { "packages": { - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>console-control-strings": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>gauge>aproba": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>gauge>has-unicode": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>gauge>object-assign": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>gauge>signal-exit": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>gauge>string-width": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>gauge>strip-ansi": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>gauge>wide-align": true + "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets>extend-shallow>is-extendable": true } }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>gauge>has-unicode": { - "builtin": { - "os.type": true - }, - "globals": { - "process.env.LANG": true, - "process.env.LC_ALL": true, - "process.env.LC_CTYPE": true + "gulp-watch>chokidar>readdirp>micromatch>extglob>extend-shallow": { + "packages": { + "gulp-watch>chokidar>readdirp>micromatch>extglob>extend-shallow>is-extendable": true } }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>gauge>signal-exit": { + "gulp-watch>chokidar>upath": { "builtin": { - "assert.equal": true, - "events": true - }, - "globals": { - "process": true + "path": true } }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>gauge>string-width": { + "gulp-watch>fancy-log": { + "globals": { + "console": true, + "process.argv.indexOf": true, + "process.stderr.write": true, + "process.stdout.write": true + }, "packages": { - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>gauge>string-width>code-point-at": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>gauge>string-width>is-fullwidth-code-point": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>gauge>strip-ansi": true + "fancy-log>ansi-gray": true, + "fancy-log>color-support": true, + "fancy-log>time-stamp": true } }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>gauge>string-width>is-fullwidth-code-point": { + "gulp-watch>glob-parent": { + "builtin": { + "os.platform": true, + "path": true + }, "packages": { - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>gauge>string-width>is-fullwidth-code-point>number-is-nan": true + "gulp-watch>glob-parent>is-glob": true, + "gulp-watch>glob-parent>path-dirname": true } }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>gauge>strip-ansi": { + "gulp-watch>glob-parent>is-glob": { "packages": { - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>gauge>strip-ansi>ansi-regex": true + "gulp-watch>glob-parent>is-glob>is-extglob": true } }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>gauge>wide-align": { - "packages": { - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>gauge>string-width": true + "gulp-watch>glob-parent>path-dirname": { + "builtin": { + "path": true, + "util.inspect": true + }, + "globals": { + "process.platform": true } }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>set-blocking": { + "gulp-watch>path-is-absolute": { "globals": { - "process.stderr": true, - "process.stdout": true + "process.platform": true } }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>rimraf": { + "gulp-watch>vinyl-file": { "builtin": { - "assert": true, - "fs": true, - "path.join": true + "path.resolve": true }, "globals": { - "process.platform": true, - "setTimeout": true + "process.cwd": true }, "packages": { - "gulp-watch>chokidar>fsevents>node-pre-gyp>rimraf>glob": true + "del>globby>pinkie-promise": true, + "fs-extra>graceful-fs": true, + "gulp-watch>vinyl-file>pify": true, + "gulp-watch>vinyl-file>strip-bom": true, + "gulp-watch>vinyl-file>strip-bom-stream": true, + "gulp-watch>vinyl-file>vinyl": true } }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>rimraf>glob": { - "builtin": { - "assert": true, - "events.EventEmitter": true, - "fs.lstat": true, - "fs.lstatSync": true, - "fs.readdir": true, - "fs.readdirSync": true, - "fs.stat": true, - "fs.statSync": true, - "path.join": true, - "path.resolve": true, - "util": true - }, + "gulp-watch>vinyl-file>strip-bom": { "globals": { - "console.error": true, - "process.cwd": true, - "process.nextTick": true, - "process.platform": true + "Buffer.isBuffer": true }, "packages": { - "gulp-watch>chokidar>fsevents>node-pre-gyp>rimraf>glob>fs.realpath": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>rimraf>glob>inflight": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>rimraf>glob>inherits": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>rimraf>glob>minimatch": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>rimraf>glob>once": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>rimraf>glob>path-is-absolute": true + "gulp>vinyl-fs>remove-bom-buffer>is-utf8": true } }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>rimraf>glob>fs.realpath": { - "builtin": { - "fs.lstat": true, - "fs.lstatSync": true, - "fs.readlink": true, - "fs.readlinkSync": true, - "fs.realpath": true, - "fs.realpathSync": true, - "fs.stat": true, - "fs.statSync": true, - "path.normalize": true, - "path.resolve": true - }, - "globals": { - "console.error": true, - "console.trace": true, - "process.env.NODE_DEBUG": true, - "process.nextTick": true, - "process.noDeprecation": true, - "process.platform": true, - "process.throwDeprecation": true, - "process.traceDeprecation": true, - "process.version": true - } - }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>rimraf>glob>inflight": { - "globals": { - "process.nextTick": true - }, - "packages": { - "gulp-watch>chokidar>fsevents>node-pre-gyp>rimraf>glob>once": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>rimraf>glob>once>wrappy": true - } - }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>rimraf>glob>inherits": { - "builtin": { - "util.inherits": true - } - }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>rimraf>glob>minimatch": { - "builtin": { - "path": true - }, - "globals": { - "console.error": true - }, - "packages": { - "gulp-watch>chokidar>fsevents>node-pre-gyp>rimraf>glob>minimatch>brace-expansion": true - } - }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>rimraf>glob>minimatch>brace-expansion": { - "packages": { - "gulp-watch>chokidar>fsevents>node-pre-gyp>rimraf>glob>minimatch>brace-expansion>balanced-match": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>rimraf>glob>minimatch>brace-expansion>concat-map": true - } - }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>rimraf>glob>once": { - "packages": { - "gulp-watch>chokidar>fsevents>node-pre-gyp>rimraf>glob>once>wrappy": true - } - }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>rimraf>glob>path-is-absolute": { - "globals": { - "process.platform": true - } - }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>semver": { - "globals": { - "console": true, - "process": true - } - }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>tar>safe-buffer": { - "builtin": { - "buffer": true - } - }, - "gulp-watch>chokidar>is-binary-path": { - "builtin": { - "path.extname": true - }, - "packages": { - "gulp-watch>chokidar>is-binary-path>binary-extensions": true - } - }, - "gulp-watch>chokidar>is-glob": { - "packages": { - "gulp-watch>chokidar>is-glob>is-extglob": true - } - }, - "gulp-watch>chokidar>readdirp": { - "builtin": { - "path.join": true, - "path.relative": true, - "util.inherits": true - }, - "globals": { - "setImmediate": true - }, - "packages": { - "fs-extra>graceful-fs": true, - "gulp-watch>chokidar>readdirp>micromatch": true, - "readable-stream": true - } - }, - "gulp-watch>chokidar>readdirp>micromatch": { - "builtin": { - "path.basename": true, - "path.sep": true, - "util.inspect": true - }, - "globals": { - "process.platform": true - }, - "packages": { - "gulp-watch>chokidar>braces": true, - "gulp-watch>chokidar>readdirp>micromatch>arr-diff": true, - "gulp-watch>chokidar>readdirp>micromatch>array-unique": true, - "gulp-watch>chokidar>readdirp>micromatch>define-property": true, - "gulp-watch>chokidar>readdirp>micromatch>extend-shallow": true, - "gulp-watch>chokidar>readdirp>micromatch>extglob": true, - "gulp-watch>chokidar>readdirp>micromatch>kind-of": true, - "webpack>micromatch>fragment-cache": true, - "webpack>micromatch>nanomatch": true, - "webpack>micromatch>object.pick": true, - "webpack>micromatch>regex-not": true, - "webpack>micromatch>snapdragon": true, - "webpack>micromatch>to-regex": true - } - }, - "gulp-watch>chokidar>readdirp>micromatch>define-property": { - "packages": { - "gulp>gulp-cli>isobject": true, - "webpack>micromatch>define-property>is-descriptor": true - } - }, - "gulp-watch>chokidar>readdirp>micromatch>extend-shallow": { - "packages": { - "gulp-watch>chokidar>readdirp>micromatch>extend-shallow>is-extendable": true, - "webpack>micromatch>extend-shallow>assign-symbols": true - } - }, - "gulp-watch>chokidar>readdirp>micromatch>extend-shallow>is-extendable": { - "packages": { - "gulp>gulp-cli>liftoff>is-plain-object": true - } - }, - "gulp-watch>chokidar>readdirp>micromatch>extglob": { - "packages": { - "gulp-watch>chokidar>readdirp>micromatch>array-unique": true, - "gulp-watch>chokidar>readdirp>micromatch>extglob>define-property": true, - "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets": true, - "gulp-watch>chokidar>readdirp>micromatch>extglob>extend-shallow": true, - "webpack>micromatch>fragment-cache": true, - "webpack>micromatch>regex-not": true, - "webpack>micromatch>snapdragon": true, - "webpack>micromatch>to-regex": true - } - }, - "gulp-watch>chokidar>readdirp>micromatch>extglob>define-property": { - "packages": { - "webpack>micromatch>define-property>is-descriptor": true - } - }, - "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets": { - "globals": { - "__filename": true - }, - "packages": { - "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets>debug": true, - "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets>define-property": true, - "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets>extend-shallow": true, - "webpack>micromatch>extglob>expand-brackets>posix-character-classes": true, - "webpack>micromatch>regex-not": true, - "webpack>micromatch>snapdragon": true, - "webpack>micromatch>to-regex": true - } - }, - "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets>debug": { - "builtin": { - "fs.SyncWriteStream": true, - "net.Socket": true, - "tty.WriteStream": true, - "tty.isatty": true, - "util": true - }, - "globals": { - "chrome": true, - "console": true, - "document": true, - "localStorage": true, - "navigator": true, - "process": true - }, - "packages": { - "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets>debug>ms": true - } - }, - "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets>define-property": { - "packages": { - "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets>define-property>is-descriptor": true - } - }, - "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets>define-property>is-descriptor": { - "packages": { - "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets>define-property>is-descriptor>is-accessor-descriptor": true, - "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets>define-property>is-descriptor>is-data-descriptor": true, - "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets>define-property>is-descriptor>kind-of": true - } - }, - "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets>define-property>is-descriptor>is-accessor-descriptor": { - "packages": { - "gulp-watch>anymatch>micromatch>kind-of": true - } - }, - "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets>define-property>is-descriptor>is-data-descriptor": { - "packages": { - "gulp-watch>anymatch>micromatch>kind-of": true - } - }, - "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets>extend-shallow": { - "packages": { - "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets>extend-shallow>is-extendable": true - } - }, - "gulp-watch>chokidar>readdirp>micromatch>extglob>extend-shallow": { - "packages": { - "gulp-watch>chokidar>readdirp>micromatch>extglob>extend-shallow>is-extendable": true - } - }, - "gulp-watch>chokidar>upath": { - "builtin": { - "path": true - } - }, - "gulp-watch>fancy-log": { - "globals": { - "console": true, - "process.argv.indexOf": true, - "process.stderr.write": true, - "process.stdout.write": true - }, - "packages": { - "fancy-log>ansi-gray": true, - "fancy-log>color-support": true, - "fancy-log>time-stamp": true - } - }, - "gulp-watch>glob-parent": { - "builtin": { - "os.platform": true, - "path": true - }, - "packages": { - "gulp-watch>glob-parent>is-glob": true, - "gulp-watch>glob-parent>path-dirname": true - } - }, - "gulp-watch>glob-parent>is-glob": { - "packages": { - "gulp-watch>glob-parent>is-glob>is-extglob": true - } - }, - "gulp-watch>glob-parent>path-dirname": { - "builtin": { - "path": true, - "util.inspect": true - }, - "globals": { - "process.platform": true - } - }, - "gulp-watch>path-is-absolute": { - "globals": { - "process.platform": true - } - }, - "gulp-watch>vinyl-file": { - "builtin": { - "path.resolve": true - }, - "globals": { - "process.cwd": true - }, - "packages": { - "del>globby>pinkie-promise": true, - "fs-extra>graceful-fs": true, - "gulp-watch>vinyl-file>pify": true, - "gulp-watch>vinyl-file>strip-bom": true, - "gulp-watch>vinyl-file>strip-bom-stream": true, - "gulp-watch>vinyl-file>vinyl": true - } - }, - "gulp-watch>vinyl-file>strip-bom": { - "globals": { - "Buffer.isBuffer": true - }, - "packages": { - "gulp>vinyl-fs>remove-bom-buffer>is-utf8": true - } - }, - "gulp-watch>vinyl-file>strip-bom-stream": { - "packages": { - "gulp-watch>vinyl-file>strip-bom": true, - "gulp-watch>vinyl-file>strip-bom-stream>first-chunk-stream": true - } - }, - "gulp-watch>vinyl-file>strip-bom-stream>first-chunk-stream": { - "builtin": { - "util.inherits": true - }, - "globals": { - "Buffer.concat": true, - "setImmediate": true - }, - "packages": { - "readable-stream": true - } - }, - "gulp-watch>vinyl-file>vinyl": { - "builtin": { - "buffer.Buffer": true, - "path.basename": true, - "path.dirname": true, - "path.extname": true, - "path.join": true, - "path.relative": true, - "stream.PassThrough": true, - "stream.Stream": true - }, - "globals": { - "process.cwd": true - }, - "packages": { - "gulp-watch>vinyl-file>vinyl>clone": true, - "gulp-watch>vinyl-file>vinyl>clone-stats": true, - "gulp-watch>vinyl-file>vinyl>replace-ext": true - } - }, - "gulp-watch>vinyl-file>vinyl>clone": { - "globals": { - "Buffer": true - } - }, - "gulp-watch>vinyl-file>vinyl>clone-stats": { - "builtin": { - "fs.Stats": true - } - }, - "gulp-watch>vinyl-file>vinyl>replace-ext": { - "builtin": { - "path.basename": true, - "path.dirname": true, - "path.extname": true, - "path.join": true - } - }, - "gulp-zip": { - "builtin": { - "buffer.constants.MAX_LENGTH": true, - "path.join": true - }, - "packages": { - "gulp-zip>get-stream": true, - "gulp-zip>plugin-error": true, - "gulp-zip>through2": true, - "gulp-zip>yazl": true, - "vinyl": true - } - }, - "gulp-zip>get-stream": { - "builtin": { - "buffer.constants.MAX_LENGTH": true, - "stream.PassThrough": true - }, - "globals": { - "Buffer.concat": true - }, - "packages": { - "pump": true - } - }, - "gulp-zip>plugin-error": { - "builtin": { - "util.inherits": true - }, - "packages": { - "gulp-watch>ansi-colors": true, - "gulp-zip>plugin-error>arr-union": true, - "gulp-zip>plugin-error>extend-shallow": true, - "webpack>micromatch>arr-diff": true - } - }, - "gulp-zip>plugin-error>extend-shallow": { - "packages": { - "gulp-zip>plugin-error>extend-shallow>is-extendable": true, - "webpack>micromatch>extend-shallow>assign-symbols": true - } - }, - "gulp-zip>plugin-error>extend-shallow>is-extendable": { - "packages": { - "gulp>gulp-cli>liftoff>is-plain-object": true - } - }, - "gulp-zip>through2": { - "builtin": { - "util.inherits": true - }, - "globals": { - "process.nextTick": true - }, - "packages": { - "gulp-zip>through2>readable-stream": true - } - }, - "gulp-zip>through2>readable-stream": { - "builtin": { - "buffer.Buffer": true, - "events.EventEmitter": true, - "stream": true, - "util": true - }, - "globals": { - "process.env.READABLE_STREAM": true, - "process.nextTick": true, - "process.stderr": true, - "process.stdout": true - }, - "packages": { - "@storybook/api>util-deprecate": true, - "browserify>string_decoder": true, - "pumpify>inherits": true - } - }, - "gulp-zip>yazl": { - "builtin": { - "events.EventEmitter": true, - "fs.createReadStream": true, - "fs.stat": true, - "stream.PassThrough": true, - "stream.Transform": true, - "util.inherits": true, - "zlib.DeflateRaw": true, - "zlib.deflateRaw": true - }, - "globals": { - "Buffer": true, - "setImmediate": true, - "utf8FileName.length": true - }, - "packages": { - "gulp-zip>yazl>buffer-crc32": true - } - }, - "gulp-zip>yazl>buffer-crc32": { - "builtin": { - "buffer.Buffer": true - } - }, - "gulp>glob-watcher": { - "packages": { - "gulp>glob-watcher>anymatch": true, - "gulp>glob-watcher>async-done": true, - "gulp>glob-watcher>chokidar": true, - "gulp>glob-watcher>is-negated-glob": true, - "gulp>glob-watcher>just-debounce": true, - "gulp>undertaker>object.defaults": true - } - }, - "gulp>glob-watcher>anymatch": { - "builtin": { - "path.sep": true - }, - "packages": { - "gulp>glob-watcher>anymatch>micromatch": true, - "gulp>glob-watcher>anymatch>normalize-path": true - } - }, - "gulp>glob-watcher>anymatch>micromatch": { - "builtin": { - "path.basename": true, - "path.sep": true, - "util.inspect": true - }, - "globals": { - "process.platform": true - }, - "packages": { - "3box>ipfs>kind-of": true, - "gulp>glob-watcher>anymatch>micromatch>define-property": true, - "gulp>glob-watcher>anymatch>micromatch>extend-shallow": true, - "gulp>glob-watcher>chokidar>braces": true, - "webpack>micromatch>arr-diff": true, - "webpack>micromatch>array-unique": true, - "webpack>micromatch>extglob": true, - "webpack>micromatch>fragment-cache": true, - "webpack>micromatch>nanomatch": true, - "webpack>micromatch>object.pick": true, - "webpack>micromatch>regex-not": true, - "webpack>micromatch>snapdragon": true, - "webpack>micromatch>to-regex": true - } - }, - "gulp>glob-watcher>anymatch>micromatch>define-property": { - "packages": { - "gulp>gulp-cli>isobject": true, - "webpack>micromatch>define-property>is-descriptor": true - } - }, - "gulp>glob-watcher>anymatch>micromatch>extend-shallow": { - "packages": { - "gulp>glob-watcher>anymatch>micromatch>extend-shallow>is-extendable": true, - "webpack>micromatch>extend-shallow>assign-symbols": true - } - }, - "gulp>glob-watcher>anymatch>micromatch>extend-shallow>is-extendable": { - "packages": { - "gulp>gulp-cli>liftoff>is-plain-object": true - } - }, - "gulp>glob-watcher>anymatch>normalize-path": { - "packages": { - "vinyl>remove-trailing-separator": true - } - }, - "gulp>glob-watcher>async-done": { - "builtin": { - "domain.create": true - }, - "globals": { - "process.nextTick": true - }, + "gulp-watch>vinyl-file>strip-bom-stream": { "packages": { - "end-of-stream": true, - "gulp>glob-watcher>async-done>stream-exhaust": true, - "pump>once": true, - "vinyl>cloneable-readable>process-nextick-args": true + "gulp-watch>vinyl-file>strip-bom": true, + "gulp-watch>vinyl-file>strip-bom-stream>first-chunk-stream": true } }, - "gulp>glob-watcher>async-done>stream-exhaust": { + "gulp-watch>vinyl-file>strip-bom-stream>first-chunk-stream": { "builtin": { - "stream.Writable": true, "util.inherits": true }, "globals": { + "Buffer.concat": true, "setImmediate": true + }, + "packages": { + "readable-stream": true } }, - "gulp>glob-watcher>chokidar": { + "gulp-watch>vinyl-file>vinyl": { "builtin": { - "events.EventEmitter": true, - "fs": true, + "buffer.Buffer": true, "path.basename": true, "path.dirname": true, "path.extname": true, "path.join": true, "path.relative": true, - "path.resolve": true, - "path.sep": true + "stream.PassThrough": true, + "stream.Stream": true }, "globals": { - "clearTimeout": true, - "console.error": true, - "process.env.CHOKIDAR_INTERVAL": true, - "process.env.CHOKIDAR_PRINT_FSEVENTS_REQUIRE_ERROR": true, - "process.env.CHOKIDAR_USEPOLLING": true, - "process.nextTick": true, - "process.platform": true, - "setTimeout": true - }, - "packages": { - "eslint>is-glob": true, - "gulp-watch>chokidar>async-each": true, - "gulp-watch>path-is-absolute": true, - "gulp>glob-watcher>anymatch": true, - "gulp>glob-watcher>chokidar>braces": true, - "gulp>glob-watcher>chokidar>fsevents": true, - "gulp>glob-watcher>chokidar>glob-parent": true, - "gulp>glob-watcher>chokidar>is-binary-path": true, - "gulp>glob-watcher>chokidar>normalize-path": true, - "gulp>glob-watcher>chokidar>readdirp": true, - "gulp>glob-watcher>chokidar>upath": true, - "pumpify>inherits": true - } - }, - "gulp>glob-watcher>chokidar>braces": { - "packages": { - "gulp>glob-watcher>chokidar>braces>fill-range": true, - "gulp>gulp-cli>isobject": true, - "gulp>undertaker>arr-flatten": true, - "webpack>micromatch>array-unique": true, - "webpack>micromatch>braces>repeat-element": true, - "webpack>micromatch>braces>snapdragon-node": true, - "webpack>micromatch>braces>split-string": true, - "webpack>micromatch>extglob>extend-shallow": true, - "webpack>micromatch>snapdragon": true, - "webpack>micromatch>to-regex": true - } - }, - "gulp>glob-watcher>chokidar>braces>fill-range": { - "builtin": { - "util.inspect": true + "process.cwd": true }, "packages": { - "gulp>glob-watcher>chokidar>braces>fill-range>is-number": true, - "gulp>glob-watcher>chokidar>braces>fill-range>to-regex-range": true, - "webpack>micromatch>braces>fill-range>repeat-string": true, - "webpack>micromatch>extglob>extend-shallow": true - } - }, - "gulp>glob-watcher>chokidar>braces>fill-range>is-number": { - "packages": { - "gulp>glob-watcher>chokidar>braces>fill-range>is-number>kind-of": true - } - }, - "gulp>glob-watcher>chokidar>braces>fill-range>is-number>kind-of": { - "packages": { - "browserify>insert-module-globals>is-buffer": true - } - }, - "gulp>glob-watcher>chokidar>braces>fill-range>to-regex-range": { - "packages": { - "gulp>glob-watcher>chokidar>braces>fill-range>is-number": true, - "webpack>micromatch>braces>fill-range>repeat-string": true + "gulp-watch>vinyl-file>vinyl>clone": true, + "gulp-watch>vinyl-file>vinyl>clone-stats": true, + "gulp-watch>vinyl-file>vinyl>replace-ext": true } }, - "gulp>glob-watcher>chokidar>fsevents": { - "builtin": { - "events.EventEmitter": true, - "fs.stat": true, - "path.join": true, - "util.inherits": true - }, + "gulp-watch>vinyl-file>vinyl>clone": { "globals": { - "__dirname": true, - "process.nextTick": true, - "process.platform": true, - "setImmediate": true - }, - "packages": { - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp": true + "Buffer": true } }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp": { + "gulp-watch>vinyl-file>vinyl>clone-stats": { "builtin": { - "events.EventEmitter": true, - "fs.existsSync": true, - "fs.readFileSync": true, - "fs.renameSync": true, - "path.dirname": true, - "path.existsSync": true, - "path.join": true, - "path.resolve": true, - "url.parse": true, - "url.resolve": true, - "util.inherits": true - }, - "globals": { - "__dirname": true, - "console.log": true, - "process.arch": true, - "process.cwd": true, - "process.env": true, - "process.platform": true, - "process.version.substr": true, - "process.versions": true - }, - "packages": { - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>detect-libc": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>nopt": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>rimraf": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>semver": true + "fs.Stats": true } }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>detect-libc": { + "gulp-watch>vinyl-file>vinyl>replace-ext": { "builtin": { - "child_process.spawnSync": true, - "fs.readdirSync": true, - "os.platform": true - }, - "globals": { - "process.env": true + "path.basename": true, + "path.dirname": true, + "path.extname": true, + "path.join": true } }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>nopt": { + "gulp-zip": { "builtin": { - "path": true, - "stream.Stream": true, - "url": true - }, - "globals": { - "console": true, - "process.argv": true, - "process.env.DEBUG_NOPT": true, - "process.env.NOPT_DEBUG": true, - "process.platform": true + "buffer.constants.MAX_LENGTH": true, + "path.join": true }, "packages": { - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>nopt>abbrev": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>nopt>osenv": true + "gulp-zip>get-stream": true, + "gulp-zip>plugin-error": true, + "gulp-zip>through2": true, + "gulp-zip>yazl": true, + "vinyl": true } }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>nopt>osenv": { + "gulp-zip>get-stream": { "builtin": { - "child_process.exec": true, - "path": true + "buffer.constants.MAX_LENGTH": true, + "stream.PassThrough": true }, "globals": { - "process.env.COMPUTERNAME": true, - "process.env.ComSpec": true, - "process.env.EDITOR": true, - "process.env.HOSTNAME": true, - "process.env.PATH": true, - "process.env.PROMPT": true, - "process.env.PS1": true, - "process.env.Path": true, - "process.env.SHELL": true, - "process.env.USER": true, - "process.env.USERDOMAIN": true, - "process.env.USERNAME": true, - "process.env.VISUAL": true, - "process.env.path": true, - "process.nextTick": true, - "process.platform": true + "Buffer.concat": true }, "packages": { - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>nopt>osenv>os-homedir": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>nopt>osenv>os-tmpdir": true + "pump": true } }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>nopt>osenv>os-homedir": { + "gulp-zip>plugin-error": { "builtin": { - "os.homedir": true + "util.inherits": true }, - "globals": { - "process.env": true, - "process.getuid": true, - "process.platform": true + "packages": { + "gulp-watch>ansi-colors": true, + "gulp-zip>plugin-error>arr-union": true, + "gulp-zip>plugin-error>extend-shallow": true, + "webpack>micromatch>arr-diff": true } }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>nopt>osenv>os-tmpdir": { - "globals": { - "process.env.SystemRoot": true, - "process.env.TEMP": true, - "process.env.TMP": true, - "process.env.TMPDIR": true, - "process.env.windir": true, - "process.platform": true + "gulp-zip>plugin-error>extend-shallow": { + "packages": { + "gulp-zip>plugin-error>extend-shallow>is-extendable": true, + "webpack>micromatch>extend-shallow>assign-symbols": true } }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog": { - "builtin": { - "events.EventEmitter": true, - "util": true - }, - "globals": { - "process.nextTick": true, - "process.stderr": true - }, + "gulp-zip>plugin-error>extend-shallow>is-extendable": { "packages": { - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>are-we-there-yet": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>console-control-strings": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>gauge": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>set-blocking": true + "gulp>gulp-cli>liftoff>is-plain-object": true } }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>are-we-there-yet": { + "gulp-zip>through2": { "builtin": { - "events.EventEmitter": true, "util.inherits": true }, + "globals": { + "process.nextTick": true + }, "packages": { - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>are-we-there-yet>delegates": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>are-we-there-yet>readable-stream": true + "gulp-zip>through2>readable-stream": true } }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>are-we-there-yet>readable-stream": { + "gulp-zip>through2>readable-stream": { "builtin": { + "buffer.Buffer": true, "events.EventEmitter": true, "stream": true, "util": true }, "globals": { - "process.browser": true, "process.env.READABLE_STREAM": true, + "process.nextTick": true, "process.stderr": true, - "process.stdout": true, - "process.version.slice": true, - "setImmediate": true + "process.stdout": true }, "packages": { - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>are-we-there-yet>readable-stream>core-util-is": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>are-we-there-yet>readable-stream>isarray": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>are-we-there-yet>readable-stream>process-nextick-args": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>are-we-there-yet>readable-stream>string_decoder": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>are-we-there-yet>readable-stream>util-deprecate": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>rimraf>glob>inherits": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>tar>safe-buffer": true - } - }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>are-we-there-yet>readable-stream>core-util-is": { - "globals": { - "Buffer.isBuffer": true + "@storybook/api>util-deprecate": true, + "browserify>string_decoder": true, + "pumpify>inherits": true } }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>are-we-there-yet>readable-stream>process-nextick-args": { + "gulp-zip>yazl": { + "builtin": { + "events.EventEmitter": true, + "fs.createReadStream": true, + "fs.stat": true, + "stream.PassThrough": true, + "stream.Transform": true, + "util.inherits": true, + "zlib.DeflateRaw": true, + "zlib.deflateRaw": true + }, "globals": { - "process": true - } - }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>are-we-there-yet>readable-stream>string_decoder": { + "Buffer": true, + "setImmediate": true, + "utf8FileName.length": true + }, "packages": { - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>tar>safe-buffer": true + "gulp-zip>yazl>buffer-crc32": true } }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>are-we-there-yet>readable-stream>util-deprecate": { + "gulp-zip>yazl>buffer-crc32": { "builtin": { - "util.deprecate": true + "buffer.Buffer": true } }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>gauge": { - "builtin": { - "util.format": true - }, - "globals": { - "clearInterval": true, - "process": true, - "setImmediate": true, - "setInterval": true - }, + "gulp>glob-watcher": { "packages": { - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>console-control-strings": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>gauge>aproba": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>gauge>has-unicode": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>gauge>object-assign": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>gauge>signal-exit": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>gauge>string-width": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>gauge>strip-ansi": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>gauge>wide-align": true + "gulp>glob-watcher>anymatch": true, + "gulp>glob-watcher>async-done": true, + "gulp>glob-watcher>chokidar": true, + "gulp>glob-watcher>is-negated-glob": true, + "gulp>glob-watcher>just-debounce": true, + "gulp>undertaker>object.defaults": true } }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>gauge>has-unicode": { + "gulp>glob-watcher>anymatch": { "builtin": { - "os.type": true + "path.sep": true }, - "globals": { - "process.env.LANG": true, - "process.env.LC_ALL": true, - "process.env.LC_CTYPE": true + "packages": { + "gulp>glob-watcher>anymatch>micromatch": true, + "gulp>glob-watcher>anymatch>normalize-path": true } }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>gauge>signal-exit": { + "gulp>glob-watcher>anymatch>micromatch": { "builtin": { - "assert.equal": true, - "events": true + "path.basename": true, + "path.sep": true, + "util.inspect": true }, "globals": { - "process": true - } - }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>gauge>string-width": { + "process.platform": true + }, "packages": { - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>gauge>string-width>code-point-at": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>gauge>string-width>is-fullwidth-code-point": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>gauge>strip-ansi": true + "3box>ipfs>kind-of": true, + "gulp>glob-watcher>anymatch>micromatch>define-property": true, + "gulp>glob-watcher>anymatch>micromatch>extend-shallow": true, + "gulp>glob-watcher>chokidar>braces": true, + "webpack>micromatch>arr-diff": true, + "webpack>micromatch>array-unique": true, + "webpack>micromatch>extglob": true, + "webpack>micromatch>fragment-cache": true, + "webpack>micromatch>nanomatch": true, + "webpack>micromatch>object.pick": true, + "webpack>micromatch>regex-not": true, + "webpack>micromatch>snapdragon": true, + "webpack>micromatch>to-regex": true } }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>gauge>string-width>is-fullwidth-code-point": { + "gulp>glob-watcher>anymatch>micromatch>define-property": { "packages": { - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>gauge>string-width>is-fullwidth-code-point>number-is-nan": true + "gulp>gulp-cli>isobject": true, + "webpack>micromatch>define-property>is-descriptor": true } }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>gauge>strip-ansi": { + "gulp>glob-watcher>anymatch>micromatch>extend-shallow": { "packages": { - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>gauge>strip-ansi>ansi-regex": true + "gulp>glob-watcher>anymatch>micromatch>extend-shallow>is-extendable": true, + "webpack>micromatch>extend-shallow>assign-symbols": true } }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>gauge>wide-align": { + "gulp>glob-watcher>anymatch>micromatch>extend-shallow>is-extendable": { "packages": { - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>gauge>string-width": true + "gulp>gulp-cli>liftoff>is-plain-object": true } }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>set-blocking": { - "globals": { - "process.stderr": true, - "process.stdout": true + "gulp>glob-watcher>anymatch>normalize-path": { + "packages": { + "vinyl>remove-trailing-separator": true } }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>rimraf": { + "gulp>glob-watcher>async-done": { "builtin": { - "assert": true, - "fs": true, - "path.join": true + "domain.create": true }, "globals": { - "process.platform": true, - "setTimeout": true + "process.nextTick": true }, "packages": { - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>rimraf>glob": true + "end-of-stream": true, + "gulp>glob-watcher>async-done>stream-exhaust": true, + "pump>once": true, + "vinyl>cloneable-readable>process-nextick-args": true } }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>rimraf>glob": { + "gulp>glob-watcher>async-done>stream-exhaust": { "builtin": { - "assert": true, - "events.EventEmitter": true, - "fs.lstat": true, - "fs.lstatSync": true, - "fs.readdir": true, - "fs.readdirSync": true, - "fs.stat": true, - "fs.statSync": true, - "path.join": true, - "path.resolve": true, - "util": true + "stream.Writable": true, + "util.inherits": true }, "globals": { - "console.error": true, - "process.cwd": true, - "process.nextTick": true, - "process.platform": true - }, - "packages": { - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>rimraf>glob>fs.realpath": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>rimraf>glob>inflight": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>rimraf>glob>inherits": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>rimraf>glob>minimatch": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>rimraf>glob>once": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>rimraf>glob>path-is-absolute": true + "setImmediate": true } }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>rimraf>glob>fs.realpath": { + "gulp>glob-watcher>chokidar": { "builtin": { - "fs.lstat": true, - "fs.lstatSync": true, - "fs.readlink": true, - "fs.readlinkSync": true, - "fs.realpath": true, - "fs.realpathSync": true, - "fs.stat": true, - "fs.statSync": true, - "path.normalize": true, - "path.resolve": true + "events.EventEmitter": true, + "fs": true, + "path.basename": true, + "path.dirname": true, + "path.extname": true, + "path.join": true, + "path.relative": true, + "path.resolve": true, + "path.sep": true }, "globals": { + "clearTimeout": true, "console.error": true, - "console.trace": true, - "process.env.NODE_DEBUG": true, + "process.env.CHOKIDAR_INTERVAL": true, + "process.env.CHOKIDAR_PRINT_FSEVENTS_REQUIRE_ERROR": true, + "process.env.CHOKIDAR_USEPOLLING": true, "process.nextTick": true, - "process.noDeprecation": true, "process.platform": true, - "process.throwDeprecation": true, - "process.traceDeprecation": true, - "process.version": true - } - }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>rimraf>glob>inflight": { - "globals": { - "process.nextTick": true + "setTimeout": true }, "packages": { - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>rimraf>glob>once": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>rimraf>glob>once>wrappy": true + "eslint>is-glob": true, + "gulp-watch>chokidar>async-each": true, + "gulp-watch>path-is-absolute": true, + "gulp>glob-watcher>anymatch": true, + "gulp>glob-watcher>chokidar>braces": true, + "gulp>glob-watcher>chokidar>glob-parent": true, + "gulp>glob-watcher>chokidar>is-binary-path": true, + "gulp>glob-watcher>chokidar>normalize-path": true, + "gulp>glob-watcher>chokidar>readdirp": true, + "gulp>glob-watcher>chokidar>upath": true, + "pumpify>inherits": true } }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>rimraf>glob>inherits": { - "builtin": { - "util.inherits": true + "gulp>glob-watcher>chokidar>braces": { + "packages": { + "gulp>glob-watcher>chokidar>braces>fill-range": true, + "gulp>gulp-cli>isobject": true, + "gulp>undertaker>arr-flatten": true, + "webpack>micromatch>array-unique": true, + "webpack>micromatch>braces>repeat-element": true, + "webpack>micromatch>braces>snapdragon-node": true, + "webpack>micromatch>braces>split-string": true, + "webpack>micromatch>extglob>extend-shallow": true, + "webpack>micromatch>snapdragon": true, + "webpack>micromatch>to-regex": true } }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>rimraf>glob>minimatch": { + "gulp>glob-watcher>chokidar>braces>fill-range": { "builtin": { - "path": true - }, - "globals": { - "console.error": true + "util.inspect": true }, "packages": { - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>rimraf>glob>minimatch>brace-expansion": true + "gulp>glob-watcher>chokidar>braces>fill-range>is-number": true, + "gulp>glob-watcher>chokidar>braces>fill-range>to-regex-range": true, + "webpack>micromatch>braces>fill-range>repeat-string": true, + "webpack>micromatch>extglob>extend-shallow": true } }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>rimraf>glob>minimatch>brace-expansion": { + "gulp>glob-watcher>chokidar>braces>fill-range>is-number": { "packages": { - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>rimraf>glob>minimatch>brace-expansion>balanced-match": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>rimraf>glob>minimatch>brace-expansion>concat-map": true + "gulp>glob-watcher>chokidar>braces>fill-range>is-number>kind-of": true } }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>rimraf>glob>once": { + "gulp>glob-watcher>chokidar>braces>fill-range>is-number>kind-of": { "packages": { - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>rimraf>glob>once>wrappy": true - } - }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>rimraf>glob>path-is-absolute": { - "globals": { - "process.platform": true - } - }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>semver": { - "globals": { - "console": true, - "process": true + "browserify>insert-module-globals>is-buffer": true } }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>tar>safe-buffer": { - "builtin": { - "buffer": true + "gulp>glob-watcher>chokidar>braces>fill-range>to-regex-range": { + "packages": { + "gulp>glob-watcher>chokidar>braces>fill-range>is-number": true, + "webpack>micromatch>braces>fill-range>repeat-string": true } }, "gulp>glob-watcher>chokidar>glob-parent": { @@ -6787,7 +6019,6 @@ "eslint>glob-parent": true, "eslint>is-glob": true, "sass>chokidar>braces": true, - "sass>chokidar>fsevents": true, "sass>chokidar>is-binary-path": true, "watchify>anymatch": true } @@ -6810,12 +6041,6 @@ "sass>chokidar>braces>fill-range>to-regex-range>is-number": true } }, - "sass>chokidar>fsevents": { - "globals": { - "process.platform": true - }, - "native": true - }, "sass>chokidar>is-binary-path": { "builtin": { "path.extname": true diff --git a/package.json b/package.json index e1466c871..6b0f134d0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "metamask-crx", - "version": "10.14.0", + "version": "10.14.7", "private": true, "repository": { "type": "git", @@ -251,6 +251,7 @@ "@metamask/eslint-config-nodejs": "^9.0.0", "@metamask/eslint-config-typescript": "^9.0.1", "@metamask/forwarder": "^1.1.0", + "@metamask/phishing-warning": "^1.1.0", "@metamask/test-dapp": "^5.0.0", "@sentry/cli": "^1.58.0", "@storybook/addon-a11y": "^6.3.12", diff --git a/test/e2e/helpers.js b/test/e2e/helpers.js index 8e13c4c6c..cd05e38e0 100644 --- a/test/e2e/helpers.js +++ b/test/e2e/helpers.js @@ -6,6 +6,7 @@ const enLocaleMessages = require('../../app/_locales/en/messages.json'); const { setupMocking } = require('./mock-e2e'); const Ganache = require('./ganache'); const FixtureServer = require('./fixture-server'); +const PhishingWarningPageServer = require('./phishing-warning-page-server'); const { buildWebDriver } = require('./webdriver'); const { ensureXServerIsRunning } = require('./x-server'); @@ -27,6 +28,7 @@ async function withFixtures(options, testSuite) { title, failOnConsoleError = true, dappPath = undefined, + dappPaths, testSpecificMock = function () { // do nothing. }, @@ -38,6 +40,7 @@ async function withFixtures(options, testSuite) { let secondaryGanacheServer; let numberOfDapps = dapp ? 1 : 0; const dappServer = []; + const phishingPageServer = new PhishingWarningPageServer(); let webDriver; let failed = false; @@ -55,14 +58,15 @@ async function withFixtures(options, testSuite) { } await fixtureServer.start(); await fixtureServer.loadState(path.join(__dirname, 'fixtures', fixtures)); + await phishingPageServer.start(); if (dapp) { if (dappOptions?.numberOfDapps) { numberOfDapps = dappOptions.numberOfDapps; } for (let i = 0; i < numberOfDapps; i++) { let dappDirectory; - if (dappPath) { - dappDirectory = path.resolve(__dirname, dappPath); + if (dappPath || (dappPaths && dappPaths[i])) { + dappDirectory = path.resolve(__dirname, dappPath || dappPaths[i]); } else { dappDirectory = path.resolve( __dirname, @@ -146,6 +150,9 @@ async function withFixtures(options, testSuite) { } } } + if (phishingPageServer.isRunning()) { + await phishingPageServer.quit(); + } await mockServer.stop(); } } diff --git a/test/e2e/mock-page-with-disallowed-iframe/index.html b/test/e2e/mock-page-with-disallowed-iframe/index.html new file mode 100644 index 000000000..ffadeeefa --- /dev/null +++ b/test/e2e/mock-page-with-disallowed-iframe/index.html @@ -0,0 +1,20 @@ + + + + Mock E2E Phishing Page + + + +
Hello
+