From 3ebba0d4118770a06760e2578eeb5c7a8b711392 Mon Sep 17 00:00:00 2001 From: Brad Decker Date: Thu, 19 Nov 2020 15:44:42 -0600 Subject: [PATCH 01/32] validate addresses in qr codes (#9916) --- ui/app/pages/send/send.component.js | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/ui/app/pages/send/send.component.js b/ui/app/pages/send/send.component.js index 727c213af..4171f0611 100644 --- a/ui/app/pages/send/send.component.js +++ b/ui/app/pages/send/send.component.js @@ -1,5 +1,6 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' +import ethUtil from 'ethereumjs-util' import { debounce } from 'lodash' import { getAmountErrorObject, @@ -16,6 +17,7 @@ import AddRecipient from './send-content/add-recipient' import SendContent from './send-content' import SendFooter from './send-footer' import EnsInput from './send-content/add-recipient/ens-input' +import { INVALID_RECIPIENT_ADDRESS_ERROR } from './send.constants' export default class SendTransactionScreen extends Component { static propTypes = { @@ -162,12 +164,18 @@ export default class SendTransactionScreen extends Component { if (qrCodeData) { if (qrCodeData.type === 'address') { scannedAddress = qrCodeData.values.address.toLowerCase() - const currentAddress = prevTo?.toLowerCase() - if (currentAddress !== scannedAddress) { - updateSendTo(scannedAddress) - updateGas = true - // Clean up QR code data after handling + if (ethUtil.isValidAddress(scannedAddress)) { + const currentAddress = prevTo?.toLowerCase() + if (currentAddress !== scannedAddress) { + updateSendTo(scannedAddress) + updateGas = true + // Clean up QR code data after handling + qrCodeDetected(null) + } + } else { + scannedAddress = null qrCodeDetected(null) + this.setState({ toError: INVALID_RECIPIENT_ADDRESS_ERROR }) } } } From 63f759e14ee2590a34c76f3f1f9a85986beafc6a Mon Sep 17 00:00:00 2001 From: Etienne Dusseault Date: Fri, 20 Nov 2020 23:26:40 +0800 Subject: [PATCH 02/32] build - catch build pipeline errors properly (#9840) --- .circleci/config.yml | 6 ++-- development/build/scripts.js | 65 ++++++++++++++++++------------------ 2 files changed, 37 insertions(+), 34 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index f018b76bd..7c43e17b6 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -122,8 +122,9 @@ jobs: prep-build: docker: - image: circleci/node@sha256:e16740707de2ebed45c05d507f33ef204902349c7356d720610b5ec6a35d3d88 + resource_class: medium+ environment: - NODE_OPTIONS: --max_old_space_size=1024 + NODE_OPTIONS: --max_old_space_size=2048 steps: - checkout - attach_workspace: @@ -143,8 +144,9 @@ jobs: prep-build-test: docker: - image: circleci/node@sha256:e16740707de2ebed45c05d507f33ef204902349c7356d720610b5ec6a35d3d88 + resource_class: medium+ environment: - NODE_OPTIONS: --max_old_space_size=1024 + NODE_OPTIONS: --max_old_space_size=2048 steps: - checkout - attach_workspace: diff --git a/development/build/scripts.js b/development/build/scripts.js index cf19060c6..de4a59e48 100644 --- a/development/build/scripts.js +++ b/development/build/scripts.js @@ -1,6 +1,8 @@ const fs = require('fs') const gulp = require('gulp') const watch = require('gulp-watch') +const pify = require('pify') +const pump = pify(require('pump')) const source = require('vinyl-source-stream') const buffer = require('vinyl-buffer') const log = require('fancy-log') @@ -11,8 +13,6 @@ const envify = require('envify/custom') const sourcemaps = require('gulp-sourcemaps') const sesify = require('sesify') const terser = require('gulp-terser-js') -const pify = require('pify') -const endOfStream = pify(require('end-of-stream')) const { makeStringTransform } = require('browserify-transform-tools') const conf = require('rc')('metamask', { @@ -200,33 +200,19 @@ function createScriptTasks({ browserPlatforms, livereload }) { bundler.on('log', log) } - let buildStream = bundler.bundle() - - // handle errors - buildStream.on('error', (err) => { - beep() - if (opts.devMode) { - console.warn(err.stack) - } else { - throw err - } - }) - - // process bundles - buildStream = buildStream + const buildPipeline = [ + bundler.bundle(), // convert bundle stream to gulp vinyl stream - .pipe(source(opts.filename)) - // buffer file contents (?) - .pipe(buffer()) - - // Initialize Source Maps - buildStream = buildStream + source(opts.filename), + // Initialize Source Maps + buffer(), // loads map from browserify file - .pipe(sourcemaps.init({ loadMaps: true })) + sourcemaps.init({ loadMaps: true }), + ] // Minification if (!opts.devMode) { - buildStream = buildStream.pipe( + buildPipeline.push( terser({ mangle: { reserved: ['MetamaskInpageProvider'], @@ -242,18 +228,28 @@ function createScriptTasks({ browserPlatforms, livereload }) { if (opts.devMode) { // Use inline source maps for development due to Chrome DevTools bug // https://bugs.chromium.org/p/chromium/issues/detail?id=931675 - buildStream = buildStream.pipe(sourcemaps.write()) + // note: sourcemaps call arity is important + buildPipeline.push(sourcemaps.write()) } else { - buildStream = buildStream.pipe(sourcemaps.write('../sourcemaps')) + buildPipeline.push(sourcemaps.write('../sourcemaps')) } // write completed bundles browserPlatforms.forEach((platform) => { const dest = `./dist/${platform}` - buildStream = buildStream.pipe(gulp.dest(dest)) + buildPipeline.push(gulp.dest(dest)) }) - await endOfStream(buildStream) + // process bundles + if (opts.devMode) { + try { + await pump(buildPipeline) + } catch (err) { + gracefulError(err) + } + } else { + await pump(buildPipeline) + } } } @@ -406,10 +402,6 @@ function createScriptTasks({ browserPlatforms, livereload }) { } } -function beep() { - process.stdout.write('\x07') -} - function getEnvironment({ devMode, test }) { // get environment slug if (devMode) { @@ -429,3 +421,12 @@ function getEnvironment({ devMode, test }) { } return 'other' } + +function beep() { + process.stdout.write('\x07') +} + +function gracefulError(err) { + console.warn(err) + beep() +} From 0315c6c20dae4e47d98ad73278955c9c31c0a29c Mon Sep 17 00:00:00 2001 From: David Walsh Date: Fri, 20 Nov 2020 10:57:45 -0600 Subject: [PATCH 03/32] Add alt text for images in list items (#9847) --- .../app/asset-list-item/asset-list-item.js | 1 + .../blockieIdenticon.component.js | 5 +++-- .../ui/identicon/identicon.component.js | 21 ++++++++++--------- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/ui/app/components/app/asset-list-item/asset-list-item.js b/ui/app/components/app/asset-list-item/asset-list-item.js index 274f0576b..b5164e39c 100644 --- a/ui/app/components/app/asset-list-item/asset-list-item.js +++ b/ui/app/components/app/asset-list-item/asset-list-item.js @@ -113,6 +113,7 @@ const AssetListItem = ({ diameter={32} address={tokenAddress} image={tokenImage} + alt={`${primary} ${tokenSymbol}`} /> } midContent={midContent} diff --git a/ui/app/components/ui/identicon/blockieIdenticon/blockieIdenticon.component.js b/ui/app/components/ui/identicon/blockieIdenticon/blockieIdenticon.component.js index 390ef02a3..05d201e22 100644 --- a/ui/app/components/ui/identicon/blockieIdenticon/blockieIdenticon.component.js +++ b/ui/app/components/ui/identicon/blockieIdenticon/blockieIdenticon.component.js @@ -2,7 +2,7 @@ import React, { useEffect, useRef, useState } from 'react' import PropTypes from 'prop-types' import { renderIcon } from '@download/blockies' -const BlockieIdenticon = ({ address, diameter }) => { +const BlockieIdenticon = ({ address, diameter, alt }) => { const [dataUrl, setDataUrl] = useState(null) const canvasRef = useRef(null) @@ -19,7 +19,7 @@ const BlockieIdenticon = ({ address, diameter }) => { return ( <> - + {alt ) } @@ -27,6 +27,7 @@ const BlockieIdenticon = ({ address, diameter }) => { BlockieIdenticon.propTypes = { address: PropTypes.string.isRequired, diameter: PropTypes.number.isRequired, + alt: PropTypes.string, } export default BlockieIdenticon diff --git a/ui/app/components/ui/identicon/identicon.component.js b/ui/app/components/ui/identicon/identicon.component.js index 840108f60..79d7cf1b5 100644 --- a/ui/app/components/ui/identicon/identicon.component.js +++ b/ui/app/components/ui/identicon/identicon.component.js @@ -21,6 +21,7 @@ export default class Identicon extends PureComponent { diameter: PropTypes.number, image: PropTypes.string, useBlockie: PropTypes.bool, + alt: PropTypes.string, } static defaultProps = { @@ -30,23 +31,24 @@ export default class Identicon extends PureComponent { diameter: 46, image: undefined, useBlockie: false, + alt: '', } renderImage() { - const { className, diameter, image } = this.props + const { className, diameter, image, alt } = this.props return ( ) } renderJazzicon() { - const { address, className, diameter } = this.props + const { address, className, diameter, alt } = this.props return ( ) } renderBlockie() { - const { address, className, diameter } = this.props + const { address, className, diameter, alt } = this.props return (
- +
) } @@ -79,6 +82,7 @@ export default class Identicon extends PureComponent { diameter, useBlockie, addBorder, + alt, } = this.props if (image) { @@ -88,10 +92,7 @@ export default class Identicon extends PureComponent { if (address) { const checksummedAddress = checksumAddress(address) - if ( - contractMap[checksummedAddress] && - contractMap[checksummedAddress].logo - ) { + if (contractMap[checksummedAddress]?.logo) { return this.renderJazzicon() } @@ -109,7 +110,7 @@ export default class Identicon extends PureComponent { className={classnames('identicon__eth-logo', className)} src="./images/eth_logo.svg" style={getStyles(diameter)} - alt="" + alt={alt} /> ) } From f8f3faf539453b87412ab3115fe7477eed023d89 Mon Sep 17 00:00:00 2001 From: Erik Marks <25517051+rekmarks@users.noreply.github.com> Date: Fri, 20 Nov 2020 13:52:07 -0800 Subject: [PATCH 04/32] resolve-url-loader@3.1.2 (#9925) --- package.json | 2 +- yarn.lock | 200 ++++++++++++++++----------------------------------- 2 files changed, 63 insertions(+), 139 deletions(-) diff --git a/package.json b/package.json index 3e73f2d8c..5c907e787 100644 --- a/package.json +++ b/package.json @@ -270,7 +270,7 @@ "regenerator-runtime": "^0.13.3", "remote-redux-devtools": "^0.5.16", "remotedev-server": "^0.3.1", - "resolve-url-loader": "^2.3.0", + "resolve-url-loader": "^3.1.2", "sass-loader": "^7.0.1", "selenium-webdriver": "^4.0.0-alpha.5", "serve-handler": "^6.1.2", diff --git a/yarn.lock b/yarn.lock index 1348d21e4..f688fa586 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3329,18 +3329,13 @@ address@1.0.3, address@^1.0.1: resolved "https://registry.yarnpkg.com/address/-/address-1.0.3.tgz#b5f50631f8d6cec8bd20c963963afb55e06cbce9" integrity sha512-z55ocwKBRLryBs394Sm3ushTtBeg6VAeuku7utSoSnsJKvKcnXFIyC6vh27n3rXyxSgkJBBCAvyOn7gSUcTYjg== -adjust-sourcemap-loader@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/adjust-sourcemap-loader/-/adjust-sourcemap-loader-1.2.0.tgz#e33fde95e50db9f2a802e3647e311d2fc5000c69" - integrity sha512-958oaHHVEXMvsY7v7cC5gEkNIcoaAVIhZ4mBReYVZJOTP9IgKmzLjIOhTtzpLMu+qriXvLsVjJ155EeInp45IQ== +adjust-sourcemap-loader@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/adjust-sourcemap-loader/-/adjust-sourcemap-loader-3.0.0.tgz#5ae12fb5b7b1c585e80bbb5a63ec163a1a45e61e" + integrity sha512-YBrGyT2/uVQ/c6Rr+t6ZJXniY03YtHGMJQYal368burRGYKqhx9qGTWqcBU5s1CwYY9E/ri63RYyG1IacMZtqw== dependencies: - assert "^1.3.0" - camelcase "^1.2.1" - loader-utils "^1.1.0" - lodash.assign "^4.0.1" - lodash.defaults "^3.1.2" - object-path "^0.9.2" - regex-parser "^2.2.9" + loader-utils "^2.0.0" + regex-parser "^2.2.11" adm-zip@0.4.11: version "0.4.11" @@ -3812,6 +3807,11 @@ aria-query@^4.2.2: "@babel/runtime" "^7.10.2" "@babel/runtime-corejs3" "^7.10.2" +arity-n@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/arity-n/-/arity-n-1.0.4.tgz#d9e76b11733e08569c0847ae7b39b2860b30b745" + integrity sha1-2edrEXM+CFacCEeuezmyhgswt0U= + arr-diff@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-1.1.0.tgz#687c32758163588fef7de7b36fabe495eb1a399a" @@ -4082,7 +4082,7 @@ assert-plus@1.0.0, assert-plus@^1.0.0: resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= -assert@^1.1.1, assert@^1.3.0, assert@^1.4.0, assert@^1.4.1: +assert@^1.1.1, assert@^1.4.0, assert@^1.4.1: version "1.5.0" resolved "https://registry.yarnpkg.com/assert/-/assert-1.5.0.tgz#55c109aaf6e0aefdb3dc4b71240c70bf574b18eb" integrity sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA== @@ -6274,10 +6274,10 @@ camelcase@5.0.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.0.0.tgz#03295527d58bd3cd4aa75363f35b2e8d97be2f42" integrity sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA== -camelcase@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39" - integrity sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk= +camelcase@5.3.1, camelcase@^5.0.0, camelcase@^5.2.0, camelcase@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== camelcase@^2.0.0: version "2.1.1" @@ -6289,16 +6289,11 @@ camelcase@^3.0.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" integrity sha1-MvxLn82vhF/N9+c7uXysImHwqwo= -camelcase@^4.0.0, camelcase@^4.1.0: +camelcase@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0= -camelcase@^5.0.0, camelcase@^5.2.0, camelcase@^5.3.1: - version "5.3.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" - integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== - camelcase@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.0.0.tgz#5259f7c30e35e278f1bdc2a4d91230b37cad981e" @@ -7003,6 +6998,13 @@ component-type@^1.2.1: resolved "https://registry.yarnpkg.com/component-type/-/component-type-1.2.1.tgz#8a47901700238e4fc32269771230226f24b415a9" integrity sha1-ikeQFwAjjk/DIml3EjAibyS0Fak= +compose-function@3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/compose-function/-/compose-function-3.0.3.tgz#9ed675f13cc54501d30950a486ff6a7ba3ab185f" + integrity sha1-ntZ18TzFRQHTCVCkhv9qe6OrGF8= + dependencies: + arity-n "^1.0.4" + concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" @@ -7135,7 +7137,7 @@ continuable-cache@^0.3.1: resolved "https://registry.yarnpkg.com/continuable-cache/-/continuable-cache-0.3.1.tgz#bd727a7faed77e71ff3985ac93351a912733ad0f" integrity sha1-vXJ6f67XfnH/OYWskzUakSczrQ8= -convert-source-map@1.X, convert-source-map@^1.5.0, convert-source-map@^1.5.1, convert-source-map@^1.7.0: +convert-source-map@1.7.0, convert-source-map@1.X, convert-source-map@^1.5.0, convert-source-map@^1.5.1, convert-source-map@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA== @@ -9197,7 +9199,7 @@ es6-error@^4.0.1, es6-error@^4.1.1: resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d" integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg== -es6-iterator@^2.0.1, es6-iterator@~2.0.1, es6-iterator@~2.0.3: +es6-iterator@2.0.3, es6-iterator@^2.0.1, es6-iterator@~2.0.1, es6-iterator@~2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c= @@ -16669,53 +16671,7 @@ lockfile-lint@^4.0.0: lockfile-lint-api "^5.0.12" yargs "^15.0.2" -lodash._baseassign@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz#8c38a099500f215ad09e59f1722fd0c52bfe0a4e" - integrity sha1-jDigmVAPIVrQnlnxci/QxSv+Ck4= - dependencies: - lodash._basecopy "^3.0.0" - lodash.keys "^3.0.0" - -lodash._basecopy@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz#8da0e6a876cf344c0ad8a54882111dd3c5c7ca36" - integrity sha1-jaDmqHbPNEwK2KVIghEd08XHyjY= - -lodash._bindcallback@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz#e531c27644cf8b57a99e17ed95b35c748789392e" - integrity sha1-5THCdkTPi1epnhftlbNcdIeJOS4= - -lodash._createassigner@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/lodash._createassigner/-/lodash._createassigner-3.1.1.tgz#838a5bae2fdaca63ac22dee8e19fa4e6d6970b11" - integrity sha1-g4pbri/aymOsIt7o4Z+k5taXCxE= - dependencies: - lodash._bindcallback "^3.0.0" - lodash._isiterateecall "^3.0.0" - lodash.restparam "^3.0.0" - -lodash._getnative@^3.0.0: - version "3.9.1" - resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" - integrity sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U= - -lodash._isiterateecall@^3.0.0: - version "3.0.9" - resolved "https://registry.yarnpkg.com/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz#5203ad7ba425fae842460e696db9cf3e6aac057c" - integrity sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw= - -lodash.assign@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-3.2.0.tgz#3ce9f0234b4b2223e296b8fa0ac1fee8ebca64fa" - integrity sha1-POnwI0tLIiPilrj6CsH+6OvKZPo= - dependencies: - lodash._baseassign "^3.0.0" - lodash._createassigner "^3.0.0" - lodash.keys "^3.0.0" - -lodash.assign@^4.0.1, lodash.assign@^4.2.0: +lodash.assign@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7" integrity sha1-DZnzzNem0mHRm9rrkkUAXShYCOc= @@ -16730,19 +16686,6 @@ lodash.debounce@^4.0.8: resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= -lodash.defaults@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-3.1.2.tgz#c7308b18dbf8bc9372d701a73493c61192bd2e2c" - integrity sha1-xzCLGNv4vJNy1wGnNJPGEZK9Liw= - dependencies: - lodash.assign "^3.0.0" - lodash.restparam "^3.0.0" - -lodash.defaults@^4.0.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c" - integrity sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw= - lodash.escape@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/lodash.escape/-/lodash.escape-4.0.1.tgz#c9044690c21e04294beaa517712fded1fa88de98" @@ -16773,16 +16716,6 @@ lodash.includes@^4.3.0: resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f" integrity sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8= -lodash.isarguments@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" - integrity sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo= - -lodash.isarray@^3.0.0: - version "3.0.4" - resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55" - integrity sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U= - lodash.isboolean@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6" @@ -16823,15 +16756,6 @@ lodash.isstring@^4.0.1: resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" integrity sha1-1SfftUVuynzJu5XV2ur4i6VKVFE= -lodash.keys@^3.0.0: - version "3.1.2" - resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a" - integrity sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo= - dependencies: - lodash._getnative "^3.0.0" - lodash.isarguments "^3.0.0" - lodash.isarray "^3.0.0" - lodash.map@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/lodash.map/-/lodash.map-4.6.0.tgz#771ec7839e3473d9c4cde28b19394c3562f4f6d3" @@ -16852,11 +16776,6 @@ lodash.once@^4.0.0: resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" integrity sha1-DdOXEhPHxW34gJd9UEyI+0cal6w= -lodash.restparam@^3.0.0: - version "3.6.1" - resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805" - integrity sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU= - lodash.some@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/lodash.some/-/lodash.some-4.6.0.tgz#1bb9f314ef6b8baded13b549169b2a945eb68e4d" @@ -18679,11 +18598,6 @@ object-keys@~0.4.0: resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-0.4.0.tgz#28a6aae7428dd2c3a92f3d95f21335dd204e0336" integrity sha1-KKaq50KN0sOpLz2V8hM13SBOAzY= -object-path@^0.9.2: - version "0.9.2" - resolved "https://registry.yarnpkg.com/object-path/-/object-path-0.9.2.tgz#0fd9a74fc5fad1ae3968b586bda5c632bd6c05a5" - integrity sha1-D9mnT8X60a45aLWGvaXGMr1sBaU= - object-visit@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" @@ -20212,6 +20126,15 @@ postcss@7.0.18: source-map "^0.6.1" supports-color "^6.1.0" +postcss@7.0.21: + version "7.0.21" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.21.tgz#06bb07824c19c2021c5d056d5b10c35b989f7e17" + integrity sha512-uIFtJElxJo29QC753JzhidoAhvp/e/Exezkdhfmt8AymWT6/5B7W1WmponYWkHk2eg6sONyTch0A3nkMPun3SQ== + dependencies: + chalk "^2.4.2" + source-map "^0.6.1" + supports-color "^6.1.0" + postcss@^6.0.1, postcss@^6.0.19, postcss@^6.0.23: version "6.0.23" resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.23.tgz#61c82cc328ac60e677645f979054eb98bc0e3324" @@ -21802,10 +21725,10 @@ regex-not@^1.0.0, regex-not@^1.0.2: extend-shallow "^3.0.2" safe-regex "^1.1.0" -regex-parser@^2.2.9: - version "2.2.9" - resolved "https://registry.yarnpkg.com/regex-parser/-/regex-parser-2.2.9.tgz#a372f45a248b62976a568037c1b6e60a60599192" - integrity sha512-VncXxOF6uFlYog5prG2j+e2UGJeam5MfNiJnB/qEgo4KTnMm2XrELCg4rNZ6IlaEUZnGlb8aB6lXowCRQtTkkA== +regex-parser@^2.2.11: + version "2.2.11" + resolved "https://registry.yarnpkg.com/regex-parser/-/regex-parser-2.2.11.tgz#3b37ec9049e19479806e878cabe7c1ca83ccfe58" + integrity sha512-jbD/FT0+9MBU2XAZluI7w2OBs1RBi6p9M83nkoZayQXXU9e8Robt69FcZc7wU4eJD/YFTjn1JdCk3rbMJajz8Q== regexp-tree@^0.1.6: version "0.1.10" @@ -22253,20 +22176,21 @@ resolve-pathname@^3.0.0: resolved "https://registry.yarnpkg.com/resolve-pathname/-/resolve-pathname-3.0.0.tgz#99d02224d3cf263689becbb393bc560313025dcd" integrity sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng== -resolve-url-loader@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/resolve-url-loader/-/resolve-url-loader-2.3.0.tgz#e1b37034d48f22f8cfb9f04c026faaa070fdaf26" - integrity sha512-RaEUWgF/B6aTg9VKaOv2o6dfm5f75/lGh8S+SQwoMcBm48WkA2nhLR+V7KEawkxXjU4lLB16IVeHCe7F69nyVw== - dependencies: - adjust-sourcemap-loader "^1.1.0" - camelcase "^4.1.0" - convert-source-map "^1.5.1" - loader-utils "^1.1.0" - lodash.defaults "^4.0.0" - rework "^1.0.1" - rework-visit "^1.0.0" - source-map "^0.5.7" - urix "^0.1.0" +resolve-url-loader@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/resolve-url-loader/-/resolve-url-loader-3.1.2.tgz#235e2c28e22e3e432ba7a5d4e305c59a58edfc08" + integrity sha512-QEb4A76c8Mi7I3xNKXlRKQSlLBwjUV/ULFMP+G7n3/7tJZ8MG5wsZ3ucxP1Jz8Vevn6fnJsxDx9cIls+utGzPQ== + dependencies: + adjust-sourcemap-loader "3.0.0" + camelcase "5.3.1" + compose-function "3.0.3" + convert-source-map "1.7.0" + es6-iterator "2.0.3" + loader-utils "1.2.3" + postcss "7.0.21" + rework "1.0.1" + rework-visit "1.0.0" + source-map "0.6.1" resolve-url@^0.2.1: version "0.2.1" @@ -22351,12 +22275,12 @@ reusify@^1.0.0: resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== -rework-visit@^1.0.0: +rework-visit@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/rework-visit/-/rework-visit-1.0.0.tgz#9945b2803f219e2f7aca00adb8bc9f640f842c9a" integrity sha1-mUWygD8hni96ygCtuLyfZA+ELJo= -rework@^1.0.1: +rework@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/rework/-/rework-1.0.1.tgz#30806a841342b54510aa4110850cd48534144aa7" integrity sha1-MIBqhBNCtUUQqkEQhQzUhTQUSqc= @@ -23512,6 +23436,11 @@ source-map-url@^0.4.0: resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= +source-map@0.6.1, source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + source-map@0.X, source-map@^0.7.2, source-map@^0.7.3: version "0.7.3" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" @@ -23536,11 +23465,6 @@ source-map@^0.5.0, source-map@^0.5.1, source-map@^0.5.3, source-map@^0.5.6, sour resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= -source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - sourcemap-codec@^1.4.1: version "1.4.8" resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4" From b3fa1e534e9ca2f10043a58794ae8dd39ec72c5f Mon Sep 17 00:00:00 2001 From: Brad Decker Date: Sat, 21 Nov 2020 09:38:43 -0600 Subject: [PATCH 05/32] add version to page events (#9926) --- ui/app/contexts/metametrics.new.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/ui/app/contexts/metametrics.new.js b/ui/app/contexts/metametrics.new.js index f8596b796..75249444f 100644 --- a/ui/app/contexts/metametrics.new.js +++ b/ui/app/contexts/metametrics.new.js @@ -83,6 +83,12 @@ export function MetaMetricsProvider({ children }) { const context = useSegmentContext() const network = useSelector(getMetricsNetworkIdentifier) const chainId = useSelector(getCurrentChainId) + // Temporary until the background controller refactor merges: + const baseVersion = global.platform.getVersion() + const version = + process.env.METAMASK_ENVIRONMENT === 'production' + ? baseVersion + : `${baseVersion}-${process.env.METAMASK_ENVIRONMENT}` /** * track a metametrics event @@ -171,13 +177,17 @@ export function MetaMetricsProvider({ children }) { network, environment_type: environmentType, }, - context, + context: { + ...context, + version, + }, }) } previousMatch.current = match?.path } }, [ location, + version, locale, context, network, From 9f6fa64d675b8330a7f7cee8c51791bce4f90ec9 Mon Sep 17 00:00:00 2001 From: Etienne Dusseault Date: Tue, 24 Nov 2020 11:26:43 +0800 Subject: [PATCH 06/32] Add SES lockdown to extension webapp (#9729) * Freezeglobals: remove Promise freezing, add lockdown * background & UI: temp disable sentry * add loose-envify, dedupe symbol-observable * use loose envify * add symbol-observable patch * run freezeGlobals after sentry init * use require instead of import * add lockdown to contentscript * add error code in message * try increasing node env heap size to 2048 * change back circe CI option * make freezeGlobals an exported function * make freezeGlobals an exported function * use freezeIntrinsics * pass down env to child process * fix unknown module * fix tests * change back to 2048 * fix import error * attempt to fix memory error * fix lint * fix lint * fix mem gain * use lockdown in phishing detect * fix lint * move sentry init into freezeIntrinsics to run lockdown before other imports * lint fix * custom lockdown modules per context * lint fix * fix global test * remove run in child process * remove lavamoat-core, use ses, require lockdown directly * revert childprocess * patch package postinstall * revert back child process * add postinstall to ci * revert node max space size to 1024 * put back loose-envify * Disable sentry to see if e2e tetss pass * use runLockdown, add as script in manifest * remove global and require from runlockdown * add more memory to tests * upgrade resource class for prep-build & prep-build-test * fix lint * lint fix * upgrade remote-redux-devtools * skillfully re-add sentry * lintfix * fix lint * put back beep * remove envify, add loose-envify and patch-package in dev deps * Replace patch with Yarn resolution (#9923) Instead of patching `symbol-observable`, this ensures that all versions of `symbol-observable` are resolved to the given range, even if it contradicts the requested range. Co-authored-by: Mark Stacey --- app/manifest/_base.json | 10 +- app/phishing.html | 2 + app/popup.html | 3 + app/scripts/background.js | 8 +- app/scripts/initSentry.js | 7 ++ app/scripts/lib/freezeGlobals.js | 37 ------- app/scripts/runLockdown.js | 7 ++ app/scripts/ui.js | 14 +-- development/build/index.js | 5 - development/build/scripts.js | 12 ++- development/build/static.js | 10 ++ development/build/task.js | 6 +- package.json | 7 +- test/unit-global/frozenPromise.js | 8 +- test/unit-global/globalPatch.js | 2 + yarn.lock | 167 ++++++++++++++++-------------- 16 files changed, 158 insertions(+), 147 deletions(-) create mode 100644 app/scripts/initSentry.js delete mode 100644 app/scripts/lib/freezeGlobals.js create mode 100644 app/scripts/runLockdown.js create mode 100644 test/unit-global/globalPatch.js diff --git a/app/manifest/_base.json b/app/manifest/_base.json index c16bc2fbf..9c703a884 100644 --- a/app/manifest/_base.json +++ b/app/manifest/_base.json @@ -1,7 +1,13 @@ { "author": "https://metamask.io", "background": { - "scripts": ["bg-libs.js", "background.js"], + "scripts": [ + "initSentry.js", + "lockdown.cjs", + "runLockdown.js", + "bg-libs.js", + "background.js" + ], "persistent": true }, "browser_action": { @@ -30,7 +36,7 @@ "content_scripts": [ { "matches": ["file://*/*", "http://*/*", "https://*/*"], - "js": ["contentscript.js"], + "js": ["lockdown.cjs", "runLockdown.js", "contentscript.js"], "run_at": "document_start", "all_frames": true }, diff --git a/app/phishing.html b/app/phishing.html index 583a50140..1c913db2e 100644 --- a/app/phishing.html +++ b/app/phishing.html @@ -2,6 +2,8 @@ Ethereum Phishing Detection - MetaMask + + diff --git a/app/popup.html b/app/popup.html index 0c3d70407..4d29f6153 100644 --- a/app/popup.html +++ b/app/popup.html @@ -10,6 +10,9 @@
+ + + diff --git a/app/scripts/background.js b/app/scripts/background.js index c57710bd2..fa1e48a10 100644 --- a/app/scripts/background.js +++ b/app/scripts/background.js @@ -3,7 +3,6 @@ */ // these need to run before anything else /* eslint-disable import/first,import/order */ -import './lib/freezeGlobals' import setupFetchDebugging from './lib/setupFetchDebugging' /* eslint-enable import/order */ @@ -29,7 +28,6 @@ import createStreamSink from './lib/createStreamSink' import NotificationManager from './lib/notification-manager' import MetamaskController from './metamask-controller' import rawFirstTimeState from './first-time-state' -import setupSentry from './lib/setupSentry' import getFirstPreferredLangCode from './lib/get-first-preferred-lang-code' import getObjStructure from './lib/getObjStructure' import setupEnsIpfsResolver from './lib/ens-ipfs/setup' @@ -41,18 +39,16 @@ import { } from './lib/enums' /* eslint-enable import/first */ +const { sentry } = global const firstTimeState = { ...rawFirstTimeState } log.setDefaultLevel(process.env.METAMASK_DEBUG ? 'debug' : 'warn') const platform = new ExtensionPlatform() + const notificationManager = new NotificationManager() global.METAMASK_NOTIFIER = notificationManager -// setup sentry error reporting -const release = platform.getVersion() -const sentry = setupSentry({ release }) - let popupIsOpen = false let notificationIsOpen = false const openMetamaskTabsIDs = {} diff --git a/app/scripts/initSentry.js b/app/scripts/initSentry.js new file mode 100644 index 000000000..70ea7b936 --- /dev/null +++ b/app/scripts/initSentry.js @@ -0,0 +1,7 @@ +import setupSentry from './lib/setupSentry' + +// setup sentry error reporting +global.sentry = setupSentry({ + release: process.env.METAMASK_VERSION, + getState: () => global.getSentryState?.() || {}, +}) diff --git a/app/scripts/lib/freezeGlobals.js b/app/scripts/lib/freezeGlobals.js deleted file mode 100644 index 08b201bee..000000000 --- a/app/scripts/lib/freezeGlobals.js +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Freezes the Promise global and prevents its reassignment. - */ -import deepFreeze from 'deep-freeze-strict' - -if (process.env.IN_TEST !== 'true' && process.env.METAMASK_ENV !== 'test') { - freeze(global, 'Promise') -} - -/** - * Makes a key:value pair on a target object immutable, with limitations. - * The key cannot be reassigned or deleted, and the value is recursively frozen - * using Object.freeze. - * - * Because of JavaScript language limitations, this is does not mean that the - * value is completely immutable. It is, however, better than nothing. - * - * @param {Object} target - The target object to freeze a property on. - * @param {string} key - The key to freeze. - * @param {any} [value] - The value to freeze, if different from the existing value on the target. - * @param {boolean} [enumerable=true] - If given a value, whether the property is enumerable. - */ -function freeze(target, key, value, enumerable = true) { - const opts = { - configurable: false, - writable: false, - } - - if (value === undefined) { - target[key] = deepFreeze(target[key]) - } else { - opts.value = deepFreeze(value) - opts.enumerable = enumerable - } - - Object.defineProperty(target, key, opts) -} diff --git a/app/scripts/runLockdown.js b/app/scripts/runLockdown.js new file mode 100644 index 000000000..00bc7658f --- /dev/null +++ b/app/scripts/runLockdown.js @@ -0,0 +1,7 @@ +// Freezes all intrinsics +// eslint-disable-next-line no-undef,import/unambiguous +lockdown({ + errorTaming: 'unsafe', + mathTaming: 'unsafe', + dateTaming: 'unsafe', +}) diff --git a/app/scripts/ui.js b/app/scripts/ui.js index 5b5932a50..f1f4a7b78 100644 --- a/app/scripts/ui.js +++ b/app/scripts/ui.js @@ -1,13 +1,9 @@ -// this must run before anything else -import './lib/freezeGlobals' - // polyfills import 'abortcontroller-polyfill/dist/polyfill-patch-fetch' import '@formatjs/intl-relativetimeformat/polyfill' import { EventEmitter } from 'events' import PortStream from 'extension-port-stream' - import extension from 'extensionizer' import Dnode from 'dnode' @@ -16,9 +12,8 @@ import EthQuery from 'eth-query' import StreamProvider from 'web3-stream-provider' import log from 'loglevel' import launchMetaMaskUi from '../../ui' -import { setupMultiplex } from './lib/stream-utils' -import setupSentry from './lib/setupSentry' import ExtensionPlatform from './platforms/extension' +import { setupMultiplex } from './lib/stream-utils' import { ENVIRONMENT_TYPE_FULLSCREEN, ENVIRONMENT_TYPE_POPUP, @@ -31,13 +26,6 @@ async function start() { // create platform global global.platform = new ExtensionPlatform() - // setup sentry error reporting - const release = global.platform.getVersion() - setupSentry({ - release, - getState: () => window.getSentryState?.() || {}, - }) - // identify window type (popup, notification) const windowType = getEnvironmentType() diff --git a/development/build/index.js b/development/build/index.js index cc75d8398..facf87b61 100755 --- a/development/build/index.js +++ b/development/build/index.js @@ -3,11 +3,6 @@ // // run any task with "yarn build ${taskName}" // -global.globalThis = global // eslint-disable-line node/no-unsupported-features/es-builtins -require('lavamoat-core/lib/ses.umd.js') - -lockdown() // eslint-disable-line no-undef - const livereload = require('gulp-livereload') const { createTask, diff --git a/development/build/scripts.js b/development/build/scripts.js index de4a59e48..ab3e60b41 100644 --- a/development/build/scripts.js +++ b/development/build/scripts.js @@ -9,7 +9,7 @@ const log = require('fancy-log') const { assign } = require('lodash') const watchify = require('watchify') const browserify = require('browserify') -const envify = require('envify/custom') +const envify = require('loose-envify/custom') const sourcemaps = require('gulp-sourcemaps') const sesify = require('sesify') const terser = require('gulp-terser-js') @@ -22,6 +22,8 @@ const conf = require('rc')('metamask', { SEGMENT_LEGACY_WRITE_KEY: process.env.SEGMENT_LEGACY_WRITE_KEY, }) +const baseManifest = require('../../app/manifest/_base.json') + const packageJSON = require('../../package.json') const { createTask, @@ -97,7 +99,12 @@ function createScriptTasks({ browserPlatforms, livereload }) { } function createTasksForBuildJsExtension({ taskPrefix, devMode, testing }) { - const standardBundles = ['background', 'ui', 'phishing-detect'] + const standardBundles = [ + 'background', + 'ui', + 'phishing-detect', + 'initSentry', + ] const standardSubtasks = standardBundles.map((filename) => { return createTask( @@ -358,6 +365,7 @@ function createScriptTasks({ browserPlatforms, livereload }) { envify({ METAMASK_DEBUG: opts.devMode, METAMASK_ENVIRONMENT: environment, + METAMASK_VERSION: baseManifest.version, METAMETRICS_PROJECT_ID: process.env.METAMETRICS_PROJECT_ID, NODE_ENV: opts.devMode ? 'development' : 'production', IN_TEST: opts.testing ? 'true' : false, diff --git a/development/build/static.js b/development/build/static.js index 8a9263935..56f1afb32 100644 --- a/development/build/static.js +++ b/development/build/static.js @@ -44,6 +44,16 @@ const copyTargets = [ pattern: `*.html`, dest: ``, }, + { + src: `./node_modules/ses/dist/`, + pattern: `lockdown.cjs`, + dest: ``, + }, + { + src: `./app/scripts/`, + pattern: `runLockdown.js`, + dest: ``, + }, ] const languageTags = new Set() diff --git a/development/build/task.js b/development/build/task.js index 553a06956..1ed252413 100644 --- a/development/build/task.js +++ b/development/build/task.js @@ -68,7 +68,9 @@ function runInChildProcess(task) { ) } return instrumentForTaskStats(taskName, async () => { - const childProcess = spawn('yarn', ['build', taskName, '--skip-stats']) + const childProcess = spawn('yarn', ['build', taskName, '--skip-stats'], { + env: process.env, + }) // forward logs to main process // skip the first stdout event (announcing the process command) childProcess.stdout.once('data', () => { @@ -85,7 +87,7 @@ function runInChildProcess(task) { if (errCode !== 0) { reject( new Error( - `MetaMask build: runInChildProcess for task "${taskName}" encountered an error`, + `MetaMask build: runInChildProcess for task "${taskName}" encountered an error ${errCode}`, ), ) return diff --git a/package.json b/package.json index 5c907e787..ac19dca58 100644 --- a/package.json +++ b/package.json @@ -57,6 +57,9 @@ "**/knex/minimist": "^1.2.5", "**/optimist/minimist": "^1.2.5", "**/socketcluster/minimist": "^1.2.5", + "**/redux/symbol-observable": "^2.0.3", + "**/redux-devtools-instrument/symbol-observable": "^2.0.3", + "**/rxjs/symbol-observable": "^2.0.3", "3box/ipfs/ipld-zcash/zcash-bitcore-lib/lodash": "^4.17.19", "3box/ipfs/ipld-zcash/zcash-bitcore-lib/elliptic": "^6.5.3", "3box/**/libp2p-crypto/node-forge": "^0.10.0", @@ -214,7 +217,6 @@ "css-loader": "^2.1.1", "del": "^3.0.0", "deps-dump": "^1.1.0", - "envify": "^4.1.0", "enzyme": "^3.10.0", "enzyme-adapter-react-16": "^1.15.1", "eslint": "^7.7.0", @@ -250,8 +252,8 @@ "gulp-zip": "^4.0.0", "jsdom": "^11.2.0", "koa": "^2.7.0", - "lavamoat-core": "^6.1.0", "lockfile-lint": "^4.0.0", + "loose-envify": "^1.4.0", "mocha": "^7.2.0", "nock": "^9.0.14", "node-fetch": "^2.6.1", @@ -274,6 +276,7 @@ "sass-loader": "^7.0.1", "selenium-webdriver": "^4.0.0-alpha.5", "serve-handler": "^6.1.2", + "ses": "0.11.0", "sesify": "^4.2.1", "sesify-viz": "^3.0.10", "sinon": "^9.0.0", diff --git a/test/unit-global/frozenPromise.js b/test/unit-global/frozenPromise.js index 6583e1edf..1a1ca18b5 100644 --- a/test/unit-global/frozenPromise.js +++ b/test/unit-global/frozenPromise.js @@ -1,6 +1,8 @@ -import '../../app/scripts/lib/freezeGlobals' - -import assert from 'assert' +// Should occur before anything else +import './globalPatch' +import 'ses/dist/lockdown.cjs' +import '../../app/scripts/runLockdown' +import assert from 'assert' /* eslint-disable-line import/first,import/order */ describe('Promise global is immutable', function () { it('throws when reassinging promise (syntax 1)', function () { diff --git a/test/unit-global/globalPatch.js b/test/unit-global/globalPatch.js new file mode 100644 index 000000000..89d392454 --- /dev/null +++ b/test/unit-global/globalPatch.js @@ -0,0 +1,2 @@ +// eslint-disable-next-line import/unambiguous,node/no-unsupported-features/es-builtins +global.globalThis = global diff --git a/yarn.lock b/yarn.lock index f688fa586..f12ac1a5a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -47,6 +47,21 @@ did-resolver "0.0.6" ipfs-did-document "^1.2.3" +"@agoric/babel-standalone@^7.9.5": + version "7.9.5" + resolved "https://registry.yarnpkg.com/@agoric/babel-standalone/-/babel-standalone-7.9.5.tgz#1ca0c17844924199d31e49d6b67e8b2a629b8599" + integrity sha512-1Aa23oPuRi4kywUyZODo8zey9Gq2NpD2xUnNvgJLoT8orMQRlVOtvbG3JeHq5sjJERlF/q6csg4/P8t8/5IABA== + +"@agoric/make-hardener@^0.1.0": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@agoric/make-hardener/-/make-hardener-0.1.1.tgz#9b887da47aeec6637d9db4f0a92a4e740b8262bb" + integrity sha512-3emNc+yWJoFK5JMLoEFPs6rCzkntWQKxpR4gt3jaZYLKoUG4LrTmID3XNe8y40B6SJ3k/wLPodKa0ToQGlhrwQ== + +"@agoric/transform-module@^0.4.1": + version "0.4.1" + resolved "https://registry.yarnpkg.com/@agoric/transform-module/-/transform-module-0.4.1.tgz#9fb152364faf372e1bda535cb4ef89717724f57c" + integrity sha512-4TJJHXeXAWu1FCA7yXCAZmhBNoGTB/BEAe2pv+J2X8W/mJTr9b395OkDCSRMpzvmSshLfBx6wT0D7dqWIWEC1w== + "@babel/code-frame@7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0.tgz#06e2ab19bdb535385559aabb5ba59729482800f8" @@ -308,7 +323,7 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.10.1", "@babel/parser@^7.10.4", "@babel/parser@^7.12.1", "@babel/parser@^7.12.3", "@babel/parser@^7.7.5": +"@babel/parser@^7.10.4", "@babel/parser@^7.12.1", "@babel/parser@^7.12.3", "@babel/parser@^7.7.5": version "7.12.3" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.12.3.tgz#a305415ebe7a6c7023b40b5122a0662d928334cd" integrity sha512-kFsOS0IbsuhO5ojF8Hc8z/8vEIOkylVBrjiZUbLTE3XFe0Qi+uu6HjzQixkFaqr0ZPAMZcBVxEwmsnsLPZ2Xsw== @@ -872,7 +887,7 @@ "@babel/parser" "^7.10.4" "@babel/types" "^7.10.4" -"@babel/traverse@^7.1.0", "@babel/traverse@^7.10.1", "@babel/traverse@^7.12.1", "@babel/traverse@^7.4.4", "@babel/traverse@^7.7.4": +"@babel/traverse@^7.1.0", "@babel/traverse@^7.12.1", "@babel/traverse@^7.4.4", "@babel/traverse@^7.7.4": version "7.12.1" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.12.1.tgz#941395e0c5cc86d5d3e75caa095d3924526f0c1e" integrity sha512-MA3WPoRt1ZHo2ZmoGKNqi20YnPt0B1S0GTZEPhhd+hw2KGUzBlHuVunj6K4sNuK+reEvyiPwtp0cpaqLzJDmAw== @@ -4177,7 +4192,7 @@ async-iterator-to-stream@^1.1.0: dependencies: readable-stream "^3.0.5" -async-limiter@~1.0.0: +async-limiter@^1.0.0, async-limiter@~1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== @@ -5196,10 +5211,10 @@ base64-arraybuffer@0.1.5: resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz#73926771923b5a19747ad666aa5cd4bf9c6e9ce8" integrity sha1-c5JncZI7Whl0etZmqlzUv5xunOg= -base64-js@^1.0.2: - version "1.3.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" - integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g== +base64-js@^1.0.2, base64-js@^1.3.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== base64id@1.0.0: version "1.0.0" @@ -5983,7 +5998,7 @@ buffer@^4.3.0: ieee754 "^1.1.4" isarray "^1.0.0" -buffer@^5.0.5, buffer@^5.2.1: +buffer@^5.0.5: version "5.4.3" resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.4.3.tgz#3fbc9c69eb713d323e3fc1a895eee0710c072115" integrity sha512-zvj65TkFeIt3i6aj5bIvJDzjjQQGs4o/sNoezg1F1kYap9Nu2jcUdpwzRSJTHMMzG0H7bZkn4rNQpImhuxWX2A== @@ -5991,6 +6006,14 @@ buffer@^5.0.5, buffer@^5.2.1: base64-js "^1.0.2" ieee754 "^1.1.4" +buffer@^5.2.1: + version "5.7.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" + integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.1.13" + buffer@~5.2.1: version "5.2.1" resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.2.1.tgz#dd57fa0f109ac59c602479044dca7b8b3d0b71d6" @@ -7626,11 +7649,6 @@ cyclist@~0.2.2: resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-0.2.2.tgz#1b33792e11e914a2fd6d6ed6447464444e5fa640" integrity sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA= -cytoplasm@^3.3.1: - version "3.3.1" - resolved "https://registry.yarnpkg.com/cytoplasm/-/cytoplasm-3.3.1.tgz#6d10099e536b12c642e8375b47cbffac66656a4b" - integrity sha512-38swm2Lr7cmTh0KRYtiUOCT5PT2TPp31Lpp3wcAIm3iGT4KdGGewyTydkFhBEDrKik/umgmG2hVoG5A1fKQY+g== - d3-array@1, d3-array@^1.1.1, d3-array@^1.2.0: version "1.2.4" resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-1.2.4.tgz#635ce4d5eea759f6f605863dbcfc30edc737f71f" @@ -9027,14 +9045,6 @@ env-paths@^2.2.0: resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.0.tgz#cdca557dc009152917d6166e2febe1f039685e43" integrity sha512-6u0VYSCo/OW6IoD5WCLLy9JUGARbamfSavcNXry/eu8aHVFei6CD3Sw+VGX5alea1i9pgPHW0mbu6Xj0uBh7gA== -envify@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/envify/-/envify-4.1.0.tgz#f39ad3db9d6801b4e6b478b61028d3f0b6819f7e" - integrity sha512-IKRVVoAYr4pIx4yIWNsz9mOsboxlNXiu7TNBnem/K/uTHdkyzXWDzHCK7UTolqBbgaBz0tQHsD3YNls0uIIjiw== - dependencies: - esprima "^4.0.0" - through "~2.3.4" - enzyme-adapter-react-16@^1.15.1: version "1.15.1" resolved "https://registry.yarnpkg.com/enzyme-adapter-react-16/-/enzyme-adapter-react-16-1.15.1.tgz#8ad55332be7091dc53a25d7d38b3485fc2ba50d5" @@ -13245,7 +13255,12 @@ idna-uts46@^1.0.1: dependencies: punycode "^2.1.0" -ieee754@^1.1.4, ieee754@^1.1.8: +ieee754@^1.1.13, ieee754@^1.1.4: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + +ieee754@^1.1.8: version "1.1.13" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== @@ -15773,25 +15788,6 @@ latest-version@^5.0.0: dependencies: package-json "^6.3.0" -lavamoat-core@^6.1.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/lavamoat-core/-/lavamoat-core-6.2.0.tgz#ff1e39c0407f4bf5b94847c5dfaf5b09f28ac77a" - integrity sha512-sY0ddwWou2WGnpEFG/8CGguo6XKq2hc5etIDQ47TYUEJB9BaWGuWulekcrTsTQ0f7EN5r0Y2QtV5ZxxM0fMm8w== - dependencies: - cytoplasm "^3.3.1" - fromentries "^1.2.0" - json-stable-stringify "^1.0.1" - lavamoat-tofu "^5.1.1" - resolve "^1.15.1" - -lavamoat-tofu@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/lavamoat-tofu/-/lavamoat-tofu-5.1.1.tgz#67d3c5775b587dd439c426f1cd86650b10443760" - integrity sha512-LIZTifbbTATA5UClVGI7YGMTOjUXjrVCBOz0DaeUicldLonLlwG81/53/vTIfPM1xV/KA85MIzGPHz4pDdiVkA== - dependencies: - "@babel/parser" "^7.10.1" - "@babel/traverse" "^7.10.1" - lazy-cache@^0.2.3: version "0.2.7" resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-0.2.7.tgz#7feddf2dcb6edb77d11ef1d117ab5ffdf0ab1b65" @@ -17966,7 +17962,12 @@ nano-json-stream-parser@^0.1.2: resolved "https://registry.yarnpkg.com/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz#0cc8f6d0e2b622b479c40d499c46d64b755c6f5f" integrity sha1-DMj20OK2IrR5xA1JnEbWS3Vcb18= -nanoid@^2.0.0, nanoid@^2.1.6: +nanoid@^2.0.0: + version "2.1.11" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-2.1.11.tgz#ec24b8a758d591561531b4176a01e3ab4f0f0280" + integrity sha512-s/snB+WGm6uwi0WjsZdaVcuf3KJXlfGl2LcxgwkEwJF0D/BWzVWAZW/XY4bFaiR7s0Jk3FPvlnepg1H1b1UwlA== + +nanoid@^2.1.6: version "2.1.6" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-2.1.6.tgz#0665418f692e54cf44f34d4010761f3240a03314" integrity sha512-2NDzpiuEy3+H0AVtdt8LoFi7PnqkOnIzYmJQp7xsEU6VexLluHQwKREuiz57XaQC5006seIadPrIZJhyS2n7aw== @@ -21621,12 +21622,12 @@ redux-devtools-core@^0.2.1: remotedev-serialize "^0.1.8" redux-devtools-instrument@^1.9.4: - version "1.9.6" - resolved "https://registry.yarnpkg.com/redux-devtools-instrument/-/redux-devtools-instrument-1.9.6.tgz#6b412595f74b9d48cfd4ecc13e585b1588ed6e7e" - integrity sha512-MwvY4cLEB2tIfWWBzrUR02UM9qRG2i7daNzywRvabOSVdvAY7s9BxSwMmVRH1Y/7QWjplNtOwgT0apKhHg2Qew== + version "1.10.0" + resolved "https://registry.yarnpkg.com/redux-devtools-instrument/-/redux-devtools-instrument-1.10.0.tgz#036caf79fa1e5f25ec4bae38a9af4f08c69e323a" + integrity sha512-X8JRBCzX2ADSMp+iiV7YQ8uoTNyEm0VPFPd4T854coz6lvRiBrFSqAr9YAS2n8Kzxx8CJQotR0QF9wsMM+3DvA== dependencies: - lodash "^4.2.0" - symbol-observable "^1.0.2" + lodash "^4.17.19" + symbol-observable "^1.2.0" redux-mock-store@^1.5.4: version "1.5.4" @@ -21926,9 +21927,9 @@ remote-redux-devtools@^0.5.16: socketcluster-client "^14.2.1" remotedev-serialize@^0.1.8: - version "0.1.8" - resolved "https://registry.yarnpkg.com/remotedev-serialize/-/remotedev-serialize-0.1.8.tgz#c99cb184e7f71a906162abc404be8ce33810205f" - integrity sha512-3YG/FDcOmiK22bl5oMRM8RRnbGrFEuPGjbcDG+z2xi5aQaNQNZ8lqoRnZTwXVfaZtutXuiAQOgPRrogzQk8edg== + version "0.1.9" + resolved "https://registry.yarnpkg.com/remotedev-serialize/-/remotedev-serialize-0.1.9.tgz#5e67e05cbca75d408d769d057dc59d0f56cd2c43" + integrity sha512-5tFdZg9mSaAWTv6xmQ7HtHjKMLSFQFExEZOtJe10PLsv1wb7cy7kYHtBvTYRro27/3fRGEcQBRNKSaixOpb69w== dependencies: jsan "^3.1.13" @@ -22202,7 +22203,14 @@ resolve@1.1.7: resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= -resolve@^1.1.4, resolve@^1.1.5, resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.10.1, resolve@^1.11.0, resolve@^1.11.1, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.15.1, resolve@^1.17.0, resolve@^1.3.2, resolve@^1.4.0, resolve@^1.8.1: +resolve@^1.1.4, resolve@^1.1.5, resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.11.0, resolve@^1.11.1, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.17.0, resolve@^1.3.2, resolve@^1.4.0, resolve@^1.8.1: + version "1.17.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444" + integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w== + dependencies: + path-parse "^1.0.6" + +resolve@^1.10.1: version "1.18.1" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.18.1.tgz#018fcb2c5b207d2a6424aee361c5a266da8f4130" integrity sha512-lDfCPaMKfOJXjy0dPayzPdF1phampNWr3qFCjAu+rw/qbQmr5jWH5xN2hwh9QKfw9E5v4hwV7A+jrCmL8yjjqA== @@ -22325,9 +22333,9 @@ rlp@^2.0.0, rlp@^2.2.1, rlp@^2.2.2, rlp@^2.2.3: bn.js "^4.11.1" rn-host-detect@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/rn-host-detect/-/rn-host-detect-1.1.5.tgz#fbecb982b73932f34529e97932b9a63e58d8deb6" - integrity sha512-ufk2dFT3QeP9HyZ/xTuMtW27KnFy815CYitJMqQm+pgG3ZAtHBsrU8nXizNKkqXGy3bQmhEoloVbrfbvMJMqkg== + version "1.2.0" + resolved "https://registry.yarnpkg.com/rn-host-detect/-/rn-host-detect-1.2.0.tgz#8b0396fc05631ec60c1cb8789e5070cdb04d0da0" + integrity sha512-btNg5kzHcjZZ7t7mvvV/4wNJ9e3MPgrWivkRgWURzXL0JJ0pwWlU4zrbmdlz3HHzHOxhBhHB4D+/dbMFfu4/4A== roarr@^2.15.3: version "2.15.3" @@ -22561,6 +22569,11 @@ sc-errors@^1.4.1: resolved "https://registry.yarnpkg.com/sc-errors/-/sc-errors-1.4.1.tgz#53e80030fe647e133d73b51eaa7d2b0f7591fd5b" integrity sha512-dBn92iIonpChTxYLgKkIT/PCApvmYT6EPIbRvbQKTgY6tbEbIy8XVUv4pGyKwEK4nCmvX4TKXcN0iXC6tNW6rQ== +sc-errors@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/sc-errors/-/sc-errors-2.0.1.tgz#3af2d934dfd82116279a4b2c1552c1e021ddcb03" + integrity sha512-JoVhq3Ud+3Ujv2SIG7W0XtjRHsrNgl6iXuHHsh0s+Kdt5NwI6N2EGAZD4iteitdDv68ENBkpjtSvN597/wxPSQ== + sc-formatter@^3.0.1, sc-formatter@^3.0.2, sc-formatter@~3.0.1: version "3.0.2" resolved "https://registry.yarnpkg.com/sc-formatter/-/sc-formatter-3.0.2.tgz#9abdb14e71873ce7157714d3002477bbdb33c4e6" @@ -22865,6 +22878,15 @@ servify@^0.1.12: request "^2.79.0" xhr "^2.3.3" +ses@0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/ses/-/ses-0.11.0.tgz#1e470112ed320d169f0b850525858129c0be0881" + integrity sha512-3HH+23C4bijk9VegfiP+cBMqkGim/TMsj/DK5nh/pJFiNrCMfi5euvVluIV66ry202+uckg7nXKrgrEcBwU8SA== + dependencies: + "@agoric/babel-standalone" "^7.9.5" + "@agoric/make-hardener" "^0.1.0" + "@agoric/transform-module" "^0.4.1" + sesify-tofu@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/sesify-tofu/-/sesify-tofu-2.0.4.tgz#b31d4c8d67ea2d61e9c5be4948f085a849f3e632" @@ -23270,9 +23292,9 @@ socket.io@^2.1.1: socket.io-parser "~3.3.0" socketcluster-client@^14.2.1: - version "14.2.2" - resolved "https://registry.yarnpkg.com/socketcluster-client/-/socketcluster-client-14.2.2.tgz#60b31318abe6828ba7233f5a9a32540263fd23b6" - integrity sha512-vofmFcTaHaIf+MqAR0OZS7e30X4jxbDPJl+taCe8kLGJ5rVOrKeuU0sGyHyHyqW87AIR6jqc4KODl4WQJ4SsAA== + version "14.3.1" + resolved "https://registry.yarnpkg.com/socketcluster-client/-/socketcluster-client-14.3.1.tgz#bfc3591c0cad2668e7b3512a102f3844f5f2e84d" + integrity sha512-Sd/T0K/9UlqTfz+HUuFq90dshA5OBJPQbdkRzGtcKIOm52fkdsBTt0FYpiuzzxv5VrU7PWpRm6KIfNXyPwlLpw== dependencies: buffer "^5.2.1" clone "2.1.1" @@ -23280,10 +23302,10 @@ socketcluster-client@^14.2.1: linked-list "0.1.0" querystring "0.2.0" sc-channel "^1.2.0" - sc-errors "^1.4.1" + sc-errors "^2.0.1" sc-formatter "^3.0.1" uuid "3.2.1" - ws "5.1.1" + ws "7.1.0" socketcluster-server@^14.3.2: version "14.4.0" @@ -24285,15 +24307,10 @@ swarm-js@^0.1.40: tar "^4.0.2" xhr-request "^1.0.1" -symbol-observable@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.1.tgz#8340fc4702c3122df5d22288f88283f513d3fdd4" - integrity sha1-g0D8RwLDEi310iKI+IKD9RPT/dQ= - -symbol-observable@^1.0.2, symbol-observable@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" - integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ== +symbol-observable@1.0.1, symbol-observable@^1.2.0, symbol-observable@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-2.0.3.tgz#5b521d3d07a43c351055fa43b8355b62d33fd16a" + integrity sha512-sQV7phh2WCYAn81oAkakC5qjq2Ml0g8ozqz03wOGnx9dDlG1de6yrF+0RAzSJD8fPUow3PTSMf2SAbOGxb93BA== symbol-tree@^3.2.1: version "3.2.2" @@ -26521,13 +26538,6 @@ write@^0.2.1: dependencies: mkdirp "^0.5.1" -ws@5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/ws/-/ws-5.1.1.tgz#1d43704689711ac1942fd2f283e38f825c4b8b95" - integrity sha512-bOusvpCb09TOBLbpMKszd45WKC2KPtxiyiHanv+H2DE3Az+1db5a/L7sVJZVDPUC1Br8f0SKRr1KjLpD1U/IAw== - dependencies: - async-limiter "~1.0.0" - ws@6.1.2: version "6.1.2" resolved "https://registry.yarnpkg.com/ws/-/ws-6.1.2.tgz#3cc7462e98792f0ac679424148903ded3b9c3ad8" @@ -26535,6 +26545,13 @@ ws@6.1.2: dependencies: async-limiter "~1.0.0" +ws@7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.1.0.tgz#0395646c6fcc3ac56abf61ce1a42039637a6bd98" + integrity sha512-Swie2C4fs7CkwlHu1glMePLYJJsWjzhl1vm3ZaLplD0h7OMkZyZ6kLTB/OagiU923bZrPFXuDTeEqaEN4NWG4g== + dependencies: + async-limiter "^1.0.0" + ws@7.2.3, ws@^7: version "7.2.3" resolved "https://registry.yarnpkg.com/ws/-/ws-7.2.3.tgz#a5411e1fb04d5ed0efee76d26d5c46d830c39b46" From bf65c979d2e5fe844c636b7b336cef6ab456549b Mon Sep 17 00:00:00 2001 From: David Walsh Date: Tue, 24 Nov 2020 09:38:04 -0600 Subject: [PATCH 07/32] Use async storage instead of localstorage (#9919) --- package.json | 1 + ui/app/ducks/gas/gas-duck.test.js | 44 ++-- ui/app/ducks/gas/gas.duck.js | 232 +++++++++--------- ui/app/ducks/swaps/swaps.js | 22 +- ui/app/helpers/utils/fetch-with-cache.js | 9 +- ui/app/helpers/utils/fetch-with-cache.test.js | 12 +- ui/app/hooks/useRetryTransaction.js | 2 +- ui/lib/local-storage-helpers.js | 20 -- ui/lib/storage-helpers.js | 23 ++ yarn.lock | 7 + 10 files changed, 190 insertions(+), 182 deletions(-) delete mode 100644 ui/lib/local-storage-helpers.js create mode 100644 ui/lib/storage-helpers.js diff --git a/package.json b/package.json index ac19dca58..7a71d40df 100644 --- a/package.json +++ b/package.json @@ -131,6 +131,7 @@ "json-rpc-engine": "^5.3.0", "json-rpc-middleware-stream": "^2.1.1", "jsonschema": "^1.2.4", + "localforage": "^1.9.0", "lodash": "^4.17.19", "loglevel": "^1.4.1", "luxon": "^1.24.1", diff --git a/ui/app/ducks/gas/gas-duck.test.js b/ui/app/ducks/gas/gas-duck.test.js index 6db54d12a..ae770a732 100644 --- a/ui/app/ducks/gas/gas-duck.test.js +++ b/ui/app/ducks/gas/gas-duck.test.js @@ -2,10 +2,10 @@ import assert from 'assert' import sinon from 'sinon' import proxyquire from 'proxyquire' -const fakeLocalStorage = {} +const fakeStorage = {} const GasDuck = proxyquire('./gas.duck.js', { - '../../../lib/local-storage-helpers': fakeLocalStorage, + '../../../lib/storage-helpers': fakeStorage, }) const { @@ -160,8 +160,8 @@ describe('Gas Duck', function () { tempFetch = window.fetch tempDateNow = global.Date.now - fakeLocalStorage.loadLocalStorageData = sinon.stub() - fakeLocalStorage.saveLocalStorageData = sinon.spy() + fakeStorage.getStorageItem = sinon.stub() + fakeStorage.setStorageItem = sinon.spy() window.fetch = sinon.stub().callsFake(fakeFetch) global.Date.now = () => 2000000 }) @@ -412,21 +412,19 @@ describe('Gas Duck', function () { ]) }) - it('should fetch recently retrieved estimates from local storage', async function () { + it('should fetch recently retrieved estimates from storage', async function () { const mockDistpatch = sinon.spy() - fakeLocalStorage.loadLocalStorageData + fakeStorage.getStorageItem .withArgs('BASIC_PRICE_ESTIMATES_LAST_RETRIEVED') .returns(2000000 - 1) // one second ago from "now" - fakeLocalStorage.loadLocalStorageData - .withArgs('BASIC_PRICE_ESTIMATES') - .returns({ - average: 25, - blockTime: 'mockBlock_time', - blockNum: 'mockBlockNum', - fast: 35, - fastest: 45, - safeLow: 15, - }) + fakeStorage.getStorageItem.withArgs('BASIC_PRICE_ESTIMATES').returns({ + average: 25, + blockTime: 'mockBlock_time', + blockNum: 'mockBlockNum', + fast: 35, + fastest: 45, + safeLow: 15, + }) await fetchBasicGasEstimates()(mockDistpatch, () => ({ gas: { ...initState }, @@ -453,9 +451,9 @@ describe('Gas Duck', function () { ]) }) - it('should fallback to network if retrieving estimates from local storage fails', async function () { + it('should fallback to network if retrieving estimates from storage fails', async function () { const mockDistpatch = sinon.spy() - fakeLocalStorage.loadLocalStorageData + fakeStorage.getStorageItem .withArgs('BASIC_PRICE_ESTIMATES_LAST_RETRIEVED') .returns(2000000 - 1) // one second ago from "now" @@ -541,12 +539,12 @@ describe('Gas Duck', function () { ]) }) - it('should fetch recently retrieved estimates from local storage', async function () { + it('should fetch recently retrieved estimates from storage', async function () { const mockDistpatch = sinon.spy() - fakeLocalStorage.loadLocalStorageData + fakeStorage.getStorageItem .withArgs('BASIC_GAS_AND_TIME_API_ESTIMATES_LAST_RETRIEVED') .returns(2000000 - 1) // one second ago from "now" - fakeLocalStorage.loadLocalStorageData + fakeStorage.getStorageItem .withArgs('BASIC_GAS_AND_TIME_API_ESTIMATES') .returns({ average: 5, @@ -596,9 +594,9 @@ describe('Gas Duck', function () { ]) }) - it('should fallback to network if retrieving estimates from local storage fails', async function () { + it('should fallback to network if retrieving estimates from storage fails', async function () { const mockDistpatch = sinon.spy() - fakeLocalStorage.loadLocalStorageData + fakeStorage.getStorageItem .withArgs('BASIC_GAS_AND_TIME_API_ESTIMATES_LAST_RETRIEVED') .returns(2000000 - 1) // one second ago from "now" diff --git a/ui/app/ducks/gas/gas.duck.js b/ui/app/ducks/gas/gas.duck.js index 5a937e744..a1a8cce4d 100644 --- a/ui/app/ducks/gas/gas.duck.js +++ b/ui/app/ducks/gas/gas.duck.js @@ -1,9 +1,7 @@ import { uniqBy, cloneDeep, flatten } from 'lodash' import BigNumber from 'bignumber.js' -import { - loadLocalStorageData, - saveLocalStorageData, -} from '../../../lib/local-storage-helpers' +import { getStorageItem, setStorageItem } from '../../../lib/storage-helpers' + import { decGWEIToHexWEI } from '../../helpers/utils/conversions.util' import { isEthereumNetwork } from '../../selectors' @@ -209,7 +207,7 @@ export function fetchBasicGasEstimates() { const { basicPriceEstimatesLastRetrieved } = getState().gas const timeLastRetrieved = basicPriceEstimatesLastRetrieved || - loadLocalStorageData('BASIC_PRICE_ESTIMATES_LAST_RETRIEVED') || + (await getStorageItem('BASIC_PRICE_ESTIMATES_LAST_RETRIEVED')) || 0 dispatch(basicGasEstimatesLoadingStarted()) @@ -218,7 +216,7 @@ export function fetchBasicGasEstimates() { if (Date.now() - timeLastRetrieved > 75000) { basicEstimates = await fetchExternalBasicGasEstimates(dispatch) } else { - const cachedBasicEstimates = loadLocalStorageData('BASIC_PRICE_ESTIMATES') + const cachedBasicEstimates = await getStorageItem('BASIC_PRICE_ESTIMATES') basicEstimates = cachedBasicEstimates || (await fetchExternalBasicGasEstimates(dispatch)) } @@ -259,8 +257,10 @@ async function fetchExternalBasicGasEstimates(dispatch) { } const timeRetrieved = Date.now() - saveLocalStorageData(basicEstimates, 'BASIC_PRICE_ESTIMATES') - saveLocalStorageData(timeRetrieved, 'BASIC_PRICE_ESTIMATES_LAST_RETRIEVED') + await Promise.all([ + setStorageItem('BASIC_PRICE_ESTIMATES', basicEstimates), + setStorageItem('BASIC_PRICE_ESTIMATES_LAST_RETRIEVED', timeRetrieved), + ]) dispatch(setBasicPriceEstimatesLastRetrieved(timeRetrieved)) return basicEstimates @@ -271,7 +271,9 @@ export function fetchBasicGasAndTimeEstimates() { const { basicPriceAndTimeEstimatesLastRetrieved } = getState().gas const timeLastRetrieved = basicPriceAndTimeEstimatesLastRetrieved || - loadLocalStorageData('BASIC_GAS_AND_TIME_API_ESTIMATES_LAST_RETRIEVED') || + (await getStorageItem( + 'BASIC_GAS_AND_TIME_API_ESTIMATES_LAST_RETRIEVED', + )) || 0 dispatch(basicGasEstimatesLoadingStarted()) @@ -280,7 +282,7 @@ export function fetchBasicGasAndTimeEstimates() { if (Date.now() - timeLastRetrieved > 75000) { basicEstimates = await fetchExternalBasicGasAndTimeEstimates(dispatch) } else { - const cachedBasicEstimates = loadLocalStorageData( + const cachedBasicEstimates = await getStorageItem( 'BASIC_GAS_AND_TIME_API_ESTIMATES', ) basicEstimates = @@ -332,11 +334,13 @@ async function fetchExternalBasicGasAndTimeEstimates(dispatch) { } const timeRetrieved = Date.now() - saveLocalStorageData(basicEstimates, 'BASIC_GAS_AND_TIME_API_ESTIMATES') - saveLocalStorageData( - timeRetrieved, - 'BASIC_GAS_AND_TIME_API_ESTIMATES_LAST_RETRIEVED', - ) + await Promise.all([ + setStorageItem('BASIC_GAS_AND_TIME_API_ESTIMATES', basicEstimates), + setStorageItem( + 'BASIC_GAS_AND_TIME_API_ESTIMATES_LAST_RETRIEVED', + timeRetrieved, + ), + ]) dispatch(setBasicApiEstimatesLastRetrieved(timeRetrieved)) return basicEstimates @@ -403,11 +407,11 @@ function inliersByIQR(data, prop) { } export function fetchGasEstimates(blockTime) { - return (dispatch, getState) => { + return async (dispatch, getState) => { const state = getState() if (!isEthereumNetwork(state)) { - return Promise.resolve(null) + return } const { @@ -416,114 +420,112 @@ export function fetchGasEstimates(blockTime) { } = state.gas const timeLastRetrieved = priceAndTimeEstimatesLastRetrieved || - loadLocalStorageData('GAS_API_ESTIMATES_LAST_RETRIEVED') || + (await getStorageItem('GAS_API_ESTIMATES_LAST_RETRIEVED')) || 0 dispatch(gasEstimatesLoadingStarted()) - const promiseToFetch = - Date.now() - timeLastRetrieved > 75000 - ? queryEthGasStationPredictionTable() - .then((r) => r.json()) - .then((r) => { - const estimatedPricesAndTimes = r.map( - ({ expectedTime, expectedWait, gasprice }) => ({ - expectedTime, - expectedWait, - gasprice, - }), - ) - const estimatedTimeWithUniquePrices = uniqBy( - estimatedPricesAndTimes, - ({ expectedTime }) => expectedTime, - ) - - const withSupplementalTimeEstimates = flatten( - estimatedTimeWithUniquePrices.map( - ({ expectedWait, gasprice }, i, arr) => { - const next = arr[i + 1] - if (!next) { - return [{ expectedWait, gasprice }] - } - const supplementalPrice = getRandomArbitrary( - gasprice, - next.gasprice, - ) - const supplementalTime = extrapolateY({ - higherY: next.expectedWait, - lowerY: expectedWait, - higherX: next.gasprice, - lowerX: gasprice, - xForExtrapolation: supplementalPrice, - }) - const supplementalPrice2 = getRandomArbitrary( - supplementalPrice, - next.gasprice, - ) - const supplementalTime2 = extrapolateY({ - higherY: next.expectedWait, - lowerY: supplementalTime, - higherX: next.gasprice, - lowerX: supplementalPrice, - xForExtrapolation: supplementalPrice2, - }) - return [ - { expectedWait, gasprice }, - { - expectedWait: supplementalTime, - gasprice: supplementalPrice, - }, - { - expectedWait: supplementalTime2, - gasprice: supplementalPrice2, - }, - ] - }, - ), - ) - const withOutliersRemoved = inliersByIQR( - withSupplementalTimeEstimates.slice(0).reverse(), - 'expectedWait', - ).reverse() - const timeMappedToSeconds = withOutliersRemoved.map( - ({ expectedWait, gasprice }) => { - const expectedTime = new BigNumber(expectedWait) - .times(Number(blockTime), 10) - .toNumber() - return { - expectedTime, - gasprice: new BigNumber(gasprice, 10).toNumber(), - } - }, - ) - - const timeRetrieved = Date.now() - dispatch(setApiEstimatesLastRetrieved(timeRetrieved)) - saveLocalStorageData( - timeRetrieved, - 'GAS_API_ESTIMATES_LAST_RETRIEVED', - ) - saveLocalStorageData(timeMappedToSeconds, 'GAS_API_ESTIMATES') - - return timeMappedToSeconds + const shouldGetFreshGasQuote = Date.now() - timeLastRetrieved > 75000 + let estimates + if (shouldGetFreshGasQuote) { + const response = await queryEthGasStationPredictionTable() + const tableJson = await response.json() + + const estimatedPricesAndTimes = tableJson.map( + ({ expectedTime, expectedWait, gasprice }) => ({ + expectedTime, + expectedWait, + gasprice, + }), + ) + const estimatedTimeWithUniquePrices = uniqBy( + estimatedPricesAndTimes, + ({ expectedTime }) => expectedTime, + ) + + const withSupplementalTimeEstimates = flatten( + estimatedTimeWithUniquePrices.map( + ({ expectedWait, gasprice }, i, arr) => { + const next = arr[i + 1] + if (!next) { + return [{ expectedWait, gasprice }] + } + const supplementalPrice = getRandomArbitrary( + gasprice, + next.gasprice, + ) + const supplementalTime = extrapolateY({ + higherY: next.expectedWait, + lowerY: expectedWait, + higherX: next.gasprice, + lowerX: gasprice, + xForExtrapolation: supplementalPrice, }) - : Promise.resolve( - priceAndTimeEstimates.length - ? priceAndTimeEstimates - : loadLocalStorageData('GAS_API_ESTIMATES'), - ) - - return promiseToFetch.then((estimates) => { - dispatch(setPricesAndTimeEstimates(estimates)) - dispatch(gasEstimatesLoadingFinished()) - }) + const supplementalPrice2 = getRandomArbitrary( + supplementalPrice, + next.gasprice, + ) + const supplementalTime2 = extrapolateY({ + higherY: next.expectedWait, + lowerY: supplementalTime, + higherX: next.gasprice, + lowerX: supplementalPrice, + xForExtrapolation: supplementalPrice2, + }) + return [ + { expectedWait, gasprice }, + { + expectedWait: supplementalTime, + gasprice: supplementalPrice, + }, + { + expectedWait: supplementalTime2, + gasprice: supplementalPrice2, + }, + ] + }, + ), + ) + const withOutliersRemoved = inliersByIQR( + withSupplementalTimeEstimates.slice(0).reverse(), + 'expectedWait', + ).reverse() + const timeMappedToSeconds = withOutliersRemoved.map( + ({ expectedWait, gasprice }) => { + const expectedTime = new BigNumber(expectedWait) + .times(Number(blockTime), 10) + .toNumber() + return { + expectedTime, + gasprice: new BigNumber(gasprice, 10).toNumber(), + } + }, + ) + + const timeRetrieved = Date.now() + dispatch(setApiEstimatesLastRetrieved(timeRetrieved)) + + await Promise.all([ + setStorageItem('GAS_API_ESTIMATES_LAST_RETRIEVED', timeRetrieved), + setStorageItem('GAS_API_ESTIMATES', timeMappedToSeconds), + ]) + + estimates = timeMappedToSeconds + } else if (priceAndTimeEstimates.length) { + estimates = priceAndTimeEstimates + } else { + estimates = await getStorageItem('GAS_API_ESTIMATES') + } + + dispatch(setPricesAndTimeEstimates(estimates)) + dispatch(gasEstimatesLoadingFinished()) } } export function setCustomGasPriceForRetry(newPrice) { - return (dispatch) => { + return async (dispatch) => { if (newPrice === '0x0') { - const { fast } = loadLocalStorageData('BASIC_PRICE_ESTIMATES') + const { fast } = await getStorageItem('BASIC_PRICE_ESTIMATES') dispatch(setCustomGasPrice(decGWEIToHexWEI(fast))) } else { dispatch(setCustomGasPrice(newPrice)) diff --git a/ui/app/ducks/swaps/swaps.js b/ui/app/ducks/swaps/swaps.js index 998648b35..9ff86dbd8 100644 --- a/ui/app/ducks/swaps/swaps.js +++ b/ui/app/ducks/swaps/swaps.js @@ -2,10 +2,8 @@ import { createSlice } from '@reduxjs/toolkit' import BigNumber from 'bignumber.js' import log from 'loglevel' -import { - loadLocalStorageData, - saveLocalStorageData, -} from '../../../lib/local-storage-helpers' +import { getStorageItem, setStorageItem } from '../../../lib/storage-helpers' + import { addToken, addUnapprovedTransaction, @@ -754,7 +752,7 @@ export function fetchMetaSwapsGasPriceEstimates() { ) const timeLastRetrieved = priceEstimatesLastRetrieved || - loadLocalStorageData('METASWAP_GAS_PRICE_ESTIMATES_LAST_RETRIEVED') || + (await getStorageItem('METASWAP_GAS_PRICE_ESTIMATES_LAST_RETRIEVED')) || 0 dispatch(swapGasPriceEstimatesFetchStarted()) @@ -764,7 +762,7 @@ export function fetchMetaSwapsGasPriceEstimates() { if (Date.now() - timeLastRetrieved > 30000) { priceEstimates = await fetchSwapsGasPrices() } else { - const cachedPriceEstimates = loadLocalStorageData( + const cachedPriceEstimates = await getStorageItem( 'METASWAP_GAS_PRICE_ESTIMATES', ) priceEstimates = cachedPriceEstimates || (await fetchSwapsGasPrices()) @@ -795,11 +793,13 @@ export function fetchMetaSwapsGasPriceEstimates() { const timeRetrieved = Date.now() - saveLocalStorageData(priceEstimates, 'METASWAP_GAS_PRICE_ESTIMATES') - saveLocalStorageData( - timeRetrieved, - 'METASWAP_GAS_PRICE_ESTIMATES_LAST_RETRIEVED', - ) + await Promise.all([ + setStorageItem('METASWAP_GAS_PRICE_ESTIMATES', priceEstimates), + setStorageItem( + 'METASWAP_GAS_PRICE_ESTIMATES_LAST_RETRIEVED', + timeRetrieved, + ), + ]) dispatch( swapGasPriceEstimatesFetchCompleted({ diff --git a/ui/app/helpers/utils/fetch-with-cache.js b/ui/app/helpers/utils/fetch-with-cache.js index c04d54086..351ee4ab9 100644 --- a/ui/app/helpers/utils/fetch-with-cache.js +++ b/ui/app/helpers/utils/fetch-with-cache.js @@ -1,7 +1,4 @@ -import { - loadLocalStorageData, - saveLocalStorageData, -} from '../../../lib/local-storage-helpers' +import { getStorageItem, setStorageItem } from '../../../lib/storage-helpers' import fetchWithTimeout from '../../../../app/scripts/lib/fetch-with-timeout' const fetchWithCache = async ( @@ -27,7 +24,7 @@ const fetchWithCache = async ( } const currentTime = Date.now() - const cachedFetch = loadLocalStorageData('cachedFetch') || {} + const cachedFetch = (await getStorageItem('cachedFetch')) || {} const { cachedResponse, cachedTime } = cachedFetch[url] || {} if (cachedResponse && currentTime - cachedTime < cacheRefreshTime) { return cachedResponse @@ -52,7 +49,7 @@ const fetchWithCache = async ( cachedTime: currentTime, } cachedFetch[url] = cacheEntry - saveLocalStorageData(cachedFetch, 'cachedFetch') + await setStorageItem('cachedFetch', cachedFetch) return responseJson } diff --git a/ui/app/helpers/utils/fetch-with-cache.test.js b/ui/app/helpers/utils/fetch-with-cache.test.js index c5981abd9..c0fcda3fc 100644 --- a/ui/app/helpers/utils/fetch-with-cache.test.js +++ b/ui/app/helpers/utils/fetch-with-cache.test.js @@ -3,15 +3,15 @@ import nock from 'nock' import sinon from 'sinon' import proxyquire from 'proxyquire' -const fakeLocalStorageHelpers = {} +const fakeStorage = {} const fetchWithCache = proxyquire('./fetch-with-cache', { - '../../../lib/local-storage-helpers': fakeLocalStorageHelpers, + '../../../lib/storage-helpers': fakeStorage, }).default describe('Fetch with cache', function () { beforeEach(function () { - fakeLocalStorageHelpers.loadLocalStorageData = sinon.stub() - fakeLocalStorageHelpers.saveLocalStorageData = sinon.stub() + fakeStorage.getStorageItem = sinon.stub() + fakeStorage.setStorageItem = sinon.stub() }) afterEach(function () { sinon.restore() @@ -36,7 +36,7 @@ describe('Fetch with cache', function () { .get('/price') .reply(200, '{"average": 2}') - fakeLocalStorageHelpers.loadLocalStorageData.returns({ + fakeStorage.getStorageItem.returns({ 'https://fetchwithcache.metamask.io/price': { cachedResponse: { average: 1 }, cachedTime: Date.now(), @@ -56,7 +56,7 @@ describe('Fetch with cache', function () { .get('/price') .reply(200, '{"average": 3}') - fakeLocalStorageHelpers.loadLocalStorageData.returns({ + fakeStorage.getStorageItem.returns({ 'https://fetchwithcache.metamask.io/cached': { cachedResponse: { average: 1 }, cachedTime: Date.now() - 1000, diff --git a/ui/app/hooks/useRetryTransaction.js b/ui/app/hooks/useRetryTransaction.js index c12000266..154e99853 100644 --- a/ui/app/hooks/useRetryTransaction.js +++ b/ui/app/hooks/useRetryTransaction.js @@ -38,7 +38,7 @@ export function useRetryTransaction(transactionGroup) { await dispatch(fetchGasEstimates(basicEstimates.blockTime)) const transaction = initialTransaction const increasedGasPrice = increaseLastGasPrice(gasPrice) - dispatch( + await dispatch( setCustomGasPriceForRetry( increasedGasPrice || transaction.txParams.gasPrice, ), diff --git a/ui/lib/local-storage-helpers.js b/ui/lib/local-storage-helpers.js deleted file mode 100644 index 58dc637ed..000000000 --- a/ui/lib/local-storage-helpers.js +++ /dev/null @@ -1,20 +0,0 @@ -export function loadLocalStorageData(itemKey) { - try { - const serializedData = window.localStorage.getItem(itemKey) - if (serializedData === null) { - return undefined - } - return JSON.parse(serializedData) - } catch (err) { - return undefined - } -} - -export function saveLocalStorageData(data, itemKey) { - try { - const serializedData = JSON.stringify(data) - window.localStorage.setItem(itemKey, serializedData) - } catch (err) { - console.warn(err) - } -} diff --git a/ui/lib/storage-helpers.js b/ui/lib/storage-helpers.js new file mode 100644 index 000000000..737147405 --- /dev/null +++ b/ui/lib/storage-helpers.js @@ -0,0 +1,23 @@ +import localforage from 'localforage' + +export async function getStorageItem(key) { + try { + const serializedData = await localforage.getItem(key) + if (serializedData === null) { + return undefined + } + + return JSON.parse(serializedData) + } catch (err) { + return undefined + } +} + +export async function setStorageItem(key, value) { + try { + const serializedData = JSON.stringify(value) + await localforage.setItem(key, serializedData) + } catch (err) { + console.warn(err) + } +} diff --git a/yarn.lock b/yarn.lock index f12ac1a5a..c33e7a68d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -16608,6 +16608,13 @@ localforage@1.8.1: dependencies: lie "3.1.1" +localforage@^1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/localforage/-/localforage-1.9.0.tgz#f3e4d32a8300b362b4634cc4e066d9d00d2f09d1" + integrity sha512-rR1oyNrKulpe+VM9cYmcFn6tsHuokyVHFaCM3+osEmxaHTbEk8oQu6eGDfS6DQLWi/N67XRmB8ECG37OES368g== + dependencies: + lie "3.1.1" + localstorage-down@^0.6.7: version "0.6.7" resolved "https://registry.yarnpkg.com/localstorage-down/-/localstorage-down-0.6.7.tgz#d0799a93b31e6c5fa5188ec06242eb1cce9d6d15" From 6a9c15d4a4f22d9fd0b064c381c70fcca172c773 Mon Sep 17 00:00:00 2001 From: Niranjana Binoy <43930900+NiranjanaBinoy@users.noreply.github.com> Date: Tue, 24 Nov 2020 14:32:06 -0500 Subject: [PATCH 08/32] updating the version of extension-port-stream to latest (#9942) --- package.json | 2 +- yarn.lock | 11 ++++------- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index 7a71d40df..13110889b 100644 --- a/package.json +++ b/package.json @@ -123,7 +123,7 @@ "ethjs-contract": "^0.2.3", "ethjs-ens": "^2.0.0", "ethjs-query": "^0.3.4", - "extension-port-stream": "^1.0.0", + "extension-port-stream": "^2.0.0", "extensionizer": "^1.0.1", "fast-json-patch": "^2.0.4", "fuse.js": "^3.2.0", diff --git a/yarn.lock b/yarn.lock index c33e7a68d..c6207fbb7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10786,13 +10786,10 @@ extend@3, extend@3.0.2, extend@^3.0.0, extend@~3.0.2: resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== -extension-port-stream@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/extension-port-stream/-/extension-port-stream-1.0.0.tgz#5da21d4627dfef6013ae101cb3ff8eacaf18b279" - integrity sha512-FsFr64yr6ituPdaGP6Io5recGFWVjJoDYt7asz2AvPkYqGN9c923nmEtyHH+413066bjGcQZaF8w5wn9HbNXiQ== - dependencies: - readable-stream "^2.3.6" - util "^0.11.0" +extension-port-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/extension-port-stream/-/extension-port-stream-2.0.0.tgz#c52da241eef4643171b7c6d696baa4a3453c5a9a" + integrity sha512-7ju8jisPXY8w8UiUczF61hRN6bpx/YTZYU9J901GnEqu7vQnweMAwS30k+SgXCcY9S38Zno+fhuu1iaxd+0swg== extensionizer@^1.0.1: version "1.0.1" From 429847a6865dc5409a6a28bd302196f63f048890 Mon Sep 17 00:00:00 2001 From: Mark Stacey Date: Mon, 30 Nov 2020 16:40:46 -0330 Subject: [PATCH 09/32] Update to `@storybook/*@6` (#9956) Our Storybook dependencies have been updated to v6.1.9, from v5. This was done to address a security vulnerability in a transitive dependency of these packages (`highlight.js`). The primary changes required by this Storybook update were the change in import path for the `withKnobs` hook, the change in background config format, and the webpack configuration. Storybook seems to work correctly. The migration was guided by the Storybook changelog[1] and the Storybook v6 migration guide[2]. There is one Storybook error remaining; it fails to load the Euclid font. This is a pre-existing error though, so we can fix it in a later PR. The `yarn.lock` file was deduplicated in this PR as well, as it was required to fix various install warnings that were introduced with this update. [1]: https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md [2]: https://github.com/storybookjs/storybook/blob/next/MIGRATION.md --- .storybook/main.js | 36 + .storybook/preview.js | 13 +- .storybook/webpack.config.js | 41 - package.json | 10 +- .../ui/button-group/button-group.stories.js | 2 +- ui/app/components/ui/button/button.stories.js | 2 +- .../ui/check-box/check-box.stories.js | 2 +- .../ui/dropdown/dropdown.stories.js | 2 +- ui/app/components/ui/icon/icon.stories.js | 2 +- .../ui/identicon/identicon.stories.js | 3 +- .../ui/info-tooltip/info-tooltip.stories.js | 2 +- .../ui/list-item/list-item.stories.js | 2 +- .../components/ui/popover/popover.stories.js | 2 +- ui/app/components/ui/tabs/tabs.stories.js | 2 +- .../actionable-message.stories.js | 2 +- .../swaps/build-quote/build-quote.stories.js | 2 +- .../countdown-timer.stories.js | 2 +- .../exchange-rate-display.stories.js | 2 +- .../pages/swaps/fee-card/fee-card.stories.js | 2 +- .../main-quote-summary.stories.js | 2 +- .../select-quote-popover.stories.js | 2 +- yarn.lock | 4310 +++++++++-------- 22 files changed, 2278 insertions(+), 2167 deletions(-) delete mode 100644 .storybook/webpack.config.js diff --git a/.storybook/main.js b/.storybook/main.js index 74acf6fb8..2411f2066 100644 --- a/.storybook/main.js +++ b/.storybook/main.js @@ -1,3 +1,7 @@ +const path = require('path') + +const CopyWebpackPlugin = require('copy-webpack-plugin') + module.exports = { stories: ['../ui/app/**/*.stories.js'], addons: [ @@ -5,4 +9,36 @@ module.exports = { '@storybook/addon-actions', '@storybook/addon-backgrounds' ], + webpackFinal: async (config) => { + config.module.strictExportPresence = true + config.module.rules.push({ + test: /\.scss$/, + loaders: [ + 'style-loader', + { + loader: 'css-loader', + options: { + import: false, + url: false, + }, + }, + 'resolve-url-loader', + { + loader: 'sass-loader', + options: { + sourceMap: true, + }, + }, + ], + }) + config.plugins.push(new CopyWebpackPlugin({ + patterns: [ + { + from: path.join('node_modules', '@fortawesome', 'fontawesome-free', 'webfonts'), + to: path.join('fonts', 'fontawesome'), + }, + ], + })) + return config + }, } diff --git a/.storybook/preview.js b/.storybook/preview.js index b28733bad..c3115997c 100644 --- a/.storybook/preview.js +++ b/.storybook/preview.js @@ -1,6 +1,6 @@ import React from 'react' import { addDecorator, addParameters } from '@storybook/react' -import { withKnobs } from '@storybook/addon-knobs/react' +import { withKnobs } from '@storybook/addon-knobs' import { I18nProvider, LegacyI18nProvider } from '../ui/app/contexts/i18n' import { Provider } from 'react-redux' import configureStore from '../ui/app/store/store' @@ -8,10 +8,13 @@ import '../ui/app/css/index.scss' import en from '../app/_locales/en/messages' addParameters({ - backgrounds: [ - { name: 'light', value: '#FFFFFF'}, - { name: 'dark', value: '#333333' }, - ], + backgrounds: { + default: 'light', + values: [ + { name: 'light', value: '#FFFFFF'}, + { name: 'dark', value: '#333333' }, + ], + } }) const styles = { diff --git a/.storybook/webpack.config.js b/.storybook/webpack.config.js deleted file mode 100644 index be7dfecea..000000000 --- a/.storybook/webpack.config.js +++ /dev/null @@ -1,41 +0,0 @@ -const path = require('path') - -const CopyWebpackPlugin = require('copy-webpack-plugin') - -module.exports = { - module: { - strictExportPresence: true, - rules: [ - { - test: /\.scss$/, - loaders: [ - 'style-loader', - { - loader: 'css-loader', - options: { - import: false, - url: false, - }, - }, - 'resolve-url-loader', - { - loader: 'sass-loader', - options: { - sourceMap: true, - }, - }, - ], - }, - ], - }, - plugins: [ - new CopyWebpackPlugin({ - patterns: [ - { - from: path.join('node_modules', '@fortawesome', 'fontawesome-free', 'webfonts'), - to: path.join('fonts', 'fontawesome'), - }, - ], - }), - ], -} diff --git a/package.json b/package.json index 13110889b..01a7ffb90 100644 --- a/package.json +++ b/package.json @@ -192,11 +192,11 @@ "@metamask/forwarder": "^1.1.0", "@metamask/test-dapp": "^4.0.1", "@sentry/cli": "^1.58.0", - "@storybook/addon-actions": "^5.3.14", - "@storybook/addon-backgrounds": "^5.3.14", - "@storybook/addon-knobs": "^5.3.14", - "@storybook/core": "^5.3.14", - "@storybook/react": "^5.3.14", + "@storybook/addon-actions": "^6.1.9", + "@storybook/addon-backgrounds": "^6.1.9", + "@storybook/addon-knobs": "^6.1.9", + "@storybook/core": "^6.1.9", + "@storybook/react": "^6.1.9", "@storybook/storybook-deployer": "^2.8.6", "@testing-library/react": "^10.4.8", "@testing-library/react-hooks": "^3.2.1", diff --git a/ui/app/components/ui/button-group/button-group.stories.js b/ui/app/components/ui/button-group/button-group.stories.js index 38c538092..d9cbdf3d5 100644 --- a/ui/app/components/ui/button-group/button-group.stories.js +++ b/ui/app/components/ui/button-group/button-group.stories.js @@ -1,7 +1,7 @@ import React from 'react' import { action } from '@storybook/addon-actions' import classnames from 'classnames' -import { text, boolean } from '@storybook/addon-knobs/react' +import { text, boolean } from '@storybook/addon-knobs' import Button from '../button' import ButtonGroup from '.' diff --git a/ui/app/components/ui/button/button.stories.js b/ui/app/components/ui/button/button.stories.js index 25fc853de..d07b02e31 100644 --- a/ui/app/components/ui/button/button.stories.js +++ b/ui/app/components/ui/button/button.stories.js @@ -1,6 +1,6 @@ import React from 'react' import { action } from '@storybook/addon-actions' -import { text, boolean } from '@storybook/addon-knobs/react' +import { text, boolean } from '@storybook/addon-knobs' import Button from '.' export default { diff --git a/ui/app/components/ui/check-box/check-box.stories.js b/ui/app/components/ui/check-box/check-box.stories.js index 20647f780..2fb7cdae7 100644 --- a/ui/app/components/ui/check-box/check-box.stories.js +++ b/ui/app/components/ui/check-box/check-box.stories.js @@ -1,6 +1,6 @@ import React from 'react' import { action } from '@storybook/addon-actions' -import { boolean, select, text } from '@storybook/addon-knobs/react' +import { boolean, select, text } from '@storybook/addon-knobs' import CheckBox, { CHECKED, INDETERMINATE, diff --git a/ui/app/components/ui/dropdown/dropdown.stories.js b/ui/app/components/ui/dropdown/dropdown.stories.js index e5771623f..b46358def 100644 --- a/ui/app/components/ui/dropdown/dropdown.stories.js +++ b/ui/app/components/ui/dropdown/dropdown.stories.js @@ -1,6 +1,6 @@ import React from 'react' import { action } from '@storybook/addon-actions' -import { boolean, select, text } from '@storybook/addon-knobs/react' +import { boolean, select, text } from '@storybook/addon-knobs' import Dropdown from '.' export default { diff --git a/ui/app/components/ui/icon/icon.stories.js b/ui/app/components/ui/icon/icon.stories.js index a737b77c9..11209a32a 100644 --- a/ui/app/components/ui/icon/icon.stories.js +++ b/ui/app/components/ui/icon/icon.stories.js @@ -1,5 +1,5 @@ import React from 'react' -import { color, number } from '@storybook/addon-knobs/react' +import { color, number } from '@storybook/addon-knobs' import Approve from './approve-icon.component' import Copy from './copy-icon.component' import Interaction from './interaction-icon.component' diff --git a/ui/app/components/ui/identicon/identicon.stories.js b/ui/app/components/ui/identicon/identicon.stories.js index fec2e2f2c..0dbefe0ff 100644 --- a/ui/app/components/ui/identicon/identicon.stories.js +++ b/ui/app/components/ui/identicon/identicon.stories.js @@ -1,6 +1,5 @@ import React from 'react' -import { text, boolean } from '@storybook/addon-knobs/react' -import { number } from '@storybook/addon-knobs' +import { text, boolean, number } from '@storybook/addon-knobs' import Identicon from './identicon.component' export default { title: 'Identicon' } diff --git a/ui/app/components/ui/info-tooltip/info-tooltip.stories.js b/ui/app/components/ui/info-tooltip/info-tooltip.stories.js index 5d79ef92a..dfe44e2cf 100644 --- a/ui/app/components/ui/info-tooltip/info-tooltip.stories.js +++ b/ui/app/components/ui/info-tooltip/info-tooltip.stories.js @@ -1,5 +1,5 @@ import React from 'react' -import { text } from '@storybook/addon-knobs/react' +import { text } from '@storybook/addon-knobs' import InfoTooltip from './info-tooltip' export default { diff --git a/ui/app/components/ui/list-item/list-item.stories.js b/ui/app/components/ui/list-item/list-item.stories.js index 80a979b5b..ce9f3d4af 100644 --- a/ui/app/components/ui/list-item/list-item.stories.js +++ b/ui/app/components/ui/list-item/list-item.stories.js @@ -1,6 +1,6 @@ import React from 'react' import PropTypes from 'prop-types' -import { text } from '@storybook/addon-knobs/react' +import { text } from '@storybook/addon-knobs' import Send from '../icon/send-icon.component' import Interaction from '../icon/interaction-icon.component' import Approve from '../icon/approve-icon.component' diff --git a/ui/app/components/ui/popover/popover.stories.js b/ui/app/components/ui/popover/popover.stories.js index f81aa69e2..be713f0dc 100644 --- a/ui/app/components/ui/popover/popover.stories.js +++ b/ui/app/components/ui/popover/popover.stories.js @@ -1,5 +1,5 @@ import React from 'react' -import { text } from '@storybook/addon-knobs/react' +import { text } from '@storybook/addon-knobs' import { action } from '@storybook/addon-actions' import Popover from './popover.component' diff --git a/ui/app/components/ui/tabs/tabs.stories.js b/ui/app/components/ui/tabs/tabs.stories.js index f69d38103..1cdc9044c 100644 --- a/ui/app/components/ui/tabs/tabs.stories.js +++ b/ui/app/components/ui/tabs/tabs.stories.js @@ -1,5 +1,5 @@ import React from 'react' -import { text } from '@storybook/addon-knobs/react' +import { text } from '@storybook/addon-knobs' import Tab from './tab/tab.component' import Tabs from './tabs.component' diff --git a/ui/app/pages/swaps/actionable-message/actionable-message.stories.js b/ui/app/pages/swaps/actionable-message/actionable-message.stories.js index 8aabbc235..66ab6031d 100644 --- a/ui/app/pages/swaps/actionable-message/actionable-message.stories.js +++ b/ui/app/pages/swaps/actionable-message/actionable-message.stories.js @@ -1,6 +1,6 @@ import React from 'react' import { action } from '@storybook/addon-actions' -import { text } from '@storybook/addon-knobs/react' +import { text } from '@storybook/addon-knobs' import ActionableMessage from '.' export default { diff --git a/ui/app/pages/swaps/build-quote/build-quote.stories.js b/ui/app/pages/swaps/build-quote/build-quote.stories.js index 8daffe17f..9a6eaf221 100644 --- a/ui/app/pages/swaps/build-quote/build-quote.stories.js +++ b/ui/app/pages/swaps/build-quote/build-quote.stories.js @@ -1,6 +1,6 @@ import React, { useState } from 'react' import { action } from '@storybook/addon-actions' -import { boolean } from '@storybook/addon-knobs/react' +import { boolean } from '@storybook/addon-knobs' import DropdownInputPair from '../dropdown-input-pair' import DropdownSearchList from '../dropdown-search-list' diff --git a/ui/app/pages/swaps/countdown-timer/countdown-timer.stories.js b/ui/app/pages/swaps/countdown-timer/countdown-timer.stories.js index 276ab01d4..6970a045a 100644 --- a/ui/app/pages/swaps/countdown-timer/countdown-timer.stories.js +++ b/ui/app/pages/swaps/countdown-timer/countdown-timer.stories.js @@ -1,5 +1,5 @@ import React from 'react' -import { number } from '@storybook/addon-knobs/react' +import { number } from '@storybook/addon-knobs' import CountdownTimer from './countdown-timer' export default { diff --git a/ui/app/pages/swaps/exchange-rate-display/exchange-rate-display.stories.js b/ui/app/pages/swaps/exchange-rate-display/exchange-rate-display.stories.js index ff939f121..b28fa3772 100644 --- a/ui/app/pages/swaps/exchange-rate-display/exchange-rate-display.stories.js +++ b/ui/app/pages/swaps/exchange-rate-display/exchange-rate-display.stories.js @@ -1,5 +1,5 @@ import React from 'react' -import { text, number } from '@storybook/addon-knobs/react' +import { text, number } from '@storybook/addon-knobs' import ExchangeRateDisplay from './exchange-rate-display' export default { diff --git a/ui/app/pages/swaps/fee-card/fee-card.stories.js b/ui/app/pages/swaps/fee-card/fee-card.stories.js index 6b316caab..af57849f3 100644 --- a/ui/app/pages/swaps/fee-card/fee-card.stories.js +++ b/ui/app/pages/swaps/fee-card/fee-card.stories.js @@ -1,6 +1,6 @@ import React from 'react' import { action } from '@storybook/addon-actions' -import { text } from '@storybook/addon-knobs/react' +import { text } from '@storybook/addon-knobs' import FeeCard from './fee-card' const tokenApprovalTextComponent = ( diff --git a/ui/app/pages/swaps/main-quote-summary/main-quote-summary.stories.js b/ui/app/pages/swaps/main-quote-summary/main-quote-summary.stories.js index f6c1ffeb2..ea267eb17 100644 --- a/ui/app/pages/swaps/main-quote-summary/main-quote-summary.stories.js +++ b/ui/app/pages/swaps/main-quote-summary/main-quote-summary.stories.js @@ -1,5 +1,5 @@ import React from 'react' -import { text, number, boolean } from '@storybook/addon-knobs/react' +import { text, number, boolean } from '@storybook/addon-knobs' import MainQuoteSummary from './main-quote-summary' export default { diff --git a/ui/app/pages/swaps/select-quote-popover/select-quote-popover.stories.js b/ui/app/pages/swaps/select-quote-popover/select-quote-popover.stories.js index b033e34ed..61693839f 100644 --- a/ui/app/pages/swaps/select-quote-popover/select-quote-popover.stories.js +++ b/ui/app/pages/swaps/select-quote-popover/select-quote-popover.stories.js @@ -1,6 +1,6 @@ import React, { useState } from 'react' import { action } from '@storybook/addon-actions' -import { object } from '@storybook/addon-knobs/react' +import { object } from '@storybook/addon-knobs' import Button from '../../../components/ui/button' import mockQuoteData from './mock-quote-data' import SelectQuotePopover from '.' diff --git a/yarn.lock b/yarn.lock index c6207fbb7..fed504d5c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -62,33 +62,38 @@ resolved "https://registry.yarnpkg.com/@agoric/transform-module/-/transform-module-0.4.1.tgz#9fb152364faf372e1bda535cb4ef89717724f57c" integrity sha512-4TJJHXeXAWu1FCA7yXCAZmhBNoGTB/BEAe2pv+J2X8W/mJTr9b395OkDCSRMpzvmSshLfBx6wT0D7dqWIWEC1w== -"@babel/code-frame@7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0.tgz#06e2ab19bdb535385559aabb5ba59729482800f8" - integrity sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA== +"@babel/code-frame@7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.8.3.tgz#33e25903d7481181534e12ec0a25f16b6fcf419e" + integrity sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g== dependencies: - "@babel/highlight" "^7.0.0" + "@babel/highlight" "^7.8.3" -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4": +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.5.5": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a" integrity sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg== dependencies: "@babel/highlight" "^7.10.4" -"@babel/core@>=7.9.0", "@babel/core@^7.12.1", "@babel/core@^7.4.3", "@babel/core@^7.7.5": - version "7.12.3" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.12.3.tgz#1b436884e1e3bff6fb1328dc02b208759de92ad8" - integrity sha512-0qXcZYKZp3/6N2jKYVxZv0aNCsxTSVCiK72DTiTYZAu7sjg73W0/aynWjMbiGd87EQL4WyA8reiJVh92AVla9g== +"@babel/compat-data@^7.12.5", "@babel/compat-data@^7.12.7": + version "7.12.7" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.12.7.tgz#9329b4782a7d6bbd7eef57e11addf91ee3ef1e41" + integrity sha512-YaxPMGs/XIWtYqrdEOZOCPsVWfEoriXopnsz3/i7apYPXQ3698UFhS6dVT1KN5qOsWmVgw/FOrmQgpRaZayGsw== + +"@babel/core@>=7.9.0", "@babel/core@^7.12.1", "@babel/core@^7.12.3", "@babel/core@^7.7.5": + version "7.12.9" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.12.9.tgz#fd450c4ec10cdbb980e2928b7aa7a28484593fc8" + integrity sha512-gTXYh3M5wb7FRXQy+FErKFAv90BnlOuNn1QkCK2lREoPAjrQCO49+HVSrFoe5uakFAF5eenS75KbO2vQiLrTMQ== dependencies: "@babel/code-frame" "^7.10.4" - "@babel/generator" "^7.12.1" + "@babel/generator" "^7.12.5" "@babel/helper-module-transforms" "^7.12.1" - "@babel/helpers" "^7.12.1" - "@babel/parser" "^7.12.3" - "@babel/template" "^7.10.4" - "@babel/traverse" "^7.12.1" - "@babel/types" "^7.12.1" + "@babel/helpers" "^7.12.5" + "@babel/parser" "^7.12.7" + "@babel/template" "^7.12.7" + "@babel/traverse" "^7.12.9" + "@babel/types" "^7.12.7" convert-source-map "^1.7.0" debug "^4.1.0" gensync "^1.0.0-beta.1" @@ -114,77 +119,93 @@ dependencies: eslint-rule-composer "^0.3.0" -"@babel/generator@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.12.1.tgz#0d70be32bdaa03d7c51c8597dda76e0df1f15468" - integrity sha512-DB+6rafIdc9o72Yc3/Ph5h+6hUjeOp66pF0naQBgUFFuPqzQwIlPTm3xZR7YNvduIMtkDIj2t21LSQwnbCrXvg== +"@babel/generator@^7.12.5": + version "7.12.5" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.12.5.tgz#a2c50de5c8b6d708ab95be5e6053936c1884a4de" + integrity sha512-m16TQQJ8hPt7E+OS/XVQg/7U184MLXtvuGbCdA7na61vha+ImkyyNM/9DDA0unYCVZn3ZOhng+qz48/KBOT96A== dependencies: - "@babel/types" "^7.12.1" + "@babel/types" "^7.12.5" jsesc "^2.5.1" source-map "^0.5.0" -"@babel/helper-annotate-as-pure@^7.0.0", "@babel/helper-annotate-as-pure@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.8.3.tgz#60bc0bc657f63a0924ff9a4b4a0b24a13cf4deee" - integrity sha512-6o+mJrZBxOoEX77Ezv9zwW7WV8DdluouRKNY/IR5u/YTMuKHgugHOzYWlYvYLpLA9nPsQCAAASpCIbjI9Mv+Uw== +"@babel/helper-annotate-as-pure@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.4.tgz#5bf0d495a3f757ac3bda48b5bf3b3ba309c72ba3" + integrity sha512-XQlqKQP4vXFB7BN8fEEerrmYvHp3fK/rBkRFz9jaJbzK0B1DSfej9Kc7ZzE8Z/OnId1jpJdNAZ3BFQjWG68rcA== dependencies: - "@babel/types" "^7.8.3" + "@babel/types" "^7.10.4" -"@babel/helper-builder-binary-assignment-operator-visitor@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.1.0.tgz#6b69628dfe4087798e0c4ed98e3d4a6b2fbd2f5f" - integrity sha512-qNSR4jrmJ8M1VMM9tibvyRAHXQs2PmaksQF7c1CGJNipfe3D8p+wgNwgso/P2A2r2mdgBWAXljNWR0QRZAMW8w== +"@babel/helper-builder-binary-assignment-operator-visitor@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.10.4.tgz#bb0b75f31bf98cbf9ff143c1ae578b87274ae1a3" + integrity sha512-L0zGlFrGWZK4PbT8AszSfLTM5sDU1+Az/En9VrdT8/LmEiJt4zXt+Jve9DCAnQcbqDhCI+29y/L93mrDzddCcg== dependencies: - "@babel/helper-explode-assignable-expression" "^7.1.0" - "@babel/types" "^7.0.0" + "@babel/helper-explode-assignable-expression" "^7.10.4" + "@babel/types" "^7.10.4" -"@babel/helper-builder-react-jsx@^7.3.0": - version "7.3.0" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.3.0.tgz#a1ac95a5d2b3e88ae5e54846bf462eeb81b318a4" - integrity sha512-MjA9KgwCuPEkQd9ncSXvSyJ5y+j2sICHyrI0M3L+6fnS4wMSNDc1ARXsbTfbb2cXHn17VisSnU/sHFTCxVxSMw== +"@babel/helper-builder-react-jsx-experimental@^7.12.4": + version "7.12.4" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx-experimental/-/helper-builder-react-jsx-experimental-7.12.4.tgz#55fc1ead5242caa0ca2875dcb8eed6d311e50f48" + integrity sha512-AjEa0jrQqNk7eDQOo0pTfUOwQBMF+xVqrausQwT9/rTKy0g04ggFNaJpaE09IQMn9yExluigWMJcj0WC7bq+Og== dependencies: - "@babel/types" "^7.3.0" - esutils "^2.0.0" + "@babel/helper-annotate-as-pure" "^7.10.4" + "@babel/helper-module-imports" "^7.12.1" + "@babel/types" "^7.12.1" -"@babel/helper-call-delegate@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/helper-call-delegate/-/helper-call-delegate-7.4.4.tgz#87c1f8ca19ad552a736a7a27b1c1fcf8b1ff1f43" - integrity sha512-l79boDFJ8S1c5hvQvG+rc+wHw6IuH7YldmRKsYtpbawsxURu/paVy57FZMomGK22/JckepaikOkY0MoAmdyOlQ== +"@babel/helper-builder-react-jsx@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.10.4.tgz#8095cddbff858e6fa9c326daee54a2f2732c1d5d" + integrity sha512-5nPcIZ7+KKDxT1427oBivl9V9YTal7qk0diccnh7RrcgrT/pGFOjgGw1dgryyx1GvHEpXVfoDF6Ak3rTiWh8Rg== dependencies: - "@babel/helper-hoist-variables" "^7.4.4" - "@babel/traverse" "^7.4.4" - "@babel/types" "^7.4.4" + "@babel/helper-annotate-as-pure" "^7.10.4" + "@babel/types" "^7.10.4" -"@babel/helper-create-class-features-plugin@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.8.3.tgz#5b94be88c255f140fd2c10dd151e7f98f4bff397" - integrity sha512-qmp4pD7zeTxsv0JNecSBsEmG1ei2MqwJq4YQcK3ZWm/0t07QstWfvuV/vm3Qt5xNMFETn2SZqpMx2MQzbtq+KA== +"@babel/helper-compilation-targets@^7.12.5": + version "7.12.5" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.12.5.tgz#cb470c76198db6a24e9dbc8987275631e5d29831" + integrity sha512-+qH6NrscMolUlzOYngSBMIOQpKUGPPsc61Bu5W10mg84LxZ7cmvnBHzARKbDoFxVvqqAbj6Tg6N7bSrWSPXMyw== dependencies: - "@babel/helper-function-name" "^7.8.3" - "@babel/helper-member-expression-to-functions" "^7.8.3" - "@babel/helper-optimise-call-expression" "^7.8.3" - "@babel/helper-plugin-utils" "^7.8.3" - "@babel/helper-replace-supers" "^7.8.3" - "@babel/helper-split-export-declaration" "^7.8.3" + "@babel/compat-data" "^7.12.5" + "@babel/helper-validator-option" "^7.12.1" + browserslist "^4.14.5" + semver "^5.5.0" -"@babel/helper-define-map@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.5.5.tgz#3dec32c2046f37e09b28c93eb0b103fd2a25d369" - integrity sha512-fTfxx7i0B5NJqvUOBBGREnrqbTxRh7zinBANpZXAVDlsZxYdclDp467G1sQ8VZYMnAURY3RpBUAgOYT9GfzHBg== +"@babel/helper-create-class-features-plugin@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.12.1.tgz#3c45998f431edd4a9214c5f1d3ad1448a6137f6e" + integrity sha512-hkL++rWeta/OVOBTRJc9a5Azh5mt5WgZUGAKMD8JM141YsE08K//bp1unBBieO6rUKkIPyUE0USQ30jAy3Sk1w== dependencies: - "@babel/helper-function-name" "^7.1.0" - "@babel/types" "^7.5.5" - lodash "^4.17.13" + "@babel/helper-function-name" "^7.10.4" + "@babel/helper-member-expression-to-functions" "^7.12.1" + "@babel/helper-optimise-call-expression" "^7.10.4" + "@babel/helper-replace-supers" "^7.12.1" + "@babel/helper-split-export-declaration" "^7.10.4" -"@babel/helper-explode-assignable-expression@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.1.0.tgz#537fa13f6f1674df745b0c00ec8fe4e99681c8f6" - integrity sha512-NRQpfHrJ1msCHtKjbzs9YcMmJZOg6mQMmGRB+hbamEdG5PNpaSm95275VD92DvJKuyl0s2sFiDmMZ+EnnvufqA== +"@babel/helper-create-regexp-features-plugin@^7.12.1": + version "7.12.7" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.12.7.tgz#2084172e95443fa0a09214ba1bb328f9aea1278f" + integrity sha512-idnutvQPdpbduutvi3JVfEgcVIHooQnhvhx0Nk9isOINOIGYkZea1Pk2JlJRiUnMefrlvr0vkByATBY/mB4vjQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.10.4" + regexpu-core "^4.7.1" + +"@babel/helper-define-map@^7.10.4": + version "7.10.5" + resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.10.5.tgz#b53c10db78a640800152692b13393147acb9bb30" + integrity sha512-fMw4kgFB720aQFXSVaXr79pjjcW5puTCM16+rECJ/plGS+zByelE8l9nCpV1GibxTnFVmUuYG9U8wYfQHdzOEQ== dependencies: - "@babel/traverse" "^7.1.0" - "@babel/types" "^7.0.0" + "@babel/helper-function-name" "^7.10.4" + "@babel/types" "^7.10.5" + lodash "^4.17.19" -"@babel/helper-function-name@^7.1.0", "@babel/helper-function-name@^7.10.4", "@babel/helper-function-name@^7.8.3": +"@babel/helper-explode-assignable-expression@^7.10.4": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.12.1.tgz#8006a466695c4ad86a2a5f2fb15b5f2c31ad5633" + integrity sha512-dmUwH8XmlrUpVqgtZ737tK88v07l840z9j3OEhCLwKTkjlvKpfqXVIZ0wpK3aeOxspwGrf/5AP5qLx4rO3w5rA== + dependencies: + "@babel/types" "^7.12.1" + +"@babel/helper-function-name@^7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz#d2d3b20c59ad8c47112fa7d2a94bc09d5ef82f1a" integrity sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ== @@ -193,35 +214,35 @@ "@babel/template" "^7.10.4" "@babel/types" "^7.10.4" -"@babel/helper-get-function-arity@^7.0.0", "@babel/helper-get-function-arity@^7.10.4": +"@babel/helper-get-function-arity@^7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz#98c1cbea0e2332f33f9a4661b8ce1505b2c19ba2" integrity sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A== dependencies: "@babel/types" "^7.10.4" -"@babel/helper-hoist-variables@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.4.4.tgz#0298b5f25c8c09c53102d52ac4a98f773eb2850a" - integrity sha512-VYk2/H/BnYbZDDg39hr3t2kKyifAm1W6zHRfhx8jGjIHpQEBv9dry7oQ2f3+J703TLu69nYdxsovl0XYfcnK4w== +"@babel/helper-hoist-variables@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.10.4.tgz#d49b001d1d5a68ca5e6604dda01a6297f7c9381e" + integrity sha512-wljroF5PgCk2juF69kanHVs6vrLwIPNp6DLD+Lrl3hoQ3PpPPikaDRNFA+0t81NOoMt2DL6WW/mdU8k4k6ZzuA== dependencies: - "@babel/types" "^7.4.4" + "@babel/types" "^7.10.4" -"@babel/helper-member-expression-to-functions@^7.12.1", "@babel/helper-member-expression-to-functions@^7.8.3": +"@babel/helper-member-expression-to-functions@^7.12.1": version "7.12.1" resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.1.tgz#fba0f2fcff3fba00e6ecb664bb5e6e26e2d6165c" integrity sha512-k0CIe3tXUKTRSoEx1LQEPFU9vRQfqHtl+kf8eNnDqb4AUJEy5pz6aIiog+YWtVm2jpggjS1laH68bPsR+KWWPQ== dependencies: "@babel/types" "^7.12.1" -"@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.12.1.tgz#1644c01591a15a2f084dd6d092d9430eb1d1216c" - integrity sha512-ZeC1TlMSvikvJNy1v/wPIazCu3NdOwgYZLIkmIyAsGhqkNpiDoQQRmaCK8YP4Pq3GPTLPV9WXaPCJKvx06JxKA== +"@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.12.1", "@babel/helper-module-imports@^7.12.5": + version "7.12.5" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz#1bfc0229f794988f76ed0a4d4e90860850b54dfb" + integrity sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA== dependencies: - "@babel/types" "^7.12.1" + "@babel/types" "^7.12.5" -"@babel/helper-module-transforms@^7.1.0", "@babel/helper-module-transforms@^7.12.1", "@babel/helper-module-transforms@^7.4.4": +"@babel/helper-module-transforms@^7.12.1": version "7.12.1" resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.12.1.tgz#7954fec71f5b32c48e4b303b437c34453fd7247c" integrity sha512-QQzehgFAZ2bbISiCpmVGfiGux8YVFXQ0abBic2Envhej22DVXV9nCFaS5hIQbkyo1AdGb+gNME2TSh3hYJVV/w== @@ -236,7 +257,7 @@ "@babel/types" "^7.12.1" lodash "^4.17.19" -"@babel/helper-optimise-call-expression@^7.0.0", "@babel/helper-optimise-call-expression@^7.10.4", "@babel/helper-optimise-call-expression@^7.8.3": +"@babel/helper-optimise-call-expression@^7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.4.tgz#50dc96413d594f995a77905905b05893cd779673" integrity sha512-n3UGKY4VXwXThEiKrgRAoVPBMqeoPgHVqiHZOanAJCG9nQUL2pLRQirUzl0ioKclHGpGqRgIOkgcIJaIWLpygg== @@ -248,25 +269,16 @@ resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz#2f75a831269d4f677de49986dff59927533cf375" integrity sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg== -"@babel/helper-regex@^7.0.0", "@babel/helper-regex@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.4.4.tgz#a47e02bc91fb259d2e6727c2a30013e3ac13c4a2" - integrity sha512-Y5nuB/kESmR3tKjU8Nkn1wMGEx1tjJX076HBMeL3XLQCu6vA/YRzuTW0bbb+qRnXvQGn+d6Rx953yffl8vEy7Q== - dependencies: - lodash "^4.17.11" - -"@babel/helper-remap-async-to-generator@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.1.0.tgz#361d80821b6f38da75bd3f0785ece20a88c5fe7f" - integrity sha512-3fOK0L+Fdlg8S5al8u/hWE6vhufGSn0bN09xm2LXMy//REAF8kDCrYoOBKYmA8m5Nom+sV9LyLCwrFynA8/slg== +"@babel/helper-remap-async-to-generator@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.12.1.tgz#8c4dbbf916314f6047dc05e6a2217074238347fd" + integrity sha512-9d0KQCRM8clMPcDwo8SevNs+/9a8yWVVmaE80FGJcEP8N1qToREmWEGnBn8BUlJhYRFz6fqxeRL1sl5Ogsed7A== dependencies: - "@babel/helper-annotate-as-pure" "^7.0.0" - "@babel/helper-wrap-function" "^7.1.0" - "@babel/template" "^7.1.0" - "@babel/traverse" "^7.1.0" - "@babel/types" "^7.0.0" + "@babel/helper-annotate-as-pure" "^7.10.4" + "@babel/helper-wrap-function" "^7.10.4" + "@babel/types" "^7.12.1" -"@babel/helper-replace-supers@^7.12.1", "@babel/helper-replace-supers@^7.5.5", "@babel/helper-replace-supers@^7.8.3": +"@babel/helper-replace-supers@^7.12.1": version "7.12.1" resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.12.1.tgz#f15c9cc897439281891e11d5ce12562ac0cf3fa9" integrity sha512-zJjTvtNJnCFsCXVi5rUInstLd/EIVNmIKA1Q9ynESmMBWPWd+7sdR+G4/wdu+Mppfep0XLyG2m7EBPvjCeFyrw== @@ -276,14 +288,21 @@ "@babel/traverse" "^7.12.1" "@babel/types" "^7.12.1" -"@babel/helper-simple-access@^7.1.0", "@babel/helper-simple-access@^7.12.1": +"@babel/helper-simple-access@^7.12.1": version "7.12.1" resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.12.1.tgz#32427e5aa61547d38eb1e6eaf5fd1426fdad9136" integrity sha512-OxBp7pMrjVewSSC8fXDFrHrBcJATOOFssZwv16F3/6Xtc138GHybBfPbm9kfiqQHKhYQrlamWILwlDCeyMFEaA== dependencies: "@babel/types" "^7.12.1" -"@babel/helper-split-export-declaration@^7.11.0", "@babel/helper-split-export-declaration@^7.4.4", "@babel/helper-split-export-declaration@^7.8.3": +"@babel/helper-skip-transparent-expression-wrappers@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.12.1.tgz#462dc63a7e435ade8468385c63d2b84cce4b3cbf" + integrity sha512-Mf5AUuhG1/OCChOJ/HcADmvcHM42WJockombn8ATJG3OnyiSxBK/Mm5x78BQWvmtXZKHgbjdGL2kin/HOLlZGA== + dependencies: + "@babel/types" "^7.12.1" + +"@babel/helper-split-export-declaration@^7.10.4", "@babel/helper-split-export-declaration@^7.11.0": version "7.11.0" resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz#f8a491244acf6a676158ac42072911ba83ad099f" integrity sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg== @@ -295,26 +314,31 @@ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz#a78c7a7251e01f616512d31b10adcf52ada5e0d2" integrity sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw== -"@babel/helper-wrap-function@^7.1.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.2.0.tgz#c4e0012445769e2815b55296ead43a958549f6fa" - integrity sha512-o9fP1BZLLSrYlxYEYyl2aS+Flun5gtjTIG8iln+XuEzQTs0PLagAGSXUcqruJwD5fM48jzIEggCKpIfWTcR7pQ== +"@babel/helper-validator-option@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.12.1.tgz#175567380c3e77d60ff98a54bb015fe78f2178d9" + integrity sha512-YpJabsXlJVWP0USHjnC/AQDTLlZERbON577YUVO/wLpqyj6HAtVYnWaQaN0iUN+1/tWn3c+uKKXjRut5115Y2A== + +"@babel/helper-wrap-function@^7.10.4": + version "7.12.3" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.12.3.tgz#3332339fc4d1fbbf1c27d7958c27d34708e990d9" + integrity sha512-Cvb8IuJDln3rs6tzjW3Y8UeelAOdnpB8xtQ4sme2MSZ9wOxrbThporC0y/EtE16VAtoyEfLM404Xr1e0OOp+ow== dependencies: - "@babel/helper-function-name" "^7.1.0" - "@babel/template" "^7.1.0" - "@babel/traverse" "^7.1.0" - "@babel/types" "^7.2.0" + "@babel/helper-function-name" "^7.10.4" + "@babel/template" "^7.10.4" + "@babel/traverse" "^7.10.4" + "@babel/types" "^7.10.4" -"@babel/helpers@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.12.1.tgz#8a8261c1d438ec18cb890434df4ec768734c1e79" - integrity sha512-9JoDSBGoWtmbay98efmT2+mySkwjzeFeAL9BuWNoVQpkPFQF8SIIFUfY5os9u8wVzglzoiPRSW7cuJmBDUt43g== +"@babel/helpers@^7.12.5": + version "7.12.5" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.12.5.tgz#1a1ba4a768d9b58310eda516c449913fe647116e" + integrity sha512-lgKGMQlKqA8meJqKsW6rUnc4MdUk35Ln0ATDqdM1a/UpARODdI4j5Y5lVfUScnSNkJcdCRAaWkspykNoFg9sJA== dependencies: "@babel/template" "^7.10.4" - "@babel/traverse" "^7.12.1" - "@babel/types" "^7.12.1" + "@babel/traverse" "^7.12.5" + "@babel/types" "^7.12.5" -"@babel/highlight@^7.0.0", "@babel/highlight@^7.10.4": +"@babel/highlight@^7.10.4", "@babel/highlight@^7.8.3": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.10.4.tgz#7d1bdfd65753538fabe6c38596cdb76d9ac60143" integrity sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA== @@ -323,119 +347,204 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.10.4", "@babel/parser@^7.12.1", "@babel/parser@^7.12.3", "@babel/parser@^7.7.5": - version "7.12.3" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.12.3.tgz#a305415ebe7a6c7023b40b5122a0662d928334cd" - integrity sha512-kFsOS0IbsuhO5ojF8Hc8z/8vEIOkylVBrjiZUbLTE3XFe0Qi+uu6HjzQixkFaqr0ZPAMZcBVxEwmsnsLPZ2Xsw== +"@babel/parser@^7.12.7", "@babel/parser@^7.7.5": + version "7.12.7" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.12.7.tgz#fee7b39fe809d0e73e5b25eecaf5780ef3d73056" + integrity sha512-oWR02Ubp4xTLCAqPRiNIuMVgNO5Aif/xpXtabhzW2HWUD47XJsAB4Zd/Rg30+XeQA3juXigV7hlquOTmwqLiwg== -"@babel/plugin-proposal-async-generator-functions@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.2.0.tgz#b289b306669dce4ad20b0252889a15768c9d417e" - integrity sha512-+Dfo/SCQqrwx48ptLVGLdE39YtWRuKc/Y9I5Fy0P1DDBB9lsAHpjcEJQt+4IifuSOSTLBKJObJqMvaO1pIE8LQ== +"@babel/plugin-proposal-async-generator-functions@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.12.1.tgz#dc6c1170e27d8aca99ff65f4925bd06b1c90550e" + integrity sha512-d+/o30tJxFxrA1lhzJqiUcEJdI6jKlNregCv5bASeGf2Q4MXmnwH7viDo7nhx1/ohf09oaH8j1GVYG/e3Yqk6A== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-remap-async-to-generator" "^7.1.0" - "@babel/plugin-syntax-async-generators" "^7.2.0" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-remap-async-to-generator" "^7.12.1" + "@babel/plugin-syntax-async-generators" "^7.8.0" -"@babel/plugin-proposal-class-properties@^7.5.5", "@babel/plugin-proposal-class-properties@^7.7.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.8.3.tgz#5e06654af5cd04b608915aada9b2a6788004464e" - integrity sha512-EqFhbo7IosdgPgZggHaNObkmO1kNUe3slaKu54d5OWvy+p9QIKOzK1GAEpAIsZtWVtPXUHSMcT4smvDrCfY4AA== +"@babel/plugin-proposal-class-properties@^7.12.1", "@babel/plugin-proposal-class-properties@^7.5.5": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.12.1.tgz#a082ff541f2a29a4821065b8add9346c0c16e5de" + integrity sha512-cKp3dlQsFsEs5CWKnN7BnSHOd0EOW8EKpEjkoz1pO2E5KzIDNV9Ros1b0CnmbVgAGXJubOYVBOGCT1OmJwOI7w== dependencies: - "@babel/helper-create-class-features-plugin" "^7.8.3" - "@babel/helper-plugin-utils" "^7.8.3" + "@babel/helper-create-class-features-plugin" "^7.12.1" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-proposal-dynamic-import@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.5.0.tgz#e532202db4838723691b10a67b8ce509e397c506" - integrity sha512-x/iMjggsKTFHYC6g11PL7Qy58IK8H5zqfm9e6hu4z1iH2IRyAp9u9dL80zA6R76yFovETFLKz2VJIC2iIPBuFw== +"@babel/plugin-proposal-decorators@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.12.1.tgz#59271439fed4145456c41067450543aee332d15f" + integrity sha512-knNIuusychgYN8fGJHONL0RbFxLGawhXOJNLBk75TniTsZZeA+wdkDuv6wp4lGwzQEKjZi6/WYtnb3udNPmQmQ== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-dynamic-import" "^7.2.0" + "@babel/helper-create-class-features-plugin" "^7.12.1" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-decorators" "^7.12.1" -"@babel/plugin-proposal-json-strings@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.2.0.tgz#568ecc446c6148ae6b267f02551130891e29f317" - integrity sha512-MAFV1CA/YVmYwZG0fBQyXhmj0BHCB5egZHCKWIFVv/XCxAeVGIHfos3SwDck4LvCllENIAg7xMKOG5kH0dzyUg== +"@babel/plugin-proposal-dynamic-import@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.12.1.tgz#43eb5c2a3487ecd98c5c8ea8b5fdb69a2749b2dc" + integrity sha512-a4rhUSZFuq5W8/OO8H7BL5zspjnc1FLd9hlOxIK/f7qG4a0qsqk8uvF/ywgBA8/OmjsapjpvaEOYItfGG1qIvQ== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-json-strings" "^7.2.0" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-dynamic-import" "^7.8.0" -"@babel/plugin-proposal-nullish-coalescing-operator@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.10.4.tgz#02a7e961fc32e6d5b2db0649e01bf80ddee7e04a" - integrity sha512-wq5n1M3ZUlHl9sqT2ok1T2/MTt6AXE0e1Lz4WzWBr95LsAZ5qDXe4KnFuauYyEyLiohvXFMdbsOTMyLZs91Zlw== +"@babel/plugin-proposal-export-default-from@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.12.1.tgz#c6e62d668a8abcfe0d28b82f560395fecb611c5a" + integrity sha512-z5Q4Ke7j0AexQRfgUvnD+BdCSgpTEKnqQ3kskk2jWtOBulxICzd1X9BGt7kmWftxZ2W3++OZdt5gtmC8KLxdRQ== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-export-default-from" "^7.12.1" + +"@babel/plugin-proposal-export-namespace-from@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.12.1.tgz#8b9b8f376b2d88f5dd774e4d24a5cc2e3679b6d4" + integrity sha512-6CThGf0irEkzujYS5LQcjBx8j/4aQGiVv7J9+2f7pGfxqyKh3WnmVJYW3hdrQjyksErMGBPQrCnHfOtna+WLbw== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + +"@babel/plugin-proposal-json-strings@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.12.1.tgz#d45423b517714eedd5621a9dfdc03fa9f4eb241c" + integrity sha512-GoLDUi6U9ZLzlSda2Df++VSqDJg3CG+dR0+iWsv6XRw1rEq+zwt4DirM9yrxW6XWaTpmai1cWJLMfM8qQJf+yw== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-json-strings" "^7.8.0" + +"@babel/plugin-proposal-logical-assignment-operators@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.12.1.tgz#f2c490d36e1b3c9659241034a5d2cd50263a2751" + integrity sha512-k8ZmVv0JU+4gcUGeCDZOGd0lCIamU/sMtIiX3UWnUc5yzgq6YUGyEolNYD+MLYKfSzgECPcqetVcJP9Afe/aCA== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + +"@babel/plugin-proposal-nullish-coalescing-operator@^7.10.4", "@babel/plugin-proposal-nullish-coalescing-operator@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.12.1.tgz#3ed4fff31c015e7f3f1467f190dbe545cd7b046c" + integrity sha512-nZY0ESiaQDI1y96+jk6VxMOaL4LPo/QDHBqL+SF3/vl6dHkTwHlOI8L4ZwuRBHgakRBw5zsVylel7QPbbGuYgg== dependencies: "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0" -"@babel/plugin-proposal-object-rest-spread@^7.5.5", "@babel/plugin-proposal-object-rest-spread@^7.6.2": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.8.3.tgz#eb5ae366118ddca67bed583b53d7554cad9951bb" - integrity sha512-8qvuPwU/xxUCt78HocNlv0mXXo0wdh9VT1R04WU8HGOfaOob26pF+9P5/lYjN/q7DHOX1bvX60hnhOvuQUJdbA== +"@babel/plugin-proposal-numeric-separator@^7.12.7": + version "7.12.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.7.tgz#8bf253de8139099fea193b297d23a9d406ef056b" + integrity sha512-8c+uy0qmnRTeukiGsjLGy6uVs/TFjJchGXUeBqlG4VWYOdJWkhhVPdQ3uHwbmalfJwv2JsV0qffXP4asRfL2SQ== dependencies: - "@babel/helper-plugin-utils" "^7.8.3" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + +"@babel/plugin-proposal-object-rest-spread@^7.12.1", "@babel/plugin-proposal-object-rest-spread@^7.5.5": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.12.1.tgz#def9bd03cea0f9b72283dac0ec22d289c7691069" + integrity sha512-s6SowJIjzlhx8o7lsFx5zmY4At6CTtDvgNQDdPzkBQucle58A6b/TTeEBYtyDgmcXjUTM+vE8YOGHZzzbc/ioA== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-object-rest-spread" "^7.8.0" + "@babel/plugin-transform-parameters" "^7.12.1" -"@babel/plugin-proposal-optional-catch-binding@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.2.0.tgz#135d81edb68a081e55e56ec48541ece8065c38f5" - integrity sha512-mgYj3jCcxug6KUcX4OBoOJz3CMrwRfQELPQ5560F70YQUBZB7uac9fqaWamKR1iWUzGiK2t0ygzjTScZnVz75g== +"@babel/plugin-proposal-optional-catch-binding@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.12.1.tgz#ccc2421af64d3aae50b558a71cede929a5ab2942" + integrity sha512-hFvIjgprh9mMw5v42sJWLI1lzU5L2sznP805zeT6rySVRA0Y18StRhDqhSxlap0oVgItRsB6WSROp4YnJTJz0g== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-optional-catch-binding" "^7.2.0" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.0" -"@babel/plugin-proposal-optional-chaining@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.8.3.tgz#ae10b3214cb25f7adb1f3bc87ba42ca10b7e2543" - integrity sha512-QIoIR9abkVn+seDE3OjA08jWcs3eZ9+wJCKSRgo3WdEU2csFYgdScb+8qHB3+WXsGJD55u+5hWCISI7ejXS+kg== +"@babel/plugin-proposal-optional-chaining@^7.12.1", "@babel/plugin-proposal-optional-chaining@^7.12.7", "@babel/plugin-proposal-optional-chaining@^7.8.3": + version "7.12.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.12.7.tgz#e02f0ea1b5dc59d401ec16fb824679f683d3303c" + integrity sha512-4ovylXZ0PWmwoOvhU2vhnzVNnm88/Sm9nx7V8BPgMvAzn5zDou3/Awy0EjglyubVHasJj+XCEkr/r1X3P5elCA== dependencies: - "@babel/helper-plugin-utils" "^7.8.3" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-skip-transparent-expression-wrappers" "^7.12.1" "@babel/plugin-syntax-optional-chaining" "^7.8.0" -"@babel/plugin-proposal-unicode-property-regex@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.4.4.tgz#501ffd9826c0b91da22690720722ac7cb1ca9c78" - integrity sha512-j1NwnOqMG9mFUOH58JTFsA/+ZYzQLUZ/drqWUqxCYLGeu2JFZL8YrNC9hBxKmWtAuOCHPcRpgv7fhap09Fb4kA== +"@babel/plugin-proposal-private-methods@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.12.1.tgz#86814f6e7a21374c980c10d38b4493e703f4a389" + integrity sha512-mwZ1phvH7/NHK6Kf8LP7MYDogGV+DKB1mryFOEwx5EBNQrosvIczzZFTUmWaeujd5xT6G1ELYWUz3CutMhjE1w== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-regex" "^7.4.4" - regexpu-core "^4.5.4" + "@babel/helper-create-class-features-plugin" "^7.12.1" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-syntax-async-generators@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.2.0.tgz#69e1f0db34c6f5a0cf7e2b3323bf159a76c8cb7f" - integrity sha512-1ZrIRBv2t0GSlcwVoQ6VgSLpLgiN/FVQUzt9znxo7v2Ov4jJrs8RY8tv0wvDmFN3qIdMKWrmMMW6yZ0G19MfGg== +"@babel/plugin-proposal-unicode-property-regex@^7.12.1", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.12.1.tgz#2a183958d417765b9eae334f47758e5d6a82e072" + integrity sha512-MYq+l+PvHuw/rKUz1at/vb6nCnQ2gmJBNaM62z0OgH7B2W1D9pvkpYtlti9bGtizNIU1K3zm4bZF9F91efVY0w== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-create-regexp-features-plugin" "^7.12.1" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-syntax-dynamic-import@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.2.0.tgz#69c159ffaf4998122161ad8ebc5e6d1f55df8612" - integrity sha512-mVxuJ0YroI/h/tbFTPGZR8cv6ai+STMKNBq0f8hFxsxWjl94qqhsb+wXbpNMDPU3cfR1TIsVFzU3nXyZMqyK4w== +"@babel/plugin-syntax-async-generators@^7.8.0": + version "7.8.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" + integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-flow@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.2.0.tgz#a765f061f803bc48f240c26f8747faf97c26bf7c" - integrity sha512-r6YMuZDWLtLlu0kqIim5o/3TNRAlWb073HwT3e2nKf9I8IIvOggPrnILYPsrrKilmn/mYEMCf/Z07w3yQJF6dg== +"@babel/plugin-syntax-class-properties@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.1.tgz#bcb297c5366e79bebadef509549cd93b04f19978" + integrity sha512-U40A76x5gTwmESz+qiqssqmeEsKvcSyvtgktrm0uzcARAmM9I1jR221f6Oq+GmHrcD+LvZDag1UTOTe2fL3TeA== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-syntax-json-strings@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.2.0.tgz#72bd13f6ffe1d25938129d2a186b11fd62951470" - integrity sha512-5UGYnMSLRE1dqqZwug+1LISpA403HzlSfsg6P9VXU6TBjcSHeNlw4DxDx7LgpF+iKZoOG/+uzqoRHTdcUpiZNg== +"@babel/plugin-syntax-decorators@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.12.1.tgz#81a8b535b284476c41be6de06853a8802b98c5dd" + integrity sha512-ir9YW5daRrTYiy9UJ2TzdNIJEZu8KclVzDcfSt4iEmOtwQ4llPtWInNKJyKnVXp1vE4bbVd5S31M/im3mYMO1w== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-syntax-jsx@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.2.0.tgz#0b85a3b4bc7cdf4cc4b8bf236335b907ca22e7c7" - integrity sha512-VyN4QANJkRW6lDBmENzRszvZf3/4AXaj9YR7GwrWeeN9tEBPuXbmDYVU9bYBN0D70zCWVwUy0HWq2553VCb6Hw== +"@babel/plugin-syntax-dynamic-import@^7.8.0", "@babel/plugin-syntax-dynamic-import@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" + integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-export-default-from@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.12.1.tgz#a9eb31881f4f9a1115a3d2c6d64ac3f6016b5a9d" + integrity sha512-dP5eGg6tHEkhnRD2/vRG/KJKRSg8gtxu2i+P/8/yFPJn/CfPU5G0/7Gks2i3M6IOVAPQekmsLN9LPsmXFFL4Uw== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-export-namespace-from@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz#028964a9ba80dbc094c915c487ad7c4e7a66465a" + integrity sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-syntax-flow@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.12.1.tgz#a77670d9abe6d63e8acadf4c31bb1eb5a506bbdd" + integrity sha512-1lBLLmtxrwpm4VKmtVFselI/P3pX+G63fAtUUt6b2Nzgao77KNDwyuRt90Mj2/9pKobtt68FdvjfqohZjg/FCA== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-json-strings@^7.8.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" + integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-jsx@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.12.1.tgz#9d9d357cc818aa7ae7935917c1257f67677a0926" + integrity sha512-1yRi7yAtB0ETgxdY9ti/p2TivUxJkTdhu/ZbF9MshVGqOx1TdB3b7xCXs49Fupgg50N45KcAsRP/ZqWjs9SRjg== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-logical-assignment-operators@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" + integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-nullish-coalescing-operator@^7.8.0": version "7.8.3" @@ -444,19 +553,26 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-object-rest-spread@^7.2.0", "@babel/plugin-syntax-object-rest-spread@^7.8.0": +"@babel/plugin-syntax-numeric-separator@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" + integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-object-rest-spread@^7.8.0": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-optional-catch-binding@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.2.0.tgz#a94013d6eda8908dfe6a477e7f9eda85656ecf5c" - integrity sha512-bDe4xKNhb0LI7IvZHiA13kff0KEfaGX/Hv4lMA9+7TEc63hMNvfKo6ZFpXhKuEp+II/q35Gc4NoMeDZyaUbj9w== +"@babel/plugin-syntax-optional-catch-binding@^7.8.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" + integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.8.0" "@babel/plugin-syntax-optional-chaining@^7.8.0": version "7.8.3" @@ -465,253 +581,273 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-transform-arrow-functions@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.2.0.tgz#9aeafbe4d6ffc6563bf8f8372091628f00779550" - integrity sha512-ER77Cax1+8/8jCB9fo4Ud161OZzWN5qawi4GusDuRLcDbDG+bIGYY20zb2dfAFdTRGzrfq2xZPvF0R64EHnimg== +"@babel/plugin-syntax-top-level-await@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.1.tgz#dd6c0b357ac1bb142d98537450a319625d13d2a0" + integrity sha512-i7ooMZFS+a/Om0crxZodrTzNEPJHZrlMVGMTEpFAj6rYY/bKCddB0Dk/YxfPuYXOopuhKk/e1jV6h+WUU9XN3A== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-async-to-generator@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.5.0.tgz#89a3848a0166623b5bc481164b5936ab947e887e" - integrity sha512-mqvkzwIGkq0bEF1zLRRiTdjfomZJDV33AH3oQzHVGkI2VzEmXLpKKOBvEVaFZBJdN0XTyH38s9j/Kiqr68dggg== +"@babel/plugin-syntax-typescript@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.12.1.tgz#460ba9d77077653803c3dd2e673f76d66b4029e5" + integrity sha512-UZNEcCY+4Dp9yYRCAHrHDU+9ZXLYaY9MgBXSRLkB9WjYFRR6quJBumfVrEkUxrePPBwFcpWfNKXqVRQQtm7mMA== dependencies: - "@babel/helper-module-imports" "^7.0.0" - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-remap-async-to-generator" "^7.1.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-block-scoped-functions@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.2.0.tgz#5d3cc11e8d5ddd752aa64c9148d0db6cb79fd190" - integrity sha512-ntQPR6q1/NKuphly49+QiQiTN0O63uOwjdD6dhIjSWBI5xlrbUFh720TIpzBhpnrLfv2tNH/BXvLIab1+BAI0w== +"@babel/plugin-transform-arrow-functions@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.12.1.tgz#8083ffc86ac8e777fbe24b5967c4b2521f3cb2b3" + integrity sha512-5QB50qyN44fzzz4/qxDPQMBCTHgxg3n0xRBLJUmBlLoU/sFvxVWGZF/ZUfMVDQuJUKXaBhbupxIzIfZ6Fwk/0A== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-block-scoping@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.5.5.tgz#a35f395e5402822f10d2119f6f8e045e3639a2ce" - integrity sha512-82A3CLRRdYubkG85lKwhZB0WZoHxLGsJdux/cOVaJCJpvYFl1LVzAIFyRsa7CvXqW8rBM4Zf3Bfn8PHt5DP0Sg== +"@babel/plugin-transform-async-to-generator@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.12.1.tgz#3849a49cc2a22e9743cbd6b52926d30337229af1" + integrity sha512-SDtqoEcarK1DFlRJ1hHRY5HvJUj5kX4qmtpMAm2QnhOlyuMC4TMdCRgW6WXpv93rZeYNeLP22y8Aq2dbcDRM1A== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - lodash "^4.17.13" + "@babel/helper-module-imports" "^7.12.1" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-remap-async-to-generator" "^7.12.1" -"@babel/plugin-transform-classes@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.5.5.tgz#d094299d9bd680a14a2a0edae38305ad60fb4de9" - integrity sha512-U2htCNK/6e9K7jGyJ++1p5XRU+LJjrwtoiVn9SzRlDT2KubcZ11OOwy3s24TjHxPgxNwonCYP7U2K51uVYCMDg== +"@babel/plugin-transform-block-scoped-functions@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.12.1.tgz#f2a1a365bde2b7112e0a6ded9067fdd7c07905d9" + integrity sha512-5OpxfuYnSgPalRpo8EWGPzIYf0lHBWORCkj5M0oLBwHdlux9Ri36QqGW3/LR13RSVOAoUUMzoPI/jpE4ABcHoA== dependencies: - "@babel/helper-annotate-as-pure" "^7.0.0" - "@babel/helper-define-map" "^7.5.5" - "@babel/helper-function-name" "^7.1.0" - "@babel/helper-optimise-call-expression" "^7.0.0" - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-replace-supers" "^7.5.5" - "@babel/helper-split-export-declaration" "^7.4.4" + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-block-scoping@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.12.1.tgz#f0ee727874b42a208a48a586b84c3d222c2bbef1" + integrity sha512-zJyAC9sZdE60r1nVQHblcfCj29Dh2Y0DOvlMkcqSo0ckqjiCwNiUezUKw+RjOCwGfpLRwnAeQ2XlLpsnGkvv9w== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-classes@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.12.1.tgz#65e650fcaddd3d88ddce67c0f834a3d436a32db6" + integrity sha512-/74xkA7bVdzQTBeSUhLLJgYIcxw/dpEpCdRDiHgPJ3Mv6uC11UhjpOhl72CgqbBCmt1qtssCyB2xnJm1+PFjog== + dependencies: + "@babel/helper-annotate-as-pure" "^7.10.4" + "@babel/helper-define-map" "^7.10.4" + "@babel/helper-function-name" "^7.10.4" + "@babel/helper-optimise-call-expression" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-replace-supers" "^7.12.1" + "@babel/helper-split-export-declaration" "^7.10.4" globals "^11.1.0" -"@babel/plugin-transform-computed-properties@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.2.0.tgz#83a7df6a658865b1c8f641d510c6f3af220216da" - integrity sha512-kP/drqTxY6Xt3NNpKiMomfgkNn4o7+vKxK2DDKcBG9sHj51vHqMBGy8wbDS/J4lMxnqs153/T3+DmCEAkC5cpA== +"@babel/plugin-transform-computed-properties@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.12.1.tgz#d68cf6c9b7f838a8a4144badbe97541ea0904852" + integrity sha512-vVUOYpPWB7BkgUWPo4C44mUQHpTZXakEqFjbv8rQMg7TC6S6ZhGZ3otQcRH6u7+adSlE5i0sp63eMC/XGffrzg== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-destructuring@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.5.0.tgz#f6c09fdfe3f94516ff074fe877db7bc9ef05855a" - integrity sha512-YbYgbd3TryYYLGyC7ZR+Tq8H/+bCmwoaxHfJHupom5ECstzbRLTch6gOQbhEY9Z4hiCNHEURgq06ykFv9JZ/QQ== +"@babel/plugin-transform-destructuring@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.12.1.tgz#b9a570fe0d0a8d460116413cb4f97e8e08b2f847" + integrity sha512-fRMYFKuzi/rSiYb2uRLiUENJOKq4Gnl+6qOv5f8z0TZXg3llUwUhsNNwrwaT/6dUhJTzNpBr+CUvEWBtfNY1cw== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-dotall-regex@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.4.4.tgz#361a148bc951444312c69446d76ed1ea8e4450c3" - integrity sha512-P05YEhRc2h53lZDjRPk/OektxCVevFzZs2Gfjd545Wde3k+yFDbXORgl2e0xpbq8mLcKJ7Idss4fAg0zORN/zg== +"@babel/plugin-transform-dotall-regex@^7.12.1", "@babel/plugin-transform-dotall-regex@^7.4.4": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.12.1.tgz#a1d16c14862817b6409c0a678d6f9373ca9cd975" + integrity sha512-B2pXeRKoLszfEW7J4Hg9LoFaWEbr/kzo3teWHmtFCszjRNa/b40f9mfeqZsIDLLt/FjwQ6pz/Gdlwy85xNckBA== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-regex" "^7.4.4" - regexpu-core "^4.5.4" + "@babel/helper-create-regexp-features-plugin" "^7.12.1" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-duplicate-keys@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.5.0.tgz#c5dbf5106bf84cdf691222c0974c12b1df931853" - integrity sha512-igcziksHizyQPlX9gfSjHkE2wmoCH3evvD2qR5w29/Dk0SMKE/eOI7f1HhBdNhR/zxJDqrgpoDTq5YSLH/XMsQ== +"@babel/plugin-transform-duplicate-keys@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.12.1.tgz#745661baba295ac06e686822797a69fbaa2ca228" + integrity sha512-iRght0T0HztAb/CazveUpUQrZY+aGKKaWXMJ4uf9YJtqxSUe09j3wteztCUDRHs+SRAL7yMuFqUsLoAKKzgXjw== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-exponentiation-operator@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.2.0.tgz#a63868289e5b4007f7054d46491af51435766008" - integrity sha512-umh4hR6N7mu4Elq9GG8TOu9M0bakvlsREEC+ialrQN6ABS4oDQ69qJv1VtR3uxlKMCQMCvzk7vr17RHKcjx68A== +"@babel/plugin-transform-exponentiation-operator@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.12.1.tgz#b0f2ed356ba1be1428ecaf128ff8a24f02830ae0" + integrity sha512-7tqwy2bv48q+c1EHbXK0Zx3KXd2RVQp6OC7PbwFNt/dPTAV3Lu5sWtWuAj8owr5wqtWnqHfl2/mJlUmqkChKug== dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor" "^7.1.0" - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-flow-strip-types@^7.0.0": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.4.4.tgz#d267a081f49a8705fc9146de0768c6b58dccd8f7" - integrity sha512-WyVedfeEIILYEaWGAUWzVNyqG4sfsNooMhXWsu/YzOvVGcsnPb5PguysjJqI3t3qiaYj0BR8T2f5njdjTGe44Q== +"@babel/plugin-transform-flow-strip-types@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.12.1.tgz#8430decfa7eb2aea5414ed4a3fa6e1652b7d77c4" + integrity sha512-8hAtkmsQb36yMmEtk2JZ9JnVyDSnDOdlB+0nEGzIDLuK4yR3JcEjfuFPYkdEPSh8Id+rAMeBEn+X0iVEyho6Hg== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-flow" "^7.2.0" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-flow" "^7.12.1" -"@babel/plugin-transform-for-of@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.4.4.tgz#0267fc735e24c808ba173866c6c4d1440fc3c556" - integrity sha512-9T/5Dlr14Z9TIEXLXkt8T1DU7F24cbhwhMNUziN3hB1AXoZcdzPcTiKGRn/6iOymDqtTKWnr/BtRKN9JwbKtdQ== +"@babel/plugin-transform-for-of@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.12.1.tgz#07640f28867ed16f9511c99c888291f560921cfa" + integrity sha512-Zaeq10naAsuHo7heQvyV0ptj4dlZJwZgNAtBYBnu5nNKJoW62m0zKcIEyVECrUKErkUkg6ajMy4ZfnVZciSBhg== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-function-name@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.4.4.tgz#e1436116abb0610c2259094848754ac5230922ad" - integrity sha512-iU9pv7U+2jC9ANQkKeNF6DrPy4GBa4NWQtl6dHB4Pb3izX2JOEvDTFarlNsBj/63ZEzNNIAMs3Qw4fNCcSOXJA== +"@babel/plugin-transform-function-name@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.12.1.tgz#2ec76258c70fe08c6d7da154003a480620eba667" + integrity sha512-JF3UgJUILoFrFMEnOJLJkRHSk6LUSXLmEFsA23aR2O5CSLUxbeUX1IZ1YQ7Sn0aXb601Ncwjx73a+FVqgcljVw== dependencies: - "@babel/helper-function-name" "^7.1.0" - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-function-name" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-literals@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.2.0.tgz#690353e81f9267dad4fd8cfd77eafa86aba53ea1" - integrity sha512-2ThDhm4lI4oV7fVQ6pNNK+sx+c/GM5/SaML0w/r4ZB7sAneD/piDJtwdKlNckXeyGK7wlwg2E2w33C/Hh+VFCg== +"@babel/plugin-transform-literals@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.12.1.tgz#d73b803a26b37017ddf9d3bb8f4dc58bfb806f57" + integrity sha512-+PxVGA+2Ag6uGgL0A5f+9rklOnnMccwEBzwYFL3EUaKuiyVnUipyXncFcfjSkbimLrODoqki1U9XxZzTvfN7IQ== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-member-expression-literals@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.2.0.tgz#fa10aa5c58a2cb6afcf2c9ffa8cb4d8b3d489a2d" - integrity sha512-HiU3zKkSU6scTidmnFJ0bMX8hz5ixC93b4MHMiYebmk2lUVNGOboPsqQvx5LzooihijUoLR/v7Nc1rbBtnc7FA== +"@babel/plugin-transform-member-expression-literals@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.12.1.tgz#496038602daf1514a64d43d8e17cbb2755e0c3ad" + integrity sha512-1sxePl6z9ad0gFMB9KqmYofk34flq62aqMt9NqliS/7hPEpURUCMbyHXrMPlo282iY7nAvUB1aQd5mg79UD9Jg== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-modules-amd@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.5.0.tgz#ef00435d46da0a5961aa728a1d2ecff063e4fb91" - integrity sha512-n20UsQMKnWrltocZZm24cRURxQnWIvsABPJlw/fvoy9c6AgHZzoelAIzajDHAQrDpuKFFPPcFGd7ChsYuIUMpg== +"@babel/plugin-transform-modules-amd@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.12.1.tgz#3154300b026185666eebb0c0ed7f8415fefcf6f9" + integrity sha512-tDW8hMkzad5oDtzsB70HIQQRBiTKrhfgwC/KkJeGsaNFTdWhKNt/BiE8c5yj19XiGyrxpbkOfH87qkNg1YGlOQ== dependencies: - "@babel/helper-module-transforms" "^7.1.0" - "@babel/helper-plugin-utils" "^7.0.0" - babel-plugin-dynamic-import-node "^2.3.0" + "@babel/helper-module-transforms" "^7.12.1" + "@babel/helper-plugin-utils" "^7.10.4" + babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-commonjs@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.5.0.tgz#425127e6045231360858eeaa47a71d75eded7a74" - integrity sha512-xmHq0B+ytyrWJvQTc5OWAC4ii6Dhr0s22STOoydokG51JjWhyYo5mRPXoi+ZmtHQhZZwuXNN+GG5jy5UZZJxIQ== +"@babel/plugin-transform-modules-commonjs@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.12.1.tgz#fa403124542636c786cf9b460a0ffbb48a86e648" + integrity sha512-dY789wq6l0uLY8py9c1B48V8mVL5gZh/+PQ5ZPrylPYsnAvnEMjqsUXkuoDVPeVK+0VyGar+D08107LzDQ6pag== dependencies: - "@babel/helper-module-transforms" "^7.4.4" - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-simple-access" "^7.1.0" - babel-plugin-dynamic-import-node "^2.3.0" + "@babel/helper-module-transforms" "^7.12.1" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-simple-access" "^7.12.1" + babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-systemjs@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.5.0.tgz#e75266a13ef94202db2a0620977756f51d52d249" - integrity sha512-Q2m56tyoQWmuNGxEtUyeEkm6qJYFqs4c+XyXH5RAuYxObRNz9Zgj/1g2GMnjYp2EUyEy7YTrxliGCXzecl/vJg== +"@babel/plugin-transform-modules-systemjs@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.12.1.tgz#663fea620d593c93f214a464cd399bf6dc683086" + integrity sha512-Hn7cVvOavVh8yvW6fLwveFqSnd7rbQN3zJvoPNyNaQSvgfKmDBO9U1YL9+PCXGRlZD9tNdWTy5ACKqMuzyn32Q== dependencies: - "@babel/helper-hoist-variables" "^7.4.4" - "@babel/helper-plugin-utils" "^7.0.0" - babel-plugin-dynamic-import-node "^2.3.0" + "@babel/helper-hoist-variables" "^7.10.4" + "@babel/helper-module-transforms" "^7.12.1" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-validator-identifier" "^7.10.4" + babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-umd@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.2.0.tgz#7678ce75169f0877b8eb2235538c074268dd01ae" - integrity sha512-BV3bw6MyUH1iIsGhXlOK6sXhmSarZjtJ/vMiD9dNmpY8QXFFQTj+6v92pcfy1iqa8DeAfJFwoxcrS/TUZda6sw== +"@babel/plugin-transform-modules-umd@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.12.1.tgz#eb5a218d6b1c68f3d6217b8fa2cc82fec6547902" + integrity sha512-aEIubCS0KHKM0zUos5fIoQm+AZUMt1ZvMpqz0/H5qAQ7vWylr9+PLYurT+Ic7ID/bKLd4q8hDovaG3Zch2uz5Q== dependencies: - "@babel/helper-module-transforms" "^7.1.0" - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-module-transforms" "^7.12.1" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-named-capturing-groups-regex@^7.4.5": - version "7.4.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.4.5.tgz#9d269fd28a370258199b4294736813a60bbdd106" - integrity sha512-z7+2IsWafTBbjNsOxU/Iv5CvTJlr5w4+HGu1HovKYTtgJ362f7kBcQglkfmlspKKZ3bgrbSGvLfNx++ZJgCWsg== +"@babel/plugin-transform-named-capturing-groups-regex@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.12.1.tgz#b407f5c96be0d9f5f88467497fa82b30ac3e8753" + integrity sha512-tB43uQ62RHcoDp9v2Nsf+dSM8sbNodbEicbQNA53zHz8pWUhsgHSJCGpt7daXxRydjb0KnfmB+ChXOv3oADp1Q== dependencies: - regexp-tree "^0.1.6" + "@babel/helper-create-regexp-features-plugin" "^7.12.1" -"@babel/plugin-transform-new-target@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.4.4.tgz#18d120438b0cc9ee95a47f2c72bc9768fbed60a5" - integrity sha512-r1z3T2DNGQwwe2vPGZMBNjioT2scgWzK9BCnDEh+46z8EEwXBq24uRzd65I7pjtugzPSj921aM15RpESgzsSuA== +"@babel/plugin-transform-new-target@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.12.1.tgz#80073f02ee1bb2d365c3416490e085c95759dec0" + integrity sha512-+eW/VLcUL5L9IvJH7rT1sT0CzkdUTvPrXC2PXTn/7z7tXLBuKvezYbGdxD5WMRoyvyaujOq2fWoKl869heKjhw== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-object-super@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.5.5.tgz#c70021df834073c65eb613b8679cc4a381d1a9f9" - integrity sha512-un1zJQAhSosGFBduPgN/YFNvWVpRuHKU7IHBglLoLZsGmruJPOo6pbInneflUdmq7YvSVqhpPs5zdBvLnteltQ== +"@babel/plugin-transform-object-super@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.12.1.tgz#4ea08696b8d2e65841d0c7706482b048bed1066e" + integrity sha512-AvypiGJH9hsquNUn+RXVcBdeE3KHPZexWRdimhuV59cSoOt5kFBmqlByorAeUlGG2CJWd0U+4ZtNKga/TB0cAw== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-replace-supers" "^7.5.5" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-replace-supers" "^7.12.1" -"@babel/plugin-transform-parameters@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.4.4.tgz#7556cf03f318bd2719fe4c922d2d808be5571e16" - integrity sha512-oMh5DUO1V63nZcu/ZVLQFqiihBGo4OpxJxR1otF50GMeCLiRx5nUdtokd+u9SuVJrvvuIh9OosRFPP4pIPnwmw== +"@babel/plugin-transform-parameters@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.12.1.tgz#d2e963b038771650c922eff593799c96d853255d" + integrity sha512-xq9C5EQhdPK23ZeCdMxl8bbRnAgHFrw5EOC3KJUsSylZqdkCaFEXxGSBuTSObOpiiHHNyb82es8M1QYgfQGfNg== dependencies: - "@babel/helper-call-delegate" "^7.4.4" - "@babel/helper-get-function-arity" "^7.0.0" - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-property-literals@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.2.0.tgz#03e33f653f5b25c4eb572c98b9485055b389e905" - integrity sha512-9q7Dbk4RhgcLp8ebduOpCbtjh7C0itoLYHXd9ueASKAG/is5PQtMR5VJGka9NKqGhYEGn5ITahd4h9QeBMylWQ== +"@babel/plugin-transform-property-literals@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.12.1.tgz#41bc81200d730abb4456ab8b3fbd5537b59adecd" + integrity sha512-6MTCR/mZ1MQS+AwZLplX4cEySjCpnIF26ToWo942nqn8hXSm7McaHQNeGx/pt7suI1TWOWMfa/NgBhiqSnX0cQ== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-react-constant-elements@^7.0.0", "@babel/plugin-transform-react-constant-elements@^7.2.0", "@babel/plugin-transform-react-constant-elements@^7.6.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.8.3.tgz#784c25294bddaad2323eb4ff0c9f4a3f6c87d6bc" - integrity sha512-glrzN2U+egwRfkNFtL34xIBYTxbbUF2qJTP8HD3qETBBqzAWSeNB821X0GjU06+dNpq/UyCIjI72FmGE5NNkQQ== +"@babel/plugin-transform-react-display-name@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.12.1.tgz#1cbcd0c3b1d6648c55374a22fc9b6b7e5341c00d" + integrity sha512-cAzB+UzBIrekfYxyLlFqf/OagTvHLcVBb5vpouzkYkBclRPraiygVnafvAoipErZLI8ANv8Ecn6E/m5qPXD26w== dependencies: - "@babel/helper-annotate-as-pure" "^7.8.3" - "@babel/helper-plugin-utils" "^7.8.3" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-react-display-name@^7.0.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.2.0.tgz#ebfaed87834ce8dc4279609a4f0c324c156e3eb0" - integrity sha512-Htf/tPa5haZvRMiNSQSFifK12gtr/8vwfr+A9y69uF0QcU77AVu4K7MiHEkTxF7lQoHOL0F9ErqgfNEAKgXj7A== +"@babel/plugin-transform-react-jsx-development@^7.12.7": + version "7.12.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.12.7.tgz#4c2a647de79c7e2b16bfe4540677ba3121e82a08" + integrity sha512-Rs3ETtMtR3VLXFeYRChle5SsP/P9Jp/6dsewBQfokDSzKJThlsuFcnzLTDRALiUmTC48ej19YD9uN1mupEeEDg== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-builder-react-jsx-experimental" "^7.12.4" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-jsx" "^7.12.1" -"@babel/plugin-transform-react-jsx-self@^7.0.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.2.0.tgz#461e21ad9478f1031dd5e276108d027f1b5240ba" - integrity sha512-v6S5L/myicZEy+jr6ielB0OR8h+EH/1QFx/YJ7c7Ua+7lqsjj/vW6fD5FR9hB/6y7mGbfT4vAURn3xqBxsUcdg== +"@babel/plugin-transform-react-jsx-self@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.12.1.tgz#ef43cbca2a14f1bd17807dbe4376ff89d714cf28" + integrity sha512-FbpL0ieNWiiBB5tCldX17EtXgmzeEZjFrix72rQYeq9X6nUK38HCaxexzVQrZWXanxKJPKVVIU37gFjEQYkPkA== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-jsx" "^7.2.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-react-jsx-source@^7.0.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.2.0.tgz#20c8c60f0140f5dd3cd63418d452801cf3f7180f" - integrity sha512-A32OkKTp4i5U6aE88GwwcuV4HAprUgHcTq0sSafLxjr6AW0QahrCRCjxogkbbcdtpbXkuTOlgpjophCxb6sh5g== +"@babel/plugin-transform-react-jsx-source@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.12.1.tgz#d07de6863f468da0809edcf79a1aa8ce2a82a26b" + integrity sha512-keQ5kBfjJNRc6zZN1/nVHCd6LLIHq4aUKcVnvE/2l+ZZROSbqoiGFRtT5t3Is89XJxBQaP7NLZX2jgGHdZvvFQ== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-jsx" "^7.2.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-react-jsx@^7.0.0": - version "7.3.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.3.0.tgz#f2cab99026631c767e2745a5368b331cfe8f5290" - integrity sha512-a/+aRb7R06WcKvQLOu4/TpjKOdvVEKRLWFpKcNuHhiREPgGRB4TQJxq07+EZLS8LFVYpfq1a5lDUnuMdcCpBKg== +"@babel/plugin-transform-react-jsx@^7.12.7": + version "7.12.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.12.7.tgz#8b14d45f6eccd41b7f924bcb65c021e9f0a06f7f" + integrity sha512-YFlTi6MEsclFAPIDNZYiCRbneg1MFGao9pPG9uD5htwE0vDbPaMUMeYd6itWjw7K4kro4UbdQf3ljmFl9y48dQ== dependencies: - "@babel/helper-builder-react-jsx" "^7.3.0" - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-jsx" "^7.2.0" + "@babel/helper-builder-react-jsx" "^7.10.4" + "@babel/helper-builder-react-jsx-experimental" "^7.12.4" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-jsx" "^7.12.1" -"@babel/plugin-transform-regenerator@^7.4.5": - version "7.4.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.4.5.tgz#629dc82512c55cee01341fb27bdfcb210354680f" - integrity sha512-gBKRh5qAaCWntnd09S8QC7r3auLCqq5DI6O0DlfoyDjslSBVqBibrMdsqO+Uhmx3+BlOmE/Kw1HFxmGbv0N9dA== +"@babel/plugin-transform-react-pure-annotations@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.12.1.tgz#05d46f0ab4d1339ac59adf20a1462c91b37a1a42" + integrity sha512-RqeaHiwZtphSIUZ5I85PEH19LOSzxfuEazoY7/pWASCAIBuATQzpSVD+eT6MebeeZT2F4eSL0u4vw6n4Nm0Mjg== dependencies: - regenerator-transform "^0.14.0" + "@babel/helper-annotate-as-pure" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-reserved-words@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.2.0.tgz#4792af87c998a49367597d07fedf02636d2e1634" - integrity sha512-fz43fqW8E1tAB3DKF19/vxbpib1fuyCwSPE418ge5ZxILnBhWyhtPgz8eh1RCGGJlwvksHkyxMxh0eenFi+kFw== +"@babel/plugin-transform-regenerator@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.12.1.tgz#5f0a28d842f6462281f06a964e88ba8d7ab49753" + integrity sha512-gYrHqs5itw6i4PflFX3OdBPMQdPbF4bj2REIUxlMRUFk0/ZOAIpDFuViuxPjUL7YC8UPnf+XG7/utJvqXdPKng== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + regenerator-transform "^0.14.2" + +"@babel/plugin-transform-reserved-words@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.12.1.tgz#6fdfc8cc7edcc42b36a7c12188c6787c873adcd8" + integrity sha512-pOnUfhyPKvZpVyBHhSBoX8vfA09b7r00Pmm1sH+29ae2hMTKVmSp4Ztsr8KBKjLjx17H0eJqaRC3bR2iThM54A== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-transform-runtime@^7.5.5": version "7.5.5" @@ -723,138 +859,189 @@ resolve "^1.8.1" semver "^5.5.1" -"@babel/plugin-transform-shorthand-properties@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.2.0.tgz#6333aee2f8d6ee7e28615457298934a3b46198f0" - integrity sha512-QP4eUM83ha9zmYtpbnyjTLAGKQritA5XW/iG9cjtuOI8s1RuL/3V6a3DeSHfKutJQ+ayUfeZJPcnCYEQzaPQqg== +"@babel/plugin-transform-shorthand-properties@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.12.1.tgz#0bf9cac5550fce0cfdf043420f661d645fdc75e3" + integrity sha512-GFZS3c/MhX1OusqB1MZ1ct2xRzX5ppQh2JU1h2Pnfk88HtFTM+TWQqJNfwkmxtPQtb/s1tk87oENfXJlx7rSDw== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-spread@^7.2.0": - version "7.2.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.2.2.tgz#3103a9abe22f742b6d406ecd3cd49b774919b406" - integrity sha512-KWfky/58vubwtS0hLqEnrWJjsMGaOeSBn90Ezn5Jeg9Z8KKHmELbP1yGylMlm5N6TPKeY9A2+UaSYLdxahg01w== +"@babel/plugin-transform-spread@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.12.1.tgz#527f9f311be4ec7fdc2b79bb89f7bf884b3e1e1e" + integrity sha512-vuLp8CP0BE18zVYjsEBZ5xoCecMK6LBMMxYzJnh01rxQRvhNhH1csMMmBfNo5tGpGO+NhdSNW2mzIvBu3K1fng== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-skip-transparent-expression-wrappers" "^7.12.1" -"@babel/plugin-transform-sticky-regex@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.2.0.tgz#a1e454b5995560a9c1e0d537dfc15061fd2687e1" - integrity sha512-KKYCoGaRAf+ckH8gEL3JHUaFVyNHKe3ASNsZ+AlktgHevvxGigoIttrEJb8iKN03Q7Eazlv1s6cx2B2cQ3Jabw== +"@babel/plugin-transform-sticky-regex@^7.12.7": + version "7.12.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.12.7.tgz#560224613ab23987453948ed21d0b0b193fa7fad" + integrity sha512-VEiqZL5N/QvDbdjfYQBhruN0HYjSPjC4XkeqW4ny/jNtH9gcbgaqBIXYEZCNnESMAGs0/K/R7oFGMhOyu/eIxg== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-regex" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-template-literals@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.4.4.tgz#9d28fea7bbce637fb7612a0750989d8321d4bcb0" - integrity sha512-mQrEC4TWkhLN0z8ygIvEL9ZEToPhG5K7KDW3pzGqOfIGZ28Jb0POUkeWcoz8HnHvhFy6dwAT1j8OzqN8s804+g== +"@babel/plugin-transform-template-literals@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.12.1.tgz#b43ece6ed9a79c0c71119f576d299ef09d942843" + integrity sha512-b4Zx3KHi+taXB1dVRBhVJtEPi9h1THCeKmae2qP0YdUHIFhVjtpqqNfxeVAa1xeHVhAy4SbHxEwx5cltAu5apw== dependencies: - "@babel/helper-annotate-as-pure" "^7.0.0" - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-typeof-symbol@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.2.0.tgz#117d2bcec2fbf64b4b59d1f9819894682d29f2b2" - integrity sha512-2LNhETWYxiYysBtrBTqL8+La0jIoQQnIScUJc74OYvUGRmkskNY4EzLCnjHBzdmb38wqtTaixpo1NctEcvMDZw== +"@babel/plugin-transform-typeof-symbol@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.12.1.tgz#9ca6be343d42512fbc2e68236a82ae64bc7af78a" + integrity sha512-EPGgpGy+O5Kg5pJFNDKuxt9RdmTgj5sgrus2XVeMp/ZIbOESadgILUbm50SNpghOh3/6yrbsH+NB5+WJTmsA7Q== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-unicode-regex@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.4.4.tgz#ab4634bb4f14d36728bf5978322b35587787970f" - integrity sha512-il+/XdNw01i93+M9J9u4T7/e/Ue/vWfNZE4IRUQjplu2Mqb/AFTDimkw2tdEdSH50wuQXZAbXSql0UphQke+vA== +"@babel/plugin-transform-typescript@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.12.1.tgz#d92cc0af504d510e26a754a7dbc2e5c8cd9c7ab4" + integrity sha512-VrsBByqAIntM+EYMqSm59SiMEf7qkmI9dqMt6RbD/wlwueWmYcI0FFK5Fj47pP6DRZm+3teXjosKlwcZJ5lIMw== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-regex" "^7.4.4" - regexpu-core "^4.5.4" + "@babel/helper-create-class-features-plugin" "^7.12.1" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-typescript" "^7.12.1" -"@babel/preset-env@^7.4.3", "@babel/preset-env@^7.4.5", "@babel/preset-env@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.5.5.tgz#bc470b53acaa48df4b8db24a570d6da1fef53c9a" - integrity sha512-GMZQka/+INwsMz1A5UEql8tG015h5j/qjptpKY2gJ7giy8ohzU710YciJB5rcKsWGWHiW3RUnHib0E5/m3Tp3A== +"@babel/plugin-transform-unicode-escapes@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.12.1.tgz#5232b9f81ccb07070b7c3c36c67a1b78f1845709" + integrity sha512-I8gNHJLIc7GdApm7wkVnStWssPNbSRMPtgHdmH3sRM1zopz09UWPS4x5V4n1yz/MIWTVnJ9sp6IkuXdWM4w+2Q== dependencies: - "@babel/helper-module-imports" "^7.0.0" - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-proposal-async-generator-functions" "^7.2.0" - "@babel/plugin-proposal-dynamic-import" "^7.5.0" - "@babel/plugin-proposal-json-strings" "^7.2.0" - "@babel/plugin-proposal-object-rest-spread" "^7.5.5" - "@babel/plugin-proposal-optional-catch-binding" "^7.2.0" - "@babel/plugin-proposal-unicode-property-regex" "^7.4.4" - "@babel/plugin-syntax-async-generators" "^7.2.0" - "@babel/plugin-syntax-dynamic-import" "^7.2.0" - "@babel/plugin-syntax-json-strings" "^7.2.0" - "@babel/plugin-syntax-object-rest-spread" "^7.2.0" - "@babel/plugin-syntax-optional-catch-binding" "^7.2.0" - "@babel/plugin-transform-arrow-functions" "^7.2.0" - "@babel/plugin-transform-async-to-generator" "^7.5.0" - "@babel/plugin-transform-block-scoped-functions" "^7.2.0" - "@babel/plugin-transform-block-scoping" "^7.5.5" - "@babel/plugin-transform-classes" "^7.5.5" - "@babel/plugin-transform-computed-properties" "^7.2.0" - "@babel/plugin-transform-destructuring" "^7.5.0" - "@babel/plugin-transform-dotall-regex" "^7.4.4" - "@babel/plugin-transform-duplicate-keys" "^7.5.0" - "@babel/plugin-transform-exponentiation-operator" "^7.2.0" - "@babel/plugin-transform-for-of" "^7.4.4" - "@babel/plugin-transform-function-name" "^7.4.4" - "@babel/plugin-transform-literals" "^7.2.0" - "@babel/plugin-transform-member-expression-literals" "^7.2.0" - "@babel/plugin-transform-modules-amd" "^7.5.0" - "@babel/plugin-transform-modules-commonjs" "^7.5.0" - "@babel/plugin-transform-modules-systemjs" "^7.5.0" - "@babel/plugin-transform-modules-umd" "^7.2.0" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.4.5" - "@babel/plugin-transform-new-target" "^7.4.4" - "@babel/plugin-transform-object-super" "^7.5.5" - "@babel/plugin-transform-parameters" "^7.4.4" - "@babel/plugin-transform-property-literals" "^7.2.0" - "@babel/plugin-transform-regenerator" "^7.4.5" - "@babel/plugin-transform-reserved-words" "^7.2.0" - "@babel/plugin-transform-shorthand-properties" "^7.2.0" - "@babel/plugin-transform-spread" "^7.2.0" - "@babel/plugin-transform-sticky-regex" "^7.2.0" - "@babel/plugin-transform-template-literals" "^7.4.4" - "@babel/plugin-transform-typeof-symbol" "^7.2.0" - "@babel/plugin-transform-unicode-regex" "^7.4.4" - "@babel/types" "^7.5.5" - browserslist "^4.6.0" - core-js-compat "^3.1.1" - invariant "^2.2.2" - js-levenshtein "^1.1.3" + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-unicode-regex@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.12.1.tgz#cc9661f61390db5c65e3febaccefd5c6ac3faecb" + integrity sha512-SqH4ClNngh/zGwHZOOQMTD+e8FGWexILV+ePMyiDJttAWRh5dhDL8rcl5lSgU3Huiq6Zn6pWTMvdPAb21Dwdyg== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.12.1" + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/preset-env@^7.12.1", "@babel/preset-env@^7.5.5": + version "7.12.7" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.12.7.tgz#54ea21dbe92caf6f10cb1a0a576adc4ebf094b55" + integrity sha512-OnNdfAr1FUQg7ksb7bmbKoby4qFOHw6DKWWUNB9KqnnCldxhxJlP+21dpyaWFmf2h0rTbOkXJtAGevY3XW1eew== + dependencies: + "@babel/compat-data" "^7.12.7" + "@babel/helper-compilation-targets" "^7.12.5" + "@babel/helper-module-imports" "^7.12.5" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-validator-option" "^7.12.1" + "@babel/plugin-proposal-async-generator-functions" "^7.12.1" + "@babel/plugin-proposal-class-properties" "^7.12.1" + "@babel/plugin-proposal-dynamic-import" "^7.12.1" + "@babel/plugin-proposal-export-namespace-from" "^7.12.1" + "@babel/plugin-proposal-json-strings" "^7.12.1" + "@babel/plugin-proposal-logical-assignment-operators" "^7.12.1" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.12.1" + "@babel/plugin-proposal-numeric-separator" "^7.12.7" + "@babel/plugin-proposal-object-rest-spread" "^7.12.1" + "@babel/plugin-proposal-optional-catch-binding" "^7.12.1" + "@babel/plugin-proposal-optional-chaining" "^7.12.7" + "@babel/plugin-proposal-private-methods" "^7.12.1" + "@babel/plugin-proposal-unicode-property-regex" "^7.12.1" + "@babel/plugin-syntax-async-generators" "^7.8.0" + "@babel/plugin-syntax-class-properties" "^7.12.1" + "@babel/plugin-syntax-dynamic-import" "^7.8.0" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + "@babel/plugin-syntax-json-strings" "^7.8.0" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + "@babel/plugin-syntax-object-rest-spread" "^7.8.0" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.0" + "@babel/plugin-syntax-optional-chaining" "^7.8.0" + "@babel/plugin-syntax-top-level-await" "^7.12.1" + "@babel/plugin-transform-arrow-functions" "^7.12.1" + "@babel/plugin-transform-async-to-generator" "^7.12.1" + "@babel/plugin-transform-block-scoped-functions" "^7.12.1" + "@babel/plugin-transform-block-scoping" "^7.12.1" + "@babel/plugin-transform-classes" "^7.12.1" + "@babel/plugin-transform-computed-properties" "^7.12.1" + "@babel/plugin-transform-destructuring" "^7.12.1" + "@babel/plugin-transform-dotall-regex" "^7.12.1" + "@babel/plugin-transform-duplicate-keys" "^7.12.1" + "@babel/plugin-transform-exponentiation-operator" "^7.12.1" + "@babel/plugin-transform-for-of" "^7.12.1" + "@babel/plugin-transform-function-name" "^7.12.1" + "@babel/plugin-transform-literals" "^7.12.1" + "@babel/plugin-transform-member-expression-literals" "^7.12.1" + "@babel/plugin-transform-modules-amd" "^7.12.1" + "@babel/plugin-transform-modules-commonjs" "^7.12.1" + "@babel/plugin-transform-modules-systemjs" "^7.12.1" + "@babel/plugin-transform-modules-umd" "^7.12.1" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.12.1" + "@babel/plugin-transform-new-target" "^7.12.1" + "@babel/plugin-transform-object-super" "^7.12.1" + "@babel/plugin-transform-parameters" "^7.12.1" + "@babel/plugin-transform-property-literals" "^7.12.1" + "@babel/plugin-transform-regenerator" "^7.12.1" + "@babel/plugin-transform-reserved-words" "^7.12.1" + "@babel/plugin-transform-shorthand-properties" "^7.12.1" + "@babel/plugin-transform-spread" "^7.12.1" + "@babel/plugin-transform-sticky-regex" "^7.12.7" + "@babel/plugin-transform-template-literals" "^7.12.1" + "@babel/plugin-transform-typeof-symbol" "^7.12.1" + "@babel/plugin-transform-unicode-escapes" "^7.12.1" + "@babel/plugin-transform-unicode-regex" "^7.12.1" + "@babel/preset-modules" "^0.1.3" + "@babel/types" "^7.12.7" + core-js-compat "^3.7.0" semver "^5.5.0" -"@babel/preset-flow@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/preset-flow/-/preset-flow-7.0.0.tgz#afd764835d9535ec63d8c7d4caf1c06457263da2" - integrity sha512-bJOHrYOPqJZCkPVbG1Lot2r5OSsB+iUOaxiHdlOeB1yPWS6evswVHwvkDLZ54WTaTRIk89ds0iHmGZSnxlPejQ== +"@babel/preset-flow@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/preset-flow/-/preset-flow-7.12.1.tgz#1a81d376c5a9549e75352a3888f8c273455ae940" + integrity sha512-UAoyMdioAhM6H99qPoKvpHMzxmNVXno8GYU/7vZmGaHk6/KqfDYL1W0NxszVbJ2EP271b7e6Ox+Vk2A9QsB3Sw== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-transform-flow-strip-types" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-transform-flow-strip-types" "^7.12.1" -"@babel/preset-react@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.0.0.tgz#e86b4b3d99433c7b3e9e91747e2653958bc6b3c0" - integrity sha512-oayxyPS4Zj+hF6Et11BwuBkmpgT/zMxyuZgFrMeZID6Hdh3dGlk4sHCAhdBCpuCKW2ppBfl2uCCetlrUIJRY3w== +"@babel/preset-modules@^0.1.3": + version "0.1.4" + resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.4.tgz#362f2b68c662842970fdb5e254ffc8fc1c2e415e" + integrity sha512-J36NhwnfdzpmH41M1DrnkkgAqhZaqr/NBdPfQ677mLzlaXo+oDiv1deyCDtgAhz8p328otdob0Du7+xgHGZbKg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-transform-react-display-name" "^7.0.0" - "@babel/plugin-transform-react-jsx" "^7.0.0" - "@babel/plugin-transform-react-jsx-self" "^7.0.0" - "@babel/plugin-transform-react-jsx-source" "^7.0.0" + "@babel/plugin-proposal-unicode-property-regex" "^7.4.4" + "@babel/plugin-transform-dotall-regex" "^7.4.4" + "@babel/types" "^7.4.4" + esutils "^2.0.2" -"@babel/register@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.5.5.tgz#40fe0d474c8c8587b28d6ae18a03eddad3dac3c1" - integrity sha512-pdd5nNR+g2qDkXZlW1yRCWFlNrAn2PPdnZUB72zjX4l1Vv4fMRRLwyf+n/idFCLI1UgVGboUU8oVziwTBiyNKQ== +"@babel/preset-react@^7.0.0", "@babel/preset-react@^7.12.1": + version "7.12.7" + resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.12.7.tgz#36d61d83223b07b6ac4ec55cf016abb0f70be83b" + integrity sha512-wKeTdnGUP5AEYCYQIMeXMMwU7j+2opxrG0WzuZfxuuW9nhKvvALBjl67653CWamZJVefuJGI219G591RSldrqQ== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-transform-react-display-name" "^7.12.1" + "@babel/plugin-transform-react-jsx" "^7.12.7" + "@babel/plugin-transform-react-jsx-development" "^7.12.7" + "@babel/plugin-transform-react-jsx-self" "^7.12.1" + "@babel/plugin-transform-react-jsx-source" "^7.12.1" + "@babel/plugin-transform-react-pure-annotations" "^7.12.1" + +"@babel/preset-typescript@^7.12.1": + version "7.12.7" + resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.12.7.tgz#fc7df8199d6aae747896f1e6c61fc872056632a3" + integrity sha512-nOoIqIqBmHBSEgBXWR4Dv/XBehtIFcw9PqZw6rFYuKrzsZmOQm3PR5siLBnKZFEsDb03IegG8nSjU/iXXXYRmw== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-validator-option" "^7.12.1" + "@babel/plugin-transform-typescript" "^7.12.1" + +"@babel/register@^7.12.1", "@babel/register@^7.5.5": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.12.1.tgz#cdb087bdfc4f7241c03231f22e15d211acf21438" + integrity sha512-XWcmseMIncOjoydKZnWvWi0/5CUCD+ZYKhRwgYlWOrA8fGZ/FjuLRpqtIhLOVD/fvR1b9DQHtZPn68VvhpYf+Q== dependencies: - core-js "^3.0.0" find-cache-dir "^2.0.0" - lodash "^4.17.13" - mkdirp "^0.5.1" + lodash "^4.17.19" + make-dir "^2.1.0" pirates "^4.0.0" - source-map-support "^0.5.9" + source-map-support "^0.5.16" "@babel/runtime-corejs3@^7.10.2": version "7.11.2" @@ -871,41 +1058,41 @@ dependencies: regenerator-runtime "^0.12.0" -"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.10.3", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.0", "@babel/runtime@^7.4.4", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.0", "@babel/runtime@^7.5.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.7": - version "7.11.2" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.11.2.tgz#f549c13c754cc40b87644b9fa9f09a6a95fe0736" - integrity sha512-TeWkU52so0mPtDcaCTxNBI/IHiz0pZgr8VEFqXFtZWpYD08ZB6FaSwVAS8MKRQAP3bYKiVjwysOJgMFY28o6Tw== +"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.10.3", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.0", "@babel/runtime@^7.4.4", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.0", "@babel/runtime@^7.5.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": + version "7.12.5" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.12.5.tgz#410e7e487441e1b360c29be715d870d9b985882e" + integrity sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg== dependencies: regenerator-runtime "^0.13.4" -"@babel/template@^7.1.0", "@babel/template@^7.10.4", "@babel/template@^7.7.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.10.4.tgz#3251996c4200ebc71d1a8fc405fba940f36ba278" - integrity sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA== +"@babel/template@^7.10.4", "@babel/template@^7.12.7", "@babel/template@^7.7.4": + version "7.12.7" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.12.7.tgz#c817233696018e39fbb6c491d2fb684e05ed43bc" + integrity sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow== dependencies: "@babel/code-frame" "^7.10.4" - "@babel/parser" "^7.10.4" - "@babel/types" "^7.10.4" + "@babel/parser" "^7.12.7" + "@babel/types" "^7.12.7" -"@babel/traverse@^7.1.0", "@babel/traverse@^7.12.1", "@babel/traverse@^7.4.4", "@babel/traverse@^7.7.4": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.12.1.tgz#941395e0c5cc86d5d3e75caa095d3924526f0c1e" - integrity sha512-MA3WPoRt1ZHo2ZmoGKNqi20YnPt0B1S0GTZEPhhd+hw2KGUzBlHuVunj6K4sNuK+reEvyiPwtp0cpaqLzJDmAw== +"@babel/traverse@^7.10.4", "@babel/traverse@^7.12.1", "@babel/traverse@^7.12.5", "@babel/traverse@^7.12.9", "@babel/traverse@^7.7.4": + version "7.12.9" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.12.9.tgz#fad26c972eabbc11350e0b695978de6cc8e8596f" + integrity sha512-iX9ajqnLdoU1s1nHt36JDI9KG4k+vmI8WgjK5d+aDTwQbL2fUnzedNedssA645Ede3PM2ma1n8Q4h2ohwXgMXw== dependencies: "@babel/code-frame" "^7.10.4" - "@babel/generator" "^7.12.1" + "@babel/generator" "^7.12.5" "@babel/helper-function-name" "^7.10.4" "@babel/helper-split-export-declaration" "^7.11.0" - "@babel/parser" "^7.12.1" - "@babel/types" "^7.12.1" + "@babel/parser" "^7.12.7" + "@babel/types" "^7.12.7" debug "^4.1.0" globals "^11.1.0" lodash "^4.17.19" -"@babel/types@^7.0.0", "@babel/types@^7.10.4", "@babel/types@^7.11.0", "@babel/types@^7.11.5", "@babel/types@^7.12.1", "@babel/types@^7.2.0", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.4.4", "@babel/types@^7.5.5", "@babel/types@^7.8.3": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.12.1.tgz#e109d9ab99a8de735be287ee3d6a9947a190c4ae" - integrity sha512-BzSY3NJBKM4kyatSOWh3D/JJ2O3CVzBybHWxtgxnggaxEuaSTTDqeiSb/xk9lrkw2Tbqyivw5ZU4rT+EfznQsA== +"@babel/types@^7.10.4", "@babel/types@^7.10.5", "@babel/types@^7.11.0", "@babel/types@^7.11.5", "@babel/types@^7.12.1", "@babel/types@^7.12.5", "@babel/types@^7.12.7", "@babel/types@^7.4.4": + version "7.12.7" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.12.7.tgz#6039ff1e242640a29452c9ae572162ec9a8f5d13" + integrity sha512-MNyI92qZq6jrQkXvtIiykvl4WtoRrVV9MPn+ZfsoEENjiWcBQ3ZSHrkxnJWgWtLX3XXqX5hrSQ+X69wkmesXuQ== dependencies: "@babel/helper-validator-identifier" "^7.10.4" lodash "^4.17.19" @@ -949,10 +1136,10 @@ "@emotion/utils" "0.11.3" "@emotion/weak-memoize" "0.2.5" -"@emotion/core@^10.0.20", "@emotion/core@^10.0.9": - version "10.0.27" - resolved "https://registry.yarnpkg.com/@emotion/core/-/core-10.0.27.tgz#7c3f78be681ab2273f3bf11ca3e2edc4a9dd1fdc" - integrity sha512-XbD5R36pVbohQMnKfajHv43g8EbN4NHdF6Zh9zg/C0nr0jqwOw3gYnC07Xj3yG43OYSRyrGsoQ5qPwc8ycvLZw== +"@emotion/core@^10.0.9", "@emotion/core@^10.1.1": + version "10.1.1" + resolved "https://registry.yarnpkg.com/@emotion/core/-/core-10.1.1.tgz#c956c1365f2f2481960064bcb8c4732e5fb612c3" + integrity sha512-ZMLG6qpXR8x031NXD8HJqugy/AZSkAuMxxqB46pmAR7ze47MhNJ56cdoX243QPZdGctrdfo+s08yZTiwaUcRKA== dependencies: "@babel/runtime" "^7.5.5" "@emotion/cache" "^10.0.27" @@ -987,6 +1174,13 @@ dependencies: "@emotion/memoize" "0.7.4" +"@emotion/is-prop-valid@^0.8.6": + version "0.8.8" + resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz#db28b1c4368a259b60a97311d6a952d4fd01ac1a" + integrity sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA== + dependencies: + "@emotion/memoize" "0.7.4" + "@emotion/memoize@0.7.4": version "0.7.4" resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.4.tgz#19bf0f5af19149111c40d98bb0cf82119f5d9eeb" @@ -1018,7 +1212,7 @@ "@emotion/serialize" "^0.11.15" "@emotion/utils" "0.11.3" -"@emotion/styled@^10.0.17": +"@emotion/styled@^10.0.23": version "10.0.27" resolved "https://registry.yarnpkg.com/@emotion/styled/-/styled-10.0.27.tgz#12cb67e91f7ad7431e1875b1d83a94b814133eaf" integrity sha512-iK/8Sh7+NLJzyp9a5+vIQIXTYxfT4yB/OJbjzQanB2RZpvmzBQOHZWhpAMZWYEKRNNbsD6WfBw5sVWkb6WzS/Q== @@ -1993,26 +2187,37 @@ dependencies: mkdirp "^1.0.4" -"@popperjs/core@^2.4.0": - version "2.4.0" - resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.4.0.tgz#0e1bdf8d021e7ea58affade33d9d607e11365915" - integrity sha512-NMrDy6EWh9TPdSRiHmHH2ye1v5U0gBD7pRYwSwJvomx7Bm4GG04vu63dYiVzebLOx2obPpJugew06xVP0Nk7hA== +"@pmmmwh/react-refresh-webpack-plugin@^0.4.2": + version "0.4.3" + resolved "https://registry.yarnpkg.com/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.4.3.tgz#1eec460596d200c0236bf195b078a5d1df89b766" + integrity sha512-br5Qwvh8D2OQqSXpd1g/xqXKnK0r+Jz6qVKBbWmpUcrbGOxUrf39V5oZ1876084CGn18uMdR5uvPqBv9UqtBjQ== + dependencies: + ansi-html "^0.0.7" + error-stack-parser "^2.0.6" + html-entities "^1.2.1" + native-url "^0.2.6" + schema-utils "^2.6.5" + source-map "^0.7.3" + +"@popperjs/core@^2.4.0", "@popperjs/core@^2.4.4", "@popperjs/core@^2.5.4": + version "2.5.4" + resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.5.4.tgz#de25b5da9f727985a3757fd59b5d028aba75841a" + integrity sha512-ZpKr+WTb8zsajqgDkvCEWgp6d5eJT6Q63Ng2neTbzBO76Lbe91vX/iVIW9dikq+Fs3yEo+ls4cxeXABD2LtcbQ== "@protobufjs/utf8@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" integrity sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA= -"@reach/router@^1.2.1": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@reach/router/-/router-1.2.1.tgz#34ae3541a5ac44fa7796e5506a5d7274a162be4e" - integrity sha512-kTaX08X4g27tzIFQGRukaHmNbtMYDS3LEWIS8+l6OayGIw6Oyo1HIF/JzeuR2FoF9z6oV+x/wJSVSq4v8tcUGQ== +"@reach/router@^1.3.3": + version "1.3.4" + resolved "https://registry.yarnpkg.com/@reach/router/-/router-1.3.4.tgz#d2574b19370a70c80480ed91f3da840136d10f8c" + integrity sha512-+mtn9wjlB9NN2CNnnC/BRYtwdKBfSyyasPYraNAyvaV1occr/5NnB4CVzjEZipNHwYebQwcndGUmpFzxAUoqSA== dependencies: - create-react-context "^0.2.1" + create-react-context "0.3.0" invariant "^2.2.3" prop-types "^15.6.1" react-lifecycles-compat "^3.0.4" - warning "^3.0.0" "@reduxjs/toolkit@^1.3.2": version "1.3.2" @@ -2157,58 +2362,63 @@ resolved "https://registry.yarnpkg.com/@stablelib/utf8/-/utf8-0.10.1.tgz#eecf54884da7b2bee235e3c70efb8cd5c07ba5bd" integrity sha512-+uM1YZ4MhBC82vt99prF7DXNGqhYmJ9cQ3p5qNowMNkkzn9OWEkqBvguBW3ChAt7JvqZ3SD5HJOfc6YgnfMTHw== -"@storybook/addon-actions@^5.3.14": - version "5.3.14" - resolved "https://registry.yarnpkg.com/@storybook/addon-actions/-/addon-actions-5.3.14.tgz#aacc4d2703fc200a4565bfaa9f5870ed70a6fe32" - integrity sha512-4lKrTMzw/r6VQiBY24v72WC3jibW7pc9BIJgtPpTmTUQWTxPnkmxDfT81pV4BjS1GFH9VCnU6f5fWK+5lrQlsw== - dependencies: - "@storybook/addons" "5.3.14" - "@storybook/api" "5.3.14" - "@storybook/client-api" "5.3.14" - "@storybook/components" "5.3.14" - "@storybook/core-events" "5.3.14" - "@storybook/theming" "5.3.14" +"@storybook/addon-actions@^6.1.9": + version "6.1.9" + resolved "https://registry.yarnpkg.com/@storybook/addon-actions/-/addon-actions-6.1.9.tgz#b6d185b8e4e73691acc428b59e4d331195d64a40" + integrity sha512-vYqwuaBHrjRbbuyf4WBc5uDhrSejVEEiCabuu4g00R3dN7P5Ne/tbSw9EkYbbrRKxlEhdkk83DU1/J/+mCY5jw== + dependencies: + "@storybook/addons" "6.1.9" + "@storybook/api" "6.1.9" + "@storybook/client-api" "6.1.9" + "@storybook/components" "6.1.9" + "@storybook/core-events" "6.1.9" + "@storybook/theming" "6.1.9" core-js "^3.0.1" - fast-deep-equal "^2.0.1" + fast-deep-equal "^3.1.1" global "^4.3.2" - polished "^3.3.1" + lodash "^4.17.15" + polished "^3.4.4" prop-types "^15.7.2" - react "^16.8.3" - react-inspector "^4.0.0" - uuid "^3.3.2" - -"@storybook/addon-backgrounds@^5.3.14": - version "5.3.14" - resolved "https://registry.yarnpkg.com/@storybook/addon-backgrounds/-/addon-backgrounds-5.3.14.tgz#b1b7fb77a82cbdb30a995f2afba2c488c6f43647" - integrity sha512-wrrbVrXV81+iHSf0Ejf9E9vwzVYhvVn0WoqY1ccneEWVWgiPwnptOCS5yYzsCQ2Riye2QutqBvZtaa0k88oKFA== - dependencies: - "@storybook/addons" "5.3.14" - "@storybook/api" "5.3.14" - "@storybook/client-logger" "5.3.14" - "@storybook/components" "5.3.14" - "@storybook/core-events" "5.3.14" - "@storybook/theming" "5.3.14" + react-inspector "^5.0.1" + regenerator-runtime "^0.13.7" + ts-dedent "^2.0.0" + util-deprecate "^1.0.2" + uuid "^8.0.0" + +"@storybook/addon-backgrounds@^6.1.9": + version "6.1.9" + resolved "https://registry.yarnpkg.com/@storybook/addon-backgrounds/-/addon-backgrounds-6.1.9.tgz#4e9647001b2f396f56428218480f541e3a8a0e60" + integrity sha512-0/nnbnWZqo4NjyHFxcCHkcU+t8uUdk///9jSXRs4swmOLIFRaftEc/ZJ2rScu1Sc7y0CQdbk1Jjyx5/2cHBQtw== + dependencies: + "@storybook/addons" "6.1.9" + "@storybook/api" "6.1.9" + "@storybook/client-logger" "6.1.9" + "@storybook/components" "6.1.9" + "@storybook/core-events" "6.1.9" + "@storybook/theming" "6.1.9" core-js "^3.0.1" + global "^4.3.2" memoizerific "^1.11.3" - react "^16.8.3" + regenerator-runtime "^0.13.7" + ts-dedent "^2.0.0" util-deprecate "^1.0.2" -"@storybook/addon-knobs@^5.3.14": - version "5.3.14" - resolved "https://registry.yarnpkg.com/@storybook/addon-knobs/-/addon-knobs-5.3.14.tgz#b8b753c7e64f7087668396d66aee253a51717a2d" - integrity sha512-pBpFOdeCR8n8w6QHK1adABt6YKf+Q4itfX0+AtZRGLvbGum9O+paihvP9EVYPlKiG+0T7Zv2vFCl6q6qFjF/Mw== - dependencies: - "@storybook/addons" "5.3.14" - "@storybook/api" "5.3.14" - "@storybook/client-api" "5.3.14" - "@storybook/components" "5.3.14" - "@storybook/core-events" "5.3.14" - "@storybook/theming" "5.3.14" - "@types/react-color" "^3.0.1" +"@storybook/addon-knobs@^6.1.9": + version "6.1.9" + resolved "https://registry.yarnpkg.com/@storybook/addon-knobs/-/addon-knobs-6.1.9.tgz#49773931770effc208db094c61eeecbceaf5836b" + integrity sha512-aUKD9FaQGl/WOkGT6utElspYZJ7cBtUARe41JN59qOao7RNviabipQUASrjORcYUUU55sfKsLPEqQaEKB3x2bw== + dependencies: + "@storybook/addons" "6.1.9" + "@storybook/api" "6.1.9" + "@storybook/channels" "6.1.9" + "@storybook/client-api" "6.1.9" + "@storybook/components" "6.1.9" + "@storybook/core-events" "6.1.9" + "@storybook/theming" "6.1.9" copy-to-clipboard "^3.0.8" core-js "^3.0.1" escape-html "^1.0.3" - fast-deep-equal "^2.0.1" + fast-deep-equal "^3.1.1" global "^4.3.2" lodash "^4.17.15" prop-types "^15.7.2" @@ -2216,175 +2426,209 @@ react-color "^2.17.0" react-lifecycles-compat "^3.0.4" react-select "^3.0.8" - -"@storybook/addons@5.3.14": - version "5.3.14" - resolved "https://registry.yarnpkg.com/@storybook/addons/-/addons-5.3.14.tgz#ff96c2c46a617f777c3660395017d2aef5319f19" - integrity sha512-zoN1MYlArdThp93i+Ogil/pihyx8n7nkrdSO0j9HUh6jUsGeFFEluPQZdRFte9NIoY6ZWSWwuEMDgrv2Pw9r2Q== - dependencies: - "@storybook/api" "5.3.14" - "@storybook/channels" "5.3.14" - "@storybook/client-logger" "5.3.14" - "@storybook/core-events" "5.3.14" + regenerator-runtime "^0.13.7" + +"@storybook/addons@6.1.9": + version "6.1.9" + resolved "https://registry.yarnpkg.com/@storybook/addons/-/addons-6.1.9.tgz#78f3cb27b7d934f091f311f89b6ca312d34f12b8" + integrity sha512-NRxdlGLmmSoVwlirVRgKC8xmW9cFkG+Sp5GEd4XkJDaaIg2vKR3RuFU9GuvIOVMxOhhERqhQ07bnDaAMKbFzGw== + dependencies: + "@storybook/api" "6.1.9" + "@storybook/channels" "6.1.9" + "@storybook/client-logger" "6.1.9" + "@storybook/core-events" "6.1.9" + "@storybook/router" "6.1.9" + "@storybook/theming" "6.1.9" core-js "^3.0.1" global "^4.3.2" - util-deprecate "^1.0.2" + regenerator-runtime "^0.13.7" -"@storybook/api@5.3.14": - version "5.3.14" - resolved "https://registry.yarnpkg.com/@storybook/api/-/api-5.3.14.tgz#8c2bb226a4a5de7974ee2ccce36986b72f462f1b" - integrity sha512-ANWRMTLEoAfu0IsXqbxmbTpxS8xTByZgLj20tH96bxgH1rJo9KAZnJ8A9kGYr+zklU8QnYvVIgmV3HESXII9zg== +"@storybook/api@6.1.9": + version "6.1.9" + resolved "https://registry.yarnpkg.com/@storybook/api/-/api-6.1.9.tgz#3f9bf00b2b18fa02965079fe775bd713677b30a3" + integrity sha512-S9SXlSiMeI450NIbOnx3UU9TZNyVD7jcBCjfNzhj0PqzRX/IG5Usj+R88Jm6MSIDjtsVjrWRCou+PrCh2xMnlQ== dependencies: - "@reach/router" "^1.2.1" - "@storybook/channels" "5.3.14" - "@storybook/client-logger" "5.3.14" - "@storybook/core-events" "5.3.14" + "@reach/router" "^1.3.3" + "@storybook/channels" "6.1.9" + "@storybook/client-logger" "6.1.9" + "@storybook/core-events" "6.1.9" "@storybook/csf" "0.0.1" - "@storybook/router" "5.3.14" - "@storybook/theming" "5.3.14" - "@types/reach__router" "^1.2.3" + "@storybook/router" "6.1.9" + "@storybook/semver" "^7.3.2" + "@storybook/theming" "6.1.9" + "@types/reach__router" "^1.3.5" core-js "^3.0.1" - fast-deep-equal "^2.0.1" + fast-deep-equal "^3.1.1" global "^4.3.2" lodash "^4.17.15" memoizerific "^1.11.3" - prop-types "^15.6.2" - react "^16.8.3" - semver "^6.0.0" - shallow-equal "^1.1.0" + regenerator-runtime "^0.13.7" store2 "^2.7.1" - telejson "^3.2.0" + telejson "^5.0.2" + ts-dedent "^2.0.0" util-deprecate "^1.0.2" -"@storybook/channel-postmessage@5.3.14": - version "5.3.14" - resolved "https://registry.yarnpkg.com/@storybook/channel-postmessage/-/channel-postmessage-5.3.14.tgz#768c87411d98caf09fdd92539b9edaaed26d5965" - integrity sha512-XKHxMSwW3movfTDOashuYlVCX3Hp7+X+amXc/xhDDzbiYjy3/CVm3LlkkM6v451IVEdK6pue4ewqZQWJAYAAEQ== +"@storybook/channel-postmessage@6.1.9": + version "6.1.9" + resolved "https://registry.yarnpkg.com/@storybook/channel-postmessage/-/channel-postmessage-6.1.9.tgz#5d73c67ba94bcf68b14138bba6c5bb0850c72c5e" + integrity sha512-tX7pD9Xrf1WsatpJqtJ6o8MlgxG7jH+oFhNPkGvUbWiolVDQmuDndwM8Hh1kUnOWlyE1AN5hlM7av8MY+9D3NA== dependencies: - "@storybook/channels" "5.3.14" - "@storybook/client-logger" "5.3.14" + "@storybook/channels" "6.1.9" + "@storybook/client-logger" "6.1.9" + "@storybook/core-events" "6.1.9" core-js "^3.0.1" global "^4.3.2" - telejson "^3.2.0" + qs "^6.6.0" + telejson "^5.0.2" -"@storybook/channels@5.3.14": - version "5.3.14" - resolved "https://registry.yarnpkg.com/@storybook/channels/-/channels-5.3.14.tgz#9969e27761a80afb495bc1475f0173f9b6ef5a76" - integrity sha512-k9QBf9Kwe+iGmdEK/kW5xprqem2SPfBVwET6LWvJkWOl9UQ9VoMuCHgV55p0tzjcugaqWWKoF9+FRMWxWRfsQg== +"@storybook/channels@6.1.9": + version "6.1.9" + resolved "https://registry.yarnpkg.com/@storybook/channels/-/channels-6.1.9.tgz#94f07ff3615b11c07d1902be6b6cd298c0eea55c" + integrity sha512-aV+KsZPuoTtFKSMUkSCyVlVmtVHkSH35dSbyMazjlUD9cOLwkXB1s+LZL/GxxSR6a6uR75V0QWxItfNxaJETMQ== dependencies: core-js "^3.0.1" + ts-dedent "^2.0.0" + util-deprecate "^1.0.2" -"@storybook/client-api@5.3.14": - version "5.3.14" - resolved "https://registry.yarnpkg.com/@storybook/client-api/-/client-api-5.3.14.tgz#5f4b199d2f2b193f9f5a856c5eb8be43a9113d12" - integrity sha512-1qx1NIwto5F9N24Fb6VzKyDzeaZHtWTZ7afPrg56e1tUu7jbog7rELdRezk8+YAujveyMDJu4MxnOSP01sv7YQ== +"@storybook/client-api@6.1.9": + version "6.1.9" + resolved "https://registry.yarnpkg.com/@storybook/client-api/-/client-api-6.1.9.tgz#d4a8d38bc657f26e4837831b961e085da1954d51" + integrity sha512-b2DFaGAS5G2ly3UJY5NJNXh/LxgLgSJLbqPL4t48MFW5XjH+rmEWXE9P+ujCaPclH1/y7mZRMprDj3ycDbRo3Q== dependencies: - "@storybook/addons" "5.3.14" - "@storybook/channel-postmessage" "5.3.14" - "@storybook/channels" "5.3.14" - "@storybook/client-logger" "5.3.14" - "@storybook/core-events" "5.3.14" + "@storybook/addons" "6.1.9" + "@storybook/channel-postmessage" "6.1.9" + "@storybook/channels" "6.1.9" + "@storybook/client-logger" "6.1.9" + "@storybook/core-events" "6.1.9" "@storybook/csf" "0.0.1" - "@types/webpack-env" "^1.15.0" + "@types/qs" "^6.9.0" + "@types/webpack-env" "^1.15.3" core-js "^3.0.1" - eventemitter3 "^4.0.0" global "^4.3.2" - is-plain-object "^3.0.0" lodash "^4.17.15" memoizerific "^1.11.3" qs "^6.6.0" + regenerator-runtime "^0.13.7" stable "^0.1.8" - ts-dedent "^1.1.0" + store2 "^2.7.1" + ts-dedent "^2.0.0" util-deprecate "^1.0.2" -"@storybook/client-logger@5.3.14": - version "5.3.14" - resolved "https://registry.yarnpkg.com/@storybook/client-logger/-/client-logger-5.3.14.tgz#85068f1b665a52163191eb5976f1581bce6df0e4" - integrity sha512-YCHEsOvo6zPb4udlyAwqr5W0Kv9mAEQmcX73w9IDvAxbjR00T7empW7qmbjvviftKB/5MEgDdiYbj64ccs3aqg== +"@storybook/client-logger@6.1.9": + version "6.1.9" + resolved "https://registry.yarnpkg.com/@storybook/client-logger/-/client-logger-6.1.9.tgz#1d61a64000d4691780d75e19b78fd44adfdb5d9c" + integrity sha512-i7Q2ky9+Jwv+wmnlOGxmDOEdmaTIB69OQnnZNWGKufOwoIMjn6QO0VifARyA9W++nNSijjJ5th84tLJALaoCTA== dependencies: core-js "^3.0.1" + global "^4.3.2" -"@storybook/components@5.3.14": - version "5.3.14" - resolved "https://registry.yarnpkg.com/@storybook/components/-/components-5.3.14.tgz#0f2f90113674e14ee74d5d16d6b3b1220cb0fa16" - integrity sha512-AsjkIFBrrqcBDLxGdmUHiauZo5gOL65eXx8WA7/yJDF8s45VVZX5Z0buOnjFyEhGVus02gwTov8da2irjL862A== +"@storybook/components@6.1.9": + version "6.1.9" + resolved "https://registry.yarnpkg.com/@storybook/components/-/components-6.1.9.tgz#f25d18f3a410cc7e9549ddb3c971c40d9108d4d8" + integrity sha512-cYYm3fHo9MW0bbl47lu1ncwulV7V9VEF8FC96uvys07oaCTFWKzQ0z/FD0nCqeK6eEz1+SEqnGwLFmOtqlRXDQ== dependencies: - "@storybook/client-logger" "5.3.14" - "@storybook/theming" "5.3.14" - "@types/react-syntax-highlighter" "11.0.2" - "@types/react-textarea-autosize" "^4.3.3" + "@popperjs/core" "^2.4.4" + "@storybook/client-logger" "6.1.9" + "@storybook/csf" "0.0.1" + "@storybook/theming" "6.1.9" + "@types/overlayscrollbars" "^1.9.0" + "@types/react-color" "^3.0.1" + "@types/react-syntax-highlighter" "11.0.4" core-js "^3.0.1" + fast-deep-equal "^3.1.1" global "^4.3.2" lodash "^4.17.15" - markdown-to-jsx "^6.9.1" + markdown-to-jsx "^6.11.4" memoizerific "^1.11.3" - polished "^3.3.1" - popper.js "^1.14.7" - prop-types "^15.7.2" - react "^16.8.3" - react-dom "^16.8.3" - react-focus-lock "^2.1.0" - react-helmet-async "^1.0.2" - react-popper-tooltip "^2.8.3" - react-syntax-highlighter "^11.0.2" - react-textarea-autosize "^7.1.0" - simplebar-react "^1.0.0-alpha.6" - ts-dedent "^1.1.0" + overlayscrollbars "^1.10.2" + polished "^3.4.4" + react-color "^2.17.0" + react-popper-tooltip "^3.1.0" + react-syntax-highlighter "^13.5.0" + react-textarea-autosize "^8.1.1" + ts-dedent "^2.0.0" -"@storybook/core-events@5.3.14": - version "5.3.14" - resolved "https://registry.yarnpkg.com/@storybook/core-events/-/core-events-5.3.14.tgz#d476eea7032670db1a84bef7e5baadb04c2de529" - integrity sha512-VCPLKqRugsOSx/smMJiJOvRgAzTrMpsbRuFw48kBGkQMP9TEV82Qe/341dv+f4GllPyBZyANG0p0m5+w7ZCURQ== +"@storybook/core-events@6.1.9": + version "6.1.9" + resolved "https://registry.yarnpkg.com/@storybook/core-events/-/core-events-6.1.9.tgz#0a88281837d1aa657a93a9abf7f5aad65b8d68e7" + integrity sha512-oOpqpjCTJCt0U5lnQ16OZU0iKIDh2/MIg4yrnDw+Pt6zGyX3zSvtB+9W8LQFnMwm+cXaNmiizGwt/W+4OiORjQ== dependencies: core-js "^3.0.1" -"@storybook/core@5.3.14", "@storybook/core@^5.3.14": - version "5.3.14" - resolved "https://registry.yarnpkg.com/@storybook/core/-/core-5.3.14.tgz#510f204219695045f249733bf94018e52c7b1448" - integrity sha512-Y57cchCRw1vvZe8OhMmgAkaHciGLm2eztdfzZMUmeHH8csBt/0RO5gYzOhWDGgdC2D9HSlaysZEDJ6sH3PChlw== - dependencies: - "@babel/plugin-proposal-class-properties" "^7.7.0" - "@babel/plugin-proposal-object-rest-spread" "^7.6.2" - "@babel/plugin-syntax-dynamic-import" "^7.2.0" - "@babel/plugin-transform-react-constant-elements" "^7.2.0" - "@babel/preset-env" "^7.4.5" - "@storybook/addons" "5.3.14" - "@storybook/channel-postmessage" "5.3.14" - "@storybook/client-api" "5.3.14" - "@storybook/client-logger" "5.3.14" - "@storybook/core-events" "5.3.14" +"@storybook/core@6.1.9", "@storybook/core@^6.1.9": + version "6.1.9" + resolved "https://registry.yarnpkg.com/@storybook/core/-/core-6.1.9.tgz#e6575e294cb4d2d9b57d5976a145cae8f4a88594" + integrity sha512-guz+R6eDX923Cw7NqgS5PrpTmmjDB+m5X1iF9pwKlpPTfzIiT/wTzJm4PwhFoGONNoXrItObX/6hW6OQbX4aOA== + dependencies: + "@babel/core" "^7.12.3" + "@babel/plugin-proposal-class-properties" "^7.12.1" + "@babel/plugin-proposal-decorators" "^7.12.1" + "@babel/plugin-proposal-export-default-from" "^7.12.1" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.12.1" + "@babel/plugin-proposal-object-rest-spread" "^7.12.1" + "@babel/plugin-proposal-optional-chaining" "^7.12.1" + "@babel/plugin-proposal-private-methods" "^7.12.1" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + "@babel/plugin-transform-arrow-functions" "^7.12.1" + "@babel/plugin-transform-block-scoping" "^7.12.1" + "@babel/plugin-transform-classes" "^7.12.1" + "@babel/plugin-transform-destructuring" "^7.12.1" + "@babel/plugin-transform-for-of" "^7.12.1" + "@babel/plugin-transform-parameters" "^7.12.1" + "@babel/plugin-transform-shorthand-properties" "^7.12.1" + "@babel/plugin-transform-spread" "^7.12.1" + "@babel/plugin-transform-template-literals" "^7.12.1" + "@babel/preset-env" "^7.12.1" + "@babel/preset-react" "^7.12.1" + "@babel/preset-typescript" "^7.12.1" + "@babel/register" "^7.12.1" + "@storybook/addons" "6.1.9" + "@storybook/api" "6.1.9" + "@storybook/channel-postmessage" "6.1.9" + "@storybook/channels" "6.1.9" + "@storybook/client-api" "6.1.9" + "@storybook/client-logger" "6.1.9" + "@storybook/components" "6.1.9" + "@storybook/core-events" "6.1.9" "@storybook/csf" "0.0.1" - "@storybook/node-logger" "5.3.14" - "@storybook/router" "5.3.14" - "@storybook/theming" "5.3.14" - "@storybook/ui" "5.3.14" + "@storybook/node-logger" "6.1.9" + "@storybook/router" "6.1.9" + "@storybook/semver" "^7.3.2" + "@storybook/theming" "6.1.9" + "@storybook/ui" "6.1.9" + "@types/glob-base" "^0.3.0" + "@types/micromatch" "^4.0.1" + "@types/node-fetch" "^2.5.4" airbnb-js-shims "^2.2.1" ansi-to-html "^0.6.11" autoprefixer "^9.7.2" - babel-plugin-add-react-displayname "^0.0.5" + babel-loader "^8.0.6" babel-plugin-emotion "^10.0.20" - babel-plugin-macros "^2.7.0" + babel-plugin-macros "^2.8.0" babel-preset-minify "^0.5.0 || 0.6.0-alpha.5" + better-opn "^2.0.0" boxen "^4.1.0" case-sensitive-paths-webpack-plugin "^2.2.0" - chalk "^3.0.0" - cli-table3 "0.5.1" - commander "^4.0.1" + chalk "^4.0.0" + cli-table3 "0.6.0" + commander "^5.0.0" core-js "^3.0.1" - corejs-upgrade-webpack-plugin "^2.2.0" - css-loader "^3.0.0" + cpy "^8.1.1" + css-loader "^3.5.3" detect-port "^1.3.0" dotenv-webpack "^1.7.0" - ejs "^2.7.4" + ejs "^3.1.2" express "^4.17.0" - file-loader "^4.2.0" + file-loader "^6.0.0" file-system-cache "^1.0.5" - find-cache-dir "^3.0.0" find-up "^4.1.0" - fs-extra "^8.0.1" + fork-ts-checker-webpack-plugin "^4.1.4" + fs-extra "^9.0.0" + glob "^7.1.6" glob-base "^0.3.0" + glob-promise "^3.4.0" global "^4.3.2" - html-webpack-plugin "^4.0.0-beta.2" + html-webpack-plugin "^4.2.1" inquirer "^7.0.0" interpret "^2.0.0" ip "^1.1.5" @@ -2392,30 +2636,31 @@ lazy-universal-dotenv "^3.0.1" micromatch "^4.0.2" node-fetch "^2.6.0" - open "^7.0.0" - pnp-webpack-plugin "1.5.0" + pkg-dir "^4.2.0" + pnp-webpack-plugin "1.6.4" postcss-flexbugs-fixes "^4.1.0" postcss-loader "^3.0.0" pretty-hrtime "^1.0.3" qs "^6.6.0" - raw-loader "^3.1.0" - react-dev-utils "^9.0.0" - regenerator-runtime "^0.13.3" - resolve "^1.11.0" + raw-loader "^4.0.1" + react-dev-utils "^10.0.0" + regenerator-runtime "^0.13.7" resolve-from "^5.0.0" - semver "^6.0.0" serve-favicon "^2.5.0" - shelljs "^0.8.3" - style-loader "^1.0.0" - terser-webpack-plugin "^2.1.2" - ts-dedent "^1.1.0" + shelljs "^0.8.4" + stable "^0.1.8" + style-loader "^1.2.1" + telejson "^5.0.2" + terser-webpack-plugin "^3.0.0" + ts-dedent "^2.0.0" unfetch "^4.1.0" - url-loader "^2.0.1" + url-loader "^4.0.0" util-deprecate "^1.0.2" - webpack "^4.33.0" + webpack "^4.44.2" webpack-dev-middleware "^3.7.0" + webpack-filter-warnings-plugin "^1.2.1" webpack-hot-middleware "^2.25.0" - webpack-virtual-modules "^0.2.0" + webpack-virtual-modules "^0.2.2" "@storybook/csf@0.0.1": version "0.0.1" @@ -2424,59 +2669,63 @@ dependencies: lodash "^4.17.15" -"@storybook/node-logger@5.3.14": - version "5.3.14" - resolved "https://registry.yarnpkg.com/@storybook/node-logger/-/node-logger-5.3.14.tgz#5e4e02585b37754bbebb8810ffb17c8ce706a1f8" - integrity sha512-/phRS49/hMZ5SU4EKUxX2kFepm9iw1cJBzggOz0GA1Yj4r9g1TA1H+OD7QvZvVTC3AESf/ZUJyaqnXEh/l+hpg== +"@storybook/node-logger@6.1.9": + version "6.1.9" + resolved "https://registry.yarnpkg.com/@storybook/node-logger/-/node-logger-6.1.9.tgz#c63a61f72209d76eeeffe9d151fec043864b9438" + integrity sha512-2gP9BSBXEOGIcUyzRdIkIJi1UEINUAIyuv9bfKODo4GfujRg7DLz/mpi/FdwmulGg/viXWSXa6ccb6ziIgY9RA== dependencies: "@types/npmlog" "^4.1.2" - chalk "^3.0.0" + chalk "^4.0.0" core-js "^3.0.1" npmlog "^4.1.2" pretty-hrtime "^1.0.3" - regenerator-runtime "^0.13.3" - -"@storybook/react@^5.3.14": - version "5.3.14" - resolved "https://registry.yarnpkg.com/@storybook/react/-/react-5.3.14.tgz#6715d9ee64e1c7b5c1e45cdbbf6df809bad60b8c" - integrity sha512-8n0oCkaxFMrimngxnISEQFkHGSF5z65Lh1XPypjIndIJ0b/IVWRJcUEh3M3xOaydFatEG+lfQbF/5OznyYEefA== - dependencies: - "@babel/plugin-transform-react-constant-elements" "^7.6.3" - "@babel/preset-flow" "^7.0.0" - "@babel/preset-react" "^7.0.0" - "@storybook/addons" "5.3.14" - "@storybook/core" "5.3.14" - "@storybook/node-logger" "5.3.14" - "@svgr/webpack" "^4.0.3" - "@types/webpack-env" "^1.15.0" + +"@storybook/react@^6.1.9": + version "6.1.9" + resolved "https://registry.yarnpkg.com/@storybook/react/-/react-6.1.9.tgz#063427015b3d0ce582b1b6b7826d40d963d265ce" + integrity sha512-HJWHQE+eCC7sz1vqvgmBMn2sA1uc0ByEj+NeSgyi45jBFI+Ke4a8hxx6k5XA7k9gLznqG8TPGg0z6EdQTJTLkQ== + dependencies: + "@babel/preset-flow" "^7.12.1" + "@babel/preset-react" "^7.12.1" + "@pmmmwh/react-refresh-webpack-plugin" "^0.4.2" + "@storybook/addons" "6.1.9" + "@storybook/core" "6.1.9" + "@storybook/node-logger" "6.1.9" + "@storybook/semver" "^7.3.2" + "@types/webpack-env" "^1.15.3" babel-plugin-add-react-displayname "^0.0.5" babel-plugin-named-asset-import "^0.3.1" - babel-plugin-react-docgen "^4.0.0" + babel-plugin-react-docgen "^4.2.1" core-js "^3.0.1" global "^4.3.2" lodash "^4.17.15" - mini-css-extract-plugin "^0.7.0" prop-types "^15.7.2" - react-dev-utils "^9.0.0" - regenerator-runtime "^0.13.3" - semver "^6.0.0" - ts-dedent "^1.1.0" - webpack "^4.33.0" - -"@storybook/router@5.3.14": - version "5.3.14" - resolved "https://registry.yarnpkg.com/@storybook/router/-/router-5.3.14.tgz#6535267624da5f54971c37e497df1c161f65be8f" - integrity sha512-O0KwQFncdBeq+O2Aq8UAFBVWjWmP5rtqoacUOFSGkXgObOnyniEraLiPH7rPtq2dAlSpgYI9+srQAZfo52Hz2A== - dependencies: - "@reach/router" "^1.2.1" - "@storybook/csf" "0.0.1" - "@types/reach__router" "^1.2.3" + react-dev-utils "^10.0.0" + react-docgen-typescript-plugin "^0.6.2" + react-refresh "^0.8.3" + regenerator-runtime "^0.13.7" + ts-dedent "^2.0.0" + webpack "^4.44.2" + +"@storybook/router@6.1.9": + version "6.1.9" + resolved "https://registry.yarnpkg.com/@storybook/router/-/router-6.1.9.tgz#c0b24dc3ab53d58541b81c7abea2f11d7fbbebf6" + integrity sha512-kIlmSFBnqI198oMCncFZR7MxoV5/kP6KS0paFcyu1XE1zO2ovV6eQZ8pPpOjSsD/ISu4Y44uE+ZDNsEehjj6GQ== + dependencies: + "@reach/router" "^1.3.3" + "@types/reach__router" "^1.3.5" core-js "^3.0.1" global "^4.3.2" - lodash "^4.17.15" memoizerific "^1.11.3" qs "^6.6.0" - util-deprecate "^1.0.2" + +"@storybook/semver@^7.3.2": + version "7.3.2" + resolved "https://registry.yarnpkg.com/@storybook/semver/-/semver-7.3.2.tgz#f3b9c44a1c9a0b933c04e66d0048fcf2fa10dac0" + integrity sha512-SWeszlsiPsMI0Ps0jVNtH64cI5c0UF3f7KgjVKJoNP30crQ6wUSddY2hsdeczZXEKVJGEn50Q60flcGsQGIcrg== + dependencies: + core-js "^3.6.5" + find-up "^4.1.0" "@storybook/storybook-deployer@^2.8.6": version "2.8.6" @@ -2489,63 +2738,59 @@ shelljs "^0.8.1" yargs "^15.0.0" -"@storybook/theming@5.3.14": - version "5.3.14" - resolved "https://registry.yarnpkg.com/@storybook/theming/-/theming-5.3.14.tgz#4923739ad0d7d673b7844f27da8a3c6cf118790f" - integrity sha512-raqXC3yJycEt1CrCAfnBYUA6pyJI80E9M26EeQl3UfytJOL6euprOi+D17QvxqBn7jmmf9ZDw5XRkvJhQ17Y7Q== +"@storybook/theming@6.1.9": + version "6.1.9" + resolved "https://registry.yarnpkg.com/@storybook/theming/-/theming-6.1.9.tgz#8c584aa623f3d6e33b1e3b3de2ec1f41bdc5d9ab" + integrity sha512-orzMQkyEhAQEi0E9iwmUkzh5yPHoYGBz17t2aydDeT6oGKii6if8Mq2oPVycfVKZ84QO7GFAS9q1nVCRcuD8oA== dependencies: - "@emotion/core" "^10.0.20" - "@emotion/styled" "^10.0.17" - "@storybook/client-logger" "5.3.14" + "@emotion/core" "^10.1.1" + "@emotion/is-prop-valid" "^0.8.6" + "@emotion/styled" "^10.0.23" + "@storybook/client-logger" "6.1.9" core-js "^3.0.1" deep-object-diff "^1.1.0" emotion-theming "^10.0.19" global "^4.3.2" memoizerific "^1.11.3" - polished "^3.3.1" - prop-types "^15.7.2" + polished "^3.4.4" resolve-from "^5.0.0" - ts-dedent "^1.1.0" - -"@storybook/ui@5.3.14": - version "5.3.14" - resolved "https://registry.yarnpkg.com/@storybook/ui/-/ui-5.3.14.tgz#f3c49241d615bb20cb6facef84b4c432a85d814b" - integrity sha512-4zQOxpcvbKqRevmFw3Er6AWr2MeEMQfnuYh4Vm5G5YpiTyM6PU0VTVRzKnkEbNBcgjClD7nwXSbkUJjW6MJ8SA== - dependencies: - "@emotion/core" "^10.0.20" - "@storybook/addons" "5.3.14" - "@storybook/api" "5.3.14" - "@storybook/channels" "5.3.14" - "@storybook/client-logger" "5.3.14" - "@storybook/components" "5.3.14" - "@storybook/core-events" "5.3.14" - "@storybook/router" "5.3.14" - "@storybook/theming" "5.3.14" + ts-dedent "^2.0.0" + +"@storybook/ui@6.1.9": + version "6.1.9" + resolved "https://registry.yarnpkg.com/@storybook/ui/-/ui-6.1.9.tgz#1ed3168d9fe5827285c13d8507dd1fd872830542" + integrity sha512-4MK5iTf7kI5DYVeWRiD6lkXdd0S6eiQJu9lvWqMOQJLOH5Bq77g0Ejo+38RTEQpV6we7hCPWWnRXQBjmJ2+19w== + dependencies: + "@emotion/core" "^10.1.1" + "@storybook/addons" "6.1.9" + "@storybook/api" "6.1.9" + "@storybook/channels" "6.1.9" + "@storybook/client-logger" "6.1.9" + "@storybook/components" "6.1.9" + "@storybook/core-events" "6.1.9" + "@storybook/router" "6.1.9" + "@storybook/semver" "^7.3.2" + "@storybook/theming" "6.1.9" + "@types/markdown-to-jsx" "^6.11.0" copy-to-clipboard "^3.0.8" core-js "^3.0.1" core-js-pure "^3.0.1" + downshift "^6.0.6" emotion-theming "^10.0.19" - fast-deep-equal "^2.0.1" - fuse.js "^3.4.6" + fuse.js "^3.6.1" global "^4.3.2" lodash "^4.17.15" - markdown-to-jsx "^6.9.3" + markdown-to-jsx "^6.11.4" memoizerific "^1.11.3" - polished "^3.3.1" - prop-types "^15.7.2" + polished "^3.4.4" qs "^6.6.0" - react "^16.8.3" - react-dom "^16.8.3" react-draggable "^4.0.3" react-helmet-async "^1.0.2" react-hotkeys "2.0.0" react-sizeme "^2.6.7" - regenerator-runtime "^0.13.2" + regenerator-runtime "^0.13.7" resolve-from "^5.0.0" - semver "^6.0.0" store2 "^2.7.1" - telejson "^3.2.0" - util-deprecate "^1.0.2" "@stylelint/postcss-css-in-js@^0.37.1": version "0.37.2" @@ -2562,111 +2807,6 @@ remark "^12.0.0" unist-util-find-all-after "^3.0.1" -"@svgr/babel-plugin-add-jsx-attribute@^4.2.0": - version "4.2.0" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-4.2.0.tgz#dadcb6218503532d6884b210e7f3c502caaa44b1" - integrity sha512-j7KnilGyZzYr/jhcrSYS3FGWMZVaqyCG0vzMCwzvei0coIkczuYMcniK07nI0aHJINciujjH11T72ICW5eL5Ig== - -"@svgr/babel-plugin-remove-jsx-attribute@^4.2.0": - version "4.2.0" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-4.2.0.tgz#297550b9a8c0c7337bea12bdfc8a80bb66f85abc" - integrity sha512-3XHLtJ+HbRCH4n28S7y/yZoEQnRpl0tvTZQsHqvaeNXPra+6vE5tbRliH3ox1yZYPCxrlqaJT/Mg+75GpDKlvQ== - -"@svgr/babel-plugin-remove-jsx-empty-expression@^4.2.0": - version "4.2.0" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-4.2.0.tgz#c196302f3e68eab6a05e98af9ca8570bc13131c7" - integrity sha512-yTr2iLdf6oEuUE9MsRdvt0NmdpMBAkgK8Bjhl6epb+eQWk6abBaX3d65UZ3E3FWaOwePyUgNyNCMVG61gGCQ7w== - -"@svgr/babel-plugin-replace-jsx-attribute-value@^4.2.0": - version "4.2.0" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-4.2.0.tgz#310ec0775de808a6a2e4fd4268c245fd734c1165" - integrity sha512-U9m870Kqm0ko8beHawRXLGLvSi/ZMrl89gJ5BNcT452fAjtF2p4uRzXkdzvGJJJYBgx7BmqlDjBN/eCp5AAX2w== - -"@svgr/babel-plugin-svg-dynamic-title@^4.3.0": - version "4.3.0" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-4.3.0.tgz#826c7d30f8f98f26bdb4af205a5dfbf1f04d80ec" - integrity sha512-3eI17Pb3jlg3oqV4Tie069n1SelYKBUpI90txDcnBWk4EGFW+YQGyQjy6iuJAReH0RnpUJ9jUExrt/xniGvhqw== - -"@svgr/babel-plugin-svg-em-dimensions@^4.2.0": - version "4.2.0" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-4.2.0.tgz#9a94791c9a288108d20a9d2cc64cac820f141391" - integrity sha512-C0Uy+BHolCHGOZ8Dnr1zXy/KgpBOkEUYY9kI/HseHVPeMbluaX3CijJr7D4C5uR8zrc1T64nnq/k63ydQuGt4w== - -"@svgr/babel-plugin-transform-react-native-svg@^4.2.0": - version "4.2.0" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-4.2.0.tgz#151487322843359a1ca86b21a3815fd21a88b717" - integrity sha512-7YvynOpZDpCOUoIVlaaOUU87J4Z6RdD6spYN4eUb5tfPoKGSF9OG2NuhgYnq4jSkAxcpMaXWPf1cePkzmqTPNw== - -"@svgr/babel-plugin-transform-svg-component@^4.2.0": - version "4.2.0" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-4.2.0.tgz#5f1e2f886b2c85c67e76da42f0f6be1b1767b697" - integrity sha512-hYfYuZhQPCBVotABsXKSCfel2slf/yvJY8heTVX1PCTaq/IgASq1IyxPPKJ0chWREEKewIU/JMSsIGBtK1KKxw== - -"@svgr/babel-preset@^4.3.0": - version "4.3.0" - resolved "https://registry.yarnpkg.com/@svgr/babel-preset/-/babel-preset-4.3.0.tgz#8a0bcc95ea7124762699e87a45ab11f408e8765e" - integrity sha512-Lgy1RJiZumGtv6yJroOxzFuL64kG/eIcivJQ7y9ljVWL+0QXvFz4ix1xMrmjMD+rpJWwj50ayCIcFelevG/XXg== - dependencies: - "@svgr/babel-plugin-add-jsx-attribute" "^4.2.0" - "@svgr/babel-plugin-remove-jsx-attribute" "^4.2.0" - "@svgr/babel-plugin-remove-jsx-empty-expression" "^4.2.0" - "@svgr/babel-plugin-replace-jsx-attribute-value" "^4.2.0" - "@svgr/babel-plugin-svg-dynamic-title" "^4.3.0" - "@svgr/babel-plugin-svg-em-dimensions" "^4.2.0" - "@svgr/babel-plugin-transform-react-native-svg" "^4.2.0" - "@svgr/babel-plugin-transform-svg-component" "^4.2.0" - -"@svgr/core@^4.3.0": - version "4.3.0" - resolved "https://registry.yarnpkg.com/@svgr/core/-/core-4.3.0.tgz#4a2bcb41e0946679a2ebe6b5bb2edd88ed35706b" - integrity sha512-Ycu1qrF5opBgKXI0eQg3ROzupalCZnSDETKCK/3MKN4/9IEmt3jPX/bbBjftklnRW+qqsCEpO0y/X9BTRw2WBg== - dependencies: - "@svgr/plugin-jsx" "^4.3.0" - camelcase "^5.3.1" - cosmiconfig "^5.2.0" - -"@svgr/hast-util-to-babel-ast@^4.2.0": - version "4.2.0" - resolved "https://registry.yarnpkg.com/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-4.2.0.tgz#dd743435a5f3a8e84a1da067f27b5fae3d7b6b63" - integrity sha512-IvAeb7gqrGB5TH9EGyBsPrMRH/QCzIuAkLySKvH2TLfLb2uqk98qtJamordRQTpHH3e6TORfBXoTo7L7Opo/Ow== - dependencies: - "@babel/types" "^7.4.0" - -"@svgr/plugin-jsx@^4.3.0": - version "4.3.0" - resolved "https://registry.yarnpkg.com/@svgr/plugin-jsx/-/plugin-jsx-4.3.0.tgz#6be203abc58e187545aa1b9a51df30d051b658e2" - integrity sha512-0ab8zJdSOTqPfjZtl89cjq2IOmXXUYV3Fs7grLT9ur1Al3+x3DSp2+/obrYKUGbQUnLq96RMjSZ7Icd+13vwlQ== - dependencies: - "@babel/core" "^7.4.3" - "@svgr/babel-preset" "^4.3.0" - "@svgr/hast-util-to-babel-ast" "^4.2.0" - rehype-parse "^6.0.0" - unified "^7.1.0" - vfile "^4.0.0" - -"@svgr/plugin-svgo@^4.2.0": - version "4.2.0" - resolved "https://registry.yarnpkg.com/@svgr/plugin-svgo/-/plugin-svgo-4.2.0.tgz#2a594a2d3312955e75fd87dc77ae51f377c809f3" - integrity sha512-zUEKgkT172YzHh3mb2B2q92xCnOAMVjRx+o0waZ1U50XqKLrVQ/8dDqTAtnmapdLsGurv8PSwenjLCUpj6hcvw== - dependencies: - cosmiconfig "^5.2.0" - merge-deep "^3.0.2" - svgo "^1.2.1" - -"@svgr/webpack@^4.0.3": - version "4.3.0" - resolved "https://registry.yarnpkg.com/@svgr/webpack/-/webpack-4.3.0.tgz#4462e05070d91c04806b99c30a703fb2b50b2bb9" - integrity sha512-rYcwi1pUnaZoOUEa8xhrX10FHnONvube1WBoJ5PQf/Cbl0GuiUUSdXSVaFgxWdeyv6jCG0vWH1mrCHhspaJv1Q== - dependencies: - "@babel/core" "^7.4.3" - "@babel/plugin-transform-react-constant-elements" "^7.0.0" - "@babel/preset-env" "^7.4.3" - "@babel/preset-react" "^7.0.0" - "@svgr/core" "^4.3.0" - "@svgr/plugin-jsx" "^4.3.0" - "@svgr/plugin-svgo" "^4.2.0" - loader-utils "^1.2.3" - "@szmarczak/http-timer@^1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421" @@ -2701,6 +2841,11 @@ "@babel/runtime" "^7.10.3" "@testing-library/dom" "^7.17.1" +"@types/anymatch@*": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@types/anymatch/-/anymatch-1.3.1.tgz#336badc1beecb9dacc38bea2cf32adf627a8421a" + integrity sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA== + "@types/aria-query@^4.2.0": version "4.2.0" resolved "https://registry.yarnpkg.com/@types/aria-query/-/aria-query-4.2.0.tgz#14264692a9d6e2fa4db3df5e56e94b5e25647ac0" @@ -2713,30 +2858,46 @@ dependencies: "@types/node" "*" +"@types/braces@*": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/braces/-/braces-3.0.0.tgz#7da1c0d44ff1c7eb660a36ec078ea61ba7eb42cb" + integrity sha512-TbH79tcyi9FHwbyboOKeRachRq63mSuWYXOflsNO9ZyE5ClQ/JaozNKl+aWUq87qPNsXasXxi2AbgfwIJ+8GQw== + "@types/color-name@^1.1.1": version "1.1.1" resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ== -"@types/events@*": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7" - integrity sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g== +"@types/glob-base@^0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@types/glob-base/-/glob-base-0.3.0.tgz#a581d688347e10e50dd7c17d6f2880a10354319d" + integrity sha1-pYHWiDR+EOUN18F9byiAoQNUMZ0= -"@types/glob@^7.1.1": - version "7.1.1" - resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.1.tgz#aa59a1c6e3fbc421e07ccd31a944c30eba521575" - integrity sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w== +"@types/glob@*", "@types/glob@^7.1.1": + version "7.1.3" + resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.3.tgz#e6ba80f36b7daad2c685acd9266382e68985c183" + integrity sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w== dependencies: - "@types/events" "*" "@types/minimatch" "*" "@types/node" "*" +"@types/hast@^2.0.0": + version "2.3.1" + resolved "https://registry.yarnpkg.com/@types/hast/-/hast-2.3.1.tgz#b16872f2a6144c7025f296fb9636a667ebb79cd9" + integrity sha512-viwwrB+6xGzw+G1eWpF9geV3fnsDgXqHG+cqgiHrvQfDUW5hzhCyV7Sy3UJxhfRFBsgky2SSW33qi/YrIkjX5Q== + dependencies: + "@types/unist" "*" + "@types/history@*": version "4.7.3" resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.3.tgz#856c99cdc1551d22c22b18b5402719affec9839a" integrity sha512-cS5owqtwzLN5kY+l+KgKdRJ/Cee8tlmQoGQuIE9tWnSmS3JMKzmxo2HIAk2wODMifGwO20d62xZQLYz+RLfXmw== +"@types/html-minifier-terser@^5.0.0": + version "5.1.1" + resolved "https://registry.yarnpkg.com/@types/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz#3c9ee980f1a10d6021ae6632ca3e79ca2ec4fb50" + integrity sha512-giAlZwstKbmvMk1OO7WXSj4OZ0keXAcl2TQq4LWHiiPH2ByaH7WeUzng+Qej8UPxxv+8lRTuouo0iaNDBuzIBA== + "@types/invariant@^2.2.29": version "2.2.29" resolved "https://registry.yarnpkg.com/@types/invariant/-/invariant-2.2.29.tgz#aa845204cd0a289f65d47e0de63a6a815e30cc66" @@ -2767,10 +2928,10 @@ "@types/istanbul-lib-coverage" "*" "@types/istanbul-lib-report" "*" -"@types/json-schema@^7.0.4": - version "7.0.5" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.5.tgz#dcce4430e64b443ba8945f0290fb564ad5bac6dd" - integrity sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ== +"@types/json-schema@^7.0.5", "@types/json-schema@^7.0.6": + version "7.0.6" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.6.tgz#f4c7ec43e81b319a9815115031709f26987891f0" + integrity sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw== "@types/json5@^0.0.29": version "0.0.29" @@ -2782,6 +2943,20 @@ resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.124.tgz#16fb067a8fc4be42f044c505d8b5316c6f54de93" integrity sha512-6bKEUVbHJ8z34jisA7lseJZD2g31SIvee3cGX2KEZCS4XXWNbjPZpmO1/2rGNR9BhGtaYr6iYXPl1EzRrDAFTA== +"@types/markdown-to-jsx@^6.11.0": + version "6.11.3" + resolved "https://registry.yarnpkg.com/@types/markdown-to-jsx/-/markdown-to-jsx-6.11.3.tgz#cdd1619308fecbc8be7e6a26f3751260249b020e" + integrity sha512-30nFYpceM/ZEvhGiqWjm5quLUxNeld0HCzJEXMZZDpq53FPkS85mTwkWtCXzCqq8s5JYLgM5W392a02xn8Bdaw== + dependencies: + "@types/react" "*" + +"@types/micromatch@^4.0.1": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@types/micromatch/-/micromatch-4.0.1.tgz#9381449dd659fc3823fd2a4190ceacc985083bc7" + integrity sha512-my6fLBvpY70KattTNzYOK6KU1oR1+UCz9ug/JbcF5UrEmeCt9P7DV2t7L8+t18mMPINqGQCE4O8PLOPbI84gxw== + dependencies: + "@types/braces" "*" + "@types/minimatch@*": version "3.0.3" resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" @@ -2792,6 +2967,14 @@ resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.0.tgz#69a23a3ad29caf0097f06eda59b361ee2f0639f6" integrity sha1-aaI6OtKcrwCX8G7aWbNh7i8GOfY= +"@types/node-fetch@^2.5.4": + version "2.5.7" + resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.5.7.tgz#20a2afffa882ab04d44ca786449a276f9f6bbf3c" + integrity sha512-o2WVNf5UhWRkxlf6eq+jMZDu7kjgpgJfl4xVNlvryc95O/6F2ld8ztKX+qu+Rjyet93WAWm5LjeX9H5FGkODvw== + dependencies: + "@types/node" "*" + form-data "^3.0.0" + "@types/node@*", "@types/node@^12.0.12", "@types/node@^12.12.6": version "12.19.1" resolved "https://registry.yarnpkg.com/@types/node/-/node-12.19.1.tgz#303f74c8a2b35644594139e948b2be470ae1186f" @@ -2822,6 +3005,11 @@ resolved "https://registry.yarnpkg.com/@types/npmlog/-/npmlog-4.1.2.tgz#d070fe6a6b78755d1092a3dc492d34c3d8f871c4" integrity sha512-4QQmOF5KlwfxJ5IGXFIudkeLCdMABz03RcUXu+LCb24zmln8QW6aDjuGl4d4XPVLf2j+FnjelHTP7dvceAFbhA== +"@types/overlayscrollbars@^1.9.0": + version "1.12.0" + resolved "https://registry.yarnpkg.com/@types/overlayscrollbars/-/overlayscrollbars-1.12.0.tgz#98456caceca8ad73bd5bb572632a585074e70764" + integrity sha512-h/pScHNKi4mb+TrJGDon8Yb06ujFG0mSg12wIO0sWMUF3dQIe2ExRRdNRviaNt9IjxIiOfnRr7FsQAdHwK4sMg== + "@types/parse-json@^4.0.0": version "4.0.0" resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" @@ -2849,10 +3037,15 @@ resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.2.tgz#690a1475b84f2a884fd07cd797c00f5f31356ea8" integrity sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw== -"@types/reach__router@^1.2.3": - version "1.2.6" - resolved "https://registry.yarnpkg.com/@types/reach__router/-/reach__router-1.2.6.tgz#b14cf1adbd1a365d204bbf6605cd9dd7b8816c87" - integrity sha512-Oh5DAVr/L2svBvubw6QEFpXGu295Y406BPs4i9t1n2pp7M+q3pmCmhzb9oZV5wncR41KCD3NHl1Yhi7uKnTPsA== +"@types/qs@^6.9.0": + version "6.9.5" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.5.tgz#434711bdd49eb5ee69d90c1d67c354a9a8ecb18b" + integrity sha512-/JHkVHtx/REVG0VVToGRGH2+23hsYLHdyG+GrvoUGlGAd0ErauXDyvHtRI/7H7mzLm+tBCKA7pfcpkQ1lf58iQ== + +"@types/reach__router@^1.3.5": + version "1.3.6" + resolved "https://registry.yarnpkg.com/@types/reach__router/-/reach__router-1.3.6.tgz#413417ce74caab331c70ce6a03a4c825188e4709" + integrity sha512-RHYataCUPQnt+GHoASyRLq6wmZ0n8jWlBW8Lxcwd30NN6vQfbmTeoSDfkgxO0S1lEzArp8OFDsq5KIs7FygjtA== dependencies: "@types/history" "*" "@types/react" "*" @@ -2864,10 +3057,10 @@ dependencies: "@types/react" "*" -"@types/react-syntax-highlighter@11.0.2": - version "11.0.2" - resolved "https://registry.yarnpkg.com/@types/react-syntax-highlighter/-/react-syntax-highlighter-11.0.2.tgz#a2e3ff657d7c47813f80ca930f3d959c31ec51e3" - integrity sha512-iMNcixH8330f2dq0RY+VOXCP8JFehgmOhLOtnO85Ty+qu0fHXJNEqWx5VuFv8v0aEq0U/N9d/k1yvA+c6PEmPw== +"@types/react-syntax-highlighter@11.0.4": + version "11.0.4" + resolved "https://registry.yarnpkg.com/@types/react-syntax-highlighter/-/react-syntax-highlighter-11.0.4.tgz#d86d17697db62f98046874f62fdb3e53a0bbc4cd" + integrity sha512-9GfTo3a0PHwQeTVoqs0g5bS28KkSY48pp5659wA+Dp4MqceDEa8EHBqrllJvvtyusszyJhViUEap0FDvlk/9Zg== dependencies: "@types/react" "*" @@ -2878,13 +3071,6 @@ dependencies: "@types/react" "*" -"@types/react-textarea-autosize@^4.3.3": - version "4.3.5" - resolved "https://registry.yarnpkg.com/@types/react-textarea-autosize/-/react-textarea-autosize-4.3.5.tgz#6c4d2753fa1864c98c0b2b517f67bb1f6e4c46de" - integrity sha512-PiDL83kPMTolyZAWW3lyzO6ktooTb9tFTntVy7CA83/qFLWKLJ5bLeRboy6J6j3b1e8h2Eec6gBTEOOJRjV14A== - dependencies: - "@types/react" "*" - "@types/react-transition-group@^4.2.0": version "4.4.0" resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.0.tgz#882839db465df1320e4753e6e9f70ca7e9b4d46d" @@ -2914,6 +3100,16 @@ dependencies: "@types/node" "*" +"@types/source-list-map@*": + version "0.1.2" + resolved "https://registry.yarnpkg.com/@types/source-list-map/-/source-list-map-0.1.2.tgz#0078836063ffaf17412349bba364087e0ac02ec9" + integrity sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA== + +"@types/tapable@*", "@types/tapable@^1.0.5": + version "1.0.6" + resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.6.tgz#a9ca4b70a18b270ccb2bc0aaafefd1d486b7ea74" + integrity sha512-W+bw9ds02rAQaMvaLYxAbJ6cvguW/iJXNT6lTssS1ps6QdrMKttqEAMEG/b5CR8TZl3/L7/lH0ZV5nNR1LXikA== + "@types/testing-library__react-hooks@^3.0.0": version "3.2.0" resolved "https://registry.yarnpkg.com/@types/testing-library__react-hooks/-/testing-library__react-hooks-3.2.0.tgz#52f3a109bef06080e3b1e3ae7ea1c014ce859897" @@ -2922,32 +3118,43 @@ "@types/react" "*" "@types/react-test-renderer" "*" +"@types/uglify-js@*": + version "3.11.1" + resolved "https://registry.yarnpkg.com/@types/uglify-js/-/uglify-js-3.11.1.tgz#97ff30e61a0aa6876c270b5f538737e2d6ab8ceb" + integrity sha512-7npvPKV+jINLu1SpSYVWG8KvyJBhBa8tmzMMdDoVc2pWUYHN8KIXlPJhjJ4LT97c4dXJA2SHL/q6ADbDriZN+Q== + dependencies: + source-map "^0.6.1" + "@types/unist@*", "@types/unist@^2.0.0", "@types/unist@^2.0.2": version "2.0.3" resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.3.tgz#9c088679876f374eb5983f150d4787aa6fb32d7e" integrity sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ== -"@types/vfile-message@*": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@types/vfile-message/-/vfile-message-1.0.1.tgz#e1e9895cc6b36c462d4244e64e6d0b6eaf65355a" - integrity sha512-mlGER3Aqmq7bqR1tTTIVHq8KSAFFRyGbrxuM8C/H82g6k7r2fS+IMEkIu3D7JHzG10NvPdR8DNx0jr0pwpp4dA== +"@types/webpack-env@^1.15.3": + version "1.16.0" + resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.16.0.tgz#8c0a9435dfa7b3b1be76562f3070efb3f92637b4" + integrity sha512-Fx+NpfOO0CpeYX2g9bkvX8O5qh9wrU1sOF4g8sft4Mu7z+qfe387YlyY8w8daDyDsKY5vUxM0yxkAYnbkRbZEw== + +"@types/webpack-sources@*": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@types/webpack-sources/-/webpack-sources-2.0.0.tgz#08216ab9be2be2e1499beaebc4d469cec81e82a7" + integrity sha512-a5kPx98CNFRKQ+wqawroFunvFqv7GHm/3KOI52NY9xWADgc8smu4R6prt4EU/M4QfVjvgBkMqU4fBhw3QfMVkg== dependencies: "@types/node" "*" - "@types/unist" "*" + "@types/source-list-map" "*" + source-map "^0.7.3" -"@types/vfile@^3.0.0": - version "3.0.2" - resolved "https://registry.yarnpkg.com/@types/vfile/-/vfile-3.0.2.tgz#19c18cd232df11ce6fa6ad80259bc86c366b09b9" - integrity sha512-b3nLFGaGkJ9rzOcuXRfHkZMdjsawuDD0ENL9fzTophtBg8FJHSGbH7daXkEpcwy3v7Xol3pAvsmlYyFhR4pqJw== +"@types/webpack@^4.41.8": + version "4.41.25" + resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.41.25.tgz#4d3b5aecc4e44117b376280fbfd2dc36697968c4" + integrity sha512-cr6kZ+4m9lp86ytQc1jPOJXgINQyz3kLLunZ57jznW+WIAL0JqZbGubQk4GlD42MuQL5JGOABrxdpqqWeovlVQ== dependencies: + "@types/anymatch" "*" "@types/node" "*" - "@types/unist" "*" - "@types/vfile-message" "*" - -"@types/webpack-env@^1.15.0": - version "1.15.0" - resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.15.0.tgz#bd9956d5044b1fb43e869a9ba9148862ff98d9fd" - integrity sha512-TfcyNecCz8Z9/s90gBOBniyzZrTru8u2Vp0VZODq4KEBaQu8bfXvu7o/KUOecMpzjbFPUA7aqgSq628Iue5BQg== + "@types/tapable" "*" + "@types/uglify-js" "*" + "@types/webpack-sources" "*" + source-map "^0.6.0" "@types/yargs-parser@*": version "15.0.0" @@ -2961,152 +3168,163 @@ dependencies: "@types/yargs-parser" "*" -"@webassemblyjs/ast@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.8.5.tgz#51b1c5fe6576a34953bf4b253df9f0d490d9e359" - integrity sha512-aJMfngIZ65+t71C3y2nBBg5FFG0Okt9m0XEgWZ7Ywgn1oMAT8cNwx00Uv1cQyHtidq0Xn94R4TAywO+LCQ+ZAQ== +"@webassemblyjs/ast@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.9.0.tgz#bd850604b4042459a5a41cd7d338cbed695ed964" + integrity sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA== dependencies: - "@webassemblyjs/helper-module-context" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/wast-parser" "1.8.5" + "@webassemblyjs/helper-module-context" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/wast-parser" "1.9.0" -"@webassemblyjs/floating-point-hex-parser@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.8.5.tgz#1ba926a2923613edce496fd5b02e8ce8a5f49721" - integrity sha512-9p+79WHru1oqBh9ewP9zW95E3XAo+90oth7S5Re3eQnECGq59ly1Ri5tsIipKGpiStHsUYmY3zMLqtk3gTcOtQ== +"@webassemblyjs/floating-point-hex-parser@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz#3c3d3b271bddfc84deb00f71344438311d52ffb4" + integrity sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA== -"@webassemblyjs/helper-api-error@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.8.5.tgz#c49dad22f645227c5edb610bdb9697f1aab721f7" - integrity sha512-Za/tnzsvnqdaSPOUXHyKJ2XI7PDX64kWtURyGiJJZKVEdFOsdKUCPTNEVFZq3zJ2R0G5wc2PZ5gvdTRFgm81zA== +"@webassemblyjs/helper-api-error@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz#203f676e333b96c9da2eeab3ccef33c45928b6a2" + integrity sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw== -"@webassemblyjs/helper-buffer@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.8.5.tgz#fea93e429863dd5e4338555f42292385a653f204" - integrity sha512-Ri2R8nOS0U6G49Q86goFIPNgjyl6+oE1abW1pS84BuhP1Qcr5JqMwRFT3Ah3ADDDYGEgGs1iyb1DGX+kAi/c/Q== +"@webassemblyjs/helper-buffer@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz#a1442d269c5feb23fcbc9ef759dac3547f29de00" + integrity sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA== -"@webassemblyjs/helper-code-frame@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.8.5.tgz#9a740ff48e3faa3022b1dff54423df9aa293c25e" - integrity sha512-VQAadSubZIhNpH46IR3yWO4kZZjMxN1opDrzePLdVKAZ+DFjkGD/rf4v1jap744uPVU6yjL/smZbRIIJTOUnKQ== +"@webassemblyjs/helper-code-frame@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz#647f8892cd2043a82ac0c8c5e75c36f1d9159f27" + integrity sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA== dependencies: - "@webassemblyjs/wast-printer" "1.8.5" + "@webassemblyjs/wast-printer" "1.9.0" -"@webassemblyjs/helper-fsm@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.8.5.tgz#ba0b7d3b3f7e4733da6059c9332275d860702452" - integrity sha512-kRuX/saORcg8se/ft6Q2UbRpZwP4y7YrWsLXPbbmtepKr22i8Z4O3V5QE9DbZK908dh5Xya4Un57SDIKwB9eow== +"@webassemblyjs/helper-fsm@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz#c05256b71244214671f4b08ec108ad63b70eddb8" + integrity sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw== -"@webassemblyjs/helper-module-context@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.8.5.tgz#def4b9927b0101dc8cbbd8d1edb5b7b9c82eb245" - integrity sha512-/O1B236mN7UNEU4t9X7Pj38i4VoU8CcMHyy3l2cV/kIF4U5KoHXDVqcDuOs1ltkac90IM4vZdHc52t1x8Yfs3g== +"@webassemblyjs/helper-module-context@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz#25d8884b76839871a08a6c6f806c3979ef712f07" + integrity sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g== dependencies: - "@webassemblyjs/ast" "1.8.5" - mamacro "^0.0.3" + "@webassemblyjs/ast" "1.9.0" -"@webassemblyjs/helper-wasm-bytecode@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.8.5.tgz#537a750eddf5c1e932f3744206551c91c1b93e61" - integrity sha512-Cu4YMYG3Ddl72CbmpjU/wbP6SACcOPVbHN1dI4VJNJVgFwaKf1ppeFJrwydOG3NDHxVGuCfPlLZNyEdIYlQ6QQ== +"@webassemblyjs/helper-wasm-bytecode@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz#4fed8beac9b8c14f8c58b70d124d549dd1fe5790" + integrity sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw== -"@webassemblyjs/helper-wasm-section@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.8.5.tgz#74ca6a6bcbe19e50a3b6b462847e69503e6bfcbf" - integrity sha512-VV083zwR+VTrIWWtgIUpqfvVdK4ff38loRmrdDBgBT8ADXYsEZ5mPQ4Nde90N3UYatHdYoDIFb7oHzMncI02tA== +"@webassemblyjs/helper-wasm-section@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz#5a4138d5a6292ba18b04c5ae49717e4167965346" + integrity sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw== dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-buffer" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/wasm-gen" "1.8.5" + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-buffer" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/wasm-gen" "1.9.0" -"@webassemblyjs/ieee754@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.8.5.tgz#712329dbef240f36bf57bd2f7b8fb9bf4154421e" - integrity sha512-aaCvQYrvKbY/n6wKHb/ylAJr27GglahUO89CcGXMItrOBqRarUMxWLJgxm9PJNuKULwN5n1csT9bYoMeZOGF3g== +"@webassemblyjs/ieee754@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz#15c7a0fbaae83fb26143bbacf6d6df1702ad39e4" + integrity sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg== dependencies: "@xtuc/ieee754" "^1.2.0" -"@webassemblyjs/leb128@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.8.5.tgz#044edeb34ea679f3e04cd4fd9824d5e35767ae10" - integrity sha512-plYUuUwleLIziknvlP8VpTgO4kqNaH57Y3JnNa6DLpu/sGcP6hbVdfdX5aHAV716pQBKrfuU26BJK29qY37J7A== +"@webassemblyjs/leb128@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.9.0.tgz#f19ca0b76a6dc55623a09cffa769e838fa1e1c95" + integrity sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw== dependencies: "@xtuc/long" "4.2.2" -"@webassemblyjs/utf8@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.8.5.tgz#a8bf3b5d8ffe986c7c1e373ccbdc2a0915f0cedc" - integrity sha512-U7zgftmQriw37tfD934UNInokz6yTmn29inT2cAetAsaU9YeVCveWEwhKL1Mg4yS7q//NGdzy79nlXh3bT8Kjw== +"@webassemblyjs/utf8@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.9.0.tgz#04d33b636f78e6a6813227e82402f7637b6229ab" + integrity sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w== -"@webassemblyjs/wasm-edit@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.8.5.tgz#962da12aa5acc1c131c81c4232991c82ce56e01a" - integrity sha512-A41EMy8MWw5yvqj7MQzkDjU29K7UJq1VrX2vWLzfpRHt3ISftOXqrtojn7nlPsZ9Ijhp5NwuODuycSvfAO/26Q== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-buffer" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/helper-wasm-section" "1.8.5" - "@webassemblyjs/wasm-gen" "1.8.5" - "@webassemblyjs/wasm-opt" "1.8.5" - "@webassemblyjs/wasm-parser" "1.8.5" - "@webassemblyjs/wast-printer" "1.8.5" - -"@webassemblyjs/wasm-gen@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.8.5.tgz#54840766c2c1002eb64ed1abe720aded714f98bc" - integrity sha512-BCZBT0LURC0CXDzj5FXSc2FPTsxwp3nWcqXQdOZE4U7h7i8FqtFK5Egia6f9raQLpEKT1VL7zr4r3+QX6zArWg== +"@webassemblyjs/wasm-edit@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz#3fe6d79d3f0f922183aa86002c42dd256cfee9cf" + integrity sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-buffer" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/helper-wasm-section" "1.9.0" + "@webassemblyjs/wasm-gen" "1.9.0" + "@webassemblyjs/wasm-opt" "1.9.0" + "@webassemblyjs/wasm-parser" "1.9.0" + "@webassemblyjs/wast-printer" "1.9.0" + +"@webassemblyjs/wasm-gen@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz#50bc70ec68ded8e2763b01a1418bf43491a7a49c" + integrity sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA== dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/ieee754" "1.8.5" - "@webassemblyjs/leb128" "1.8.5" - "@webassemblyjs/utf8" "1.8.5" + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/ieee754" "1.9.0" + "@webassemblyjs/leb128" "1.9.0" + "@webassemblyjs/utf8" "1.9.0" -"@webassemblyjs/wasm-opt@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.8.5.tgz#b24d9f6ba50394af1349f510afa8ffcb8a63d264" - integrity sha512-HKo2mO/Uh9A6ojzu7cjslGaHaUU14LdLbGEKqTR7PBKwT6LdPtLLh9fPY33rmr5wcOMrsWDbbdCHq4hQUdd37Q== +"@webassemblyjs/wasm-opt@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz#2211181e5b31326443cc8112eb9f0b9028721a61" + integrity sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A== dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-buffer" "1.8.5" - "@webassemblyjs/wasm-gen" "1.8.5" - "@webassemblyjs/wasm-parser" "1.8.5" + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-buffer" "1.9.0" + "@webassemblyjs/wasm-gen" "1.9.0" + "@webassemblyjs/wasm-parser" "1.9.0" -"@webassemblyjs/wasm-parser@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.8.5.tgz#21576f0ec88b91427357b8536383668ef7c66b8d" - integrity sha512-pi0SYE9T6tfcMkthwcgCpL0cM9nRYr6/6fjgDtL6q/ZqKHdMWvxitRi5JcZ7RI4SNJJYnYNaWy5UUrHQy998lw== +"@webassemblyjs/wasm-parser@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz#9d48e44826df4a6598294aa6c87469d642fff65e" + integrity sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA== dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-api-error" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/ieee754" "1.8.5" - "@webassemblyjs/leb128" "1.8.5" - "@webassemblyjs/utf8" "1.8.5" + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-api-error" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/ieee754" "1.9.0" + "@webassemblyjs/leb128" "1.9.0" + "@webassemblyjs/utf8" "1.9.0" -"@webassemblyjs/wast-parser@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.8.5.tgz#e10eecd542d0e7bd394f6827c49f3df6d4eefb8c" - integrity sha512-daXC1FyKWHF1i11obK086QRlsMsY4+tIOKgBqI1lxAnkp9xe9YMcgOxm9kLe+ttjs5aWV2KKE1TWJCN57/Btsg== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/floating-point-hex-parser" "1.8.5" - "@webassemblyjs/helper-api-error" "1.8.5" - "@webassemblyjs/helper-code-frame" "1.8.5" - "@webassemblyjs/helper-fsm" "1.8.5" +"@webassemblyjs/wast-parser@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz#3031115d79ac5bd261556cecc3fa90a3ef451914" + integrity sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/floating-point-hex-parser" "1.9.0" + "@webassemblyjs/helper-api-error" "1.9.0" + "@webassemblyjs/helper-code-frame" "1.9.0" + "@webassemblyjs/helper-fsm" "1.9.0" "@xtuc/long" "4.2.2" -"@webassemblyjs/wast-printer@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.8.5.tgz#114bbc481fd10ca0e23b3560fa812748b0bae5bc" - integrity sha512-w0U0pD4EhlnvRyeJzBqaVSJAo9w/ce7/WPogeXLzGkO6hzhr4GnQIZ4W4uUt5b9ooAaXPtnXlj0gzsXEOUNYMg== +"@webassemblyjs/wast-printer@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz#4935d54c85fef637b00ce9f52377451d00d47899" + integrity sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA== dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/wast-parser" "1.8.5" + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/wast-parser" "1.9.0" "@xtuc/long" "4.2.2" +"@webpack-contrib/schema-utils@^1.0.0-beta.0": + version "1.0.0-beta.0" + resolved "https://registry.yarnpkg.com/@webpack-contrib/schema-utils/-/schema-utils-1.0.0-beta.0.tgz#bf9638c9464d177b48209e84209e23bee2eb4f65" + integrity sha512-LonryJP+FxQQHsjGBi6W786TQB1Oym+agTpY0c+Kj8alnIw+DLUJb6SI8Y1GHGhLCH1yPRrucjObUmxNICQ1pg== + dependencies: + ajv "^6.1.0" + ajv-keywords "^3.1.0" + chalk "^2.3.2" + strip-ansi "^4.0.0" + text-table "^0.2.0" + webpack-log "^1.1.2" + "@wry/equality@^0.1.2": version "0.1.9" resolved "https://registry.yarnpkg.com/@wry/equality/-/equality-0.1.9.tgz#b13e18b7a8053c6858aa6c85b54911fb31e3a909" @@ -3286,10 +3504,10 @@ acorn@^3.0.4: resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" integrity sha1-ReN/s56No/JbruP/U2niu18iAXo= -acorn@^6.0.1, acorn@^6.0.2, acorn@^6.0.7, acorn@^6.2.1: - version "6.4.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.1.tgz#531e58ba3f51b9dacb9a6646ca4debf5b14ca474" - integrity sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA== +acorn@^6.0.1, acorn@^6.0.2, acorn@^6.0.7, acorn@^6.4.1: + version "6.4.2" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6" + integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ== acorn@^7.0.0, acorn@^7.1.1, acorn@^7.4.0: version "7.4.1" @@ -3339,10 +3557,10 @@ addons-linter@1.14.0: optionalDependencies: fsevents "2.0.7" -address@1.0.3, address@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/address/-/address-1.0.3.tgz#b5f50631f8d6cec8bd20c963963afb55e06cbce9" - integrity sha512-z55ocwKBRLryBs394Sm3ushTtBeg6VAeuku7utSoSnsJKvKcnXFIyC6vh27n3rXyxSgkJBBCAvyOn7gSUcTYjg== +address@1.1.2, address@^1.0.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/address/-/address-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6" + integrity sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA== adjust-sourcemap-loader@3.0.0: version "3.0.0" @@ -3462,10 +3680,10 @@ ajv-keywords@^1.0.0: resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c" integrity sha1-MU3QpLM2j609/NxU7eYXG4htrzw= -ajv-keywords@^3.1.0, ajv-keywords@^3.4.1: - version "3.4.1" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.4.1.tgz#ef916e271c64ac12171fd8384eaae6b2345854da" - integrity sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ== +ajv-keywords@^3.1.0, ajv-keywords@^3.4.1, ajv-keywords@^3.5.2: + version "3.5.2" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" + integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== ajv-merge-patch@4.1.0: version "4.1.0" @@ -3493,7 +3711,7 @@ ajv@^4.7.0: co "^4.6.0" json-stable-stringify "^1.0.1" -ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.2, ajv@^6.12.4, ajv@^6.5.5, ajv@^6.9.1: +ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.4, ajv@^6.12.5, ajv@^6.5.5, ajv@^6.9.1: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -3589,7 +3807,7 @@ ansi-gray@^0.1.1: dependencies: ansi-wrap "0.1.0" -ansi-html@0.0.7: +ansi-html@0.0.7, ansi-html@^0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/ansi-html/-/ansi-html-0.0.7.tgz#813584021962a9e9e6fd039f940d12f56ca7859e" integrity sha1-gTWEAhliqenm/QOflA0S9WynhZ4= @@ -3891,11 +4109,6 @@ array-filter@^1.0.0: resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-1.0.0.tgz#baf79e62e6ef4c2a4c0b831232daffec251f9d83" integrity sha1-uveeYubvTCpMC4MSMtr/7CUfnYM= -array-filter@~0.0.0: - version "0.0.1" - resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-0.0.1.tgz#7da8cf2e26628ed732803581fd21f67cacd2eeec" - integrity sha1-fajPLiZijtcygDWB/SH2fKzS7uw= - array-find-index@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" @@ -3935,16 +4148,6 @@ array-last@^1.1.1: dependencies: is-number "^4.0.0" -array-map@~0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/array-map/-/array-map-0.0.0.tgz#88a2bab73d1cf7bcd5c1b118a003f66f665fa662" - integrity sha1-iKK6tz0c97zVwbEYoAP2b2ZfpmI= - -array-reduce@~0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/array-reduce/-/array-reduce-0.0.0.tgz#173899d3ffd1c7d9383e4479525dbe278cab5f2b" - integrity sha1-FziZ0//Rx9k4PkR5Ul2+J4yrXys= - array-slice@^0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/array-slice/-/array-slice-0.2.3.tgz#dd3cfb80ed7973a75117cdac69b0b99ec86186f5" @@ -3964,7 +4167,7 @@ array-sort@^1.0.0: get-value "^2.0.6" kind-of "^5.0.2" -array-union@^1.0.1: +array-union@^1.0.1, array-union@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" integrity sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk= @@ -4036,7 +4239,7 @@ arrify@^2.0.1: resolved "https://registry.yarnpkg.com/arrify/-/arrify-2.0.1.tgz#c9655e9331e0abcd588d2a7cad7e9956f66701fa" integrity sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug== -asap@^2.0.0, asap@^2.0.6, asap@~2.0.3: +asap@^2.0.0, asap@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY= @@ -4115,12 +4318,14 @@ assign-symbols@^1.0.0: resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= -ast-types@0.11.3: - version "0.11.3" - resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.11.3.tgz#c20757fe72ee71278ea0ff3d87e5c2ca30d9edf8" - integrity sha512-XA5o5dsNw8MhyW0Q7MWXJWc4oOzZKbdsEJq45h7c8q/d9DwWZ5F2ugUc1PuMLPGsUnphCt/cNDHu8JeBbxf1qA== +ast-types@0.x.x, ast-types@^0.14.2: + version "0.14.2" + resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.14.2.tgz#600b882df8583e3cd4f2df5fa20fa83759d4bdfd" + integrity sha512-O0yuUDnZeQDL+ncNGlJ78BiO4jnYI3bvMsD5prT0/nsgijG/LpNBIr63gTjVTNsiGkgQhiyCShTgxt8oXOrklA== + dependencies: + tslib "^2.0.1" -ast-types@0.x.x, ast-types@^0.13.2: +ast-types@^0.13.2: version "0.13.2" resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.13.2.tgz#df39b677a911a83f3a049644fb74fdded23cea48" integrity sha512-uWMHxJxtfj/1oZClOxDEV1sQ1HCDkA4MG8Gr69KKeBjEVH0R84WlejZ0y2DcwyBlpAEMltmVYkVgqfLFb2oyiA== @@ -4301,6 +4506,11 @@ asynckit@^0.4.0: resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= +at-least-node@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" + integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== + atob@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.1.tgz#ae2d5a729477f289d60dd7f96a6314a22dd6c22a" @@ -4585,10 +4795,10 @@ babel-plugin-check-es2015-constants@^6.22.0: dependencies: babel-runtime "^6.22.0" -babel-plugin-dynamic-import-node@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.0.tgz#f00f507bdaa3c3e3ff6e7e5e98d90a7acab96f7f" - integrity sha512-o6qFkpeQEBxcqt0XYlWzAVxNCSCZdUgcR8IRlhD/8DylxjjO4foPcvTW0GGKa/cVt3rvxZ7o5ippJ+/0nvLhlQ== +babel-plugin-dynamic-import-node@^2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz#84fda19c976ec5c6defef57f9427b3def66e17a3" + integrity sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ== dependencies: object.assign "^4.1.0" @@ -4608,7 +4818,7 @@ babel-plugin-emotion@^10.0.20, babel-plugin-emotion@^10.0.27: find-root "^1.1.0" source-map "^0.5.7" -babel-plugin-macros@^2.0.0, babel-plugin-macros@^2.7.0: +babel-plugin-macros@^2.0.0, babel-plugin-macros@^2.8.0: version "2.8.0" resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-2.8.0.tgz#0f958a7cc6556b1e65344465d99111a1e5e10138" integrity sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg== @@ -4696,14 +4906,14 @@ babel-plugin-named-asset-import@^0.3.1: resolved "https://registry.yarnpkg.com/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.2.tgz#20978ed446b8e1bf4a2f42d0a94c0ece85f75f4f" integrity sha512-CxwvxrZ9OirpXQ201Ec57OmGhmI8/ui/GwTDy0hSp6CmRvgRC0pSair6Z04Ck+JStA0sMPZzSJ3uE4n17EXpPQ== -babel-plugin-react-docgen@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/babel-plugin-react-docgen/-/babel-plugin-react-docgen-4.1.0.tgz#1dfa447dac9ca32d625a123df5733a9e47287c26" - integrity sha512-vzpnBlfGv8XOhJM2zbPyyqw2OLEbelgZZsaaRRTpVwNKuYuc+pUg4+dy7i9gCRms0uOQn4osX571HRcCJMJCmA== +babel-plugin-react-docgen@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/babel-plugin-react-docgen/-/babel-plugin-react-docgen-4.2.1.tgz#7cc8e2f94e8dc057a06e953162f0810e4e72257b" + integrity sha512-UQ0NmGHj/HAqi5Bew8WvNfCk8wSsmdgNd8ZdMjBCICtyCJCq9LiqgqvjCYe570/Wg7AQArSq1VQ60Dd/CHN7mQ== dependencies: + ast-types "^0.14.2" lodash "^4.17.15" react-docgen "^5.0.0" - recast "^0.14.7" babel-plugin-syntax-async-functions@^6.8.0: version "6.13.0" @@ -5270,6 +5480,13 @@ better-assert@~1.0.0: dependencies: callsite "1.0.0" +better-opn@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/better-opn/-/better-opn-2.1.1.tgz#94a55b4695dc79288f31d7d0e5f658320759f7c6" + integrity sha512-kIPXZS5qwyKiX/HcRvDYfmBQUa8XP17I0mYZZ0y4UhpYOSvtsLHDYqmomS+Mj20aDvD3knEiQ0ecQy2nhio3yA== + dependencies: + open "^7.0.3" + big.js@^5.1.2, big.js@^5.2.2: version "5.2.2" resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" @@ -5831,14 +6048,15 @@ browserify@^16.1.0, browserify@^16.5.1: vm-browserify "^1.0.0" xtend "^4.0.0" -browserslist@4.5.4: - version "4.5.4" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.5.4.tgz#166c4ecef3b51737a42436ea8002aeea466ea2c7" - integrity sha512-rAjx494LMjqKnMPhFkuLmLp8JWEX0o8ADTGeAbOqaF+XCvYLreZrG5uVjnPBlAQ8REZK4pzXGvp0bWgrFtKaag== +browserslist@4.10.0: + version "4.10.0" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.10.0.tgz#f179737913eaf0d2b98e4926ac1ca6a15cbcc6a9" + integrity sha512-TpfK0TDgv71dzuTsEAlQiHeWQ/tiPqgNZVdv046fvNtBZrjbv2O3TsWCDU0AWGJJKCF/KsjNdLzR9hXOsh/CfA== dependencies: - caniuse-lite "^1.0.30000955" - electron-to-chromium "^1.3.122" - node-releases "^1.1.13" + caniuse-lite "^1.0.30001035" + electron-to-chromium "^1.3.378" + node-releases "^1.1.52" + pkg-up "^3.1.0" browserslist@^3.1.1, browserslist@^3.2.6: version "3.2.8" @@ -5848,15 +6066,16 @@ browserslist@^3.1.1, browserslist@^3.2.6: caniuse-lite "^1.0.30000844" electron-to-chromium "^1.3.47" -browserslist@^4.12.0, browserslist@^4.6.0: - version "4.13.0" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.13.0.tgz#42556cba011e1b0a2775b611cba6a8eca18e940d" - integrity sha512-MINatJ5ZNrLnQ6blGvePd/QOz9Xtu+Ne+x29iQSCHfkU5BugKVJwZKn/iiL8UbpIpa3JhviKjz+XxMo0m2caFQ== +browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4.14.7: + version "4.14.7" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.14.7.tgz#c071c1b3622c1c2e790799a37bb09473a4351cb6" + integrity sha512-BSVRLCeG3Xt/j/1cCGj1019Wbty0H+Yvu2AOuZSuoaUWn3RatbL33Cxk+Q4jRMRAbOm0p7SLravLjpnT6s0vzQ== dependencies: - caniuse-lite "^1.0.30001093" - electron-to-chromium "^1.3.488" - escalade "^3.0.1" - node-releases "^1.1.58" + caniuse-lite "^1.0.30001157" + colorette "^1.2.1" + electron-to-chromium "^1.3.591" + escalade "^3.1.1" + node-releases "^1.1.66" bs58@4.0.1, bs58@^4.0.0, bs58@^4.0.1: version "4.0.1" @@ -5998,15 +6217,7 @@ buffer@^4.3.0: ieee754 "^1.1.4" isarray "^1.0.0" -buffer@^5.0.5: - version "5.4.3" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.4.3.tgz#3fbc9c69eb713d323e3fc1a895eee0710c072115" - integrity sha512-zvj65TkFeIt3i6aj5bIvJDzjjQQGs4o/sNoezg1F1kYap9Nu2jcUdpwzRSJTHMMzG0H7bZkn4rNQpImhuxWX2A== - dependencies: - base64-js "^1.0.2" - ieee754 "^1.1.4" - -buffer@^5.2.1: +buffer@^5.0.5, buffer@^5.2.1: version "5.7.1" resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== @@ -6097,31 +6308,7 @@ cacache@^12.0.2: unique-filename "^1.1.1" y18n "^4.0.0" -cacache@^13.0.1: - version "13.0.1" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-13.0.1.tgz#a8000c21697089082f85287a1aec6e382024a71c" - integrity sha512-5ZvAxd05HDDU+y9BVvcqYu2LLXmPnQ0hW62h32g4xBTgL/MppR4/04NHfj/ycM2y6lmTnbw6HVi+1eN0Psba6w== - dependencies: - chownr "^1.1.2" - figgy-pudding "^3.5.1" - fs-minipass "^2.0.0" - glob "^7.1.4" - graceful-fs "^4.2.2" - infer-owner "^1.0.4" - lru-cache "^5.1.1" - minipass "^3.0.0" - minipass-collect "^1.0.2" - minipass-flush "^1.0.5" - minipass-pipeline "^1.2.2" - mkdirp "^0.5.1" - move-concurrently "^1.0.1" - p-map "^3.0.0" - promise-inflight "^1.0.1" - rimraf "^2.7.1" - ssri "^7.0.0" - unique-filename "^1.1.1" - -cacache@^15.0.4: +cacache@^15.0.4, cacache@^15.0.5: version "15.0.5" resolved "https://registry.yarnpkg.com/cacache/-/cacache-15.0.5.tgz#69162833da29170d6732334643c60e005f5f17d0" integrity sha512-lloiL22n7sOjEEXdL8NAjTgv9a1u43xICE9/203qonkZUCj5X1UEWIdf2/Y0d6QcCtMzbKQyhrcDbdvlZTs/+A== @@ -6226,13 +6413,6 @@ callbackify@^1.1.0: resolved "https://registry.yarnpkg.com/callbackify/-/callbackify-1.1.0.tgz#d2a36986d28aa69714526c111209beeb9979d31e" integrity sha1-0qNphtKKppcUUmwREgm+65l50x4= -caller-callsite@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/caller-callsite/-/caller-callsite-2.0.0.tgz#847e0fce0a223750a9a027c54b33731ad3154134" - integrity sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ= - dependencies: - callsites "^2.0.0" - caller-path@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" @@ -6240,13 +6420,6 @@ caller-path@^0.1.0: dependencies: callsites "^0.2.0" -caller-path@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-2.0.0.tgz#468f83044e369ab2010fac5f06ceee15bb2cb1f4" - integrity sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ= - dependencies: - caller-callsite "^2.0.0" - callsite@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/callsite/-/callsite-1.0.0.tgz#280398e5d664bd74038b6f0905153e6e8af1bc20" @@ -6257,23 +6430,18 @@ callsites@^0.2.0: resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" integrity sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo= -callsites@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" - integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA= - callsites@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== -camel-case@3.0.x: - version "3.0.0" - resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-3.0.0.tgz#ca3c3688a4e9cf3a4cda777dc4dcbc713249cf73" - integrity sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M= +camel-case@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-4.1.1.tgz#1fc41c854f00e2f7d0139dfeba1542d6896fe547" + integrity sha512-7fa2WcG4fYFkclIvEmxBbTvmibwF2/agfEBc6q3lOpVu0A13ltLsA+Hr/8Hp6kp5f+G7hKi6t8lys6XxP+1K6Q== dependencies: - no-case "^2.2.0" - upper-case "^1.1.1" + pascal-case "^3.1.1" + tslib "^1.10.0" camelcase-keys@^2.0.0: version "2.1.0" @@ -6322,15 +6490,10 @@ camelcase@^6.0.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.0.0.tgz#5259f7c30e35e278f1bdc2a4d91230b37cad981e" integrity sha512-8KMDF1Vz2gzOq54ONPJS65IvTUaB1cHJ2DMM7MbPmLZljDH1qpzzLsWdiN9pHh6qvkRVDTi/07+eNGch/oLU4w== -can-use-dom@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/can-use-dom/-/can-use-dom-0.1.0.tgz#22cc4a34a0abc43950f42c6411024a3f6366b45a" - integrity sha1-IsxKNKCrxDlQ9CxkEQJKP2NmtFo= - -caniuse-lite@^1.0.30000810, caniuse-lite@^1.0.30000844, caniuse-lite@^1.0.30000955, caniuse-lite@^1.0.30001093, caniuse-lite@^1.0.30001097: - version "1.0.30001100" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001100.tgz#2a58615e0c01cf716ab349b20ca4d86ef944aa4e" - integrity sha512-0eYdp1+wFCnMlCj2oudciuQn2B9xAFq3WpgpcBIZTxk/1HNA/O2YA7rpeYhnOqsqAJq1AHUgx6i1jtafg7m2zA== +caniuse-lite@^1.0.30000810, caniuse-lite@^1.0.30000844, caniuse-lite@^1.0.30001035, caniuse-lite@^1.0.30001097, caniuse-lite@^1.0.30001157: + version "1.0.30001162" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001162.tgz#9f83aad1f42539ce9aab58bb177598f2f8e22ec6" + integrity sha512-E9FktFxaNnp4ky3ucIGzEXLM+Knzlpuq1oN1sFAU0KeayygabGTmOsndpo8QrL4D9pcThlf4D2pUKaDxPCUmVw== capture-stack-trace@^1.0.0: version "1.0.1" @@ -6362,7 +6525,7 @@ cbor-sync@^1.0.4: resolved "https://registry.yarnpkg.com/cbor-sync/-/cbor-sync-1.0.4.tgz#5a11a1ab75c2a14d1af1b237fd84aa8c1593662f" integrity sha512-GWlXN4wiz0vdWWXBU71Dvc1q3aBo0HytqwAZnXF1wOwjqNnDWA1vZ1gDMFLlqohak31VQzmhiYfiCX5QSSfagA== -ccount@^1.0.0, ccount@^1.0.3: +ccount@^1.0.0: version "1.0.4" resolved "https://registry.yarnpkg.com/ccount/-/ccount-1.0.4.tgz#9cf2de494ca84060a2a8d2854edd6dfb0445f386" integrity sha512-fpZ81yYfzentuieinmGnphk0pLkOTMm6MZdVqwd77ROvhko6iujLNGrHH5E7utq3ygWklwfmwuG+A7P+NpqT6w== @@ -6531,10 +6694,10 @@ chokidar@3.3.0: optionalDependencies: fsevents "~2.1.1" -chokidar@^2.0.0, chokidar@^2.0.2, chokidar@^2.0.4, chokidar@^2.1.1: - version "2.1.6" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.6.tgz#b6cad653a929e244ce8a834244164d241fa954c5" - integrity sha512-V2jUo67OKkc6ySiRpJrjlpJKl9kDuG+Xb8VgsGzb+aEouhgS1D0weyPU4lEzdAcsCAvrih2J2BqyXqHWvVLw5g== +chokidar@^2.0.0, chokidar@^2.1.1, chokidar@^2.1.8: + version "2.1.8" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" + integrity sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg== dependencies: anymatch "^2.0.0" async-each "^1.0.1" @@ -6550,7 +6713,22 @@ chokidar@^2.0.0, chokidar@^2.0.2, chokidar@^2.0.4, chokidar@^2.1.1: optionalDependencies: fsevents "^1.2.7" -chownr@^1.0.1, chownr@^1.1.1, chownr@^1.1.2: +chokidar@^3.3.0, chokidar@^3.4.1: + version "3.4.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.4.3.tgz#c1df38231448e45ca4ac588e6c79573ba6a57d5b" + integrity sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ== + dependencies: + anymatch "~3.1.1" + braces "~3.0.2" + glob-parent "~5.1.0" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.5.0" + optionalDependencies: + fsevents "~2.1.2" + +chownr@^1.0.1, chownr@^1.1.1: version "1.1.3" resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.3.tgz#42d837d5239688d55f303003a508230fa6727142" integrity sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw== @@ -6652,10 +6830,10 @@ classnames@^2.2.4, classnames@^2.2.5, classnames@^2.2.6: resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce" integrity sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q== -clean-css@4.2.x: - version "4.2.1" - resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.1.tgz#2d411ef76b8569b6d0c84068dabe85b0aa5e5c17" - integrity sha512-4ZxI6dy4lrY6FHzfiy1aEOXgu4LIsW2MhwG0VBKdcoGoH/XLFgaHSdLTGr4O8Be6A8r3MOphEiI8Gc1n0ecf3g== +clean-css@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.3.tgz#507b5de7d97b48ee53d84adb0160ff6216380f78" + integrity sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA== dependencies: source-map "~0.6.0" @@ -6695,13 +6873,13 @@ cli-cursor@^3.1.0: dependencies: restore-cursor "^3.1.0" -cli-table3@0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.5.1.tgz#0252372d94dfc40dbd8df06005f48f31f656f202" - integrity sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw== +cli-table3@0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.6.0.tgz#b7b1bc65ca8e7b5cef9124e13dc2b21e2ce4faee" + integrity sha512-gnB85c3MGC7Nm9I/FkiasNBOKjOiO1RNuXXarQms37q4QMpWdlbBgD/VnOStA2faG1dpXMv31RFApjX1/QdgWQ== dependencies: object-assign "^4.1.0" - string-width "^2.1.1" + string-width "^4.2.0" optionalDependencies: colors "^1.1.2" @@ -6919,7 +7097,7 @@ color@^0.11.3: color-convert "^1.3.0" color-string "^0.3.0" -colorette@^1.2.0: +colorette@^1.2.0, colorette@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.1.tgz#4d0b921325c14faf92633086a536db6e89564b1b" integrity sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw== @@ -6952,7 +7130,7 @@ combine-source-map@^0.8.0, combine-source-map@~0.8.0: lodash.memoize "~3.0.3" source-map "~0.5.3" -combined-stream@^1.0.6, combined-stream@~1.0.6: +combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== @@ -6969,20 +7147,15 @@ commander@2, commander@^2.15.0, commander@^2.15.1, commander@^2.16.0, commander@ resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== -commander@2.17.x: - version "2.17.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf" - integrity sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg== - -commander@^4.0.1: - version "4.1.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.0.tgz#545983a0603fe425bc672d66c9e3c89c42121a83" - integrity sha512-NIQrwvv9V39FHgGFm36+U9SMQzbiHvU79k+iADraJTpmrFFfx7Ds0IvDoAdZsDrknlkRk14OYoWXb57uTh7/sw== +commander@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" + integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== -commander@~2.19.0: - version "2.19.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" - integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg== +commander@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae" + integrity sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg== commander@~2.8.1: version "2.8.1" @@ -7028,6 +7201,11 @@ compose-function@3.0.3: dependencies: arity-n "^1.0.4" +compute-scroll-into-view@^1.0.14: + version "1.0.16" + resolved "https://registry.yarnpkg.com/compute-scroll-into-view/-/compute-scroll-into-view-1.0.16.tgz#5b7bf4f7127ea2c19b750353d7ce6776a90ee088" + integrity sha512-a85LHKY81oQnikatZYA90pufpZ6sQx++BoCxOEMsjpZx+ZnaKGQnCyCehTRr/1p9GBIAHTjcU9k71kSYWloLiQ== + concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" @@ -7254,36 +7432,25 @@ copy-webpack-plugin@^6.0.3: serialize-javascript "^4.0.0" webpack-sources "^1.4.3" -core-js-compat@^3.1.1: - version "3.1.3" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.1.3.tgz#0cc3ba4c7f62928c2837e1cffbe8dc78b4f1ae14" - integrity sha512-EP018pVhgwsKHz3YoN1hTq49aRe+h017Kjz0NQz3nXV0cCRMvH3fLQl+vEPGr4r4J5sk4sU3tUC7U1aqTCeJeA== +core-js-compat@^3.7.0: + version "3.8.0" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.8.0.tgz#3248c6826f4006793bd637db608bca6e4cd688b1" + integrity sha512-o9QKelQSxQMYWHXc/Gc4L8bx/4F7TTraE5rhuN8I7mKBt5dBIUpXpIR3omv70ebr8ST5R3PqbDQr+ZI3+Tt1FQ== dependencies: - browserslist "^4.6.0" - core-js-pure "3.1.3" - semver "^6.1.0" - -core-js-pure@3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.1.3.tgz#4c90752d5b9471f641514f3728f51c1e0783d0b5" - integrity sha512-k3JWTrcQBKqjkjI0bkfXS0lbpWPxYuHWfMMjC1VDmzU4Q58IwSbuXSo99YO/hUHlw/EB4AlfA2PVxOGkrIq6dA== + browserslist "^4.14.7" + semver "7.0.0" core-js-pure@^3.0.0, core-js-pure@^3.0.1: version "3.6.5" resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.6.5.tgz#c79e75f5e38dbc85a662d91eea52b8256d53b813" integrity sha512-lacdXOimsiD0QyNf9BC/mxivNJ/ybBGJXQFKzRekp1WTHoVUWsUHEn+2T8GJAzzIhyOuXA+gOxCVN3l+5PLPUA== -core-js@^1.0.0: - version "1.2.7" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636" - integrity sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY= - core-js@^2.4.0, core-js@^2.5.0, core-js@^2.5.3: version "2.6.11" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.11.tgz#38831469f9922bded8ee21c9dc46985e0399308c" integrity sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg== -core-js@^3.0.0, core-js@^3.0.1, core-js@^3.0.4, core-js@^3.6.5: +core-js@^3.0.1, core-js@^3.0.4, core-js@^3.6.5: version "3.6.5" resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.6.5.tgz#7395dc273af37fb2e50e9bd3d9fe841285231d1a" integrity sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA== @@ -7293,14 +7460,6 @@ core-util-is@1.0.2, core-util-is@~1.0.0: resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= -corejs-upgrade-webpack-plugin@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/corejs-upgrade-webpack-plugin/-/corejs-upgrade-webpack-plugin-2.2.0.tgz#503293bf1fdcb104918eb40d0294e4776ad6923a" - integrity sha512-J0QMp9GNoiw91Kj/dkIQFZeiCXgXoja/Wlht1SPybxerBWh4NCmb0pOgCv61lrlQZETwvVVfAFAA3IqoEO9aqQ== - dependencies: - resolve-from "^5.0.0" - webpack "^4.38.0" - cors@^2.7.1, cors@^2.8.1: version "2.8.5" resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" @@ -7319,16 +7478,6 @@ cosmiconfig@^4.0.0: parse-json "^4.0.0" require-from-string "^2.0.1" -cosmiconfig@^5.2.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.2.1.tgz#040f726809c591e77a17c0a3626ca45b4f168b1a" - integrity sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA== - dependencies: - import-fresh "^2.0.0" - is-directory "^0.3.1" - js-yaml "^3.13.1" - parse-json "^4.0.0" - cosmiconfig@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-6.0.0.tgz#da4fee853c52f6b1e6935f41c1a2fc50bd4a9982" @@ -7351,6 +7500,31 @@ coveralls@^3.0.0: minimist "^1.2.0" request "^2.79.0" +cp-file@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/cp-file/-/cp-file-7.0.0.tgz#b9454cfd07fe3b974ab9ea0e5f29655791a9b8cd" + integrity sha512-0Cbj7gyvFVApzpK/uhCtQ/9kE9UnYpxMzaq5nQQC/Dh4iaj5fxp7iEFIullrYwzj8nf0qnsI1Qsx34hAeAebvw== + dependencies: + graceful-fs "^4.1.2" + make-dir "^3.0.0" + nested-error-stacks "^2.0.0" + p-event "^4.1.0" + +cpy@^8.1.1: + version "8.1.1" + resolved "https://registry.yarnpkg.com/cpy/-/cpy-8.1.1.tgz#066ed4c6eaeed9577df96dae4db9438c1a90df62" + integrity sha512-vqHT+9o67sMwJ5hUd/BAOYeemkU+MuFRsK2c36Xc3eefQpAsp1kAsyDxEDcc5JS1+y9l/XHPrIsVTcyGGmkUUQ== + dependencies: + arrify "^2.0.1" + cp-file "^7.0.0" + globby "^9.2.0" + has-glob "^1.0.0" + junk "^3.1.0" + nested-error-stacks "^2.1.0" + p-all "^2.1.0" + p-filter "^2.1.0" + p-map "^3.0.0" + crdts@~0.1.2: version "0.1.5" resolved "https://registry.yarnpkg.com/crdts/-/crdts-0.1.5.tgz#89413e8adfc3ab943300a890ee6392db5ba60c06" @@ -7394,21 +7568,13 @@ create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.3, create-hmac@^1.1.4, safe-buffer "^5.0.1" sha.js "^2.4.8" -create-react-context@<=0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/create-react-context/-/create-react-context-0.2.2.tgz#9836542f9aaa22868cd7d4a6f82667df38019dca" - integrity sha512-KkpaLARMhsTsgp0d2NA/R94F/eDLbhXERdIq3LvX2biCAXcDvHYoOqHfWCHf1+OLj+HKBotLG3KqaOOf+C1C+A== - dependencies: - fbjs "^0.8.0" - gud "^1.0.0" - -create-react-context@^0.2.1: - version "0.2.3" - resolved "https://registry.yarnpkg.com/create-react-context/-/create-react-context-0.2.3.tgz#9ec140a6914a22ef04b8b09b7771de89567cb6f3" - integrity sha512-CQBmD0+QGgTaxDL3OX1IDXYqjkp2It4RIbcb99jS6AEg27Ga+a9G3JtK6SIu0HBwPLZlmwt9F7UwWA4Bn92Rag== +create-react-context@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/create-react-context/-/create-react-context-0.3.0.tgz#546dede9dc422def0d3fc2fe03afe0bc0f4f7d8c" + integrity sha512-dNldIoSuNSvlTJ7slIKC/ZFGKexBMBrrcc+TTe1NdmROnaASuLPvqpwj9v4XS4uXZ8+YPu0sNmShX2rXI5LNsw== dependencies: - fbjs "^0.8.0" gud "^1.0.0" + warning "^4.0.3" cross-fetch@2.2.2: version "2.2.2" @@ -7426,16 +7592,14 @@ cross-fetch@^2.1.0, cross-fetch@^2.1.1: node-fetch "2.1.2" whatwg-fetch "2.0.4" -cross-spawn@6.0.5, cross-spawn@^6.0.0, cross-spawn@^6.0.5: - version "6.0.5" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" - integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== +cross-spawn@7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.1.tgz#0ab56286e0f7c24e153d04cc2aa027e43a9a5d14" + integrity sha512-u7v4o84SwFpD32Z8IIcPZ6z1/ie24O6RU3RbtL5Y316l3KuHVPx9ItBgWQ6VlfAFnRnTtMUrsQ9MUUTuEZjogg== dependencies: - nice-try "^1.0.4" - path-key "^2.0.1" - semver "^5.5.0" - shebang-command "^1.2.0" - which "^1.2.9" + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" cross-spawn@^3.0.0: version "3.0.1" @@ -7454,6 +7618,17 @@ cross-spawn@^5.0.1: shebang-command "^1.2.0" which "^1.2.9" +cross-spawn@^6.0.0, cross-spawn@^6.0.5: + version "6.0.5" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" + integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== + dependencies: + nice-try "^1.0.4" + path-key "^2.0.1" + semver "^5.5.0" + shebang-command "^1.2.0" + which "^1.2.9" + cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" @@ -7512,23 +7687,24 @@ css-loader@^2.1.1: postcss-value-parser "^3.3.0" schema-utils "^1.0.0" -css-loader@^3.0.0: - version "3.4.2" - resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-3.4.2.tgz#d3fdb3358b43f233b78501c5ed7b1c6da6133202" - integrity sha512-jYq4zdZT0oS0Iykt+fqnzVLRIeiPWhka+7BqPn+oSIpWJAHak5tmB/WZrJ2a21JhCeFyNnnlroSl8c+MtVndzA== +css-loader@^3.5.3: + version "3.6.0" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-3.6.0.tgz#2e4b2c7e6e2d27f8c8f28f61bffcd2e6c91ef645" + integrity sha512-M5lSukoWi1If8dhQAUCvj4H8vUt3vOnwbQBH9DdTm/s4Ym2B/3dPMtYZeJmq7Q3S3Pa+I94DcZ7pc9bP14cWIQ== dependencies: camelcase "^5.3.1" cssesc "^3.0.0" icss-utils "^4.1.1" loader-utils "^1.2.3" normalize-path "^3.0.0" - postcss "^7.0.23" + postcss "^7.0.32" postcss-modules-extract-imports "^2.0.0" postcss-modules-local-by-default "^3.0.2" - postcss-modules-scope "^2.1.1" + postcss-modules-scope "^2.2.0" postcss-modules-values "^3.0.0" - postcss-value-parser "^4.0.2" - schema-utils "^2.6.0" + postcss-value-parser "^4.1.0" + schema-utils "^2.7.0" + semver "^6.3.0" css-select-base-adapter@^0.1.1: version "0.1.1" @@ -8031,7 +8207,7 @@ debug@3.1.0, debug@=3.1.0, debug@~3.1.0: dependencies: ms "2.0.0" -debug@3.2.6, debug@3.X, debug@^3.0.0, debug@^3.1.0, debug@^3.2.5, debug@^3.2.6: +debug@3.2.6, debug@3.X, debug@^3.0.0, debug@^3.1.0, debug@^3.2.6: version "3.2.6" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== @@ -8135,6 +8311,11 @@ decompress@^4.0.0, decompress@^4.2.0: pify "^2.3.0" strip-dirs "^2.0.0" +dedent@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" + integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw= + deep-eql@^0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-0.1.3.tgz#ef558acab8de25206cd713906d74e56930eb69f2" @@ -8533,6 +8714,13 @@ dir-glob@2.0.0: arrify "^1.0.1" path-type "^3.0.0" +dir-glob@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-2.2.2.tgz#fa09f0694153c8918b18ba0deafae94769fc50c4" + integrity sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw== + dependencies: + path-type "^3.0.0" + dir-glob@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" @@ -8724,6 +8912,14 @@ domutils@^1.5.1, domutils@^1.7.0: dom-serializer "0" domelementtype "1" +dot-case@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.3.tgz#21d3b52efaaba2ea5fda875bb1aa8124521cf4aa" + integrity sha512-7hwEmg6RiSQfm/GwPL4AAWXKy3YNNZA3oFv2Pdiey0mwkRCPZ9x6SZbkLcn8Ma5PYeVokzoD4Twv2n7LKp5WeA== + dependencies: + no-case "^3.0.3" + tslib "^1.10.0" + dot-prop@^4.1.0, dot-prop@^5.1.1: version "5.2.0" resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.2.0.tgz#c34ecc29556dc45f1f4c22697b6f4904e0cc4fcb" @@ -8795,6 +8991,16 @@ download@^7.1.0: p-event "^2.1.0" pify "^3.0.0" +downshift@^6.0.6: + version "6.0.6" + resolved "https://registry.yarnpkg.com/downshift/-/downshift-6.0.6.tgz#82aee8e2e260d7ad99df8a0969bd002dd523abe8" + integrity sha512-tmLab3cXCn6PtZYl9V8r/nB2m+7/nCNrwo0B3kTHo/2lRBHr+1en1VNOQt2wIt0ajanAnxquZ00WPCyxe6cNFQ== + dependencies: + "@babel/runtime" "^7.11.2" + compute-scroll-into-view "^1.0.14" + prop-types "^15.7.2" + react-is "^16.13.1" + drbg.js@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/drbg.js/-/drbg.js-1.0.1.tgz#3e36b6c42b37043823cdbc332d58f31e2445480b" @@ -8864,22 +9070,22 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= -ejs@^2.4.1, ejs@^2.7.4: +ejs@^2.4.1: version "2.7.4" resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.7.4.tgz#48661287573dcc53e366c7a1ae52c3a120eec9ba" integrity sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA== -ejs@^3.0.2: - version "3.1.3" - resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.3.tgz#514d967a8894084d18d3d47bd169a1c0560f093d" - integrity sha512-wmtrUGyfSC23GC/B1SMv2ogAUgbQEtDmTIhfqielrG5ExIM9TP4UoYdi90jLF1aTcsWCJNEO0UrgKzP0y3nTSg== +ejs@^3.0.2, ejs@^3.1.2: + version "3.1.5" + resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.5.tgz#aed723844dc20acb4b170cd9ab1017e476a0d93b" + integrity sha512-dldq3ZfFtgVTJMLjOe+/3sROTzALlL9E34V4/sDtUd/KlBSS0s6U1/+WPE1B4sj9CXHJpL1M6rhNJnc9Wbal9w== dependencies: jake "^10.6.1" -electron-to-chromium@^1.3.122, electron-to-chromium@^1.3.47, electron-to-chromium@^1.3.488: - version "1.3.498" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.498.tgz#fd7188c8a49d6d0b5df1df55a1f1a4bf2c177457" - integrity sha512-W1hGwaQEU8j9su2jeAr3aabkPuuXw+j8t73eajGAkEJWbfWiwbxBwQN/8Qmv2qCy3uCDm2rOAaZneYQM8VGC4w== +electron-to-chromium@^1.3.378, electron-to-chromium@^1.3.47, electron-to-chromium@^1.3.591: + version "1.3.610" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.610.tgz#1254eb394acd220a836ea1f203f8cded4e487052" + integrity sha512-eFDC+yVQpEhtlapk4CYDPfV9ajF9cEof5TBcO49L1ETO+aYogrKWDmYpZyxBScMNe8Bo/gJamH4amQ4yyvXg4g== electron@^9.1.0: version "9.1.2" @@ -8979,6 +9185,15 @@ end-of-stream@^1.0.0, end-of-stream@^1.1.0, end-of-stream@^1.4.0, end-of-stream@ dependencies: once "^1.4.0" +endent@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/endent/-/endent-2.0.1.tgz#fb18383a3f37ae3213a5d9f6c4a880d1061eb4c5" + integrity sha512-mADztvcC+vCk4XEZaCz6xIPO2NHQuprv5CAEjuVAu6aZwqAj7nVNlMyl1goPFYqCCpS2OJV9jwpumJLkotZrNw== + dependencies: + dedent "^0.7.0" + fast-json-parse "^1.0.3" + objectorarray "^1.0.4" + engine.io-client@~3.3.1: version "3.3.2" resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-3.3.2.tgz#04e068798d75beda14375a264bb3d742d7bc33aa" @@ -9019,13 +9234,13 @@ engine.io@~3.3.1: engine.io-parser "~2.1.0" ws "~6.1.0" -enhanced-resolve@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz#41c7e0bfdfe74ac1ffe1e57ad6a5c6c9f3742a7f" - integrity sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng== +enhanced-resolve@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.3.0.tgz#3b806f3bfafc1ec7de69551ef93cca46c1704126" + integrity sha512-3e87LvavsdxyoCfGusJnrZ5G8SLPOFeHSNpZI/ATL9a5leXo2k0w6MKnbqhdBad9qTobSfB20Ld7UmgoNbAZkQ== dependencies: graceful-fs "^4.1.2" - memory-fs "^0.4.0" + memory-fs "^0.5.0" tapable "^1.0.0" enquirer@^2.3.5: @@ -9138,6 +9353,13 @@ error-inject@^1.0.0: resolved "https://registry.yarnpkg.com/error-inject/-/error-inject-1.0.0.tgz#e2b3d91b54aed672f309d950d154850fa11d4f37" integrity sha1-4rPZG1Su1nLzCdlQ0VSFD6EdTzc= +error-stack-parser@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/error-stack-parser/-/error-stack-parser-2.0.6.tgz#5a99a707bd7a4c58a797902d48d82803ede6aad8" + integrity sha512-d51brTeqC+BHlwF0BhPtcYgF5nlzf9ZZ0ZIUQNZpc9ZB9qw5IJ2diTrBY9jlCJkTLITYPjmiX6OWCwH+fuyNgQ== + dependencies: + stackframe "^1.1.1" + error@^7.0.0: version "7.0.2" resolved "https://registry.yarnpkg.com/error/-/error-7.0.2.tgz#a5f75fff4d9926126ddac0ea5dc38e689153cb02" @@ -9281,10 +9503,10 @@ es6-weak-map@^2.0.1, es6-weak-map@^2.0.2: es6-iterator "^2.0.1" es6-symbol "^3.1.1" -escalade@^3.0.1: - version "3.0.2" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.0.2.tgz#6a580d70edb87880f22b4c91d0d56078df6962c4" - integrity sha512-gPYAU37hYCUhW5euPeR+Y74F7BL+IBsV93j5cvGriSaD1aG6MGsqsV1yamRdrWrb2j3aiZvb0X+UBOWpx3JWtQ== +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== escape-html@^1.0.3, escape-html@~1.0.3: version "1.0.3" @@ -9296,6 +9518,11 @@ escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1 resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= +escape-string-regexp@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" + integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== + escape-string-regexp@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" @@ -9646,7 +9873,7 @@ esprima@3.x.x: resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" integrity sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM= -esprima@4.0.1, esprima@^4.0.0, esprima@^4.0.1, esprima@~4.0.0: +esprima@4.0.1, esprima@^4.0.0, esprima@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== @@ -9680,7 +9907,7 @@ estree-is-function@^1.0.0: resolved "https://registry.yarnpkg.com/estree-is-function/-/estree-is-function-1.0.0.tgz#c0adc29806d7f18a74db7df0f3b2666702e37ad2" integrity sha512-nSCWn1jkSq2QAtkaVLJZY2ezwcFO161HVc174zL1KPW3RJ+O6C3eJb8Nx7OXzvhoEv+nLgSR1g71oWUHUDTrJA== -esutils@^2.0.0, esutils@^2.0.2: +esutils@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== @@ -10568,7 +10795,7 @@ event-target-shim@^5.0.0: resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== -eventemitter3@4.0.4, eventemitter3@^4.0.0: +eventemitter3@4.0.4: version "4.0.4" resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.4.tgz#b5463ace635a083d018bdc7c917b4c5f10a85384" integrity sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ== @@ -10593,13 +10820,6 @@ events@^3.0.0: resolved "https://registry.yarnpkg.com/events/-/events-3.0.0.tgz#9a0a0dfaf62893d92b875b8f2698ca4114973e88" integrity sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA== -eventsource@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-1.0.7.tgz#8fbc72c93fcd34088090bc0a4e64f4b5cee6d8d0" - integrity sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ== - dependencies: - original "^1.0.0" - evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" @@ -10911,7 +11131,7 @@ fast-future@~1.0.2: resolved "https://registry.yarnpkg.com/fast-future/-/fast-future-1.0.2.tgz#8435a9aaa02d79248d17d704e76259301d99280a" integrity sha1-hDWpqqAteSSNF9cE52JZMB2ZKAo= -fast-glob@^2.0.2: +fast-glob@^2.0.2, fast-glob@^2.2.6: version "2.2.7" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-2.2.7.tgz#6953857c3afa475fff92ee6015d52da70a4cd39d" integrity sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw== @@ -10986,12 +11206,12 @@ fastq@^1.6.0: dependencies: reusify "^1.0.0" -fault@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/fault/-/fault-1.0.3.tgz#4da88cf979b6b792b4e13c7ec836767725170b7e" - integrity sha512-sfFuP4X0hzrbGKjAUNXYvNqsZ5F6ohx/dZ9I0KQud/aiZNwg263r5L9yGB0clvXHCkzXh5W3t7RSHchggYIFmA== +fault@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/fault/-/fault-1.0.4.tgz#eafcfc0a6d214fc94601e170df29954a4f842f13" + integrity sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA== dependencies: - format "^0.2.2" + format "^0.2.0" faye-websocket@~0.10.0: version "0.10.0" @@ -11000,26 +11220,6 @@ faye-websocket@~0.10.0: dependencies: websocket-driver ">=0.5.1" -faye-websocket@~0.11.1: - version "0.11.1" - resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.1.tgz#f0efe18c4f56e4f40afc7e06c719fd5ee6188f38" - integrity sha1-8O/hjE9W5PQK/H4Gxxn9XuYYjzg= - dependencies: - websocket-driver ">=0.5.1" - -fbjs@^0.8.0: - version "0.8.16" - resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.16.tgz#5e67432f550dc41b572bf55847b8aca64e5337db" - integrity sha1-XmdDL1UNxBtXK/VYR7ispk5TN9s= - dependencies: - core-js "^1.0.0" - isomorphic-fetch "^2.1.1" - loose-envify "^1.0.0" - object-assign "^4.1.0" - promise "^7.1.1" - setimmediate "^1.0.5" - ua-parser-js "^0.7.9" - fd-slicer@~1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e" @@ -11084,13 +11284,13 @@ file-loader@^1.1.11: loader-utils "^1.0.2" schema-utils "^0.4.5" -file-loader@^4.2.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-4.3.0.tgz#780f040f729b3d18019f20605f723e844b8a58af" - integrity sha512-aKrYPYjF1yG3oX0kWRrqrSMfgftm7oJW5M+m4owoldH5C51C0RkIwB++JbRvEW3IU6/ZG5n8UvEcdgwOt2UOWA== +file-loader@^6.0.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-6.2.0.tgz#baef7cf8e1840df325e4390b4484879480eebe4d" + integrity sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw== dependencies: - loader-utils "^1.2.3" - schema-utils "^2.5.0" + loader-utils "^2.0.0" + schema-utils "^3.0.0" file-system-cache@^1.0.5: version "1.0.5" @@ -11172,7 +11372,12 @@ filenamify@^2.0.0: strip-outer "^1.0.0" trim-repeated "^1.0.0" -filesize@3.6.1, filesize@^3.6.1: +filesize@6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/filesize/-/filesize-6.0.1.tgz#f850b509909c7c86f7e450ea19006c31c2ed3d2f" + integrity sha512-u4AYWPgbI5GBhs6id1KdImZWn5yfyFrrQ8OWZdN7ZMfA8Bf4HcO0BGo9bmUIEV8yrp8I1xVfJ/dn90GtFNNJcg== + +filesize@^3.6.1: version "3.6.1" resolved "https://registry.yarnpkg.com/filesize/-/filesize-3.6.1.tgz#090bb3ee01b6f801a8a8be99d31710b3422bb317" integrity sha512-7KjR1vv6qnicaPMi1iiTcI85CyYwRO/PSFCu6SvqL8jN2Wjt/NIYQTFtFs7fSDCYOstUkEWIQGFUg5YZQfjlcg== @@ -11235,7 +11440,7 @@ find-cache-dir@^2.0.0, find-cache-dir@^2.1.0: make-dir "^2.0.0" pkg-dir "^3.0.0" -find-cache-dir@^3.0.0, find-cache-dir@^3.2.0, find-cache-dir@^3.3.1: +find-cache-dir@^3.2.0, find-cache-dir@^3.3.1: version "3.3.1" resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.1.tgz#89b33fad4a4670daa94f855f7fbe31d6d84fe880" integrity sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ== @@ -11256,6 +11461,14 @@ find-up@3.0.0, find-up@^3.0.0: dependencies: locate-path "^3.0.0" +find-up@4.1.0, find-up@^4.0.0, find-up@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + find-up@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" @@ -11271,14 +11484,6 @@ find-up@^2.0.0, find-up@^2.1.0: dependencies: locate-path "^2.0.0" -find-up@^4.0.0, find-up@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" - integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== - dependencies: - locate-path "^5.0.0" - path-exists "^4.0.0" - find-versions@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/find-versions/-/find-versions-3.1.0.tgz#10161f29cf3eb4350dec10a29bdde75bff0df32d" @@ -11412,11 +11617,6 @@ fnv1a@^1.0.1: resolved "https://registry.yarnpkg.com/fnv1a/-/fnv1a-1.0.1.tgz#915e2d6d023c43d5224ad9f6d2a3c4156f5712f5" integrity sha1-kV4tbQI8Q9UiStn20qPEFW9XEvU= -focus-lock@^0.6.6: - version "0.6.6" - resolved "https://registry.yarnpkg.com/focus-lock/-/focus-lock-0.6.6.tgz#98119a755a38cfdbeda0280eaa77e307eee850c7" - integrity sha512-Dx69IXGCq1qsUExWuG+5wkiMqVM/zGx/reXSJSLogECwp3x6KeNQZ+NAetgxEFpnC41rD8U3+jRCW68+LNzdtw== - follow-redirects@1.5.10: version "1.5.10" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a" @@ -11473,14 +11673,27 @@ forever-agent@~0.6.1: resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= -fork-ts-checker-webpack-plugin@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-1.1.1.tgz#caf2a210778fb1e171b6993ca0a40f9b6589e3b7" - integrity sha512-gqWAEMLlae/oeVnN6RWCAhesOJMswAN1MaKNqhhjXHV5O0/rTUjWI4UbgQHdlrVbCnb+xLotXmJbBlC66QmpFw== +fork-ts-checker-webpack-plugin@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-3.1.1.tgz#a1642c0d3e65f50c2cc1742e9c0a80f441f86b19" + integrity sha512-DuVkPNrM12jR41KM2e+N+styka0EgLkTnXmNcXdgOM37vtGeY+oCBK/Jx0hzSeEU6memFCtWb4htrHPMDfwwUQ== dependencies: babel-code-frame "^6.22.0" chalk "^2.4.1" - chokidar "^2.0.4" + chokidar "^3.3.0" + micromatch "^3.1.10" + minimatch "^3.0.4" + semver "^5.6.0" + tapable "^1.0.0" + worker-rpc "^0.1.0" + +fork-ts-checker-webpack-plugin@^4.1.4: + version "4.1.6" + resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-4.1.6.tgz#5055c703febcf37fa06405d400c122b905167fc5" + integrity sha512-DUxuQaKoqfNne8iikd14SAkh5uw4+8vNifp6gmA73yYNS6ywLIWSLD/n/mBzHQRpW3J7rbATEakmiA8JvkTyZw== + dependencies: + "@babel/code-frame" "^7.5.5" + chalk "^2.4.1" micromatch "^3.1.10" minimatch "^3.0.4" semver "^5.6.0" @@ -11496,7 +11709,16 @@ form-data@^2.3.1, form-data@~2.3.2: combined-stream "^1.0.6" mime-types "^2.1.12" -format@^0.2.2: +form-data@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.0.tgz#31b7e39c85f1355b7139ee0c647cf0de7f83c682" + integrity sha512-CKMFDglpbMi6PyN+brwB9Q/GOw0eAnsrEZDgcsH5Krhz5Od/haKHAX0NmQfha2zPPz0JpWzA7GJHGSnvCRLWsg== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + +format@^0.2.0: version "0.2.2" resolved "https://registry.yarnpkg.com/format/-/format-0.2.2.tgz#d6170107e9efdc4ed30c9dc39016df942b5cb58b" integrity sha1-1hcBB+nv3E7TDJ3DkBbflCtctYs= @@ -11584,7 +11806,7 @@ fs-extra@^7.0.1: jsonfile "^4.0.0" universalify "^0.1.0" -fs-extra@^8.0.1, fs-extra@^8.1.0: +fs-extra@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== @@ -11593,6 +11815,16 @@ fs-extra@^8.0.1, fs-extra@^8.1.0: jsonfile "^4.0.0" universalify "^0.1.0" +fs-extra@^9.0.0: + version "9.0.1" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.0.1.tgz#910da0062437ba4c39fedd863f1675ccfefcb9fc" + integrity sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ== + dependencies: + at-least-node "^1.0.0" + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^1.0.0" + fs-minipass@^1.2.5: version "1.2.6" resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.6.tgz#2c5cc30ded81282bfe8a0d7c7c1853ddeb102c07" @@ -11643,10 +11875,10 @@ fsevents@^1.2.7: nan "^2.12.1" node-pre-gyp "^0.12.0" -fsevents@~2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.2.tgz#4c0a1fb34bc68e543b4b82a9ec392bfbda840805" - integrity sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA== +fsevents@~2.1.1, fsevents@~2.1.2: + version "2.1.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e" + integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ== fsm-event@^2.1.0: version "2.1.0" @@ -11705,10 +11937,10 @@ functions-have-names@^1.1.1: resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.0.tgz#83da7583e4ea0c9ac5ff530f73394b033e0bf77d" integrity sha512-zKXyzksTeaCSw5wIX79iCA40YAa6CJMJgNg9wdkU/ERBrIdPSimPICYiLp65lRbSBqtiHql/HZfS2DyI/AH6tQ== -fuse.js@^3.2.0, fuse.js@^3.4.6: - version "3.4.6" - resolved "https://registry.yarnpkg.com/fuse.js/-/fuse.js-3.4.6.tgz#545c3411fed88bf2e27c457cab6e73e7af697a45" - integrity sha512-H6aJY4UpLFwxj1+5nAvufom5b2BT2v45P1MkPvdGIK8fWjQx/7o6tTT1+ALV0yawQvbmvCF0ufl2et8eJ7v7Cg== +fuse.js@^3.2.0, fuse.js@^3.6.1: + version "3.6.1" + resolved "https://registry.yarnpkg.com/fuse.js/-/fuse.js-3.6.1.tgz#7de85fdd6e1b3377c23ce010892656385fd9b10c" + integrity sha512-hT9yh/tiinkmirKrlv4KWOjztdoZo1mx9Qh4KvWqC7isoXwdUY3PNWUxceF4/qO9R6riA2C29jdTOeQOIROjgw== ganache-cli@^6.12.1: version "6.12.1" @@ -12018,6 +12250,13 @@ glob-parent@^5.0.0, glob-parent@^5.1.0, glob-parent@^5.1.1, glob-parent@~5.1.0: dependencies: is-glob "^4.0.1" +glob-promise@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/glob-promise/-/glob-promise-3.4.0.tgz#b6b8f084504216f702dc2ce8c9bc9ac8866fdb20" + integrity sha512-q08RJ6O+eJn+dVanerAndJwIcumgbDdYiUT7zFQl3Wm1xD6fBKtah7H8ZJChj4wP+8C+QfeVy8xautR7rdmKEw== + dependencies: + "@types/glob" "*" + glob-stream@^6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/glob-stream/-/glob-stream-6.1.0.tgz#7045c99413b3eb94888d83ab46d0b404cc7bdde4" @@ -12266,6 +12505,20 @@ globby@^6.1.0: pify "^2.0.0" pinkie-promise "^2.0.0" +globby@^9.2.0: + version "9.2.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-9.2.0.tgz#fd029a706c703d29bdd170f4b6db3a3f7a7cb63d" + integrity sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg== + dependencies: + "@types/glob" "^7.1.1" + array-union "^1.0.2" + dir-glob "^2.2.2" + fast-glob "^2.2.6" + glob "^7.1.3" + ignore "^4.0.3" + pify "^4.0.1" + slash "^2.0.0" + globjoin@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/globjoin/-/globjoin-0.1.4.tgz#2f4494ac8919e3767c5cbb691e9f463324285d43" @@ -12400,7 +12653,7 @@ got@^8.3.1: url-parse-lax "^3.0.0" url-to-options "^1.0.1" -graceful-fs@4.X, graceful-fs@^4.0.0, graceful-fs@^4.1.10, graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0, graceful-fs@^4.2.2: +graceful-fs@4.X, graceful-fs@^4.0.0, graceful-fs@^4.1.10, graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0: version "4.2.3" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423" integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ== @@ -12680,15 +12933,7 @@ gulplog@^1.0.0: dependencies: glogg "^1.0.0" -gzip-size@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-5.0.0.tgz#a55ecd99222f4c48fd8c01c625ce3b349d0a0e80" - integrity sha512-5iI7omclyqrnWw4XbXAmGhPsABkSIDQonv2K0h61lybgofWa6iZyvrI3r2zsJH4P8Nb64fFVzlvfhs0g7BBxAA== - dependencies: - duplexer "^0.1.1" - pify "^3.0.0" - -gzip-size@^5.1.1: +gzip-size@5.1.1, gzip-size@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-5.1.1.tgz#cb9bee692f87c0612b232840a873904e4c135274" integrity sha512-FNHi6mmoHvs1mxZAds4PpdCS6QG8B4C1krxJsMutgxl5t3+GlRTzzI3NEkifXx2pVsOvJdOGSmIgDhQ55FwdPA== @@ -12765,6 +13010,13 @@ has-flag@^4.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== +has-glob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-glob/-/has-glob-1.0.0.tgz#9aaa9eedbffb1ba3990a7b0010fb678ee0081207" + integrity sha1-mqqe7b/7G6OZCnsAEPtnjuAIEgc= + dependencies: + is-glob "^3.0.0" + has-localstorage@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/has-localstorage/-/has-localstorage-1.0.1.tgz#fe62406c4767fbd6d784dac6905928108b82971b" @@ -12872,30 +13124,20 @@ hashlru@^2.3.0: resolved "https://registry.yarnpkg.com/hashlru/-/hashlru-2.3.0.tgz#5dc15928b3f6961a2056416bb3a4910216fdfb51" integrity sha512-0cMsjjIC8I+D3M44pOQdsy0OHXGLVz6Z0beRuufhKa0KfaD2wGwAev6jILzXsd3/vpnNQJmWyZtIILqM1N+n5A== -hast-util-from-parse5@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/hast-util-from-parse5/-/hast-util-from-parse5-5.0.1.tgz#7da8841d707dcf7be73715f7f3b14e021c4e469a" - integrity sha512-UfPzdl6fbxGAxqGYNThRUhRlDYY7sXu6XU9nQeX4fFZtV+IHbyEJtd+DUuwOqNV4z3K05E/1rIkoVr/JHmeWWA== - dependencies: - ccount "^1.0.3" - hastscript "^5.0.0" - property-information "^5.0.0" - web-namespaces "^1.1.2" - xtend "^4.0.1" - -hast-util-parse-selector@^2.2.0: - version "2.2.2" - resolved "https://registry.yarnpkg.com/hast-util-parse-selector/-/hast-util-parse-selector-2.2.2.tgz#66aabccb252c47d94975f50a281446955160380b" - integrity sha512-jIMtnzrLTjzqgVEQqPEmwEZV+ea4zHRFTP8Z2Utw0I5HuBOXHzUPPQWr6ouJdJqDKLbFU/OEiYwZ79LalZkmmw== +hast-util-parse-selector@^2.0.0: + version "2.2.5" + resolved "https://registry.yarnpkg.com/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz#d57c23f4da16ae3c63b3b6ca4616683313499c3a" + integrity sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ== -hastscript@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/hastscript/-/hastscript-5.1.0.tgz#a19b3cca6a26a2bcd0f1b1eac574af9427c1c7df" - integrity sha512-7mOQX5VfVs/gmrOGlN8/EDfp1GqV6P3gTNVt+KnX4gbYhpASTM8bklFdFQCbFRAadURXAmw0R1QQdBdqp7jswQ== +hastscript@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/hastscript/-/hastscript-6.0.0.tgz#e8768d7eac56c3fdeac8a92830d58e811e5bf640" + integrity sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w== dependencies: + "@types/hast" "^2.0.0" comma-separated-tokens "^1.0.0" - hast-util-parse-selector "^2.2.0" - property-information "^5.0.1" + hast-util-parse-selector "^2.0.0" + property-information "^5.0.0" space-separated-tokens "^1.0.0" hdkey@0.8.0: @@ -12915,7 +13157,7 @@ hdkey@^0.7.0: coinstring "^2.0.0" secp256k1 "^3.0.1" -he@1.2.0, he@1.2.x: +he@1.2.0, he@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== @@ -12930,10 +13172,10 @@ hi-base32@~0.5.0: resolved "https://registry.yarnpkg.com/hi-base32/-/hi-base32-0.5.0.tgz#61329f76a31f31008533f1c36f2473e259d64571" integrity sha512-DDRmxSyoYuvjUb9EnXdoiMChBZ7ZcUVJsK5Frd3kqMhuBxvmZdnBeynAVfj7/ECbn++CekcoprvC/rprHPAtow== -highlight.js@~9.13.0: - version "9.13.1" - resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.13.1.tgz#054586d53a6863311168488a0f58d6c505ce641e" - integrity sha512-Sc28JNQNDzaH6PORtRLMvif9RSn1mYuOoX3omVjnb0+HbpPygU2ALBI0R/wsiqCb4/fcp07Gdo8g+fhtFrQl6A== +highlight.js@^10.1.1, highlight.js@~10.4.0: + version "10.4.0" + resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-10.4.0.tgz#ef3ce475e5dfa7a48484260b49ea242ddab823a0" + integrity sha512-EfrUGcQ63oLJbj0J0RI9ebX6TAITbsDBLbsjr881L/X5fMO9+oadKzEF21C7R3ULKG6Gv3uoab2HiqVJa/4+oA== history@^4.9.0: version "4.10.1" @@ -13012,44 +13254,47 @@ html-encoding-sniffer@^1.0.1: dependencies: whatwg-encoding "^1.0.1" -html-entities@^1.2.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.2.1.tgz#0df29351f0721163515dfb9e5543e5f6eed5162f" - integrity sha1-DfKTUfByEWNRXfueVUPl9u7VFi8= +html-entities@^1.2.0, html-entities@^1.2.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.3.1.tgz#fb9a1a4b5b14c5daba82d3e34c6ae4fe701a0e44" + integrity sha512-rhE/4Z3hIhzHAUKbW8jVcCyuT5oJCXXqhN/6mXXVCpzTmvJnoH2HL/bt3EZ6p55jbFJBeAe1ZNpL5BugLujxNA== html-escaper@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.0.tgz#71e87f931de3fe09e56661ab9a29aadec707b491" integrity sha512-a4u9BeERWGu/S8JiWEAQcdrg9v4QArtP9keViQjGMdff20fBdd8waotXaNmODqBe6uZ3Nafi7K/ho4gCQHV3Ig== -html-minifier@^3.5.20: - version "3.5.21" - resolved "https://registry.yarnpkg.com/html-minifier/-/html-minifier-3.5.21.tgz#d0040e054730e354db008463593194015212d20c" - integrity sha512-LKUKwuJDhxNa3uf/LPR/KVjm/l3rBqtYeCOAekvG8F1vItxMUpueGd94i/asDDr8/1u7InxzFA5EeGjhhG5mMA== +html-minifier-terser@^5.0.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz#922e96f1f3bb60832c2634b79884096389b1f054" + integrity sha512-ZPr5MNObqnV/T9akshPKbVgyOqLmy+Bxo7juKCfTfnjNniTAMdy4hz21YQqoofMBJD2kdREaqPPdThoR78Tgxg== dependencies: - camel-case "3.0.x" - clean-css "4.2.x" - commander "2.17.x" - he "1.2.x" - param-case "2.1.x" - relateurl "0.2.x" - uglify-js "3.4.x" + camel-case "^4.1.1" + clean-css "^4.2.3" + commander "^4.1.1" + he "^1.2.0" + param-case "^3.0.3" + relateurl "^0.2.7" + terser "^4.6.3" html-tags@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-3.1.0.tgz#7b5e6f7e665e9fb41f30007ed9e0d41e97fb2140" integrity sha512-1qYz89hW3lFDEazhjW0yVAV87lw8lVkrJocr72XmBkMKsoSVJCQx3W8BXsC7hO2qAt8BoVjYjtAcZ9perqGnNg== -html-webpack-plugin@^4.0.0-beta.2: - version "4.0.0-beta.5" - resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-4.0.0-beta.5.tgz#2c53083c1151bfec20479b1f8aaf0039e77b5513" - integrity sha512-y5l4lGxOW3pz3xBTFdfB9rnnrWRPVxlAhX6nrBYIcW+2k2zC3mSp/3DxlWVCMBfnO6UAnoF8OcFn0IMy6kaKAQ== +html-webpack-plugin@^4.2.1: + version "4.5.0" + resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-4.5.0.tgz#625097650886b97ea5dae331c320e3238f6c121c" + integrity sha512-MouoXEYSjTzCrjIxWwg8gxL5fE2X2WZJLmBYXlaJhQUH5K/b5OrqmV7T4dB7iu0xkmJ6JlUuV6fFVtnqbPopZw== dependencies: - html-minifier "^3.5.20" - loader-utils "^1.1.0" - lodash "^4.17.11" + "@types/html-minifier-terser" "^5.0.0" + "@types/tapable" "^1.0.5" + "@types/webpack" "^4.41.8" + html-minifier-terser "^5.0.1" + loader-utils "^1.2.3" + lodash "^4.17.15" pretty-error "^2.1.1" - tapable "^1.1.0" + tapable "^1.1.3" util.promisify "1.0.0" htmlescape@^1.1.0: @@ -13252,16 +13497,11 @@ idna-uts46@^1.0.1: dependencies: punycode "^2.1.0" -ieee754@^1.1.13, ieee754@^1.1.4: +ieee754@^1.1.13, ieee754@^1.1.4, ieee754@^1.1.8: version "1.2.1" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== -ieee754@^1.1.8: - version "1.1.13" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" - integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== - iferr@^0.1.5: version "0.1.5" resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" @@ -13279,7 +13519,7 @@ ignore@^3.2.0, ignore@^3.3.5: resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.7.tgz#612289bfb3c220e186a58118618d5be8c1bab021" integrity sha512-YGG3ejvBNHRqu0559EOxxNFihD0AjpvHlC/pdGKd3X3ofe+CoJkYazwNJYTNebqpPKN+VVQbh4ZFn1DivMNuHA== -ignore@^4.0.6: +ignore@^4.0.3, ignore@^4.0.6: version "4.0.6" resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== @@ -13363,14 +13603,6 @@ import-cwd@^2.0.0: dependencies: import-from "^2.1.0" -import-fresh@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546" - integrity sha1-2BNVwVYS04bGH53dOSLUMEgipUY= - dependencies: - caller-path "^2.0.0" - resolve-from "^3.0.0" - import-fresh@^3.0.0, import-fresh@^3.1.0, import-fresh@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.2.1.tgz#633ff618506e793af5ac91bf48b72677e15cbe66" @@ -13492,23 +13724,23 @@ inquirer@5.2.0: strip-ansi "^4.0.0" through "^2.3.6" -inquirer@6.2.2: - version "6.2.2" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.2.2.tgz#46941176f65c9eb20804627149b743a218f25406" - integrity sha512-Z2rREiXA6cHRR9KBOarR3WuLlFzlIfAEIiB45ll5SSadMg7WqOh1MKEjjndfuH5ewXdixWCxqnVfGOQzPeiztA== +inquirer@7.0.4, inquirer@^7.0.0: + version "7.0.4" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.0.4.tgz#99af5bde47153abca23f5c7fc30db247f39da703" + integrity sha512-Bu5Td5+j11sCkqfqmUTiwv+tWisMtP0L7Q8WrqA2C/BbBhy1YTdFrvjjlrKq8oagA/tLQBski2Gcx/Sqyi2qSQ== dependencies: - ansi-escapes "^3.2.0" + ansi-escapes "^4.2.1" chalk "^2.4.2" - cli-cursor "^2.1.0" + cli-cursor "^3.1.0" cli-width "^2.0.0" external-editor "^3.0.3" - figures "^2.0.0" - lodash "^4.17.11" - mute-stream "0.0.7" + figures "^3.0.0" + lodash "^4.17.15" + mute-stream "0.0.8" run-async "^2.2.0" - rxjs "^6.4.0" - string-width "^2.1.0" - strip-ansi "^5.0.0" + rxjs "^6.5.3" + string-width "^4.1.0" + strip-ansi "^5.1.0" through "^2.3.6" inquirer@^0.12.0: @@ -13549,25 +13781,6 @@ inquirer@^6.2.2: strip-ansi "^5.1.0" through "^2.3.6" -inquirer@^7.0.0: - version "7.0.4" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.0.4.tgz#99af5bde47153abca23f5c7fc30db247f39da703" - integrity sha512-Bu5Td5+j11sCkqfqmUTiwv+tWisMtP0L7Q8WrqA2C/BbBhy1YTdFrvjjlrKq8oagA/tLQBski2Gcx/Sqyi2qSQ== - dependencies: - ansi-escapes "^4.2.1" - chalk "^2.4.2" - cli-cursor "^3.1.0" - cli-width "^2.0.0" - external-editor "^3.0.3" - figures "^3.0.0" - lodash "^4.17.15" - mute-stream "0.0.8" - run-async "^2.2.0" - rxjs "^6.5.3" - string-width "^4.1.0" - strip-ansi "^5.1.0" - through "^2.3.6" - insert-module-globals@^7.0.0: version "7.2.0" resolved "https://registry.yarnpkg.com/insert-module-globals/-/insert-module-globals-7.2.0.tgz#ec87e5b42728479e327bd5c5c71611ddfb4752ba" @@ -14380,10 +14593,13 @@ is-docker@^2.0.0: resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.0.0.tgz#2cb0df0e75e2d064fe1864c37cdeacb7b2dcf25b" integrity sha512-pJEdRugimx4fBMra5z2/5iRdZ63OhYV0vr0Dwm5+xtW4D1FvRkB8hamMIhnWfyJeDdyr/aa7BDyNbtG38VxgoQ== -is-dom@^1.0.9: - version "1.0.9" - resolved "https://registry.yarnpkg.com/is-dom/-/is-dom-1.0.9.tgz#483832d52972073de12b9fe3f60320870da8370d" - integrity sha1-SDgy1SlyBz3hK5/j9gMghw2oNw0= +is-dom@^1.0.0, is-dom@^1.0.9: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-dom/-/is-dom-1.1.0.tgz#af1fced292742443bb59ca3f76ab5e80907b4e8a" + integrity sha512-u82f6mvhYxRPKpw8V1N0W8ce1xXwOrQtgGcxl6UCL5zBmZu3is/18K0rR7uFCnMDuAsS/3W54mGL4vsaFUQlEQ== + dependencies: + is-object "^1.0.1" + is-window "^1.0.2" is-dotfile@^1.0.0: version "1.0.3" @@ -14453,10 +14669,10 @@ is-fullwidth-code-point@^3.0.0: resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== -is-function@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.1.tgz#12cfb98b65b57dd3d193a3121f5f6e2f437602b5" - integrity sha1-Es+5i2W1fdPRk6MSH19uL0N2ArU= +is-function@^1.0.1, is-function@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.2.tgz#4f097f30abf6efadac9833b17ca5dc03f8144e08" + integrity sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ== is-generator-function@^1.0.7: version "1.0.7" @@ -14477,7 +14693,7 @@ is-glob@^2.0.0, is-glob@^2.0.1: dependencies: is-extglob "^1.0.0" -is-glob@^3.1.0: +is-glob@^3.0.0, is-glob@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= @@ -14700,13 +14916,6 @@ is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: dependencies: isobject "^3.0.1" -is-plain-object@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-3.0.0.tgz#47bfc5da1b5d50d64110806c199359482e75a928" - integrity sha512-tZIpofR+P05k8Aocp7UI/2UTa9lTJSebCXpFFoR9aibpokDj/uXBsJ8luUu0tTVYKkMU6URDUuOfJZ7koewXvg== - dependencies: - isobject "^4.0.0" - is-png@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-png/-/is-png-2.0.0.tgz#ee8cbc9e9b050425cedeeb4a6fb74a649b0a4a8d" @@ -14781,10 +14990,10 @@ is-retry-allowed@^1.0.0, is-retry-allowed@^1.1.0: resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz#d778488bd0a4666a3be8a1482b9f2baafedea8b4" integrity sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg== -is-root@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-root/-/is-root-2.0.0.tgz#838d1e82318144e5a6f77819d90207645acc7019" - integrity sha512-F/pJIk8QD6OX5DNhRB7hWamLsUilmkDGho48KbgZ6xg/lmAZXHxzXQ91jzB3yRSw5kdQGGGc4yz8HYhTYIMWPg== +is-root@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-root/-/is-root-2.1.0.tgz#809e18129cf1129644302a4f8544035d51984a9c" + integrity sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg== is-ssh@^1.3.0: version "1.3.1" @@ -14859,6 +15068,11 @@ is-whitespace-character@^1.0.0: resolved "https://registry.yarnpkg.com/is-whitespace-character/-/is-whitespace-character-1.0.3.tgz#b3ad9546d916d7d3ffa78204bca0c26b56257fac" integrity sha512-SNPgMLz9JzPccD3nPctcj8sZlX9DAMJSKH8bP7Z6bohCwuNgX8xbWr1eTAYXX9Vpi/aSn8Y1akL9WgM3t43YNQ== +is-window@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-window/-/is-window-1.0.2.tgz#2c896ca53db97de45d3c33133a65d8c9f563480d" + integrity sha1-LIlspT25feRdPDMTOmXYyfVjSA0= + is-windows@^1.0.1, is-windows@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" @@ -14956,14 +15170,6 @@ isobject@^4.0.0: resolved "https://registry.yarnpkg.com/isobject/-/isobject-4.0.0.tgz#3f1c9155e73b192022a80819bacd0343711697b0" integrity sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA== -isomorphic-fetch@^2.1.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9" - integrity sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk= - dependencies: - node-fetch "^1.0.1" - whatwg-fetch ">=0.10.0" - isomorphic-fetch@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz#0267b005049046d2421207215d45d6a262b8b8b4" @@ -15078,11 +15284,12 @@ jed@1.1.1: resolved "https://registry.yarnpkg.com/jed/-/jed-1.1.1.tgz#7a549bbd9ffe1585b0cd0a191e203055bee574b4" integrity sha1-elSbvZ/+FYWwzQoZHiAwVb7ldLQ= -jest-worker@^25.4.0: - version "25.5.0" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-25.5.0.tgz#2611d071b79cea0f43ee57a3d118593ac1547db1" - integrity sha512-/dsSmUkIy5EBGfv/IjjqmFxrNAUpBERfGs1oHROyD7yxjG/w+t0GOJDX8O1k32ySmd7+a5IhnJU2qQFcJ4n1vw== +jest-worker@^26.2.1: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed" + integrity sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ== dependencies: + "@types/node" "*" merge-stream "^2.0.0" supports-color "^7.0.0" @@ -15115,11 +15322,6 @@ js-base64@^2.1.8: resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.4.3.tgz#2e545ec2b0f2957f41356510205214e98fad6582" integrity sha512-H7ErYLM34CvDMto3GbD6xD0JLUGYXR3QTcH6B/tr4Hi/QpSThnCsIp+Sy5FRTw3B0d6py4HcNkW7nO/wdtGWEw== -js-levenshtein@^1.1.3: - version "1.1.6" - resolved "https://registry.yarnpkg.com/js-levenshtein/-/js-levenshtein-1.1.6.tgz#c6cee58eb3550372df8deb85fad5ce66ce01d59d" - integrity sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g== - js-sha256@^0.9.0: version "0.9.0" resolved "https://registry.yarnpkg.com/js-sha256/-/js-sha256-0.9.0.tgz#0b89ac166583e91ef9123644bd3c5334ce9d0966" @@ -15331,11 +15533,6 @@ json-text-sequence@~0.1.0: dependencies: delimit-stream "0.1.0" -json3@^3.3.2: - version "3.3.3" - resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.3.tgz#7fc10e375fc5ae42c4705a5cc0aa6f62be305b81" - integrity sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA== - json5@^0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" @@ -15369,6 +15566,15 @@ jsonfile@^4.0.0: optionalDependencies: graceful-fs "^4.1.6" +jsonfile@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" + integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== + dependencies: + universalify "^2.0.0" + optionalDependencies: + graceful-fs "^4.1.6" + jsonify@~0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" @@ -16681,11 +16887,6 @@ lodash.clonedeep@4.5.0, lodash.clonedeep@^4.3.2: resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= -lodash.debounce@^4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" - integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= - lodash.escape@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/lodash.escape/-/lodash.escape-4.0.1.tgz#c9044690c21e04294beaa517712fded1fa88de98" @@ -16761,11 +16962,6 @@ lodash.map@^4.6.0: resolved "https://registry.yarnpkg.com/lodash.map/-/lodash.map-4.6.0.tgz#771ec7839e3473d9c4cde28b19394c3562f4f6d3" integrity sha1-dx7Hg540c9nEzeKLGTlMNWL09tM= -lodash.memoize@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" - integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4= - lodash.memoize@~3.0.3: version "3.0.4" resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-3.0.4.tgz#2dcbd2c287cbc0a55cc42328bd0c736150d53e3f" @@ -16801,7 +16997,7 @@ lodash.uniqby@^4.7.0: resolved "https://registry.yarnpkg.com/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz#d99c07a669e9e6d24e1362dfe266c67616af1302" integrity sha1-2ZwHpmnp5tJOE2Lf4mbGdhavEwI= -lodash@4.17.20, lodash@=3.10.1, lodash@^4.0.0, lodash@^4.0.1, lodash@^4.13.1, lodash@^4.14.0, lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.3.0, lodash@^4.8.0, lodash@~4.17.2, lodash@~4.17.4: +lodash@4.17.20, lodash@=3.10.1, lodash@^4.0.0, lodash@^4.0.1, lodash@^4.13.1, lodash@^4.14.0, lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.3.0, lodash@^4.8.0, lodash@~4.17.2, lodash@~4.17.4: version "4.17.20" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== @@ -16818,7 +17014,7 @@ log-symbols@3.0.0: dependencies: chalk "^2.4.2" -log-symbols@^2.2.0: +log-symbols@^2.1.0, log-symbols@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" integrity sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg== @@ -16845,6 +17041,14 @@ loglevel@^1.4.1, loglevel@^1.5.0: resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.0.tgz#ae0caa561111498c5ba13723d6fb631d24003934" integrity sha1-rgyqVhERSYxboTcj1vtjHSQAOTQ= +loglevelnext@^1.0.1: + version "1.0.5" + resolved "https://registry.yarnpkg.com/loglevelnext/-/loglevelnext-1.0.5.tgz#36fc4f5996d6640f539ff203ba819641680d75a2" + integrity sha512-V/73qkPuJmx4BcBF19xPBr+0ZRVBhc4POxvZTZdMeXpJ4NItXSJ/MSwuFT0kQJlCbXvdlZoQQ/418bS1y9Jh6A== + dependencies: + es6-symbol "^3.1.1" + object.assign "^4.1.0" + logplease@^1.2.14, logplease@~1.2.14, logplease@~1.2.15: version "1.2.15" resolved "https://registry.yarnpkg.com/logplease/-/logplease-1.2.15.tgz#3da442e93751a5992cc19010a826b08d0293c48a" @@ -16895,10 +17099,12 @@ loud-rejection@^1.0.0: currently-unhandled "^0.4.1" signal-exit "^3.0.0" -lower-case@^1.1.1: - version "1.1.4" - resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-1.1.4.tgz#9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac" - integrity sha1-miyr0bno4K6ZOkv31YdcOcQujqw= +lower-case@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.1.tgz#39eeb36e396115cc05e29422eaea9e692c9408c7" + integrity sha512-LiWgfDLLb1dwbFQZsSglpRj+1ctGnayXz3Uv0/WO8n558JycT5fg6zkNcnW0G68Nn0aEldTFeEfmjCfmqry/rQ== + dependencies: + tslib "^1.10.0" lowercase-keys@1.0.0: version "1.0.0" @@ -16915,13 +17121,13 @@ lowercase-keys@^2.0.0: resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== -lowlight@~1.11.0: - version "1.11.0" - resolved "https://registry.yarnpkg.com/lowlight/-/lowlight-1.11.0.tgz#1304d83005126d4e8b1dc0f07981e9b689ec2efc" - integrity sha512-xrGGN6XLL7MbTMdPD6NfWPwY43SNkjf/d0mecSx/CW36fUZTjRHEq0/Cdug3TWKtRXLWi7iMl1eP0olYxj/a4A== +lowlight@^1.14.0: + version "1.17.0" + resolved "https://registry.yarnpkg.com/lowlight/-/lowlight-1.17.0.tgz#a1143b2fba8239df8cd5893f9fe97aaf8465af4a" + integrity sha512-vmtBgYKD+QVNy7tIa7ulz5d//Il9R4MooOVh4nkOf9R9Cb/Dk5TXMSTieg/vDulkBkIWj59/BIlyFQxT9X1oAQ== dependencies: - fault "^1.0.2" - highlight.js "~9.13.0" + fault "^1.0.0" + highlight.js "~10.4.0" lpad-align@^1.0.1: version "1.1.2" @@ -17012,7 +17218,7 @@ make-dir@^1.0.0, make-dir@^1.2.0: dependencies: pify "^3.0.0" -make-dir@^2.0.0: +make-dir@^2.0.0, make-dir@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== @@ -17034,11 +17240,6 @@ make-iterator@^1.0.0: dependencies: kind-of "^6.0.2" -mamacro@^0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/mamacro/-/mamacro-0.0.3.tgz#ad2c9576197c9f1abf308d0787865bd975a3f3e4" - integrity sha512-qMEwh+UujcQ+kbz3T6V+wAmO2U8veoq2w+3wY8MquqwVA3jChfwY+Tk52GZKDfACEPjuZ7r2oJLejwpt8jtwTA== - map-age-cleaner@^0.1.1, map-age-cleaner@^0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" @@ -17090,7 +17291,7 @@ markdown-table@^2.0.0: dependencies: repeat-string "^1.0.0" -markdown-to-jsx@^6.9.1, markdown-to-jsx@^6.9.3: +markdown-to-jsx@^6.11.4: version "6.11.4" resolved "https://registry.yarnpkg.com/markdown-to-jsx/-/markdown-to-jsx-6.11.4.tgz#b4528b1ab668aef7fe61c1535c27e837819392c5" integrity sha512-3lRCD5Sh+tfA52iGgfs/XZiw33f7fFX9Bn55aNnVNUd2GzLDkOWyKYYD8Yju2B1Vn+feiEdgJs8T6Tg0xNokPw== @@ -17245,7 +17446,7 @@ memoizerific@^1.11.3: dependencies: map-or-similar "^1.5.0" -memory-fs@^0.4.0, memory-fs@^0.4.1: +memory-fs@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" integrity sha1-OpoguEYlI+RHz7x+i7gO1me/xVI= @@ -17253,6 +17454,14 @@ memory-fs@^0.4.0, memory-fs@^0.4.1: errno "^0.1.3" readable-stream "^2.0.1" +memory-fs@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.5.0.tgz#324c01288b88652966d161db77838720845a8e3c" + integrity sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA== + dependencies: + errno "^0.1.3" + readable-stream "^2.0.1" + meow@^3.3.0, meow@^3.7.0: version "3.7.0" resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" @@ -17427,10 +17636,10 @@ miller-rabin@^4.0.0: bn.js "^4.0.0" brorand "^1.0.1" -mime-db@1.42.0, mime-db@1.x.x, mime-db@^1.28.0: - version "1.42.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.42.0.tgz#3e252907b4c7adb906597b4b65636272cf9e7bac" - integrity sha512-UbfJCR4UAVRNgMpfImz05smAXK7+c+ZntjaA26ANtkXLlOe947Aag5zdIcKQULAiF9Cq4WxBi9jUs5zkA84bYQ== +mime-db@1.44.0, mime-db@1.x.x, mime-db@^1.28.0: + version "1.44.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" + integrity sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg== mime-db@~1.33.0: version "1.33.0" @@ -17444,19 +17653,19 @@ mime-types@2.1.18: dependencies: mime-db "~1.33.0" -mime-types@^2.1.12, mime-types@^2.1.16, mime-types@^2.1.18, mime-types@^2.1.21, mime-types@~2.1.19, mime-types@~2.1.24: - version "2.1.25" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.25.tgz#39772d46621f93e2a80a856c53b86a62156a6437" - integrity sha512-5KhStqB5xpTAeGqKBAMgwaYMnQik7teQN4IAzC7npDv6kzeU6prfkR67bc87J1kWMPGkoaZSq1npmexMgkmEVg== +mime-types@^2.1.12, mime-types@^2.1.16, mime-types@^2.1.18, mime-types@^2.1.21, mime-types@^2.1.27, mime-types@~2.1.19, mime-types@~2.1.24: + version "2.1.27" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f" + integrity sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w== dependencies: - mime-db "1.42.0" + mime-db "1.44.0" mime@1.6.0, mime@^1.4.1: version "1.6.0" resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== -mime@^2.4.2, mime@^2.4.4: +mime@^2.4.2: version "2.4.4" resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.4.tgz#bd7b91135fc6b01cde3e9bae33d659b63d8857e5" integrity sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA== @@ -17497,16 +17706,6 @@ mini-create-react-context@^0.3.0: gud "^1.0.0" tiny-warning "^1.0.2" -mini-css-extract-plugin@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-0.7.0.tgz#5ba8290fbb4179a43dd27cca444ba150bee743a0" - integrity sha512-RQIw6+7utTYn8DBGsf/LpRgZCJMpZt+kuawJ/fju0KiOL6nAaTBNmCJwS7HtwSCXfS47gCkmtBFS7HdsquhdxQ== - dependencies: - loader-utils "^1.1.0" - normalize-url "1.9.1" - schema-utils "^1.0.0" - webpack-sources "^1.1.0" - minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" @@ -17638,7 +17837,7 @@ mkdirp@*, mkdirp@^1.0.3, mkdirp@^1.0.4: resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== -mkdirp@0.5.5, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.4, mkdirp@^0.5.5, mkdirp@~0.5.1: +mkdirp@0.5.5, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.4, mkdirp@^0.5.5, mkdirp@~0.5.1: version "0.5.5" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== @@ -17966,16 +18165,11 @@ nano-json-stream-parser@^0.1.2: resolved "https://registry.yarnpkg.com/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz#0cc8f6d0e2b622b479c40d499c46d64b755c6f5f" integrity sha1-DMj20OK2IrR5xA1JnEbWS3Vcb18= -nanoid@^2.0.0: +nanoid@^2.0.0, nanoid@^2.1.6: version "2.1.11" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-2.1.11.tgz#ec24b8a758d591561531b4176a01e3ab4f0f0280" integrity sha512-s/snB+WGm6uwi0WjsZdaVcuf3KJXlfGl2LcxgwkEwJF0D/BWzVWAZW/XY4bFaiR7s0Jk3FPvlnepg1H1b1UwlA== -nanoid@^2.1.6: - version "2.1.6" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-2.1.6.tgz#0665418f692e54cf44f34d4010761f3240a03314" - integrity sha512-2NDzpiuEy3+H0AVtdt8LoFi7PnqkOnIzYmJQp7xsEU6VexLluHQwKREuiz57XaQC5006seIadPrIZJhyS2n7aw== - nanoid@^3.1.12: version "3.1.16" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.16.tgz#b21f0a7d031196faf75314d7c65d36352beeef64" @@ -18004,6 +18198,13 @@ napi-macros@~1.8.1: resolved "https://registry.yarnpkg.com/napi-macros/-/napi-macros-1.8.2.tgz#299265c1d8aa401351ad0675107d751228c03eda" integrity sha512-Tr0DNY4RzTaBG2W2m3l7ZtFuJChTH6VZhXVhkGGjF/4cZTt+i8GcM9ozD+30Lmr4mDoZ5Xx34t2o4GJqYWDGcg== +native-url@^0.2.6: + version "0.2.6" + resolved "https://registry.yarnpkg.com/native-url/-/native-url-0.2.6.tgz#ca1258f5ace169c716ff44eccbddb674e10399ae" + integrity sha512-k4bDC87WtgrdD362gZz6zoiXQrl40kYlBmpfmSjwRO1VU0V5ccwJTlxuE72F6m3V0vc1xOf6n3UCP9QyerRqmA== + dependencies: + querystring "^0.2.0" + natural-compare-lite@~1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz#17b09581988979fddafe0201e931ba933c96cbb4" @@ -18065,6 +18266,11 @@ neo-async@^2.5.0, neo-async@^2.6.1: resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.1.tgz#ac27ada66167fa8849a6addd837f6b189ad2081c" integrity sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw== +nested-error-stacks@^2.0.0, nested-error-stacks@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/nested-error-stacks/-/nested-error-stacks-2.1.0.tgz#0fbdcf3e13fe4994781280524f8b96b0cdff9c61" + integrity sha512-AO81vsIO1k1sM4Zrd6Hu7regmJN1NSiAja10gc4bX3F0wd+9rQmcuHQaHVQCYIEC8iFXnE+mavh23GOt7wBgug== + netmask@^1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/netmask/-/netmask-1.0.6.tgz#20297e89d86f6f6400f250d9f4f6b4c1945fcd35" @@ -18092,12 +18298,13 @@ nise@^4.0.1: just-extend "^4.0.2" path-to-regexp "^1.7.0" -no-case@^2.2.0: - version "2.3.2" - resolved "https://registry.yarnpkg.com/no-case/-/no-case-2.3.2.tgz#60b813396be39b3f1288a4c1ed5d1e7d28b464ac" - integrity sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ== +no-case@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/no-case/-/no-case-3.0.3.tgz#c21b434c1ffe48b39087e86cfb4d2582e9df18f8" + integrity sha512-ehY/mVQCf9BL0gKfsJBvFJen+1V//U+0HQMPrWct40ixE4jnv0bfvxDbWtAHL9EcaPEOJHVVYKoQn1TlZUB8Tw== dependencies: - lower-case "^1.1.1" + lower-case "^2.0.1" + tslib "^1.10.0" nock@^9.0.14: version "9.1.5" @@ -18139,7 +18346,12 @@ node-fetch@2.1.2: resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.1.2.tgz#ab884e8e7e57e38a944753cec706f788d1768bb5" integrity sha1-q4hOjn5X44qUR1POxwb3iNF2i7U= -node-fetch@^1.0.1, node-fetch@~1.7.1: +node-fetch@^2.3.0, node-fetch@^2.6.0, node-fetch@^2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" + integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== + +node-fetch@~1.7.1: version "1.7.3" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" integrity sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ== @@ -18147,11 +18359,6 @@ node-fetch@^1.0.1, node-fetch@~1.7.1: encoding "^0.1.11" is-stream "^1.0.1" -node-fetch@^2.3.0, node-fetch@^2.6.0, node-fetch@^2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" - integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== - node-forge@^0.10.0, node-forge@^0.7.1, node-forge@^0.7.5, node-forge@~0.7.6: version "0.10.0" resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3" @@ -18284,10 +18491,10 @@ node-preload@^0.2.0: dependencies: process-on-spawn "^1.0.0" -node-releases@^1.1.13, node-releases@^1.1.58: - version "1.1.59" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.59.tgz#4d648330641cec704bff10f8e4fe28e453ab8e8e" - integrity sha512-H3JrdUczbdiwxN5FuJPyCHnGHIFqQ0wWxo+9j1kAXAzqNMAHlo+4I/sYYxpyK0irQ73HgdiyzD32oqQDcU2Osw== +node-releases@^1.1.52, node-releases@^1.1.66: + version "1.1.67" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.67.tgz#28ebfcccd0baa6aad8e8d4d8fe4cbc49ae239c12" + integrity sha512-V5QF9noGFl3EymEwUYzO+3NTDpGfQB4ve6Qfnzf3UNydMhjQRVPR1DZTuvWiLzaFJYw2fmDwAfnRNEVb64hSIg== node-sass@^4.14.1, node-sass@^4.8.3: version "4.14.1" @@ -18397,16 +18604,6 @@ normalize-selector@^0.2.0: resolved "https://registry.yarnpkg.com/normalize-selector/-/normalize-selector-0.2.0.tgz#d0b145eb691189c63a78d201dc4fdb1293ef0c03" integrity sha1-0LFF62kRicY6eNIB3E/bEpPvDAM= -normalize-url@1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-1.9.1.tgz#2cc0d66b31ea23036458436e3620d85954c66c3c" - integrity sha1-LMDWazHqIwNkWENuNiDYWVTGbDw= - dependencies: - object-assign "^4.0.1" - prepend-http "^1.0.0" - query-string "^4.1.0" - sort-keys "^1.0.0" - normalize-url@2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-2.0.1.tgz#835a9da1551fa26f70e92329069a23aa6574d7e6" @@ -18708,6 +18905,11 @@ object.values@^1.0.4, object.values@^1.1.0, object.values@^1.1.1: function-bind "^1.1.1" has "^1.0.3" +objectorarray@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/objectorarray/-/objectorarray-1.0.4.tgz#d69b2f0ff7dc2701903d308bb85882f4ddb49483" + integrity sha512-91k8bjcldstRz1bG6zJo8lWD7c6QXcB4nTDUqiEvIL1xAsLoZlOOZZG+nd6YPz+V7zY1580J4Xxh1vZtyv4i/w== + oboe@2.1.4: version "2.1.4" resolved "https://registry.yarnpkg.com/oboe/-/oboe-2.1.4.tgz#20c88cdb0c15371bb04119257d4fdd34b0aa49f6" @@ -18780,10 +18982,10 @@ only@~0.0.2: resolved "https://registry.yarnpkg.com/only/-/only-0.0.2.tgz#2afde84d03e50b9a8edc444e30610a70295edfb4" integrity sha1-Kv3oTQPlC5qO3EROMGEKcCle37Q= -open@^7.0.0, open@^7.0.3: - version "7.1.0" - resolved "https://registry.yarnpkg.com/open/-/open-7.1.0.tgz#68865f7d3cb238520fa1225a63cf28bcf8368a1c" - integrity sha512-lLPI5KgOwEYCDKXf4np7y1PBEkj7HYIyP2DY8mVDRnx0VIIu6bNrRB0R66TuO7Mack6EnTNLm4uvcl1UoklTpA== +open@^7.0.2, open@^7.0.3: + version "7.3.0" + resolved "https://registry.yarnpkg.com/open/-/open-7.3.0.tgz#45461fdee46444f3645b6e14eb3ca94b82e1be69" + integrity sha512-mgLwQIx2F/ye9SmbrUkurZCnkoXyXyu9EbHtJZrICjVAJfyMArdHp3KkixGdZx1ZHFPNIwl0DDM1dFFqXbTLZw== dependencies: is-docker "^2.0.0" is-wsl "^2.1.1" @@ -18793,13 +18995,6 @@ opencollective-postinstall@^2.0.0: resolved "https://registry.yarnpkg.com/opencollective-postinstall/-/opencollective-postinstall-2.0.2.tgz#5657f1bede69b6e33a45939b061eb53d3c6c3a89" integrity sha512-pVOEP16TrAO2/fjej1IdOyupJY8KDUM1CvsaScRbw6oddvpQoOfGk4ywha0HKKVAD6RkW4x6Q+tNBwhf3Bgpuw== -opn@5.4.0: - version "5.4.0" - resolved "https://registry.yarnpkg.com/opn/-/opn-5.4.0.tgz#cb545e7aab78562beb11aa3bfabc7042e1761035" - integrity sha512-YF9MNdVy/0qvJvDtunAOzFw9iasOQHpVthTCvGzxt61Il64AYSGdK+rYwld7NAfk9qJ7dt+hymBNSc9LNYS+Sw== - dependencies: - is-wsl "^1.1.0" - optimist@~0.3.5: version "0.3.7" resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.3.7.tgz#c90941ad59e4273328923074d2cf2e7cbc6ec0d9" @@ -18994,13 +19189,6 @@ ordered-read-streams@^1.0.0: dependencies: readable-stream "^2.0.1" -original@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/original/-/original-1.0.2.tgz#e442a61cffe1c5fd20a65f3261c26663b303f25f" - integrity sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg== - dependencies: - url-parse "^1.4.3" - os-browserify@^0.3.0, os-browserify@~0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" @@ -19063,6 +19251,18 @@ outpipe@^1.1.0: dependencies: shell-quote "^1.4.2" +overlayscrollbars@^1.10.2: + version "1.13.0" + resolved "https://registry.yarnpkg.com/overlayscrollbars/-/overlayscrollbars-1.13.0.tgz#1edb436328133b94877b558f77966d5497ca36a7" + integrity sha512-p8oHrMeRAKxXDMPI/EBNITj/zTVHKNnAnM59Im+xnoZUlV07FyTg46wom2286jJlXGGfcPFG/ba5NUiCwWNd4w== + +p-all@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/p-all/-/p-all-2.1.0.tgz#91419be56b7dee8fe4c5db875d55e0da084244a0" + integrity sha512-HbZxz5FONzz/z2gJfk6bFca0BCiSRF8jU3yCsWOen/vR6lZjfPOu/e7L3uFzTW1i0H8TlC3vqQstEJPQL4/uLA== + dependencies: + p-map "^2.0.0" + p-cancelable@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.3.0.tgz#b9e123800bcebb7ac13a479be195b507b98d30fa" @@ -19109,6 +19309,20 @@ p-event@^2.1.0: dependencies: p-timeout "^2.0.1" +p-event@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/p-event/-/p-event-4.2.0.tgz#af4b049c8acd91ae81083ebd1e6f5cae2044c1b5" + integrity sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ== + dependencies: + p-timeout "^3.1.0" + +p-filter@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/p-filter/-/p-filter-2.1.0.tgz#1b1472562ae7a0f742f0f3d3d3718ea66ff9c09c" + integrity sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw== + dependencies: + p-map "^2.0.0" + p-finally@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" @@ -19136,19 +19350,19 @@ p-limit@^1.1.0: dependencies: p-try "^1.0.0" -p-limit@^2.0.0, p-limit@^2.2.0, p-limit@^2.3.0: +p-limit@^2.0.0, p-limit@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== dependencies: p-try "^2.0.0" -p-limit@^3.0.1: - version "3.0.2" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.0.2.tgz#1664e010af3cadc681baafd3e2a437be7b0fb5fe" - integrity sha512-iwqZSOoWIW+Ew4kAGUlN16J4M7OB3ysMLSZtnhmqx7njIHFPlxWBX8xo3lVTyFVq6mI/lL9qt2IsN1sHwaxJkg== +p-limit@^3.0.1, p-limit@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== dependencies: - p-try "^2.0.0" + yocto-queue "^0.1.0" p-locate@^2.0.0: version "2.0.0" @@ -19246,6 +19460,13 @@ p-timeout@^2.0.1: dependencies: p-finally "^1.0.0" +p-timeout@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-3.2.0.tgz#c7e17abc971d2a7962ef83626b35d635acf23dfe" + integrity sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg== + dependencies: + p-finally "^1.0.0" + p-times@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/p-times/-/p-times-2.1.0.tgz#b3e7f9159f916cacb6aae06d67c79451b0076c6c" @@ -19337,12 +19558,13 @@ parallel-transform@^1.1.0: inherits "^2.0.3" readable-stream "^2.1.5" -param-case@2.1.x: - version "2.1.1" - resolved "https://registry.yarnpkg.com/param-case/-/param-case-2.1.1.tgz#df94fd8cf6531ecf75e6bef9a0858fbc72be2247" - integrity sha1-35T9jPZTHs915r75oIWPvHK+Ikc= +param-case@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/param-case/-/param-case-3.0.3.tgz#4be41f8399eff621c56eebb829a5e451d9801238" + integrity sha512-VWBVyimc1+QrzappRs7waeN2YmoZFCGXWASRYX1/rGHtXqEcrGEIDm+jqIwFa2fRXNgQEwrxaYuIrX0WcAguTA== dependencies: - no-case "^2.2.0" + dot-case "^3.0.3" + tslib "^1.10.0" parent-module@^1.0.0: version "1.0.1" @@ -19369,18 +19591,6 @@ parse-asn1@^5.0.0: evp_bytestokey "^1.0.0" pbkdf2 "^3.0.3" -parse-entities@^1.1.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-1.2.2.tgz#c31bf0f653b6661354f8973559cb86dd1d5edf50" - integrity sha512-NzfpbxW/NPrzZ/yYSoQxyqUZMZXIdCfE0OIN4ESsnptHJECoUk3FZktxNuzQf4tjt5UEopnxpYJbvYuxIFDdsg== - dependencies: - character-entities "^1.0.0" - character-entities-legacy "^1.0.0" - character-reference-invalid "^1.0.0" - is-alphanumerical "^1.0.0" - is-decimal "^1.0.0" - is-hexadecimal "^1.0.0" - parse-entities@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-2.0.0.tgz#53c6eb5b9314a1f4ec99fa0fdf7ce01ecda0cbe8" @@ -19485,11 +19695,6 @@ parse5@^3.0.1, parse5@^3.0.2: dependencies: "@types/node" "*" -parse5@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.0.tgz#c59341c9723f414c452975564c7c00a68d58acd2" - integrity sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ== - parseqs@0.0.5: version "0.0.5" resolved "https://registry.yarnpkg.com/parseqs/-/parseqs-0.0.5.tgz#d5208a3738e46766e291ba2ea173684921a8b89d" @@ -19509,6 +19714,14 @@ parseurl@^1.3.2, parseurl@~1.3.2, parseurl@~1.3.3: resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== +pascal-case@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/pascal-case/-/pascal-case-3.1.1.tgz#5ac1975133ed619281e88920973d2cd1f279de5f" + integrity sha512-XIeHKqIrsquVTQL2crjq3NfJUxmdLasn3TYOU0VBM+UX2a6ztAWBlJQBePLGY7VHW8+2dRadeIPK5+KImwTxQA== + dependencies: + no-case "^3.0.3" + tslib "^1.10.0" + pascalcase@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" @@ -19857,19 +20070,19 @@ pkg-dir@^3.0.0: dependencies: find-up "^3.0.0" -pkg-dir@^4.1.0: +pkg-dir@^4.1.0, pkg-dir@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== dependencies: find-up "^4.0.0" -pkg-up@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-2.0.0.tgz#c819ac728059a461cab1c3889a2be3c49a004d7f" - integrity sha1-yBmscoBZpGHKscOImivjxJoATX8= +pkg-up@3.1.0, pkg-up@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-3.1.0.tgz#100ec235cc150e4fd42519412596a28512a0def5" + integrity sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA== dependencies: - find-up "^2.1.0" + find-up "^3.0.0" plugin-error@1.0.1, plugin-error@^1.0.1: version "1.0.1" @@ -19916,12 +20129,12 @@ pn@^1.0.0: resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb" integrity sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA== -pnp-webpack-plugin@1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/pnp-webpack-plugin/-/pnp-webpack-plugin-1.5.0.tgz#62a1cd3068f46d564bb33c56eb250e4d586676eb" - integrity sha512-jd9olUr9D7do+RN8Wspzhpxhgp1n6Vd0NtQ4SFkmIACZoEL1nkyAdW9Ygrinjec0vgDcWjscFQQ1gDW8rsfKTg== +pnp-webpack-plugin@1.6.4: + version "1.6.4" + resolved "https://registry.yarnpkg.com/pnp-webpack-plugin/-/pnp-webpack-plugin-1.6.4.tgz#c9711ac4dc48a685dabafc86f8b6dd9f8df84149" + integrity sha512-7Wjy+9E3WwLOEL30D+m8TSTF7qJJUJLONBnwQp0518siuMxUQUbgZwssaFX+QKlZkjHZcw/IpZCt/H0srrntSg== dependencies: - ts-pnp "^1.1.2" + ts-pnp "^1.1.6" po2json@0.4.5: version "0.4.5" @@ -19931,12 +20144,12 @@ po2json@0.4.5: gettext-parser "1.1.0" nomnom "1.8.1" -polished@^3.3.1: - version "3.4.0" - resolved "https://registry.yarnpkg.com/polished/-/polished-3.4.0.tgz#29b2a028ee0408df5dded55a2a25e913bc6749a9" - integrity sha512-GiuavmunMIKMOEoSPkXoqBYM2ZcI4YIwCaiwmTOQ55Zq4HG2kD0YZt3WlLZ2l3U9XhJ1LM/fgjCFHHffiZP0YQ== +polished@^3.4.4: + version "3.6.7" + resolved "https://registry.yarnpkg.com/polished/-/polished-3.6.7.tgz#44cbd0047f3187d83db0c479ef0c7d5583af5fb6" + integrity sha512-b4OViUOihwV0icb9PHmWbR+vPqaSzSAEbgLskvb7ANPATVXGiYv/TQFHQo65S53WU9i5EQ1I03YDOJW7K0bmYg== dependencies: - "@babel/runtime" "^7.4.4" + "@babel/runtime" "^7.9.2" polyfill-crypto.getrandomvalues@^1.0.0: version "1.0.0" @@ -19950,7 +20163,7 @@ popper.js@1.16.1-lts: resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.16.1-lts.tgz#cf6847b807da3799d80ee3d6d2f90df8a3f50b05" integrity sha512-Kjw8nKRl1m+VrSFCoVGPph93W/qrSO7ZkqPpTf7F4bk/sqcfWK019dWBUpE/fBOsOQY1dks/Bmcbfn1heM/IsA== -popper.js@^1.11.1, popper.js@^1.14.4, popper.js@^1.14.7: +popper.js@^1.11.1: version "1.15.0" resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.15.0.tgz#5560b99bbad7647e9faa475c6b8056621f5a4ff2" integrity sha512-w010cY1oCUmI+9KwwlWki+r5jxKfTFDVoadl7MSrIujHU5MJ5OR6HTDj6Xo8aoR/QsA56x8jKjA59qGH4ELtrA== @@ -20037,10 +20250,10 @@ postcss-modules-local-by-default@^3.0.2: postcss-selector-parser "^6.0.2" postcss-value-parser "^4.0.0" -postcss-modules-scope@^2.1.0, postcss-modules-scope@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-2.1.1.tgz#33d4fc946602eb5e9355c4165d68a10727689dba" - integrity sha512-OXRUPecnHCg8b9xWvldG/jUpRIGPNRka0r4D4j0ESUU2/5IOnpsjfPPmDprM3Ih8CgZ8FXjWqaniK5v4rWt3oQ== +postcss-modules-scope@^2.1.0, postcss-modules-scope@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz#385cae013cc7743f5a7d7602d1073a89eaae62ee" + integrity sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ== dependencies: postcss "^7.0.6" postcss-selector-parser "^6.0.0" @@ -20117,7 +20330,7 @@ postcss-value-parser@^3.2.3, postcss-value-parser@^3.3.0, postcss-value-parser@^ resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281" integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ== -postcss-value-parser@^4.0.0, postcss-value-parser@^4.0.2, postcss-value-parser@^4.1.0: +postcss-value-parser@^4.0.0, postcss-value-parser@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz#443f6a20ced6481a2bda4fa8532a6e55d789a2cb" integrity sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ== @@ -20149,7 +20362,7 @@ postcss@^6.0.1, postcss@^6.0.19, postcss@^6.0.23: source-map "^0.6.1" supports-color "^5.4.0" -postcss@^7.0.0, postcss@^7.0.14, postcss@^7.0.16, postcss@^7.0.2, postcss@^7.0.21, postcss@^7.0.23, postcss@^7.0.26, postcss@^7.0.32, postcss@^7.0.5, postcss@^7.0.6, postcss@^7.0.7: +postcss@^7.0.0, postcss@^7.0.14, postcss@^7.0.16, postcss@^7.0.2, postcss@^7.0.21, postcss@^7.0.26, postcss@^7.0.32, postcss@^7.0.5, postcss@^7.0.6, postcss@^7.0.7: version "7.0.32" resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.32.tgz#4310d6ee347053da3433db2be492883d62cec59d" integrity sha512-03eXong5NLnNCD05xscnGKGDZ98CyzoqPSMjOe6SuoQY7Z2hIj0Ld1g/O/UQRuOle2aRtiIRDg9tDcTGAkLfKw== @@ -20180,7 +20393,7 @@ prelude-ls@~1.1.2: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= -prepend-http@^1.0.0, prepend-http@^1.0.1: +prepend-http@^1.0.1: version "1.0.4" resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= @@ -20254,14 +20467,14 @@ priorityqueue@~0.2.1: resolved "https://registry.yarnpkg.com/priorityqueue/-/priorityqueue-0.2.1.tgz#f57e623f20237f30c142d4cb45fafed9e7d51403" integrity sha512-Dr6ZkRFGZHoAri6iNp5KvspOrFPfhxJ5AExXqLy5ChgdwALd3nC+q5/QG+gmjmf9W63joDXc+Zp0h05Ug/RtYg== -prismjs@^1.8.4, prismjs@~1.16.0: - version "1.16.0" - resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.16.0.tgz#406eb2c8aacb0f5f0f1167930cb83835d10a4308" - integrity sha512-OA4MKxjFZHSvZcisLGe14THYsug/nF6O1f0pAJc0KN0wTyAcLqmsbE+lTGKSpyh+9pEW57+k6pg2AfYR+coyHA== +prismjs@^1.21.0, prismjs@~1.22.0: + version "1.22.0" + resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.22.0.tgz#73c3400afc58a823dd7eed023f8e1ce9fd8977fa" + integrity sha512-lLJ/Wt9yy0AiSYBf212kK3mM5L8ycwlyTlSxHBAneXLR0nzFMlZ5y7riFPF3E33zXOF2IH95xdY5jIyZbM9z/w== optionalDependencies: clipboard "^2.0.0" -private@^0.1.6, private@^0.1.8, private@~0.1.5: +private@^0.1.6, private@^0.1.8: version "0.1.8" resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg== @@ -20373,13 +20586,6 @@ promise.prototype.finally@^3.1.0: es-abstract "^1.9.0" function-bind "^1.1.1" -promise@^7.1.1: - version "7.3.1" - resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" - integrity sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg== - dependencies: - asap "~2.0.3" - promise@~1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/promise/-/promise-1.3.0.tgz#e5cc9a4c8278e4664ffedc01c7da84842b040175" @@ -20401,7 +20607,7 @@ prop-types-exact@^1.2.0: object.assign "^4.1.0" reflect.ownkeys "^0.2.0" -prop-types@15.7.2, prop-types@^15.5.10, prop-types@^15.5.6, prop-types@^15.5.7, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2: +prop-types@15.7.2, prop-types@^15.0.0, prop-types@^15.5.10, prop-types@^15.5.6, prop-types@^15.5.7, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2: version "15.7.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== @@ -20424,7 +20630,7 @@ proper-lockfile@^4.0.0: retry "^0.12.0" signal-exit "^3.0.2" -property-information@^5.0.0, property-information@^5.0.1: +property-information@^5.0.0: version "5.1.0" resolved "https://registry.yarnpkg.com/property-information/-/property-information-5.1.0.tgz#e4755eee5319f03f7f6f5a9bc1a6a7fea6609e2c" integrity sha512-tODH6R3+SwTkAQckSp2S9xyYX8dEKYkeXw+4TmJzTxnNzd6mQPu1OD4f9zPrvw/Rm4wpPgI+Zp63mNSGNzUgHg== @@ -20805,14 +21011,6 @@ qs@~6.5.2: resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== -query-string@^4.1.0: - version "4.3.4" - resolved "https://registry.yarnpkg.com/query-string/-/query-string-4.3.4.tgz#bbb693b9ca915c232515b228b1a02b609043dbeb" - integrity sha1-u7aTucqRXCMlFbIosaArYJBD2+s= - dependencies: - object-assign "^4.1.0" - strict-uri-encode "^1.0.0" - query-string@^5.0.1: version "5.1.1" resolved "https://registry.yarnpkg.com/query-string/-/query-string-5.1.1.tgz#a78c012b71c17e05f2e3fa2319dd330682efb3cb" @@ -20832,11 +21030,6 @@ querystring@0.2.0, querystring@^0.2.0: resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= -querystringify@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.1.1.tgz#60e5a5fd64a7f8bfa4d2ab2ed6fdf4c85bad154e" - integrity sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA== - quick-format-unescaped@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/quick-format-unescaped/-/quick-format-unescaped-3.0.2.tgz#0137e94d8fb37ffeb70040535111c378e75396fb" @@ -20955,13 +21148,13 @@ raw-body@~1.1.0: bytes "1" string_decoder "0.10" -raw-loader@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/raw-loader/-/raw-loader-3.1.0.tgz#5e9d399a5a222cc0de18f42c3bc5e49677532b3f" - integrity sha512-lzUVMuJ06HF4rYveaz9Tv0WRlUMxJ0Y1hgSkkgg+50iEdaI0TthyEDe08KIHb0XsF6rn8WYTqPCaGTZg3sX+qA== +raw-loader@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/raw-loader/-/raw-loader-4.0.2.tgz#1aac6b7d1ad1501e66efdac1522c73e59a584eb6" + integrity sha512-ZnScIV3ag9A4wPX/ZayxL/jZH+euYb6FcUinPcgiQW0+UBtEv0O6Q3lGd3cqJ+GHH+rksEv3Pj99oxJ3u3VIKA== dependencies: - loader-utils "^1.1.0" - schema-utils "^2.0.1" + loader-utils "^2.0.0" + schema-utils "^3.0.0" rc@^1.0.1, rc@^1.1.6, rc@^1.2.7, rc@^1.2.8: version "1.2.8" @@ -20973,13 +21166,6 @@ rc@^1.0.1, rc@^1.1.6, rc@^1.2.7, rc@^1.2.8: minimist "^1.2.0" strip-json-comments "~2.0.1" -react-clientside-effect@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/react-clientside-effect/-/react-clientside-effect-1.2.2.tgz#6212fb0e07b204e714581dd51992603d1accc837" - integrity sha512-nRmoyxeok5PBO6ytPvSjKp9xwXg9xagoTK1mMjwnQxqM9Hd7MNPl+LS1bOSOe+CV2+4fnEquc7H/S8QD3q697A== - dependencies: - "@babel/runtime" "^7.0.0" - react-color@^2.17.0: version "2.17.3" resolved "https://registry.yarnpkg.com/react-color/-/react-color-2.17.3.tgz#b8556d744f95193468c7061d2aa19180118d4a48" @@ -20992,35 +21178,34 @@ react-color@^2.17.0: reactcss "^1.2.0" tinycolor2 "^1.4.1" -react-dev-utils@^9.0.0: - version "9.0.1" - resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-9.0.1.tgz#5c03d85a0b2537d0c46af7165c24a7dfb274bef2" - integrity sha512-pnaeMo/Pxel8aZpxk1WwxT3uXxM3tEwYvsjCYn5R7gNxjhN1auowdcLDzFB8kr7rafAj2rxmvfic/fbac5CzwQ== +react-dev-utils@^10.0.0: + version "10.2.1" + resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-10.2.1.tgz#f6de325ae25fa4d546d09df4bb1befdc6dd19c19" + integrity sha512-XxTbgJnYZmxuPtY3y/UV0D8/65NKkmaia4rXzViknVnZeVlklSh8u6TnaEYPfAi/Gh1TP4mEOXHI6jQOPbeakQ== dependencies: - "@babel/code-frame" "7.0.0" - address "1.0.3" - browserslist "4.5.4" + "@babel/code-frame" "7.8.3" + address "1.1.2" + browserslist "4.10.0" chalk "2.4.2" - cross-spawn "6.0.5" + cross-spawn "7.0.1" detect-port-alt "1.1.6" - escape-string-regexp "1.0.5" - filesize "3.6.1" - find-up "3.0.0" - fork-ts-checker-webpack-plugin "1.1.1" + escape-string-regexp "2.0.0" + filesize "6.0.1" + find-up "4.1.0" + fork-ts-checker-webpack-plugin "3.1.1" global-modules "2.0.0" globby "8.0.2" - gzip-size "5.0.0" + gzip-size "5.1.1" immer "1.10.0" - inquirer "6.2.2" - is-root "2.0.0" + inquirer "7.0.4" + is-root "2.1.0" loader-utils "1.2.3" - opn "5.4.0" - pkg-up "2.0.0" - react-error-overlay "^5.1.6" + open "^7.0.2" + pkg-up "3.1.0" + react-error-overlay "^6.0.7" recursive-readdir "2.2.2" - shell-quote "1.6.1" - sockjs-client "1.3.0" - strip-ansi "5.2.0" + shell-quote "1.7.2" + strip-ansi "6.0.0" text-table "0.2.0" react-devtools-core@4.8.2: @@ -21063,6 +21248,32 @@ react-dnd@^3.0.2: prop-types "^15.5.10" shallowequal "^1.0.2" +react-docgen-typescript-loader@^3.7.2: + version "3.7.2" + resolved "https://registry.yarnpkg.com/react-docgen-typescript-loader/-/react-docgen-typescript-loader-3.7.2.tgz#45cb2305652c0602767242a8700ad1ebd66bbbbd" + integrity sha512-fNzUayyUGzSyoOl7E89VaPKJk9dpvdSgyXg81cUkwy0u+NBvkzQG3FC5WBIlXda0k/iaxS+PWi+OC+tUiGxzPA== + dependencies: + "@webpack-contrib/schema-utils" "^1.0.0-beta.0" + loader-utils "^1.2.3" + react-docgen-typescript "^1.15.0" + +react-docgen-typescript-plugin@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/react-docgen-typescript-plugin/-/react-docgen-typescript-plugin-0.6.2.tgz#c83305206c61d5c7e004eaf2dc4661367ddc105d" + integrity sha512-Orw0WKdJGAg5eMZGbEMw/rKonoxbi8epU6RJWTW3ukWuTarxckFXTltGvm8XADAWlBHak30KD71XThtJruxfTg== + dependencies: + debug "^4.1.1" + endent "^2.0.1" + micromatch "^4.0.2" + react-docgen-typescript "^1.20.1" + react-docgen-typescript-loader "^3.7.2" + tslib "^2.0.0" + +react-docgen-typescript@^1.15.0, react-docgen-typescript@^1.20.1: + version "1.20.5" + resolved "https://registry.yarnpkg.com/react-docgen-typescript/-/react-docgen-typescript-1.20.5.tgz#fb8d78a707243498436c2952bd3f6f488a68d4f3" + integrity sha512-AbLGMtn76bn7SYBJSSaKJrZ0lgNRRR3qL60PucM5M4v/AXyC8221cKBXW5Pyt9TfDRfe+LDnPNlg7TibxX0ovA== + react-docgen@^5.0.0: version "5.1.0" resolved "https://registry.yarnpkg.com/react-docgen/-/react-docgen-5.1.0.tgz#8e69f1d2e9153c535c20162ea1b85878b059b474" @@ -21077,7 +21288,7 @@ react-docgen@^5.0.0: node-dir "^0.1.10" strip-indent "^3.0.0" -react-dom@^16.12.0, react-dom@^16.8.3: +react-dom@^16.12.0: version "16.12.0" resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.12.0.tgz#0da4b714b8d13c2038c9396b54a92baea633fe11" integrity sha512-LMxFfAGrcS3kETtQaCkTKjMiifahaMySFDn71fZUNpPHZQEzmk/GiAeIT8JSOrHB23fnuCOMruL2a8NYlw+8Gw== @@ -21095,10 +21306,10 @@ react-draggable@^4.0.3: classnames "^2.2.5" prop-types "^15.6.0" -react-error-overlay@^5.1.6: - version "5.1.6" - resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-5.1.6.tgz#0cd73407c5d141f9638ae1e0c63e7b2bf7e9929d" - integrity sha512-X1Y+0jR47ImDVr54Ab6V9eGk0Hnu7fVWGeHQSOXHf/C2pF9c6uy3gef8QUeuUiWlNb0i08InPSE5a/KJzNzw1Q== +react-error-overlay@^6.0.7: + version "6.0.8" + resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.8.tgz#474ed11d04fc6bda3af643447d85e9127ed6b5de" + integrity sha512-HvPuUQnLp5H7TouGq3kzBeioJmXms1wHy9EGjz2OURWBp4qZO6AfGEcnxts1D/CbwPLRAgTMPCEgYhA3sEM4vw== react-fast-compare@2.0.4: version "2.0.4" @@ -21110,18 +21321,6 @@ react-fast-compare@^3.0.1: resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.1.1.tgz#0becf31e3812fa70dc231e259f40d892d4767900" integrity sha512-SCsAORWK59BvauR2L1BTdjQbJcSGJJz03U0awektk2hshLKrITDDFTlgGCqIZpTDlPC/NFlZee6xTMzXPVLiHw== -react-focus-lock@^2.1.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/react-focus-lock/-/react-focus-lock-2.2.1.tgz#1d12887416925dc53481914b7cedd39494a3b24a" - integrity sha512-47g0xYcCTZccdzKRGufepY8oZ3W1Qg+2hn6u9SHZ0zUB6uz/4K4xJe7yYFNZ1qT6m+2JDm82F6QgKeBTbjW4PQ== - dependencies: - "@babel/runtime" "^7.0.0" - focus-lock "^0.6.6" - prop-types "^15.6.2" - react-clientside-effect "^1.2.2" - use-callback-ref "^1.2.1" - use-sidecar "^1.0.1" - react-helmet-async@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/react-helmet-async/-/react-helmet-async-1.0.2.tgz#bb55dd8268f7b15aac69c6b22e2f950abda8cc44" @@ -21160,16 +21359,16 @@ react-inspector@^2.3.0: babel-runtime "^6.26.0" is-dom "^1.0.9" -react-inspector@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/react-inspector/-/react-inspector-4.0.1.tgz#0f888f78ff7daccbc7be5d452b20c96dc6d5fbb8" - integrity sha512-xSiM6CE79JBqSj8Fzd9dWBHv57tLTH7OM57GP3VrE5crzVF3D5Khce9w1Xcw75OAbvrA0Mi2vBneR1OajKmXFg== +react-inspector@^5.0.1: + version "5.1.0" + resolved "https://registry.yarnpkg.com/react-inspector/-/react-inspector-5.1.0.tgz#45a325e15f33e595be5356ca2d3ceffb7d6b8c3a" + integrity sha512-JAwswiengIcxi4X/Ssb8nf6suOuQsyit8Fxo04+iPKTnPNY3XIOuagjMZSzpJDDKkYcc/ARlySOYZZv626WUvA== dependencies: - "@babel/runtime" "^7.6.3" - is-dom "^1.0.9" - prop-types "^15.6.1" + "@babel/runtime" "^7.0.0" + is-dom "^1.0.0" + prop-types "^15.0.0" -react-is@^16.10.2, react-is@^16.12.0, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.0, react-is@^16.8.1, react-is@^16.8.6, react-is@^16.9.0: +react-is@^16.10.2, react-is@^16.12.0, react-is@^16.13.1, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.0, react-is@^16.8.1, react-is@^16.8.6, react-is@^16.9.0: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== @@ -21188,30 +21387,19 @@ react-motion@^0.5.2: prop-types "^15.5.8" raf "^3.1.0" -react-popper-tooltip@^2.8.3: - version "2.8.3" - resolved "https://registry.yarnpkg.com/react-popper-tooltip/-/react-popper-tooltip-2.8.3.tgz#1c63e7473a96362bd93be6c94fa404470a265197" - integrity sha512-g5tfxmuj8ClNVwH4zswYJcD3GKoc5RMeRawd/WZnbyZGEDecsRKaVL+Kj7L3BG7w5qb6/MHcLTG8yE4CidwezQ== - dependencies: - "@babel/runtime" "^7.4.5" - react-popper "^1.3.3" - -react-popper@^1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-1.3.3.tgz#2c6cef7515a991256b4f0536cd4bdcb58a7b6af6" - integrity sha512-ynMZBPkXONPc5K4P5yFWgZx5JGAUIP3pGGLNs58cfAPgK67olx7fmLp+AdpZ0+GoQ+ieFDa/z4cdV6u7sioH6w== +react-popper-tooltip@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/react-popper-tooltip/-/react-popper-tooltip-3.1.1.tgz#329569eb7b287008f04fcbddb6370452ad3f9eac" + integrity sha512-EnERAnnKRptQBJyaee5GJScWNUKQPDD2ywvzZyUjst/wj5U64C8/CnSYLNEmP2hG0IJ3ZhtDxE8oDN+KOyavXQ== dependencies: - "@babel/runtime" "^7.1.2" - create-react-context "<=0.2.2" - popper.js "^1.14.4" - prop-types "^15.6.1" - typed-styles "^0.0.7" - warning "^4.0.2" + "@babel/runtime" "^7.12.5" + "@popperjs/core" "^2.5.4" + react-popper "^2.2.4" -react-popper@^2.2.3: - version "2.2.3" - resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-2.2.3.tgz#33d425fa6975d4bd54d9acd64897a89d904b9d97" - integrity sha512-mOEiMNT1249js0jJvkrOjyHsGvqcJd3aGW/agkiMoZk3bZ1fXN1wQszIQSjHIai48fE67+zwF8Cs+C4fWqlfjw== +react-popper@^2.2.3, react-popper@^2.2.4: + version "2.2.4" + resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-2.2.4.tgz#d2ad3d2474ac9f1abf93df3099d408e5aa6a2e22" + integrity sha512-NacOu4zWupdQjVXq02XpTD3yFPSfg5a7fex0wa3uGKVkFK7UN6LvVxgcb+xYr56UCuWiNPMH20tntdVdJRwYew== dependencies: react-fast-compare "^3.0.1" warning "^4.0.2" @@ -21227,6 +21415,11 @@ react-redux@^7.2.0: prop-types "^15.7.2" react-is "^16.9.0" +react-refresh@^0.8.3: + version "0.8.3" + resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.8.3.tgz#721d4657672d400c5e3c75d063c4a85fb2d5d68f" + integrity sha512-X8jZHc7nCMjaCqoU+V2I0cOhNW+QMBwSUkeXnTi8IPe6zaRWfn60ZzvFDZqWPfmSJfjub7dDW1SP0jaHWLu/hg== + react-router-dom@^5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-5.1.2.tgz#06701b834352f44d37fbb6311f870f84c76b9c18" @@ -21296,16 +21489,16 @@ react-sizeme@^2.6.7: shallowequal "^1.1.0" throttle-debounce "^2.1.0" -react-syntax-highlighter@^11.0.2: - version "11.0.2" - resolved "https://registry.yarnpkg.com/react-syntax-highlighter/-/react-syntax-highlighter-11.0.2.tgz#4e3f376e752b20d2f54e4c55652fd663149e4029" - integrity sha512-kqmpM2OH5OodInbEADKARwccwSQWBfZi0970l5Jhp4h39q9Q65C4frNcnd6uHE5pR00W8pOWj9HDRntj2G4Rww== +react-syntax-highlighter@^13.5.0: + version "13.5.3" + resolved "https://registry.yarnpkg.com/react-syntax-highlighter/-/react-syntax-highlighter-13.5.3.tgz#9712850f883a3e19eb858cf93fad7bb357eea9c6" + integrity sha512-crPaF+QGPeHNIblxxCdf2Lg936NAHKhNhuMzRL3F9ct6aYXL3NcZtCL0Rms9+qVo6Y1EQLdXGypBNSbPL/r+qg== dependencies: "@babel/runtime" "^7.3.1" - highlight.js "~9.13.0" - lowlight "~1.11.0" - prismjs "^1.8.4" - refractor "^2.4.1" + highlight.js "^10.1.1" + lowlight "^1.14.0" + prismjs "^1.21.0" + refractor "^3.1.0" react-test-renderer@^16.0.0-0, react-test-renderer@^16.12.0: version "16.12.0" @@ -21317,13 +21510,14 @@ react-test-renderer@^16.0.0-0, react-test-renderer@^16.12.0: react-is "^16.8.6" scheduler "^0.18.0" -react-textarea-autosize@^7.1.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/react-textarea-autosize/-/react-textarea-autosize-7.1.0.tgz#3132cb77e65d94417558d37c0bfe415a5afd3445" - integrity sha512-c2FlR/fP0qbxmlrW96SdrbgP/v0XZMTupqB90zybvmDVDutytUgPl7beU35klwcTeMepUIQEpQUn3P3bdshGPg== +react-textarea-autosize@^8.1.1: + version "8.3.0" + resolved "https://registry.yarnpkg.com/react-textarea-autosize/-/react-textarea-autosize-8.3.0.tgz#e6e2fd186d9f61bb80ac6e2dcb4c55504f93c2fa" + integrity sha512-3GLWFAan2pbwBeoeNDoqGmSbrShORtgWfaWX0RJDivsUrpShh01saRM5RU/i4Zmf+whpBVEY5cA90Eq8Ub1N3w== dependencies: - "@babel/runtime" "^7.1.2" - prop-types "^15.6.0" + "@babel/runtime" "^7.10.2" + use-composed-ref "^1.0.0" + use-latest "^1.0.0" react-tippy@^1.2.2: version "1.2.2" @@ -21371,7 +21565,7 @@ react-transition-group@^4.4.0: loose-envify "^1.4.0" prop-types "^15.6.2" -react@^16.12.0, react@^16.8.3: +react@^16.12.0: version "16.12.0" resolved "https://registry.yarnpkg.com/react/-/react-16.12.0.tgz#0c0a9c6a142429e3614834d5a778e18aa78a0b83" integrity sha512-fglqy3k5E+81pA8s+7K0/T3DBCF0ZDOher1elBFzF7O6arXJgzyu/FW+COxFvAWXJoJN9KIZbT2LXlukwphYTA== @@ -21558,6 +21752,13 @@ readdirp@~3.2.0: dependencies: picomatch "^2.0.4" +readdirp@~3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.5.0.tgz#9ba74c019b15d365278d2e91bb8c48d7b4d42c9e" + integrity sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ== + dependencies: + picomatch "^2.2.1" + readline2@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/readline2/-/readline2-1.0.1.tgz#41059608ffc154757b715d9989d199ffbf372e35" @@ -21567,16 +21768,6 @@ readline2@^1.0.1: is-fullwidth-code-point "^1.0.0" mute-stream "0.0.5" -recast@^0.14.7: - version "0.14.7" - resolved "https://registry.yarnpkg.com/recast/-/recast-0.14.7.tgz#4f1497c2b5826d42a66e8e3c9d80c512983ff61d" - integrity sha512-/nwm9pkrcWagN40JeJhkPaRxiHXBRkXyRh/hgU088Z/v+qCy+zIHHY6bC6o7NaKAxPqtE6nD8zBH1LfU0/Wx6A== - dependencies: - ast-types "0.11.3" - esprima "~4.0.0" - private "~0.1.5" - source-map "~0.6.1" - receptacle@^1.3.2: version "1.3.2" resolved "https://registry.yarnpkg.com/receptacle/-/receptacle-1.3.2.tgz#a7994c7efafc7a01d0e2041839dab6c4951360d2" @@ -21658,19 +21849,19 @@ reflect.ownkeys@^0.2.0: resolved "https://registry.yarnpkg.com/reflect.ownkeys/-/reflect.ownkeys-0.2.0.tgz#749aceec7f3fdf8b63f927a04809e90c5c0b3460" integrity sha1-dJrO7H8/34tj+SegSAnpDFwLNGA= -refractor@^2.4.1: - version "2.9.0" - resolved "https://registry.yarnpkg.com/refractor/-/refractor-2.9.0.tgz#0a381aadb51513e4e6ec1ed410b5104dd65e2489" - integrity sha512-lCnCYvXpqd8hC7ksuvo516rz5q4NwzBbq0X5qjH5pxRfcQKiQxKZ8JctrSQmrR/7pcV2TRrs9TT+Whmq/wtluQ== +refractor@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/refractor/-/refractor-3.2.0.tgz#bc46f7cfbb6adbf45cd304e8e299b7fa854804e0" + integrity sha512-hSo+EyMIZTLBvNNgIU5lW4yjCzNYMZ4dcEhBq/3nReGfqzd2JfVhdlPDfU9rEsgcAyWx+OimIIUoL4ZU7NtYHQ== dependencies: - hastscript "^5.0.0" - parse-entities "^1.1.2" - prismjs "~1.16.0" + hastscript "^6.0.0" + parse-entities "^2.0.0" + prismjs "~1.22.0" -regenerate-unicode-properties@^8.0.2: - version "8.1.0" - resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.1.0.tgz#ef51e0f0ea4ad424b77bf7cb41f3e015c70a3f0e" - integrity sha512-LGZzkgtLY79GeXLm8Dp0BVLdQlWICzBnJz/ipWUgo59qBaZ+BHtq51P2q1uVZlppMuUAT37SDk39qUbjTWB7bA== +regenerate-unicode-properties@^8.2.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz#e5de7111d655e7ba60c057dbe9ff37c87e65cdec" + integrity sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA== dependencies: regenerate "^1.4.0" @@ -21694,10 +21885,10 @@ regenerator-runtime@^0.12.0: resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz#fa1a71544764c036f8c49b13a08b2594c9f8a0de" integrity sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg== -regenerator-runtime@^0.13.2, regenerator-runtime@^0.13.3, regenerator-runtime@^0.13.4: - version "0.13.5" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz#d878a1d094b4306d10b9096484b33ebd55e26697" - integrity sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA== +regenerator-runtime@^0.13.3, regenerator-runtime@^0.13.4, regenerator-runtime@^0.13.7: + version "0.13.7" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz#cac2dacc8a1ea675feaabaeb8ae833898ae46f55" + integrity sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew== regenerator-transform@^0.10.0: version "0.10.1" @@ -21708,12 +21899,12 @@ regenerator-transform@^0.10.0: babel-types "^6.19.0" private "^0.1.6" -regenerator-transform@^0.14.0: - version "0.14.0" - resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.0.tgz#2ca9aaf7a2c239dd32e4761218425b8c7a86ecaf" - integrity sha512-rtOelq4Cawlbmq9xuMR5gdFmv7ku/sFoB7sRiywx7aq53bc52b4j6zvH7Te1Vt/X2YveDKnCGUbioieU7FEL3w== +regenerator-transform@^0.14.2: + version "0.14.5" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.5.tgz#c98da154683671c9c4dcb16ece736517e1b7feb4" + integrity sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw== dependencies: - private "^0.1.6" + "@babel/runtime" "^7.8.4" regex-cache@^0.4.2: version "0.4.4" @@ -21735,11 +21926,6 @@ regex-parser@^2.2.11: resolved "https://registry.yarnpkg.com/regex-parser/-/regex-parser-2.2.11.tgz#3b37ec9049e19479806e878cabe7c1ca83ccfe58" integrity sha512-jbD/FT0+9MBU2XAZluI7w2OBs1RBi6p9M83nkoZayQXXU9e8Robt69FcZc7wU4eJD/YFTjn1JdCk3rbMJajz8Q== -regexp-tree@^0.1.6: - version "0.1.10" - resolved "https://registry.yarnpkg.com/regexp-tree/-/regexp-tree-0.1.10.tgz#d837816a039c7af8a8d64d7a7c3cf6a1d93450bc" - integrity sha512-K1qVSbcedffwuIslMwpe6vGlj+ZXRnGkvjAtFHfDZZZuEdA/h0dxljAPu9vhUo6Rrx2U2AwJ+nSQ6hK+lrP5MQ== - regexp.prototype.flags@^1.2.0, regexp.prototype.flags@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz#7aba89b3c13a64509dabcf3ca8d9fbb9bdf5cb75" @@ -21767,17 +21953,17 @@ regexpu-core@^2.0.0: regjsgen "^0.2.0" regjsparser "^0.1.4" -regexpu-core@^4.5.4: - version "4.5.4" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.5.4.tgz#080d9d02289aa87fe1667a4f5136bc98a6aebaae" - integrity sha512-BtizvGtFQKGPUcTy56o3nk1bGRp4SZOTYrDtGNlqCQufptV5IkkLN6Emw+yunAJjzf+C9FQFtvq7IoA3+oMYHQ== +regexpu-core@^4.7.1: + version "4.7.1" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.7.1.tgz#2dea5a9a07233298fbf0db91fa9abc4c6e0f8ad6" + integrity sha512-ywH2VUraA44DZQuRKzARmw6S66mr48pQVva4LBeRhcOltJ6hExvWly5ZjFLYo67xbIxb6W1q4bAGtgfEl20zfQ== dependencies: regenerate "^1.4.0" - regenerate-unicode-properties "^8.0.2" - regjsgen "^0.5.0" - regjsparser "^0.6.0" + regenerate-unicode-properties "^8.2.0" + regjsgen "^0.5.1" + regjsparser "^0.6.4" unicode-match-property-ecmascript "^1.0.4" - unicode-match-property-value-ecmascript "^1.1.0" + unicode-match-property-value-ecmascript "^1.2.0" registry-auth-token@^3.0.1: version "3.4.0" @@ -21814,10 +22000,10 @@ regjsgen@^0.2.0: resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" integrity sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc= -regjsgen@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.0.tgz#a7634dc08f89209c2049adda3525711fb97265dd" - integrity sha512-RnIrLhrXCX5ow/E5/Mh2O4e/oa1/jW0eaBKTSy3LaCj+M3Bqvm97GWDp2yUtzIs4LEn65zR2yiYGFqb2ApnzDA== +regjsgen@^0.5.1: + version "0.5.2" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.2.tgz#92ff295fb1deecbf6ecdab2543d207e91aa33733" + integrity sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A== regjsparser@^0.1.4: version "0.1.5" @@ -21826,23 +22012,14 @@ regjsparser@^0.1.4: dependencies: jsesc "~0.5.0" -regjsparser@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.0.tgz#f1e6ae8b7da2bae96c99399b868cd6c933a2ba9c" - integrity sha512-RQ7YyokLiQBomUJuUG8iGVvkgOLxwyZM8k6d3q5SAXpg4r5TZJZigKFvC6PpD+qQ98bCDC5YelPeA3EucDoNeQ== +regjsparser@^0.6.4: + version "0.6.4" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.4.tgz#a769f8684308401a66e9b529d2436ff4d0666272" + integrity sha512-64O87/dPDgfk8/RQqC4gkZoGyyWFIEUTTh80CU6CWuK5vkCGyekIx+oKcEIYtP/RAxSQltCZHCNu/mdd7fqlJw== dependencies: jsesc "~0.5.0" -rehype-parse@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/rehype-parse/-/rehype-parse-6.0.0.tgz#f681555f2598165bee2c778b39f9073d17b16bca" - integrity sha512-V2OjMD0xcSt39G4uRdMTqDXXm6HwkUbLMDayYKA/d037j8/OtVSQ+tqKwYWOuyBeoCs/3clXRe30VUjeMDTBSA== - dependencies: - hast-util-from-parse5 "^5.0.0" - parse5 "^5.0.0" - xtend "^4.0.1" - -relateurl@0.2.x: +relateurl@^0.2.7: version "0.2.7" resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" integrity sha1-VNvzd+UUQKypCkzSdGANP/LYiKk= @@ -22113,11 +22290,6 @@ require-uncached@^1.0.2: caller-path "^0.1.0" resolve-from "^1.0.0" -requires-port@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" - integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= - reselect@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/reselect/-/reselect-3.0.1.tgz#efdaa98ea7451324d092b2b2163a6a1d7a9a2147" @@ -22128,11 +22300,6 @@ reselect@^4.0.0: resolved "https://registry.yarnpkg.com/reselect/-/reselect-4.0.0.tgz#f2529830e5d3d0e021408b246a206ef4ea4437f7" integrity sha512-qUgANli03jjAyGlnbYVAV5vvnOmJnODyABz51RdBN7M4WaVu8mecZWgyQNkG8Yqe3KRGRt0l4K4B3XVEULC4CA== -resize-observer-polyfill@^1.5.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz#0e9020dd3d21024458d4ebd27e23e40269810464" - integrity sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg== - resolve-dir@^1.0.0, resolve-dir@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43" @@ -22207,14 +22374,7 @@ resolve@1.1.7: resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= -resolve@^1.1.4, resolve@^1.1.5, resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.11.0, resolve@^1.11.1, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.17.0, resolve@^1.3.2, resolve@^1.4.0, resolve@^1.8.1: - version "1.17.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444" - integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w== - dependencies: - path-parse "^1.0.6" - -resolve@^1.10.1: +resolve@^1.1.4, resolve@^1.1.5, resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.10.1, resolve@^1.11.1, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.17.0, resolve@^1.3.2, resolve@^1.4.0, resolve@^1.8.1: version "1.18.1" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.18.1.tgz#018fcb2c5b207d2a6424aee361c5a266da8f4130" integrity sha512-lDfCPaMKfOJXjy0dPayzPdF1phampNWr3qFCjAu+rw/qbQmr5jWH5xN2hwh9QKfw9E5v4hwV7A+jrCmL8yjjqA== @@ -22300,7 +22460,7 @@ rework@1.0.1: convert-source-map "^0.3.3" css "^2.0.0" -rimraf@2, rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.3, rimraf@^2.7.1: +rimraf@2, rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.3: version "2.7.1" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== @@ -22625,14 +22785,23 @@ schema-utils@^1.0.0: ajv-errors "^1.0.0" ajv-keywords "^3.1.0" -schema-utils@^2.0.1, schema-utils@^2.5.0, schema-utils@^2.6.0, schema-utils@^2.6.4, schema-utils@^2.6.6, schema-utils@^2.7.0: - version "2.7.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.0.tgz#17151f76d8eae67fbbf77960c33c676ad9f4efc7" - integrity sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A== +schema-utils@^2.6.5, schema-utils@^2.6.6, schema-utils@^2.7.0: + version "2.7.1" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.1.tgz#1ca4f32d1b24c590c203b8e7a50bf0ea4cd394d7" + integrity sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg== dependencies: - "@types/json-schema" "^7.0.4" - ajv "^6.12.2" - ajv-keywords "^3.4.1" + "@types/json-schema" "^7.0.5" + ajv "^6.12.4" + ajv-keywords "^3.5.2" + +schema-utils@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.0.0.tgz#67502f6aa2b66a2d4032b4279a2944978a0913ef" + integrity sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA== + dependencies: + "@types/json-schema" "^7.0.6" + ajv "^6.12.5" + ajv-keywords "^3.5.2" scope-analyzer@^2.0.1: version "2.1.1" @@ -22647,11 +22816,6 @@ scope-analyzer@^2.0.1: estree-is-function "^1.0.0" get-assigned-identifiers "^1.1.0" -scrollbarwidth@^0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/scrollbarwidth/-/scrollbarwidth-0.1.3.tgz#1b0de64e288c38c427f4a01fe00a462a04b94fdf" - integrity sha1-Gw3mTiiMOMQn9KAf4ApGKgS5T98= - scrypt-js@2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-2.0.4.tgz#32f8c5149f0797672e551c07e230f834b6af5f16" @@ -22788,6 +22952,11 @@ semver@6.3.0, semver@^6.0.0, semver@^6.1.0, semver@^6.1.1, semver@^6.2.0, semver resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== +semver@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" + integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== + semver@^7.2.1, semver@^7.3.2: version "7.3.2" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938" @@ -23004,11 +23173,6 @@ shallow-copy@~0.0.1: resolved "https://registry.yarnpkg.com/shallow-copy/-/shallow-copy-0.0.1.tgz#415f42702d73d810330292cc5ee86eae1a11a170" integrity sha1-QV9CcC1z2BAzApLMXuhurhoRoXA= -shallow-equal@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/shallow-equal/-/shallow-equal-1.1.0.tgz#cc022f030dcba0d1c198abf658a3c6c744e171ca" - integrity sha512-0SW1nWo1hnabO62SEeHsl8nmTVVEzguVWZCj5gaQrgWAxz/BaCja4OWdJBWLVPDxdtE/WU7c98uUCCXyPHSCvw== - shallowequal@1.1.0, shallowequal@^1.0.2, shallowequal@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-1.1.0.tgz#188d521de95b9087404fd4dcb68b13df0ae4e7f8" @@ -23046,15 +23210,10 @@ shebang-regex@^3.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== -shell-quote@1.6.1, shell-quote@^1.4.2, shell-quote@^1.6.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.6.1.tgz#f4781949cce402697127430ea3b3c5476f481767" - integrity sha1-9HgZSczkAmlxJ0MOo7PFR29IF2c= - dependencies: - array-filter "~0.0.0" - array-map "~0.0.0" - array-reduce "~0.0.0" - jsonify "~0.0.0" +shell-quote@1.7.2, shell-quote@^1.4.2, shell-quote@^1.6.1: + version "1.7.2" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.2.tgz#67a7d02c76c9da24f99d20808fcaded0e0e04be2" + integrity sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg== shelljs@^0.7.5: version "0.7.8" @@ -23065,10 +23224,10 @@ shelljs@^0.7.5: interpret "^1.0.0" rechoir "^0.6.2" -shelljs@^0.8.1, shelljs@^0.8.3: - version "0.8.3" - resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.3.tgz#a7f3319520ebf09ee81275b2368adb286659b097" - integrity sha512-fc0BKlAWiLpwZljmOvAOTE/gXawtCoNrP5oaY7KIaQbbyHeQVg01pSEuEGvGh3HEdBU4baCD7wQBwADmM/7f7A== +shelljs@^0.8.1, shelljs@^0.8.4: + version "0.8.4" + resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.4.tgz#de7684feeb767f8716b326078a8a00875890e3c2" + integrity sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ== dependencies: glob "^7.0.0" interpret "^1.0.0" @@ -23126,27 +23285,6 @@ simple-peer@^9.3.0: randombytes "^2.0.3" readable-stream "^3.4.0" -simplebar-react@^1.0.0-alpha.6: - version "1.0.0" - resolved "https://registry.yarnpkg.com/simplebar-react/-/simplebar-react-1.0.0.tgz#8fe914d7f980dd077cc9dfd3e22ec5596f006b8d" - integrity sha512-FbM2yn7D/UzrJGCY60CKeLkZ3gOs7tYr7KmyamteUt9SKh2x4yW5KVM4IQBw86x4ofRoD6FT19MWmfMKv4Onhw== - dependencies: - prop-types "^15.6.1" - simplebar "^4.0.0" - -simplebar@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/simplebar/-/simplebar-4.0.0.tgz#7f1b9e735ec94a58f887d4803f6b15abf401b6b5" - integrity sha512-td6vJVhqIXfa3JgNZR5OgETPLfmHNSSpt+OXIbk6WH/nOrUtX3Qcyio30+5rdxxAV/61+F5eJ4jJV4Ek7/KJYQ== - dependencies: - can-use-dom "^0.1.0" - core-js "^3.0.1" - lodash.debounce "^4.0.8" - lodash.memoize "^4.1.2" - lodash.throttle "^4.1.1" - resize-observer-polyfill "^1.5.1" - scrollbarwidth "^0.1.3" - single-call-balance-checker-abi@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/single-call-balance-checker-abi/-/single-call-balance-checker-abi-1.0.0.tgz#b369009fd4cc6214968cdba650ad93986315d92d" @@ -23344,18 +23482,6 @@ socketcluster@^14.3.3: uid-number "0.0.6" uuid "3.2.1" -sockjs-client@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.3.0.tgz#12fc9d6cb663da5739d3dc5fb6e8687da95cb177" - integrity sha512-R9jxEzhnnrdxLCNln0xg5uGHqMnkhPSTzUZH2eXcR03S/On9Yvoq2wyUZILRUhZCNVu2PmwWVoyuiPz8th8zbg== - dependencies: - debug "^3.2.5" - eventsource "^1.0.7" - faye-websocket "~0.11.1" - inherits "^2.0.3" - json3 "^3.3.2" - url-parse "^1.4.3" - socks-proxy-agent@^4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-4.0.2.tgz#3c8991f3145b2799e70e11bd5fbc8b1963116386" @@ -23442,7 +23568,7 @@ source-map-support@0.5.12: buffer-from "^1.0.0" source-map "^0.6.0" -source-map-support@0.5.13, source-map-support@^0.5.1, source-map-support@^0.5.11, source-map-support@^0.5.9, source-map-support@~0.5.12, source-map-support@~0.5.4: +source-map-support@0.5.13: version "0.5.13" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.13.tgz#31b24a9c2e73c2de85066c0feb7d44767ed52932" integrity sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w== @@ -23457,6 +23583,14 @@ source-map-support@^0.4.15: dependencies: source-map "^0.5.6" +source-map-support@^0.5.1, source-map-support@^0.5.11, source-map-support@^0.5.16, source-map-support@~0.5.12, source-map-support@~0.5.4: + version "0.5.19" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" + integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + source-map-url@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" @@ -23621,14 +23755,6 @@ ssri@^6.0.1: dependencies: figgy-pudding "^3.5.1" -ssri@^7.0.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/ssri/-/ssri-7.1.0.tgz#92c241bf6de82365b5c7fb4bd76e975522e1294d" - integrity sha512-77/WrDZUWocK0mvA5NTRQyveUf+wsrIc6vyrxpS8tVvYBcX215QbafrJR3KtkpskIzoFLqqNuuYQvxaMjXJ/0g== - dependencies: - figgy-pudding "^3.5.1" - minipass "^3.1.1" - ssri@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/ssri/-/ssri-8.0.0.tgz#79ca74e21f8ceaeddfcb4b90143c458b8d988808" @@ -23646,6 +23772,11 @@ stack-trace@0.0.10: resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" integrity sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA= +stackframe@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.2.0.tgz#52429492d63c62eb989804c11552e3d22e779303" + integrity sha512-GrdeshiRmS1YLMYgzF16olf2jJ/IzxXY9lhKOskuVziubpTYcYqyOwYeJKzQkwy7uN0fYSsbsC4RQaXf9LCrYA== + state-toggle@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/state-toggle/-/state-toggle-1.0.2.tgz#75e93a61944116b4959d665c8db2d243631d6ddc" @@ -23963,12 +24094,12 @@ stringify-object@^3.0.0: is-obj "^1.0.1" is-regexp "^1.0.0" -strip-ansi@5.2.0, strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" - integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== +strip-ansi@6.0.0, strip-ansi@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" + integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w== dependencies: - ansi-regex "^4.1.0" + ansi-regex "^5.0.0" strip-ansi@^3.0.0, strip-ansi@^3.0.1: version "3.0.1" @@ -23984,12 +24115,12 @@ strip-ansi@^4.0.0: dependencies: ansi-regex "^3.0.0" -strip-ansi@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" - integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w== +strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" + integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== dependencies: - ansi-regex "^5.0.0" + ansi-regex "^4.1.0" strip-ansi@~0.1.0: version "0.1.1" @@ -24099,13 +24230,13 @@ style-loader@^0.21.0: loader-utils "^1.1.0" schema-utils "^0.4.5" -style-loader@^1.0.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-1.1.3.tgz#9e826e69c683c4d9bf9db924f85e9abb30d5e200" - integrity sha512-rlkH7X/22yuwFYK357fMN/BxYOorfnfq0eD7+vqlemSK4wEcejFF1dg4zxP0euBW8NrYx2WZzZ8PPFevr7D+Kw== +style-loader@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-1.3.0.tgz#828b4a3b3b7e7aa5847ce7bae9e874512114249e" + integrity sha512-V7TCORko8rs9rIqkSrlMfkqA63DfoGBBJmK1kKGCcSi+BWb4cqz0SRsnp4l6rU5iwOEd0/2ePv68SV22VXon4Q== dependencies: - loader-utils "^1.2.3" - schema-utils "^2.6.4" + loader-utils "^2.0.0" + schema-utils "^2.7.0" style-search@^0.1.0: version "0.1.0" @@ -24270,7 +24401,7 @@ svg-tags@^1.0.0: resolved "https://registry.yarnpkg.com/svg-tags/-/svg-tags-1.0.0.tgz#58f71cee3bd519b59d4b2a843b6c7de64ac04764" integrity sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q= -svgo@^1.0.5, svgo@^1.2.1: +svgo@^1.0.5: version "1.3.0" resolved "https://registry.yarnpkg.com/svgo/-/svgo-1.3.0.tgz#bae51ba95ded9a33a36b7c46ce9c359ae9154313" integrity sha512-MLfUA6O+qauLDbym+mMZgtXCGRfIxyQoeH6IKVcFslyODEe/ElJNwr0FohQ3xG4C6HK6bk3KYPPXwHVJk3V5NQ== @@ -24357,7 +24488,7 @@ table@^5.2.3, table@^5.4.6: slice-ansi "^2.1.0" string-width "^3.0.0" -tapable@^1.0.0, tapable@^1.1.0, tapable@^1.1.3: +tapable@^1.0.0, tapable@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== @@ -24472,18 +24603,18 @@ tdigest@^0.1.1: dependencies: bintrees "1.0.1" -telejson@^3.2.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/telejson/-/telejson-3.3.0.tgz#6d814f3c0d254d5c4770085aad063e266b56ad03" - integrity sha512-er08AylQ+LEbDLp1GRezORZu5wKOHaBczF6oYJtgC3Idv10qZ8A3p6ffT+J5BzDKkV9MqBvu8HAKiIIOp6KJ2w== +telejson@^5.0.2: + version "5.1.0" + resolved "https://registry.yarnpkg.com/telejson/-/telejson-5.1.0.tgz#cc04e4c2a355f9eb6af557e37acd6449feb1d146" + integrity sha512-Yy0N2OV0mosmr1SCZEm3Ezhu/oi5Dbao5RqauZu4+VI5I/XtVBHXajRk0txuqbFYtKdzzWGDZFGSif9ovVLjEA== dependencies: "@types/is-function" "^1.0.0" global "^4.4.0" - is-function "^1.0.1" - is-regex "^1.0.4" + is-function "^1.0.2" + is-regex "^1.1.1" is-symbol "^1.0.3" isobject "^4.0.0" - lodash "^4.17.15" + lodash "^4.17.20" memoizerific "^1.11.3" temp-dir@^1.0.0: @@ -24533,22 +24664,22 @@ terser-webpack-plugin@^1.4.3: webpack-sources "^1.4.0" worker-farm "^1.7.0" -terser-webpack-plugin@^2.1.2: - version "2.3.8" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-2.3.8.tgz#894764a19b0743f2f704e7c2a848c5283a696724" - integrity sha512-/fKw3R+hWyHfYx7Bv6oPqmk4HGQcrWLtV3X6ggvPuwPNHSnzvVV51z6OaaCOus4YLjutYGOz3pEpbhe6Up2s1w== +terser-webpack-plugin@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-3.1.0.tgz#91e6d39571460ed240c0cf69d295bcf30ebf98cb" + integrity sha512-cjdZte66fYkZ65rQ2oJfrdCAkkhJA7YLYk5eGOcGCSGlq0ieZupRdjedSQXYknMPo2IveQL+tPdrxUkERENCFA== dependencies: - cacache "^13.0.1" + cacache "^15.0.5" find-cache-dir "^3.3.1" - jest-worker "^25.4.0" - p-limit "^2.3.0" + jest-worker "^26.2.1" + p-limit "^3.0.2" schema-utils "^2.6.6" serialize-javascript "^4.0.0" source-map "^0.6.1" - terser "^4.6.12" + terser "^4.8.0" webpack-sources "^1.4.3" -terser@^4.1.2, terser@^4.6.12: +terser@^4.1.2, terser@^4.6.12, terser@^4.6.3, terser@^4.8.0: version "4.8.0" resolved "https://registry.yarnpkg.com/terser/-/terser-4.8.0.tgz#63056343d7c70bb29f3af665865a46fe03a0df17" integrity sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw== @@ -24948,10 +25079,15 @@ ts-custom-error@^2.2.1: resolved "https://registry.yarnpkg.com/ts-custom-error/-/ts-custom-error-2.2.1.tgz#47086fbc34df5c7c2d4fba8c92d8767662066951" integrity sha512-lHKZtU+PXkVuap6nlFZybIAFLUO8B3jbCs1VynBL8AUSAHfeG6HpztcBTDRp5I+fN5820N9kGg+eTIvr+le2yg== -ts-dedent@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/ts-dedent/-/ts-dedent-1.1.1.tgz#68fad040d7dbd53a90f545b450702340e17d18f3" - integrity sha512-UGTRZu1evMw4uTPyYF66/KFd22XiU+jMaIuHrkIHQ2GivAXVlLV0v/vHrpOuTRf9BmpNHi/SO7Vd0rLu0y57jg== +ts-dedent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ts-dedent/-/ts-dedent-2.0.0.tgz#47c5eb23d9096f3237cc413bc82d387d36dbe690" + integrity sha512-DfxKjSFQfw9+uf7N9Cy8Ebx9fv5fquK4hZ6SD3Rzr+1jKP6AVA6H8+B5457ZpUs0JKsGpGqIevbpZ9DMQJDp1A== + +ts-essentials@^2.0.3: + version "2.0.12" + resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-2.0.12.tgz#c9303f3d74f75fa7528c3d49b80e089ab09d8745" + integrity sha512-3IVX4nI6B5cc31/GFFE+i8ey/N2eA0CZDbo6n0yrz0zDX8ZJ8djmU1p+XRz7G3is0F3bB3pu2pAroFdAWQKU3w== ts-invariant@^0.4.0: version "0.4.4" @@ -24960,10 +25096,10 @@ ts-invariant@^0.4.0: dependencies: tslib "^1.9.3" -ts-pnp@^1.1.2: - version "1.1.5" - resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.1.5.tgz#840e0739c89fce5f3abd9037bb091dbff16d9dec" - integrity sha512-ti7OGMOUOzo66wLF3liskw6YQIaSsBgc4GOAlWRnIEj8htCxJUxskanMUoJOD6MDCRAXo36goXJZch+nOS0VMA== +ts-pnp@^1.1.6: + version "1.2.0" + resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.2.0.tgz#a500ad084b0798f1c3071af391e65912c86bca92" + integrity sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw== tsconfig-paths@^3.9.0: version "3.9.0" @@ -24975,10 +25111,15 @@ tsconfig-paths@^3.9.0: minimist "^1.2.0" strip-bom "^3.0.0" -tslib@^1.9.0, tslib@^1.9.3: - version "1.9.3" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" - integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ== +tslib@^1.10.0, tslib@^1.9.0, tslib@^1.9.3: + version "1.14.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" + integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== + +tslib@^2.0.0, tslib@^2.0.1: + version "2.0.3" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.0.3.tgz#8e0741ac45fc0c226e58a17bfc3e64b9bc6ca61c" + integrity sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ== tsscmp@1.0.6: version "1.0.6" @@ -25087,11 +25228,6 @@ type-is@^1.6.16, type-is@~1.6.17, type-is@~1.6.18: media-typer "0.3.0" mime-types "~2.1.24" -typed-styles@^0.0.7: - version "0.0.7" - resolved "https://registry.yarnpkg.com/typed-styles/-/typed-styles-0.0.7.tgz#93392a008794c4595119ff62dde6809dbc40a3d9" - integrity sha512-pzP0PWoZUhsECYjABgCGQlRGL1n7tOHsgwYv3oIiEpJwGhFTuty/YNeduxQYzXXa3Ge5BdT6sHYIQYpl4uJ+5Q== - typedarray-to-buffer@^3.1.5, typedarray-to-buffer@~3.1.5: version "3.1.5" resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" @@ -25131,19 +25267,6 @@ typical@^5.0.0: resolved "https://registry.yarnpkg.com/typical/-/typical-5.1.0.tgz#7116ca103caf2574985fc84fbaa8fd0ee5ea1684" integrity sha512-t5Ik8UAwBal1P1XzuVE4dc+RYQZicLUGJdvqr/vdqsED7SQECgsGBylldSsfWZL7RQjxT3xhQcKHWhLaVSR6YQ== -ua-parser-js@^0.7.9: - version "0.7.17" - resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.17.tgz#e9ec5f9498b9ec910e7ae3ac626a805c4d09ecac" - integrity sha512-uRdSdu1oA1rncCQL7sCj8vSyZkgtL7faaw9Tc9rZ3mGgraQ7+Pdx7w5mnOSF3gw9ZNG6oc+KXfkon3bKuROm0g== - -uglify-js@3.4.x: - version "3.4.10" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.4.10.tgz#9ad9563d8eb3acdfb8d38597d2af1d815f6a755f" - integrity sha512-Y2VsbPVs0FIshJztycsO2SfPk7/KAF/T72qzv9u5EpQ4kB2hQoHlhNQTsNyy6ul7lQtqJN/AoWeS23OzEiEFxw== - dependencies: - commander "~2.19.0" - source-map "~0.6.1" - uid-number@0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" @@ -25248,30 +25371,16 @@ unicode-match-property-ecmascript@^1.0.4: unicode-canonical-property-names-ecmascript "^1.0.4" unicode-property-aliases-ecmascript "^1.0.4" -unicode-match-property-value-ecmascript@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.1.0.tgz#5b4b426e08d13a80365e0d657ac7a6c1ec46a277" - integrity sha512-hDTHvaBk3RmFzvSl0UVrUmC3PuW9wKVnpoUDYH0JDkSIovzw+J5viQmeYHxVSBptubnr7PbH2e0fnpDRQnQl5g== +unicode-match-property-value-ecmascript@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz#0d91f600eeeb3096aa962b1d6fc88876e64ea531" + integrity sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ== unicode-property-aliases-ecmascript@^1.0.4: version "1.0.5" resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.5.tgz#a9cc6cc7ce63a0a3023fc99e341b94431d405a57" integrity sha512-L5RAqCfXqAwR3RriF8pM0lU0w4Ryf/GgzONwi6KnL1taJQa7x1TCxdJnILX59WIGOwR57IVxn7Nej0fz1Ny6fw== -unified@^7.1.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/unified/-/unified-7.1.0.tgz#5032f1c1ee3364bd09da12e27fdd4a7553c7be13" - integrity sha512-lbk82UOIGuCEsZhPj8rNAkXSDXd6p0QLzIuSsCdxrqnqU56St4eyOB+AlXsVgVeRmetPTYydIuvFfpDIed8mqw== - dependencies: - "@types/unist" "^2.0.0" - "@types/vfile" "^3.0.0" - bail "^1.0.0" - extend "^3.0.0" - is-plain-obj "^1.1.0" - trough "^1.0.0" - vfile "^3.0.0" - x-is-string "^0.1.0" - unified@^9.0.0: version "9.0.0" resolved "https://registry.yarnpkg.com/unified/-/unified-9.0.0.tgz#12b099f97ee8b36792dbad13d278ee2f696eed1d" @@ -25352,11 +25461,6 @@ unist-util-remove-position@^2.0.0: dependencies: unist-util-visit "^2.0.0" -unist-util-stringify-position@^1.0.0, unist-util-stringify-position@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-1.1.1.tgz#3ccbdc53679eed6ecf3777dd7f5e3229c1b6aa3c" - integrity sha1-PMvcU2ee7W7PN3fdf14yKcG2qjw= - unist-util-stringify-position@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-2.0.1.tgz#de2a2bc8d3febfa606652673a91455b6a36fb9f3" @@ -25386,6 +25490,16 @@ universalify@^0.1.0: resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.1.tgz#fa71badd4437af4c148841e3b3b165f9e9e590b7" integrity sha1-+nG63UQ3r0wUiEHjs7Fl+enlkLc= +universalify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-1.0.0.tgz#b61a1da173e8435b2fe3c67d29b9adf8594bd16d" + integrity sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug== + +universalify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" + integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== + unorm@^1.3.3: version "1.5.0" resolved "https://registry.yarnpkg.com/unorm/-/unorm-1.5.0.tgz#01fa9b76f1c60f7916834605c032aa8962c3f00a" @@ -25465,11 +25579,6 @@ uport-base64url@3.0.2-alpha.0: dependencies: buffer "^5.2.1" -upper-case@^1.1.1: - version "1.1.3" - resolved "https://registry.yarnpkg.com/upper-case/-/upper-case-1.1.3.tgz#f6b4501c2ec4cdd26ba78be7222961de77621598" - integrity sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg= - uri-js@^4.2.2: version "4.2.2" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" @@ -25490,14 +25599,14 @@ urix@^0.1.0: resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= -url-loader@^2.0.1: - version "2.3.0" - resolved "https://registry.yarnpkg.com/url-loader/-/url-loader-2.3.0.tgz#e0e2ef658f003efb8ca41b0f3ffbf76bab88658b" - integrity sha512-goSdg8VY+7nPZKUEChZSEtW5gjbS66USIGCeSJ1OVOJ7Yfuh/36YxCwMi5HVEJh6mqUYOoy3NJ0vlOMrWsSHog== +url-loader@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/url-loader/-/url-loader-4.1.1.tgz#28505e905cae158cf07c92ca622d7f237e70a4e2" + integrity sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA== dependencies: - loader-utils "^1.2.3" - mime "^2.4.4" - schema-utils "^2.5.0" + loader-utils "^2.0.0" + mime-types "^2.1.27" + schema-utils "^3.0.0" url-parse-lax@^1.0.0: version "1.0.0" @@ -25513,14 +25622,6 @@ url-parse-lax@^3.0.0: dependencies: prepend-http "^2.0.0" -url-parse@^1.4.3: - version "1.4.7" - resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.4.7.tgz#a8a83535e8c00a316e403a5db4ac1b9b853ae278" - integrity sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg== - dependencies: - querystringify "^2.1.1" - requires-port "^1.0.0" - url-set-query@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/url-set-query/-/url-set-query-1.0.0.tgz#016e8cfd7c20ee05cafe7795e892bd0702faa339" @@ -25547,18 +25648,24 @@ ursa-optional@~0.9.10: bindings "^1.3.0" nan "^2.11.1" -use-callback-ref@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/use-callback-ref/-/use-callback-ref-1.2.1.tgz#898759ccb9e14be6c7a860abafa3ffbd826c89bb" - integrity sha512-C3nvxh0ZpaOxs9RCnWwAJ+7bJPwQI8LHF71LzbQ3BvzH5XkdtlkMadqElGevg5bYBDFip4sAnD4m06zAKebg1w== +use-composed-ref@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/use-composed-ref/-/use-composed-ref-1.1.0.tgz#9220e4e94a97b7b02d7d27eaeab0b37034438bbc" + integrity sha512-my1lNHGWsSDAhhVAT4MKs6IjBUtG6ZG11uUqexPH9PptiIZDQOzaF4f5tEbJ2+7qvNbtXNBbU3SfmN+fXlWDhg== + dependencies: + ts-essentials "^2.0.3" -use-sidecar@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/use-sidecar/-/use-sidecar-1.0.2.tgz#e72f582a75842f7de4ef8becd6235a4720ad8af6" - integrity sha512-287RZny6m5KNMTb/Kq9gmjafi7lQL0YHO1lYolU6+tY1h9+Z3uCtkJJ3OSOq3INwYf2hBryCcDh4520AhJibMA== +use-isomorphic-layout-effect@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.0.tgz#4db2111e0d53ca694187ea5fd5cb2ba610286fe0" + integrity sha512-kady5Z1O1qx5RitodCCKbpJSVEtECXYcnBnb5Q48Bz5V6gBmTu85ZcGdVwVFs8+DaOurNb/L5VdGHoQRMknghw== + +use-latest@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/use-latest/-/use-latest-1.2.0.tgz#a44f6572b8288e0972ec411bdd0840ada366f232" + integrity sha512-d2TEuG6nSLKQLAfW3By8mKr8HurOlTkul0sOpxbClIv4SQ4iOd7BYr7VIzdbktUCnv7dua/60xzd8igMU6jmyw== dependencies: - detect-node "^2.0.4" - tslib "^1.9.3" + use-isomorphic-layout-effect "^1.0.0" use@^3.1.0: version "3.1.0" @@ -25678,6 +25785,11 @@ uuid@^3.0.1, uuid@^3.1.0, uuid@^3.2.1, uuid@^3.2.2, uuid@^3.3.2, uuid@^3.3.3: resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.3.tgz#4568f0216e78760ee1dbf3a4d2cf53e224112866" integrity sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ== +uuid@^8.0.0: + version "8.3.1" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.1.tgz#2ba2e6ca000da60fce5a196954ab241131e05a31" + integrity sha512-FOmRr+FmWEIG8uhZv6C2bTgEVXsHk08kE7mPlrBbEe+c3r9pjceVPgupIfNIhc4yx55H69OXANrUaSuu9eInKg== + v8-compile-cache@^2.0.3, v8-compile-cache@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz#54bc3cdd43317bca91e35dcaf305b1a7237de745" @@ -25751,13 +25863,6 @@ vfile-location@^3.0.0: resolved "https://registry.yarnpkg.com/vfile-location/-/vfile-location-3.0.1.tgz#d78677c3546de0f7cd977544c367266764d31bb3" integrity sha512-yYBO06eeN/Ki6Kh1QAkgzYpWT1d3Qln+ZCtSbJqFExPl1S3y2qqotJQXoh6qEvl/jDlgpUJolBn3PItVnnZRqQ== -vfile-message@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-1.0.0.tgz#a6adb0474ea400fa25d929f1d673abea6a17e359" - integrity sha512-HPREhzTOB/sNDc9/Mxf8w0FmHnThg5CRSJdR9VRFkD2riqYWs+fuXlj5z8mIpv2LrD7uU41+oPWFOL4Mjlf+dw== - dependencies: - unist-util-stringify-position "^1.1.1" - vfile-message@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-2.0.1.tgz#951881861c22fc1eb39f873c0b93e336a64e8f6d" @@ -25766,16 +25871,6 @@ vfile-message@^2.0.0: "@types/unist" "^2.0.2" unist-util-stringify-position "^2.0.0" -vfile@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/vfile/-/vfile-3.0.1.tgz#47331d2abe3282424f4a4bb6acd20a44c4121803" - integrity sha512-y7Y3gH9BsUSdD4KzHsuMaCzRjglXN0W2EcMf0gpvu6+SbsGhMje7xDc8AEoeXy6mIwCKMI6BkjMsRjzQbhMEjQ== - dependencies: - is-buffer "^2.0.0" - replace-ext "1.0.0" - unist-util-stringify-position "^1.0.0" - vfile-message "^1.0.0" - vfile@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/vfile/-/vfile-4.0.1.tgz#fc3d43a1c71916034216bf65926d5ee3c64ed60c" @@ -25891,7 +25986,7 @@ warning@^3.0.0: dependencies: loose-envify "^1.0.0" -warning@^4.0.2: +warning@^4.0.2, warning@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/warning/-/warning-4.0.3.tgz#16e9e077eb8a86d6af7d64aa1e05fd85b4678ca3" integrity sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w== @@ -25911,14 +26006,23 @@ watchify@^3.11.1: through2 "^2.0.0" xtend "^4.0.0" -watchpack@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.6.0.tgz#4bc12c2ebe8aa277a71f1d3f14d685c7b446cd00" - integrity sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA== +watchpack-chokidar2@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz#38500072ee6ece66f3769936950ea1771be1c957" + integrity sha512-nCFfBIPKr5Sh61s4LPpy1Wtfi0HE8isJ3d2Yb5/Ppw2P2B/3eVSEBjKfN0fmHJSK14+31KwMKmcrzs2GM4P0Ww== + dependencies: + chokidar "^2.1.8" + +watchpack@^1.7.4: + version "1.7.5" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.7.5.tgz#1267e6c55e0b9b5be44c2023aed5437a2c26c453" + integrity sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ== dependencies: - chokidar "^2.0.2" graceful-fs "^4.1.2" neo-async "^2.5.0" + optionalDependencies: + chokidar "^3.4.1" + watchpack-chokidar2 "^2.0.1" wcwidth@^1.0.0: version "1.0.1" @@ -25935,11 +26039,6 @@ weak@^1.0.0: bindings "^1.2.1" nan "^2.0.5" -web-namespaces@^1.1.2: - version "1.1.3" - resolved "https://registry.yarnpkg.com/web-namespaces/-/web-namespaces-1.1.3.tgz#9bbf5c99ff0908d2da031f1d732492a96571a83f" - integrity sha512-r8sAtNmgR0WKOKOxzuSgk09JsHlpKlB+uHi937qypOu3PZ17UxPrierFKDye/uNHjNTTEshu5PId8rojIPj/tA== - web3-bzz@1.2.11: version "1.2.11" resolved "https://registry.yarnpkg.com/web3-bzz/-/web3-bzz-1.2.11.tgz#41bc19a77444bd5365744596d778b811880f707f" @@ -26271,6 +26370,11 @@ webpack-dev-middleware@^3.7.0: range-parser "^1.2.1" webpack-log "^2.0.0" +webpack-filter-warnings-plugin@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/webpack-filter-warnings-plugin/-/webpack-filter-warnings-plugin-1.2.1.tgz#dc61521cf4f9b4a336fbc89108a75ae1da951cdb" + integrity sha512-Ez6ytc9IseDMLPo0qCuNNYzgtUl8NovOqjIq4uAU8LTD4uoa1w1KpZyyzFtLTEMZpkkOkLfL9eN+KGYdk1Qtwg== + webpack-hot-middleware@^2.25.0: version "2.25.0" resolved "https://registry.yarnpkg.com/webpack-hot-middleware/-/webpack-hot-middleware-2.25.0.tgz#4528a0a63ec37f8f8ef565cf9e534d57d09fe706" @@ -26281,6 +26385,16 @@ webpack-hot-middleware@^2.25.0: querystring "^0.2.0" strip-ansi "^3.0.0" +webpack-log@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/webpack-log/-/webpack-log-1.2.0.tgz#a4b34cda6b22b518dbb0ab32e567962d5c72a43d" + integrity sha512-U9AnICnu50HXtiqiDxuli5gLB5PGBo7VvcHx36jRZHwK4vzOYLbImqT4lwWwoMHdQWwEKw736fCHEekokTEKHA== + dependencies: + chalk "^2.1.0" + log-symbols "^2.1.0" + loglevelnext "^1.0.1" + uuid "^3.1.0" + webpack-log@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/webpack-log/-/webpack-log-2.0.0.tgz#5b7928e0637593f119d32f6227c1e0ac31e1b47f" @@ -26289,7 +26403,7 @@ webpack-log@^2.0.0: ansi-colors "^3.0.0" uuid "^3.3.2" -webpack-sources@^1.1.0, webpack-sources@^1.4.0, webpack-sources@^1.4.1, webpack-sources@^1.4.3: +webpack-sources@^1.4.0, webpack-sources@^1.4.1, webpack-sources@^1.4.3: version "1.4.3" resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933" integrity sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ== @@ -26297,40 +26411,40 @@ webpack-sources@^1.1.0, webpack-sources@^1.4.0, webpack-sources@^1.4.1, webpack- source-list-map "^2.0.0" source-map "~0.6.1" -webpack-virtual-modules@^0.2.0: - version "0.2.1" - resolved "https://registry.yarnpkg.com/webpack-virtual-modules/-/webpack-virtual-modules-0.2.1.tgz#8ab73d4df0fd37ed27bb8d823bc60ea7266c8bf7" - integrity sha512-0PWBlxyt4uGDofooIEanWhhyBOHdd+lr7QpYNDLC7/yc5lqJT8zlc04MTIBnKj+c2BlQNNuwE5er/Tg4wowHzA== +webpack-virtual-modules@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/webpack-virtual-modules/-/webpack-virtual-modules-0.2.2.tgz#20863dc3cb6bb2104729fff951fbe14b18bd0299" + integrity sha512-kDUmfm3BZrei0y+1NTHJInejzxfhtU8eDj2M7OKb2IWrPFAeO1SOH2KuQ68MSZu9IGEHcxbkKKR1v18FrUSOmA== dependencies: debug "^3.0.0" -webpack@^4.33.0, webpack@^4.38.0, webpack@^4.41.6: - version "4.41.6" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.41.6.tgz#12f2f804bf6542ef166755050d4afbc8f66ba7e1" - integrity sha512-yxXfV0Zv9WMGRD+QexkZzmGIh54bsvEs+9aRWxnN8erLWEOehAKUTeNBoUbA6HPEZPlRo7KDi2ZcNveoZgK9MA== +webpack@^4.41.6, webpack@^4.44.2: + version "4.44.2" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.44.2.tgz#6bfe2b0af055c8b2d1e90ed2cd9363f841266b72" + integrity sha512-6KJVGlCxYdISyurpQ0IPTklv+DULv05rs2hseIXer6D7KrUicRDLFb4IUM1S6LUAKypPM/nSiVSuv8jHu1m3/Q== dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-module-context" "1.8.5" - "@webassemblyjs/wasm-edit" "1.8.5" - "@webassemblyjs/wasm-parser" "1.8.5" - acorn "^6.2.1" + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-module-context" "1.9.0" + "@webassemblyjs/wasm-edit" "1.9.0" + "@webassemblyjs/wasm-parser" "1.9.0" + acorn "^6.4.1" ajv "^6.10.2" ajv-keywords "^3.4.1" chrome-trace-event "^1.0.2" - enhanced-resolve "^4.1.0" + enhanced-resolve "^4.3.0" eslint-scope "^4.0.3" json-parse-better-errors "^1.0.2" loader-runner "^2.4.0" loader-utils "^1.2.3" memory-fs "^0.4.1" micromatch "^3.1.10" - mkdirp "^0.5.1" + mkdirp "^0.5.3" neo-async "^2.6.1" node-libs-browser "^2.2.1" schema-utils "^1.0.0" tapable "^1.1.3" terser-webpack-plugin "^1.4.3" - watchpack "^1.6.0" + watchpack "^1.7.4" webpack-sources "^1.4.1" "webrtcsupport@github:ipfs/webrtcsupport": @@ -26374,7 +26488,7 @@ whatwg-fetch@2.0.4: resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz#dde6a5df315f9d39991aa17621853d720b85566f" integrity sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng== -whatwg-fetch@>=0.10.0, whatwg-fetch@^3.0.0, whatwg-fetch@^3.4.1: +whatwg-fetch@^3.0.0, whatwg-fetch@^3.4.1: version "3.4.1" resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.4.1.tgz#e5f871572d6879663fa5674c8f833f15a8425ab3" integrity sha512-sofZVzE1wKwO+EYPbWfiwzaKovWiZXf4coEzjGP9b2GBVgQRLQUZ2QcuPpQExGDAW5GItpEm6Tl4OU5mywnAoQ== @@ -26592,11 +26706,6 @@ ws@~6.1.0: dependencies: async-limiter "~1.0.0" -x-is-string@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/x-is-string/-/x-is-string-0.1.0.tgz#474b50865af3a49a9c4657f05acd145458f77d82" - integrity sha1-R0tQhlrzpJqcRlfwWs0UVFj3fYI= - xdg-basedir@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" @@ -26885,6 +26994,11 @@ ylru@^1.2.0: resolved "https://registry.yarnpkg.com/ylru/-/ylru-1.2.1.tgz#f576b63341547989c1de7ba288760923b27fe84f" integrity sha512-faQrqNMzcPCHGVC2aaOINk13K+aaBDUPjGWl0teOXywElLjyVAB6Oe2jj62jHYtwsU49jXhScYbvPENK+6zAvQ== +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== + zcash-bitcore-lib@~0.13.20-rc3: version "0.13.20-rc3" resolved "https://registry.yarnpkg.com/zcash-bitcore-lib/-/zcash-bitcore-lib-0.13.20-rc3.tgz#813a0f56dcf8b76bc1429951bea6d1236c507008" From cb44cff168708e77b0ad303f23250d4b097e6509 Mon Sep 17 00:00:00 2001 From: Erik Marks <25517051+rekmarks@users.noreply.github.com> Date: Mon, 30 Nov 2020 12:59:01 -0800 Subject: [PATCH 10/32] Fix watchAsset symbol validation (#9960) --- app/scripts/controllers/preferences.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app/scripts/controllers/preferences.js b/app/scripts/controllers/preferences.js index 5e376a797..a3c6fec92 100644 --- a/app/scripts/controllers/preferences.js +++ b/app/scripts/controllers/preferences.js @@ -800,14 +800,16 @@ export default class PreferencesController { * doesn't fulfill requirements * */ - _validateERC20AssetParams(opts) { - const { rawAddress, symbol, decimals } = opts + _validateERC20AssetParams({ rawAddress, symbol, decimals } = {}) { if (!rawAddress || !symbol || typeof decimals === 'undefined') { throw new Error( `Cannot suggest token without address, symbol, and decimals`, ) } - if (!(symbol.length < 7)) { + if (typeof symbol !== 'string') { + throw new Error(`Invalid symbol: not a string`) + } + if (symbol.length > 6) { throw new Error(`Invalid symbol ${symbol} more than six characters`) } const numDecimals = parseInt(decimals, 10) From cc1161a52a4b23f779fc00a34007d132193c5157 Mon Sep 17 00:00:00 2001 From: Mark Stacey Date: Tue, 1 Dec 2020 17:54:56 -0330 Subject: [PATCH 11/32] Add metrics e2e test (#9784) An e2e test has been added that uses the new mock Segment server to verify that the three initial page metric events are sent correctly. Using the mock Segment server requires a special build with this mock Segment server hostname embedded, so a distinct job for building and running this test was required. As such, it was left out of the `run-all.sh` script. --- .circleci/config.yml | 79 +++++++++ package.json | 3 + test/e2e/fixtures/metrics-enabled/state.json | 168 +++++++++++++++++++ test/e2e/helpers.js | 36 +++- test/e2e/metrics.spec.js | 57 +++++++ 5 files changed, 341 insertions(+), 2 deletions(-) create mode 100644 test/e2e/fixtures/metrics-enabled/state.json create mode 100644 test/e2e/metrics.spec.js diff --git a/.circleci/config.yml b/.circleci/config.yml index 7c43e17b6..cd6efe2a3 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -18,6 +18,9 @@ workflows: - prep-build-test: requires: - prep-deps + - prep-build-test-metrics: + requires: + - prep-deps - prep-build-storybook: requires: - prep-deps @@ -34,6 +37,12 @@ workflows: - test-e2e-firefox: requires: - prep-build-test + - test-e2e-chrome-metrics: + requires: + - prep-build-test-metrics + - test-e2e-firefox-metrics: + requires: + - prep-build-test-metrics - test-unit: requires: - prep-deps @@ -58,6 +67,8 @@ workflows: - test-mozilla-lint - test-e2e-chrome - test-e2e-firefox + - test-e2e-chrome-metrics + - test-e2e-firefox-metrics - benchmark: requires: - prep-build-test @@ -162,6 +173,27 @@ jobs: paths: - dist-test + prep-build-test-metrics: + docker: + - image: circleci/node@sha256:e16740707de2ebed45c05d507f33ef204902349c7356d720610b5ec6a35d3d88 + resource_class: medium+ + environment: + NODE_OPTIONS: --max_old_space_size=2048 + steps: + - checkout + - attach_workspace: + at: . + - run: + name: Build extension for testing metrics + command: yarn build:test:metrics + - run: + name: Move test build to 'dist-test-metrics' to avoid conflict with production build + command: mv ./dist ./dist-test-metrics + - persist_to_workspace: + root: . + paths: + - dist-test-metrics + prep-build-storybook: docker: - image: circleci/node@sha256:e16740707de2ebed45c05d507f33ef204902349c7356d720610b5ec6a35d3d88 @@ -245,6 +277,28 @@ jobs: path: test-artifacts destination: test-artifacts + test-e2e-chrome-metrics: + docker: + - image: circleci/node@sha256:e16740707de2ebed45c05d507f33ef204902349c7356d720610b5ec6a35d3d88 + steps: + - checkout + - attach_workspace: + at: . + - run: + name: Move test build to dist + command: mv ./dist-test-metrics ./dist + - run: + name: test:e2e:chrome:metrics + command: | + if .circleci/scripts/test-run-e2e + then + yarn test:e2e:chrome:metrics + fi + no_output_timeout: 20m + - store_artifacts: + path: test-artifacts + destination: test-artifacts + test-e2e-firefox: docker: - image: circleci/node@sha256:e16740707de2ebed45c05d507f33ef204902349c7356d720610b5ec6a35d3d88 @@ -270,6 +324,31 @@ jobs: path: test-artifacts destination: test-artifacts + test-e2e-firefox-metrics: + docker: + - image: circleci/node@sha256:e16740707de2ebed45c05d507f33ef204902349c7356d720610b5ec6a35d3d88 + steps: + - checkout + - run: + name: Install Firefox + command: ./.circleci/scripts/firefox-install + - attach_workspace: + at: . + - run: + name: Move test build to dist + command: mv ./dist-test-metrics ./dist + - run: + name: test:e2e:firefox:metrics + command: | + if .circleci/scripts/test-run-e2e + then + yarn test:e2e:firefox:metrics + fi + no_output_timeout: 20m + - store_artifacts: + path: test-artifacts + destination: test-artifacts + benchmark: docker: - image: circleci/node@sha256:e16740707de2ebed45c05d507f33ef204902349c7356d720610b5ec6a35d3d88 diff --git a/package.json b/package.json index 01a7ffb90..dab32252b 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "benchmark:chrome": "SELENIUM_BROWSER=chrome node test/e2e/benchmark.js", "benchmark:firefox": "SELENIUM_BROWSER=firefox node test/e2e/benchmark.js", "build:test": "yarn build test", + "build:test:metrics": "SEGMENT_HOST='http://localhost:9090' SEGMENT_WRITE_KEY='FAKE' SEGMENT_LEGACY_WRITE_KEY='FAKE' yarn build test", "test": "yarn test:unit && yarn lint", "dapp": "node development/static-server.js node_modules/@metamask/test-dapp/dist --port 8080", "dapp-chain": "GANACHE_ARGS='-b 2' concurrently -k -n ganache,dapp -p '[{time}][{name}]' 'yarn ganache:start' 'sleep 5 && yarn dapp'", @@ -22,7 +23,9 @@ "test:unit:strict": "mocha --exit --require test/env.js --require test/setup.js --recursive \"test/unit/**/permissions/*.js\"", "test:unit:path": "mocha --exit --require test/env.js --require test/setup.js --recursive", "test:e2e:chrome": "SELENIUM_BROWSER=chrome test/e2e/run-all.sh", + "test:e2e:chrome:metrics": "SELENIUM_BROWSER=chrome mocha test/e2e/metrics.spec.js", "test:e2e:firefox": "SELENIUM_BROWSER=firefox test/e2e/run-all.sh", + "test:e2e:firefox:metrics": "SELENIUM_BROWSER=firefox mocha test/e2e/metrics.spec.js", "test:coverage": "nyc --silent --check-coverage yarn test:unit:strict && nyc --silent --no-clean yarn test:unit:lax && nyc report --reporter=text --reporter=html", "test:coverage:strict": "nyc --check-coverage yarn test:unit:strict", "test:coverage:path": "nyc --check-coverage yarn test:unit:path", diff --git a/test/e2e/fixtures/metrics-enabled/state.json b/test/e2e/fixtures/metrics-enabled/state.json new file mode 100644 index 000000000..4b0e52e70 --- /dev/null +++ b/test/e2e/fixtures/metrics-enabled/state.json @@ -0,0 +1,168 @@ +{ + "data": { + "AppStateController": { + "connectedStatusPopoverHasBeenShown": false, + "swapsWelcomeMessageHasBeenShown": true + }, + "CachedBalancesController": { + "cachedBalances": { + "4": {}, + "1337": { + "0x5cfe73b6021e818b776b421b1c4db2474086a7e1": "0x15af1d78b58c40000" + } + } + }, + "CurrencyController": { + "conversionDate": 1594348502.519, + "conversionRate": 240.09, + "currentCurrency": "usd", + "nativeCurrency": "ETH" + }, + "IncomingTransactionsController": { + "incomingTransactions": {}, + "incomingTxLastFetchedBlocksByNetwork": { + "goerli": null, + "kovan": null, + "mainnet": null, + "rinkeby": 5570536, + "localhost": 98 + } + }, + "KeyringController": { + "vault": "{\"data\":\"s6TpYjlUNsn7ifhEFTkuDGBUM1GyOlPrim7JSjtfIxgTt8/6MiXgiR/CtFfR4dWW2xhq85/NGIBYEeWrZThGdKGarBzeIqBfLFhw9n509jprzJ0zc2Rf+9HVFGLw+xxC4xPxgCS0IIWeAJQ+XtGcHmn0UZXriXm8Ja4kdlow6SWinB7sr/WM3R0+frYs4WgllkwggDf2/Tv6VHygvLnhtzp6hIJFyTjh+l/KnyJTyZW1TkZhDaNDzX3SCOHT\",\"iv\":\"FbeHDAW5afeWNORfNJBR0Q==\",\"salt\":\"TxZ+WbCW6891C9LK/hbMAoUsSEW1E8pyGLVBU6x5KR8=\"}" + }, + "NetworkController": { + "provider": { + "nickname": "Localhost 8545", + "rpcUrl": "http://localhost:8545", + "chainId": "0x539", + "ticker": "ETH", + "type": "rpc" + }, + "network": "1337" + }, + "OnboardingController": { + "onboardingTabs": {}, + "seedPhraseBackedUp": false + }, + "PermissionsMetadata": { + "permissionsLog": [ + { + "id": 1764280960, + "method": "eth_requestAccounts", + "methodType": "restricted", + "origin": "http://127.0.0.1:8080", + "request": { + "method": "eth_requestAccounts", + "jsonrpc": "2.0", + "id": 1764280960, + "origin": "http://127.0.0.1:8080", + "tabId": 2 + }, + "requestTime": 1594348329232, + "response": { + "id": 1764280960, + "jsonrpc": "2.0", + "result": ["0x5cfe73b6021e818b776b421b1c4db2474086a7e1"] + }, + "responseTime": 1594348332276, + "success": true + } + ], + "permissionsHistory": { + "http://127.0.0.1:8080": { + "eth_accounts": { + "accounts": { + "0x5cfe73b6021e818b776b421b1c4db2474086a7e1": 1594348332276 + }, + "lastApproved": 1594348332276 + } + } + }, + "domainMetadata": { + "http://127.0.0.1:8080": { + "name": "E2E Test Dapp", + "icon": "http://127.0.0.1:8080/metamask-fox.svg", + "lastUpdated": 1594348323811, + "host": "127.0.0.1:8080" + } + } + }, + "PreferencesController": { + "frequentRpcListDetail": [], + "accountTokens": { + "0x5cfe73b6021e818b776b421b1c4db2474086a7e1": { + "rinkeby": [], + "ropsten": [] + } + }, + "assetImages": {}, + "tokens": [], + "suggestedTokens": {}, + "useBlockie": false, + "useNonceField": false, + "usePhishDetect": true, + "featureFlags": { + "showIncomingTransactions": true, + "transactionTime": false + }, + "knownMethodData": {}, + "participateInMetaMetrics": true, + "firstTimeFlowType": "create", + "currentLocale": "en", + "identities": { + "0x5cfe73b6021e818b776b421b1c4db2474086a7e1": { + "address": "0x5cfe73b6021e818b776b421b1c4db2474086a7e1", + "name": "Account 1" + } + }, + "lostIdentities": {}, + "forgottenPassword": false, + "preferences": { + "useNativeCurrencyAsPrimaryCurrency": true + }, + "completedOnboarding": true, + "metaMetricsId": "fake-metrics-id", + "metaMetricsSendCount": 0, + "ipfsGateway": "dweb.link", + "selectedAddress": "0x5cfe73b6021e818b776b421b1c4db2474086a7e1" + }, + "config": {}, + "firstTimeInfo": { + "date": 1575697234195, + "version": "7.7.0" + }, + "PermissionsController": { + "permissionsRequests": [], + "permissionsDescriptions": {}, + "domains": { + "http://127.0.0.1:8080": { + "permissions": [ + { + "@context": ["https://github.com/MetaMask/rpc-cap"], + "parentCapability": "eth_accounts", + "id": "f55a1c15-ea48-4088-968e-63be474d42fa", + "date": 1594348332268, + "invoker": "http://127.0.0.1:8080", + "caveats": [ + { + "type": "limitResponseLength", + "value": 1, + "name": "primaryAccountOnly" + }, + { + "type": "filterResponse", + "value": ["0x5cfe73b6021e818b776b421b1c4db2474086a7e1"], + "name": "exposedAccounts" + } + ] + } + ] + } + } + } + }, + "meta": { + "version": 47 + } +} diff --git a/test/e2e/helpers.js b/test/e2e/helpers.js index 9e6aa2f9f..de5986546 100644 --- a/test/e2e/helpers.js +++ b/test/e2e/helpers.js @@ -1,5 +1,9 @@ const path = require('path') +const sinon = require('sinon') const createStaticServer = require('../../development/create-static-server') +const { + createSegmentServer, +} = require('../../development/lib/create-segment-server') const Ganache = require('./ganache') const FixtureServer = require('./fixture-server') const { buildWebDriver } = require('./webdriver') @@ -11,10 +15,19 @@ const largeDelayMs = regularDelayMs * 2 const dappPort = 8080 async function withFixtures(options, testSuite) { - const { dapp, fixtures, ganacheOptions, driverOptions, title } = options + const { + dapp, + fixtures, + ganacheOptions, + driverOptions, + mockSegment, + title, + } = options const fixtureServer = new FixtureServer() const ganacheServer = new Ganache() let dappServer + let segmentServer + let segmentSpy let webDriver try { @@ -38,11 +51,23 @@ async function withFixtures(options, testSuite) { dappServer.on('error', reject) }) } + if (mockSegment) { + segmentSpy = sinon.spy() + segmentServer = createSegmentServer((_request, response, events) => { + for (const event of events) { + segmentSpy(event) + } + response.statusCode = 200 + response.end() + }) + await segmentServer.start(9090) + } const { driver } = await buildWebDriver(driverOptions) webDriver = driver await testSuite({ driver, + segmentSpy, }) if (process.env.SELENIUM_BROWSER === 'chrome') { @@ -57,7 +82,11 @@ async function withFixtures(options, testSuite) { } } catch (error) { if (webDriver) { - await webDriver.verboseReportOnFailure(title) + try { + await webDriver.verboseReportOnFailure(title) + } catch (verboseReportError) { + console.error(verboseReportError) + } } throw error } finally { @@ -76,6 +105,9 @@ async function withFixtures(options, testSuite) { }) }) } + if (segmentServer) { + await segmentServer.stop() + } } } diff --git a/test/e2e/metrics.spec.js b/test/e2e/metrics.spec.js new file mode 100644 index 000000000..e8598b792 --- /dev/null +++ b/test/e2e/metrics.spec.js @@ -0,0 +1,57 @@ +const { strict: assert } = require('assert') +const { By, Key } = require('selenium-webdriver') +const { withFixtures } = require('./helpers') + +/** + * WARNING: These tests must be run using a build created with `yarn build:test:metrics`, so that it has + * the correct Segment host and write keys set. Otherwise this test will fail. + */ +describe('Segment metrics', function () { + this.timeout(0) + + it('should send first three Page metric events upon fullscreen page load', async function () { + const ganacheOptions = { + accounts: [ + { + secretKey: + '0x7C9529A67102755B7E6102D6D950AC5D5863C98713805CEC576B945B15B71EAC', + balance: 25000000000000000000, + }, + ], + } + await withFixtures( + { + fixtures: 'metrics-enabled', + ganacheOptions, + title: this.test.title, + mockSegment: true, + }, + async ({ driver, segmentSpy }) => { + const passwordField = await driver.findElement(By.css('#password')) + await passwordField.sendKeys('correct horse battery staple') + await passwordField.sendKeys(Key.ENTER) + + // find arbitary element to ensure Home page has loaded + await driver.findElement(By.css('[data-testid="eth-overview-send"]')) + + assert.ok(segmentSpy.called, 'Segment should receive metrics') + assert.ok( + segmentSpy.callCount >= 3, + 'At least 3 segment events should be sent', + ) + + const firstSegmentEvent = segmentSpy.getCall(0).args[0] + assert.equal(firstSegmentEvent.name, 'Home') + assert.equal(firstSegmentEvent.context.page.path, '/') + + const secondSegmentEvent = segmentSpy.getCall(1).args[0] + assert.equal(secondSegmentEvent.name, 'Unlock Page') + assert.equal(secondSegmentEvent.context.page.path, '/unlock') + + const thirdSegmentEvent = segmentSpy.getCall(2).args[0] + assert.equal(thirdSegmentEvent.name, 'Home') + assert.equal(thirdSegmentEvent.context.page.path, '/') + }, + ) + }) +}) From 9d4b8a4903e39ccc16c1122e31c429f89e9eba1a Mon Sep 17 00:00:00 2001 From: Erik Marks <25517051+rekmarks@users.noreply.github.com> Date: Tue, 1 Dec 2020 14:55:01 -0800 Subject: [PATCH 12/32] @metamask/contract-metadata (#9968) --- .github/dependabot.yml | 1 - app/scripts/controllers/detect-tokens.js | 4 ++-- app/scripts/metamask-controller.js | 2 +- development/build/static.js | 2 +- package.json | 2 +- shared/constants/tokens.js | 4 ++-- test/unit/app/controllers/detect-tokens-test.js | 2 +- ui/app/components/ui/identicon/identicon.component.js | 2 +- ui/app/helpers/utils/token-util.js | 2 +- ui/app/hooks/useTokensToSearch.js | 2 +- .../pages/add-token/token-search/token-search.component.js | 2 +- .../confirm-transaction-base.container.js | 2 +- .../pages/send/send-content/add-recipient/add-recipient.js | 2 +- ui/lib/icon-factory.js | 2 +- yarn.lock | 7 ++++++- 15 files changed, 21 insertions(+), 17 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index d35290252..3c2610e72 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -9,5 +9,4 @@ updates: interval: "daily" allow: - dependency-name: "@metamask/*" - - dependency-name: "eth-contract-metadata" versioning-strategy: "lockfile-only" diff --git a/app/scripts/controllers/detect-tokens.js b/app/scripts/controllers/detect-tokens.js index 6c1c213a6..1fda6dccc 100644 --- a/app/scripts/controllers/detect-tokens.js +++ b/app/scripts/controllers/detect-tokens.js @@ -1,5 +1,5 @@ import Web3 from 'web3' -import contracts from 'eth-contract-metadata' +import contracts from '@metamask/contract-metadata' import { warn } from 'loglevel' import SINGLE_CALL_BALANCES_ABI from 'single-call-balance-checker-abi' import { MAINNET } from './network/enums' @@ -32,7 +32,7 @@ export default class DetectTokensController { } /** - * For each token in eth-contract-metadata, find check selectedAddress balance. + * For each token in @metamask/contract-metadata, find check selectedAddress balance. */ async detectNewTokens() { if (!this.isActive) { diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index e6678054d..5a4e69aaf 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -18,7 +18,7 @@ import TrezorKeyring from 'eth-trezor-keyring' import LedgerBridgeKeyring from '@metamask/eth-ledger-bridge-keyring' import EthQuery from 'eth-query' import nanoid from 'nanoid' -import contractMap from 'eth-contract-metadata' +import contractMap from '@metamask/contract-metadata' import { AddressBookController, CurrencyRateController, diff --git a/development/build/static.js b/development/build/static.js index 56f1afb32..142f290d1 100644 --- a/development/build/static.js +++ b/development/build/static.js @@ -19,7 +19,7 @@ const copyTargets = [ dest: `images`, }, { - src: `./node_modules/eth-contract-metadata/images/`, + src: `./node_modules/@metamask/contract-metadata/images/`, dest: `images/contract`, }, { diff --git a/package.json b/package.json index dab32252b..5305c17ac 100644 --- a/package.json +++ b/package.json @@ -76,6 +76,7 @@ "@formatjs/intl-relativetimeformat": "^5.2.6", "@fortawesome/fontawesome-free": "^5.13.0", "@material-ui/core": "^4.11.0", + "@metamask/contract-metadata": "^1.19.0", "@metamask/controllers": "^4.2.0", "@metamask/eth-ledger-bridge-keyring": "^0.2.6", "@metamask/eth-token-tracker": "^3.0.1", @@ -104,7 +105,6 @@ "dnode": "^1.2.2", "end-of-stream": "^1.4.4", "eth-block-tracker": "^4.4.2", - "eth-contract-metadata": "^1.16.0", "eth-ens-namehash": "^2.0.8", "eth-json-rpc-errors": "^2.0.2", "eth-json-rpc-filters": "^4.2.1", diff --git a/shared/constants/tokens.js b/shared/constants/tokens.js index a31c1ec18..27b240f7b 100644 --- a/shared/constants/tokens.js +++ b/shared/constants/tokens.js @@ -1,8 +1,8 @@ -import contractMap from 'eth-contract-metadata' +import contractMap from '@metamask/contract-metadata' /** * A normalized list of addresses exported as part of the contractMap in - * eth-contract-metadata. Used primarily to validate if manually entered + * @metamask/contract-metadata. Used primarily to validate if manually entered * contract addresses do not match one of our listed tokens */ export const LISTED_CONTRACT_ADDRESSES = Object.keys( diff --git a/test/unit/app/controllers/detect-tokens-test.js b/test/unit/app/controllers/detect-tokens-test.js index 8f3a5a52c..82be8808a 100644 --- a/test/unit/app/controllers/detect-tokens-test.js +++ b/test/unit/app/controllers/detect-tokens-test.js @@ -1,7 +1,7 @@ import assert from 'assert' import sinon from 'sinon' import ObservableStore from 'obs-store' -import contracts from 'eth-contract-metadata' +import contracts from '@metamask/contract-metadata' import BigNumber from 'bignumber.js' import DetectTokensController from '../../../../app/scripts/controllers/detect-tokens' diff --git a/ui/app/components/ui/identicon/identicon.component.js b/ui/app/components/ui/identicon/identicon.component.js index 79d7cf1b5..09a731eca 100644 --- a/ui/app/components/ui/identicon/identicon.component.js +++ b/ui/app/components/ui/identicon/identicon.component.js @@ -1,7 +1,7 @@ import React, { PureComponent } from 'react' import PropTypes from 'prop-types' import classnames from 'classnames' -import contractMap from 'eth-contract-metadata' +import contractMap from '@metamask/contract-metadata' import { checksumAddress } from '../../../helpers/utils/util' import Jazzicon from '../jazzicon' diff --git a/ui/app/helpers/utils/token-util.js b/ui/app/helpers/utils/token-util.js index fa581f910..e8965edb3 100644 --- a/ui/app/helpers/utils/token-util.js +++ b/ui/app/helpers/utils/token-util.js @@ -1,6 +1,6 @@ import log from 'loglevel' import BigNumber from 'bignumber.js' -import contractMap from 'eth-contract-metadata' +import contractMap from '@metamask/contract-metadata' import * as util from './util' import { conversionUtil, multiplyCurrencies } from './conversion-util' import { formatCurrency } from './confirm-tx.util' diff --git a/ui/app/hooks/useTokensToSearch.js b/ui/app/hooks/useTokensToSearch.js index 0d9485e1b..8df33e55e 100644 --- a/ui/app/hooks/useTokensToSearch.js +++ b/ui/app/hooks/useTokensToSearch.js @@ -1,6 +1,6 @@ import { useMemo } from 'react' import { useSelector } from 'react-redux' -import contractMap from 'eth-contract-metadata' +import contractMap from '@metamask/contract-metadata' import BigNumber from 'bignumber.js' import { isEqual, shuffle } from 'lodash' import { checksumAddress } from '../helpers/utils/util' diff --git a/ui/app/pages/add-token/token-search/token-search.component.js b/ui/app/pages/add-token/token-search/token-search.component.js index 8ef9d20af..8b889b057 100644 --- a/ui/app/pages/add-token/token-search/token-search.component.js +++ b/ui/app/pages/add-token/token-search/token-search.component.js @@ -1,6 +1,6 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' -import contractMap from 'eth-contract-metadata' +import contractMap from '@metamask/contract-metadata' import Fuse from 'fuse.js' import InputAdornment from '@material-ui/core/InputAdornment' import TextField from '../../../components/ui/text-field' diff --git a/ui/app/pages/confirm-transaction-base/confirm-transaction-base.container.js b/ui/app/pages/confirm-transaction-base/confirm-transaction-base.container.js index 245df89ec..09cece00e 100644 --- a/ui/app/pages/confirm-transaction-base/confirm-transaction-base.container.js +++ b/ui/app/pages/confirm-transaction-base/confirm-transaction-base.container.js @@ -1,7 +1,7 @@ import { connect } from 'react-redux' import { compose } from 'redux' import { withRouter } from 'react-router-dom' -import contractMap from 'eth-contract-metadata' +import contractMap from '@metamask/contract-metadata' import { clearConfirmTransaction } from '../../ducks/confirm-transaction/confirm-transaction.duck' import { diff --git a/ui/app/pages/send/send-content/add-recipient/add-recipient.js b/ui/app/pages/send/send-content/add-recipient/add-recipient.js index dc6283b83..47b64f774 100644 --- a/ui/app/pages/send/send-content/add-recipient/add-recipient.js +++ b/ui/app/pages/send/send-content/add-recipient/add-recipient.js @@ -1,5 +1,5 @@ import ethUtil from 'ethereumjs-util' -import contractMap from 'eth-contract-metadata' +import contractMap from '@metamask/contract-metadata' import { REQUIRED_ERROR, INVALID_RECIPIENT_ADDRESS_ERROR, diff --git a/ui/lib/icon-factory.js b/ui/lib/icon-factory.js index 789d1c34b..fa3f2bbf3 100644 --- a/ui/lib/icon-factory.js +++ b/ui/lib/icon-factory.js @@ -1,5 +1,5 @@ import { isValidAddress } from 'ethereumjs-util' -import contractMap from 'eth-contract-metadata' +import contractMap from '@metamask/contract-metadata' import { checksumAddress } from '../app/helpers/utils/util' let iconFactory diff --git a/yarn.lock b/yarn.lock index fed504d5c..f20a183c9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2014,6 +2014,11 @@ prop-types "^15.7.2" react-is "^16.8.0" +"@metamask/contract-metadata@^1.19.0": + version "1.19.0" + resolved "https://registry.yarnpkg.com/@metamask/contract-metadata/-/contract-metadata-1.19.0.tgz#2f074bce7ab7ffd0d20e3905b1936da0749a0473" + integrity sha512-TklMuz7ZbFJ2Zc6C7I+9qL3J9J+4prs5Ok5MJzoxD/57Iq6espzArhpI275elVCFF9ci8IMvach1kH8+F04/hA== + "@metamask/controllers@^3.1.0": version "3.2.0" resolved "https://registry.yarnpkg.com/@metamask/controllers/-/controllers-3.2.0.tgz#8ad2e63f7953d294712d9b5bacaea1c5261ce588" @@ -9942,7 +9947,7 @@ eth-block-tracker@^4.4.2: pify "^3.0.0" safe-event-emitter "^1.0.1" -eth-contract-metadata@^1.11.0, eth-contract-metadata@^1.16.0: +eth-contract-metadata@^1.11.0: version "1.17.0" resolved "https://registry.yarnpkg.com/eth-contract-metadata/-/eth-contract-metadata-1.17.0.tgz#96d4b056ac9a7175eeba091dbabd0713cfd4c703" integrity sha512-vlw4OiW3+9J3kJfEtPCyiSW9fhdWTqrAhXcvdMY2CevGxbhvOd5Lz59DeWerSTV3IoSXttghDurPA76dAeTV+A== From c3eb272af9c279a59c247010b88d56d1adbe2fc6 Mon Sep 17 00:00:00 2001 From: Erik Marks <25517051+rekmarks@users.noreply.github.com> Date: Wed, 2 Dec 2020 08:49:49 -0800 Subject: [PATCH 13/32] Use method middleware for watchAsset (#9943) * Use method middleware for watchAsset * Update validation error messages * Make addSuggestedERC20Asset private * Remove redundant check in _handleWatchAssetERC20 --- app/scripts/controllers/preferences.js | 125 ++++++++---------- app/scripts/lib/enums.js | 2 + .../createMethodMiddleware.js | 4 +- .../rpc-method-middleware/handlers/index.js | 3 +- .../handlers/log-web3-usage.js | 2 +- .../handlers/watch-asset.js | 40 ++++++ app/scripts/metamask-controller.js | 9 +- .../preferences-controller-test.js | 65 ++++----- 8 files changed, 129 insertions(+), 121 deletions(-) create mode 100644 app/scripts/lib/rpc-method-middleware/handlers/watch-asset.js diff --git a/app/scripts/controllers/preferences.js b/app/scripts/controllers/preferences.js index a3c6fec92..c7bc88f0b 100644 --- a/app/scripts/controllers/preferences.js +++ b/app/scripts/controllers/preferences.js @@ -1,12 +1,12 @@ import { strict as assert } from 'assert' import ObservableStore from 'obs-store' +import { ethErrors } from 'eth-json-rpc-errors' import { normalize as normalizeAddress } from 'eth-sig-util' import { isValidAddress, sha3, bufferToHex } from 'ethereumjs-util' import ethers from 'ethers' import log from 'loglevel' import { isPrefixedFormattedHexString } from '../lib/util' import { LISTED_CONTRACT_ADDRESSES } from '../../../shared/constants/tokens' -import { addInternalMethodPrefix } from './permissions' import { NETWORK_TYPE_TO_ID_MAP } from './network/enums' export default class PreferencesController { @@ -171,22 +171,6 @@ export default class PreferencesController { return this.store.getState().assetImages } - addSuggestedERC20Asset(tokenOpts) { - this._validateERC20AssetParams(tokenOpts) - const suggested = this.getSuggestedTokens() - const { rawAddress, symbol, decimals, image } = tokenOpts - const address = normalizeAddress(rawAddress) - const newEntry = { - address, - symbol, - decimals, - image, - unlisted: !LISTED_CONTRACT_ADDRESSES.includes(address.toLowerCase()), - } - suggested[address] = newEntry - this.store.updateState({ suggestedTokens: suggested }) - } - /** * Add new methodData to state, to avoid requesting this information again through Infura * @@ -200,37 +184,21 @@ export default class PreferencesController { } /** - * RPC engine middleware for requesting new asset added - * - * @param {any} req - * @param {any} res - * @param {Function} next - * @param {Function} end - */ - async requestWatchAsset(req, res, next, end) { - if ( - req.method === 'metamask_watchAsset' || - req.method === addInternalMethodPrefix('watchAsset') - ) { - const { type, options } = req.params - switch (type) { - case 'ERC20': { - const result = await this._handleWatchAssetERC20(options) - if (result instanceof Error) { - end(result) - } else { - res.result = result - end() - } - return - } - default: - end(new Error(`Asset of type ${type} not supported`)) - return - } - } + * wallet_watchAsset request handler. + * + * @param {Object} req - The watchAsset JSON-RPC request object. + */ + async requestWatchAsset(req) { + const { type, options } = req.params - next() + switch (type) { + case 'ERC20': + return await this._handleWatchAssetERC20(options) + default: + throw ethErrors.rpc.invalidParams( + `Asset of type "${type}" not supported.`, + ) + } } /** @@ -775,21 +743,17 @@ export default class PreferencesController { * */ async _handleWatchAssetERC20(tokenMetadata) { - const { address, symbol, decimals, image } = tokenMetadata - const rawAddress = address - try { - this._validateERC20AssetParams({ rawAddress, symbol, decimals }) - } catch (err) { - return err - } - const tokenOpts = { rawAddress, decimals, symbol, image } - this.addSuggestedERC20Asset(tokenOpts) - return this.openPopup().then(() => { - const tokenAddresses = this.getTokens().filter( - (token) => token.address === normalizeAddress(rawAddress), - ) - return tokenAddresses.length > 0 - }) + this._validateERC20AssetParams(tokenMetadata) + + const address = normalizeAddress(tokenMetadata.address) + const { symbol, decimals, image } = tokenMetadata + this._addSuggestedERC20Asset(address, symbol, decimals, image) + + await this.openPopup() + const tokenAddresses = this.getTokens().filter( + (token) => token.address === address, + ) + return tokenAddresses.length > 0 } /** @@ -800,26 +764,41 @@ export default class PreferencesController { * doesn't fulfill requirements * */ - _validateERC20AssetParams({ rawAddress, symbol, decimals } = {}) { - if (!rawAddress || !symbol || typeof decimals === 'undefined') { - throw new Error( - `Cannot suggest token without address, symbol, and decimals`, + _validateERC20AssetParams({ address, symbol, decimals }) { + if (!address || !symbol || typeof decimals === 'undefined') { + throw ethErrors.rpc.invalidParams( + `Must specify address, symbol, and decimals.`, ) } if (typeof symbol !== 'string') { - throw new Error(`Invalid symbol: not a string`) + throw ethErrors.rpc.invalidParams(`Invalid symbol: not a string.`) } - if (symbol.length > 6) { - throw new Error(`Invalid symbol ${symbol} more than six characters`) + if (!(symbol.length < 7)) { + throw ethErrors.rpc.invalidParams( + `Invalid symbol "${symbol}": longer than 6 characters.`, + ) } const numDecimals = parseInt(decimals, 10) if (isNaN(numDecimals) || numDecimals > 36 || numDecimals < 0) { - throw new Error( - `Invalid decimals ${decimals} must be at least 0, and not over 36`, + throw ethErrors.rpc.invalidParams( + `Invalid decimals "${decimals}": must be 0 <= 36.`, ) } - if (!isValidAddress(rawAddress)) { - throw new Error(`Invalid address ${rawAddress}`) + if (!isValidAddress(address)) { + throw ethErrors.rpc.invalidParams(`Invalid address "${address}".`) } } + + _addSuggestedERC20Asset(address, symbol, decimals, image) { + const newEntry = { + address, + symbol, + decimals, + image, + unlisted: !LISTED_CONTRACT_ADDRESSES.includes(address), + } + const suggested = this.getSuggestedTokens() + suggested[address] = newEntry + this.store.updateState({ suggestedTokens: suggested }) + } } diff --git a/app/scripts/lib/enums.js b/app/scripts/lib/enums.js index 543e8db36..d93030f2c 100644 --- a/app/scripts/lib/enums.js +++ b/app/scripts/lib/enums.js @@ -25,6 +25,8 @@ const MESSAGE_TYPE = { ETH_SIGN_TYPED_DATA: 'eth_signTypedData', LOG_WEB3_USAGE: 'metamask_logInjectedWeb3Usage', PERSONAL_SIGN: 'personal_sign', + WATCH_ASSET: 'wallet_watchAsset', + WATCH_ASSET_LEGACY: 'metamask_watchAsset', } export { diff --git a/app/scripts/lib/rpc-method-middleware/createMethodMiddleware.js b/app/scripts/lib/rpc-method-middleware/createMethodMiddleware.js index fff0afb16..b87047cd2 100644 --- a/app/scripts/lib/rpc-method-middleware/createMethodMiddleware.js +++ b/app/scripts/lib/rpc-method-middleware/createMethodMiddleware.js @@ -1,7 +1,9 @@ import handlers from './handlers' const handlerMap = handlers.reduce((map, handler) => { - map.set(handler.methodName, handler.implementation) + for (const methodName of handler.methodNames) { + map.set(methodName, handler.implementation) + } return map }, new Map()) diff --git a/app/scripts/lib/rpc-method-middleware/handlers/index.js b/app/scripts/lib/rpc-method-middleware/handlers/index.js index bc87cb309..74e26b675 100644 --- a/app/scripts/lib/rpc-method-middleware/handlers/index.js +++ b/app/scripts/lib/rpc-method-middleware/handlers/index.js @@ -1,4 +1,5 @@ import logWeb3Usage from './log-web3-usage' +import watchAsset from './watch-asset' -const handlers = [logWeb3Usage] +const handlers = [logWeb3Usage, watchAsset] export default handlers diff --git a/app/scripts/lib/rpc-method-middleware/handlers/log-web3-usage.js b/app/scripts/lib/rpc-method-middleware/handlers/log-web3-usage.js index 290c52b94..44bb3a2ca 100644 --- a/app/scripts/lib/rpc-method-middleware/handlers/log-web3-usage.js +++ b/app/scripts/lib/rpc-method-middleware/handlers/log-web3-usage.js @@ -8,7 +8,7 @@ import { MESSAGE_TYPE } from '../../enums' */ const logWeb3Usage = { - methodName: MESSAGE_TYPE.LOG_WEB3_USAGE, + methodNames: [MESSAGE_TYPE.LOG_WEB3_USAGE], implementation: logWeb3UsageHandler, } export default logWeb3Usage diff --git a/app/scripts/lib/rpc-method-middleware/handlers/watch-asset.js b/app/scripts/lib/rpc-method-middleware/handlers/watch-asset.js new file mode 100644 index 000000000..1c5f4c1db --- /dev/null +++ b/app/scripts/lib/rpc-method-middleware/handlers/watch-asset.js @@ -0,0 +1,40 @@ +import { MESSAGE_TYPE } from '../../enums' + +const watchAsset = { + methodNames: [MESSAGE_TYPE.WATCH_ASSET, MESSAGE_TYPE.WATCH_ASSET_LEGACY], + implementation: watchAssetHandler, +} +export default watchAsset + +/** + * @typedef {Object} WatchAssetOptions + * @property {Function} handleWatchAssetRequest - The wallet_watchAsset method implementation. + */ + +/** + * @typedef {Object} WatchAssetParam + * @property {string} type - The type of the asset to watch. + * @property {Object} options - Watch options for the asset. + */ + +/** + * @param {import('json-rpc-engine').JsonRpcRequest} req - The JSON-RPC request object. + * @param {import('json-rpc-engine').JsonRpcResponse} res - The JSON-RPC response object. + * @param {Function} _next - The json-rpc-engine 'next' callback. + * @param {Function} end - The json-rpc-engine 'end' callback. + * @param {WatchAssetOptions} options + */ +async function watchAssetHandler( + req, + res, + _next, + end, + { handleWatchAssetRequest }, +) { + try { + res.result = await handleWatchAssetRequest(req) + return end() + } catch (error) { + return end(error) + } +} diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 5a4e69aaf..bbd2c9d0f 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -1968,6 +1968,9 @@ export default class MetamaskController extends EventEmitter { createMethodMiddleware({ origin, sendMetrics: this.trackMetaMetricsEvent, + handleWatchAssetRequest: this.preferencesController.requestWatchAsset.bind( + this.preferencesController, + ), }), ) // filter and subscription polyfills @@ -1979,12 +1982,6 @@ export default class MetamaskController extends EventEmitter { this.permissionsController.createMiddleware({ origin, extensionId }), ) } - // watch asset - engine.push( - this.preferencesController.requestWatchAsset.bind( - this.preferencesController, - ), - ) // forward to metamask primary provider engine.push(providerAsMiddleware(provider)) return engine diff --git a/test/unit/app/controllers/preferences-controller-test.js b/test/unit/app/controllers/preferences-controller-test.js index e041bb582..6a831c3e7 100644 --- a/test/unit/app/controllers/preferences-controller-test.js +++ b/test/unit/app/controllers/preferences-controller-test.js @@ -2,7 +2,6 @@ import assert from 'assert' import ObservableStore from 'obs-store' import sinon from 'sinon' import PreferencesController from '../../../../app/scripts/controllers/preferences' -import { addInternalMethodPrefix } from '../../../../app/scripts/controllers/permissions' describe('preferences controller', function () { let preferencesController @@ -405,53 +404,41 @@ describe('preferences controller', function () { }) describe('on watchAsset', function () { - let stubHandleWatchAssetERC20, asy, req, res + let req, stubHandleWatchAssetERC20 const sandbox = sinon.createSandbox() beforeEach(function () { - req = { params: {} } - res = {} - asy = { next: sandbox.spy(), end: sandbox.spy() } + req = { method: 'wallet_watchAsset', params: {} } stubHandleWatchAssetERC20 = sandbox.stub( preferencesController, '_handleWatchAssetERC20', ) }) + after(function () { sandbox.restore() }) - it('shouldn not do anything if method not corresponds', async function () { - req.method = 'metamask' - await preferencesController.requestWatchAsset(req, res, asy.next, asy.end) - sandbox.assert.notCalled(asy.end) - sandbox.assert.called(asy.next) + it('should error if passed no type', async function () { + await assert.rejects( + () => preferencesController.requestWatchAsset(req), + { message: 'Asset of type "undefined" not supported.' }, + 'should have errored', + ) }) - it('should do something if method is supported', async function () { - req.method = 'metamask_watchAsset' - req.params.type = 'someasset' - await preferencesController.requestWatchAsset(req, res, asy.next, asy.end) - sandbox.assert.called(asy.end) - sandbox.assert.notCalled(asy.next) - req.method = addInternalMethodPrefix('watchAsset') + + it('should error if method is not supported', async function () { req.params.type = 'someasset' - await preferencesController.requestWatchAsset(req, res, asy.next, asy.end) - sandbox.assert.calledTwice(asy.end) - sandbox.assert.notCalled(asy.next) + await assert.rejects( + () => preferencesController.requestWatchAsset(req), + { message: 'Asset of type "someasset" not supported.' }, + 'should have errored', + ) }) - it('should through error if method is supported but asset type is not', async function () { - req.method = 'metamask_watchAsset' - req.params.type = 'someasset' - await preferencesController.requestWatchAsset(req, res, asy.next, asy.end) - sandbox.assert.called(asy.end) - sandbox.assert.notCalled(stubHandleWatchAssetERC20) - sandbox.assert.notCalled(asy.next) - assert.deepEqual(res, {}) - }) - it('should trigger handle add asset if type supported', async function () { - req.method = 'metamask_watchAsset' + + it('should handle ERC20 type', async function () { req.params.type = 'ERC20' - await preferencesController.requestWatchAsset(req, res, asy.next, asy.end) + await preferencesController.requestWatchAsset(req) sandbox.assert.called(stubHandleWatchAssetERC20) }) }) @@ -527,7 +514,7 @@ describe('preferences controller', function () { assert.doesNotThrow(() => validate({ - rawAddress: '0xd26114cd6EE289AccF82350c8d8487fedB8A0C07', + address: '0xd26114cd6EE289AccF82350c8d8487fedB8A0C07', symbol: 'ABC', decimals: 0, }), @@ -539,7 +526,7 @@ describe('preferences controller', function () { assert.throws( () => validate({ - rawAddress: '0xd26114cd6EE289AccF82350c8d8487fedB8A0C07', + address: '0xd26114cd6EE289AccF82350c8d8487fedB8A0C07', decimals: 0, }), 'missing symbol should fail', @@ -547,7 +534,7 @@ describe('preferences controller', function () { assert.throws( () => validate({ - rawAddress: '0xd26114cd6EE289AccF82350c8d8487fedB8A0C07', + address: '0xd26114cd6EE289AccF82350c8d8487fedB8A0C07', symbol: 'ABC', }), 'missing decimals should fail', @@ -555,7 +542,7 @@ describe('preferences controller', function () { assert.throws( () => validate({ - rawAddress: '0xd26114cd6EE289AccF82350c8d8487fedB8A0C07', + address: '0xd26114cd6EE289AccF82350c8d8487fedB8A0C07', symbol: 'ABCDEFGHI', decimals: 0, }), @@ -564,7 +551,7 @@ describe('preferences controller', function () { assert.throws( () => validate({ - rawAddress: '0xd26114cd6EE289AccF82350c8d8487fedB8A0C07', + address: '0xd26114cd6EE289AccF82350c8d8487fedB8A0C07', symbol: 'ABC', decimals: -1, }), @@ -573,14 +560,14 @@ describe('preferences controller', function () { assert.throws( () => validate({ - rawAddress: '0xd26114cd6EE289AccF82350c8d8487fedB8A0C07', + address: '0xd26114cd6EE289AccF82350c8d8487fedB8A0C07', symbol: 'ABC', decimals: 38, }), 'decimals > 36 should fail', ) assert.throws( - () => validate({ rawAddress: '0x123', symbol: 'ABC', decimals: 0 }), + () => validate({ address: '0x123', symbol: 'ABC', decimals: 0 }), 'invalid address should fail', ) }) From df209612d54afa8b671076afdbf9c3199207d7fe Mon Sep 17 00:00:00 2001 From: Erik Marks <25517051+rekmarks@users.noreply.github.com> Date: Wed, 2 Dec 2020 08:59:04 -0800 Subject: [PATCH 14/32] @metamask/etherscan-link@1.4.0 (#9970) --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 5305c17ac..2981ea5c5 100644 --- a/package.json +++ b/package.json @@ -80,7 +80,7 @@ "@metamask/controllers": "^4.2.0", "@metamask/eth-ledger-bridge-keyring": "^0.2.6", "@metamask/eth-token-tracker": "^3.0.1", - "@metamask/etherscan-link": "^1.3.0", + "@metamask/etherscan-link": "^1.4.0", "@metamask/inpage-provider": "^6.1.0", "@metamask/jazzicon": "^2.0.0", "@metamask/logo": "^2.5.0", diff --git a/yarn.lock b/yarn.lock index f20a183c9..166f19ad7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2105,10 +2105,10 @@ human-standard-token-abi "^1.0.2" safe-event-emitter "^1.0.1" -"@metamask/etherscan-link@^1.3.0": - version "1.3.0" - resolved "https://registry.yarnpkg.com/@metamask/etherscan-link/-/etherscan-link-1.3.0.tgz#ce5b9e0083f51386f8f462110b4094cf6243022c" - integrity sha512-2BLaSJLqOIq5CasneVqortc7sPMjgXDTdPv4dSjseF+RUtv/HPTSXZPhV2dFkGd/n+eCQoevPRVOFsVvuRnFeA== +"@metamask/etherscan-link@^1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@metamask/etherscan-link/-/etherscan-link-1.4.0.tgz#4631e9beec17de26b35b3ccd643ede2bae8ed811" + integrity sha512-4Bi72Y8/FQZbfTARyv+oWKGuECzdQ37cQKt88Eu5JPDrHAcRDZt4Bt7bWC9phUBrphAr1qbCKh9S90X9hW0pZg== "@metamask/forwarder@^1.1.0": version "1.1.0" From 1da9ad77a40f03b352721f563c350a4b5c1ac202 Mon Sep 17 00:00:00 2001 From: Erik Marks <25517051+rekmarks@users.noreply.github.com> Date: Wed, 2 Dec 2020 11:41:24 -0800 Subject: [PATCH 15/32] json-rpc-engine@6.1.0 (#9922) --- .../controllers/network/createInfuraClient.js | 3 +-- .../network/createJsonRpcClient.js | 3 +-- .../network/createMetamaskMiddleware.js | 3 +-- .../controllers/network/middleware/pending.js | 2 +- app/scripts/controllers/network/network.js | 2 +- app/scripts/controllers/permissions/index.js | 5 ++--- .../permissionsMethodMiddleware.js | 2 +- app/scripts/controllers/threebox.js | 2 +- app/scripts/metamask-controller.js | 4 ++-- package.json | 2 +- test/stub/provider.js | 2 +- .../permissions-controller-test.js | 12 ----------- yarn.lock | 20 +++++++++++++++++++ 13 files changed, 33 insertions(+), 29 deletions(-) diff --git a/app/scripts/controllers/network/createInfuraClient.js b/app/scripts/controllers/network/createInfuraClient.js index 52048a775..0d1514d61 100644 --- a/app/scripts/controllers/network/createInfuraClient.js +++ b/app/scripts/controllers/network/createInfuraClient.js @@ -1,5 +1,4 @@ -import mergeMiddleware from 'json-rpc-engine/src/mergeMiddleware' -import createScaffoldMiddleware from 'json-rpc-engine/src/createScaffoldMiddleware' +import { createScaffoldMiddleware, mergeMiddleware } from 'json-rpc-engine' import createBlockReRefMiddleware from 'eth-json-rpc-middleware/block-ref' import createRetryOnEmptyMiddleware from 'eth-json-rpc-middleware/retryOnEmpty' import createBlockCacheMiddleware from 'eth-json-rpc-middleware/block-cache' diff --git a/app/scripts/controllers/network/createJsonRpcClient.js b/app/scripts/controllers/network/createJsonRpcClient.js index b3c9cb062..cc8e9edc5 100644 --- a/app/scripts/controllers/network/createJsonRpcClient.js +++ b/app/scripts/controllers/network/createJsonRpcClient.js @@ -1,5 +1,4 @@ -import createAsyncMiddleware from 'json-rpc-engine/src/createAsyncMiddleware' -import mergeMiddleware from 'json-rpc-engine/src/mergeMiddleware' +import { createAsyncMiddleware, mergeMiddleware } from 'json-rpc-engine' import createFetchMiddleware from 'eth-json-rpc-middleware/fetch' import createBlockRefRewriteMiddleware from 'eth-json-rpc-middleware/block-ref-rewrite' import createBlockCacheMiddleware from 'eth-json-rpc-middleware/block-cache' diff --git a/app/scripts/controllers/network/createMetamaskMiddleware.js b/app/scripts/controllers/network/createMetamaskMiddleware.js index 1d1291eea..f4e9c5d1a 100644 --- a/app/scripts/controllers/network/createMetamaskMiddleware.js +++ b/app/scripts/controllers/network/createMetamaskMiddleware.js @@ -1,5 +1,4 @@ -import mergeMiddleware from 'json-rpc-engine/src/mergeMiddleware' -import createScaffoldMiddleware from 'json-rpc-engine/src/createScaffoldMiddleware' +import { createScaffoldMiddleware, mergeMiddleware } from 'json-rpc-engine' import createWalletSubprovider from 'eth-json-rpc-middleware/wallet' import { createPendingNonceMiddleware, diff --git a/app/scripts/controllers/network/middleware/pending.js b/app/scripts/controllers/network/middleware/pending.js index fe243ec28..905e44129 100644 --- a/app/scripts/controllers/network/middleware/pending.js +++ b/app/scripts/controllers/network/middleware/pending.js @@ -1,4 +1,4 @@ -import createAsyncMiddleware from 'json-rpc-engine/src/createAsyncMiddleware' +import { createAsyncMiddleware } from 'json-rpc-engine' import { formatTxMetaForRpcResult } from '../util' export function createPendingNonceMiddleware({ getPendingNonce }) { diff --git a/app/scripts/controllers/network/network.js b/app/scripts/controllers/network/network.js index 5527d8628..9b437745f 100644 --- a/app/scripts/controllers/network/network.js +++ b/app/scripts/controllers/network/network.js @@ -2,7 +2,7 @@ import assert from 'assert' import EventEmitter from 'events' import ObservableStore from 'obs-store' import ComposedStore from 'obs-store/lib/composed' -import JsonRpcEngine from 'json-rpc-engine' +import { JsonRpcEngine } from 'json-rpc-engine' import providerFromEngine from 'eth-json-rpc-middleware/providerFromEngine' import log from 'loglevel' import { diff --git a/app/scripts/controllers/permissions/index.js b/app/scripts/controllers/permissions/index.js index dac4eef94..2e3c12775 100644 --- a/app/scripts/controllers/permissions/index.js +++ b/app/scripts/controllers/permissions/index.js @@ -1,6 +1,5 @@ import nanoid from 'nanoid' -import JsonRpcEngine from 'json-rpc-engine' -import asMiddleware from 'json-rpc-engine/src/asMiddleware' +import { JsonRpcEngine } from 'json-rpc-engine' import ObservableStore from 'obs-store' import log from 'loglevel' import { CapabilitiesController as RpcCap } from 'rpc-cap' @@ -109,7 +108,7 @@ export class PermissionsController { }), ) - return asMiddleware(engine) + return engine.asMiddleware() } /** diff --git a/app/scripts/controllers/permissions/permissionsMethodMiddleware.js b/app/scripts/controllers/permissions/permissionsMethodMiddleware.js index eae072495..f2eec6cf4 100644 --- a/app/scripts/controllers/permissions/permissionsMethodMiddleware.js +++ b/app/scripts/controllers/permissions/permissionsMethodMiddleware.js @@ -1,4 +1,4 @@ -import createAsyncMiddleware from 'json-rpc-engine/src/createAsyncMiddleware' +import { createAsyncMiddleware } from 'json-rpc-engine' import { ethErrors } from 'eth-json-rpc-errors' /** diff --git a/app/scripts/controllers/threebox.js b/app/scripts/controllers/threebox.js index 2459d79e2..ec73e2651 100644 --- a/app/scripts/controllers/threebox.js +++ b/app/scripts/controllers/threebox.js @@ -7,7 +7,7 @@ const Box = process.env.IN_TEST /* eslint-enable import/order */ import log from 'loglevel' -import JsonRpcEngine from 'json-rpc-engine' +import { JsonRpcEngine } from 'json-rpc-engine' import providerFromEngine from 'eth-json-rpc-middleware/providerFromEngine' import Migrator from '../lib/migrator' import migrations from '../migrations' diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index bbd2c9d0f..b94c82cdb 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -4,7 +4,7 @@ import pump from 'pump' import Dnode from 'dnode' import ObservableStore from 'obs-store' import asStream from 'obs-store/lib/asStream' -import RpcEngine from 'json-rpc-engine' +import { JsonRpcEngine } from 'json-rpc-engine' import { debounce } from 'lodash' import createEngineStream from 'json-rpc-middleware-stream/engineStream' import createFilterMiddleware from 'eth-json-rpc-filters' @@ -1935,7 +1935,7 @@ export default class MetamaskController extends EventEmitter { isInternal = false, }) { // setup json rpc engine stack - const engine = new RpcEngine() + const engine = new JsonRpcEngine() const { provider, blockTracker } = this // create filter polyfill middleware diff --git a/package.json b/package.json index 2981ea5c5..3a00c26cf 100644 --- a/package.json +++ b/package.json @@ -131,7 +131,7 @@ "fast-json-patch": "^2.0.4", "fuse.js": "^3.2.0", "human-standard-token-abi": "^2.0.0", - "json-rpc-engine": "^5.3.0", + "json-rpc-engine": "^6.1.0", "json-rpc-middleware-stream": "^2.1.1", "jsonschema": "^1.2.4", "localforage": "^1.9.0", diff --git a/test/stub/provider.js b/test/stub/provider.js index 40fd95258..f9bc72977 100644 --- a/test/stub/provider.js +++ b/test/stub/provider.js @@ -1,4 +1,4 @@ -import JsonRpcEngine from 'json-rpc-engine' +import { JsonRpcEngine } from 'json-rpc-engine' import scaffoldMiddleware from 'eth-json-rpc-middleware/scaffold' import providerAsMiddleware from 'eth-json-rpc-middleware/providerAsMiddleware' import GanacheCore from 'ganache-core' diff --git a/test/unit/app/controllers/permissions/permissions-controller-test.js b/test/unit/app/controllers/permissions/permissions-controller-test.js index 5e593f114..5f79bb443 100644 --- a/test/unit/app/controllers/permissions/permissions-controller-test.js +++ b/test/unit/app/controllers/permissions/permissions-controller-test.js @@ -1290,12 +1290,6 @@ describe('permissions controller', function () { }, 'should not throw') assert.equal(typeof middleware, 'function', 'should return function') - - assert.equal( - middleware.name, - 'engineAsMiddleware', - 'function name should be "engineAsMiddleware"', - ) }) it('should create a middleware with extensionId', function () { @@ -1311,12 +1305,6 @@ describe('permissions controller', function () { assert.equal(typeof middleware, 'function', 'should return function') - assert.equal( - middleware.name, - 'engineAsMiddleware', - 'function name should be "engineAsMiddleware"', - ) - const metadataStore = permController.store.getState()[METADATA_STORE_KEY] assert.deepEqual( diff --git a/yarn.lock b/yarn.lock index 166f19ad7..03b749ecb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2146,6 +2146,11 @@ gl-mat4 "1.1.4" gl-vec3 "1.0.3" +"@metamask/safe-event-emitter@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@metamask/safe-event-emitter/-/safe-event-emitter-2.0.0.tgz#af577b477c683fad17c619a78208cede06f9605c" + integrity sha512-/kSXhY692qiV1MXu6EeOZvg5nECLclxNXcKCxJ3cXQgYuRymRHpdx/t7JXfsK+JLjwA1e1c1/SBrlQYpusC29Q== + "@metamask/test-dapp@^4.0.1": version "4.0.1" resolved "https://registry.yarnpkg.com/@metamask/test-dapp/-/test-dapp-4.0.1.tgz#fbc66069687f0502ebb4c6ac0fa7c9862ea6563c" @@ -10160,6 +10165,13 @@ eth-rpc-errors@^4.0.0: dependencies: fast-safe-stringify "^2.0.6" +eth-rpc-errors@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/eth-rpc-errors/-/eth-rpc-errors-4.0.2.tgz#11bc164e25237a679061ac05b7da7537b673d3b7" + integrity sha512-n+Re6Gu8XGyfFy1it0AwbD1x0MUzspQs0D5UiPs1fFPCr6WAwZM+vbIhXheBFrpgosqN9bs5PqlB4Q61U/QytQ== + dependencies: + fast-safe-stringify "^2.0.6" + eth-sig-util@^1.4.0, eth-sig-util@^1.4.2: version "1.4.2" resolved "https://registry.yarnpkg.com/eth-sig-util/-/eth-sig-util-1.4.2.tgz#8d958202c7edbaae839707fba6f09ff327606210" @@ -15472,6 +15484,14 @@ json-rpc-engine@^5.2.0, json-rpc-engine@^5.3.0: eth-rpc-errors "^3.0.0" safe-event-emitter "^1.0.1" +json-rpc-engine@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/json-rpc-engine/-/json-rpc-engine-6.1.0.tgz#bf5ff7d029e1c1bf20cb6c0e9f348dcd8be5a393" + integrity sha512-NEdLrtrq1jUZyfjkr9OCz9EzCNhnRyWtt1PAnvnhwy6e8XETS0Dtc+ZNCO2gvuAoKsIn2+vCSowXTYE4CkgnAQ== + dependencies: + "@metamask/safe-event-emitter" "^2.0.0" + eth-rpc-errors "^4.0.2" + json-rpc-error@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/json-rpc-error/-/json-rpc-error-2.0.0.tgz#a7af9c202838b5e905c7250e547f1aff77258a02" From 5fb2e544d441d1d38420c4e957548fb53eb837fa Mon Sep 17 00:00:00 2001 From: Erik Marks <25517051+rekmarks@users.noreply.github.com> Date: Wed, 2 Dec 2020 12:35:45 -0800 Subject: [PATCH 16/32] Add __isMetaMaskShim__ property to injected web3 (#9972) --- app/scripts/lib/setupWeb3.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/app/scripts/lib/setupWeb3.js b/app/scripts/lib/setupWeb3.js index 8f196a94e..9dc74ddb2 100644 --- a/app/scripts/lib/setupWeb3.js +++ b/app/scripts/lib/setupWeb3.js @@ -27,7 +27,12 @@ export default function setupWeb3(log) { web3.setProvider = function () { log.debug('MetaMask - overrode web3.setProvider') } - log.debug('MetaMask - injected web3') + Object.defineProperty(web3, '__isMetaMaskShim__', { + value: true, + enumerable: false, + configurable: false, + writable: false, + }) Object.defineProperty(window.ethereum, '_web3Ref', { enumerable: false, @@ -180,12 +185,13 @@ export default function setupWeb3(log) { }, }) - Object.defineProperty(global, 'web3', { + Object.defineProperty(window, 'web3', { enumerable: false, writable: true, configurable: true, value: web3Proxy, }) + log.debug('MetaMask - injected web3') window.ethereum._publicConfigStore.subscribe((state) => { // if the auto refresh on network change is false do not @@ -231,7 +237,7 @@ export default function setupWeb3(log) { // reload the page function triggerReset() { - global.location.reload() + window.location.reload() } /** From ba98edf604a1344a5acacdbc0aaefbbc6c93ba60 Mon Sep 17 00:00:00 2001 From: Mark Stacey Date: Wed, 2 Dec 2020 17:27:42 -0330 Subject: [PATCH 17/32] Remove unnecessary assertion in e2e metrics test (#9974) The assertion ensuring that there were at least 3 metrics received didn't end up being useful. If this assertion fails, it doesn't explain what segment events _were_ received. By removing this assertion and letting the later assertions catch this case, we at least learn which of the three expected events were present. --- test/e2e/metrics.spec.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/test/e2e/metrics.spec.js b/test/e2e/metrics.spec.js index e8598b792..ceca2cb64 100644 --- a/test/e2e/metrics.spec.js +++ b/test/e2e/metrics.spec.js @@ -35,10 +35,6 @@ describe('Segment metrics', function () { await driver.findElement(By.css('[data-testid="eth-overview-send"]')) assert.ok(segmentSpy.called, 'Segment should receive metrics') - assert.ok( - segmentSpy.callCount >= 3, - 'At least 3 segment events should be sent', - ) const firstSegmentEvent = segmentSpy.getCall(0).args[0] assert.equal(firstSegmentEvent.name, 'Home') From 673371d0133aad1e1af03bbae7d80e4952c73724 Mon Sep 17 00:00:00 2001 From: David Walsh Date: Wed, 2 Dec 2020 15:27:45 -0600 Subject: [PATCH 18/32] Fix #9872 - Show price difference warning on swaps price quote (#9899) --- app/_locales/en/messages.json | 14 ++ ...-preferenced-currency-display.component.js | 1 - .../pages/swaps/swaps-footer/swaps-footer.js | 4 +- ui/app/pages/swaps/view-quote/index.scss | 56 ++++++- .../tests/view-quote-price-difference.test.js | 149 ++++++++++++++++++ .../view-quote/view-quote-price-difference.js | 114 ++++++++++++++ ui/app/pages/swaps/view-quote/view-quote.js | 34 +++- 7 files changed, 359 insertions(+), 13 deletions(-) create mode 100644 ui/app/pages/swaps/view-quote/tests/view-quote-price-difference.test.js create mode 100644 ui/app/pages/swaps/view-quote/view-quote-price-difference.js diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json index 8a00369f4..a3d5b5f4c 100644 --- a/app/_locales/en/messages.json +++ b/app/_locales/en/messages.json @@ -1741,6 +1741,20 @@ "message": "Your $1 will be added to your account once this transaction has processed.", "description": "This message communicates the token that is being transferred. It is shown on the awaiting swap screen. The $1 will be a token symbol." }, + "swapPriceDifference": { + "message": "You are about to swap $1 $2 (~$3) for $4 $5 (~$6).", + "description": "This message represents the price slippage for the swap. $1 and $4 are a number (ex: 2.89), $2 and $5 are symbols (ex: ETH), and $3 and $6 are fiat currency amounts." + }, + "swapPriceDifferenceTitle": { + "message": "Price difference of ~$1%", + "description": "$1 is a number (ex: 1.23) that represents the price difference." + }, + "swapPriceDifferenceTooltip": { + "message": "The difference in market prices can be affected by fees taken by intermediaries, size of market, size of trade, or market inefficiencies." + }, + "swapPriceDifferenceUnavailable": { + "message": "Market price is unavailable. Make sure you feel comfortable with the returned amount before proceeding." + }, "swapProcessing": { "message": "Processing" }, diff --git a/ui/app/components/app/user-preferenced-currency-display/user-preferenced-currency-display.component.js b/ui/app/components/app/user-preferenced-currency-display/user-preferenced-currency-display.component.js index 208b93197..8496d7ca1 100644 --- a/ui/app/components/app/user-preferenced-currency-display/user-preferenced-currency-display.component.js +++ b/ui/app/components/app/user-preferenced-currency-display/user-preferenced-currency-display.component.js @@ -19,7 +19,6 @@ export default function UserPreferencedCurrencyDisplay({ fiatNumberOfDecimals, numberOfDecimals: propsNumberOfDecimals, }) - const prefixComponent = useMemo(() => { return ( currency === ETH && diff --git a/ui/app/pages/swaps/swaps-footer/swaps-footer.js b/ui/app/pages/swaps/swaps-footer/swaps-footer.js index c158c21fb..870ce028b 100644 --- a/ui/app/pages/swaps/swaps-footer/swaps-footer.js +++ b/ui/app/pages/swaps/swaps-footer/swaps-footer.js @@ -13,13 +13,14 @@ export default function SwapsFooter({ disabled, showTermsOfService, showTopBorder, + className = '', }) { const t = useContext(I18nContext) return (
@@ -62,4 +63,5 @@ SwapsFooter.propTypes = { disabled: PropTypes.bool, showTermsOfService: PropTypes.bool, showTopBorder: PropTypes.bool, + className: PropTypes.string, } diff --git a/ui/app/pages/swaps/view-quote/index.scss b/ui/app/pages/swaps/view-quote/index.scss index 1b76853fb..474eced60 100644 --- a/ui/app/pages/swaps/view-quote/index.scss +++ b/ui/app/pages/swaps/view-quote/index.scss @@ -86,14 +86,60 @@ }; } - &__insufficient-eth-warning-wrapper { - margin-top: 8px; + &__price-difference-warning { + &-wrapper { + width: 100%; + + &.medium .actionable-message, + &.fiat-error .actionable-message { + border-color: $Yellow-500; + background: $Yellow-100; + + .actionable-message__message { + color: inherit; + } + } + + &.high .actionable-message { + border-color: $Red-500; + background: $Red-100; + + .actionable-message__message { + color: $Red-500; + } + } + + /* Hides info tooltip if there's a fiat error message */ + &.fiat-error div[data-tooltipped] { + /* !important overrides style being applied directly to tooltip by component */ + display: none !important; + } + } + + &-contents { + display: flex; + + &-title { + font-weight: bold; + } + + i { + margin-inline-start: 10px; + } + } + } + + &__warning-wrapper { width: 100%; align-items: center; justify-content: center; + margin-top: 8px; @media screen and (min-width: 576px) { - min-height: 36px; + &--thin { + min-height: 36px; + } + display: flex; } } @@ -165,4 +211,8 @@ &__metamask-rate-info-icon { margin-left: 4px; } + + &__thin-swaps-footer { + max-height: 82px; + } } diff --git a/ui/app/pages/swaps/view-quote/tests/view-quote-price-difference.test.js b/ui/app/pages/swaps/view-quote/tests/view-quote-price-difference.test.js new file mode 100644 index 000000000..d32cc5759 --- /dev/null +++ b/ui/app/pages/swaps/view-quote/tests/view-quote-price-difference.test.js @@ -0,0 +1,149 @@ +import assert from 'assert' +import React from 'react' +import { shallow } from 'enzyme' +import { Provider } from 'react-redux' +import configureMockStore from 'redux-mock-store' +import ViewQuotePriceDifference from '../view-quote-price-difference' + +describe('View Price Quote Difference', function () { + const t = (key) => `translate ${key}` + + const state = { + metamask: { + tokens: [], + provider: { type: 'rpc', nickname: '', rpcUrl: '' }, + preferences: { showFiatInTestnets: true }, + currentCurrency: 'usd', + conversionRate: 600.0, + }, + } + + const store = configureMockStore()(state) + + // Sample transaction is 1 $ETH to ~42.880915 $LINK + const DEFAULT_PROPS = { + usedQuote: { + trade: { + data: + '0x5f575529000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000007756e69737761700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca0000000000000000000000000000000000000000000000000dc1a09f859b20000000000000000000000000000000000000000000000000024855454cb32d335f0000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000005fc7b7100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001f161421c8e0000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca', + from: '0xd7440fdcb70a9fba55dfe06942ddbc17679c90ac', + value: '0xde0b6b3a7640000', + gas: '0xbbfd0', + to: '0x881D40237659C251811CEC9c364ef91dC08D300C', + }, + sourceAmount: '1000000000000000000', + destinationAmount: '42947749216634160067', + error: null, + sourceToken: '0x0000000000000000000000000000000000000000', + destinationToken: '0x514910771af9ca656af840dff83e8264ecf986ca', + approvalNeeded: null, + maxGas: 770000, + averageGas: 210546, + estimatedRefund: 80000, + fetchTime: 647, + aggregator: 'uniswap', + aggType: 'DEX', + fee: 0.875, + gasMultiplier: 1.5, + priceSlippage: { + ratio: 1.007876641534847, + calculationError: '', + bucket: 'low', + sourceAmountInETH: 1, + destinationAmountInEth: 0.9921849150875727, + }, + slippage: 2, + sourceTokenInfo: { + symbol: 'ETH', + name: 'Ether', + address: '0x0000000000000000000000000000000000000000', + decimals: 18, + iconUrl: 'images/black-eth-logo.svg', + }, + destinationTokenInfo: { + address: '0x514910771af9ca656af840dff83e8264ecf986ca', + symbol: 'LINK', + decimals: 18, + occurances: 12, + iconUrl: + 'https://cloudflare-ipfs.com/ipfs/QmQhZAdcZvW9T2tPm516yHqbGkfhyZwTZmLixW9MXJudTA', + }, + ethFee: '0.011791', + ethValueOfTokens: '0.99220724791716534441', + overallValueOfQuote: '0.98041624791716534441', + metaMaskFeeInEth: '0.00875844985551091729', + isBestQuote: true, + savings: { + performance: '0.00207907025112527799', + fee: '0.005581', + metaMaskFee: '0.00875844985551091729', + total: '-0.0010983796043856393', + medianMetaMaskFee: '0.00874009740688812165', + }, + }, + sourceTokenValue: '1', + destinationTokenValue: '42.947749', + } + + let component + function renderComponent(props) { + component = shallow( + + + , + { + context: { t }, + }, + ) + } + + afterEach(function () { + component.unmount() + }) + + it('does not render when there is no quote', function () { + const props = { ...DEFAULT_PROPS, usedQuote: null } + renderComponent(props) + + const wrappingDiv = component.find( + '.view-quote__price-difference-warning-wrapper', + ) + assert.strictEqual(wrappingDiv.length, 0) + }) + + it('does not render when the item is in the low bucket', function () { + const props = { ...DEFAULT_PROPS } + props.usedQuote.priceSlippage.bucket = 'low' + + renderComponent(props) + const wrappingDiv = component.find( + '.view-quote__price-difference-warning-wrapper', + ) + assert.strictEqual(wrappingDiv.length, 0) + }) + + it('displays an error when in medium bucket', function () { + const props = { ...DEFAULT_PROPS } + props.usedQuote.priceSlippage.bucket = 'medium' + + renderComponent(props) + assert.strictEqual(component.html().includes('medium'), true) + }) + + it('displays an error when in high bucket', function () { + const props = { ...DEFAULT_PROPS } + props.usedQuote.priceSlippage.bucket = 'high' + + renderComponent(props) + assert.strictEqual(component.html().includes('high'), true) + }) + + it('displays a fiat error when calculationError is present', function () { + const props = { ...DEFAULT_PROPS } + props.usedQuote.priceSlippage.calculationError = + 'Could not determine price.' + + renderComponent(props) + assert.strictEqual(component.html().includes('fiat-error'), true) + }) +}) diff --git a/ui/app/pages/swaps/view-quote/view-quote-price-difference.js b/ui/app/pages/swaps/view-quote/view-quote-price-difference.js new file mode 100644 index 000000000..5a3be3cac --- /dev/null +++ b/ui/app/pages/swaps/view-quote/view-quote-price-difference.js @@ -0,0 +1,114 @@ +import React, { useContext } from 'react' + +import PropTypes from 'prop-types' +import classnames from 'classnames' +import BigNumber from 'bignumber.js' +import { useEthFiatAmount } from '../../../hooks/useEthFiatAmount' +import { I18nContext } from '../../../contexts/i18n' + +import ActionableMessage from '../actionable-message' +import Tooltip from '../../../components/ui/tooltip' + +export default function ViewQuotePriceDifference(props) { + const { usedQuote, sourceTokenValue, destinationTokenValue } = props + + const t = useContext(I18nContext) + + const priceSlippageFromSource = useEthFiatAmount( + usedQuote?.priceSlippage?.sourceAmountInETH || 0, + ) + const priceSlippageFromDestination = useEthFiatAmount( + usedQuote?.priceSlippage?.destinationAmountInEth || 0, + ) + + if (!usedQuote || !usedQuote.priceSlippage) { + return null + } + + const { priceSlippage } = usedQuote + + // We cannot present fiat value if there is a calculation error or no slippage + // from source or destination + const priceSlippageUnknownFiatValue = + !priceSlippageFromSource || + !priceSlippageFromDestination || + priceSlippage.calculationError + + let priceDifferencePercentage = 0 + if (priceSlippage.ratio) { + priceDifferencePercentage = parseFloat( + new BigNumber(priceSlippage.ratio, 10) + .minus(1, 10) + .times(100, 10) + .toFixed(2), + 10, + ) + } + + const shouldShowPriceDifferenceWarning = + ['high', 'medium'].includes(priceSlippage.bucket) || + priceSlippageUnknownFiatValue + + if (!shouldShowPriceDifferenceWarning) { + return null + } + + let priceDifferenceTitle = '' + let priceDifferenceMessage = '' + let priceDifferenceClass = '' + if (priceSlippageUnknownFiatValue) { + // A calculation error signals we cannot determine dollar value + priceDifferenceMessage = t('swapPriceDifferenceUnavailable') + priceDifferenceClass = 'fiat-error' + } else { + priceDifferenceTitle = t('swapPriceDifferenceTitle', [ + priceDifferencePercentage, + ]) + priceDifferenceMessage = t('swapPriceDifference', [ + sourceTokenValue, // Number of source token to swap + usedQuote.sourceTokenInfo.symbol, // Source token symbol + priceSlippageFromSource, // Source tokens total value + destinationTokenValue, // Number of destination tokens in return + usedQuote.destinationTokenInfo.symbol, // Destination token symbol, + priceSlippageFromDestination, // Destination tokens total value + ]) + priceDifferenceClass = priceSlippage.bucket + } + + return ( +
+ +
+ {priceDifferenceTitle && ( +
+ {priceDifferenceTitle} +
+ )} + {priceDifferenceMessage} +
+ + + +
+ } + /> +
+ ) +} + +ViewQuotePriceDifference.propTypes = { + usedQuote: PropTypes.object, + sourceTokenValue: PropTypes.string, + destinationTokenValue: PropTypes.string, +} diff --git a/ui/app/pages/swaps/view-quote/view-quote.js b/ui/app/pages/swaps/view-quote/view-quote.js index 8528a38b3..4db97824f 100644 --- a/ui/app/pages/swaps/view-quote/view-quote.js +++ b/ui/app/pages/swaps/view-quote/view-quote.js @@ -74,6 +74,7 @@ import { QUOTES_EXPIRED_ERROR } from '../../../helpers/constants/swaps' import CountdownTimer from '../countdown-timer' import SwapsFooter from '../swaps-footer' import InfoTooltip from '../../../components/ui/info-tooltip' +import ViewQuotePriceDifference from './view-quote-price-difference' export default function ViewQuote() { const history = useHistory() @@ -279,7 +280,7 @@ export default function ViewQuote() { } }, [originalApproveAmount, approveAmount]) - const showWarning = + const showInsufficientWarning = (balanceError || tokenBalanceNeeded || ethBalanceNeeded) && !warningHidden const numberOfQuotes = Object.values(quotes).length @@ -452,7 +453,7 @@ export default function ViewQuote() { ) - const actionableMessage = t('swapApproveNeedMoreTokens', [ + const actionableInsufficientMessage = t('swapApproveNeedMoreTokens', [ {tokenBalanceNeeded || ethBalanceNeeded} , @@ -461,6 +462,17 @@ export default function ViewQuote() { : 'ETH', ]) + const viewQuotePriceDifferenceComponent = ( + + ) + + const isShowingWarning = + showInsufficientWarning || viewQuotePriceDifferenceComponent !== null + return (
@@ -474,17 +486,22 @@ export default function ViewQuote() { onQuoteDetailsIsOpened={quoteDetailsOpened} /> )} -
- {showWarning && ( +
+ {!showInsufficientWarning && viewQuotePriceDifferenceComponent} + {showInsufficientWarning && ( setWarningHidden(true)} /> )}
await dispatch(navigateBackToBuildQuote(history))} disabled={balanceError || gasPrice === null || gasPrice === undefined} + className={isShowingWarning && 'view-quote__thin-swaps-footer'} showTermsOfService showTopBorder /> From 0653a489b0abe90ab9f8d393d9b072add8ef17dc Mon Sep 17 00:00:00 2001 From: Brad Decker Date: Wed, 2 Dec 2020 15:41:30 -0600 Subject: [PATCH 19/32] add new MetaMetricsController (#9857) --- app/scripts/controllers/metametrics.js | 366 ++++++++++++ app/scripts/controllers/network/network.js | 5 + app/scripts/controllers/preferences.js | 38 +- app/scripts/controllers/transactions/index.js | 18 +- .../handlers/log-web3-usage.js | 16 +- app/scripts/lib/segment.js | 101 ++++ app/scripts/metamask-controller.js | 96 +-- app/scripts/migrations/049.js | 44 ++ app/scripts/migrations/index.js | 1 + shared/constants/metametrics.js | 140 +++++ shared/modules/README.md | 3 + shared/modules/metametrics.js | 302 ---------- .../controllers/metamask-controller-test.js | 3 +- test/unit/app/controllers/metametrics-test.js | 546 ++++++++++++++++++ test/unit/migrations/049-test.js | 132 +++++ test/unit/ui/app/actions.spec.js | 1 + ui/app/contexts/metametrics.js | 127 ++-- ui/app/contexts/metametrics.new.js | 211 +++---- ui/app/ducks/swaps/swaps.js | 31 +- ui/app/hooks/useMetricEvent.js | 29 +- .../metametrics-opt-in.component.js | 3 + ui/app/store/actions.js | 26 + 22 files changed, 1595 insertions(+), 644 deletions(-) create mode 100644 app/scripts/controllers/metametrics.js create mode 100644 app/scripts/lib/segment.js create mode 100644 app/scripts/migrations/049.js create mode 100644 shared/constants/metametrics.js create mode 100644 shared/modules/README.md delete mode 100644 shared/modules/metametrics.js create mode 100644 test/unit/app/controllers/metametrics-test.js create mode 100644 test/unit/migrations/049-test.js diff --git a/app/scripts/controllers/metametrics.js b/app/scripts/controllers/metametrics.js new file mode 100644 index 000000000..810b55276 --- /dev/null +++ b/app/scripts/controllers/metametrics.js @@ -0,0 +1,366 @@ +import { merge, omit } from 'lodash' +import ObservableStore from 'obs-store' +import { bufferToHex, sha3 } from 'ethereumjs-util' +import { ENVIRONMENT_TYPE_BACKGROUND } from '../lib/enums' +import { + METAMETRICS_ANONYMOUS_ID, + METAMETRICS_BACKGROUND_PAGE_OBJECT, +} from '../../../shared/constants/metametrics' + +/** + * Used to determine whether or not to attach a user's metametrics id + * to events that include on-chain data. This helps to prevent identifying + * a user by being able to trace their activity on etherscan/block exploring + */ +const trackableSendCounts = { + 1: true, + 10: true, + 30: true, + 50: true, + 100: true, + 250: true, + 500: true, + 1000: true, + 2500: true, + 5000: true, + 10000: true, + 25000: true, +} + +export function sendCountIsTrackable(sendCount) { + return Boolean(trackableSendCounts[sendCount]) +} + +/** + * @typedef {import('../../../shared/constants/metametrics').MetaMetricsContext} MetaMetricsContext + * @typedef {import('../../../shared/constants/metametrics').MetaMetricsEventPayload} MetaMetricsEventPayload + * @typedef {import('../../../shared/constants/metametrics').MetaMetricsEventOptions} MetaMetricsEventOptions + * @typedef {import('../../../shared/constants/metametrics').SegmentEventPayload} SegmentEventPayload + * @typedef {import('../../../shared/constants/metametrics').SegmentInterface} SegmentInterface + * @typedef {import('../../../shared/constants/metametrics').MetaMetricsPagePayload} MetaMetricsPagePayload + * @typedef {import('../../../shared/constants/metametrics').MetaMetricsPageOptions} MetaMetricsPageOptions + */ + +/** + * @typedef {Object} MetaMetricsControllerState + * @property {?string} metaMetricsId - The user's metaMetricsId that will be + * attached to all non-anonymized event payloads + * @property {?boolean} participateInMetaMetrics - The user's preference for + * participating in the MetaMetrics analytics program. This setting controls + * whether or not events are tracked + * @property {number} metaMetricsSendCount - How many send transactions have + * been tracked through this controller. Used to prevent attaching sensitive + * data that can be traced through on chain data. + */ + +export default class MetaMetricsController { + /** + * @param {Object} segment - an instance of analytics-node for tracking + * events that conform to the new MetaMetrics tracking plan. + * @param {Object} segmentLegacy - an instance of analytics-node for + * tracking legacy schema events. Will eventually be phased out + * @param {Object} preferencesStore - The preferences controller store, used + * to access and subscribe to preferences that will be attached to events + * @param {function} onNetworkDidChange - Used to attach a listener to the + * networkDidChange event emitted by the networkController + * @param {function} getCurrentChainId - Gets the current chain id from the + * network controller + * @param {function} getNetworkIdentifier - Gets the current network + * identifier from the network controller + * @param {string} version - The version of the extension + * @param {string} environment - The environment the extension is running in + * @param {MetaMetricsControllerState} initState - State to initialized with + */ + constructor({ + segment, + segmentLegacy, + preferencesStore, + onNetworkDidChange, + getCurrentChainId, + getNetworkIdentifier, + version, + environment, + initState, + }) { + const prefState = preferencesStore.getState() + this.chainId = getCurrentChainId() + this.network = getNetworkIdentifier() + this.locale = prefState.currentLocale.replace('_', '-') + this.version = + environment === 'production' ? version : `${version}-${environment}` + + this.store = new ObservableStore({ + participateInMetaMetrics: null, + metaMetricsId: null, + metaMetricsSendCount: 0, + ...initState, + }) + + preferencesStore.subscribe(({ currentLocale }) => { + this.locale = currentLocale.replace('_', '-') + }) + + onNetworkDidChange(() => { + this.chainId = getCurrentChainId() + this.network = getNetworkIdentifier() + }) + this.segment = segment + this.segmentLegacy = segmentLegacy + } + + generateMetaMetricsId() { + return bufferToHex( + sha3( + String(Date.now()) + + String(Math.round(Math.random() * Number.MAX_SAFE_INTEGER)), + ), + ) + } + + /** + * Setter for the `participateInMetaMetrics` property + * + * @param {boolean} participateInMetaMetrics - Whether or not the user wants + * to participate in MetaMetrics + * @returns {string|null} the string of the new metametrics id, or null + * if not set + */ + setParticipateInMetaMetrics(participateInMetaMetrics) { + let { metaMetricsId } = this.state + if (participateInMetaMetrics && !metaMetricsId) { + metaMetricsId = this.generateMetaMetricsId() + } else if (participateInMetaMetrics === false) { + metaMetricsId = null + } + this.store.updateState({ participateInMetaMetrics, metaMetricsId }) + return metaMetricsId + } + + get state() { + return this.store.getState() + } + + setMetaMetricsSendCount(val) { + this.store.updateState({ metaMetricsSendCount: val }) + } + + /** + * Build the context object to attach to page and track events. + * @private + * @param {Pick} [referrer] - dapp origin that initialized + * the notification window. + * @param {Pick} [page] - page object describing the current + * view of the extension. Defaults to the background-process object. + * @returns {MetaMetricsContext} + */ + _buildContext(referrer, page = METAMETRICS_BACKGROUND_PAGE_OBJECT) { + return { + app: { + name: 'MetaMask Extension', + version: this.version, + }, + userAgent: window.navigator.userAgent, + page, + referrer, + } + } + + /** + * Build's the event payload, processing all fields into a format that can be + * fed to Segment's track method + * @private + * @param { + * Omit + * } rawPayload - raw payload provided to trackEvent + * @returns {SegmentEventPayload} - formatted event payload for segment + */ + _buildEventPayload(rawPayload) { + const { + event, + properties, + revenue, + value, + currency, + category, + page, + referrer, + environmentType = ENVIRONMENT_TYPE_BACKGROUND, + } = rawPayload + return { + event, + properties: { + // These values are omitted from properties because they have special meaning + // in segment. https://segment.com/docs/connections/spec/track/#properties. + // to avoid accidentally using these inappropriately, you must add them as top + // level properties on the event payload. We also exclude locale to prevent consumers + // from overwriting this context level property. We track it as a property + // because not all destinations map locale from context. + ...omit(properties, ['revenue', 'locale', 'currency', 'value']), + revenue, + value, + currency, + category, + network: this.network, + locale: this.locale, + chain_id: this.chainId, + environment_type: environmentType, + }, + context: this._buildContext(referrer, page), + } + } + + /** + * Perform validation on the payload and update the id type to use before + * sending to Segment. Also examines the options to route and handle the + * event appropriately. + * @private + * @param {SegmentEventPayload} payload - properties to attach to event + * @param {MetaMetricsEventOptions} options - options for routing and + * handling the event + * @returns {Promise} + */ + _track(payload, options) { + const { + isOptIn, + metaMetricsId: metaMetricsIdOverride, + matomoEvent, + flushImmediately, + } = options + let idType = 'userId' + let idValue = this.state.metaMetricsId + let excludeMetaMetricsId = options.excludeMetaMetricsId ?? false + // This is carried over from the old implementation, and will likely need + // to be updated to work with the new tracking plan. I think we should use + // a config setting for this instead of trying to match the event name + const isSendFlow = Boolean(payload.event.match(/^send|^confirm/iu)) + if ( + isSendFlow && + this.state.metaMetricsSendCount && + !sendCountIsTrackable(this.state.metaMetricsSendCount + 1) + ) { + excludeMetaMetricsId = true + } + // If we are tracking sensitive data we will always use the anonymousId + // property as well as our METAMETRICS_ANONYMOUS_ID. This prevents us from + // associating potentially identifiable information with a specific id. + // During the opt in flow we will track all events, but do so with the + // anonymous id. The one exception to that rule is after the user opts in + // to MetaMetrics. When that happens we receive back the user's new + // MetaMetrics id before it is fully persisted to state. To avoid a race + // condition we explicitly pass the new id to the track method. In that + // case we will track the opt in event to the user's id. In all other cases + // we use the metaMetricsId from state. + if (excludeMetaMetricsId || (isOptIn && !metaMetricsIdOverride)) { + idType = 'anonymousId' + idValue = METAMETRICS_ANONYMOUS_ID + } else if (isOptIn && metaMetricsIdOverride) { + idValue = metaMetricsIdOverride + } + payload[idType] = idValue + + // Promises will only resolve when the event is sent to segment. For any + // event that relies on this promise being fulfilled before performing UI + // updates, or otherwise delaying user interaction, supply the + // 'flushImmediately' flag to the trackEvent method. + return new Promise((resolve, reject) => { + const callback = (err) => { + if (err) { + return reject(err) + } + return resolve() + } + + const target = matomoEvent === true ? this.segmentLegacy : this.segment + + target.track(payload, callback) + if (flushImmediately) { + target.flush() + } + }) + } + + /** + * track a page view with Segment + * @param {MetaMetricsPagePayload} payload - details of the page viewed + * @param {MetaMetricsPageOptions} options - options for handling the page + * view + */ + trackPage({ name, params, environmentType, page, referrer }, options = {}) { + if (this.state.participateInMetaMetrics === false) { + return + } + + if (this.state.participateInMetaMetrics === null && !options.isOptInPath) { + return + } + const { metaMetricsId } = this.state + const idTrait = metaMetricsId ? 'userId' : 'anonymousId' + const idValue = metaMetricsId ?? METAMETRICS_ANONYMOUS_ID + this.segment.page({ + [idTrait]: idValue, + name, + properties: { + params, + locale: this.locale, + network: this.network, + chain_id: this.chainId, + environment_type: environmentType, + }, + context: this._buildContext(referrer, page), + }) + } + + /** + * track a metametrics event, performing necessary payload manipulation and + * routing the event to the appropriate segment source. Will split events + * with sensitiveProperties into two events, tracking the sensitiveProperties + * with the anonymousId only. + * @param {MetaMetricsEventPayload} payload - details of the event + * @param {MetaMetricsEventOptions} options - options for handling/routing the event + * @returns {Promise} + */ + async trackEvent(payload, options = {}) { + // event and category are required fields for all payloads + if (!payload.event || !payload.category) { + throw new Error('Must specify event and category.') + } + + if (!this.state.participateInMetaMetrics && !options.isOptIn) { + return + } + + // We might track multiple events if sensitiveProperties is included, this array will hold + // the promises returned from this._track. + const events = [] + + if (payload.sensitiveProperties) { + // sensitiveProperties will only be tracked using the anonymousId property and generic id + // If the event options already specify to exclude the metaMetricsId we throw an error as + // a signal to the developer that the event was implemented incorrectly + if (options.excludeMetaMetricsId === true) { + throw new Error( + 'sensitiveProperties was specified in an event payload that also set the excludeMetaMetricsId flag', + ) + } + + const combinedProperties = merge( + payload.sensitiveProperties, + payload.properties, + ) + + events.push( + this._track( + this._buildEventPayload({ + ...payload, + properties: combinedProperties, + }), + { ...options, excludeMetaMetricsId: true }, + ), + ) + } + + events.push(this._track(this._buildEventPayload(payload), options)) + + await Promise.all(events) + } +} diff --git a/app/scripts/controllers/network/network.js b/app/scripts/controllers/network/network.js index 9b437745f..016331bce 100644 --- a/app/scripts/controllers/network/network.js +++ b/app/scripts/controllers/network/network.js @@ -195,6 +195,11 @@ export default class NetworkController extends EventEmitter { return this.providerStore.getState() } + getNetworkIdentifier() { + const provider = this.providerStore.getState() + return provider.type === 'rpc' ? provider.rpcUrl : provider.type + } + // // Private // diff --git a/app/scripts/controllers/preferences.js b/app/scripts/controllers/preferences.js index c7bc88f0b..d521f613d 100644 --- a/app/scripts/controllers/preferences.js +++ b/app/scripts/controllers/preferences.js @@ -2,7 +2,7 @@ import { strict as assert } from 'assert' import ObservableStore from 'obs-store' import { ethErrors } from 'eth-json-rpc-errors' import { normalize as normalizeAddress } from 'eth-sig-util' -import { isValidAddress, sha3, bufferToHex } from 'ethereumjs-util' +import { isValidAddress } from 'ethereumjs-util' import ethers from 'ethers' import log from 'loglevel' import { isPrefixedFormattedHexString } from '../lib/util' @@ -50,7 +50,6 @@ export default class PreferencesController { transactionTime: false, }, knownMethodData: {}, - participateInMetaMetrics: null, firstTimeFlowType: null, currentLocale: opts.initLangCode, identities: {}, @@ -62,9 +61,6 @@ export default class PreferencesController { useNativeCurrencyAsPrimaryCurrency: true, }, completedOnboarding: false, - metaMetricsId: null, - metaMetricsSendCount: 0, - // ENS decentralized website resolution ipfsGateway: 'dweb.link', ...opts.initState, @@ -121,38 +117,6 @@ export default class PreferencesController { this.store.updateState({ usePhishDetect: val }) } - /** - * Setter for the `participateInMetaMetrics` property - * - * @param {boolean} bool - Whether or not the user wants to participate in MetaMetrics - * @returns {string|null} the string of the new metametrics id, or null if not set - * - */ - setParticipateInMetaMetrics(bool) { - this.store.updateState({ participateInMetaMetrics: bool }) - let metaMetricsId = null - if (bool && !this.store.getState().metaMetricsId) { - metaMetricsId = bufferToHex( - sha3( - String(Date.now()) + - String(Math.round(Math.random() * Number.MAX_SAFE_INTEGER)), - ), - ) - this.store.updateState({ metaMetricsId }) - } else if (bool === false) { - this.store.updateState({ metaMetricsId }) - } - return metaMetricsId - } - - getParticipateInMetaMetrics() { - return this.store.getState().participateInMetaMetrics - } - - setMetaMetricsSendCount(val) { - this.store.updateState({ metaMetricsSendCount: val }) - } - /** * Setter for the `firstTimeFlowType` property * diff --git a/app/scripts/controllers/transactions/index.js b/app/scripts/controllers/transactions/index.js index c905c3e1c..0c6f3c6ac 100644 --- a/app/scripts/controllers/transactions/index.js +++ b/app/scripts/controllers/transactions/index.js @@ -929,15 +929,8 @@ export default class TransactionController extends EventEmitter { if (txMeta.txReceipt.status === '0x0') { this._trackMetaMetricsEvent({ event: 'Swap Failed', + sensitiveProperties: { ...txMeta.swapMetaData }, category: 'swaps', - excludeMetaMetricsId: false, - }) - - this._trackMetaMetricsEvent({ - event: 'Swap Failed', - properties: { ...txMeta.swapMetaData }, - category: 'swaps', - excludeMetaMetricsId: true, }) } else { const tokensReceived = getSwapsTokensReceivedFromTxMeta( @@ -965,19 +958,12 @@ export default class TransactionController extends EventEmitter { this._trackMetaMetricsEvent({ event: 'Swap Completed', category: 'swaps', - excludeMetaMetricsId: false, - }) - - this._trackMetaMetricsEvent({ - event: 'Swap Completed', - category: 'swaps', - properties: { + sensitiveProperties: { ...txMeta.swapMetaData, token_to_amount_received: tokensReceived, quote_vs_executionRatio: quoteVsExecutionRatio, estimated_vs_used_gasRatio: estimatedVsUsedGasRatio, }, - excludeMetaMetricsId: true, }) } } diff --git a/app/scripts/lib/rpc-method-middleware/handlers/log-web3-usage.js b/app/scripts/lib/rpc-method-middleware/handlers/log-web3-usage.js index 44bb3a2ca..c80303223 100644 --- a/app/scripts/lib/rpc-method-middleware/handlers/log-web3-usage.js +++ b/app/scripts/lib/rpc-method-middleware/handlers/log-web3-usage.js @@ -43,17 +43,19 @@ function logWeb3UsageHandler(req, res, _next, end, { origin, sendMetrics }) { if (!recordedWeb3Usage[origin][path]) { recordedWeb3Usage[origin][path] = true - sendMetrics({ - event: `Website Used window.web3`, - category: 'inpage_provider', - properties: { action, web3Path: path }, - eventContext: { + sendMetrics( + { + event: `Website Used window.web3`, + category: 'inpage_provider', + properties: { action, web3Path: path }, referrer: { url: origin, }, }, - excludeMetaMetricsId: true, - }) + { + excludeMetaMetricsId: true, + }, + ) } res.result = true diff --git a/app/scripts/lib/segment.js b/app/scripts/lib/segment.js new file mode 100644 index 000000000..e5b67ab18 --- /dev/null +++ b/app/scripts/lib/segment.js @@ -0,0 +1,101 @@ +import Analytics from 'analytics-node' + +const isDevOrTestEnvironment = Boolean( + process.env.METAMASK_DEBUG || process.env.IN_TEST, +) +const SEGMENT_WRITE_KEY = process.env.SEGMENT_WRITE_KEY ?? null +const SEGMENT_LEGACY_WRITE_KEY = process.env.SEGMENT_LEGACY_WRITE_KEY ?? null +const SEGMENT_HOST = process.env.SEGMENT_HOST ?? null + +// flushAt controls how many events are sent to segment at once. Segment will +// hold onto a queue of events until it hits this number, then it sends them as +// a batch. This setting defaults to 20, but in development we likely want to +// see events in real time for debugging, so this is set to 1 to disable the +// queueing mechanism. +const SEGMENT_FLUSH_AT = + process.env.METAMASK_ENVIRONMENT === 'production' ? undefined : 1 + +// flushInterval controls how frequently the queue is flushed to segment. +// This happens regardless of the size of the queue. The default setting is +// 10,000ms (10 seconds). This default is rather high, though thankfully +// using the background process as our event handler means we don't have to +// deal with short lived sessions that happen faster than the interval +// e.g confirmations. This is set to 5,000ms (5 seconds) arbitrarily with the +// intent of having a value less than 10 seconds. +const SEGMENT_FLUSH_INTERVAL = 5000 + +/** + * Creates a mock segment module for usage in test environments. This is used + * when building the application in test mode to catch event calls and prevent + * them from being sent to segment. It is also used in unit tests to mock and + * spy on the methods to ensure proper behavior + * @param {number} flushAt - number of events to queue before sending to segment + * @param {number} flushInterval - ms interval to flush queue and send to segment + * @returns {SegmentInterface} + */ +export const createSegmentMock = ( + flushAt = SEGMENT_FLUSH_AT, + flushInterval = SEGMENT_FLUSH_INTERVAL, +) => { + const segmentMock = { + // Internal queue to keep track of events and properly mimic segment's + // queueing behavior. + queue: [], + + /** + * Used to immediately send all queued events and reset the queue to zero. + * For our purposes this simply triggers the callback method registered with + * the event. + */ + flush() { + segmentMock.queue.forEach(([_, callback]) => { + callback() + }) + segmentMock.queue = [] + }, + + /** + * Track an event and add it to the queue. If the queue size reaches the + * flushAt threshold, flush the queue. + */ + track(payload, callback = () => undefined) { + segmentMock.queue.push([payload, callback]) + + if (segmentMock.queue.length >= flushAt) { + segmentMock.flush() + } + }, + + /** + * A true NOOP, these methods are either not used or do not await callback + * and therefore require no functionality. + */ + page() { + // noop + }, + identify() { + // noop + }, + } + // Mimic the flushInterval behavior with an interval + setInterval(segmentMock.flush, flushInterval) + return segmentMock +} + +export const segment = + !SEGMENT_WRITE_KEY || (isDevOrTestEnvironment && !SEGMENT_HOST) + ? createSegmentMock(SEGMENT_FLUSH_AT, SEGMENT_FLUSH_INTERVAL) + : new Analytics(SEGMENT_WRITE_KEY, { + host: SEGMENT_HOST, + flushAt: SEGMENT_FLUSH_AT, + flushInterval: SEGMENT_FLUSH_INTERVAL, + }) + +export const segmentLegacy = + !SEGMENT_LEGACY_WRITE_KEY || (isDevOrTestEnvironment && !SEGMENT_HOST) + ? createSegmentMock(SEGMENT_FLUSH_AT, SEGMENT_FLUSH_INTERVAL) + : new Analytics(SEGMENT_LEGACY_WRITE_KEY, { + host: SEGMENT_HOST, + flushAt: SEGMENT_FLUSH_AT, + flushInterval: SEGMENT_FLUSH_INTERVAL, + }) diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index b94c82cdb..a7517c5db 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -24,7 +24,6 @@ import { CurrencyRateController, PhishingController, } from '@metamask/controllers' -import { getTrackMetaMetricsEvent } from '../../shared/modules/metametrics' import { getBackgroundMetaMetricState } from '../../ui/app/selectors' import { TRANSACTION_STATUSES } from '../../shared/constants/transaction' import ComposableObservableStore from './lib/ComposableObservableStore' @@ -58,7 +57,8 @@ import getRestrictedMethods from './controllers/permissions/restrictedMethods' import nodeify from './lib/nodeify' import accountImporter from './account-import-strategies' import seedPhraseVerifier from './lib/seed-phrase-verifier' -import { ENVIRONMENT_TYPE_BACKGROUND } from './lib/enums' +import MetaMetricsController from './controllers/metametrics' +import { segment, segmentLegacy } from './lib/segment' export default class MetamaskController extends EventEmitter { /** @@ -115,35 +115,24 @@ export default class MetamaskController extends EventEmitter { migrateAddressBookState: this.migrateAddressBookState.bind(this), }) - this.trackMetaMetricsEvent = getTrackMetaMetricsEvent( - this.platform.getVersion(), - () => { - const participateInMetaMetrics = this.preferencesController.getParticipateInMetaMetrics() - const { - currentLocale, - metaMetricsId, - } = this.preferencesController.store.getState() - const chainId = this.networkController.getCurrentChainId() - const provider = this.networkController.getProviderConfig() - const network = - provider.type === 'rpc' ? provider.rpcUrl : provider.type - return { - participateInMetaMetrics, - metaMetricsId, - environmentType: ENVIRONMENT_TYPE_BACKGROUND, - chainId, - network, - context: { - page: { - path: '/background-process', - title: 'Background Process', - url: '/background-process', - }, - locale: currentLocale.replace('_', '-'), - }, - } - }, - ) + this.metaMetricsController = new MetaMetricsController({ + segment, + segmentLegacy, + preferencesStore: this.preferencesController.store, + onNetworkDidChange: this.networkController.on.bind( + this.networkController, + 'networkDidChange', + ), + getNetworkIdentifier: this.networkController.getNetworkIdentifier.bind( + this.networkController, + ), + getCurrentChainId: this.networkController.getCurrentChainId.bind( + this.networkController, + ), + version: this.platform.getVersion(), + environment: process.env.METAMASK_ENVIRONMENT, + initState: initState.MetaMetricsController, + }) this.appStateController = new AppStateController({ addUnlockListener: this.on.bind(this, 'unlock'), @@ -298,9 +287,9 @@ export default class MetamaskController extends EventEmitter { ), provider: this.provider, blockTracker: this.blockTracker, - trackMetaMetricsEvent: this.trackMetaMetricsEvent, + trackMetaMetricsEvent: this.metaMetricsController.trackEvent, getParticipateInMetrics: () => - this.preferencesController.getParticipateInMetaMetrics(), + this.metaMetricsController.state.participateInMetaMetrics, }) this.txController.on('newUnapprovedTx', () => opts.showUserConfirmation()) @@ -362,6 +351,7 @@ export default class MetamaskController extends EventEmitter { TransactionController: this.txController.store, KeyringController: this.keyringController.store, PreferencesController: this.preferencesController.store, + MetaMetricsController: this.metaMetricsController.store, AddressBookController: this.addressBookController, CurrencyController: this.currencyRateController, NetworkController: this.networkController.store, @@ -388,6 +378,7 @@ export default class MetamaskController extends EventEmitter { TypesMessageManager: this.typedMessageManager.memStore, KeyringController: this.keyringController.memStore, PreferencesController: this.preferencesController.store, + MetaMetricsController: this.metaMetricsController.store, AddressBookController: this.addressBookController, CurrencyController: this.currencyRateController, AlertController: this.alertController.store, @@ -528,6 +519,7 @@ export default class MetamaskController extends EventEmitter { threeBoxController, txController, swapsController, + metaMetricsController, } = this return { @@ -825,6 +817,16 @@ export default class MetamaskController extends EventEmitter { swapsController.setSwapsLiveness, swapsController, ), + + // MetaMetrics + trackMetaMetricsEvent: nodeify( + metaMetricsController.trackEvent, + metaMetricsController, + ), + trackMetaMetricsPage: nodeify( + metaMetricsController.trackPage, + metaMetricsController, + ), } } @@ -1967,7 +1969,7 @@ export default class MetamaskController extends EventEmitter { engine.push( createMethodMiddleware({ origin, - sendMetrics: this.trackMetaMetricsEvent, + sendMetrics: this.metaMetricsController.trackEvent, handleWatchAssetRequest: this.preferencesController.requestWatchAsset.bind( this.preferencesController, ), @@ -2177,16 +2179,20 @@ export default class MetamaskController extends EventEmitter { metamask: metamaskState, }) - this.trackMetaMetricsEvent({ - event: name, - category: 'Background', - matomoEvent: true, - properties: { - action, - ...additionalProperties, - ...customVariables, + this.metaMetricsController.trackEvent( + { + event: name, + category: 'Background', + properties: { + action, + ...additionalProperties, + ...customVariables, + }, }, - }) + { + matomoEvent: true, + }, + ) } /** @@ -2421,7 +2427,7 @@ export default class MetamaskController extends EventEmitter { */ setParticipateInMetaMetrics(bool, cb) { try { - const metaMetricsId = this.preferencesController.setParticipateInMetaMetrics( + const metaMetricsId = this.metaMetricsController.setParticipateInMetaMetrics( bool, ) cb(null, metaMetricsId) @@ -2435,7 +2441,7 @@ export default class MetamaskController extends EventEmitter { setMetaMetricsSendCount(val, cb) { try { - this.preferencesController.setMetaMetricsSendCount(val) + this.metaMetricsController.setMetaMetricsSendCount(val) cb(null) return } catch (err) { diff --git a/app/scripts/migrations/049.js b/app/scripts/migrations/049.js new file mode 100644 index 000000000..6a9b6ea43 --- /dev/null +++ b/app/scripts/migrations/049.js @@ -0,0 +1,44 @@ +import { cloneDeep } from 'lodash' + +const version = 49 + +/** + * Migrate metaMetrics state to the new MetaMetrics controller + */ +export default { + version, + async migrate(originalVersionedData) { + const versionedData = cloneDeep(originalVersionedData) + versionedData.meta.version = version + const state = versionedData.data + versionedData.data = transformState(state) + return versionedData + }, +} + +function transformState(state = {}) { + if (state.PreferencesController) { + const { + metaMetricsId, + participateInMetaMetrics, + metaMetricsSendCount, + } = state.PreferencesController + state.MetaMetricsController = state.MetaMetricsController ?? {} + + if (metaMetricsId !== undefined) { + state.MetaMetricsController.metaMetricsId = metaMetricsId + delete state.PreferencesController.metaMetricsId + } + + if (participateInMetaMetrics !== undefined) { + state.MetaMetricsController.participateInMetaMetrics = participateInMetaMetrics + delete state.PreferencesController.participateInMetaMetrics + } + + if (metaMetricsSendCount !== undefined) { + state.MetaMetricsController.metaMetricsSendCount = metaMetricsSendCount + delete state.PreferencesController.metaMetricsSendCount + } + } + return state +} diff --git a/app/scripts/migrations/index.js b/app/scripts/migrations/index.js index b10848db1..007a5ae06 100644 --- a/app/scripts/migrations/index.js +++ b/app/scripts/migrations/index.js @@ -53,6 +53,7 @@ const migrations = [ require('./046').default, require('./047').default, require('./048').default, + require('./049').default, ] export default migrations diff --git a/shared/constants/metametrics.js b/shared/constants/metametrics.js new file mode 100644 index 000000000..7bd2c4c5e --- /dev/null +++ b/shared/constants/metametrics.js @@ -0,0 +1,140 @@ +// Type Imports +/** + * @typedef {import('../../app/scripts/lib/enums').EnvironmentType} EnvironmentType + */ + +// Type Declarations +/** + * Used to attach context of where the user was at in the application when the + * event was triggered. Also included as full details of the current page in + * page events. + * @typedef {Object} MetaMetricsPageObject + * @property {string} [path] - the path of the current page (e.g /home) + * @property {string} [title] - the title of the current page (e.g 'home') + * @property {string} [url] - the fully qualified url of the current page + */ + +/** + * For metamask, this is the dapp that triggered an interaction + * @typedef {Object} MetaMetricsReferrerObject + * @property {string} [url] - the origin of the dapp issuing the + * notification + */ + +/** + * We attach context to every meta metrics event that help to qualify our + * analytics. This type has all optional values because it represents a + * returned object from a method call. Ideally app and userAgent are + * defined on every event. This is confirmed in the getTrackMetaMetricsEvent + * function, but still provides the consumer a way to override these values if + * necessary. + * @typedef {Object} MetaMetricsContext + * @property {Object} app + * @property {string} app.name - the name of the application tracking the event + * @property {string} app.version - the version of the application + * @property {string} userAgent - the useragent string of the user + * @property {MetaMetricsPageObject} [page] - an object representing details of + * the current page + * @property {MetaMetricsReferrerObject} [referrer] - for metamask, this is the + * dapp that triggered an interaction + */ + +/** + * @typedef {Object} MetaMetricsEventPayload + * @property {string} event - event name to track + * @property {string} category - category to associate event to + * @property {string} [environmentType] - The type of environment this event + * occurred in. Defaults to the background process type + * @property {object} [properties] - object of custom values to track, keys + * in this object must be in snake_case + * @property {object} [sensitiveProperties] - Object of sensitive values to + * track. Keys in this object must be in snake_case. These properties will be + * sent in an additional event that excludes the user's metaMetricsId + * @property {number} [revenue] - amount of currency that event creates in + * revenue for MetaMask + * @property {string} [currency] - ISO 4127 format currency for events with + * revenue, defaults to US dollars + * @property {number} [value] - Abstract business "value" attributable to + * customers who trigger this event + * @property {MetaMetricsPageObject} [page] - the page/route that the event + * occurred on + * @property {MetaMetricsReferrerObject} [referrer] - the origin of the dapp + * that triggered the event + */ + +/** + * @typedef {Object} MetaMetricsEventOptions + * @property {boolean} [isOptIn] - happened during opt in/out workflow + * @property {boolean} [flushImmediately] - When true will automatically flush + * the segment queue after tracking the event. Recommended if the result of + * tracking the event must be known before UI transition or update + * @property {boolean} [excludeMetaMetricsId] - whether to exclude the user's + * metametrics id for anonymity + * @property {string} [metaMetricsId] - an override for the metaMetricsId in + * the event one is created as part of an asynchronous workflow, such as + * awaiting the result of the metametrics opt-in function that generates the + * user's metametrics id + * @property {boolean} [matomoEvent] - is this event a holdover from matomo + * that needs further migration? when true, sends the data to a special + * segment source that marks the event data as not conforming to our schema + */ + +/** + * Represents the shape of data sent to the segment.track method. + * @typedef {Object} SegmentEventPayload + * @property {string} [userId] - The metametrics id for the user + * @property {string} [anonymousId] - An anonymousId that is used to track + * sensitive data while preserving anonymity. + * @property {string} event - name of the event to track + * @property {Object} properties - properties to attach to the event + * @property {MetaMetricsContext} context - the context the event occurred in + */ + +/** + * @typedef {Object} MetaMetricsPagePayload + * @property {string} name - The name of the page that was viewed + * @property {Object} [params] - The variadic parts of the page url + * example (route: `/asset/:asset`, path: `/asset/ETH`) + * params: { asset: 'ETH' } + * @property {EnvironmentType} environmentType - the environment type that the + * page was viewed in + * @property {MetaMetricsPageObject} [page] - the details of the page + * @property {MetaMetricsReferrerObject} [referrer] - dapp that triggered the page + * view + */ + +/** + * @typedef {Object} MetaMetricsPageOptions + * @property {boolean} [isOptInPath] - is the current path one of the pages in + * the onboarding workflow? If true and participateInMetaMetrics is null track + * the page view + */ + +export const METAMETRICS_ANONYMOUS_ID = '0x0000000000000000' + +/** + * This object is used to identify events that are triggered by the background + * process. + * @type {MetaMetricsPageObject} + */ +export const METAMETRICS_BACKGROUND_PAGE_OBJECT = { + path: '/background-process', + title: 'Background Process', + url: '/background-process', +} + +/** + * @typedef {Object} SegmentInterface + * @property {SegmentEventPayload[]} queue - A queue of events to be sent when + * the flushAt limit has been reached, or flushInterval occurs + * @property {() => void} flush - Immediately flush the queue, resetting it to + * an empty array and sending the pending events to Segment + * @property {( + * payload: SegmentEventPayload, + * callback: (err?: Error) => void + * ) => void} track - Track an event with Segment, using the internal batching + * mechanism to optimize network requests + * @property {(payload: Object) => void} page - Track a page view with Segment + * @property {() => void} identify - Identify an anonymous user. We do not + * currently use this method. + */ diff --git a/shared/modules/README.md b/shared/modules/README.md new file mode 100644 index 000000000..5b6e0ffd6 --- /dev/null +++ b/shared/modules/README.md @@ -0,0 +1,3 @@ +### Shared Modules + +This folder is reserved for modules that can be used globally within both the background and ui applications. diff --git a/shared/modules/metametrics.js b/shared/modules/metametrics.js deleted file mode 100644 index 523ac6933..000000000 --- a/shared/modules/metametrics.js +++ /dev/null @@ -1,302 +0,0 @@ -import Analytics from 'analytics-node' -import { merge, omit, pick } from 'lodash' - -// flushAt controls how many events are sent to segment at once. Segment -// will hold onto a queue of events until it hits this number, then it sends -// them as a batch. This setting defaults to 20, but that is too high for -// notification workflows. We also cannot send each event as singular payloads -// because it seems to bombard segment and potentially cause event loss. -// I chose 5 here because it is sufficiently high enough to optimize our network -// requests, while also being low enough to be reasonable. -const flushAt = process.env.METAMASK_ENVIRONMENT === 'production' ? 5 : 1 -// flushInterval controls how frequently the queue is flushed to segment. -// This happens regardless of the size of the queue. The default setting is -// 10,000ms (10 seconds). This default is absurdly high for our typical user -// flow through confirmations. I have chosen 10 ms here because it works really -// well with our wrapped track function. The track function returns a promise -// that is only fulfilled when it has been sent to segment. A 10 ms delay is -// negligible to the user, but allows us to properly batch events that happen -// in rapid succession. -const flushInterval = 10 - -export const METAMETRICS_ANONYMOUS_ID = '0x0000000000000000' - -const segmentNoop = { - track(_, callback = () => undefined) { - // Need to call the callback so that environments without a segment id still - // resolve the promise from trackMetaMetricsEvent - return callback() - }, - page() { - // noop - }, - identify() { - // noop - }, -} - -/** - * Used to determine whether or not to attach a user's metametrics id - * to events that include on-chain data. This helps to prevent identifying - * a user by being able to trace their activity on etherscan/block exploring - */ -const trackableSendCounts = { - 1: true, - 10: true, - 30: true, - 50: true, - 100: true, - 250: true, - 500: true, - 1000: true, - 2500: true, - 5000: true, - 10000: true, - 25000: true, -} - -export function sendCountIsTrackable(sendCount) { - return Boolean(trackableSendCounts[sendCount]) -} - -const isDevOrTestEnvironment = Boolean( - process.env.METAMASK_DEBUG || process.env.IN_TEST, -) - -// This allows us to overwrite the metric destination for testing purposes -const host = process.env.SEGMENT_HOST ?? undefined - -// We do not want to track events on development builds unless specifically -// provided a SEGMENT_WRITE_KEY. This also holds true for test environments and -// E2E, which is handled in the build process by never providing the SEGMENT_WRITE_KEY -// when process.env.IN_TEST is truthy -export const segment = - !process.env.SEGMENT_WRITE_KEY || (isDevOrTestEnvironment && !host) - ? segmentNoop - : new Analytics(process.env.SEGMENT_WRITE_KEY, { - host, - flushAt, - flushInterval, - }) - -export const segmentLegacy = - !process.env.SEGMENT_LEGACY_WRITE_KEY || (isDevOrTestEnvironment && !host) - ? segmentNoop - : new Analytics(process.env.SEGMENT_LEGACY_WRITE_KEY, { - host, - flushAt, - flushInterval, - }) - -/** - * We attach context to every meta metrics event that help to qualify our analytics. - * This type has all optional values because it represents a returned object from a - * method call. Ideally app and userAgent are defined on every event. This is confirmed - * in the getTrackMetaMetricsEvent function, but still provides the consumer a way to - * override these values if necessary. - * @typedef {Object} MetaMetricsContext - * @property {Object} app - * @property {string} app.name - the name of the application tracking the event - * @property {string} app.version - the version of the application - * @property {string} userAgent - the useragent string of the user - * @property {Object} [page] - an object representing details of the current page - * @property {string} [page.path] - the path of the current page (e.g /home) - * @property {string} [page.title] - the title of the current page (e.g 'home') - * @property {string} [page.url] - the fully qualified url of the current page - * @property {Object} [referrer] - for metamask, this is the dapp that triggered an interaction - * @property {string} [referrer.url] - the origin of the dapp issuing the notification - */ - -/** - * page and referrer from the MetaMetricsContext are very dynamic in nature and may be - * provided as part of the initial context payload when creating the trackMetaMetricsEvent function, - * or at the event level when calling the trackMetaMetricsEvent function. - * @typedef {Pick} MetaMetricsDynamicContext - */ - -/** - * @typedef {import('../../app/scripts/lib/enums').EnvironmentType} EnvironmentType - */ - -/** - * @typedef {Object} MetaMetricsRequiredState - * @property {bool} participateInMetaMetrics - has the user opted into metametrics - * @property {string} [metaMetricsId] - the user's metaMetricsId, if they have opted in - * @property {MetaMetricsDynamicContext} context - context about the event - * @property {string} chainId - the chain id of the current network - * @property {string} locale - the locale string of the current user - * @property {string} network - the name of the current network - * @property {EnvironmentType} environmentType - environment that the event happened in - * @property {string} [metaMetricsSendCount] - number of transactions sent, used to add metametricsId - * intermittently to events with onchain data attached to them used to protect identity of users. - */ - -/** - * @typedef {Object} MetaMetricsEventPayload - * @property {string} event - event name to track - * @property {string} category - category to associate event to - * @property {boolean} [isOptIn] - happened during opt in/out workflow - * @property {object} [properties] - object of custom values to track, snake_case - * @property {object} [sensitiveProperties] - Object of sensitive values to track, snake_case. - * These properties will be sent in an additional event that excludes the user's metaMetricsId. - * @property {number} [revenue] - amount of currency that event creates in revenue for MetaMask - * @property {string} [currency] - ISO 4127 format currency for events with revenue, defaults to US dollars - * @property {number} [value] - Abstract "value" that this event has for MetaMask. - * @property {boolean} [excludeMetaMetricsId] - whether to exclude the user's metametrics id for anonymity - * @property {string} [metaMetricsId] - an override for the metaMetricsId in the event one is created as part - * of an asynchronous workflow, such as awaiting the result of the metametrics opt-in function that generates the - * user's metametrics id. - * @property {boolean} [matomoEvent] - is this event a holdover from matomo that needs further migration? - * when true, sends the data to a special segment source that marks the event data as not conforming to our - * ideal schema - * @property {MetaMetricsDynamicContext} [eventContext] - additional context to attach to event - */ - -/** - * Returns a function for tracking Segment events. - * - * @param {string} metamaskVersion - The current version of the MetaMask extension. - * @param {() => MetaMetricsRequiredState} getDynamicState - A function returning required fields - * @returns {(payload: MetaMetricsEventPayload) => Promise} function to track an event - */ -export function getTrackMetaMetricsEvent(metamaskVersion, getDynamicState) { - const version = - process.env.METAMASK_ENVIRONMENT === 'production' - ? metamaskVersion - : `${metamaskVersion}-${process.env.METAMASK_ENVIRONMENT}` - - return function trackMetaMetricsEvent({ - event, - category, - isOptIn, - properties = {}, - sensitiveProperties, - revenue, - currency, - value, - metaMetricsId: metaMetricsIdOverride, - excludeMetaMetricsId: excludeId, - matomoEvent = false, - eventContext = {}, - }) { - if (!event || !category) { - throw new Error('Must specify event and category.') - } - // Uses recursion to track a duplicate event with sensitive properties included, - // but metaMetricsId excluded - if (sensitiveProperties) { - if (excludeId === true) { - throw new Error( - 'sensitiveProperties was specified in an event payload that also set the excludeMetaMetricsId flag', - ) - } - trackMetaMetricsEvent({ - event, - category, - isOptIn, - properties: merge(sensitiveProperties, properties), - revenue, - currency, - value, - excludeMetaMetricsId: true, - matomoEvent, - eventContext, - }) - } - const { - participateInMetaMetrics, - context: providedContext, - metaMetricsId, - environmentType, - chainId, - locale, - network, - metaMetricsSendCount, - } = getDynamicState() - - let excludeMetaMetricsId = excludeId ?? false - - // This is carried over from the old implementation, and will likely need - // to be updated to work with the new tracking plan. I think we should use - // a config setting for this instead of trying to match the event name - const isSendFlow = Boolean(event.match(/^send|^confirm/u)) - if ( - isSendFlow && - metaMetricsSendCount && - !sendCountIsTrackable(metaMetricsSendCount + 1) - ) { - excludeMetaMetricsId = true - } - - if (!participateInMetaMetrics && !isOptIn) { - return Promise.resolve() - } - - /** @type {MetaMetricsContext} */ - const context = { - app: { - name: 'MetaMask Extension', - version, - }, - userAgent: window.navigator.userAgent, - ...pick(providedContext, ['page', 'referrer']), - ...pick(eventContext, ['page', 'referrer']), - } - - const trackOptions = { - event, - properties: { - // These values are omitted from properties because they have special meaning - // in segment. https://segment.com/docs/connections/spec/track/#properties. - // to avoid accidentally using these inappropriately, you must add them as top - // level properties on the event payload. We also exclude locale to prevent consumers - // from overwriting this context level property. We track it as a property - // because not all destinations map locale from context. - ...omit(properties, ['revenue', 'locale', 'currency', 'value']), - revenue, - value, - currency, - category, - network, - locale, - chain_id: chainId, - environment_type: environmentType, - }, - context, - } - - // If we are tracking sensitive data we will always use the anonymousId property - // as well as our METAMETRICS_ANONYMOUS_ID. This prevents us from associating potentially - // identifiable information with a specific id. During the opt in flow we will track all - // events, but do so with the anonymous id. The one exception to that rule is after the - // user opts in to MetaMetrics. When that happens we receive back the user's new MetaMetrics - // id before it is fully persisted to state. To avoid a race condition we explicitly pass the - // new id to the track method. In that case we will track the opt in event to the user's id. - // In all other cases we use the metaMetricsId from state. - if (excludeMetaMetricsId) { - trackOptions.anonymousId = METAMETRICS_ANONYMOUS_ID - } else if (isOptIn && metaMetricsIdOverride) { - trackOptions.userId = metaMetricsIdOverride - } else if (isOptIn) { - trackOptions.anonymousId = METAMETRICS_ANONYMOUS_ID - } else { - trackOptions.userId = metaMetricsId - } - - return new Promise((resolve, reject) => { - // This is only safe to do because we have set an extremely low (10ms) flushInterval. - const callback = (err) => { - if (err) { - return reject(err) - } - return resolve() - } - - if (matomoEvent === true) { - segmentLegacy.track(trackOptions, callback) - } else { - segment.track(trackOptions, callback) - } - }) - } -} diff --git a/test/unit/app/controllers/metamask-controller-test.js b/test/unit/app/controllers/metamask-controller-test.js index 09b8ffac7..99bd3f957 100644 --- a/test/unit/app/controllers/metamask-controller-test.js +++ b/test/unit/app/controllers/metamask-controller-test.js @@ -108,6 +108,7 @@ describe('MetaMaskController', function () { }, }, initState: cloneDeep(firstTimeState), + initLangCode: 'en_US', platform: { showTransactionNotification: () => undefined, getVersion: () => 'foo', @@ -799,7 +800,7 @@ describe('MetaMaskController', function () { it('checks the default currentLocale', function () { const preferenceCurrentLocale = metamaskController.preferencesController.store.getState() .currentLocale - assert.equal(preferenceCurrentLocale, undefined) + assert.equal(preferenceCurrentLocale, 'en_US') }) it('sets current locale in preferences controller', function () { diff --git a/test/unit/app/controllers/metametrics-test.js b/test/unit/app/controllers/metametrics-test.js new file mode 100644 index 000000000..d43f48f4f --- /dev/null +++ b/test/unit/app/controllers/metametrics-test.js @@ -0,0 +1,546 @@ +import { strict as assert } from 'assert' +import sinon from 'sinon' +import MetaMetricsController from '../../../../app/scripts/controllers/metametrics' +import { ENVIRONMENT_TYPE_BACKGROUND } from '../../../../app/scripts/lib/enums' +import { createSegmentMock } from '../../../../app/scripts/lib/segment' +import { + METAMETRICS_ANONYMOUS_ID, + METAMETRICS_BACKGROUND_PAGE_OBJECT, +} from '../../../../shared/constants/metametrics' +import waitUntilCalled from '../../../lib/wait-until-called' + +const segment = createSegmentMock(2, 10000) +const segmentLegacy = createSegmentMock(2, 10000) + +const VERSION = '0.0.1-test' +const NETWORK = 'Mainnet' +const FAKE_CHAIN_ID = '0x1338' +const LOCALE = 'en_US' +const TEST_META_METRICS_ID = '0xabc' + +const DEFAULT_TEST_CONTEXT = { + app: { name: 'MetaMask Extension', version: VERSION }, + page: METAMETRICS_BACKGROUND_PAGE_OBJECT, + referrer: undefined, + userAgent: window.navigator.userAgent, +} + +const DEFAULT_SHARED_PROPERTIES = { + chain_id: FAKE_CHAIN_ID, + locale: LOCALE.replace('_', '-'), + network: NETWORK, + environment_type: 'background', +} + +const DEFAULT_EVENT_PROPERTIES = { + category: 'Unit Test', + revenue: undefined, + value: undefined, + currency: undefined, + ...DEFAULT_SHARED_PROPERTIES, +} + +const DEFAULT_PAGE_PROPERTIES = { + ...DEFAULT_SHARED_PROPERTIES, +} + +function getMockNetworkController( + chainId = FAKE_CHAIN_ID, + provider = { type: NETWORK }, +) { + let networkStore = { chainId, provider } + const on = sinon.stub().withArgs('networkDidChange') + const updateState = (newState) => { + networkStore = { ...networkStore, ...newState } + on.getCall(0).args[1]() + } + return { + store: { + getState: () => networkStore, + updateState, + }, + getCurrentChainId: () => networkStore.chainId, + getNetworkIdentifier: () => networkStore.provider.type, + on, + } +} + +function getMockPreferencesStore({ currentLocale = LOCALE } = {}) { + let preferencesStore = { + currentLocale, + } + const subscribe = sinon.stub() + const updateState = (newState) => { + preferencesStore = { ...preferencesStore, ...newState } + subscribe.getCall(0).args[0](preferencesStore) + } + return { + getState: sinon.stub().returns(preferencesStore), + updateState, + subscribe, + } +} + +function getMetaMetricsController({ + participateInMetaMetrics = true, + metaMetricsId = TEST_META_METRICS_ID, + metaMetricsSendCount = 0, + preferencesStore = getMockPreferencesStore(), + networkController = getMockNetworkController(), +} = {}) { + return new MetaMetricsController({ + segment, + segmentLegacy, + getNetworkIdentifier: networkController.getNetworkIdentifier.bind( + networkController, + ), + getCurrentChainId: networkController.getCurrentChainId.bind( + networkController, + ), + onNetworkDidChange: networkController.on.bind( + networkController, + 'networkDidChange', + ), + preferencesStore, + version: '0.0.1', + environment: 'test', + initState: { + participateInMetaMetrics, + metaMetricsId, + metaMetricsSendCount, + }, + }) +} +describe('MetaMetricsController', function () { + describe('constructor', function () { + it('should properly initialize', function () { + const metaMetricsController = getMetaMetricsController() + assert.strictEqual(metaMetricsController.version, VERSION) + assert.strictEqual(metaMetricsController.network, NETWORK) + assert.strictEqual(metaMetricsController.chainId, FAKE_CHAIN_ID) + assert.strictEqual( + metaMetricsController.state.participateInMetaMetrics, + true, + ) + assert.strictEqual( + metaMetricsController.state.metaMetricsId, + TEST_META_METRICS_ID, + ) + assert.strictEqual(metaMetricsController.locale, LOCALE.replace('_', '-')) + }) + + it('should update when network changes', function () { + const networkController = getMockNetworkController() + const metaMetricsController = getMetaMetricsController({ + networkController, + }) + assert.strictEqual(metaMetricsController.network, NETWORK) + networkController.store.updateState({ + provider: { + type: 'NEW_NETWORK', + }, + chainId: '0xaab', + }) + assert.strictEqual(metaMetricsController.network, 'NEW_NETWORK') + assert.strictEqual(metaMetricsController.chainId, '0xaab') + }) + + it('should update when preferences changes', function () { + const preferencesStore = getMockPreferencesStore() + const metaMetricsController = getMetaMetricsController({ + preferencesStore, + }) + assert.strictEqual(metaMetricsController.network, NETWORK) + preferencesStore.updateState({ + currentLocale: 'en_UK', + }) + assert.strictEqual(metaMetricsController.locale, 'en-UK') + }) + }) + + describe('generateMetaMetricsId', function () { + it('should generate an 0x prefixed hex string', function () { + const metaMetricsController = getMetaMetricsController() + assert.equal( + metaMetricsController.generateMetaMetricsId().startsWith('0x'), + true, + ) + }) + }) + + describe('setParticipateInMetaMetrics', function () { + it('should update the value of participateInMetaMetrics', function () { + const metaMetricsController = getMetaMetricsController({ + participateInMetaMetrics: null, + metaMetricsId: null, + }) + assert.equal(metaMetricsController.state.participateInMetaMetrics, null) + metaMetricsController.setParticipateInMetaMetrics(true) + assert.equal(metaMetricsController.state.participateInMetaMetrics, true) + metaMetricsController.setParticipateInMetaMetrics(false) + assert.equal(metaMetricsController.state.participateInMetaMetrics, false) + }) + it('should generate and update the metaMetricsId when set to true', function () { + const metaMetricsController = getMetaMetricsController({ + participateInMetaMetrics: null, + metaMetricsId: null, + }) + assert.equal(metaMetricsController.state.metaMetricsId, null) + metaMetricsController.setParticipateInMetaMetrics(true) + assert.equal(typeof metaMetricsController.state.metaMetricsId, 'string') + }) + it('should nullify the metaMetricsId when set to false', function () { + const metaMetricsController = getMetaMetricsController() + metaMetricsController.setParticipateInMetaMetrics(false) + assert.equal(metaMetricsController.state.metaMetricsId, null) + }) + }) + + describe('setMetaMetricsSendCount', function () { + it('should update the send count in state', function () { + const metaMetricsController = getMetaMetricsController() + metaMetricsController.setMetaMetricsSendCount(1) + assert.equal(metaMetricsController.state.metaMetricsSendCount, 1) + }) + }) + + describe('trackEvent', function () { + it('should not track an event if user is not participating in metametrics', function () { + const mock = sinon.mock(segment) + const metaMetricsController = getMetaMetricsController({ + participateInMetaMetrics: false, + }) + mock.expects('track').never() + metaMetricsController.trackEvent({ + event: 'Fake Event', + category: 'Unit Test', + properties: { + test: 1, + }, + }) + mock.verify() + }) + + it('should track an event if user has not opted in, but isOptIn is true', function () { + const mock = sinon.mock(segment) + const metaMetricsController = getMetaMetricsController({ + participateInMetaMetrics: false, + }) + mock + .expects('track') + .once() + .withArgs({ + event: 'Fake Event', + anonymousId: METAMETRICS_ANONYMOUS_ID, + context: DEFAULT_TEST_CONTEXT, + properties: { + test: 1, + ...DEFAULT_EVENT_PROPERTIES, + }, + }) + metaMetricsController.trackEvent( + { + event: 'Fake Event', + category: 'Unit Test', + properties: { + test: 1, + }, + }, + { isOptIn: true }, + ) + mock.verify() + }) + + it('should track an event during optin and allow for metaMetricsId override', function () { + const mock = sinon.mock(segment) + const metaMetricsController = getMetaMetricsController({ + participateInMetaMetrics: false, + }) + mock + .expects('track') + .once() + .withArgs({ + event: 'Fake Event', + userId: 'TESTID', + context: DEFAULT_TEST_CONTEXT, + properties: { + test: 1, + ...DEFAULT_EVENT_PROPERTIES, + }, + }) + metaMetricsController.trackEvent( + { + event: 'Fake Event', + category: 'Unit Test', + properties: { + test: 1, + }, + }, + { isOptIn: true, metaMetricsId: 'TESTID' }, + ) + mock.verify() + }) + + it('should track a legacy event', function () { + const mock = sinon.mock(segmentLegacy) + const metaMetricsController = getMetaMetricsController() + mock + .expects('track') + .once() + .withArgs({ + event: 'Fake Event', + userId: TEST_META_METRICS_ID, + context: DEFAULT_TEST_CONTEXT, + properties: { + test: 1, + ...DEFAULT_EVENT_PROPERTIES, + }, + }) + metaMetricsController.trackEvent( + { + event: 'Fake Event', + category: 'Unit Test', + properties: { + test: 1, + }, + }, + { matomoEvent: true }, + ) + mock.verify() + }) + + it('should track a non legacy event', function () { + const mock = sinon.mock(segment) + const metaMetricsController = getMetaMetricsController() + mock + .expects('track') + .once() + .withArgs({ + event: 'Fake Event', + userId: TEST_META_METRICS_ID, + context: DEFAULT_TEST_CONTEXT, + properties: { + test: 1, + ...DEFAULT_EVENT_PROPERTIES, + }, + }) + metaMetricsController.trackEvent({ + event: 'Fake Event', + category: 'Unit Test', + properties: { + test: 1, + }, + }) + mock.verify() + }) + + it('should use anonymousId when metametrics send count is not trackable in send flow', function () { + const mock = sinon.mock(segment) + const metaMetricsController = getMetaMetricsController({ + metaMetricsSendCount: 1, + }) + mock + .expects('track') + .once() + .withArgs({ + event: 'Send Fake Event', + anonymousId: METAMETRICS_ANONYMOUS_ID, + context: DEFAULT_TEST_CONTEXT, + properties: { + test: 1, + ...DEFAULT_EVENT_PROPERTIES, + }, + }) + metaMetricsController.trackEvent({ + event: 'Send Fake Event', + category: 'Unit Test', + properties: { + test: 1, + }, + }) + mock.verify() + }) + + it('should use user metametrics id when metametrics send count is trackable in send flow', function () { + const mock = sinon.mock(segment) + const metaMetricsController = getMetaMetricsController() + mock + .expects('track') + .once() + .withArgs({ + event: 'Send Fake Event', + userId: TEST_META_METRICS_ID, + context: DEFAULT_TEST_CONTEXT, + properties: { + test: 1, + ...DEFAULT_EVENT_PROPERTIES, + }, + }) + metaMetricsController.trackEvent( + { + event: 'Send Fake Event', + category: 'Unit Test', + properties: { + test: 1, + }, + }, + { metaMetricsSendCount: 0 }, + ) + mock.verify() + }) + + it('should immediately flush queue if flushImmediately set to true', async function () { + const metaMetricsController = getMetaMetricsController() + const flushStub = sinon.stub(segment, 'flush') + const flushCalled = waitUntilCalled(flushStub, segment) + metaMetricsController.trackEvent( + { + event: 'Fake Event', + category: 'Unit Test', + }, + { flushImmediately: true }, + ) + assert.doesNotReject(flushCalled) + }) + + it('should throw if event or category not provided', function () { + const metaMetricsController = getMetaMetricsController() + assert.rejects( + () => metaMetricsController.trackEvent({ event: 'test' }), + /Must specify event and category\./u, + 'must specify category', + ) + + assert.rejects( + () => metaMetricsController.trackEvent({ category: 'test' }), + /Must specify event and category\./u, + 'must specify event', + ) + }) + + it('should throw if provided sensitiveProperties, when excludeMetaMetricsId is true', function () { + const metaMetricsController = getMetaMetricsController() + assert.rejects( + () => + metaMetricsController.trackEvent( + { + event: 'Fake Event', + category: 'Unit Test', + sensitiveProperties: { foo: 'bar' }, + }, + { excludeMetaMetricsId: true }, + ), + /sensitiveProperties was specified in an event payload that also set the excludeMetaMetricsId flag/u, + ) + }) + + it('should track sensitiveProperties in a separate, anonymous event', function () { + const metaMetricsController = getMetaMetricsController() + const spy = sinon.spy(segment, 'track') + metaMetricsController.trackEvent({ + event: 'Fake Event', + category: 'Unit Test', + sensitiveProperties: { foo: 'bar' }, + }) + assert.ok(spy.calledTwice) + assert.ok( + spy.calledWith({ + event: 'Fake Event', + anonymousId: METAMETRICS_ANONYMOUS_ID, + context: DEFAULT_TEST_CONTEXT, + properties: { + foo: 'bar', + ...DEFAULT_EVENT_PROPERTIES, + }, + }), + ) + assert.ok( + spy.calledWith({ + event: 'Fake Event', + userId: TEST_META_METRICS_ID, + context: DEFAULT_TEST_CONTEXT, + properties: DEFAULT_EVENT_PROPERTIES, + }), + ) + }) + }) + + describe('trackPage', function () { + it('should track a page view', function () { + const mock = sinon.mock(segment) + const metaMetricsController = getMetaMetricsController() + mock + .expects('page') + .once() + .withArgs({ + name: 'home', + userId: TEST_META_METRICS_ID, + context: DEFAULT_TEST_CONTEXT, + properties: { + params: null, + ...DEFAULT_PAGE_PROPERTIES, + }, + }) + metaMetricsController.trackPage({ + name: 'home', + params: null, + environmentType: ENVIRONMENT_TYPE_BACKGROUND, + page: METAMETRICS_BACKGROUND_PAGE_OBJECT, + }) + mock.verify() + }) + + it('should not track a page view if user is not participating in metametrics', function () { + const mock = sinon.mock(segment) + const metaMetricsController = getMetaMetricsController({ + participateInMetaMetrics: false, + }) + mock.expects('page').never() + metaMetricsController.trackPage({ + name: 'home', + params: null, + environmentType: ENVIRONMENT_TYPE_BACKGROUND, + page: METAMETRICS_BACKGROUND_PAGE_OBJECT, + }) + mock.verify() + }) + + it('should track a page view if isOptInPath is true and user not yet opted in', function () { + const mock = sinon.mock(segment) + const metaMetricsController = getMetaMetricsController({ + preferencesStore: getMockPreferencesStore({ + participateInMetaMetrics: null, + }), + }) + mock + .expects('page') + .once() + .withArgs({ + name: 'home', + userId: TEST_META_METRICS_ID, + context: DEFAULT_TEST_CONTEXT, + properties: { + params: null, + ...DEFAULT_PAGE_PROPERTIES, + }, + }) + metaMetricsController.trackPage( + { + name: 'home', + params: null, + environmentType: ENVIRONMENT_TYPE_BACKGROUND, + page: METAMETRICS_BACKGROUND_PAGE_OBJECT, + }, + { isOptInPath: true }, + ) + mock.verify() + }) + }) + + afterEach(function () { + // flush the queues manually after each test + segment.flush() + segmentLegacy.flush() + sinon.restore() + }) +}) diff --git a/test/unit/migrations/049-test.js b/test/unit/migrations/049-test.js new file mode 100644 index 000000000..f720a4723 --- /dev/null +++ b/test/unit/migrations/049-test.js @@ -0,0 +1,132 @@ +import assert from 'assert' +import migration49 from '../../../app/scripts/migrations/049' + +describe('migration #49', function () { + it('should update the version metadata', async function () { + const oldStorage = { + meta: { + version: 48, + }, + data: {}, + } + + const newStorage = await migration49.migrate(oldStorage) + assert.deepStrictEqual(newStorage.meta, { + version: 49, + }) + }) + + it('should move metaMetricsId to MetaMetricsController', async function () { + const oldStorage = { + meta: {}, + data: { + PreferencesController: { + metaMetricsId: '0xaab', + bar: 'baz', + }, + foo: 'bar', + }, + } + + const newStorage = await migration49.migrate(oldStorage) + assert.deepStrictEqual(newStorage.data, { + PreferencesController: { + bar: 'baz', + }, + MetaMetricsController: { + metaMetricsId: '0xaab', + }, + foo: 'bar', + }) + }) + + it('should move participateInMetaMetrics to MetaMetricsController', async function () { + const oldStorage = { + meta: {}, + data: { + PreferencesController: { + participateInMetaMetrics: false, + bar: 'baz', + }, + foo: 'bar', + }, + } + + const newStorage = await migration49.migrate(oldStorage) + assert.deepStrictEqual(newStorage.data, { + PreferencesController: { + bar: 'baz', + }, + MetaMetricsController: { + participateInMetaMetrics: false, + }, + foo: 'bar', + }) + }) + + it('should move metaMetricsSendCount to MetaMetricsController', async function () { + const oldStorage = { + meta: {}, + data: { + PreferencesController: { + metaMetricsSendCount: 1, + bar: 'baz', + }, + foo: 'bar', + }, + } + + const newStorage = await migration49.migrate(oldStorage) + assert.deepStrictEqual(newStorage.data, { + PreferencesController: { + bar: 'baz', + }, + MetaMetricsController: { + metaMetricsSendCount: 1, + }, + foo: 'bar', + }) + }) + + it('should move all metaMetrics fields to MetaMetricsController', async function () { + const oldStorage = { + meta: {}, + data: { + PreferencesController: { + metaMetricsSendCount: 1, + metaMetricsId: '0xaab', + participateInMetaMetrics: true, + bar: 'baz', + }, + foo: 'bar', + }, + } + + const newStorage = await migration49.migrate(oldStorage) + assert.deepStrictEqual(newStorage.data, { + PreferencesController: { + bar: 'baz', + }, + MetaMetricsController: { + metaMetricsSendCount: 1, + metaMetricsId: '0xaab', + participateInMetaMetrics: true, + }, + foo: 'bar', + }) + }) + + it('should do nothing if no PreferencesController key', async function () { + const oldStorage = { + meta: {}, + data: { + foo: 'bar', + }, + } + + const newStorage = await migration49.migrate(oldStorage) + assert.deepStrictEqual(newStorage.data, { + foo: 'bar', + }) + }) +}) diff --git a/test/unit/ui/app/actions.spec.js b/test/unit/ui/app/actions.spec.js index d487d825e..09ae2acba 100644 --- a/test/unit/ui/app/actions.spec.js +++ b/test/unit/ui/app/actions.spec.js @@ -54,6 +54,7 @@ describe('Actions', function () { return Promise.resolve(this.object) }, }, + initLangCode: 'en_US', initState: cloneDeep(firstTimeState), infuraProjectId: 'foo', }) diff --git a/ui/app/contexts/metametrics.js b/ui/app/contexts/metametrics.js index 835f0caea..80d383a54 100644 --- a/ui/app/contexts/metametrics.js +++ b/ui/app/contexts/metametrics.js @@ -4,7 +4,6 @@ import React, { useEffect, useCallback, useState, - useMemo, } from 'react' import { useSelector } from 'react-redux' import PropTypes from 'prop-types' @@ -12,17 +11,14 @@ import { useHistory } from 'react-router-dom' import { captureException } from '@sentry/browser' import { - getCurrentNetworkId, getAccountType, getNumberOfAccounts, getNumberOfTokens, - getCurrentChainId, } from '../selectors/selectors' import { getSendToken } from '../selectors/send' import { txDataSelector } from '../selectors/confirm-transaction' import { getEnvironmentType } from '../../../app/scripts/lib/util' -import { getTrackMetaMetricsEvent } from '../../../shared/modules/metametrics' -import { getCurrentLocale } from '../ducks/metamask/metamask' +import { trackMetaMetricsEvent } from '../store/actions' export const MetaMetricsContext = createContext(() => { captureException( @@ -34,20 +30,10 @@ export const MetaMetricsContext = createContext(() => { export function MetaMetricsProvider({ children }) { const txData = useSelector(txDataSelector) || {} - const network = useSelector(getCurrentNetworkId) const environmentType = getEnvironmentType() - const chainId = useSelector(getCurrentChainId) - const locale = useSelector(getCurrentLocale) const activeCurrency = useSelector(getSendToken)?.symbol const accountType = useSelector(getAccountType) const confirmTransactionOrigin = txData.origin - const metaMetricsId = useSelector((state) => state.metamask.metaMetricsId) - const participateInMetaMetrics = useSelector( - (state) => state.metamask.participateInMetaMetrics, - ) - const metaMetricsSendCount = useSelector( - (state) => state.metamask.metaMetricsSendCount, - ) const numberOfTokens = useSelector(getNumberOfTokens) const numberOfAccounts = useSelector(getNumberOfAccounts) const history = useHistory() @@ -69,75 +55,58 @@ export function MetaMetricsProvider({ children }) { return unlisten }, [history]) - /** - * track a metametrics event - * - * @param {import('../../../shared/modules/metametrics').MetaMetricsEventPayload} payload - payload for event - * @returns undefined - */ - const trackEvent = useMemo(() => { - const referrer = confirmTransactionOrigin - ? { url: confirmTransactionOrigin } - : undefined - const page = { - path: currentPath, - } - return getTrackMetaMetricsEvent(global.platform.getVersion(), () => ({ - context: { - referrer, - page, - }, - environmentType, - locale: locale.replace('_', '-'), - network, - chainId, - participateInMetaMetrics, - metaMetricsId, - metaMetricsSendCount, - })) - }, [ - network, - chainId, - locale, - environmentType, - participateInMetaMetrics, - currentPath, - confirmTransactionOrigin, - metaMetricsId, - metaMetricsSendCount, - ]) - const metricsEvent = useCallback( (config = {}, overrides = {}) => { const { eventOpts = {} } = config - - return trackEvent({ - event: eventOpts.name, - category: eventOpts.category, - isOptIn: config.isOptIn, - excludeMetaMetricsId: - eventOpts.excludeMetaMetricsId ?? - overrides.excludeMetaMetricsId ?? - false, - metaMetricsId: config.metaMetricsId, - matomoEvent: true, - properties: { - action: eventOpts.action, - number_of_tokens: numberOfTokens, - number_of_accounts: numberOfAccounts, - active_currency: activeCurrency, - account_type: accountType, - is_new_visit: config.is_new_visit, - // the properties coming from this key will not match our standards for - // snake_case on properties, and they may be redundant and/or not in the - // proper location (origin not as a referrer, for example). This is a temporary - // solution to not lose data, and the entire event system will be reworked in - // forthcoming PRs to deprecate the old Matomo events in favor of the new schema. - ...config.customVariables, + const referrer = confirmTransactionOrigin + ? { url: confirmTransactionOrigin } + : undefined + const page = { + path: currentPath, + } + return trackMetaMetricsEvent( + { + event: eventOpts.name, + category: eventOpts.category, + properties: { + action: eventOpts.action, + number_of_tokens: numberOfTokens, + number_of_accounts: numberOfAccounts, + active_currency: activeCurrency, + account_type: accountType, + is_new_visit: config.is_new_visit, + // the properties coming from this key will not match our standards for + // snake_case on properties, and they may be redundant and/or not in the + // proper location (origin not as a referrer, for example). This is a temporary + // solution to not lose data, and the entire event system will be reworked in + // forthcoming PRs to deprecate the old Matomo events in favor of the new schema. + ...config.customVariables, + }, + page, + referrer, + environmentType, }, - }) + { + isOptIn: config.isOptIn, + excludeMetaMetricsId: + eventOpts.excludeMetaMetricsId ?? + overrides.excludeMetaMetricsId ?? + false, + metaMetricsId: config.metaMetricsId, + matomoEvent: true, + flushImmediately: config.flushImmediately, + }, + ) }, - [accountType, activeCurrency, numberOfTokens, numberOfAccounts, trackEvent], + [ + accountType, + currentPath, + confirmTransactionOrigin, + activeCurrency, + numberOfTokens, + numberOfAccounts, + environmentType, + ], ) return ( diff --git a/ui/app/contexts/metametrics.new.js b/ui/app/contexts/metametrics.new.js index 75249444f..ca39df100 100644 --- a/ui/app/contexts/metametrics.new.js +++ b/ui/app/contexts/metametrics.new.js @@ -4,33 +4,46 @@ * metrics system. This file implements Segment analytics tracking. */ import React, { - useRef, Component, createContext, useEffect, - useMemo, + useRef, + useCallback, } from 'react' import { useSelector } from 'react-redux' import PropTypes from 'prop-types' -import { useLocation, matchPath, useRouteMatch } from 'react-router-dom' +import { matchPath, useLocation, useRouteMatch } from 'react-router-dom' import { captureException, captureMessage } from '@sentry/browser' import { omit } from 'lodash' - import { getEnvironmentType } from '../../../app/scripts/lib/util' import { PATH_NAME_MAP } from '../helpers/constants/routes' -import { getCurrentLocale } from '../ducks/metamask/metamask' -import { - getCurrentChainId, - getMetricsNetworkIdentifier, - txDataSelector, -} from '../selectors' -import { - getTrackMetaMetricsEvent, - METAMETRICS_ANONYMOUS_ID, - segment, -} from '../../../shared/modules/metametrics' +import { txDataSelector } from '../selectors' + +import { trackMetaMetricsEvent, trackMetaMetricsPage } from '../store/actions' + +// type imports +/** + * @typedef {import('../../../shared/constants/metametrics').MetaMetricsEventPayload} MetaMetricsEventPayload + * @typedef {import('../../../shared/constants/metametrics').MetaMetricsEventOptions} MetaMetricsEventOptions + * @typedef {import('../../../shared/constants/metametrics').MetaMetricsPageObject} MetaMetricsPageObject + * @typedef {import('../../../shared/constants/metametrics').MetaMetricsReferrerObject} MetaMetricsReferrerObject + */ + +// types +/** + * @typedef {Omit} UIMetricsEventPayload + */ +/** + * @typedef {( + * payload: UIMetricsEventPayload, + * options: MetaMetricsEventOptions + * ) => Promise} UITrackEventMethod + */ +/** + * @type {React.Context} + */ export const MetaMetricsContext = createContext(() => { captureException( Error( @@ -41,6 +54,14 @@ export const MetaMetricsContext = createContext(() => { const PATHS_TO_CHECK = Object.keys(PATH_NAME_MAP) +/** + * Returns the current page if it matches out route map, as well as the origin + * if there is a confirmation that was triggered by a dapp + * @returns {{ + * page?: MetaMetricsPageObject + * referrer?: MetaMetricsReferrerObject + * }} + */ function useSegmentContext() { const match = useRouteMatch({ path: PATHS_TO_CHECK, @@ -71,51 +92,25 @@ function useSegmentContext() { } export function MetaMetricsProvider({ children }) { - const metaMetricsId = useSelector((state) => state.metamask.metaMetricsId) - const participateInMetaMetrics = useSelector( - (state) => state.metamask.participateInMetaMetrics, - ) - const metaMetricsSendCount = useSelector( - (state) => state.metamask.metaMetricsSendCount, - ) - const locale = useSelector(getCurrentLocale) const location = useLocation() const context = useSegmentContext() - const network = useSelector(getMetricsNetworkIdentifier) - const chainId = useSelector(getCurrentChainId) - // Temporary until the background controller refactor merges: - const baseVersion = global.platform.getVersion() - const version = - process.env.METAMASK_ENVIRONMENT === 'production' - ? baseVersion - : `${baseVersion}-${process.env.METAMASK_ENVIRONMENT}` /** - * track a metametrics event - * - * @param {import('../../../shared/modules/metametrics').MetaMetricsEventPayload} payload - payload for event - * @returns undefined + * @type {UITrackEventMethod} */ - const trackEvent = useMemo(() => { - return getTrackMetaMetricsEvent(global.platform.getVersion(), () => ({ - context, - locale: locale.replace('_', '-'), - environmentType: getEnvironmentType(), - chainId, - network, - participateInMetaMetrics, - metaMetricsId, - metaMetricsSendCount, - })) - }, [ - network, - participateInMetaMetrics, - locale, - metaMetricsId, - metaMetricsSendCount, - chainId, - context, - ]) + const trackEvent = useCallback( + (payload, options) => { + trackMetaMetricsEvent( + { + ...payload, + environmentType: getEnvironmentType(), + ...context, + }, + options, + ) + }, + [context], + ) // Used to prevent double tracking page calls const previousMatch = useRef() @@ -128,72 +123,52 @@ export function MetaMetricsProvider({ children }) { */ useEffect(() => { const environmentType = getEnvironmentType() - if ( - (participateInMetaMetrics === null && - location.pathname.startsWith('/initialize')) || - participateInMetaMetrics - ) { - // Events that happen during initialization before the user opts into - // MetaMetrics will be anonymous - const idTrait = metaMetricsId ? 'userId' : 'anonymousId' - const idValue = metaMetricsId ?? METAMETRICS_ANONYMOUS_ID - const match = matchPath(location.pathname, { - path: PATHS_TO_CHECK, - exact: true, - strict: true, + const match = matchPath(location.pathname, { + path: PATHS_TO_CHECK, + exact: true, + strict: true, + }) + // Start by checking for a missing match route. If this falls through to + // the else if, then we know we have a matched route for tracking. + if (!match) { + captureMessage(`Segment page tracking found unmatched route`, { + extra: { + previousMatch, + currentPath: location.pathname, + }, }) - // Start by checking for a missing match route. If this falls through to - // the else if, then we know we have a matched route for tracking. - if (!match) { - captureMessage(`Segment page tracking found unmatched route`, { - extra: { - previousMatch, - currentPath: location.pathname, - }, - }) - } else if ( - previousMatch.current !== match.path && - !( - environmentType === 'notification' && - match.path === '/' && - previousMatch.current === undefined - ) - ) { - // When a notification window is open by a Dapp we do not want to track - // the initial home route load that can sometimes happen. To handle - // this we keep track of the previousMatch, and we skip the event track - // in the event that we are dealing with the initial load of the - // homepage - const { path, params } = match - const name = PATH_NAME_MAP[path] - segment.page({ - [idTrait]: idValue, + } else if ( + previousMatch.current !== match.path && + !( + environmentType === 'notification' && + match.path === '/' && + previousMatch.current === undefined + ) + ) { + // When a notification window is open by a Dapp we do not want to track + // the initial home route load that can sometimes happen. To handle + // this we keep track of the previousMatch, and we skip the event track + // in the event that we are dealing with the initial load of the + // homepage + const { path, params } = match + const name = PATH_NAME_MAP[path] + trackMetaMetricsPage( + { name, - properties: { - // We do not want to send addresses or accounts in any events - // Some routes include these as params. - params: omit(params, ['account', 'address']), - locale: locale.replace('_', '-'), - network, - environment_type: environmentType, - }, - context: { - ...context, - version, - }, - }) - } - previousMatch.current = match?.path + // We do not want to send addresses or accounts in any events + // Some routes include these as params. + params: omit(params, ['account', 'address']), + environmentType, + page: context.page, + referrer: context.referrer, + }, + { + isOptInPath: location.pathname.startsWith('/initialize'), + }, + ) } - }, [ - location, - version, - locale, - context, - network, - metaMetricsId, - participateInMetaMetrics, - ]) + previousMatch.current = match?.path + }, [location, context]) return ( diff --git a/ui/app/ducks/swaps/swaps.js b/ui/app/ducks/swaps/swaps.js index 9ff86dbd8..7f4c5df96 100644 --- a/ui/app/ducks/swaps/swaps.js +++ b/ui/app/ducks/swaps/swaps.js @@ -467,12 +467,7 @@ export const fetchQuotesAndSetQuoteState = ( metaMetricsEvent({ event: 'Quotes Requested', category: 'swaps', - }) - metaMetricsEvent({ - event: 'Quotes Requested', - category: 'swaps', - excludeMetaMetricsId: true, - properties: { + sensitiveProperties: { token_from: fromTokenSymbol, token_from_amount: String(inputValue), token_to: toTokenSymbol, @@ -518,12 +513,7 @@ export const fetchQuotesAndSetQuoteState = ( metaMetricsEvent({ event: 'No Quotes Available', category: 'swaps', - }) - metaMetricsEvent({ - event: 'No Quotes Available', - category: 'swaps', - excludeMetaMetricsId: true, - properties: { + sensitiveProperties: { token_from: fromTokenSymbol, token_from_amount: String(inputValue), token_to: toTokenSymbol, @@ -539,12 +529,7 @@ export const fetchQuotesAndSetQuoteState = ( metaMetricsEvent({ event: 'Quotes Received', category: 'swaps', - }) - metaMetricsEvent({ - event: 'Quotes Received', - category: 'swaps', - excludeMetaMetricsId: true, - properties: { + sensitiveProperties: { token_from: fromTokenSymbol, token_from_amount: String(inputValue), token_to: toTokenSymbol, @@ -671,16 +656,10 @@ export const signAndSendTransactions = (history, metaMetricsEvent) => { median_metamask_fee: usedQuote.savings?.medianMetaMaskFee, } - const metaMetricsConfig = { + metaMetricsEvent({ event: 'Swap Started', category: 'swaps', - } - - metaMetricsEvent({ ...metaMetricsConfig }) - metaMetricsEvent({ - ...metaMetricsConfig, - excludeMetaMetricsId: true, - properties: swapMetaData, + sensitiveProperties: swapMetaData, }) let finalApproveTxMeta diff --git a/ui/app/hooks/useMetricEvent.js b/ui/app/hooks/useMetricEvent.js index 352f95cc4..e428fc5d2 100644 --- a/ui/app/hooks/useMetricEvent.js +++ b/ui/app/hooks/useMetricEvent.js @@ -3,6 +3,12 @@ import { MetaMetricsContext } from '../contexts/metametrics' import { MetaMetricsContext as NewMetaMetricsContext } from '../contexts/metametrics.new' import { useEqualityCheck } from './useEqualityCheck' +// Type imports +/** + * @typedef {import('../contexts/metametrics.new').UIMetricsEventPayload} UIMetricsEventPayload + * @typedef {import('../../../shared/constants/metametrics').MetaMetricsEventOptions} MetaMetricsEventOptions + */ + export function useMetricEvent(config = {}, overrides = {}) { const metricsEvent = useContext(MetaMetricsContext) const trackEvent = useCallback(() => metricsEvent(config, overrides), [ @@ -17,21 +23,18 @@ export function useMetricEvent(config = {}, overrides = {}) { * track a metametrics event using segment * e.g metricsEvent({ event: 'Unlocked MetaMask', category: 'Navigation' }) * - * @param {Object} config - configuration object for the event to track - * @param {string} config.event - event name to track - * @param {string} config.category - category to associate event to - * @param {boolean} [config.isOptIn] - happened during opt in/out workflow - * @param {Object} [config.properties] - object of custom values to track, snake_case - * @param {number} [config.revenue] - amount of currency that event creates in revenue for MetaMask - * @param {string} [config.currency] - ISO 4127 format currency for events with revenue, defaults to US dollars - * @param {number} [config.value] - Abstract "value" that this event has for MetaMask. - * @return {() => undefined} function to execute the tracking event + * @param {UIMetricsEventPayload} payload - payload of the event to track + * @param {MetaMetricsEventOptions} options - options for handling/routing event + * @return {() => Promise} function to execute the tracking event */ -export function useNewMetricEvent(config) { - const memoizedConfig = useEqualityCheck(config) +export function useNewMetricEvent(payload, options) { + const memoizedPayload = useEqualityCheck(payload) + const memoizedOptions = useEqualityCheck(options) const metricsEvent = useContext(NewMetaMetricsContext) - return useCallback(() => metricsEvent(memoizedConfig), [ + + return useCallback(() => metricsEvent(memoizedPayload, memoizedOptions), [ metricsEvent, - memoizedConfig, + memoizedPayload, + memoizedOptions, ]) } diff --git a/ui/app/pages/first-time-flow/metametrics-opt-in/metametrics-opt-in.component.js b/ui/app/pages/first-time-flow/metametrics-opt-in/metametrics-opt-in.component.js index b859457e8..2b34662ce 100644 --- a/ui/app/pages/first-time-flow/metametrics-opt-in/metametrics-opt-in.component.js +++ b/ui/app/pages/first-time-flow/metametrics-opt-in/metametrics-opt-in.component.js @@ -113,6 +113,7 @@ export default class MetaMetricsOptIn extends Component { name: 'Metrics Opt Out', }, isOptIn: true, + flushImmediately: true, }) } } finally { @@ -136,6 +137,7 @@ export default class MetaMetricsOptIn extends Component { name: 'Metrics Opt In', }, isOptIn: true, + flushImmediately: true, }), ) } @@ -148,6 +150,7 @@ export default class MetaMetricsOptIn extends Component { }, isOptIn: true, metaMetricsId, + flushImmediately: true, }), ) await Promise.all(metrics) diff --git a/ui/app/store/actions.js b/ui/app/store/actions.js index f9d9de22d..474cdda67 100644 --- a/ui/app/store/actions.js +++ b/ui/app/store/actions.js @@ -2746,3 +2746,29 @@ export function getCurrentWindowTab() { dispatch(setCurrentWindowTab(currentWindowTab)) } } + +// MetaMetrics +/** + * @typedef {import('../../../shared/constants/metametrics').MetaMetricsEventPayload} MetaMetricsEventPayload + * @typedef {import('../../../shared/constants/metametrics').MetaMetricsEventOptions} MetaMetricsEventOptions + * @typedef {import('../../../shared/constants/metametrics').MetaMetricsPagePayload} MetaMetricsPagePayload + * @typedef {import('../../../shared/constants/metametrics').MetaMetricsPageOptions} MetaMetricsPageOptions + */ + +/** + * @param {MetaMetricsEventPayload} payload - details of the event to track + * @param {MetaMetricsEventOptions} options - options for routing/handling of event + * @returns {Promise} + */ +export function trackMetaMetricsEvent(payload, options) { + return promisifiedBackground.trackMetaMetricsEvent(payload, options) +} + +/** + * @param {MetaMetricsPagePayload} payload - details of the page viewed + * @param {MetaMetricsPageOptions} options - options for handling the page view + * @returns {void} + */ +export function trackMetaMetricsPage(payload, options) { + return promisifiedBackground.trackMetaMetricsPage(payload, options) +} From 97d268c8eea6aac630ae47b3c993cae1c4847f19 Mon Sep 17 00:00:00 2001 From: Dan J Miller Date: Wed, 2 Dec 2020 19:55:19 -0330 Subject: [PATCH 20/32] Remove use of ethgasstation; use metaswap /gasPrices api for gas price estimates (#9867) * Remove use of ethgassthat; use metaswap /gasPrices api for gas price estimates * Remove references to ethgasstation * Pass base to BigNumber constructor in fetchExternalBasicGasEstimates * Update ui/app/hooks/useTokenTracker.js Co-authored-by: Erik Marks <25517051+rekmarks@users.noreply.github.com> * Delete gas price chart * Remove price chart css import * Delete additional fee chart code * Lint fix * Delete more code no longer used after ethgasstation removal Co-authored-by: Erik Marks <25517051+rekmarks@users.noreply.github.com> --- app/_locales/am/messages.json | 15 - app/_locales/ar/messages.json | 15 - app/_locales/bg/messages.json | 15 - app/_locales/bn/messages.json | 15 - app/_locales/ca/messages.json | 15 - app/_locales/da/messages.json | 15 - app/_locales/de/messages.json | 15 - app/_locales/el/messages.json | 15 - app/_locales/en/messages.json | 31 - app/_locales/es/messages.json | 15 - app/_locales/es_419/messages.json | 15 - app/_locales/et/messages.json | 15 - app/_locales/fa/messages.json | 15 - app/_locales/fi/messages.json | 15 - app/_locales/fil/messages.json | 15 - app/_locales/fr/messages.json | 15 - app/_locales/he/messages.json | 15 - app/_locales/hi/messages.json | 15 - app/_locales/hr/messages.json | 15 - app/_locales/hu/messages.json | 15 - app/_locales/id/messages.json | 15 - app/_locales/it/messages.json | 18 - app/_locales/ja/messages.json | 3 - app/_locales/kn/messages.json | 15 - app/_locales/ko/messages.json | 15 - app/_locales/lt/messages.json | 15 - app/_locales/lv/messages.json | 15 - app/_locales/ms/messages.json | 15 - app/_locales/no/messages.json | 15 - app/_locales/pl/messages.json | 15 - app/_locales/pt_BR/messages.json | 15 - app/_locales/ro/messages.json | 15 - app/_locales/ru/messages.json | 15 - app/_locales/sk/messages.json | 15 - app/_locales/sl/messages.json | 15 - app/_locales/sr/messages.json | 15 - app/_locales/sv/messages.json | 15 - app/_locales/sw/messages.json | 15 - app/_locales/th/messages.json | 6 - app/_locales/uk/messages.json | 15 - app/_locales/zh_CN/messages.json | 15 - app/_locales/zh_TW/messages.json | 15 - app/scripts/controllers/preferences.js | 1 - development/build/scripts.js | 3 +- package.json | 2 - test/data/fetch-mocks.json | 5914 +---------------- test/e2e/webdriver/index.js | 9 +- .../advanced-tab-content.component.js | 49 +- .../advanced-tab-content/index.scss | 3 +- .../advanced-tab-content-component.test.js | 65 +- .../gas-modal-page-container.component.js | 26 +- .../gas-modal-page-container.container.js | 43 +- ...gas-modal-page-container-component.test.js | 46 +- ...gas-modal-page-container-container.test.js | 12 - .../gas-price-chart.component.js | 123 - .../gas-price-chart/gas-price-chart.utils.js | 422 -- .../gas-price-chart/index.js | 1 - .../gas-price-chart/index.scss | 134 - .../tests/gas-price-chart.component.test.js | 258 - .../app/gas-customization/index.scss | 1 - .../app/sidebars/sidebar-content.scss | 8 - .../transaction-list-item.component.js | 23 +- .../transaction-list.component.js | 59 +- ui/app/ducks/gas/gas-duck.test.js | 515 +- ui/app/ducks/gas/gas.duck.js | 388 +- .../helpers/utils/gas-time-estimates.util.js | 125 - .../hooks/tests/useRetryTransaction.test.js | 2 - ui/app/hooks/useRetryTransaction.js | 6 +- ui/app/hooks/useTransactionTimeRemaining.js | 126 - .../confirm-transaction.component.js | 6 +- .../confirm-transaction.container.js | 5 +- .../advanced-tab/advanced-tab.component.js | 32 - .../advanced-tab/advanced-tab.container.js | 5 +- .../tests/advanced-tab-component.test.js | 4 +- .../swaps/awaiting-swap/awaiting-swap.js | 105 +- ui/app/pages/swaps/index.js | 4 - ui/app/selectors/custom-gas.js | 88 +- ui/app/selectors/selectors.js | 7 - ui/app/selectors/tests/custom-gas.test.js | 90 - yarn.lock | 274 +- 80 files changed, 84 insertions(+), 9528 deletions(-) delete mode 100644 ui/app/components/app/gas-customization/gas-price-chart/gas-price-chart.component.js delete mode 100644 ui/app/components/app/gas-customization/gas-price-chart/gas-price-chart.utils.js delete mode 100644 ui/app/components/app/gas-customization/gas-price-chart/index.js delete mode 100644 ui/app/components/app/gas-customization/gas-price-chart/index.scss delete mode 100644 ui/app/components/app/gas-customization/gas-price-chart/tests/gas-price-chart.component.test.js delete mode 100644 ui/app/helpers/utils/gas-time-estimates.util.js delete mode 100644 ui/app/hooks/useTransactionTimeRemaining.js diff --git a/app/_locales/am/messages.json b/app/_locales/am/messages.json index 92ada3d3b..227bbcb84 100644 --- a/app/_locales/am/messages.json +++ b/app/_locales/am/messages.json @@ -167,9 +167,6 @@ "chainId": { "message": "የሰንሰለት መታወቂያ" }, - "chartOnlyAvailableEth": { - "message": "ቻርት የሚገኘው በ Ethereum አውታረ መረቦች ላይ ብቻ ነው።" - }, "chromeRequiredForHardwareWallets": { "message": "ከሃርድዌርዎ ቋት ጋር ለመገናኘት MetaMask በ Google Chrome ላይ መጠቀም አለብዎት።" }, @@ -398,9 +395,6 @@ "fast": { "message": "ፈጣን" }, - "faster": { - "message": "በፍጥነት" - }, "fiat": { "message": "ፊያት", "description": "Exchange type" @@ -579,9 +573,6 @@ "links": { "message": "ማስፈንጠሪያዎች" }, - "liveGasPricePredictions": { - "message": "ቀጥታ የነዳጅ ዋጋ ትንበያዎች" - }, "loadMore": { "message": "ተጨማሪ ጫን" }, @@ -1015,9 +1006,6 @@ "slow": { "message": "ቀስ" }, - "slower": { - "message": "ዘገምተኛ" - }, "somethingWentWrong": { "message": "ኤጭ! የሆነ ችግር ተፈጥሯል።" }, @@ -1162,9 +1150,6 @@ "transactionSubmitted": { "message": "ግብይቱ የቀረበው በነዳጅ ዋጋ $1በ$2ነው።" }, - "transactionTime": { - "message": "የግብይት ጊዜ" - }, "transactionUpdated": { "message": "ግብይት የዘመነው በ $2ነው።" }, diff --git a/app/_locales/ar/messages.json b/app/_locales/ar/messages.json index 070e0ab64..39a3df7c0 100644 --- a/app/_locales/ar/messages.json +++ b/app/_locales/ar/messages.json @@ -167,9 +167,6 @@ "chainId": { "message": "معرّف السلسلة" }, - "chartOnlyAvailableEth": { - "message": "الرسم البياني متاح فقط على شبكات إيثيريوم." - }, "chromeRequiredForHardwareWallets": { "message": "تحتاج إلى استخدام MetaMask على Google Chrome للاتصال بمحفظة الأجهزة الخاصة بك." }, @@ -398,9 +395,6 @@ "fast": { "message": "سريع" }, - "faster": { - "message": "أسرع" - }, "fileImportFail": { "message": "استيراد الملف لا ينجح؟ انقر هنا!", "description": "Helps user import their account from a JSON file" @@ -575,9 +569,6 @@ "links": { "message": "الروابط" }, - "liveGasPricePredictions": { - "message": "توقعات أسعار الجاس الحية" - }, "loadMore": { "message": "تحميل المزيد" }, @@ -1011,9 +1002,6 @@ "slow": { "message": "بطيء" }, - "slower": { - "message": "أبطأ" - }, "somethingWentWrong": { "message": "عذراً! حدث خطأ ما." }, @@ -1158,9 +1146,6 @@ "transactionSubmitted": { "message": "تم تقديم المعاملة برسوم $1 من عملة جاس في $2." }, - "transactionTime": { - "message": "وقت المعاملة" - }, "transactionUpdated": { "message": "تم تحديث المعاملة في $2." }, diff --git a/app/_locales/bg/messages.json b/app/_locales/bg/messages.json index 30c39d8cf..ec998b1ce 100644 --- a/app/_locales/bg/messages.json +++ b/app/_locales/bg/messages.json @@ -167,9 +167,6 @@ "chainId": { "message": "Идентификатор на веригата" }, - "chartOnlyAvailableEth": { - "message": "Диаграмата е достъпна само в мрежи на Ethereum." - }, "chromeRequiredForHardwareWallets": { "message": "За да се свържете с хардуерния си портфейл, трябва да използвате MetaMask в Google Chrome." }, @@ -398,9 +395,6 @@ "fast": { "message": "Бързо" }, - "faster": { - "message": "По-бързо" - }, "fileImportFail": { "message": "Импортирането на файл не работи? Натиснете тук!", "description": "Helps user import their account from a JSON file" @@ -575,9 +569,6 @@ "links": { "message": "Връзки" }, - "liveGasPricePredictions": { - "message": "Прогнози на живо за цената на газа" - }, "loadMore": { "message": "Зареди повече" }, @@ -1014,9 +1005,6 @@ "slow": { "message": "Бавно" }, - "slower": { - "message": "По-бавно" - }, "somethingWentWrong": { "message": "Упс! Нещо се обърка." }, @@ -1161,9 +1149,6 @@ "transactionSubmitted": { "message": "Транзакция, изпратена с такса за газ от $1 при $2." }, - "transactionTime": { - "message": "Време на транзакция" - }, "transactionUpdated": { "message": "Транзакцията е актуализирана на $2." }, diff --git a/app/_locales/bn/messages.json b/app/_locales/bn/messages.json index 3b07cc64f..2840c8470 100644 --- a/app/_locales/bn/messages.json +++ b/app/_locales/bn/messages.json @@ -167,9 +167,6 @@ "chainId": { "message": "চেন আইডি" }, - "chartOnlyAvailableEth": { - "message": "শুধুমাত্র Ethereum নেটওয়ার্কগুলিতে চার্ট উপলভ্য। " - }, "chromeRequiredForHardwareWallets": { "message": "আপনার হার্ডওয়্যার ওয়ালেটের সাথে সংযোগ করতে আপনাকে Google Chrome এ MetaMask ব্যবহার করতে হবে। " }, @@ -398,9 +395,6 @@ "fast": { "message": "দ্রুত" }, - "faster": { - "message": "দ্রুততর" - }, "fiat": { "message": "ফিয়াট", "description": "Exchange type" @@ -579,9 +573,6 @@ "links": { "message": "লিঙ্কসমূহ" }, - "liveGasPricePredictions": { - "message": "সরাসরি গ্যাসের মূল্যের অনুমান" - }, "loadMore": { "message": "আরও লোড করুন" }, @@ -1018,9 +1009,6 @@ "slow": { "message": "মন্থর" }, - "slower": { - "message": "ধীর গতির" - }, "somethingWentWrong": { "message": "ওহো! কিছু সমস্যা হয়েছে।" }, @@ -1165,9 +1153,6 @@ "transactionSubmitted": { "message": "$2 এ $1 এর গ্যাস ফী সহ লেনদেন জমা করা হয়েছে।" }, - "transactionTime": { - "message": "লেনদেনের সময়" - }, "transactionUpdated": { "message": "লেনদেন $2 এ আপডেট করা হয়েছে।" }, diff --git a/app/_locales/ca/messages.json b/app/_locales/ca/messages.json index 29b2bb7e3..571da2f5f 100644 --- a/app/_locales/ca/messages.json +++ b/app/_locales/ca/messages.json @@ -164,9 +164,6 @@ "chainId": { "message": "Cadena ID" }, - "chartOnlyAvailableEth": { - "message": "Mostra només els disponibles a les xarxes Ethereum." - }, "chromeRequiredForHardwareWallets": { "message": "Necessites fer servir MetaMask amb Google Chrome per a connectar-te al teu Moneder Hardware." }, @@ -395,9 +392,6 @@ "fast": { "message": "Ràpid" }, - "faster": { - "message": "Més ràpid" - }, "fileImportFail": { "message": "La importació no funciona? Fes clic aquí!", "description": "Helps user import their account from a JSON file" @@ -566,9 +560,6 @@ "links": { "message": "Enllaços" }, - "liveGasPricePredictions": { - "message": "Prediccions del preu del gas en directe" - }, "loadMore": { "message": "Carregar Més" }, @@ -996,9 +987,6 @@ "slow": { "message": "Lent" }, - "slower": { - "message": "Més lent" - }, "somethingWentWrong": { "message": "Ui! Alguna cosa ha fallat." }, @@ -1134,9 +1122,6 @@ "transactionSubmitted": { "message": "Transacció enviada amb un preu del gas de $1 a $2." }, - "transactionTime": { - "message": "Temps de transacció" - }, "transactionUpdated": { "message": "Transacció actualitzada a $2." }, diff --git a/app/_locales/da/messages.json b/app/_locales/da/messages.json index cb6109a44..f4765f987 100644 --- a/app/_locales/da/messages.json +++ b/app/_locales/da/messages.json @@ -167,9 +167,6 @@ "chainId": { "message": "Kæde-ID" }, - "chartOnlyAvailableEth": { - "message": "Skema kun tilgængeligt på Ethereum-netværk." - }, "chromeRequiredForHardwareWallets": { "message": "Du skal bruge MetaMask i Google Chrome for at forbinde med din Hardware Wallet." }, @@ -398,9 +395,6 @@ "fast": { "message": "Hurtig" }, - "faster": { - "message": "Hurtigere" - }, "fileImportFail": { "message": "Virker filimportering ikke? Klik her!", "description": "Helps user import their account from a JSON file" @@ -569,9 +563,6 @@ "likeToAddTokens": { "message": "Ønsker du at tilføje disse tokens?" }, - "liveGasPricePredictions": { - "message": "Live forudsigelser af brændstofpriser" - }, "loadMore": { "message": "Indlæs Mere" }, @@ -996,9 +987,6 @@ "slow": { "message": "Langsom" }, - "slower": { - "message": "Langsommere" - }, "somethingWentWrong": { "message": "Ups! Noget gik galt." }, @@ -1134,9 +1122,6 @@ "transactionSubmitted": { "message": "Transaktion indsendt med brændstofgebyr på $1 til $2." }, - "transactionTime": { - "message": "Transaktionstid" - }, "transactionUpdated": { "message": "Transaktion opdateret til $2." }, diff --git a/app/_locales/de/messages.json b/app/_locales/de/messages.json index c656bd935..bfd714822 100644 --- a/app/_locales/de/messages.json +++ b/app/_locales/de/messages.json @@ -158,9 +158,6 @@ "cancelled": { "message": "Abgebrochen" }, - "chartOnlyAvailableEth": { - "message": "Die Grafik ist nur in Ethereum-Netzwerken verfügbar." - }, "chromeRequiredForHardwareWallets": { "message": "Sie müssen MetaMask unter Google Chrome nutzen, um sich mit Ihrem Hardware-Wallet zu verbinden." }, @@ -386,9 +383,6 @@ "fast": { "message": "Schnell" }, - "faster": { - "message": "Schneller" - }, "fiat": { "message": "FIAT", "description": "Exchange type" @@ -564,9 +558,6 @@ "likeToAddTokens": { "message": "Möchtest du diese Token hinzufügen?" }, - "liveGasPricePredictions": { - "message": "Live-Gaspreisprognosen" - }, "loadMore": { "message": "Mehr laden" }, @@ -987,9 +978,6 @@ "slow": { "message": "Langsam" }, - "slower": { - "message": "Langsamer" - }, "somethingWentWrong": { "message": "Hoppla! Da hat etwas nicht geklappt." }, @@ -1128,9 +1116,6 @@ "transactionSubmitted": { "message": "Transaktion mit einer Gasgebühr von $1 bei $2 übermittelt." }, - "transactionTime": { - "message": "Transaktionszeit" - }, "transactionUpdated": { "message": "Transaktion für $2 aktualisiert." }, diff --git a/app/_locales/el/messages.json b/app/_locales/el/messages.json index 45d38521d..eab1d1077 100644 --- a/app/_locales/el/messages.json +++ b/app/_locales/el/messages.json @@ -164,9 +164,6 @@ "chainId": { "message": "Αναγνωριστικό Αλυσίδας" }, - "chartOnlyAvailableEth": { - "message": "Το διάγραμμα είναι διαθέσιμο μόνο σε δίκτυα Ethereum." - }, "chromeRequiredForHardwareWallets": { "message": "Θα πρέπει να χρησιμοποιήσετε το MetaMask στο Google Chrome για να συνδεθείτε στο Πορτοφόλι Υλικού." }, @@ -395,9 +392,6 @@ "fast": { "message": "Γρήγορα" }, - "faster": { - "message": "Πιο γρήγορα" - }, "fiat": { "message": "Εντολή", "description": "Exchange type" @@ -576,9 +570,6 @@ "links": { "message": "Σύνδεσμοι" }, - "liveGasPricePredictions": { - "message": "Ζωντανές Προβλέψεις Τιμής Καυσίμου" - }, "loadMore": { "message": "Φόρτωση Περισσότερων" }, @@ -1015,9 +1006,6 @@ "slow": { "message": "Αργά" }, - "slower": { - "message": "Πιο αργά" - }, "somethingWentWrong": { "message": "Ουπς! Κάτι πήγε στραβά." }, @@ -1159,9 +1147,6 @@ "transactionSubmitted": { "message": "Η συναλλαγή στάλθηκε με τέλος gas του $1 σε $2." }, - "transactionTime": { - "message": "Χρόνος Συναλλαγής" - }, "transactionUpdated": { "message": "Η συναλλαγή ενημερώθηκε σε $2." }, diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json index a3d5b5f4c..16e21905a 100644 --- a/app/_locales/en/messages.json +++ b/app/_locales/en/messages.json @@ -245,9 +245,6 @@ "chainId": { "message": "Chain ID" }, - "chartOnlyAvailableEth": { - "message": "Chart only available on Ethereum networks." - }, "chromeRequiredForHardwareWallets": { "message": "You need to use MetaMask on Google Chrome in order to connect to your Hardware Wallet." }, @@ -660,9 +657,6 @@ "fast": { "message": "Fast" }, - "faster": { - "message": "Faster" - }, "fastest": { "message": "Fastest" }, @@ -914,9 +908,6 @@ "links": { "message": "Links" }, - "liveGasPricePredictions": { - "message": "Live Gas Price Predictions" - }, "loadMore": { "message": "Load More" }, @@ -1491,9 +1482,6 @@ "showSeedPhrase": { "message": "Show seed phrase" }, - "showTransactionTimeDescription": { - "message": "Select this to display pending transaction time estimates in the activity tab while on the Ethereum Mainnet. Note: estimates are approximations based on network conditions." - }, "sigRequest": { "message": "Signature Request" }, @@ -1515,9 +1503,6 @@ "slow": { "message": "Slow" }, - "slower": { - "message": "Slower" - }, "somethingWentWrong": { "message": "Oops! Something went wrong." }, @@ -1654,16 +1639,6 @@ "swapEstimatedNetworkFeesInfo": { "message": "This is an estimate of the network fee that will be used to complete your swap. The actual amount may change according to network conditions." }, - "swapEstimatedTime": { - "message": "Estimated time:" - }, - "swapEstimatedTimeCalculating": { - "message": "Calculating..." - }, - "swapEstimatedTimeFull": { - "message": "$1 $2", - "description": "This message shows bolded swapEstimatedTime message, which is substited for $1, followed by either the estimated remaining transaction time in mm:ss, or the swapEstimatedTimeCalculating message, which are substituted for $2." - }, "swapFailedErrorDescription": { "message": "Your funds are safe and still available in your wallet." }, @@ -1871,9 +1846,6 @@ "swapsAdvancedOptions": { "message": "Advanced Options" }, - "swapsAlmostDone": { - "message": "Almost done..." - }, "swapsBestQuote": { "message": "Best quote" }, @@ -2012,9 +1984,6 @@ "transactionSubmitted": { "message": "Transaction submitted with gas fee of $1 at $2." }, - "transactionTime": { - "message": "Transaction Time" - }, "transactionUpdated": { "message": "Transaction updated at $2." }, diff --git a/app/_locales/es/messages.json b/app/_locales/es/messages.json index 542a8724f..55f77bb00 100644 --- a/app/_locales/es/messages.json +++ b/app/_locales/es/messages.json @@ -139,9 +139,6 @@ "chainId": { "message": "ID Cadena" }, - "chartOnlyAvailableEth": { - "message": "Tabla solo disponible en redes Ethereum." - }, "chromeRequiredForHardwareWallets": { "message": "Hay que usar MetaMask en Google Chrome para poder conectarse con tu Monedero Físico." }, @@ -322,9 +319,6 @@ "fast": { "message": "Rápido" }, - "faster": { - "message": "Más Rápido" - }, "fiat": { "message": "FIAT", "description": "Exchange type" @@ -470,9 +464,6 @@ "links": { "message": "Enlaces" }, - "liveGasPricePredictions": { - "message": "Previsiones en vivo del precio de Gas" - }, "loadMore": { "message": "Cargar Más" }, @@ -801,9 +792,6 @@ "slow": { "message": "Lento" }, - "slower": { - "message": "Más lento" - }, "somethingWentWrong": { "message": "¡Ups! Algo funcionó mal." }, @@ -912,9 +900,6 @@ "transactionSubmitted": { "message": "Se propuso la transacción con una comisión de gas de $1, en $2." }, - "transactionTime": { - "message": "Tiempo de Transacción" - }, "transactionUpdated": { "message": "Se actualizó la transacción en $2." }, diff --git a/app/_locales/es_419/messages.json b/app/_locales/es_419/messages.json index 46b86e032..1073b7e31 100644 --- a/app/_locales/es_419/messages.json +++ b/app/_locales/es_419/messages.json @@ -164,9 +164,6 @@ "chainId": { "message": "ID de cadena" }, - "chartOnlyAvailableEth": { - "message": "Chart está disponible únicamente en las redes de Ethereum." - }, "chromeRequiredForHardwareWallets": { "message": "Debes utilizar MetaMask en Google Chrome para poder conectarte a tu billetera de hardware." }, @@ -395,9 +392,6 @@ "fast": { "message": "Rápido" }, - "faster": { - "message": "Más rápido" - }, "fiat": { "message": "Dinero fiduciario", "description": "Exchange type" @@ -570,9 +564,6 @@ "links": { "message": "Enlaces" }, - "liveGasPricePredictions": { - "message": "Predicciones del precio del gas en vivo" - }, "loadMore": { "message": "Cargar más" }, @@ -1003,9 +994,6 @@ "slow": { "message": "Lento" }, - "slower": { - "message": "Más lento" - }, "somethingWentWrong": { "message": "¡Vaya! Se produjo un error." }, @@ -1144,9 +1132,6 @@ "transactionSubmitted": { "message": "Se envió la transacción con una tasa de gas de $1 en $2." }, - "transactionTime": { - "message": "Tiempo de transacción" - }, "transactionUpdated": { "message": "La transacción se actualizó en $2." }, diff --git a/app/_locales/et/messages.json b/app/_locales/et/messages.json index 93ae71db0..681daaac3 100644 --- a/app/_locales/et/messages.json +++ b/app/_locales/et/messages.json @@ -167,9 +167,6 @@ "chainId": { "message": "Ahela ID" }, - "chartOnlyAvailableEth": { - "message": "Tabel on saadaval vaid Ethereumi võrkudes." - }, "chromeRequiredForHardwareWallets": { "message": "Riistvararahakoti ühendamiseks peate kasutama MetaMaski Google Chrome'is." }, @@ -398,9 +395,6 @@ "fast": { "message": "Kiire" }, - "faster": { - "message": "Kiiremini" - }, "fileImportFail": { "message": "Faili importimine ei toimi? Klõpsake siia!", "description": "Helps user import their account from a JSON file" @@ -575,9 +569,6 @@ "links": { "message": "Lingid" }, - "liveGasPricePredictions": { - "message": "Gaasihinna prognoosid reaalajas" - }, "loadMore": { "message": "Laadi rohkem" }, @@ -1008,9 +999,6 @@ "slow": { "message": "Aeglane" }, - "slower": { - "message": "Aeglasem" - }, "somethingWentWrong": { "message": "Oih! Midagi läks valesti." }, @@ -1155,9 +1143,6 @@ "transactionSubmitted": { "message": "Tehing edastatud gaasihinnaga $1 asukohas $2." }, - "transactionTime": { - "message": "Tehingu aeg" - }, "transactionUpdated": { "message": "Tehing on uuendatud $2." }, diff --git a/app/_locales/fa/messages.json b/app/_locales/fa/messages.json index 5713eed42..15cb8b997 100644 --- a/app/_locales/fa/messages.json +++ b/app/_locales/fa/messages.json @@ -167,9 +167,6 @@ "chainId": { "message": "آی دی زنجیره" }, - "chartOnlyAvailableEth": { - "message": "تنها قابل دسترس را در شبکه های ایتریوم جدول بندی نمایید" - }, "chromeRequiredForHardwareWallets": { "message": "برای وصل شدن به کیف سخت افزار شما باید MetaMask را در گوگل کروم استفاده نمایید." }, @@ -398,9 +395,6 @@ "fast": { "message": "سریع" }, - "faster": { - "message": "سریع تر" - }, "fiat": { "message": "حکم قانونی", "description": "Exchange type" @@ -579,9 +573,6 @@ "links": { "message": "لینک ها" }, - "liveGasPricePredictions": { - "message": "پیش بینی های قیمت گاز" - }, "loadMore": { "message": "بارگیری بیشتر" }, @@ -1018,9 +1009,6 @@ "slow": { "message": "آهسته" }, - "slower": { - "message": "آهسته تر" - }, "somethingWentWrong": { "message": "اوه! مشکلی پیش آمده." }, @@ -1165,9 +1153,6 @@ "transactionSubmitted": { "message": "معامله با فیس گاز 1$1 در 2$2 ارائه شد." }, - "transactionTime": { - "message": "زمان معامله" - }, "transactionUpdated": { "message": "معامله به 1$2 بروزرسانی شد." }, diff --git a/app/_locales/fi/messages.json b/app/_locales/fi/messages.json index 76eab95d3..1aa3be909 100644 --- a/app/_locales/fi/messages.json +++ b/app/_locales/fi/messages.json @@ -167,9 +167,6 @@ "chainId": { "message": "Ketjun tunnus" }, - "chartOnlyAvailableEth": { - "message": "Kaavio saatavilla vain Ethereum-verkoissa." - }, "chromeRequiredForHardwareWallets": { "message": "Sinun tarvitsee käyttää MetaMaskia Google Chromessa voidaksesi yhdistää laitteistokukkaroosi." }, @@ -398,9 +395,6 @@ "fast": { "message": "Nopea" }, - "faster": { - "message": "Nopeammin" - }, "fiat": { "message": "Kiinteä", "description": "Exchange type" @@ -579,9 +573,6 @@ "links": { "message": "Linkit" }, - "liveGasPricePredictions": { - "message": "Polttoaineen hintojen live-ennusteet" - }, "loadMore": { "message": "Lataa lisää" }, @@ -1015,9 +1006,6 @@ "slow": { "message": "Hidas" }, - "slower": { - "message": "Hitaammin" - }, "somethingWentWrong": { "message": "Hupsis! Jotakin meni pieleen." }, @@ -1162,9 +1150,6 @@ "transactionSubmitted": { "message": "Tapahtuma toimitettu $1 bensataksalla kohdassa $2." }, - "transactionTime": { - "message": "Tapahtuman aika" - }, "transactionUpdated": { "message": "Tapahtuma päivitetty – $2." }, diff --git a/app/_locales/fil/messages.json b/app/_locales/fil/messages.json index 150838e9c..fa048b96d 100644 --- a/app/_locales/fil/messages.json +++ b/app/_locales/fil/messages.json @@ -146,9 +146,6 @@ "cancelled": { "message": "Nakansela" }, - "chartOnlyAvailableEth": { - "message": "Available lang ang chart sa mga Ethereum network." - }, "chromeRequiredForHardwareWallets": { "message": "Kailangan mong gamitin ang MetaMask sa Google Chrome upang makakonekta sa iyong Hardware Wallet." }, @@ -371,9 +368,6 @@ "fast": { "message": "Mabilis" }, - "faster": { - "message": "Mas Mabilis" - }, "fileImportFail": { "message": "Hindi gumagana ang pag-import ng file? Mag-click dito!", "description": "Helps user import their account from a JSON file" @@ -529,9 +523,6 @@ "links": { "message": "Mga Link" }, - "liveGasPricePredictions": { - "message": "Mga Live na Prediksyon sa Presyo ng Gas" - }, "loadMore": { "message": "Mag-load Pa" }, @@ -924,9 +915,6 @@ "slow": { "message": "Mabagal" }, - "slower": { - "message": "Mas Mabagal" - }, "somethingWentWrong": { "message": "Oops! Nagkaroon ng problema." }, @@ -1062,9 +1050,6 @@ "transactionSubmitted": { "message": "Nasumite ang transaksyon nang may gas fee na $1 sa $2." }, - "transactionTime": { - "message": "Oras ng Transaksyon" - }, "transactionUpdated": { "message": "Na-update ang transaksyon sa $2." }, diff --git a/app/_locales/fr/messages.json b/app/_locales/fr/messages.json index 69f7ffb2c..f05faf62c 100644 --- a/app/_locales/fr/messages.json +++ b/app/_locales/fr/messages.json @@ -158,9 +158,6 @@ "chainId": { "message": "ID de chaîne" }, - "chartOnlyAvailableEth": { - "message": "Tableau disponible uniquement sur les réseaux Ethereum." - }, "chromeRequiredForHardwareWallets": { "message": "Pour connecter votre portefeuille hardware, vous devez utiliser MetaMask pour Google Chrome." }, @@ -389,9 +386,6 @@ "fast": { "message": "Rapide" }, - "faster": { - "message": "Plus rapide" - }, "fiat": { "message": "FIAT", "description": "Exchange type" @@ -573,9 +567,6 @@ "links": { "message": "Liens" }, - "liveGasPricePredictions": { - "message": "Prévisions des prix de l'essence en direct" - }, "loadMore": { "message": "Charger plus" }, @@ -1000,9 +991,6 @@ "slow": { "message": "Lente" }, - "slower": { - "message": "Plus lent" - }, "somethingWentWrong": { "message": "Oups ! Quelque chose a mal tourné. " }, @@ -1141,9 +1129,6 @@ "transactionSubmitted": { "message": "Transaction envoyée sur $2." }, - "transactionTime": { - "message": "Heure de la transaction" - }, "transactionUpdated": { "message": "Transaction mise à jour sur $2." }, diff --git a/app/_locales/he/messages.json b/app/_locales/he/messages.json index b2642a218..71900e7e7 100644 --- a/app/_locales/he/messages.json +++ b/app/_locales/he/messages.json @@ -167,9 +167,6 @@ "chainId": { "message": "מזהה שרשרת" }, - "chartOnlyAvailableEth": { - "message": "טבלה זמינה רק ברשתות אתריום." - }, "chromeRequiredForHardwareWallets": { "message": "עליך להשתמש ב-MetaMask בגוגל כרום כדי להתחבר לארנק החומרה שלך." }, @@ -398,9 +395,6 @@ "fast": { "message": "מהיר" }, - "faster": { - "message": "מהר יותר" - }, "fiat": { "message": "פיאט", "description": "Exchange type" @@ -579,9 +573,6 @@ "links": { "message": "קישורים" }, - "liveGasPricePredictions": { - "message": "תחזיות מחירי גז בשידור חי" - }, "loadMore": { "message": "טען עוד" }, @@ -1012,9 +1003,6 @@ "slow": { "message": "אטי" }, - "slower": { - "message": "לאט יותר" - }, "somethingWentWrong": { "message": "אופס! משהו השתבש." }, @@ -1159,9 +1147,6 @@ "transactionSubmitted": { "message": "עסקה הוגשה עם עמלת דלק של $1 ב-$2." }, - "transactionTime": { - "message": "זמן העסקה" - }, "transactionUpdated": { "message": "העסקה עודכנה ב- $2." }, diff --git a/app/_locales/hi/messages.json b/app/_locales/hi/messages.json index f759ed46a..3cba3b1d1 100644 --- a/app/_locales/hi/messages.json +++ b/app/_locales/hi/messages.json @@ -167,9 +167,6 @@ "chainId": { "message": "चेन आई.डी." }, - "chartOnlyAvailableEth": { - "message": "केवल ईथरअम नेटवर्क पर उपलब्ध चार्ट।" - }, "chromeRequiredForHardwareWallets": { "message": "अपने हार्डवेयर वॉलेट से कनेक्ट करने के लिए आपको Google Chrome में MetaMask का उपयोग करना ज़रूरी है।" }, @@ -398,9 +395,6 @@ "fast": { "message": "तेज़" }, - "faster": { - "message": "तीव्र" - }, "fiat": { "message": "फ़्लैट", "description": "Exchange type" @@ -576,9 +570,6 @@ "likeToAddTokens": { "message": "क्या आप इन टोकन को जोड़ना चाहेंगे?" }, - "liveGasPricePredictions": { - "message": "लाइव गैस की कीमत की भविष्यवाणी" - }, "loadMore": { "message": "और लोड करें" }, @@ -1012,9 +1003,6 @@ "slow": { "message": "धीमा" }, - "slower": { - "message": "धीमा" - }, "somethingWentWrong": { "message": "ओह! कुछ गलत हो गया।" }, @@ -1159,9 +1147,6 @@ "transactionSubmitted": { "message": "$2 पर $1 के गैस शुल्क के साथ ट्रांज़ैक्शन दर्ज किया गया।" }, - "transactionTime": { - "message": "ट्रांज़ैक्शन का समय" - }, "transactionUpdated": { "message": "$2 पर ट्रांज़ैक्शन अपडेट किया गया।" }, diff --git a/app/_locales/hr/messages.json b/app/_locales/hr/messages.json index eb4f9eae1..42ffcb611 100644 --- a/app/_locales/hr/messages.json +++ b/app/_locales/hr/messages.json @@ -167,9 +167,6 @@ "chainId": { "message": "Identifikacijska oznaka bloka" }, - "chartOnlyAvailableEth": { - "message": "Grafikon je dostupan samo na mrežama Ethereum." - }, "chromeRequiredForHardwareWallets": { "message": "Trebate upotrebljavati MetaMask u pregledniku Google Chrome kako biste ga povezali s vašim hardverskim novčanikom." }, @@ -398,9 +395,6 @@ "fast": { "message": "Brzo" }, - "faster": { - "message": "Brže" - }, "fileImportFail": { "message": "Uvoženje datoteke ne radi? Kliknite ovdje.", "description": "Helps user import their account from a JSON file" @@ -575,9 +569,6 @@ "links": { "message": "Poveznice" }, - "liveGasPricePredictions": { - "message": "Predviđanja uživo za cijenu goriva" - }, "loadMore": { "message": "Učitaj više" }, @@ -1011,9 +1002,6 @@ "slow": { "message": "Sporo" }, - "slower": { - "message": "Sporije" - }, "somethingWentWrong": { "message": "Ups! Nešto je pošlo po zlu." }, @@ -1155,9 +1143,6 @@ "transactionSubmitted": { "message": "Transakcija je poslana s naknadom za gorivo od $1 u $2." }, - "transactionTime": { - "message": "Vrijeme transkacije" - }, "transactionUpdated": { "message": "Transakcija je ažurirana u $2." }, diff --git a/app/_locales/hu/messages.json b/app/_locales/hu/messages.json index effc61461..cf3dda940 100644 --- a/app/_locales/hu/messages.json +++ b/app/_locales/hu/messages.json @@ -167,9 +167,6 @@ "chainId": { "message": "Lánc azonosítója" }, - "chartOnlyAvailableEth": { - "message": "A diagram csak Ethereum hálózatokon érhető el" - }, "chromeRequiredForHardwareWallets": { "message": "A MetaMask-ot Google Chrome-mal kell használnia a Hardveres pénztárcához való csatlakozáshoz." }, @@ -398,9 +395,6 @@ "fast": { "message": "Gyors" }, - "faster": { - "message": "Gyorsabban" - }, "fileImportFail": { "message": "Nem működik a fájl importálása? Kattintson ide!", "description": "Helps user import their account from a JSON file" @@ -575,9 +569,6 @@ "links": { "message": "Linkek" }, - "liveGasPricePredictions": { - "message": "Élő előrejelzések gázárak alakulására" - }, "loadMore": { "message": "Továbbiak betöltése" }, @@ -1011,9 +1002,6 @@ "slow": { "message": "Lassú" }, - "slower": { - "message": "Lassabban" - }, "somethingWentWrong": { "message": "Hoppá! Valami hiba történt..." }, @@ -1155,9 +1143,6 @@ "transactionSubmitted": { "message": "Tranzakció jóváhagyva $1 üzemanyag költséggel $2-kor." }, - "transactionTime": { - "message": "Tranzakció ideje" - }, "transactionUpdated": { "message": "Tranzakció frissítve $2-nál" }, diff --git a/app/_locales/id/messages.json b/app/_locales/id/messages.json index fceea2c05..da00b134a 100644 --- a/app/_locales/id/messages.json +++ b/app/_locales/id/messages.json @@ -167,9 +167,6 @@ "chainId": { "message": "ID Rantai" }, - "chartOnlyAvailableEth": { - "message": "Grafik hanya tersedia pada jaringan Ethereum." - }, "chromeRequiredForHardwareWallets": { "message": "Anda harus menggunakan MetaMask di Google Chrome untuk menyambung ke dompet Perangkat Keras Anda." }, @@ -392,9 +389,6 @@ "fast": { "message": "Cepat" }, - "faster": { - "message": "Lebih Cepat" - }, "fileImportFail": { "message": "Impor berkas tidak tersedia? Klik di sini!", "description": "Helps user import their account from a JSON file" @@ -569,9 +563,6 @@ "links": { "message": "Tautan" }, - "liveGasPricePredictions": { - "message": "Prediksi Harga Gas Langsung" - }, "loadMore": { "message": "Muat Lainnya" }, @@ -1002,9 +993,6 @@ "slow": { "message": "Lambat" }, - "slower": { - "message": "Lebih Lambat" - }, "somethingWentWrong": { "message": "Ups! Terjadi sesuatu." }, @@ -1143,9 +1131,6 @@ "transactionSubmitted": { "message": "Transaksi diajukan dengan biaya gas sebesar $1 di $2." }, - "transactionTime": { - "message": "Waktu Transaksi" - }, "transactionUpdated": { "message": "Transaksi diperbarui di $2." }, diff --git a/app/_locales/it/messages.json b/app/_locales/it/messages.json index da1dcdc8b..f0a6c950d 100644 --- a/app/_locales/it/messages.json +++ b/app/_locales/it/messages.json @@ -229,9 +229,6 @@ "chainId": { "message": "Blockchain ID" }, - "chartOnlyAvailableEth": { - "message": "Grafico disponibile solo per le reti Ethereum." - }, "chromeRequiredForHardwareWallets": { "message": "Devi usare MetaMask con Google Chrome per connettere il tuo Portafoglio Hardware" }, @@ -630,9 +627,6 @@ "fast": { "message": "Veloce" }, - "faster": { - "message": "Più veloce" - }, "feeAssociatedRequest": { "message": "Una tassa è associata a questa richiesta." }, @@ -851,9 +845,6 @@ "links": { "message": "Collegamenti" }, - "liveGasPricePredictions": { - "message": "Previsione del prezzo del gas in tempo reale" - }, "loadMore": { "message": "Carica di più" }, @@ -1382,9 +1373,6 @@ "showSeedPhrase": { "message": "Mostra frase seed" }, - "showTransactionTimeDescription": { - "message": "Seleziona per mostrare nella scheda attività una stima dei tempi di transazione per le transazioni in corso sulla rete Ethereum principale. Nota: la stima è approssimativa basata sulle condizioni della rete." - }, "sigRequest": { "message": "Firma Richiesta" }, @@ -1406,9 +1394,6 @@ "slow": { "message": "Lenta" }, - "slower": { - "message": "Più lenta" - }, "somethingWentWrong": { "message": "Oops! Qualcosa è andato storto." }, @@ -1600,9 +1585,6 @@ "transactionSubmitted": { "message": "Transazione inviata alle $2." }, - "transactionTime": { - "message": "Tempo Conferma Transazione" - }, "transactionUpdated": { "message": "Transazione aggiornata alle $2." }, diff --git a/app/_locales/ja/messages.json b/app/_locales/ja/messages.json index e0360ced8..728676097 100644 --- a/app/_locales/ja/messages.json +++ b/app/_locales/ja/messages.json @@ -115,9 +115,6 @@ "cancel": { "message": "キャンセル" }, - "chartOnlyAvailableEth": { - "message": "チャートはEthereumネットワークでのみ利用可能です。" - }, "confirm": { "message": "確認" }, diff --git a/app/_locales/kn/messages.json b/app/_locales/kn/messages.json index baeeba4a0..8c6c0a9e1 100644 --- a/app/_locales/kn/messages.json +++ b/app/_locales/kn/messages.json @@ -167,9 +167,6 @@ "chainId": { "message": "ಚೈನ್ ID" }, - "chartOnlyAvailableEth": { - "message": "ಎಥೆರಿಯಮ್ ನೆಟ್‌ವರ್ಕ್‌ಗಳಲ್ಲಿ ಮಾತ್ರವೇ ಚಾರ್ಟ್‌ಗಳು ಲಭ್ಯವಿರುತ್ತವೆ." - }, "chromeRequiredForHardwareWallets": { "message": "ನಿಮ್ಮ ಹಾರ್ಡ್‌ವೇರ್ ವ್ಯಾಲೆಟ್‌ಗೆ ಸಂಪರ್ಕಪಡಿಸುವ ಸಲುವಾಗಿ Google Chrome ನಲ್ಲಿ ನಿಮಗೆ MetaMask ಅನ್ನು ಬಳಸುವ ಅಗತ್ಯವಿದೆ." }, @@ -398,9 +395,6 @@ "fast": { "message": "ವೇಗ" }, - "faster": { - "message": "ವೇಗವಾಗಿ" - }, "fiat": { "message": "ಫಿಯೆಟ್", "description": "Exchange type" @@ -579,9 +573,6 @@ "links": { "message": "ಲಿಂಕ್‌ಗಳು" }, - "liveGasPricePredictions": { - "message": "ಲೈವ್ ಗ್ಯಾಸ್ ಬೆಲೆಯ ಭವಿಷ್ಯಗಳು" - }, "loadMore": { "message": "ಇನ್ನಷ್ಟು ಲೋಡ್ ಮಾಡಿ" }, @@ -1018,9 +1009,6 @@ "slow": { "message": "ನಿಧಾನ" }, - "slower": { - "message": "ನಿಧಾನ" - }, "somethingWentWrong": { "message": "ಓಹ್‌‍! ಏನೋ ತಪ್ಪಾಗಿದೆ." }, @@ -1165,9 +1153,6 @@ "transactionSubmitted": { "message": "ವಹಿವಾಟನ್ನು $2 ನಲ್ಲಿ $1 ಗ್ಯಾಸ್ ಶುಲ್ಕದೊಂದಿಗೆ ರಚಿಸಲಾಗಿದೆ." }, - "transactionTime": { - "message": "ವಹಿವಾಟು ಸಮಯ" - }, "transactionUpdated": { "message": "$2 ನಲ್ಲಿ ವಹಿವಾಟನ್ನು ನವೀಕರಿಸಲಾಗಿದೆ." }, diff --git a/app/_locales/ko/messages.json b/app/_locales/ko/messages.json index 1b16838f1..43c6278b1 100644 --- a/app/_locales/ko/messages.json +++ b/app/_locales/ko/messages.json @@ -164,9 +164,6 @@ "chainId": { "message": "체인 ID" }, - "chartOnlyAvailableEth": { - "message": "이더리움 네트워크에서만 사용 가능한 차트." - }, "chromeRequiredForHardwareWallets": { "message": "하드웨어 지갑을 연결하기 위해서는 구글 크롬에서 메타마스크를 사용하셔야 합니다." }, @@ -395,9 +392,6 @@ "fast": { "message": "빠름" }, - "faster": { - "message": "빨라짐" - }, "fiat": { "message": "FIAT", "description": "Exchange type" @@ -573,9 +567,6 @@ "links": { "message": "링크" }, - "liveGasPricePredictions": { - "message": "실시간 가스 가격 예측" - }, "loadMore": { "message": "더 많이 로딩" }, @@ -1009,9 +1000,6 @@ "slow": { "message": "느림" }, - "slower": { - "message": "느려짐" - }, "somethingWentWrong": { "message": "헉! 뭔가 잘못됐어요." }, @@ -1156,9 +1144,6 @@ "transactionSubmitted": { "message": "$1의 가스 요금으로 트랜잭션이 제출됨 $2." }, - "transactionTime": { - "message": "트랜잭션 시간" - }, "transactionUpdated": { "message": "트랜잭션이 수정됨 $2." }, diff --git a/app/_locales/lt/messages.json b/app/_locales/lt/messages.json index 37b05da6e..3158cb579 100644 --- a/app/_locales/lt/messages.json +++ b/app/_locales/lt/messages.json @@ -167,9 +167,6 @@ "chainId": { "message": "Grandinės ID" }, - "chartOnlyAvailableEth": { - "message": "Diagramos yra tik „Ethereum“ tinkluose." - }, "chromeRequiredForHardwareWallets": { "message": "Norėdami prisijungti prie aparatinės įrangos slaptažodinės, „MetaMask“ naudokitės „Google Chrome“ naršyklėje." }, @@ -398,9 +395,6 @@ "fast": { "message": "Greitas" }, - "faster": { - "message": "Greičiau" - }, "fiat": { "message": "Standartinė valiuta", "description": "Exchange type" @@ -579,9 +573,6 @@ "links": { "message": "Nuorodos" }, - "liveGasPricePredictions": { - "message": "Tiesioginiai dujų kainos spėjimai" - }, "loadMore": { "message": "Įkelti daugiau" }, @@ -1018,9 +1009,6 @@ "slow": { "message": "Lėtas" }, - "slower": { - "message": "Lėčiau" - }, "somethingWentWrong": { "message": "Vaje! Kažkas negerai." }, @@ -1165,9 +1153,6 @@ "transactionSubmitted": { "message": "Operacija pateikta $2 su $1 dujų mokesčiu." }, - "transactionTime": { - "message": "Operacijos laikas" - }, "transactionUpdated": { "message": "Operacija atnaujinta$2." }, diff --git a/app/_locales/lv/messages.json b/app/_locales/lv/messages.json index 1586d9f5b..43b5a6375 100644 --- a/app/_locales/lv/messages.json +++ b/app/_locales/lv/messages.json @@ -167,9 +167,6 @@ "chainId": { "message": "Ķēdes ID" }, - "chartOnlyAvailableEth": { - "message": "Grafiks pieejams vienīgi Ethereum tīklos." - }, "chromeRequiredForHardwareWallets": { "message": "MetaMask ir jāpalaiž pārlūkprogrammā Google Chrome, lai varētu pievienot aparatūras maku." }, @@ -398,9 +395,6 @@ "fast": { "message": "Ātrs" }, - "faster": { - "message": "Ātrāk" - }, "fileImportFail": { "message": "Vai faila importēšanas iespēja nedarbojas? Klikšķiniet šeit!", "description": "Helps user import their account from a JSON file" @@ -575,9 +569,6 @@ "links": { "message": "Saites" }, - "liveGasPricePredictions": { - "message": "Reāllaika Gas cenu prognozes" - }, "loadMore": { "message": "Ielādēt vairāk" }, @@ -1014,9 +1005,6 @@ "slow": { "message": "Lēns" }, - "slower": { - "message": "Lēnāk" - }, "somethingWentWrong": { "message": "Ak vai! Radās problēma." }, @@ -1161,9 +1149,6 @@ "transactionSubmitted": { "message": "Darījums iesniegts ar maksu par Gas $1 pie $2." }, - "transactionTime": { - "message": "Darījuma ilgums" - }, "transactionUpdated": { "message": "Darījums atjaunināts $2." }, diff --git a/app/_locales/ms/messages.json b/app/_locales/ms/messages.json index d141c683b..e64b4f582 100644 --- a/app/_locales/ms/messages.json +++ b/app/_locales/ms/messages.json @@ -167,9 +167,6 @@ "chainId": { "message": "ID Rantaian" }, - "chartOnlyAvailableEth": { - "message": "Carta hanya tersedia di rangkaian Ethereum." - }, "chromeRequiredForHardwareWallets": { "message": "Anda perlu menggunakan MetaMask di Google Chrome untuk menyambung kepada Dompet Perkakasan anda." }, @@ -392,9 +389,6 @@ "fast": { "message": "Cepat" }, - "faster": { - "message": "Lebih cepat" - }, "fileImportFail": { "message": "Pengimportan fail tidak berfungsi? Klik di sini!", "description": "Helps user import their account from a JSON file" @@ -565,9 +559,6 @@ "links": { "message": "Pautan" }, - "liveGasPricePredictions": { - "message": "Ramalan Harga Gas Langsung" - }, "loadMore": { "message": "Muat Lagi" }, @@ -995,9 +986,6 @@ "slow": { "message": "Perlahan" }, - "slower": { - "message": "Lebih Perlahan" - }, "somethingWentWrong": { "message": "Alamak! Ada yang tak kena." }, @@ -1139,9 +1127,6 @@ "transactionSubmitted": { "message": "Transaksi dihantar dengan fi gas sebanyak $1 pada $2." }, - "transactionTime": { - "message": "Masa Transaksi" - }, "transactionUpdated": { "message": "Transaksi dikemaskini pada $2." }, diff --git a/app/_locales/no/messages.json b/app/_locales/no/messages.json index 80f116b75..816ea9ed8 100644 --- a/app/_locales/no/messages.json +++ b/app/_locales/no/messages.json @@ -164,9 +164,6 @@ "chainId": { "message": "Blokkjede " }, - "chartOnlyAvailableEth": { - "message": "Diagram kun tilgjengelig på Ethereum-nettverk." - }, "chromeRequiredForHardwareWallets": { "message": "Du må bruke MetaMask på Google Chrome for å koble deg til maskinvare-lommeboken." }, @@ -395,9 +392,6 @@ "fast": { "message": "Høy" }, - "faster": { - "message": "Raskere " - }, "fileImportFail": { "message": "Virker ikke filimporteringen? Trykk her!", "description": "Helps user import their account from a JSON file" @@ -566,9 +560,6 @@ "links": { "message": "Lenker " }, - "liveGasPricePredictions": { - "message": "Prisforutsigelse av datakraft i sanntid" - }, "loadMore": { "message": "Last mer " }, @@ -996,9 +987,6 @@ "slow": { "message": "Lav" }, - "slower": { - "message": "Saktere" - }, "somethingWentWrong": { "message": "Oisann! Noe gikk galt. " }, @@ -1137,9 +1125,6 @@ "transactionSubmitted": { "message": "Transaksjon sendt med datakraftavgift på $1 til $2." }, - "transactionTime": { - "message": "Transaksjonstid" - }, "transactionUpdated": { "message": "Transaksjonen oppdatert på $2." }, diff --git a/app/_locales/pl/messages.json b/app/_locales/pl/messages.json index 7f3dc09a9..e1a1c8c9a 100644 --- a/app/_locales/pl/messages.json +++ b/app/_locales/pl/messages.json @@ -167,9 +167,6 @@ "chainId": { "message": "Identyfikator łańcucha" }, - "chartOnlyAvailableEth": { - "message": "Wykres dostępny tylko w sieciach Ethereum" - }, "chromeRequiredForHardwareWallets": { "message": "Żeby połączyć się z portfelem sprzętowym, należy uruchomić MetaMask z przeglądarką Google Chrome." }, @@ -398,9 +395,6 @@ "fast": { "message": "Szybko" }, - "faster": { - "message": "Szybciej" - }, "fiat": { "message": "FIAT", "description": "Exchange type" @@ -579,9 +573,6 @@ "links": { "message": "Łącza" }, - "liveGasPricePredictions": { - "message": "Przewidywanie ceny gazu na żywo" - }, "loadMore": { "message": "Załaduj więcej" }, @@ -1012,9 +1003,6 @@ "slow": { "message": "Powoli" }, - "slower": { - "message": "Wolniej" - }, "somethingWentWrong": { "message": "Ups! Coś poszło nie tak." }, @@ -1153,9 +1141,6 @@ "transactionSubmitted": { "message": "Transakcja wykonana z opłatą za gaz w wysokości $1 – $2." }, - "transactionTime": { - "message": "Czas transakcji" - }, "transactionUpdated": { "message": "Transakcja zaktualizowana – $2." }, diff --git a/app/_locales/pt_BR/messages.json b/app/_locales/pt_BR/messages.json index 8973b3544..154668b75 100644 --- a/app/_locales/pt_BR/messages.json +++ b/app/_locales/pt_BR/messages.json @@ -161,9 +161,6 @@ "chainId": { "message": "ID da Cadeia" }, - "chartOnlyAvailableEth": { - "message": "Tabela disponível apenas em redes de Ethereum." - }, "chromeRequiredForHardwareWallets": { "message": "Você precisa usar o MetaMask no Google Chrome para se conectar à sua Carteira de Hardware." }, @@ -392,9 +389,6 @@ "fast": { "message": "Rápido" }, - "faster": { - "message": "Mais rápido" - }, "fiat": { "message": "Ordem", "description": "Exchange type" @@ -570,9 +564,6 @@ "likeToAddTokens": { "message": "Deseja adicionar esses tokens?" }, - "liveGasPricePredictions": { - "message": "Previsões de Preços de Gás Ao Vivo" - }, "loadMore": { "message": "Carregar Mais" }, @@ -1006,9 +997,6 @@ "slow": { "message": "Lento" }, - "slower": { - "message": "Mais lento" - }, "somethingWentWrong": { "message": "Opa! Algo deu errado." }, @@ -1147,9 +1135,6 @@ "transactionSubmitted": { "message": "Transação enviada com taxa de gás de $1 a $2." }, - "transactionTime": { - "message": "Hora da Transação" - }, "transactionUpdated": { "message": "Transação atualizada às $2." }, diff --git a/app/_locales/ro/messages.json b/app/_locales/ro/messages.json index 890b5758b..7c5cc0c8a 100644 --- a/app/_locales/ro/messages.json +++ b/app/_locales/ro/messages.json @@ -167,9 +167,6 @@ "chainId": { "message": "ID lanț" }, - "chartOnlyAvailableEth": { - "message": "Grafic disponibil numai pe rețelele Ethereum." - }, "chromeRequiredForHardwareWallets": { "message": "Trebuie să folosiți MetaMask în Google Chrome pentru a vă conecta la portofelul hardware." }, @@ -398,9 +395,6 @@ "fast": { "message": "Rapid" }, - "faster": { - "message": "Mai repede" - }, "fileImportFail": { "message": "Importarea fișierului nu funcționează? Dați clic aici!", "description": "Helps user import their account from a JSON file" @@ -569,9 +563,6 @@ "links": { "message": "Link-uri" }, - "liveGasPricePredictions": { - "message": "Predicții live de preț în gas" - }, "loadMore": { "message": "Încărcați mai multe" }, @@ -1005,9 +996,6 @@ "slow": { "message": "Lent" }, - "slower": { - "message": "Mai încet" - }, "somethingWentWrong": { "message": "Hopa! A apărut o eroare." }, @@ -1149,9 +1137,6 @@ "transactionSubmitted": { "message": "Tranzacția a fost trimisă, cu o taxă gas de $1 la $2." }, - "transactionTime": { - "message": "Ora tranzacției" - }, "transactionUpdated": { "message": "Tranzacție actualizată la $2." }, diff --git a/app/_locales/ru/messages.json b/app/_locales/ru/messages.json index c33af5cd1..b528ec886 100644 --- a/app/_locales/ru/messages.json +++ b/app/_locales/ru/messages.json @@ -166,9 +166,6 @@ "chainId": { "message": "ID сети" }, - "chartOnlyAvailableEth": { - "message": "Диаграмма доступна только в сетях Ethereum." - }, "chromeRequiredForHardwareWallets": { "message": "Вам необходимо использовать MetaMask в Google Chrome, чтобы подключиться к своему аппаратному кошельку." }, @@ -427,9 +424,6 @@ "fast": { "message": "Быстро" }, - "faster": { - "message": "Быстрее" - }, "fiat": { "message": "Валюта", "description": "Exchange type" @@ -608,9 +602,6 @@ "links": { "message": "Ссылки" }, - "liveGasPricePredictions": { - "message": "Прогноз цены газа в режиме реального времени" - }, "loadMore": { "message": "Загрузить еще" }, @@ -1054,9 +1045,6 @@ "slow": { "message": "Медленно" }, - "slower": { - "message": "Медленнее" - }, "somethingWentWrong": { "message": "Опс! Что-то пошло не так." }, @@ -1201,9 +1189,6 @@ "transactionSubmitted": { "message": "Сделка подана с оплатой за газ в размере 1$ за 2$." }, - "transactionTime": { - "message": "Время транзакции" - }, "transactionUpdated": { "message": "Транзакция обновлена до $2." }, diff --git a/app/_locales/sk/messages.json b/app/_locales/sk/messages.json index 08bd00cc6..86e9040ab 100644 --- a/app/_locales/sk/messages.json +++ b/app/_locales/sk/messages.json @@ -161,9 +161,6 @@ "chainId": { "message": "ID reťazca" }, - "chartOnlyAvailableEth": { - "message": "Graf je k dispozícii iba v sieťach Ethereum." - }, "chromeRequiredForHardwareWallets": { "message": "Ak sa chcete pripojiť k svojej hardvérovej peňaženke, musíte v Google Chrome použiť MetaMask." }, @@ -392,9 +389,6 @@ "fast": { "message": "Rýchle" }, - "faster": { - "message": "Rýchlejšie" - }, "fiat": { "message": "FIAT", "description": "Exchange type" @@ -563,9 +557,6 @@ "links": { "message": "Odkazy" }, - "liveGasPricePredictions": { - "message": "Predpoveď cien GAS naživo" - }, "loadMore": { "message": "Načítať viac" }, @@ -981,9 +972,6 @@ "slow": { "message": "Pomalé" }, - "slower": { - "message": "Pomalší" - }, "somethingWentWrong": { "message": "Och! Niečo zlyhalo." }, @@ -1122,9 +1110,6 @@ "transactionSubmitted": { "message": "Transakcia bola odoslaná s poplatkom za GAS z $1 na $2." }, - "transactionTime": { - "message": "Čas transakcie" - }, "transactionUpdated": { "message": "Transakcia bola aktualizovaná na $2." }, diff --git a/app/_locales/sl/messages.json b/app/_locales/sl/messages.json index 8c92173c0..ffb268e59 100644 --- a/app/_locales/sl/messages.json +++ b/app/_locales/sl/messages.json @@ -167,9 +167,6 @@ "chainId": { "message": "ID verige" }, - "chartOnlyAvailableEth": { - "message": "Grafikon na voljo le v glavnih omrežjih." - }, "chromeRequiredForHardwareWallets": { "message": "Za uporabo strojne denarnice potrebujete Google Chrome." }, @@ -398,9 +395,6 @@ "fast": { "message": "Hiter" }, - "faster": { - "message": "Hitrejši" - }, "fiat": { "message": "Klasične", "description": "Exchange type" @@ -570,9 +564,6 @@ "links": { "message": "Povezave" }, - "liveGasPricePredictions": { - "message": "Napovedi o gas price" - }, "loadMore": { "message": "Naloži več" }, @@ -1000,9 +991,6 @@ "slow": { "message": "Počasen" }, - "slower": { - "message": "Počasnejši" - }, "somethingWentWrong": { "message": "Oops! Nekaj je šlo narobe." }, @@ -1147,9 +1135,6 @@ "transactionSubmitted": { "message": "Transakcija z gas fee $1 oddana na $2." }, - "transactionTime": { - "message": "Transakcijski čas" - }, "transactionUpdated": { "message": "Transakcija na $2 spremenjena." }, diff --git a/app/_locales/sr/messages.json b/app/_locales/sr/messages.json index bb2276471..7aea49f76 100644 --- a/app/_locales/sr/messages.json +++ b/app/_locales/sr/messages.json @@ -164,9 +164,6 @@ "cancelled": { "message": "Otkazano" }, - "chartOnlyAvailableEth": { - "message": "Grafikon dostupan jedino na mrežama Ethereum." - }, "chromeRequiredForHardwareWallets": { "message": "Da biste se povezali sa Vašim hardverskim novčanikom morate da koristite MetaMask na Google Chrome-u." }, @@ -395,9 +392,6 @@ "fast": { "message": "Брзо" }, - "faster": { - "message": "Brže" - }, "fiat": { "message": "Dekret", "description": "Exchange type" @@ -576,9 +570,6 @@ "links": { "message": "Veze" }, - "liveGasPricePredictions": { - "message": "Predviđanja cene gasa uživo" - }, "loadMore": { "message": "Učitati više" }, @@ -1009,9 +1000,6 @@ "slow": { "message": "Споро" }, - "slower": { - "message": "Sporije" - }, "somethingWentWrong": { "message": "Ups! Nešto nije u redu." }, @@ -1150,9 +1138,6 @@ "transactionSubmitted": { "message": "Transakcija je podnešena sa gas naknadom od $1 na $2." }, - "transactionTime": { - "message": "Vreme transakcije" - }, "transactionUpdated": { "message": "Transakcija je ažurirana na $2." }, diff --git a/app/_locales/sv/messages.json b/app/_locales/sv/messages.json index d902d2fe2..183d1064f 100644 --- a/app/_locales/sv/messages.json +++ b/app/_locales/sv/messages.json @@ -161,9 +161,6 @@ "cancelled": { "message": "Avbruten" }, - "chartOnlyAvailableEth": { - "message": "Tabellen är endast tillgänglig på Ethereum-nätverk." - }, "chromeRequiredForHardwareWallets": { "message": "Du måste använda MetaMask på Google Chrome för att ansluta till din hårdvaruplånbok." }, @@ -392,9 +389,6 @@ "fast": { "message": "Snabb" }, - "faster": { - "message": "Snabbare" - }, "fileImportFail": { "message": "Fungerar inte filimporten? Klicka här!", "description": "Helps user import their account from a JSON file" @@ -569,9 +563,6 @@ "links": { "message": "Länkar" }, - "liveGasPricePredictions": { - "message": "Liveuppdaterad gaspris-förutsägelser" - }, "loadMore": { "message": "Ladda mer" }, @@ -1002,9 +993,6 @@ "slow": { "message": "Långsamt" }, - "slower": { - "message": "Långsammare" - }, "somethingWentWrong": { "message": "Hoppsan! Något gick fel." }, @@ -1140,9 +1128,6 @@ "transactionSubmitted": { "message": "Överföring angedd med gasavgift på $1 vid $2." }, - "transactionTime": { - "message": "Transaktionstid" - }, "transactionUpdated": { "message": "Transaktionen uppdaterades $2." }, diff --git a/app/_locales/sw/messages.json b/app/_locales/sw/messages.json index 25911569a..f5516ae5f 100644 --- a/app/_locales/sw/messages.json +++ b/app/_locales/sw/messages.json @@ -161,9 +161,6 @@ "chainId": { "message": "Utambulisho wa Mnyororo" }, - "chartOnlyAvailableEth": { - "message": "Zogoa inapatikana kwenye mitandao ya Ethereum pekee." - }, "chromeRequiredForHardwareWallets": { "message": "Unapaswa kutumia MetaMask kwenye Google Chrome ili kuungnisha kwenye Waleti yako ya Programu Maunzi." }, @@ -392,9 +389,6 @@ "fast": { "message": "Haraka" }, - "faster": { - "message": "Ingiza" - }, "fileImportFail": { "message": "Kuhamisha faili hakufanyi kazi? Bofya hapa!", "description": "Helps user import their account from a JSON file" @@ -566,9 +560,6 @@ "links": { "message": "Viungo" }, - "liveGasPricePredictions": { - "message": "Utabiri wa moja kwa moja wa Bei ya Gesi" - }, "loadMore": { "message": "Pak zAIDI" }, @@ -996,9 +987,6 @@ "slow": { "message": "Polepole" }, - "slower": { - "message": "Taratibu" - }, "somethingWentWrong": { "message": "Ayaa! Hitilafu fulani imetokea." }, @@ -1143,9 +1131,6 @@ "transactionSubmitted": { "message": "Muamala umewasilishwa ukiwa na ada ya gesi ya$1 mnamo $2." }, - "transactionTime": { - "message": "Muda wa Muamala" - }, "transactionUpdated": { "message": "Muamala umesasishwa mnamo $2." }, diff --git a/app/_locales/th/messages.json b/app/_locales/th/messages.json index 951958eff..330d10cb7 100644 --- a/app/_locales/th/messages.json +++ b/app/_locales/th/messages.json @@ -190,9 +190,6 @@ "fast": { "message": "เร็ว" }, - "faster": { - "message": "เร็วขึ้น" - }, "fiat": { "message": "เงินตรา", "description": "Exchange type" @@ -477,9 +474,6 @@ "signed": { "message": "ลงชื่อแล้ว" }, - "slower": { - "message": "ช้าลง" - }, "stateLogs": { "message": "บันทึกของสถานะ" }, diff --git a/app/_locales/uk/messages.json b/app/_locales/uk/messages.json index 53c845fe1..c613908bd 100644 --- a/app/_locales/uk/messages.json +++ b/app/_locales/uk/messages.json @@ -167,9 +167,6 @@ "chainId": { "message": "ID мережі" }, - "chartOnlyAvailableEth": { - "message": "Таблиця доступна тільки в мережах Ethereum." - }, "chromeRequiredForHardwareWallets": { "message": "Щоб підключитися до апаратного гаманця, розширення MetaMask потрібно використовувати в Google Chrome." }, @@ -398,9 +395,6 @@ "fast": { "message": "Швидка" }, - "faster": { - "message": "Швидше" - }, "fiat": { "message": "Вказівка", "description": "Exchange type" @@ -579,9 +573,6 @@ "links": { "message": "Посилання" }, - "liveGasPricePredictions": { - "message": "Прогнози ціни на пальне наживо" - }, "loadMore": { "message": "Завантажити більше" }, @@ -1018,9 +1009,6 @@ "slow": { "message": "Повільна" }, - "slower": { - "message": "Повільніше" - }, "somethingWentWrong": { "message": "Ой! Щось пішло не так." }, @@ -1165,9 +1153,6 @@ "transactionSubmitted": { "message": "Транзакція надіслана з оплатою за газ $1 о $2." }, - "transactionTime": { - "message": "Час транзакції" - }, "transactionUpdated": { "message": "Час оновлення транзакції: $2." }, diff --git a/app/_locales/zh_CN/messages.json b/app/_locales/zh_CN/messages.json index 6330781c6..1a0631b6a 100644 --- a/app/_locales/zh_CN/messages.json +++ b/app/_locales/zh_CN/messages.json @@ -167,9 +167,6 @@ "chainId": { "message": "链 ID" }, - "chartOnlyAvailableEth": { - "message": "聊天功能仅对以太坊网络开放。" - }, "chromeRequiredForHardwareWallets": { "message": "您需要通过 Google Chrome 浏览器使用 MetaMask ,连接个人硬件钱包。" }, @@ -398,9 +395,6 @@ "fast": { "message": "快" }, - "faster": { - "message": "快捷操作" - }, "fiat": { "message": "FIAT", "description": "Exchange type" @@ -570,9 +564,6 @@ "links": { "message": "链接" }, - "liveGasPricePredictions": { - "message": "实时天然气价格预测" - }, "loadMore": { "message": "加载更多" }, @@ -1000,9 +991,6 @@ "slow": { "message": "慢" }, - "slower": { - "message": "降速" - }, "somethingWentWrong": { "message": "哎呀!出问题了。" }, @@ -1147,9 +1135,6 @@ "transactionSubmitted": { "message": "在 $2 提交的交易单,其天然气费为 $1 。" }, - "transactionTime": { - "message": "交易时间" - }, "transactionUpdated": { "message": "交易单已于 $2 更新。" }, diff --git a/app/_locales/zh_TW/messages.json b/app/_locales/zh_TW/messages.json index 3f4ec252d..c58f87eea 100644 --- a/app/_locales/zh_TW/messages.json +++ b/app/_locales/zh_TW/messages.json @@ -167,9 +167,6 @@ "chainId": { "message": "鏈 ID" }, - "chartOnlyAvailableEth": { - "message": "圖表僅適用於以太坊網路。" - }, "chromeRequiredForHardwareWallets": { "message": "您需要在 Google Chrome 瀏覽器使用 MetaMask 連結您的硬體錢包" }, @@ -398,9 +395,6 @@ "fast": { "message": "快" }, - "faster": { - "message": "更快" - }, "fiat": { "message": "法定貨幣", "description": "Exchange type" @@ -579,9 +573,6 @@ "links": { "message": "連結" }, - "liveGasPricePredictions": { - "message": "即時 Gas 價格預估" - }, "loadMore": { "message": "載入更多" }, @@ -997,9 +988,6 @@ "slow": { "message": "慢" }, - "slower": { - "message": "更慢" - }, "somethingWentWrong": { "message": "糟糕!出了點問題。" }, @@ -1144,9 +1132,6 @@ "transactionSubmitted": { "message": "交易送出 手續費 $1 時間 $2" }, - "transactionTime": { - "message": "交易時間" - }, "transactionUpdated": { "message": "交易狀態更新 時間 $2" }, diff --git a/app/scripts/controllers/preferences.js b/app/scripts/controllers/preferences.js index d521f613d..bfba2835b 100644 --- a/app/scripts/controllers/preferences.js +++ b/app/scripts/controllers/preferences.js @@ -47,7 +47,6 @@ export default class PreferencesController { // perform sensitive operations. featureFlags: { showIncomingTransactions: true, - transactionTime: false, }, knownMethodData: {}, firstTimeFlowType: null, diff --git a/development/build/scripts.js b/development/build/scripts.js index ab3e60b41..86f6e9eb3 100644 --- a/development/build/scripts.js +++ b/development/build/scripts.js @@ -39,11 +39,10 @@ const dependencies = Object.keys( ) const materialUIDependencies = ['@material-ui/core'] const reactDepenendencies = dependencies.filter((dep) => dep.match(/react/u)) -const d3Dependencies = ['c3', 'd3'] const externalDependenciesMap = { background: ['3box'], - ui: [...materialUIDependencies, ...reactDepenendencies, ...d3Dependencies], + ui: [...materialUIDependencies, ...reactDepenendencies], } function createScriptTasks({ browserPlatforms, livereload }) { diff --git a/package.json b/package.json index 3a00c26cf..f11903fbb 100644 --- a/package.json +++ b/package.json @@ -94,12 +94,10 @@ "await-semaphore": "^0.1.1", "bignumber.js": "^4.1.0", "bn.js": "^4.11.7", - "c3": "^0.7.10", "classnames": "^2.2.6", "content-hash": "^2.5.2", "copy-to-clipboard": "^3.0.8", "currency-formatter": "^1.4.2", - "d3": "^5.15.0", "debounce-stream": "^2.0.0", "deep-freeze-strict": "1.1.1", "dnode": "^1.2.2", diff --git a/test/data/fetch-mocks.json b/test/data/fetch-mocks.json index 805d6e33a..886f87697 100644 --- a/test/data/fetch-mocks.json +++ b/test/data/fetch-mocks.json @@ -1,5921 +1,9 @@ { - "ethGasBasic": { + "gasPricesBasic": { "average": 85, - "fastestWait": 0.6, - "fastWait": 0.6, "fast": 200, - "safeLowWait": 4.8, - "blockNum": 6648312, - "avgWait": 4.2, - "block_time": 15.516129032258064, - "speed": 0.7828720873342716, - "fastest": 400, "safeLow": 80 }, - "ethGasPredictTable": [ - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 7.2632423756, - "pct_remaining5m": 0, - "sum": 7.029975, - "tx_atabove": 4136, - "hashpower_accepting": 10.4166666667, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 1.2, - "pct_mined_5m": 0, - "total_seen_5m": 1, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 7.433788122, - "pct_remaining5m": 0, - "sum": 7.01731875, - "tx_atabove": 4136, - "hashpower_accepting": 10.9375, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 1.5, - "pct_mined_5m": 0, - "total_seen_5m": 84, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 7.433788122, - "pct_remaining5m": 0, - "sum": 7.01731875, - "tx_atabove": 4136, - "hashpower_accepting": 10.9375, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 1.7, - "pct_mined_5m": 0, - "total_seen_5m": 5, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 7.4638844302, - "pct_remaining5m": 0, - "sum": 7.01731875, - "tx_atabove": 4136, - "hashpower_accepting": 10.9375, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 1.8, - "pct_mined_5m": 0, - "total_seen_5m": 20, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 7.4839486356, - "pct_remaining5m": 0, - "sum": 7.01731875, - "tx_atabove": 4136, - "hashpower_accepting": 10.9375, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 1.9, - "pct_mined_5m": 0, - "total_seen_5m": 8, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 7.7347512039, - "pct_remaining5m": 0, - "sum": 7.0046625, - "tx_atabove": 4136, - "hashpower_accepting": 11.4583333333, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 2, - "pct_mined_5m": 0, - "total_seen_5m": 52, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 17, - "hashpower_accepting2": 7.7447833066, - "pct_remaining5m": 1, - "sum": 7.0046625, - "tx_atabove": 4136, - "hashpower_accepting": 11.4583333333, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 2.1, - "pct_mined_5m": 0, - "total_seen_5m": 97, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 20, - "hashpower_accepting2": 7.7447833066, - "pct_remaining5m": 1, - "sum": 7.0040625, - "tx_atabove": 4135, - "hashpower_accepting": 11.4583333333, - "hpa_coef2": -0.067, - "total_seen_30m": 6, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 2.2, - "pct_mined_5m": 0, - "total_seen_5m": 433, - "pct_mined_30m": 0, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 68, - "hashpower_accepting2": 7.7447833066, - "pct_remaining5m": 0, - "sum": 6.9986625, - "tx_atabove": 4126, - "hashpower_accepting": 11.4583333333, - "hpa_coef2": -0.067, - "total_seen_30m": 2, - "int2": 6.9238, - "pct_remaining30m": 50, - "gasprice": 2.3, - "pct_mined_5m": 0, - "total_seen_5m": 14, - "pct_mined_30m": 0, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 7.7447833066, - "pct_remaining5m": 0, - "sum": 6.9980625, - "tx_atabove": 4125, - "hashpower_accepting": 11.4583333333, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 2.4, - "pct_mined_5m": 0, - "total_seen_5m": 4, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 20, - "hashpower_accepting2": 7.7447833066, - "pct_remaining5m": 37, - "sum": 6.9956625, - "tx_atabove": 4121, - "hashpower_accepting": 11.4583333333, - "hpa_coef2": -0.067, - "total_seen_30m": 4, - "int2": 6.9238, - "pct_remaining30m": 75, - "gasprice": 2.5, - "pct_mined_5m": 0, - "total_seen_5m": 45, - "pct_mined_30m": 0, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 79, - "hashpower_accepting2": 7.7447833066, - "pct_remaining5m": 0, - "sum": 6.9788625, - "tx_atabove": 4093, - "hashpower_accepting": 11.4583333333, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 100, - "gasprice": 2.6, - "pct_mined_5m": 0, - "total_seen_5m": 3, - "pct_mined_30m": 0, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 27.5, - "hashpower_accepting2": 7.7447833066, - "pct_remaining5m": 100, - "sum": 6.9764625, - "tx_atabove": 4089, - "hashpower_accepting": 11.4583333333, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 2.7, - "pct_mined_5m": 0, - "total_seen_5m": 3, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 22.5, - "hashpower_accepting2": 7.7447833066, - "pct_remaining5m": 66, - "sum": 6.9740625, - "tx_atabove": 4085, - "hashpower_accepting": 11.4583333333, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 2.8, - "pct_mined_5m": 0, - "total_seen_5m": 6, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 20, - "hashpower_accepting2": 7.7548154093, - "pct_remaining5m": 38, - "sum": 6.9686625, - "tx_atabove": 4076, - "hashpower_accepting": 11.4583333333, - "hpa_coef2": -0.067, - "total_seen_30m": 2, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 2.9, - "pct_mined_5m": 2, - "total_seen_5m": 36, - "pct_mined_30m": 0, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 27, - "hashpower_accepting2": 11.5268860353, - "pct_remaining5m": 77, - "sum": 6.8307, - "tx_atabove": 4057, - "hashpower_accepting": 16.6666666667, - "hpa_coef2": -0.067, - "total_seen_30m": 127, - "int2": 6.9238, - "pct_remaining30m": 48, - "gasprice": 3, - "pct_mined_5m": 0, - "total_seen_5m": 322, - "pct_mined_30m": 39, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 67, - "hashpower_accepting2": 11.5268860353, - "pct_remaining5m": 100, - "sum": 6.5697, - "tx_atabove": 3622, - "hashpower_accepting": 16.6666666667, - "hpa_coef2": -0.067, - "total_seen_30m": 85, - "int2": 6.9238, - "pct_remaining30m": 98, - "gasprice": 3.1, - "pct_mined_5m": 0, - "total_seen_5m": 79, - "pct_mined_30m": 0, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 71, - "hashpower_accepting2": 11.5268860353, - "pct_remaining5m": 100, - "sum": 6.4311, - "tx_atabove": 3391, - "hashpower_accepting": 16.6666666667, - "hpa_coef2": -0.067, - "total_seen_30m": 7, - "int2": 6.9238, - "pct_remaining30m": 100, - "gasprice": 3.2, - "pct_mined_5m": 0, - "total_seen_5m": 4, - "pct_mined_30m": 0, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 62, - "hashpower_accepting2": 11.5268860353, - "pct_remaining5m": 100, - "sum": 6.4209, - "tx_atabove": 3374, - "hashpower_accepting": 16.6666666667, - "hpa_coef2": -0.067, - "total_seen_30m": 14, - "int2": 6.9238, - "pct_remaining30m": 92, - "gasprice": 3.3, - "pct_mined_5m": 0, - "total_seen_5m": 7, - "pct_mined_30m": 0, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 1472, - "hashpower_accepting2": 11.5569823435, - "pct_remaining5m": 100, - "sum": 6.3951, - "tx_atabove": 3331, - "hashpower_accepting": 16.6666666667, - "hpa_coef2": -0.067, - "total_seen_30m": 29, - "int2": 6.9238, - "pct_remaining30m": 100, - "gasprice": 3.4, - "pct_mined_5m": 0, - "total_seen_5m": 27, - "pct_mined_30m": 0, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 307, - "hashpower_accepting2": 11.5670144462, - "pct_remaining5m": 100, - "sum": 6.1521, - "tx_atabove": 2926, - "hashpower_accepting": 16.6666666667, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 3.7, - "pct_mined_5m": 0, - "total_seen_5m": 1, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 1399, - "hashpower_accepting2": 11.577046549, - "pct_remaining5m": 100, - "sum": 6.1395, - "tx_atabove": 2905, - "hashpower_accepting": 16.6666666667, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 3.9, - "pct_mined_5m": 0, - "total_seen_5m": 1, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 1005, - "hashpower_accepting2": 11.5971107544, - "pct_remaining5m": 88, - "sum": 6.1035, - "tx_atabove": 2845, - "hashpower_accepting": 16.6666666667, - "hpa_coef2": -0.067, - "total_seen_30m": 9, - "int2": 6.9238, - "pct_remaining30m": 88, - "gasprice": 4, - "pct_mined_5m": 0, - "total_seen_5m": 9, - "pct_mined_30m": 0, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 1546, - "hashpower_accepting2": 11.6171749599, - "pct_remaining5m": null, - "sum": 5.6151, - "tx_atabove": 2031, - "hashpower_accepting": 16.6666666667, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 100, - "gasprice": 4.1, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 0, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 1065, - "hashpower_accepting2": 11.6171749599, - "pct_remaining5m": 100, - "sum": 5.5509, - "tx_atabove": 1924, - "hashpower_accepting": 16.6666666667, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 4.3, - "pct_mined_5m": 0, - "total_seen_5m": 2, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 459, - "hashpower_accepting2": 11.6171749599, - "pct_remaining5m": 50, - "sum": 5.5137, - "tx_atabove": 1862, - "hashpower_accepting": 16.6666666667, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 4.4, - "pct_mined_5m": 0, - "total_seen_5m": 2, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 298, - "hashpower_accepting2": 11.6171749599, - "pct_remaining5m": null, - "sum": 5.4903, - "tx_atabove": 1823, - "hashpower_accepting": 16.6666666667, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 100, - "gasprice": 4.7, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 0, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 812, - "hashpower_accepting2": 11.6472712681, - "pct_remaining5m": 0, - "sum": 5.4831, - "tx_atabove": 1811, - "hashpower_accepting": 16.6666666667, - "hpa_coef2": -0.067, - "total_seen_30m": 2, - "int2": 6.9238, - "pct_remaining30m": 100, - "gasprice": 4.8, - "pct_mined_5m": 0, - "total_seen_5m": 1, - "pct_mined_30m": 0, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 541, - "hashpower_accepting2": 11.6472712681, - "pct_remaining5m": 100, - "sum": 5.4375, - "tx_atabove": 1735, - "hashpower_accepting": 16.6666666667, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 4.9, - "pct_mined_5m": 0, - "total_seen_5m": 1, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 1134, - "hashpower_accepting2": 11.7375601926, - "pct_remaining5m": 100, - "sum": 5.41824375, - "tx_atabove": 1724, - "hashpower_accepting": 17.1875, - "hpa_coef2": -0.067, - "total_seen_30m": 6, - "int2": 6.9238, - "pct_remaining30m": 100, - "gasprice": 5, - "pct_mined_5m": 0, - "total_seen_5m": 5, - "pct_mined_30m": 0, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 1958, - "hashpower_accepting2": 11.7676565008, - "pct_remaining5m": null, - "sum": 4.9567875, - "tx_atabove": 976, - "hashpower_accepting": 17.7083333333, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 100, - "gasprice": 5.2, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 0, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 1203.5, - "hashpower_accepting2": 11.8077849117, - "pct_remaining5m": null, - "sum": 4.9507875, - "tx_atabove": 966, - "hashpower_accepting": 17.7083333333, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 100, - "gasprice": 5.3, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 0, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 677.5, - "hashpower_accepting2": 11.8378812199, - "pct_remaining5m": null, - "sum": 4.9141875, - "tx_atabove": 905, - "hashpower_accepting": 17.7083333333, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 100, - "gasprice": 5.5, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 0, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 3, - "hashpower_accepting2": 13.3928571429, - "pct_remaining5m": 0, - "sum": 3.16120625, - "tx_atabove": 832, - "hashpower_accepting": 20.3125, - "hpa_coef2": -0.067, - "total_seen_30m": 9, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 6, - "pct_mined_5m": 100, - "total_seen_5m": 12, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 5.92, - "avgdiff": 1, - "expectedWait": 23.5990451154, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 14.0248796148, - "pct_remaining5m": 0, - "sum": 3.10120625, - "tx_atabove": 732, - "hashpower_accepting": 20.3125, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 6.1, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 5.58, - "avgdiff": 1, - "expectedWait": 22.2247437161, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 0, - "hashpower_accepting2": 14.1753611557, - "pct_remaining5m": 0, - "sum": 3.09640625, - "tx_atabove": 724, - "hashpower_accepting": 20.3125, - "hpa_coef2": -0.067, - "total_seen_30m": 3, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 6.2, - "pct_mined_5m": 100, - "total_seen_5m": 3, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 5.55, - "avgdiff": 1, - "expectedWait": 22.1183205662, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 14.3459069021, - "pct_remaining5m": 0, - "sum": 3.09580625, - "tx_atabove": 723, - "hashpower_accepting": 20.3125, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 6.3, - "pct_mined_5m": 100, - "total_seen_5m": 4, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 5.55, - "avgdiff": 1, - "expectedWait": 22.1050535543, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 14.3960674157, - "pct_remaining5m": 0, - "sum": 3.09460625, - "tx_atabove": 721, - "hashpower_accepting": 20.3125, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 6.4, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 5.54, - "avgdiff": 1, - "expectedWait": 22.0785433993, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 14.5465489567, - "pct_remaining5m": 0, - "sum": 3.09460625, - "tx_atabove": 721, - "hashpower_accepting": 20.3125, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 6.5, - "pct_mined_5m": 100, - "total_seen_5m": 3, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 5.54, - "avgdiff": 1, - "expectedWait": 22.0785433993, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 14.5666131621, - "pct_remaining5m": null, - "sum": 3.09460625, - "tx_atabove": 721, - "hashpower_accepting": 20.3125, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 6.6, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 5.54, - "avgdiff": 1, - "expectedWait": 22.0785433993, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 2, - "hashpower_accepting2": 14.6769662921, - "pct_remaining5m": null, - "sum": 3.09460625, - "tx_atabove": 721, - "hashpower_accepting": 20.3125, - "hpa_coef2": -0.067, - "total_seen_30m": 2, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 6.7, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 5.54, - "avgdiff": 1, - "expectedWait": 22.0785433993, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 14.7070626003, - "pct_remaining5m": null, - "sum": 3.09400625, - "tx_atabove": 720, - "hashpower_accepting": 20.3125, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 6.8, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 5.54, - "avgdiff": 1, - "expectedWait": 22.0653002466, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 14.7271268058, - "pct_remaining5m": 0, - "sum": 3.09400625, - "tx_atabove": 720, - "hashpower_accepting": 20.3125, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 6.9, - "pct_mined_5m": 100, - "total_seen_5m": 2, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 5.54, - "avgdiff": 1, - "expectedWait": 22.0653002466, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 3, - "hashpower_accepting2": 15.4795345104, - "pct_remaining5m": 0, - "sum": 3.06749375, - "tx_atabove": 718, - "hashpower_accepting": 21.3541666667, - "hpa_coef2": -0.067, - "total_seen_30m": 11, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 7, - "pct_mined_5m": 100, - "total_seen_5m": 6, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 5.39, - "avgdiff": 1, - "expectedWait": 21.4879808804, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 0, - "hashpower_accepting2": 15.5898876404, - "pct_remaining5m": 0, - "sum": 3.06089375, - "tx_atabove": 707, - "hashpower_accepting": 21.3541666667, - "hpa_coef2": -0.067, - "total_seen_30m": 4, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 7.1, - "pct_mined_5m": 100, - "total_seen_5m": 2, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 5.36, - "avgdiff": 1, - "expectedWait": 21.3466271869, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 15.5999197432, - "pct_remaining5m": null, - "sum": 3.06029375, - "tx_atabove": 706, - "hashpower_accepting": 21.3541666667, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 7.2, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 5.35, - "avgdiff": 1, - "expectedWait": 21.3338230522, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 0, - "hashpower_accepting2": 15.8507223114, - "pct_remaining5m": 0, - "sum": 3.05969375, - "tx_atabove": 705, - "hashpower_accepting": 21.3541666667, - "hpa_coef2": -0.067, - "total_seen_30m": 5, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 7.6, - "pct_mined_5m": 100, - "total_seen_5m": 2, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 5.35, - "avgdiff": 1, - "expectedWait": 21.3210265977, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 15.8607544141, - "pct_remaining5m": null, - "sum": 3.05909375, - "tx_atabove": 704, - "hashpower_accepting": 21.3541666667, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 7.7, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 0, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 5.35, - "avgdiff": 1, - "expectedWait": 21.3082378187, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 0, - "hashpower_accepting2": 18.86035313, - "pct_remaining5m": 0, - "sum": 2.8933625, - "tx_atabove": 702, - "hashpower_accepting": 28.125, - "hpa_coef2": -0.067, - "total_seen_30m": 30, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 8, - "pct_mined_5m": 100, - "total_seen_5m": 37, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 4.53, - "avgdiff": 1, - "expectedWait": 18.053913939, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 1, - "hashpower_accepting2": 19.1011235955, - "pct_remaining5m": 0, - "sum": 2.85250625, - "tx_atabove": 655, - "hashpower_accepting": 28.6458333333, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 8.1, - "pct_mined_5m": 100, - "total_seen_5m": 5, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 4.35, - "avgdiff": 1, - "expectedWait": 17.331163684, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 19.1613162119, - "pct_remaining5m": 0, - "sum": 2.84890625, - "tx_atabove": 649, - "hashpower_accepting": 28.6458333333, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 8.2, - "pct_mined_5m": 100, - "total_seen_5m": 3, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 4.33, - "avgdiff": 1, - "expectedWait": 17.268883666, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 19.231540931, - "pct_remaining5m": 0, - "sum": 2.8097375, - "tx_atabove": 647, - "hashpower_accepting": 30.2083333333, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 8.4, - "pct_mined_5m": 100, - "total_seen_5m": 6, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 4.17, - "avgdiff": 1, - "expectedWait": 16.6055586875, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 1, - "hashpower_accepting2": 19.5224719101, - "pct_remaining5m": 0, - "sum": 2.777225, - "tx_atabove": 635, - "hashpower_accepting": 31.25, - "hpa_coef2": -0.067, - "total_seen_30m": 7, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 8.5, - "pct_mined_5m": 100, - "total_seen_5m": 12, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 4.03, - "avgdiff": 1, - "expectedWait": 16.0743526708, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 0, - "hashpower_accepting2": 19.7331460674, - "pct_remaining5m": 0, - "sum": 2.774225, - "tx_atabove": 630, - "hashpower_accepting": 31.25, - "hpa_coef2": -0.067, - "total_seen_30m": 5, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 8.6, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 4.02, - "avgdiff": 1, - "expectedWait": 16.0262018751, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 19.8033707865, - "pct_remaining5m": 0, - "sum": 2.72905625, - "tx_atabove": 618, - "hashpower_accepting": 32.8125, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 8.8, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 3.84, - "avgdiff": 1, - "expectedWait": 15.3184234339, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 19.9638844302, - "pct_remaining5m": 0, - "sum": 2.6954, - "tx_atabove": 583, - "hashpower_accepting": 33.3333333333, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 8.9, - "pct_mined_5m": 100, - "total_seen_5m": 6, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 3.72, - "avgdiff": 1, - "expectedWait": 14.8114421454, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 0, - "hashpower_accepting2": 23.6155698234, - "pct_remaining5m": 0, - "sum": 2.3937875, - "tx_atabove": 460, - "hashpower_accepting": 42.7083333333, - "hpa_coef2": -0.067, - "total_seen_30m": 43, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 9, - "pct_mined_5m": 100, - "total_seen_5m": 120, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 2.75, - "avgdiff": 1, - "expectedWait": 10.9549071782, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 24.0268860353, - "pct_remaining5m": 0, - "sum": 2.30313125, - "tx_atabove": 330, - "hashpower_accepting": 43.2291666667, - "hpa_coef2": -0.067, - "total_seen_30m": 2, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 9.1, - "pct_mined_5m": 100, - "total_seen_5m": 23, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 2.51, - "avgdiff": 1, - "expectedWait": 10.0054630618, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 0, - "hashpower_accepting2": 24.1472712681, - "pct_remaining5m": 0, - "sum": 2.287475, - "tx_atabove": 325, - "hashpower_accepting": 43.75, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 9.2, - "pct_mined_5m": 100, - "total_seen_5m": 3, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 2.47, - "avgdiff": 1, - "expectedWait": 9.8500349165, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 24.2174959872, - "pct_remaining5m": 0, - "sum": 2.2609625, - "tx_atabove": 323, - "hashpower_accepting": 44.7916666667, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 9.3, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 2.41, - "avgdiff": 1, - "expectedWait": 9.5923173304, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 24.3880417335, - "pct_remaining5m": 0, - "sum": 2.22239375, - "tx_atabove": 322, - "hashpower_accepting": 46.3541666667, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 9.4, - "pct_mined_5m": 100, - "total_seen_5m": 7, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 2.32, - "avgdiff": 1, - "expectedWait": 9.2293973144, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 1, - "hashpower_accepting2": 24.5284911717, - "pct_remaining5m": 0, - "sum": 2.2091375, - "tx_atabove": 321, - "hashpower_accepting": 46.875, - "hpa_coef2": -0.067, - "total_seen_30m": 5, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 9.5, - "pct_mined_5m": 100, - "total_seen_5m": 3, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 2.29, - "avgdiff": 1, - "expectedWait": 9.1078574773, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 24.7391653291, - "pct_remaining5m": 0, - "sum": 2.2073375, - "tx_atabove": 318, - "hashpower_accepting": 46.875, - "hpa_coef2": -0.067, - "total_seen_30m": 9, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 9.6, - "pct_mined_5m": 100, - "total_seen_5m": 8, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 2.28, - "avgdiff": 1, - "expectedWait": 9.0914780797, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 24.9699036918, - "pct_remaining5m": 0, - "sum": 2.182025, - "tx_atabove": 318, - "hashpower_accepting": 47.9166666667, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 9.7, - "pct_mined_5m": 88, - "total_seen_5m": 9, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 2.22, - "avgdiff": 1, - "expectedWait": 8.8642381788, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 2, - "hashpower_accepting2": 25.1203852327, - "pct_remaining5m": 0, - "sum": 2.16936875, - "tx_atabove": 318, - "hashpower_accepting": 48.4375, - "hpa_coef2": -0.067, - "total_seen_30m": 6, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 9.8, - "pct_mined_5m": 75, - "total_seen_5m": 4, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 2.2, - "avgdiff": 1, - "expectedWait": 8.7527571186, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 25.1705457464, - "pct_remaining5m": 0, - "sum": 2.1561125, - "tx_atabove": 317, - "hashpower_accepting": 48.9583333333, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 9.9, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 2.17, - "avgdiff": 1, - "expectedWait": 8.637494048, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 0, - "hashpower_accepting2": 36.3864365971, - "pct_remaining5m": 0, - "sum": 1.769825, - "tx_atabove": 306, - "hashpower_accepting": 64.5833333333, - "hpa_coef2": -0.067, - "total_seen_30m": 353, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 10, - "pct_mined_5m": 99, - "total_seen_5m": 245, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 1.47, - "avgdiff": 1, - "expectedWait": 5.8698260519, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 36.536918138, - "pct_remaining5m": 0, - "sum": 1.733225, - "tx_atabove": 245, - "hashpower_accepting": 64.5833333333, - "hpa_coef2": -0.067, - "total_seen_30m": 7, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 10.1, - "pct_mined_5m": 100, - "total_seen_5m": 2, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 1.42, - "avgdiff": 1, - "expectedWait": 5.658874382, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 36.7576243981, - "pct_remaining5m": 0, - "sum": 1.733225, - "tx_atabove": 245, - "hashpower_accepting": 64.5833333333, - "hpa_coef2": -0.067, - "total_seen_30m": 6, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 10.2, - "pct_mined_5m": 100, - "total_seen_5m": 2, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 1.42, - "avgdiff": 1, - "expectedWait": 5.658874382, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 0, - "hashpower_accepting2": 36.8378812199, - "pct_remaining5m": 0, - "sum": 1.732625, - "tx_atabove": 244, - "hashpower_accepting": 64.5833333333, - "hpa_coef2": -0.067, - "total_seen_30m": 2, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 10.3, - "pct_mined_5m": 100, - "total_seen_5m": 3, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 1.42, - "avgdiff": 1, - "expectedWait": 5.6554800758, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 36.8679775281, - "pct_remaining5m": 0, - "sum": 1.732025, - "tx_atabove": 243, - "hashpower_accepting": 64.5833333333, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 10.4, - "pct_mined_5m": 100, - "total_seen_5m": 2, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 1.42, - "avgdiff": 1, - "expectedWait": 5.6520878055, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 1, - "hashpower_accepting2": 37.8109951846, - "pct_remaining5m": 0, - "sum": 1.69405625, - "tx_atabove": 243, - "hashpower_accepting": 66.1458333333, - "hpa_coef2": -0.067, - "total_seen_30m": 12, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 10.5, - "pct_mined_5m": 100, - "total_seen_5m": 53, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 1.37, - "avgdiff": 1, - "expectedWait": 5.4415081179, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 37.871187801, - "pct_remaining5m": 0, - "sum": 1.69285625, - "tx_atabove": 241, - "hashpower_accepting": 66.1458333333, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 10.7, - "pct_mined_5m": 100, - "total_seen_5m": 2, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 1.36, - "avgdiff": 1, - "expectedWait": 5.4349822245, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 0, - "hashpower_accepting2": 38.1019261637, - "pct_remaining5m": 0, - "sum": 1.69285625, - "tx_atabove": 241, - "hashpower_accepting": 66.1458333333, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 10.8, - "pct_mined_5m": 100, - "total_seen_5m": 6, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 1.36, - "avgdiff": 1, - "expectedWait": 5.4349822245, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 38.1821829856, - "pct_remaining5m": 0, - "sum": 1.68565625, - "tx_atabove": 229, - "hashpower_accepting": 66.1458333333, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 10.9, - "pct_mined_5m": 100, - "total_seen_5m": 3, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 1.35, - "avgdiff": 1, - "expectedWait": 5.3959908897, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 0, - "hashpower_accepting2": 40.7002407705, - "pct_remaining5m": 0, - "sum": 1.520525, - "tx_atabove": 228, - "hashpower_accepting": 72.9166666667, - "hpa_coef2": -0.067, - "total_seen_30m": 84, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 11, - "pct_mined_5m": 100, - "total_seen_5m": 84, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 1.15, - "avgdiff": 1, - "expectedWait": 4.5746262436, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 40.8206260032, - "pct_remaining5m": 0, - "sum": 1.507325, - "tx_atabove": 206, - "hashpower_accepting": 72.9166666667, - "hpa_coef2": -0.067, - "total_seen_30m": 5, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 11.1, - "pct_mined_5m": 100, - "total_seen_5m": 4, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 1.13, - "avgdiff": 1, - "expectedWait": 4.5146379708, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 40.8908507223, - "pct_remaining5m": 0, - "sum": 1.507325, - "tx_atabove": 206, - "hashpower_accepting": 72.9166666667, - "hpa_coef2": -0.067, - "total_seen_30m": 2, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 11.2, - "pct_mined_5m": 100, - "total_seen_5m": 2, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 1.13, - "avgdiff": 1, - "expectedWait": 4.5146379708, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 41.4024879615, - "pct_remaining5m": 0, - "sum": 1.49466875, - "tx_atabove": 206, - "hashpower_accepting": 73.4375, - "hpa_coef2": -0.067, - "total_seen_30m": 15, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 11.4, - "pct_mined_5m": 100, - "total_seen_5m": 2, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 1.12, - "avgdiff": 1, - "expectedWait": 4.4578596422, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 41.4827447833, - "pct_remaining5m": 0, - "sum": 1.49466875, - "tx_atabove": 206, - "hashpower_accepting": 73.4375, - "hpa_coef2": -0.067, - "total_seen_30m": 2, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 11.5, - "pct_mined_5m": 100, - "total_seen_5m": 2, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 1.12, - "avgdiff": 1, - "expectedWait": 4.4578596422, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 41.6131621188, - "pct_remaining5m": 0, - "sum": 1.49406875, - "tx_atabove": 205, - "hashpower_accepting": 73.4375, - "hpa_coef2": -0.067, - "total_seen_30m": 8, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 11.6, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 1.12, - "avgdiff": 1, - "expectedWait": 4.4551857287, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 41.6332263242, - "pct_remaining5m": 0, - "sum": 1.49406875, - "tx_atabove": 205, - "hashpower_accepting": 73.4375, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 11.7, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 1.12, - "avgdiff": 1, - "expectedWait": 4.4551857287, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 41.753611557, - "pct_remaining5m": 0, - "sum": 1.49406875, - "tx_atabove": 205, - "hashpower_accepting": 73.4375, - "hpa_coef2": -0.067, - "total_seen_30m": 2, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 11.8, - "pct_mined_5m": 100, - "total_seen_5m": 6, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 1.12, - "avgdiff": 1, - "expectedWait": 4.4551857287, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 41.7736757624, - "pct_remaining5m": null, - "sum": 1.49406875, - "tx_atabove": 205, - "hashpower_accepting": 73.4375, - "hpa_coef2": -0.067, - "total_seen_30m": 2, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 11.9, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 1.12, - "avgdiff": 1, - "expectedWait": 4.4551857287, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 1, - "hashpower_accepting2": 44.7030497592, - "pct_remaining5m": 0, - "sum": 1.41813125, - "tx_atabove": 205, - "hashpower_accepting": 76.5625, - "hpa_coef2": -0.067, - "total_seen_30m": 96, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 12, - "pct_mined_5m": 100, - "total_seen_5m": 39, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 1.04, - "avgdiff": 1, - "expectedWait": 4.1293964158, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 44.9036918138, - "pct_remaining5m": 0, - "sum": 1.399475, - "tx_atabove": 195, - "hashpower_accepting": 77.0833333333, - "hpa_coef2": -0.067, - "total_seen_30m": 11, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 12.1, - "pct_mined_5m": 100, - "total_seen_5m": 6, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 1.02, - "avgdiff": 1, - "expectedWait": 4.0530715456, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 0, - "hashpower_accepting2": 45.0341091493, - "pct_remaining5m": null, - "sum": 1.38681875, - "tx_atabove": 195, - "hashpower_accepting": 77.6041666667, - "hpa_coef2": -0.067, - "total_seen_30m": 3, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 12.2, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 1, - "avgdiff": 1, - "expectedWait": 4.0020981056, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 45.1845906902, - "pct_remaining5m": 0, - "sum": 1.3735625, - "tx_atabove": 194, - "hashpower_accepting": 78.125, - "hpa_coef2": -0.067, - "total_seen_30m": 9, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 12.3, - "pct_mined_5m": 100, - "total_seen_5m": 2, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.99, - "avgdiff": 1, - "expectedWait": 3.9493953846, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 45.1946227929, - "pct_remaining5m": null, - "sum": 1.3735625, - "tx_atabove": 194, - "hashpower_accepting": 78.125, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 12.4, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.99, - "avgdiff": 1, - "expectedWait": 3.9493953846, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 45.3752006421, - "pct_remaining5m": 0, - "sum": 1.36090625, - "tx_atabove": 194, - "hashpower_accepting": 78.6458333333, - "hpa_coef2": -0.067, - "total_seen_30m": 10, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 12.5, - "pct_mined_5m": 100, - "total_seen_5m": 2, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.98, - "avgdiff": 1, - "expectedWait": 3.8997258274, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 45.4955858748, - "pct_remaining5m": 0, - "sum": 1.36090625, - "tx_atabove": 194, - "hashpower_accepting": 78.6458333333, - "hpa_coef2": -0.067, - "total_seen_30m": 4, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 12.6, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.98, - "avgdiff": 1, - "expectedWait": 3.8997258274, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 45.525682183, - "pct_remaining5m": null, - "sum": 1.36090625, - "tx_atabove": 194, - "hashpower_accepting": 78.6458333333, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 12.7, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.98, - "avgdiff": 1, - "expectedWait": 3.8997258274, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 45.5858747994, - "pct_remaining5m": 0, - "sum": 1.36090625, - "tx_atabove": 194, - "hashpower_accepting": 78.6458333333, - "hpa_coef2": -0.067, - "total_seen_30m": 4, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 12.8, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.98, - "avgdiff": 1, - "expectedWait": 3.8997258274, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 45.636035313, - "pct_remaining5m": 0, - "sum": 1.36090625, - "tx_atabove": 194, - "hashpower_accepting": 78.6458333333, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 12.9, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.98, - "avgdiff": 1, - "expectedWait": 3.8997258274, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 1, - "hashpower_accepting2": 46.9903691814, - "pct_remaining5m": 0, - "sum": 1.31028125, - "tx_atabove": 194, - "hashpower_accepting": 80.7291666667, - "hpa_coef2": -0.067, - "total_seen_30m": 47, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 13, - "pct_mined_5m": 100, - "total_seen_5m": 34, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.93, - "avgdiff": 1, - "expectedWait": 3.7072162202, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 47.5321027287, - "pct_remaining5m": 0, - "sum": 1.292825, - "tx_atabove": 186, - "hashpower_accepting": 81.25, - "hpa_coef2": -0.067, - "total_seen_30m": 9, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 13.2, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.91, - "avgdiff": 1, - "expectedWait": 3.6430636874, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 47.5621990369, - "pct_remaining5m": 0, - "sum": 1.292825, - "tx_atabove": 186, - "hashpower_accepting": 81.25, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 13.3, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.91, - "avgdiff": 1, - "expectedWait": 3.6430636874, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 47.632423756, - "pct_remaining5m": null, - "sum": 1.292825, - "tx_atabove": 186, - "hashpower_accepting": 81.25, - "hpa_coef2": -0.067, - "total_seen_30m": 2, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 13.4, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.91, - "avgdiff": 1, - "expectedWait": 3.6430636874, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 0.5, - "hashpower_accepting2": 48.1440609952, - "pct_remaining5m": 0, - "sum": 1.28016875, - "tx_atabove": 186, - "hashpower_accepting": 81.7708333333, - "hpa_coef2": -0.067, - "total_seen_30m": 2, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 13.5, - "pct_mined_5m": 100, - "total_seen_5m": 21, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.9, - "avgdiff": 1, - "expectedWait": 3.5972467097, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 48.4550561798, - "pct_remaining5m": 0, - "sum": 1.2651125, - "tx_atabove": 182, - "hashpower_accepting": 82.2916666667, - "hpa_coef2": -0.067, - "total_seen_30m": 10, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 13.6, - "pct_mined_5m": 100, - "total_seen_5m": 10, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.89, - "avgdiff": 1, - "expectedWait": 3.5434913565, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 1, - "hashpower_accepting2": 55.9590690209, - "pct_remaining5m": 0, - "sum": 1.2398, - "tx_atabove": 182, - "hashpower_accepting": 83.3333333333, - "hpa_coef2": -0.067, - "total_seen_30m": 253, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 13.7, - "pct_mined_5m": 100, - "total_seen_5m": 212, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.87, - "avgdiff": 1, - "expectedWait": 3.4549224112, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 56.0593900482, - "pct_remaining5m": 0, - "sum": 1.226, - "tx_atabove": 159, - "hashpower_accepting": 83.3333333333, - "hpa_coef2": -0.067, - "total_seen_30m": 6, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 13.8, - "pct_mined_5m": 100, - "total_seen_5m": 2, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.86, - "avgdiff": 1, - "expectedWait": 3.4075719515, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 56.1095505618, - "pct_remaining5m": 0, - "sum": 1.226, - "tx_atabove": 159, - "hashpower_accepting": 83.3333333333, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 13.9, - "pct_mined_5m": 100, - "total_seen_5m": 4, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.86, - "avgdiff": 1, - "expectedWait": 3.4075719515, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 0.5, - "hashpower_accepting2": 59.6408507223, - "pct_remaining5m": 0, - "sum": 1.13740625, - "tx_atabove": 159, - "hashpower_accepting": 86.9791666667, - "hpa_coef2": -0.067, - "total_seen_30m": 119, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 14, - "pct_mined_5m": 100, - "total_seen_5m": 115, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.78, - "avgdiff": 1, - "expectedWait": 3.1186688184, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 59.7311396469, - "pct_remaining5m": 0, - "sum": 1.13440625, - "tx_atabove": 154, - "hashpower_accepting": 86.9791666667, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 14.1, - "pct_mined_5m": 100, - "total_seen_5m": 5, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.78, - "avgdiff": 1, - "expectedWait": 3.1093268319, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 59.8214285714, - "pct_remaining5m": 0, - "sum": 1.13440625, - "tx_atabove": 154, - "hashpower_accepting": 86.9791666667, - "hpa_coef2": -0.067, - "total_seen_30m": 4, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 14.2, - "pct_mined_5m": 100, - "total_seen_5m": 4, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.78, - "avgdiff": 1, - "expectedWait": 3.1093268319, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 1, - "hashpower_accepting2": 60.1524879615, - "pct_remaining5m": 0, - "sum": 1.13380625, - "tx_atabove": 153, - "hashpower_accepting": 86.9791666667, - "hpa_coef2": -0.067, - "total_seen_30m": 5, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 14.4, - "pct_mined_5m": 100, - "total_seen_5m": 3, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.78, - "avgdiff": 1, - "expectedWait": 3.1074617954, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 60.1725521669, - "pct_remaining5m": 0, - "sum": 1.13320625, - "tx_atabove": 152, - "hashpower_accepting": 86.9791666667, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 14.5, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.78, - "avgdiff": 1, - "expectedWait": 3.1055978775, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 60.2528089888, - "pct_remaining5m": 0, - "sum": 1.13320625, - "tx_atabove": 152, - "hashpower_accepting": 86.9791666667, - "hpa_coef2": -0.067, - "total_seen_30m": 3, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 14.6, - "pct_mined_5m": 100, - "total_seen_5m": 2, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.78, - "avgdiff": 1, - "expectedWait": 3.1055978775, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 60.6440609952, - "pct_remaining5m": 0, - "sum": 1.13320625, - "tx_atabove": 152, - "hashpower_accepting": 86.9791666667, - "hpa_coef2": -0.067, - "total_seen_30m": 10, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 14.7, - "pct_mined_5m": 100, - "total_seen_5m": 10, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.78, - "avgdiff": 1, - "expectedWait": 3.1055978775, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 60.6641252006, - "pct_remaining5m": 0, - "sum": 1.13320625, - "tx_atabove": 152, - "hashpower_accepting": 86.9791666667, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 14.8, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.78, - "avgdiff": 1, - "expectedWait": 3.1055978775, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 60.6942215088, - "pct_remaining5m": null, - "sum": 1.13320625, - "tx_atabove": 152, - "hashpower_accepting": 86.9791666667, - "hpa_coef2": -0.067, - "total_seen_30m": 2, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 14.9, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.78, - "avgdiff": 1, - "expectedWait": 3.1055978775, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 0, - "hashpower_accepting2": 62.9113162119, - "pct_remaining5m": 0, - "sum": 1.0952375, - "tx_atabove": 152, - "hashpower_accepting": 88.5416666667, - "hpa_coef2": -0.067, - "total_seen_30m": 65, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 15, - "pct_mined_5m": 100, - "total_seen_5m": 48, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.75, - "avgdiff": 1, - "expectedWait": 2.9898926986, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 63.4129213483, - "pct_remaining5m": 0, - "sum": 1.0910375, - "tx_atabove": 145, - "hashpower_accepting": 88.5416666667, - "hpa_coef2": -0.067, - "total_seen_30m": 11, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 15.1, - "pct_mined_5m": 100, - "total_seen_5m": 8, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.75, - "avgdiff": 1, - "expectedWait": 2.9773614832, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 1, - "hashpower_accepting2": 64.4161316212, - "pct_remaining5m": 0, - "sum": 1.0886375, - "tx_atabove": 141, - "hashpower_accepting": 88.5416666667, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 15.5, - "pct_mined_5m": 100, - "total_seen_5m": 4, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.75, - "avgdiff": 1, - "expectedWait": 2.9702243836, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 64.4863563403, - "pct_remaining5m": 0, - "sum": 1.0820375, - "tx_atabove": 130, - "hashpower_accepting": 88.5416666667, - "hpa_coef2": -0.067, - "total_seen_30m": 5, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 15.6, - "pct_mined_5m": 50, - "total_seen_5m": 2, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.74, - "avgdiff": 1, - "expectedWait": 2.9506854521, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 1, - "hashpower_accepting2": 66.1817817014, - "pct_remaining5m": 0, - "sum": 1.0820375, - "tx_atabove": 130, - "hashpower_accepting": 88.5416666667, - "hpa_coef2": -0.067, - "total_seen_30m": 24, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 15.7, - "pct_mined_5m": 100, - "total_seen_5m": 17, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.74, - "avgdiff": 1, - "expectedWait": 2.9506854521, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 66.2620385233, - "pct_remaining5m": 0, - "sum": 1.0766375, - "tx_atabove": 121, - "hashpower_accepting": 88.5416666667, - "hpa_coef2": -0.067, - "total_seen_30m": 2, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 15.8, - "pct_mined_5m": 83, - "total_seen_5m": 6, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.74, - "avgdiff": 1, - "expectedWait": 2.9347946943, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 0, - "hashpower_accepting2": 67.2853130016, - "pct_remaining5m": 0, - "sum": 1.0766375, - "tx_atabove": 121, - "hashpower_accepting": 88.5416666667, - "hpa_coef2": -0.067, - "total_seen_30m": 15, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 16, - "pct_mined_5m": 100, - "total_seen_5m": 11, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.74, - "avgdiff": 1, - "expectedWait": 2.9347946943, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 67.2953451043, - "pct_remaining5m": null, - "sum": 1.0748375, - "tx_atabove": 118, - "hashpower_accepting": 88.5416666667, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 16.1, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.74, - "avgdiff": 1, - "expectedWait": 2.9295168154, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 67.4458266453, - "pct_remaining5m": 0, - "sum": 1.0748375, - "tx_atabove": 118, - "hashpower_accepting": 88.5416666667, - "hpa_coef2": -0.067, - "total_seen_30m": 3, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 16.2, - "pct_mined_5m": 100, - "total_seen_5m": 7, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.74, - "avgdiff": 1, - "expectedWait": 2.9295168154, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 67.455858748, - "pct_remaining5m": 0, - "sum": 1.0748375, - "tx_atabove": 118, - "hashpower_accepting": 88.5416666667, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 16.3, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.74, - "avgdiff": 1, - "expectedWait": 2.9295168154, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 67.6565008026, - "pct_remaining5m": 0, - "sum": 1.0748375, - "tx_atabove": 118, - "hashpower_accepting": 88.5416666667, - "hpa_coef2": -0.067, - "total_seen_30m": 5, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 16.4, - "pct_mined_5m": 100, - "total_seen_5m": 7, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.74, - "avgdiff": 1, - "expectedWait": 2.9295168154, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 67.7267255217, - "pct_remaining5m": 0, - "sum": 1.0742375, - "tx_atabove": 117, - "hashpower_accepting": 88.5416666667, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 16.5, - "pct_mined_5m": 100, - "total_seen_5m": 2, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.73, - "avgdiff": 1, - "expectedWait": 2.9277596325, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 1, - "hashpower_accepting2": 68.6697431782, - "pct_remaining5m": 0, - "sum": 1.0742375, - "tx_atabove": 117, - "hashpower_accepting": 88.5416666667, - "hpa_coef2": -0.067, - "total_seen_30m": 42, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 16.7, - "pct_mined_5m": 100, - "total_seen_5m": 27, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.73, - "avgdiff": 1, - "expectedWait": 2.9277596325, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 68.8904494382, - "pct_remaining5m": 0, - "sum": 1.0718375, - "tx_atabove": 113, - "hashpower_accepting": 88.5416666667, - "hpa_coef2": -0.067, - "total_seen_30m": 11, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 17, - "pct_mined_5m": 100, - "total_seen_5m": 3, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.73, - "avgdiff": 1, - "expectedWait": 2.9207414346, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 0, - "hashpower_accepting2": 69.0308988764, - "pct_remaining5m": 0, - "sum": 1.0712375, - "tx_atabove": 112, - "hashpower_accepting": 88.5416666667, - "hpa_coef2": -0.067, - "total_seen_30m": 8, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 17.1, - "pct_mined_5m": 100, - "total_seen_5m": 3, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.73, - "avgdiff": 1, - "expectedWait": 2.9189895153, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 69.0409309791, - "pct_remaining5m": null, - "sum": 1.0706375, - "tx_atabove": 111, - "hashpower_accepting": 88.5416666667, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 17.3, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.73, - "avgdiff": 1, - "expectedWait": 2.9172386469, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 69.0710272873, - "pct_remaining5m": 0, - "sum": 1.0706375, - "tx_atabove": 111, - "hashpower_accepting": 88.5416666667, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 17.5, - "pct_mined_5m": 100, - "total_seen_5m": 2, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.73, - "avgdiff": 1, - "expectedWait": 2.9172386469, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 69.08105939, - "pct_remaining5m": 0, - "sum": 1.0706375, - "tx_atabove": 111, - "hashpower_accepting": 88.5416666667, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 17.6, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.73, - "avgdiff": 1, - "expectedWait": 2.9172386469, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 69.1011235955, - "pct_remaining5m": null, - "sum": 1.0706375, - "tx_atabove": 111, - "hashpower_accepting": 88.5416666667, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 17.8, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.73, - "avgdiff": 1, - "expectedWait": 2.9172386469, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 69.1111556982, - "pct_remaining5m": 0, - "sum": 1.0706375, - "tx_atabove": 111, - "hashpower_accepting": 88.5416666667, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 17.9, - "pct_mined_5m": 0, - "total_seen_5m": 1, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.73, - "avgdiff": 1, - "expectedWait": 2.9172386469, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 69.7632423756, - "pct_remaining5m": 0, - "sum": 1.05798125, - "tx_atabove": 111, - "hashpower_accepting": 89.0625, - "hpa_coef2": -0.067, - "total_seen_30m": 16, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 18, - "pct_mined_5m": 100, - "total_seen_5m": 16, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.72, - "avgdiff": 1, - "expectedWait": 2.8805500054, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 69.7732744783, - "pct_remaining5m": 0, - "sum": 1.05618125, - "tx_atabove": 108, - "hashpower_accepting": 89.0625, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 18.1, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.72, - "avgdiff": 1, - "expectedWait": 2.875369679, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 69.8134028892, - "pct_remaining5m": 0, - "sum": 1.05618125, - "tx_atabove": 108, - "hashpower_accepting": 89.0625, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 18.5, - "pct_mined_5m": 100, - "total_seen_5m": 2, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.72, - "avgdiff": 1, - "expectedWait": 2.875369679, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 69.823434992, - "pct_remaining5m": 0, - "sum": 1.05618125, - "tx_atabove": 108, - "hashpower_accepting": 89.0625, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 18.7, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.72, - "avgdiff": 1, - "expectedWait": 2.875369679, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 69.8535313002, - "pct_remaining5m": null, - "sum": 1.05618125, - "tx_atabove": 108, - "hashpower_accepting": 89.0625, - "hpa_coef2": -0.067, - "total_seen_30m": 2, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 18.8, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.72, - "avgdiff": 1, - "expectedWait": 2.875369679, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 69.8735955056, - "pct_remaining5m": 0, - "sum": 1.05618125, - "tx_atabove": 108, - "hashpower_accepting": 89.0625, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 18.9, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.72, - "avgdiff": 1, - "expectedWait": 2.875369679, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 70.3150080257, - "pct_remaining5m": 0, - "sum": 1.043525, - "tx_atabove": 108, - "hashpower_accepting": 89.5833333333, - "hpa_coef2": -0.067, - "total_seen_30m": 13, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 19, - "pct_mined_5m": 100, - "total_seen_5m": 11, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.71, - "avgdiff": 1, - "expectedWait": 2.8392076024, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 70.3350722311, - "pct_remaining5m": 0, - "sum": 1.042325, - "tx_atabove": 106, - "hashpower_accepting": 89.5833333333, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 19.3, - "pct_mined_5m": 66, - "total_seen_5m": 3, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.71, - "avgdiff": 1, - "expectedWait": 2.8358025967, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 70.3752006421, - "pct_remaining5m": 0, - "sum": 1.042325, - "tx_atabove": 106, - "hashpower_accepting": 89.5833333333, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 19.4, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.71, - "avgdiff": 1, - "expectedWait": 2.8358025967, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 70.3852327448, - "pct_remaining5m": null, - "sum": 1.042325, - "tx_atabove": 106, - "hashpower_accepting": 89.5833333333, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 19.5, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.71, - "avgdiff": 1, - "expectedWait": 2.8358025967, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 70.4052969502, - "pct_remaining5m": null, - "sum": 1.042325, - "tx_atabove": 106, - "hashpower_accepting": 89.5833333333, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 19.8, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.71, - "avgdiff": 1, - "expectedWait": 2.8358025967, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 70.8266452648, - "pct_remaining5m": 0, - "sum": 1.042325, - "tx_atabove": 106, - "hashpower_accepting": 89.5833333333, - "hpa_coef2": -0.067, - "total_seen_30m": 18, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 19.9, - "pct_mined_5m": 100, - "total_seen_5m": 10, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.71, - "avgdiff": 1, - "expectedWait": 2.8358025967, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 0, - "hashpower_accepting2": 75.2708667737, - "pct_remaining5m": 0, - "sum": 0.90310625, - "tx_atabove": 106, - "hashpower_accepting": 95.3125, - "hpa_coef2": -0.067, - "total_seen_30m": 144, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 20, - "pct_mined_5m": 100, - "total_seen_5m": 185, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.62, - "avgdiff": 1, - "expectedWait": 2.4672551317, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 75.3009630819, - "pct_remaining5m": null, - "sum": 0.89650625, - "tx_atabove": 95, - "hashpower_accepting": 95.3125, - "hpa_coef2": -0.067, - "total_seen_30m": 3, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 20.2, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.62, - "avgdiff": 1, - "expectedWait": 2.4510248666, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 75.3210272873, - "pct_remaining5m": 0, - "sum": 0.89650625, - "tx_atabove": 95, - "hashpower_accepting": 95.3125, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 20.3, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.62, - "avgdiff": 1, - "expectedWait": 2.4510248666, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 77.7387640449, - "pct_remaining5m": 0, - "sum": 0.88385, - "tx_atabove": 95, - "hashpower_accepting": 95.8333333333, - "hpa_coef2": -0.067, - "total_seen_30m": 24, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 20.5, - "pct_mined_5m": 100, - "total_seen_5m": 9, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.61, - "avgdiff": 1, - "expectedWait": 2.420199561, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 77.7688603531, - "pct_remaining5m": 0, - "sum": 0.88325, - "tx_atabove": 94, - "hashpower_accepting": 95.8333333333, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 20.7, - "pct_mined_5m": 100, - "total_seen_5m": 2, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.61, - "avgdiff": 1, - "expectedWait": 2.4187478768, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 77.9093097913, - "pct_remaining5m": null, - "sum": 0.87059375, - "tx_atabove": 94, - "hashpower_accepting": 96.3541666667, - "hpa_coef2": -0.067, - "total_seen_30m": 7, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 20.9, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.6, - "avgdiff": 1, - "expectedWait": 2.3883285027, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 0, - "hashpower_accepting2": 79.7752808989, - "pct_remaining5m": 0, - "sum": 0.87059375, - "tx_atabove": 94, - "hashpower_accepting": 96.3541666667, - "hpa_coef2": -0.067, - "total_seen_30m": 39, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 21, - "pct_mined_5m": 100, - "total_seen_5m": 36, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.6, - "avgdiff": 1, - "expectedWait": 2.3883285027, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 79.7953451043, - "pct_remaining5m": 0, - "sum": 0.86819375, - "tx_atabove": 90, - "hashpower_accepting": 96.3541666667, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 21.1, - "pct_mined_5m": 100, - "total_seen_5m": 2, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.6, - "avgdiff": 1, - "expectedWait": 2.3826033871, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 79.8154093098, - "pct_remaining5m": null, - "sum": 0.86819375, - "tx_atabove": 90, - "hashpower_accepting": 96.3541666667, - "hpa_coef2": -0.067, - "total_seen_30m": 2, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 21.4, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.6, - "avgdiff": 1, - "expectedWait": 2.3826033871, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 79.845505618, - "pct_remaining5m": 0, - "sum": 0.86819375, - "tx_atabove": 90, - "hashpower_accepting": 96.3541666667, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 21.7, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.6, - "avgdiff": 1, - "expectedWait": 2.3826033871, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 80.3069823435, - "pct_remaining5m": 0, - "sum": 0.86819375, - "tx_atabove": 90, - "hashpower_accepting": 96.3541666667, - "hpa_coef2": -0.067, - "total_seen_30m": 9, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 21.9, - "pct_mined_5m": 100, - "total_seen_5m": 3, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.6, - "avgdiff": 1, - "expectedWait": 2.3826033871, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 80.8888443018, - "pct_remaining5m": 0, - "sum": 0.8555375, - "tx_atabove": 90, - "hashpower_accepting": 96.875, - "hpa_coef2": -0.067, - "total_seen_30m": 13, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 22, - "pct_mined_5m": 100, - "total_seen_5m": 13, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.59, - "avgdiff": 1, - "expectedWait": 2.352638584, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 80.9089085072, - "pct_remaining5m": null, - "sum": 0.8555375, - "tx_atabove": 90, - "hashpower_accepting": 96.875, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 22.1, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.59, - "avgdiff": 1, - "expectedWait": 2.352638584, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 80.91894061, - "pct_remaining5m": 0, - "sum": 0.8555375, - "tx_atabove": 90, - "hashpower_accepting": 96.875, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 22.2, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.59, - "avgdiff": 1, - "expectedWait": 2.352638584, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 80.9289727127, - "pct_remaining5m": null, - "sum": 0.8555375, - "tx_atabove": 90, - "hashpower_accepting": 96.875, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 22.3, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.59, - "avgdiff": 1, - "expectedWait": 2.352638584, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 80.9490369181, - "pct_remaining5m": 0, - "sum": 0.8555375, - "tx_atabove": 90, - "hashpower_accepting": 96.875, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 22.5, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.59, - "avgdiff": 1, - "expectedWait": 2.352638584, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 80.9791332263, - "pct_remaining5m": 0, - "sum": 0.8555375, - "tx_atabove": 90, - "hashpower_accepting": 96.875, - "hpa_coef2": -0.067, - "total_seen_30m": 2, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 22.8, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.59, - "avgdiff": 1, - "expectedWait": 2.352638584, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 80.9891653291, - "pct_remaining5m": null, - "sum": 0.8555375, - "tx_atabove": 90, - "hashpower_accepting": 96.875, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 22.9, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.59, - "avgdiff": 1, - "expectedWait": 2.352638584, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 0, - "hashpower_accepting2": 81.47070626, - "pct_remaining5m": 0, - "sum": 0.8555375, - "tx_atabove": 90, - "hashpower_accepting": 96.875, - "hpa_coef2": -0.067, - "total_seen_30m": 15, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 23, - "pct_mined_5m": 100, - "total_seen_5m": 19, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.59, - "avgdiff": 1, - "expectedWait": 2.352638584, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 81.4907704655, - "pct_remaining5m": 0, - "sum": 0.8531375, - "tx_atabove": 86, - "hashpower_accepting": 96.875, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 23.1, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.59, - "avgdiff": 1, - "expectedWait": 2.3469990216, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 81.5108346709, - "pct_remaining5m": 0, - "sum": 0.8525375, - "tx_atabove": 85, - "hashpower_accepting": 96.875, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 23.3, - "pct_mined_5m": 100, - "total_seen_5m": 2, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.59, - "avgdiff": 1, - "expectedWait": 2.3455912446, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 81.6011235955, - "pct_remaining5m": 0, - "sum": 0.8525375, - "tx_atabove": 85, - "hashpower_accepting": 96.875, - "hpa_coef2": -0.067, - "total_seen_30m": 3, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 23.7, - "pct_mined_5m": 100, - "total_seen_5m": 3, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.59, - "avgdiff": 1, - "expectedWait": 2.3455912446, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 81.621187801, - "pct_remaining5m": 0, - "sum": 0.8525375, - "tx_atabove": 85, - "hashpower_accepting": 96.875, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 23.9, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.59, - "avgdiff": 1, - "expectedWait": 2.3455912446, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 0, - "hashpower_accepting2": 81.8719903692, - "pct_remaining5m": 0, - "sum": 0.8525375, - "tx_atabove": 85, - "hashpower_accepting": 96.875, - "hpa_coef2": -0.067, - "total_seen_30m": 7, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 24, - "pct_mined_5m": 100, - "total_seen_5m": 9, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.59, - "avgdiff": 1, - "expectedWait": 2.3455912446, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 81.8820224719, - "pct_remaining5m": 0, - "sum": 0.8501375, - "tx_atabove": 81, - "hashpower_accepting": 96.875, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 24.3, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.59, - "avgdiff": 1, - "expectedWait": 2.3399685755, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 81.9121187801, - "pct_remaining5m": 0, - "sum": 0.8501375, - "tx_atabove": 81, - "hashpower_accepting": 96.875, - "hpa_coef2": -0.067, - "total_seen_30m": 2, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 24.6, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.59, - "avgdiff": 1, - "expectedWait": 2.3399685755, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 81.9321829856, - "pct_remaining5m": 0, - "sum": 0.8501375, - "tx_atabove": 81, - "hashpower_accepting": 96.875, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 24.7, - "pct_mined_5m": 100, - "total_seen_5m": 2, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.59, - "avgdiff": 1, - "expectedWait": 2.3399685755, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 0, - "hashpower_accepting2": 83.3868378812, - "pct_remaining5m": 0, - "sum": 0.83688125, - "tx_atabove": 80, - "hashpower_accepting": 97.3958333333, - "hpa_coef2": -0.067, - "total_seen_30m": 24, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 25, - "pct_mined_5m": 100, - "total_seen_5m": 32, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.58, - "avgdiff": 1, - "expectedWait": 2.3091540608, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 83.6276083467, - "pct_remaining5m": 0, - "sum": 0.82128125, - "tx_atabove": 54, - "hashpower_accepting": 97.3958333333, - "hpa_coef2": -0.067, - "total_seen_30m": 10, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 26, - "pct_mined_5m": 100, - "total_seen_5m": 7, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.57, - "avgdiff": 1, - "expectedWait": 2.2734107799, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 0, - "hashpower_accepting2": 83.7379614767, - "pct_remaining5m": 0, - "sum": 0.82008125, - "tx_atabove": 52, - "hashpower_accepting": 97.3958333333, - "hpa_coef2": -0.067, - "total_seen_30m": 5, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 27, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.57, - "avgdiff": 1, - "expectedWait": 2.2706843231, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 83.9887640449, - "pct_remaining5m": 0, - "sum": 0.81948125, - "tx_atabove": 51, - "hashpower_accepting": 97.3958333333, - "hpa_coef2": -0.067, - "total_seen_30m": 13, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 28, - "pct_mined_5m": 100, - "total_seen_5m": 7, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.57, - "avgdiff": 1, - "expectedWait": 2.2693223212, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 84.0690208668, - "pct_remaining5m": 0, - "sum": 0.806825, - "tx_atabove": 51, - "hashpower_accepting": 97.9166666667, - "hpa_coef2": -0.067, - "total_seen_30m": 4, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 29, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.56, - "avgdiff": 1, - "expectedWait": 2.240782197, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 0, - "hashpower_accepting2": 85.8447030498, - "pct_remaining5m": 0, - "sum": 0.7809125, - "tx_atabove": 50, - "hashpower_accepting": 98.9583333333, - "hpa_coef2": -0.067, - "total_seen_30m": 55, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 30, - "pct_mined_5m": 100, - "total_seen_5m": 49, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.55, - "avgdiff": 1, - "expectedWait": 2.1834637674, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 85.9751203852, - "pct_remaining5m": 0, - "sum": 0.7743125, - "tx_atabove": 39, - "hashpower_accepting": 98.9583333333, - "hpa_coef2": -0.067, - "total_seen_30m": 6, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 31, - "pct_mined_5m": 100, - "total_seen_5m": 5, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.54, - "avgdiff": 1, - "expectedWait": 2.169100358, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 86.1356340289, - "pct_remaining5m": 0, - "sum": 0.7743125, - "tx_atabove": 39, - "hashpower_accepting": 98.9583333333, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 32, - "pct_mined_5m": 100, - "total_seen_5m": 4, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.54, - "avgdiff": 1, - "expectedWait": 2.169100358, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 86.2760834671, - "pct_remaining5m": 0, - "sum": 0.7743125, - "tx_atabove": 39, - "hashpower_accepting": 98.9583333333, - "hpa_coef2": -0.067, - "total_seen_30m": 3, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 33, - "pct_mined_5m": 100, - "total_seen_5m": 6, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.54, - "avgdiff": 1, - "expectedWait": 2.169100358, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 86.4165329053, - "pct_remaining5m": 0, - "sum": 0.7737125, - "tx_atabove": 38, - "hashpower_accepting": 98.9583333333, - "hpa_coef2": -0.067, - "total_seen_30m": 6, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 34, - "pct_mined_5m": 60, - "total_seen_5m": 5, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.54, - "avgdiff": 1, - "expectedWait": 2.1677992881, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 0.5, - "hashpower_accepting2": 86.7475922953, - "pct_remaining5m": 0, - "sum": 0.7737125, - "tx_atabove": 38, - "hashpower_accepting": 98.9583333333, - "hpa_coef2": -0.067, - "total_seen_30m": 10, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 35, - "pct_mined_5m": 100, - "total_seen_5m": 17, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.54, - "avgdiff": 1, - "expectedWait": 2.1677992881, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 86.7877207063, - "pct_remaining5m": 0, - "sum": 0.7725125, - "tx_atabove": 36, - "hashpower_accepting": 98.9583333333, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 36, - "pct_mined_5m": 100, - "total_seen_5m": 2, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.54, - "avgdiff": 1, - "expectedWait": 2.1651994891, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 86.8579454254, - "pct_remaining5m": 0, - "sum": 0.7725125, - "tx_atabove": 36, - "hashpower_accepting": 98.9583333333, - "hpa_coef2": -0.067, - "total_seen_30m": 2, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 37, - "pct_mined_5m": 66, - "total_seen_5m": 3, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.54, - "avgdiff": 1, - "expectedWait": 2.1651994891, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 86.908105939, - "pct_remaining5m": 0, - "sum": 0.7725125, - "tx_atabove": 36, - "hashpower_accepting": 98.9583333333, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 38, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.54, - "avgdiff": 1, - "expectedWait": 2.1651994891, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 86.9783306581, - "pct_remaining5m": 0, - "sum": 0.7725125, - "tx_atabove": 36, - "hashpower_accepting": 98.9583333333, - "hpa_coef2": -0.067, - "total_seen_30m": 3, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 39, - "pct_mined_5m": 100, - "total_seen_5m": 2, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.54, - "avgdiff": 1, - "expectedWait": 2.1651994891, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 1, - "hashpower_accepting2": 87.4498394864, - "pct_remaining5m": 0, - "sum": 0.75985625, - "tx_atabove": 36, - "hashpower_accepting": 99.4791666667, - "hpa_coef2": -0.067, - "total_seen_30m": 16, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 40, - "pct_mined_5m": 100, - "total_seen_5m": 14, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.54, - "avgdiff": 1, - "expectedWait": 2.1379688654, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 1, - "hashpower_accepting2": 89.6167736758, - "pct_remaining5m": 0, - "sum": 0.75805625, - "tx_atabove": 33, - "hashpower_accepting": 99.4791666667, - "hpa_coef2": -0.067, - "total_seen_30m": 112, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 41, - "pct_mined_5m": 100, - "total_seen_5m": 57, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.54, - "avgdiff": 1, - "expectedWait": 2.1341239829, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 89.6869983949, - "pct_remaining5m": 0, - "sum": 0.75445625, - "tx_atabove": 27, - "hashpower_accepting": 99.4791666667, - "hpa_coef2": -0.067, - "total_seen_30m": 2, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 42, - "pct_mined_5m": 100, - "total_seen_5m": 3, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.53, - "avgdiff": 1, - "expectedWait": 2.1264549491, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 89.7070626003, - "pct_remaining5m": null, - "sum": 0.75385625, - "tx_atabove": 26, - "hashpower_accepting": 99.4791666667, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 43, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.53, - "avgdiff": 1, - "expectedWait": 2.1251794588, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 1, - "hashpower_accepting2": 89.9478330658, - "pct_remaining5m": 0, - "sum": 0.75385625, - "tx_atabove": 26, - "hashpower_accepting": 99.4791666667, - "hpa_coef2": -0.067, - "total_seen_30m": 9, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 44, - "pct_mined_5m": 100, - "total_seen_5m": 9, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.53, - "avgdiff": 1, - "expectedWait": 2.1251794588, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 90.088282504, - "pct_remaining5m": 0, - "sum": 0.7394, - "tx_atabove": 23, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": 8, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 45, - "pct_mined_5m": 100, - "total_seen_5m": 5, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.53, - "avgdiff": 1, - "expectedWait": 2.0946783304, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 1, - "hashpower_accepting2": 90.4995987159, - "pct_remaining5m": 0, - "sum": 0.7394, - "tx_atabove": 23, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": 17, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 46, - "pct_mined_5m": 100, - "total_seen_5m": 19, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.53, - "avgdiff": 1, - "expectedWait": 2.0946783304, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 90.5999197432, - "pct_remaining5m": 0, - "sum": 0.7382, - "tx_atabove": 21, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": 4, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 47, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.53, - "avgdiff": 1, - "expectedWait": 2.0921662239, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 90.6199839486, - "pct_remaining5m": null, - "sum": 0.7382, - "tx_atabove": 21, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": 2, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 48, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.53, - "avgdiff": 1, - "expectedWait": 2.0921662239, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 90.6500802568, - "pct_remaining5m": null, - "sum": 0.7382, - "tx_atabove": 21, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": 2, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 49, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.53, - "avgdiff": 1, - "expectedWait": 2.0921662239, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 1, - "hashpower_accepting2": 94.1412520064, - "pct_remaining5m": 0, - "sum": 0.7382, - "tx_atabove": 21, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": 62, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 50, - "pct_mined_5m": 100, - "total_seen_5m": 71, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.53, - "avgdiff": 1, - "expectedWait": 2.0921662239, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 94.2114767255, - "pct_remaining5m": 0, - "sum": 0.7358, - "tx_atabove": 17, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 51, - "pct_mined_5m": 100, - "total_seen_5m": 3, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.52, - "avgdiff": 1, - "expectedWait": 2.0871510456, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 94.4422150883, - "pct_remaining5m": 0, - "sum": 0.7358, - "tx_atabove": 17, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": 5, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 52, - "pct_mined_5m": 100, - "total_seen_5m": 2, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.52, - "avgdiff": 1, - "expectedWait": 2.0871510456, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 94.4723113965, - "pct_remaining5m": null, - "sum": 0.7358, - "tx_atabove": 17, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": 2, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 54, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.52, - "avgdiff": 1, - "expectedWait": 2.0871510456, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 94.4823434992, - "pct_remaining5m": null, - "sum": 0.7346, - "tx_atabove": 15, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 56, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.52, - "avgdiff": 1, - "expectedWait": 2.0846479665, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 0, - "hashpower_accepting2": 95.0140449438, - "pct_remaining5m": 0, - "sum": 0.7346, - "tx_atabove": 15, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": 27, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 60, - "pct_mined_5m": 100, - "total_seen_5m": 17, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.52, - "avgdiff": 1, - "expectedWait": 2.0846479665, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 0, - "hashpower_accepting2": 95.6059390048, - "pct_remaining5m": 0, - "sum": 0.7334, - "tx_atabove": 13, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": 28, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 61, - "pct_mined_5m": 100, - "total_seen_5m": 14, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.52, - "avgdiff": 1, - "expectedWait": 2.0821478893, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 96.8699839486, - "pct_remaining5m": 0, - "sum": 0.7322, - "tx_atabove": 11, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": 21, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 63, - "pct_mined_5m": 100, - "total_seen_5m": 25, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.52, - "avgdiff": 1, - "expectedWait": 2.0796508104, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 1, - "hashpower_accepting2": 98.3948635634, - "pct_remaining5m": 0, - "sum": 0.7298, - "tx_atabove": 7, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": 83, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 64, - "pct_mined_5m": 100, - "total_seen_5m": 38, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.52, - "avgdiff": 1, - "expectedWait": 2.0746656331, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 98.4149277689, - "pct_remaining5m": 0, - "sum": 0.728, - "tx_atabove": 4, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 65, - "pct_mined_5m": 100, - "total_seen_5m": 2, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.52, - "avgdiff": 1, - "expectedWait": 2.0709345939, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 98.4951845907, - "pct_remaining5m": 0, - "sum": 0.7274, - "tx_atabove": 3, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": 3, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 66, - "pct_mined_5m": 100, - "total_seen_5m": 3, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.52, - "avgdiff": 1, - "expectedWait": 2.0696924058, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 98.5052166934, - "pct_remaining5m": null, - "sum": 0.7274, - "tx_atabove": 3, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 69, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.52, - "avgdiff": 1, - "expectedWait": 2.0696924058, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 98.5152487961, - "pct_remaining5m": null, - "sum": 0.7274, - "tx_atabove": 3, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 70, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.52, - "avgdiff": 1, - "expectedWait": 2.0696924058, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 98.5553772071, - "pct_remaining5m": 0, - "sum": 0.7274, - "tx_atabove": 3, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 72, - "pct_mined_5m": 100, - "total_seen_5m": 2, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.52, - "avgdiff": 1, - "expectedWait": 2.0696924058, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 98.5754414125, - "pct_remaining5m": 0, - "sum": 0.7274, - "tx_atabove": 3, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 73, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.52, - "avgdiff": 1, - "expectedWait": 2.0696924058, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 98.5854735152, - "pct_remaining5m": 0, - "sum": 0.7274, - "tx_atabove": 3, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 77, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.52, - "avgdiff": 1, - "expectedWait": 2.0696924058, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 98.6055377207, - "pct_remaining5m": null, - "sum": 0.7274, - "tx_atabove": 3, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 79, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.52, - "avgdiff": 1, - "expectedWait": 2.0696924058, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 98.8663723917, - "pct_remaining5m": 0, - "sum": 0.7274, - "tx_atabove": 3, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": 14, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 80, - "pct_mined_5m": 100, - "total_seen_5m": 6, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.52, - "avgdiff": 1, - "expectedWait": 2.0696924058, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 98.8864365971, - "pct_remaining5m": 0, - "sum": 0.7268, - "tx_atabove": 2, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 84, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.52, - "avgdiff": 1, - "expectedWait": 2.0684509628, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 98.9466292135, - "pct_remaining5m": 0, - "sum": 0.7268, - "tx_atabove": 2, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 88, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.52, - "avgdiff": 1, - "expectedWait": 2.0684509628, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 98.9566613162, - "pct_remaining5m": null, - "sum": 0.7268, - "tx_atabove": 2, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 90, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.52, - "avgdiff": 1, - "expectedWait": 2.0684509628, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 99.0469502408, - "pct_remaining5m": 0, - "sum": 0.7268, - "tx_atabove": 2, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": 4, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 91, - "pct_mined_5m": 100, - "total_seen_5m": 3, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.52, - "avgdiff": 1, - "expectedWait": 2.0684509628, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 99.1272070626, - "pct_remaining5m": 0, - "sum": 0.7268, - "tx_atabove": 2, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": 3, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 96, - "pct_mined_5m": 100, - "total_seen_5m": 2, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.52, - "avgdiff": 1, - "expectedWait": 2.0684509628, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 99.1372391653, - "pct_remaining5m": 0, - "sum": 0.7268, - "tx_atabove": 2, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 97, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.52, - "avgdiff": 1, - "expectedWait": 2.0684509628, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 99.1472712681, - "pct_remaining5m": 0, - "sum": 0.7268, - "tx_atabove": 2, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 99, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.52, - "avgdiff": 1, - "expectedWait": 2.0684509628, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 99.7090690209, - "pct_remaining5m": 0, - "sum": 0.7268, - "tx_atabove": 2, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": 23, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 100, - "pct_mined_5m": 100, - "total_seen_5m": 22, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.52, - "avgdiff": 1, - "expectedWait": 2.0684509628, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 99.8394863563, - "pct_remaining5m": 0, - "sum": 0.7268, - "tx_atabove": 2, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": 7, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 101, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.52, - "avgdiff": 1, - "expectedWait": 2.0684509628, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 99.9097110754, - "pct_remaining5m": 0, - "sum": 0.7268, - "tx_atabove": 2, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": 2, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 120, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.52, - "avgdiff": 1, - "expectedWait": 2.0684509628, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 99.9297752809, - "pct_remaining5m": 0, - "sum": 0.7268, - "tx_atabove": 2, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 134, - "pct_mined_5m": 100, - "total_seen_5m": 2, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.52, - "avgdiff": 1, - "expectedWait": 2.0684509628, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 0, - "hashpower_accepting2": 99.9498394864, - "pct_remaining5m": 0, - "sum": 0.7268, - "tx_atabove": 2, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 137, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.52, - "avgdiff": 1, - "expectedWait": 2.0684509628, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 99.9699036918, - "pct_remaining5m": null, - "sum": 0.7256, - "tx_atabove": 0, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 180, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.52, - "avgdiff": 1, - "expectedWait": 2.0659703104, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - } - ], "metametrics": { "mockMetaMetricsResponse": true }, diff --git a/test/e2e/webdriver/index.js b/test/e2e/webdriver/index.js index 267287ff6..093883a1a 100644 --- a/test/e2e/webdriver/index.js +++ b/test/e2e/webdriver/index.js @@ -45,12 +45,11 @@ async function setupFetchMocking(driver) { window.origFetch = window.fetch.bind(window) window.fetch = async (...args) => { const url = args[0] - if (url.match(/^http(s)?:\/\/ethgasstation\.info\/json\/ethgasAPI.*/u)) { - return { json: async () => clone(mockResponses.ethGasBasic) } - } else if ( - url.match(/http(s?):\/\/ethgasstation\.info\/json\/predictTable.*/u) + // api.metaswap.codefi.network/gasPrices + if ( + url.match(/^http(s)?:\/\/api\.metaswap\.codefi\.network\/gasPrices/u) ) { - return { json: async () => clone(mockResponses.ethGasPredictTable) } + return { json: async () => clone(mockResponses.gasPricesBasic) } } else if (url.match(/chromeextensionmm/u)) { return { json: async () => clone(mockResponses.metametrics) } } else if (url.match(/^https:\/\/(api\.metaswap|.*airswap-dev)/u)) { diff --git a/ui/app/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js b/ui/app/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js index c79122aa2..8f2ddbc6c 100644 --- a/ui/app/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js +++ b/ui/app/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js @@ -1,8 +1,5 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' -import { decGWEIToHexWEI } from '../../../../../helpers/utils/conversions.util' -import Loading from '../../../../ui/loading-screen' -import GasPriceChart from '../../gas-price-chart' import AdvancedGasInputs from '../../advanced-gas-inputs' export default class AdvancedTabContent extends Component { @@ -15,65 +12,46 @@ export default class AdvancedTabContent extends Component { updateCustomGasLimit: PropTypes.func, customModalGasPriceInHex: PropTypes.string, customModalGasLimitInHex: PropTypes.string, - gasEstimatesLoading: PropTypes.bool, - millisecondsRemaining: PropTypes.number, transactionFee: PropTypes.string, - timeRemaining: PropTypes.string, - gasChartProps: PropTypes.object, insufficientBalance: PropTypes.bool, customPriceIsSafe: PropTypes.bool, isSpeedUp: PropTypes.bool, - isEthereumNetwork: PropTypes.bool, customGasLimitMessage: PropTypes.string, minimumGasLimit: PropTypes.number, } - renderDataSummary(transactionFee, timeRemaining) { + renderDataSummary(transactionFee) { return (
{this.context.t('newTransactionFee')} - ~{this.context.t('transactionTime')}
{transactionFee}
-
- {timeRemaining} -
) } - onGasChartUpdate = (price) => { - const { updateCustomGasPrice } = this.props - updateCustomGasPrice(decGWEIToHexWEI(price)) - } - render() { - const { t } = this.context const { updateCustomGasPrice, updateCustomGasLimit, - timeRemaining, customModalGasPriceInHex, customModalGasLimitInHex, insufficientBalance, - gasChartProps, - gasEstimatesLoading, customPriceIsSafe, isSpeedUp, transactionFee, - isEthereumNetwork, customGasLimitMessage, minimumGasLimit, } = this.props return (
- {this.renderDataSummary(transactionFee, timeRemaining)} + {this.renderDataSummary(transactionFee)}
- {isEthereumNetwork ? ( -
-
- {t('liveGasPricePredictions')} -
- {gasEstimatesLoading ? ( - - ) : ( - - )} -
- {t('slower')} - {t('faster')} -
-
- ) : ( -
- {t('chartOnlyAvailableEth')} -
- )}
) diff --git a/ui/app/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/index.scss b/ui/app/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/index.scss index d6b21e04c..0371d1d14 100644 --- a/ui/app/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/index.scss +++ b/ui/app/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/index.scss @@ -2,8 +2,7 @@ display: flex; flex-flow: column; - &__transaction-data-summary, - &__fee-chart-title { + &__transaction-data-summary { padding-left: 24px; padding-right: 24px; } diff --git a/ui/app/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js b/ui/app/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js index 283240cef..0e632a92a 100644 --- a/ui/app/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js +++ b/ui/app/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js @@ -4,9 +4,6 @@ import sinon from 'sinon' import shallow from '../../../../../../../lib/shallow-with-context' import AdvancedTabContent from '../advanced-tab-content.component' -import GasPriceChart from '../../../gas-price-chart' -import Loading from '../../../../../ui/loading-screen' - describe('AdvancedTabContent Component', function () { let wrapper @@ -23,12 +20,10 @@ describe('AdvancedTabContent Component', function () { updateCustomGasLimit={propsMethodSpies.updateCustomGasLimit} customModalGasPriceInHex="11" customModalGasLimitInHex="23456" - timeRemaining="21500" transactionFee="$0.25" insufficientBalance={false} customPriceIsSafe isSpeedUp={false} - isEthereumNetwork />, ) }) @@ -42,7 +37,7 @@ describe('AdvancedTabContent Component', function () { assert(wrapper.hasClass('advanced-tab')) }) - it('should render the expected four children of the advanced-tab div', function () { + it('should render the expected child of the advanced-tab div', function () { const advancedTabChildren = wrapper.children() assert.equal(advancedTabChildren.length, 2) @@ -51,59 +46,13 @@ describe('AdvancedTabContent Component', function () { .at(0) .hasClass('advanced-tab__transaction-data-summary'), ) - assert(advancedTabChildren.at(1).hasClass('advanced-tab__fee-chart')) - - const feeChartDiv = advancedTabChildren.at(1) - - assert( - feeChartDiv - .childAt(1) - .childAt(0) - .hasClass('advanced-tab__fee-chart__title'), - ) - assert(feeChartDiv.childAt(1).childAt(1).is(GasPriceChart)) - assert( - feeChartDiv - .childAt(1) - .childAt(2) - .hasClass('advanced-tab__fee-chart__speed-buttons'), - ) - }) - - it('should render a loading component instead of the chart if gasEstimatesLoading is true', function () { - wrapper.setProps({ gasEstimatesLoading: true }) - const advancedTabChildren = wrapper.children() - assert.equal(advancedTabChildren.length, 2) - - assert( - advancedTabChildren - .at(0) - .hasClass('advanced-tab__transaction-data-summary'), - ) - assert(advancedTabChildren.at(1).hasClass('advanced-tab__fee-chart')) - - const feeChartDiv = advancedTabChildren.at(1) - - assert( - feeChartDiv - .childAt(1) - .childAt(0) - .hasClass('advanced-tab__fee-chart__title'), - ) - assert(feeChartDiv.childAt(1).childAt(1).is(Loading)) - assert( - feeChartDiv - .childAt(1) - .childAt(2) - .hasClass('advanced-tab__fee-chart__speed-buttons'), - ) }) it('should call renderDataSummary with the expected params', function () { const renderDataSummaryArgs = AdvancedTabContent.prototype.renderDataSummary.getCall( 0, ).args - assert.deepEqual(renderDataSummaryArgs, ['$0.25', '21500']) + assert.deepEqual(renderDataSummaryArgs, ['$0.25']) }) }) @@ -112,7 +61,7 @@ describe('AdvancedTabContent Component', function () { beforeEach(function () { dataSummary = shallow( - wrapper.instance().renderDataSummary('mockTotalFee', 'mockMsRemaining'), + wrapper.instance().renderDataSummary('mockTotalFee'), ) }) @@ -126,7 +75,6 @@ describe('AdvancedTabContent Component', function () { titlesNode.hasClass('advanced-tab__transaction-data-summary__titles'), ) assert.equal(titlesNode.children().at(0).text(), 'newTransactionFee') - assert.equal(titlesNode.children().at(1).text(), '~transactionTime') }) it('should render the data', function () { @@ -135,13 +83,6 @@ describe('AdvancedTabContent Component', function () { dataNode.hasClass('advanced-tab__transaction-data-summary__container'), ) assert.equal(dataNode.children().at(0).text(), 'mockTotalFee') - assert( - dataNode - .children() - .at(1) - .hasClass('advanced-tab__transaction-data-summary__time-remaining'), - ) - assert.equal(dataNode.children().at(1).text(), 'mockMsRemaining') }) }) }) diff --git a/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js b/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js index 4fe7ad979..05810f07f 100644 --- a/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js +++ b/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js @@ -16,13 +16,9 @@ export default class GasModalPageContainer extends Component { hideBasic: PropTypes.bool, updateCustomGasPrice: PropTypes.func, updateCustomGasLimit: PropTypes.func, - currentTimeEstimate: PropTypes.string, insufficientBalance: PropTypes.bool, - fetchBasicGasAndTimeEstimates: PropTypes.func, - fetchGasEstimates: PropTypes.func, + fetchBasicGasEstimates: PropTypes.func, gasPriceButtonGroupProps: PropTypes.object, - gasChartProps: PropTypes.object, - gasEstimatesLoading: PropTypes.bool, infoRowProps: PropTypes.shape({ originalTotalFiat: PropTypes.string, originalTotalEth: PropTypes.string, @@ -35,24 +31,14 @@ export default class GasModalPageContainer extends Component { customModalGasPriceInHex: PropTypes.string, customModalGasLimitInHex: PropTypes.string, cancelAndClose: PropTypes.func, - blockTime: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), customPriceIsSafe: PropTypes.bool, isSpeedUp: PropTypes.bool, isRetry: PropTypes.bool, disableSave: PropTypes.bool, - isEthereumNetwork: PropTypes.bool, } componentDidMount() { - const promise = this.props.hideBasic - ? Promise.resolve(this.props.blockTime) - : this.props - .fetchBasicGasAndTimeEstimates() - .then((basicEstimates) => basicEstimates.blockTime) - - promise.then((blockTime) => { - this.props.fetchGasEstimates(blockTime) - }) + this.props.fetchBasicGasEstimates() } renderBasicTabContent(gasPriceButtonGroupProps) { @@ -67,15 +53,11 @@ export default class GasModalPageContainer extends Component { updateCustomGasLimit, customModalGasPriceInHex, customModalGasLimitInHex, - gasChartProps, - currentTimeEstimate, insufficientBalance, - gasEstimatesLoading, customPriceIsSafe, isSpeedUp, isRetry, infoRowProps: { transactionFee }, - isEthereumNetwork, } = this.props return ( @@ -84,15 +66,11 @@ export default class GasModalPageContainer extends Component { updateCustomGasLimit={updateCustomGasLimit} customModalGasPriceInHex={customModalGasPriceInHex} customModalGasLimitInHex={customModalGasLimitInHex} - timeRemaining={currentTimeEstimate} transactionFee={transactionFee} - gasChartProps={gasChartProps} insufficientBalance={insufficientBalance} - gasEstimatesLoading={gasEstimatesLoading} customPriceIsSafe={customPriceIsSafe} isSpeedUp={isSpeedUp} isRetry={isRetry} - isEthereumNetwork={isEthereumNetwork} /> ) } diff --git a/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js b/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js index e383d1bac..bdf987c8a 100644 --- a/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js +++ b/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js @@ -1,5 +1,4 @@ import { connect } from 'react-redux' -import { captureException } from '@sentry/browser' import { addHexPrefix } from '../../../../../../app/scripts/lib/util' import { hideModal, @@ -16,8 +15,7 @@ import { setCustomGasPrice, setCustomGasLimit, resetCustomData, - fetchGasEstimates, - fetchBasicGasAndTimeEstimates, + fetchBasicGasEstimates, } from '../../../../ducks/gas/gas.duck' import { hideGasButtonGroup, @@ -29,21 +27,16 @@ import { getCurrentEthBalance, getIsMainnet, getSendToken, - isEthereumNetwork, getPreferences, getBasicGasEstimateLoadingStatus, - getGasEstimatesLoadingStatus, getCustomGasLimit, getCustomGasPrice, getDefaultActiveButtonIndex, - getEstimatedGasPrices, - getEstimatedGasTimes, getRenderableBasicEstimateData, - getBasicGasEstimateBlockTime, isCustomPriceSafe, getTokenBalance, getSendMaxModeState, - getFastPriceEstimateInHexWEI, + getAveragePriceEstimateInHexWEI, } from '../../../../selectors' import { @@ -53,7 +46,6 @@ import { getValueFromWeiHex, sumHexWEIsToRenderableFiat, } from '../../../../helpers/utils/conversions.util' -import { getRenderableTimeEstimate } from '../../../../helpers/utils/gas-time-estimates.util' import { formatETHFee } from '../../../../helpers/utils/formatters' import { calcGasTotal, @@ -73,7 +65,6 @@ const mapStateToProps = (state, ownProps) => { ({ id }) => id === (transaction.id || txData.id), ) const buttonDataLoading = getBasicGasEstimateLoadingStatus(state) - const gasEstimatesLoading = getGasEstimatesLoadingStatus(state) const sendToken = getSendToken(state) // a "default" txParams is used during the send flow, since the transaction doesn't exist yet in that case @@ -81,7 +72,7 @@ const mapStateToProps = (state, ownProps) => { ? selectedTransaction.txParams : { gas: send.gasLimit || '0x5208', - gasPrice: send.gasPrice || getFastPriceEstimateInHexWEI(state, true), + gasPrice: send.gasPrice || getAveragePriceEstimateInHexWEI(state, true), value: sendToken ? '0x0' : send.amount, } @@ -113,8 +104,6 @@ const mapStateToProps = (state, ownProps) => { const maxModeOn = getSendMaxModeState(state) - const gasPrices = getEstimatedGasPrices(state) - const estimatedTimes = getEstimatedGasTimes(state) const balance = getCurrentEthBalance(state) const { showFiatInTestnets } = getPreferences(state) @@ -142,17 +131,6 @@ const mapStateToProps = (state, ownProps) => { conversionRate, }) - let currentTimeEstimate = '' - try { - currentTimeEstimate = getRenderableTimeEstimate( - customGasPrice, - gasPrices, - estimatedTimes, - ) - } catch (error) { - captureException(error) - } - return { hideBasic, isConfirm: isConfirm(state), @@ -162,8 +140,6 @@ const mapStateToProps = (state, ownProps) => { customGasLimit: calcCustomGasLimit(customModalGasLimitInHex), customGasTotal, newTotalFiat, - currentTimeEstimate, - blockTime: getBasicGasEstimateBlockTime(state), customPriceIsSafe: isCustomPriceSafe(state), maxModeOn, gasPriceButtonGroupProps: { @@ -174,13 +150,6 @@ const mapStateToProps = (state, ownProps) => { ), gasButtonInfo, }, - gasChartProps: { - currentPrice: customGasPrice, - gasPrices, - estimatedTimes, - gasPricesMax: gasPrices[gasPrices.length - 1], - estimatedTimesMax: estimatedTimes[0], - }, infoRowProps: { originalTotalFiat: sumHexWEIsToRenderableFiat( [value, customGasTotal], @@ -198,9 +167,7 @@ const mapStateToProps = (state, ownProps) => { isRetry: transaction.status === TRANSACTION_STATUSES.FAILED, txId: transaction.id, insufficientBalance, - gasEstimatesLoading, isMainnet, - isEthereumNetwork: isEthereumNetwork(state), sendToken, balance, tokenBalance: getTokenBalance(state), @@ -239,9 +206,7 @@ const mapDispatchToProps = (dispatch) => { }, hideGasButtonGroup: () => dispatch(hideGasButtonGroup()), hideSidebar: () => dispatch(hideSidebar()), - fetchGasEstimates: (blockTime) => dispatch(fetchGasEstimates(blockTime)), - fetchBasicGasAndTimeEstimates: () => - dispatch(fetchBasicGasAndTimeEstimates()), + fetchBasicGasEstimates: () => dispatch(fetchBasicGasEstimates()), setGasTotal: (total) => dispatch(setGasTotal(total)), setAmountToMax: (maxAmountDataObject) => { dispatch(updateSendErrors({ amount: null })) diff --git a/ui/app/components/app/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js b/ui/app/components/app/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js index b3c9f98f5..74bd8ee90 100644 --- a/ui/app/components/app/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js +++ b/ui/app/components/app/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js @@ -3,23 +3,21 @@ import React from 'react' import sinon from 'sinon' import shallow from '../../../../../../lib/shallow-with-context' import GasModalPageContainer from '../gas-modal-page-container.component' -import timeout from '../../../../../../lib/test-timeout' import PageContainer from '../../../../ui/page-container' import { Tab } from '../../../../ui/tabs' const mockBasicGasEstimates = { - blockTime: 'mockBlockTime', + average: '20', } const propsMethodSpies = { cancelAndClose: sinon.spy(), onSubmit: sinon.spy(), - fetchBasicGasAndTimeEstimates: sinon + fetchBasicGasEstimates: sinon .stub() .returns(Promise.resolve(mockBasicGasEstimates)), - fetchGasEstimates: sinon.spy(), } const mockGasPriceButtonGroupProps = { @@ -70,17 +68,11 @@ describe('GasModalPageContainer Component', function () { 'mockupdateCustomGasPrice'} updateCustomGasLimit={() => 'mockupdateCustomGasLimit'} - customGasPrice={21} - customGasLimit={54321} gasPriceButtonGroupProps={mockGasPriceButtonGroupProps} infoRowProps={mockInfoRowProps} - currentTimeEstimate="1 min 31 sec" customGasPriceInHex="mockCustomGasPriceInHex" customGasLimitInHex="mockCustomGasLimitInHex" insufficientBalance={false} @@ -94,23 +86,11 @@ describe('GasModalPageContainer Component', function () { }) describe('componentDidMount', function () { - it('should call props.fetchBasicGasAndTimeEstimates', function () { - propsMethodSpies.fetchBasicGasAndTimeEstimates.resetHistory() - assert.equal(propsMethodSpies.fetchBasicGasAndTimeEstimates.callCount, 0) + it('should call props.fetchBasicGasEstimates', function () { + propsMethodSpies.fetchBasicGasEstimates.resetHistory() + assert.equal(propsMethodSpies.fetchBasicGasEstimates.callCount, 0) wrapper.instance().componentDidMount() - assert.equal(propsMethodSpies.fetchBasicGasAndTimeEstimates.callCount, 1) - }) - - it('should call props.fetchGasEstimates with the block time returned by fetchBasicGasAndTimeEstimates', async function () { - propsMethodSpies.fetchGasEstimates.resetHistory() - assert.equal(propsMethodSpies.fetchGasEstimates.callCount, 0) - wrapper.instance().componentDidMount() - await timeout(250) - assert.equal(propsMethodSpies.fetchGasEstimates.callCount, 1) - assert.equal( - propsMethodSpies.fetchGasEstimates.getCall(0).args[0], - 'mockBlockTime', - ) + assert.equal(propsMethodSpies.fetchBasicGasEstimates.callCount, 1) }) }) @@ -139,9 +119,7 @@ describe('GasModalPageContainer Component', function () { sinon.stub(GP, 'renderTabs').returns('mockTabs') const renderTabsWrapperTester = shallow( , { context: { t: (str1, str2) => (str2 ? str1 + str2 : str1) } }, @@ -208,17 +186,11 @@ describe('GasModalPageContainer Component', function () { 'mockupdateCustomGasPrice'} updateCustomGasLimit={() => 'mockupdateCustomGasLimit'} - customGasPrice={21} - customGasLimit={54321} gasPriceButtonGroupProps={mockGasPriceButtonGroupProps} infoRowProps={mockInfoRowProps} - currentTimeEstimate="1 min 31 sec" customGasPriceInHex="mockCustomGasPriceInHex" customGasLimitInHex="mockCustomGasLimitInHex" insufficientBalance={false} diff --git a/ui/app/components/app/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js b/ui/app/components/app/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js index 49687ee89..81934468c 100644 --- a/ui/app/components/app/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js +++ b/ui/app/components/app/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js @@ -104,7 +104,6 @@ describe('gas-modal-page-container container', function () { limit: 'aaaaaaaa', price: 'ffffffff', }, - gasEstimatesLoading: false, priceAndTimeEstimates: [ { gasprice: 3, expectedTime: 31 }, { gasprice: 4, expectedTime: 62 }, @@ -127,27 +126,17 @@ describe('gas-modal-page-container container', function () { isConfirm: true, customGasPrice: 4.294967295, customGasLimit: 2863311530, - currentTimeEstimate: '~1 min 11 sec', newTotalFiat: '637.41', - blockTime: 12, conversionRate: 50, customModalGasLimitInHex: 'aaaaaaaa', customModalGasPriceInHex: 'ffffffff', customGasTotal: 'aaaaaaa955555556', customPriceIsSafe: true, - gasChartProps: { - currentPrice: 4.294967295, - estimatedTimes: [31, 62, 93, 124], - estimatedTimesMax: 31, - gasPrices: [3, 4, 5, 6], - gasPricesMax: 6, - }, gasPriceButtonGroupProps: { buttonDataLoading: 'mockBasicGasEstimateLoadingStatus:4', defaultActiveButtonIndex: 'mockRenderableBasicEstimateData:4ffffffff', gasButtonInfo: 'mockRenderableBasicEstimateData:4', }, - gasEstimatesLoading: false, hideBasic: true, infoRowProps: { originalTotalFiat: '637.41', @@ -161,7 +150,6 @@ describe('gas-modal-page-container container', function () { isSpeedUp: false, isRetry: false, txId: 34, - isEthereumNetwork: true, isMainnet: true, maxModeOn: false, sendToken: null, diff --git a/ui/app/components/app/gas-customization/gas-price-chart/gas-price-chart.component.js b/ui/app/components/app/gas-customization/gas-price-chart/gas-price-chart.component.js deleted file mode 100644 index e01001ebf..000000000 --- a/ui/app/components/app/gas-customization/gas-price-chart/gas-price-chart.component.js +++ /dev/null @@ -1,123 +0,0 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import * as d3 from 'd3' -import { - generateChart, - getCoordinateData, - handleChartUpdate, - hideDataUI, - setTickPosition, - handleMouseMove, -} from './gas-price-chart.utils' - -export default class GasPriceChart extends Component { - static contextTypes = { - t: PropTypes.func, - } - - static propTypes = { - gasPrices: PropTypes.array, - estimatedTimes: PropTypes.array, - gasPricesMax: PropTypes.number, - estimatedTimesMax: PropTypes.number, - currentPrice: PropTypes.number, - updateCustomGasPrice: PropTypes.func, - } - - renderChart() { - const { - currentPrice, - gasPrices, - estimatedTimes, - gasPricesMax, - estimatedTimesMax, - updateCustomGasPrice, - } = this.props - const chart = generateChart( - gasPrices, - estimatedTimes, - gasPricesMax, - estimatedTimesMax, - this.context.t, - ) - setTimeout(function () { - setTickPosition('y', 0, -5, 8) - setTickPosition('y', 1, -3, -5) - setTickPosition('x', 0, 3) - setTickPosition('x', 1, 3, -8) - - const { x: domainX } = getCoordinateData('.domain') - const { x: yAxisX } = getCoordinateData('.c3-axis-y-label') - const { x: tickX } = getCoordinateData('.c3-axis-x .tick') - - d3.select('.c3-axis-x .tick').attr( - 'transform', - `translate(${(domainX - tickX) / 2}, 0)`, - ) - d3.select('.c3-axis-x-label').attr('transform', 'translate(0,-15)') - d3.select('.c3-axis-y-label').attr( - 'transform', - `translate(${domainX - yAxisX - 12}, 2) rotate(-90)`, - ) - d3.select('.c3-xgrid-focus line').attr('y2', 98) - - d3.select('.c3-chart').on('mouseout', () => { - hideDataUI(chart, '#overlayed-circle') - }) - - d3.select('.c3-chart').on('click', () => { - const { x: newGasPrice } = d3.select('#overlayed-circle').datum() - updateCustomGasPrice(newGasPrice) - }) - - const { x: chartXStart, width: chartWidth } = getCoordinateData( - '.c3-areas-data1', - ) - - handleChartUpdate({ - chart, - gasPrices, - newPrice: currentPrice, - cssId: '#set-circle', - }) - - d3.select('.c3-chart').on('mousemove', function () { - handleMouseMove({ - xMousePos: d3.event.clientX, - chartXStart, - chartWidth, - gasPrices, - estimatedTimes, - chart, - }) - }) - }, 0) - - this.chart = chart - } - - componentDidUpdate(prevProps) { - const { gasPrices, currentPrice: newPrice } = this.props - - if (prevProps.currentPrice !== newPrice) { - handleChartUpdate({ - chart: this.chart, - gasPrices, - newPrice, - cssId: '#set-circle', - }) - } - } - - componentDidMount() { - this.renderChart() - } - - render() { - return ( -
-
-
- ) - } -} diff --git a/ui/app/components/app/gas-customization/gas-price-chart/gas-price-chart.utils.js b/ui/app/components/app/gas-customization/gas-price-chart/gas-price-chart.utils.js deleted file mode 100644 index 6fa809686..000000000 --- a/ui/app/components/app/gas-customization/gas-price-chart/gas-price-chart.utils.js +++ /dev/null @@ -1,422 +0,0 @@ -import * as d3 from 'd3' -import c3 from 'c3' -import { - extrapolateY, - getAdjacentGasPrices, - newBigSigDig, - bigNumMinus, - bigNumDiv, -} from '../../../../helpers/utils/gas-time-estimates.util' - -export function handleMouseMove({ - xMousePos, - chartXStart, - chartWidth, - gasPrices, - estimatedTimes, - chart, -}) { - const { currentPosValue, newTimeEstimate } = getNewXandTimeEstimate({ - xMousePos, - chartXStart, - chartWidth, - gasPrices, - estimatedTimes, - }) - - if (currentPosValue === null && newTimeEstimate === null) { - hideDataUI(chart, '#overlayed-circle') - return - } - - const indexOfNewCircle = estimatedTimes.length + 1 - const dataUIObj = generateDataUIObj( - currentPosValue, - indexOfNewCircle, - newTimeEstimate, - ) - - chart.internal.overlayPoint(dataUIObj, indexOfNewCircle) - chart.internal.showTooltip( - [dataUIObj], - d3.select('.c3-areas-data1')._groups[0], - ) - chart.internal.showXGridFocus([dataUIObj]) -} - -export function getCoordinateData(selector) { - const node = d3.select(selector).node() - return node ? node.getBoundingClientRect() : {} -} - -export function generateDataUIObj(x, index, value) { - return { - x, - value, - index, - id: 'data1', - name: 'data1', - } -} - -export function handleChartUpdate({ chart, gasPrices, newPrice, cssId }) { - const { - closestLowerValueIndex, - closestLowerValue, - closestHigherValueIndex, - closestHigherValue, - } = getAdjacentGasPrices({ gasPrices, priceToPosition: newPrice }) - - if (closestLowerValue && closestHigherValue) { - setSelectedCircle({ - chart, - newPrice, - closestLowerValueIndex, - closestLowerValue, - closestHigherValueIndex, - closestHigherValue, - }) - } else { - hideDataUI(chart, cssId) - } -} - -export function getNewXandTimeEstimate({ - xMousePos, - chartXStart, - chartWidth, - gasPrices, - estimatedTimes, -}) { - const chartMouseXPos = bigNumMinus(xMousePos, chartXStart) - const posPercentile = bigNumDiv(chartMouseXPos, chartWidth) - - const currentPosValue = bigNumMinus( - gasPrices[gasPrices.length - 1], - gasPrices[0], - ) - .times(newBigSigDig(posPercentile)) - .plus(newBigSigDig(gasPrices[0])) - .toNumber() - - const { - closestLowerValueIndex, - closestLowerValue, - closestHigherValueIndex, - closestHigherValue, - } = getAdjacentGasPrices({ gasPrices, priceToPosition: currentPosValue }) - - return !closestHigherValue || !closestLowerValue - ? { - currentPosValue: null, - newTimeEstimate: null, - } - : { - currentPosValue, - newTimeEstimate: extrapolateY({ - higherY: estimatedTimes[closestHigherValueIndex], - lowerY: estimatedTimes[closestLowerValueIndex], - higherX: closestHigherValue, - lowerX: closestLowerValue, - xForExtrapolation: currentPosValue, - }), - } -} - -export function hideDataUI(chart, dataNodeId) { - const overLayedCircle = d3.select(dataNodeId) - if (!overLayedCircle.empty()) { - overLayedCircle.remove() - } - d3.select('.c3-tooltip-container').style('display', 'none !important') - chart.internal.hideXGridFocus() -} - -export function setTickPosition(axis, n, newPosition, secondNewPosition) { - const positionToShift = axis === 'y' ? 'x' : 'y' - const secondPositionToShift = axis === 'y' ? 'y' : 'x' - d3.select('#chart') - .select(`.c3-axis-${axis}`) - .selectAll('.tick') - .filter((_, i) => i === n) - .select('text') - .attr(positionToShift, 0) - .select('tspan') - .attr(positionToShift, newPosition) - .attr(secondPositionToShift, secondNewPosition || 0) - .style('visibility', 'visible') -} - -/* eslint-disable @babel/no-invalid-this */ -export function appendOrUpdateCircle({ - data, - itemIndex, - cx, - cy, - cssId, - appendOnly, -}) { - const circle = this.main - .select(`.c3-selected-circles${this.getTargetSelectorSuffix(data.id)}`) - .selectAll(`.c3-selected-circle-${itemIndex}`) - - if (appendOnly || circle.empty()) { - circle - .data([data]) - .enter() - .append('circle') - .attr('class', () => this.generateClass('c3-selected-circle', itemIndex)) - .attr('id', cssId) - .attr('cx', cx) - .attr('cy', cy) - .attr('stroke', () => this.color(data)) - .attr('r', 6) - } else { - circle.data([data]).attr('cx', cx).attr('cy', cy) - } -} -/* eslint-enable @babel/no-invalid-this */ - -export function setSelectedCircle({ - chart, - newPrice, - closestLowerValueIndex, - closestLowerValue, - closestHigherValueIndex, - closestHigherValue, -}) { - const numberOfValues = chart.internal.data.xs.data1.length - - const { x: lowerX, y: lowerY } = getCoordinateData( - `.c3-circle-${closestLowerValueIndex}`, - ) - let { x: higherX, y: higherY } = getCoordinateData( - `.c3-circle-${closestHigherValueIndex}`, - ) - let count = closestHigherValueIndex + 1 - - if (lowerX && higherX) { - while (lowerX === higherX) { - higherX = getCoordinateData(`.c3-circle-${count}`).x - higherY = getCoordinateData(`.c3-circle-${count}`).y - count += 1 - } - } - - const currentX = bigNumMinus(higherX, lowerX) - .times(bigNumMinus(newPrice, closestLowerValue)) - .div(bigNumMinus(closestHigherValue, closestLowerValue)) - .plus(newBigSigDig(lowerX)) - - const newTimeEstimate = extrapolateY({ - higherY, - lowerY, - higherX, - lowerX, - xForExtrapolation: currentX, - }) - - chart.internal.selectPoint( - generateDataUIObj(currentX.toNumber(), numberOfValues, newTimeEstimate), - numberOfValues, - ) -} - -export function generateChart( - gasPrices, - estimatedTimes, - gasPricesMax, - estimatedTimesMax, -) { - const gasPricesMaxPadded = gasPricesMax + 1 - const chart = c3.generate({ - size: { - height: 165, - }, - transition: { - duration: 0, - }, - padding: { left: 20, right: 15, top: 6, bottom: 10 }, - data: { - x: 'x', - columns: [ - ['x', ...gasPrices], - ['data1', ...estimatedTimes], - ], - types: { - data1: 'area', - }, - selection: { - enabled: false, - }, - }, - color: { - data1: '#259de5', - }, - axis: { - x: { - min: gasPrices[0], - max: gasPricesMax, - tick: { - values: [Math.floor(gasPrices[0]), Math.ceil(gasPricesMax)], - outer: false, - format(val) { - return `${val} GWEI` - }, - }, - padding: { left: gasPricesMax / 50, right: gasPricesMax / 50 }, - label: { - text: 'Gas Price ($)', - position: 'outer-center', - }, - }, - y: { - padding: { top: 7, bottom: 7 }, - tick: { - values: [ - Math.floor(estimatedTimesMax * 0.05), - Math.ceil(estimatedTimesMax * 0.97), - ], - outer: false, - }, - label: { - text: 'Confirmation time (sec)', - position: 'outer-middle', - }, - min: 0, - }, - }, - legend: { - show: false, - }, - grid: { - x: {}, - lines: { - front: false, - }, - }, - point: { - focus: { - expand: { - enabled: false, - r: 3.5, - }, - }, - }, - tooltip: { - format: { - title: (v) => v.toPrecision(4), - }, - contents(d) { - const titleFormat = this.config.tooltip_format_title - let text - d.forEach((el) => { - if (el && (el.value || el.value === 0) && !text) { - text = `` - } - }) - return `${text}
${titleFormat( - el.x, - )}
` - }, - position() { - if (d3.select('#overlayed-circle').empty()) { - return { top: -100, left: -100 } - } - - const { - x: circleX, - y: circleY, - width: circleWidth, - } = getCoordinateData('#overlayed-circle') - const { x: chartXStart, y: chartYStart } = getCoordinateData( - '.c3-chart', - ) - - // TODO: Confirm the below constants work with all data sets and screen sizes - const flipTooltip = circleY - circleWidth < chartYStart + 5 - - d3.select('.tooltip-arrow').style( - 'margin-top', - flipTooltip ? '-16px' : '4px', - ) - - return { - top: bigNumMinus(circleY, chartYStart) - .minus(19) - .plus(flipTooltip ? circleWidth + 38 : 0) - .toNumber(), - left: bigNumMinus(circleX, chartXStart) - .plus(newBigSigDig(circleWidth)) - .minus(bigNumDiv(gasPricesMaxPadded, 50)) - .toNumber(), - } - }, - show: true, - }, - }) - - chart.internal.selectPoint = function (data, itemIndex = data.index || 0) { - const { x: chartXStart, y: chartYStart } = getCoordinateData( - '.c3-areas-data1', - ) - - d3.select('#set-circle').remove() - - appendOrUpdateCircle.bind(this)({ - data, - itemIndex, - cx: () => bigNumMinus(data.x, chartXStart).plus(11).toNumber(), - cy: () => bigNumMinus(data.value, chartYStart).plus(10).toNumber(), - cssId: 'set-circle', - appendOnly: true, - }) - } - - chart.internal.overlayPoint = function (data, itemIndex) { - appendOrUpdateCircle.bind(this)({ - data, - itemIndex, - cx: this.circleX.bind(this), - cy: this.circleY.bind(this), - cssId: 'overlayed-circle', - }) - } - - chart.internal.showTooltip = function (selectedData, element) { - const dataToShow = selectedData.filter( - (d) => d && (d.value || d.value === 0), - ) - - if (dataToShow.length) { - this.tooltip - .html( - this.config.tooltip_contents.call( - this, - selectedData, - this.axis.getXAxisTickFormat(), - this.getYFormat(), - this.color, - ), - ) - .style('display', 'flex') - - // Get tooltip dimensions - const tWidth = this.tooltip.property('offsetWidth') - const tHeight = this.tooltip.property('offsetHeight') - const position = this.config.tooltip_position.call( - this, - dataToShow, - tWidth, - tHeight, - element, - ) - // Set tooltip - this.tooltip - .style('top', `${position.top}px`) - .style('left', `${position.left}px`) - } - } - - return chart -} diff --git a/ui/app/components/app/gas-customization/gas-price-chart/index.js b/ui/app/components/app/gas-customization/gas-price-chart/index.js deleted file mode 100644 index 9895acb62..000000000 --- a/ui/app/components/app/gas-customization/gas-price-chart/index.js +++ /dev/null @@ -1 +0,0 @@ -export { default } from './gas-price-chart.component' diff --git a/ui/app/components/app/gas-customization/gas-price-chart/index.scss b/ui/app/components/app/gas-customization/gas-price-chart/index.scss deleted file mode 100644 index 8d204e9ec..000000000 --- a/ui/app/components/app/gas-customization/gas-price-chart/index.scss +++ /dev/null @@ -1,134 +0,0 @@ -.gas-price-chart { - display: flex; - position: relative; - justify-content: center; - - &__root { - max-height: 154px; - max-width: 391px; - position: relative; - overflow: hidden; - - @media screen and (max-width: $break-small) { - max-width: 326px; - } - } - - .tick text, - .c3-axis-x-label, - .c3-axis-y-label { - @include H9; - - line-height: normal; - font-weight: bold; - text-align: center; - fill: #9a9ca6 !important; - } - - .c3-tooltip-container { - display: flex; - justify-content: center !important; - align-items: flex-end !important; - } - - .custom-tooltip { - background: rgba(0, 0, 0, 1); - box-shadow: 0 4px 4px rgba(0, 0, 0, 0.25); - border-radius: 3px; - opacity: 1 !important; - height: 21px; - z-index: 1; - } - - .tooltip-arrow { - background: black; - box-shadow: 0 4px 4px rgba(0, 0, 0, 0.5); - -webkit-transform: rotate(45deg); - transform: rotate(45deg); - opacity: 1 !important; - width: 9px; - height: 9px; - margin-top: 4px; - } - - .custom-tooltip th { - @include H8; - - font-weight: 500; - text-align: center; - padding: 3px; - color: #fff; - } - - .c3-circle { - visibility: hidden; - } - - .c3-selected-circle, - .c3-circle._expanded_ { - fill: #fff !important; - stroke-width: 2.4px !important; - stroke: #2d9fd9 !important; - - /* visibility: visible; */ - } - - #set-circle { - fill: #313a5e !important; - stroke: #313a5e !important; - } - - .c3-axis-x-label, - .c3-axis-y-label { - font-weight: normal; - } - - .tick text tspan { - visibility: hidden; - } - - .c3-circle { - fill: #2d9fd9 !important; - } - - .c3-line-data1 { - stroke: #2d9fd9 !important; - background: rgba(0, 0, 0, 0) !important; - color: rgba(0, 0, 0, 0) !important; - } - - .c3 path { - fill: none; - } - - .c3 path.c3-area-data1 { - opacity: 1; - fill: #e9edf1 !important; - } - - .c3-xgrid-line line { - stroke: #b8b8b8 !important; - } - - .c3-xgrid-focus { - stroke: #aaa; - } - - .c3-axis-x .domain { - fill: none; - stroke: none; - } - - .c3-axis-y .domain { - fill: none; - stroke: #c8ccd6; - } - - .c3-event-rect { - cursor: pointer; - } -} - -#chart { - background: #f8f9fb; -} diff --git a/ui/app/components/app/gas-customization/gas-price-chart/tests/gas-price-chart.component.test.js b/ui/app/components/app/gas-customization/gas-price-chart/tests/gas-price-chart.component.test.js deleted file mode 100644 index 6256b8734..000000000 --- a/ui/app/components/app/gas-customization/gas-price-chart/tests/gas-price-chart.component.test.js +++ /dev/null @@ -1,258 +0,0 @@ -import assert from 'assert' -import React from 'react' -import proxyquire from 'proxyquire' -import sinon from 'sinon' -import * as d3 from 'd3' -import shallow from '../../../../../../lib/shallow-with-context' - -function timeout(time) { - return new Promise((resolve) => { - setTimeout(resolve, time) - }) -} - -describe('GasPriceChart Component', function () { - let GasPriceChart - let gasPriceChartUtilsSpies - let propsMethodSpies - let selectReturnSpies - let testProps - let wrapper - - beforeEach(function () { - propsMethodSpies = { - updateCustomGasPrice: sinon.spy(), - } - - selectReturnSpies = { - empty: sinon.spy(), - remove: sinon.spy(), - style: sinon.spy(), - select: d3.select, - attr: sinon.spy(), - on: sinon.spy(), - datum: sinon.stub().returns({ x: 'mockX' }), - } - - const mockSelectReturn = { - ...d3.select('div'), - node: () => ({ - getBoundingClientRect: () => ({ x: 123, y: 321, width: 400 }), - }), - ...selectReturnSpies, - } - - gasPriceChartUtilsSpies = { - appendOrUpdateCircle: sinon.spy(), - generateChart: sinon.stub().returns({ mockChart: true }), - generateDataUIObj: sinon.spy(), - getAdjacentGasPrices: sinon.spy(), - getCoordinateData: sinon - .stub() - .returns({ x: 'mockCoordinateX', width: 'mockWidth' }), - getNewXandTimeEstimate: sinon.spy(), - handleChartUpdate: sinon.spy(), - hideDataUI: sinon.spy(), - setSelectedCircle: sinon.spy(), - setTickPosition: sinon.spy(), - handleMouseMove: sinon.spy(), - } - - testProps = { - gasPrices: [1.5, 2.5, 4, 8], - estimatedTimes: [100, 80, 40, 10], - gasPricesMax: 9, - estimatedTimesMax: 100, - currentPrice: 6, - updateCustomGasPrice: propsMethodSpies.updateCustomGasPrice, - } - - GasPriceChart = proxyquire('../gas-price-chart.component.js', { - './gas-price-chart.utils.js': gasPriceChartUtilsSpies, - d3: { - ...d3, - select(...args) { - const result = d3.select(...args) - return result.empty() ? mockSelectReturn : result - }, - event: { - clientX: 'mockClientX', - }, - }, - }).default - sinon.spy(GasPriceChart.prototype, 'renderChart') - - wrapper = shallow() - }) - - afterEach(function () { - sinon.restore() - }) - - describe('render()', function () { - it('should render', function () { - assert(wrapper.hasClass('gas-price-chart')) - }) - - it('should render the chart div', function () { - assert(wrapper.childAt(0).hasClass('gas-price-chart__root')) - assert.equal(wrapper.childAt(0).props().id, 'chart') - }) - }) - - describe('componentDidMount', function () { - it('should call this.renderChart', function () { - assert(GasPriceChart.prototype.renderChart.callCount, 1) - wrapper.instance().componentDidMount() - assert(GasPriceChart.prototype.renderChart.callCount, 2) - }) - }) - - describe('componentDidUpdate', function () { - it('should call handleChartUpdate if props.currentPrice has changed', function () { - gasPriceChartUtilsSpies.handleChartUpdate.resetHistory() - wrapper.instance().componentDidUpdate({ currentPrice: 7 }) - assert.equal(gasPriceChartUtilsSpies.handleChartUpdate.callCount, 1) - }) - - it('should call handleChartUpdate with the correct props', function () { - gasPriceChartUtilsSpies.handleChartUpdate.resetHistory() - wrapper.instance().componentDidUpdate({ currentPrice: 7 }) - assert.deepEqual( - gasPriceChartUtilsSpies.handleChartUpdate.getCall(0).args, - [ - { - chart: { mockChart: true }, - gasPrices: [1.5, 2.5, 4, 8], - newPrice: 6, - cssId: '#set-circle', - }, - ], - ) - }) - - it('should not call handleChartUpdate if props.currentPrice has not changed', function () { - gasPriceChartUtilsSpies.handleChartUpdate.resetHistory() - wrapper.instance().componentDidUpdate({ currentPrice: 6 }) - assert.equal(gasPriceChartUtilsSpies.handleChartUpdate.callCount, 0) - }) - }) - - describe('renderChart', function () { - it('should call setTickPosition 4 times, with the expected props', async function () { - await timeout(0) - gasPriceChartUtilsSpies.setTickPosition.resetHistory() - assert.equal(gasPriceChartUtilsSpies.setTickPosition.callCount, 0) - wrapper.instance().renderChart(testProps) - await timeout(0) - assert.equal(gasPriceChartUtilsSpies.setTickPosition.callCount, 4) - assert.deepEqual( - gasPriceChartUtilsSpies.setTickPosition.getCall(0).args, - ['y', 0, -5, 8], - ) - assert.deepEqual( - gasPriceChartUtilsSpies.setTickPosition.getCall(1).args, - ['y', 1, -3, -5], - ) - assert.deepEqual( - gasPriceChartUtilsSpies.setTickPosition.getCall(2).args, - ['x', 0, 3], - ) - assert.deepEqual( - gasPriceChartUtilsSpies.setTickPosition.getCall(3).args, - ['x', 1, 3, -8], - ) - }) - - it('should call handleChartUpdate with the correct props', async function () { - await timeout(0) - gasPriceChartUtilsSpies.handleChartUpdate.resetHistory() - wrapper.instance().renderChart(testProps) - await timeout(0) - assert.deepEqual( - gasPriceChartUtilsSpies.handleChartUpdate.getCall(0).args, - [ - { - chart: { mockChart: true }, - gasPrices: [1.5, 2.5, 4, 8], - newPrice: 6, - cssId: '#set-circle', - }, - ], - ) - }) - - it('should add three events to the chart', async function () { - await timeout(0) - selectReturnSpies.on.resetHistory() - assert.equal(selectReturnSpies.on.callCount, 0) - wrapper.instance().renderChart(testProps) - await timeout(0) - assert.equal(selectReturnSpies.on.callCount, 3) - - const firstOnEventArgs = selectReturnSpies.on.getCall(0).args - assert.equal(firstOnEventArgs[0], 'mouseout') - const secondOnEventArgs = selectReturnSpies.on.getCall(1).args - assert.equal(secondOnEventArgs[0], 'click') - const thirdOnEventArgs = selectReturnSpies.on.getCall(2).args - assert.equal(thirdOnEventArgs[0], 'mousemove') - }) - - it('should hide the data UI on mouseout', async function () { - await timeout(0) - selectReturnSpies.on.resetHistory() - wrapper.instance().renderChart(testProps) - gasPriceChartUtilsSpies.hideDataUI.resetHistory() - await timeout(0) - const mouseoutEventArgs = selectReturnSpies.on.getCall(0).args - assert.equal(gasPriceChartUtilsSpies.hideDataUI.callCount, 0) - mouseoutEventArgs[1]() - assert.equal(gasPriceChartUtilsSpies.hideDataUI.callCount, 1) - assert.deepEqual(gasPriceChartUtilsSpies.hideDataUI.getCall(0).args, [ - { mockChart: true }, - '#overlayed-circle', - ]) - }) - - it('should updateCustomGasPrice on click', async function () { - await timeout(0) - selectReturnSpies.on.resetHistory() - wrapper.instance().renderChart(testProps) - propsMethodSpies.updateCustomGasPrice.resetHistory() - await timeout(0) - const mouseoutEventArgs = selectReturnSpies.on.getCall(1).args - assert.equal(propsMethodSpies.updateCustomGasPrice.callCount, 0) - mouseoutEventArgs[1]() - assert.equal(propsMethodSpies.updateCustomGasPrice.callCount, 1) - assert.equal( - propsMethodSpies.updateCustomGasPrice.getCall(0).args[0], - 'mockX', - ) - }) - - it('should handle mousemove', async function () { - await timeout(0) - selectReturnSpies.on.resetHistory() - wrapper.instance().renderChart(testProps) - gasPriceChartUtilsSpies.handleMouseMove.resetHistory() - await timeout(0) - const mouseoutEventArgs = selectReturnSpies.on.getCall(2).args - assert.equal(gasPriceChartUtilsSpies.handleMouseMove.callCount, 0) - mouseoutEventArgs[1]() - assert.equal(gasPriceChartUtilsSpies.handleMouseMove.callCount, 1) - assert.deepEqual( - gasPriceChartUtilsSpies.handleMouseMove.getCall(0).args, - [ - { - xMousePos: 'mockClientX', - chartXStart: 'mockCoordinateX', - chartWidth: 'mockWidth', - gasPrices: testProps.gasPrices, - estimatedTimes: testProps.estimatedTimes, - chart: { mockChart: true }, - }, - ], - ) - }) - }) -}) diff --git a/ui/app/components/app/gas-customization/index.scss b/ui/app/components/app/gas-customization/index.scss index 06a9d7820..fa8954bab 100644 --- a/ui/app/components/app/gas-customization/index.scss +++ b/ui/app/components/app/gas-customization/index.scss @@ -1,4 +1,3 @@ @import './gas-slider/index'; @import './gas-modal-page-container/index'; -@import './gas-price-chart/index'; @import './advanced-gas-inputs/index'; diff --git a/ui/app/components/app/sidebars/sidebar-content.scss b/ui/app/components/app/sidebars/sidebar-content.scss index 91222fdbc..d8bb0a5d0 100644 --- a/ui/app/components/app/sidebars/sidebar-content.scss +++ b/ui/app/components/app/sidebars/sidebar-content.scss @@ -23,14 +23,6 @@ } } - .gas-price-chart { - margin-left: 10px; - - &__root { - max-height: 160px !important; - } - } - .page-container__bottom { display: flex; flex-direction: column; diff --git a/ui/app/components/app/transaction-list-item/transaction-list-item.component.js b/ui/app/components/app/transaction-list-item/transaction-list-item.component.js index 9c472c11f..64a617cda 100644 --- a/ui/app/components/app/transaction-list-item/transaction-list-item.component.js +++ b/ui/app/components/app/transaction-list-item/transaction-list-item.component.js @@ -4,7 +4,6 @@ import classnames from 'classnames' import { useHistory } from 'react-router-dom' import ListItem from '../../ui/list-item' import { useTransactionDisplayData } from '../../../hooks/useTransactionDisplayData' -import Preloader from '../../ui/icon/preloader' import { useI18nContext } from '../../../hooks/useI18nContext' import { useCancelTransaction } from '../../../hooks/useCancelTransaction' import { useRetryTransaction } from '../../../hooks/useRetryTransaction' @@ -15,8 +14,6 @@ import { CONFIRM_TRANSACTION_ROUTE } from '../../../helpers/constants/routes' import { useShouldShowSpeedUp } from '../../../hooks/useShouldShowSpeedUp' import TransactionStatus from '../transaction-status/transaction-status.component' import TransactionIcon from '../transaction-icon' -import { useTransactionTimeRemaining } from '../../../hooks/useTransactionTimeRemaining' -import IconWithLabel from '../../ui/icon-with-label' import { TRANSACTION_GROUP_CATEGORIES, TRANSACTION_STATUSES, @@ -33,7 +30,7 @@ export default function TransactionListItem({ const { initialTransaction: { id }, - primaryTransaction: { err, gasPrice, status, submittedTime }, + primaryTransaction: { err, status }, } = transactionGroup const [cancelEnabled, cancelTransaction] = useCancelTransaction( transactionGroup, @@ -56,16 +53,8 @@ export default function TransactionListItem({ displayedStatusKey, isPending, senderAddress, - isSubmitted, } = useTransactionDisplayData(transactionGroup) - const timeRemaining = useTransactionTimeRemaining( - isSubmitted, - isEarliestNonce, - submittedTime, - gasPrice, - ) - const isSignatureReq = category === TRANSACTION_GROUP_CATEGORIES.SIGNATURE_REQUEST const isApproval = category === TRANSACTION_GROUP_CATEGORIES.APPROVAL @@ -143,16 +132,6 @@ export default function TransactionListItem({ onClick={toggleShowDetails} className={className} title={title} - titleIcon={ - !isUnapproved && - isPending && - isEarliestNonce && ( - } - label={timeRemaining} - /> - ) - } icon={ } diff --git a/ui/app/components/app/transaction-list/transaction-list.component.js b/ui/app/components/app/transaction-list/transaction-list.component.js index cfb70244f..31f690740 100644 --- a/ui/app/components/app/transaction-list/transaction-list.component.js +++ b/ui/app/components/app/transaction-list/transaction-list.component.js @@ -1,12 +1,10 @@ -import React, { useMemo, useEffect, useRef, useState, useCallback } from 'react' +import React, { useMemo, useState, useCallback } from 'react' import PropTypes from 'prop-types' -import { useSelector, useDispatch } from 'react-redux' +import { useSelector } from 'react-redux' import { nonceSortedCompletedTransactionsSelector, nonceSortedPendingTransactionsSelector, } from '../../../selectors/transactions' -import { getFeatureFlags } from '../../../selectors/selectors' -import * as actions from '../../../ducks/gas/gas.duck' import { useI18nContext } from '../../../hooks/useI18nContext' import TransactionListItem from '../transaction-list-item' import Button from '../../ui/button' @@ -63,16 +61,12 @@ export default function TransactionList({ const [limit, setLimit] = useState(PAGE_INCREMENT) const t = useI18nContext() - const dispatch = useDispatch() const unfilteredPendingTransactions = useSelector( nonceSortedPendingTransactionsSelector, ) const unfilteredCompletedTransactions = useSelector( nonceSortedCompletedTransactionsSelector, ) - const { transactionTime: transactionTimeFeatureActive } = useSelector( - getFeatureFlags, - ) const pendingTransactions = useMemo( () => @@ -93,55 +87,6 @@ export default function TransactionList({ [hideTokenTransactions, tokenAddress, unfilteredCompletedTransactions], ) - const { fetchGasEstimates, fetchBasicGasAndTimeEstimates } = useMemo( - () => ({ - fetchGasEstimates: (blockTime) => - dispatch(actions.fetchGasEstimates(blockTime)), - fetchBasicGasAndTimeEstimates: () => - dispatch(actions.fetchBasicGasAndTimeEstimates()), - }), - [dispatch], - ) - - // keep track of previous values from state. - // loaded is used here to determine if our effect has ran at least once. - const prevState = useRef({ - loaded: false, - pendingTransactions, - transactionTimeFeatureActive, - }) - - useEffect(() => { - const { loaded } = prevState.current - const pendingTransactionAdded = - pendingTransactions.length > 0 && - prevState.current.pendingTransactions.length === 0 - const transactionTimeFeatureWasActivated = - !prevState.current.transactionTimeFeatureActive && - transactionTimeFeatureActive - if ( - transactionTimeFeatureActive && - pendingTransactions.length > 0 && - (loaded === false || - transactionTimeFeatureWasActivated || - pendingTransactionAdded) - ) { - fetchBasicGasAndTimeEstimates().then(({ blockTime }) => - fetchGasEstimates(blockTime), - ) - } - prevState.current = { - loaded: true, - pendingTransactions, - transactionTimeFeatureActive, - } - }, [ - fetchGasEstimates, - fetchBasicGasAndTimeEstimates, - transactionTimeFeatureActive, - pendingTransactions, - ]) - const viewMore = useCallback( () => setLimit((prev) => prev + PAGE_INCREMENT), [], diff --git a/ui/app/ducks/gas/gas-duck.test.js b/ui/app/ducks/gas/gas-duck.test.js index ae770a732..b9935af5c 100644 --- a/ui/app/ducks/gas/gas-duck.test.js +++ b/ui/app/ducks/gas/gas-duck.test.js @@ -17,140 +17,21 @@ const { setCustomGasTotal, setCustomGasErrors, resetCustomGasState, - fetchBasicGasAndTimeEstimates, fetchBasicGasEstimates, - gasEstimatesLoadingStarted, - gasEstimatesLoadingFinished, - setPricesAndTimeEstimates, - fetchGasEstimates, - setApiEstimatesLastRetrieved, } = GasDuck const GasReducer = GasDuck.default describe('Gas Duck', function () { let tempFetch let tempDateNow - const mockEthGasApiResponse = { - average: 20, - avgWait: 'mockAvgWait', - block_time: 'mockBlock_time', - blockNum: 'mockBlockNum', - fast: 30, - fastest: 40, - fastestWait: 'mockFastestWait', - fastWait: 'mockFastWait', - safeLow: 10, - safeLowWait: 'mockSafeLowWait', - speed: 'mockSpeed', - standard: 20, + const mockGasPriceApiResponse = { + SafeGasPrice: 10, + ProposeGasPrice: 20, + FastGasPrice: 30, } - const mockPredictTableResponse = [ - { - expectedTime: 400, - expectedWait: 40, - gasprice: 0.25, - somethingElse: 'foobar', - }, - { - expectedTime: 200, - expectedWait: 20, - gasprice: 0.5, - somethingElse: 'foobar', - }, - { - expectedTime: 100, - expectedWait: 10, - gasprice: 1, - somethingElse: 'foobar', - }, - { - expectedTime: 75, - expectedWait: 7.5, - gasprice: 1.5, - somethingElse: 'foobar', - }, - { expectedTime: 50, expectedWait: 5, gasprice: 2, somethingElse: 'foobar' }, - { - expectedTime: 35, - expectedWait: 4.5, - gasprice: 3, - somethingElse: 'foobar', - }, - { - expectedTime: 34, - expectedWait: 4.4, - gasprice: 3.1, - somethingElse: 'foobar', - }, - { - expectedTime: 25, - expectedWait: 4.2, - gasprice: 3.5, - somethingElse: 'foobar', - }, - { expectedTime: 20, expectedWait: 4, gasprice: 4, somethingElse: 'foobar' }, - { - expectedTime: 19, - expectedWait: 3.9, - gasprice: 4.1, - somethingElse: 'foobar', - }, - { expectedTime: 15, expectedWait: 3, gasprice: 7, somethingElse: 'foobar' }, - { - expectedTime: 14, - expectedWait: 2.9, - gasprice: 7.1, - somethingElse: 'foobar', - }, - { - expectedTime: 12, - expectedWait: 2.5, - gasprice: 8, - somethingElse: 'foobar', - }, - { - expectedTime: 10, - expectedWait: 2, - gasprice: 10, - somethingElse: 'foobar', - }, - { - expectedTime: 9, - expectedWait: 1.9, - gasprice: 10.1, - somethingElse: 'foobar', - }, - { expectedTime: 5, expectedWait: 1, gasprice: 15, somethingElse: 'foobar' }, - { - expectedTime: 4, - expectedWait: 0.9, - gasprice: 15.1, - somethingElse: 'foobar', - }, - { - expectedTime: 2, - expectedWait: 0.8, - gasprice: 17, - somethingElse: 'foobar', - }, - { - expectedTime: 1.1, - expectedWait: 0.6, - gasprice: 19.9, - somethingElse: 'foobar', - }, - { - expectedTime: 1, - expectedWait: 0.5, - gasprice: 20, - somethingElse: 'foobar', - }, - ] - const fakeFetch = (url) => + const fakeFetch = () => new Promise((resolve) => { - const dataToResolve = url.match(/ethgasAPI/u) - ? mockEthGasApiResponse - : mockPredictTableResponse + const dataToResolve = mockGasPriceApiResponse resolve({ json: () => Promise.resolve(dataToResolve), }) @@ -183,45 +64,23 @@ describe('Gas Duck', function () { }, basicEstimates: { average: null, - fastestWait: null, - fastWait: null, fast: null, - safeLowWait: null, - blockNum: null, - avgWait: null, - blockTime: null, - speed: null, - fastest: null, safeLow: null, }, basicEstimateIsLoading: true, errors: {}, - gasEstimatesLoading: true, - priceAndTimeEstimates: [], - priceAndTimeEstimatesLastRetrieved: 0, - basicPriceAndTimeEstimatesLastRetrieved: 0, basicPriceEstimatesLastRetrieved: 0, } const BASIC_GAS_ESTIMATE_LOADING_FINISHED = 'metamask/gas/BASIC_GAS_ESTIMATE_LOADING_FINISHED' const BASIC_GAS_ESTIMATE_LOADING_STARTED = 'metamask/gas/BASIC_GAS_ESTIMATE_LOADING_STARTED' - const GAS_ESTIMATE_LOADING_FINISHED = - 'metamask/gas/GAS_ESTIMATE_LOADING_FINISHED' - const GAS_ESTIMATE_LOADING_STARTED = - 'metamask/gas/GAS_ESTIMATE_LOADING_STARTED' const RESET_CUSTOM_GAS_STATE = 'metamask/gas/RESET_CUSTOM_GAS_STATE' const SET_BASIC_GAS_ESTIMATE_DATA = 'metamask/gas/SET_BASIC_GAS_ESTIMATE_DATA' const SET_CUSTOM_GAS_ERRORS = 'metamask/gas/SET_CUSTOM_GAS_ERRORS' const SET_CUSTOM_GAS_LIMIT = 'metamask/gas/SET_CUSTOM_GAS_LIMIT' const SET_CUSTOM_GAS_PRICE = 'metamask/gas/SET_CUSTOM_GAS_PRICE' const SET_CUSTOM_GAS_TOTAL = 'metamask/gas/SET_CUSTOM_GAS_TOTAL' - const SET_PRICE_AND_TIME_ESTIMATES = - 'metamask/gas/SET_PRICE_AND_TIME_ESTIMATES' - const SET_API_ESTIMATES_LAST_RETRIEVED = - 'metamask/gas/SET_API_ESTIMATES_LAST_RETRIEVED' - const SET_BASIC_API_ESTIMATES_LAST_RETRIEVED = - 'metamask/gas/SET_BASIC_API_ESTIMATES_LAST_RETRIEVED' const SET_BASIC_PRICE_ESTIMATES_LAST_RETRIEVED = 'metamask/gas/SET_BASIC_PRICE_ESTIMATES_LAST_RETRIEVED' @@ -254,20 +113,6 @@ describe('Gas Duck', function () { ) }) - it('should set gasEstimatesLoading to true when receiving a GAS_ESTIMATE_LOADING_STARTED action', function () { - assert.deepEqual( - GasReducer(mockState, { type: GAS_ESTIMATE_LOADING_STARTED }), - { gasEstimatesLoading: true, ...mockState }, - ) - }) - - it('should set gasEstimatesLoading to false when receiving a GAS_ESTIMATE_LOADING_FINISHED action', function () { - assert.deepEqual( - GasReducer(mockState, { type: GAS_ESTIMATE_LOADING_FINISHED }), - { gasEstimatesLoading: false, ...mockState }, - ) - }) - it('should set basicEstimates when receiving a SET_BASIC_GAS_ESTIMATE_DATA action', function () { assert.deepEqual( GasReducer(mockState, { @@ -278,16 +123,6 @@ describe('Gas Duck', function () { ) }) - it('should set priceAndTimeEstimates when receiving a SET_PRICE_AND_TIME_ESTIMATES action', function () { - assert.deepEqual( - GasReducer(mockState, { - type: SET_PRICE_AND_TIME_ESTIMATES, - value: { someProp: 'someData123' }, - }), - { priceAndTimeEstimates: { someProp: 'someData123' }, ...mockState }, - ) - }) - it('should set customData.price when receiving a SET_CUSTOM_GAS_PRICE action', function () { assert.deepEqual( GasReducer(mockState, { @@ -318,29 +153,6 @@ describe('Gas Duck', function () { ) }) - it('should set priceAndTimeEstimatesLastRetrieved when receiving a SET_API_ESTIMATES_LAST_RETRIEVED action', function () { - assert.deepEqual( - GasReducer(mockState, { - type: SET_API_ESTIMATES_LAST_RETRIEVED, - value: 1500000000000, - }), - { priceAndTimeEstimatesLastRetrieved: 1500000000000, ...mockState }, - ) - }) - - it('should set priceAndTimeEstimatesLastRetrieved when receiving a SET_BASIC_API_ESTIMATES_LAST_RETRIEVED action', function () { - assert.deepEqual( - GasReducer(mockState, { - type: SET_BASIC_API_ESTIMATES_LAST_RETRIEVED, - value: 1700000000000, - }), - { - basicPriceAndTimeEstimatesLastRetrieved: 1700000000000, - ...mockState, - }, - ) - }) - it('should set errors when receiving a SET_CUSTOM_GAS_ERRORS action', function () { assert.deepEqual( GasReducer(mockState, { @@ -388,8 +200,8 @@ describe('Gas Duck', function () { assert.ok( window.fetch .getCall(0) - .args[0].startsWith('https://ethgasstation.info/json/ethgasAPI.json'), - 'should fetch ETH Gas Station', + .args[0].startsWith('https://api.metaswap.codefi.network/gasPrices'), + 'should fetch metaswap /gasPrices', ) assert.deepEqual(mockDistpatch.getCall(1).args, [ { type: SET_BASIC_PRICE_ESTIMATES_LAST_RETRIEVED, value: 2000000 }, @@ -398,12 +210,9 @@ describe('Gas Duck', function () { { type: SET_BASIC_GAS_ESTIMATE_DATA, value: { - average: 2, - blockTime: 'mockBlock_time', - blockNum: 'mockBlockNum', - fast: 3, - fastest: 4, - safeLow: 1, + average: 20, + fast: 30, + safeLow: 10, }, }, ]) @@ -419,10 +228,7 @@ describe('Gas Duck', function () { .returns(2000000 - 1) // one second ago from "now" fakeStorage.getStorageItem.withArgs('BASIC_PRICE_ESTIMATES').returns({ average: 25, - blockTime: 'mockBlock_time', - blockNum: 'mockBlockNum', fast: 35, - fastest: 45, safeLow: 15, }) @@ -438,10 +244,7 @@ describe('Gas Duck', function () { type: SET_BASIC_GAS_ESTIMATE_DATA, value: { average: 25, - blockTime: 'mockBlock_time', - blockNum: 'mockBlockNum', fast: 35, - fastest: 45, safeLow: 15, }, }, @@ -466,8 +269,8 @@ describe('Gas Duck', function () { assert.ok( window.fetch .getCall(0) - .args[0].startsWith('https://ethgasstation.info/json/ethgasAPI.json'), - 'should fetch ETH Gas Station', + .args[0].startsWith('https://api.metaswap.codefi.network/gasPrices'), + 'should fetch metaswap /gasPrices', ) assert.deepEqual(mockDistpatch.getCall(1).args, [ { type: SET_BASIC_PRICE_ESTIMATES_LAST_RETRIEVED, value: 2000000 }, @@ -476,165 +279,9 @@ describe('Gas Duck', function () { { type: SET_BASIC_GAS_ESTIMATE_DATA, value: { - average: 2, - blockTime: 'mockBlock_time', - blockNum: 'mockBlockNum', - fast: 3, - fastest: 4, - safeLow: 1, - }, - }, - ]) - assert.deepEqual(mockDistpatch.getCall(3).args, [ - { type: BASIC_GAS_ESTIMATE_LOADING_FINISHED }, - ]) - }) - }) - - describe('fetchBasicGasAndTimeEstimates', function () { - it('should call fetch with the expected params', async function () { - const mockDistpatch = sinon.spy() - - await fetchBasicGasAndTimeEstimates()(mockDistpatch, () => ({ - gas: { - ...initState, - basicPriceAndTimeEstimatesLastRetrieved: 1000000, - }, - metamask: { provider: { type: 'ropsten' } }, - })) - assert.deepEqual(mockDistpatch.getCall(0).args, [ - { type: BASIC_GAS_ESTIMATE_LOADING_STARTED }, - ]) - assert.ok( - window.fetch - .getCall(0) - .args[0].startsWith('https://ethgasstation.info/json/ethgasAPI.json'), - 'should fetch ETH Gas Station', - ) - - assert.deepEqual(mockDistpatch.getCall(1).args, [ - { type: SET_BASIC_API_ESTIMATES_LAST_RETRIEVED, value: 2000000 }, - ]) - - assert.deepEqual(mockDistpatch.getCall(2).args, [ - { - type: SET_BASIC_GAS_ESTIMATE_DATA, - value: { - average: 2, - avgWait: 'mockAvgWait', - blockTime: 'mockBlock_time', - blockNum: 'mockBlockNum', - fast: 3, - fastest: 4, - fastestWait: 'mockFastestWait', - fastWait: 'mockFastWait', - safeLow: 1, - safeLowWait: 'mockSafeLowWait', - speed: 'mockSpeed', - }, - }, - ]) - assert.deepEqual(mockDistpatch.getCall(3).args, [ - { type: BASIC_GAS_ESTIMATE_LOADING_FINISHED }, - ]) - }) - - it('should fetch recently retrieved estimates from storage', async function () { - const mockDistpatch = sinon.spy() - fakeStorage.getStorageItem - .withArgs('BASIC_GAS_AND_TIME_API_ESTIMATES_LAST_RETRIEVED') - .returns(2000000 - 1) // one second ago from "now" - fakeStorage.getStorageItem - .withArgs('BASIC_GAS_AND_TIME_API_ESTIMATES') - .returns({ - average: 5, - avgWait: 'mockAvgWait', - blockTime: 'mockBlock_time', - blockNum: 'mockBlockNum', - fast: 6, - fastest: 7, - fastestWait: 'mockFastestWait', - fastWait: 'mockFastWait', - safeLow: 1, - safeLowWait: 'mockSafeLowWait', - speed: 'mockSpeed', - }) - - await fetchBasicGasAndTimeEstimates()(mockDistpatch, () => ({ - gas: { - ...initState, - }, - metamask: { provider: { type: 'ropsten' } }, - })) - assert.deepEqual(mockDistpatch.getCall(0).args, [ - { type: BASIC_GAS_ESTIMATE_LOADING_STARTED }, - ]) - assert.ok(window.fetch.notCalled) - - assert.deepEqual(mockDistpatch.getCall(1).args, [ - { - type: SET_BASIC_GAS_ESTIMATE_DATA, - value: { - average: 5, - avgWait: 'mockAvgWait', - blockTime: 'mockBlock_time', - blockNum: 'mockBlockNum', - fast: 6, - fastest: 7, - fastestWait: 'mockFastestWait', - fastWait: 'mockFastWait', - safeLow: 1, - safeLowWait: 'mockSafeLowWait', - speed: 'mockSpeed', - }, - }, - ]) - assert.deepEqual(mockDistpatch.getCall(2).args, [ - { type: BASIC_GAS_ESTIMATE_LOADING_FINISHED }, - ]) - }) - - it('should fallback to network if retrieving estimates from storage fails', async function () { - const mockDistpatch = sinon.spy() - fakeStorage.getStorageItem - .withArgs('BASIC_GAS_AND_TIME_API_ESTIMATES_LAST_RETRIEVED') - .returns(2000000 - 1) // one second ago from "now" - - await fetchBasicGasAndTimeEstimates()(mockDistpatch, () => ({ - gas: { - ...initState, - }, - metamask: { provider: { type: 'ropsten' } }, - })) - assert.deepEqual(mockDistpatch.getCall(0).args, [ - { type: BASIC_GAS_ESTIMATE_LOADING_STARTED }, - ]) - assert.ok( - window.fetch - .getCall(0) - .args[0].startsWith('https://ethgasstation.info/json/ethgasAPI.json'), - 'should fetch ETH Gas Station', - ) - - assert.deepEqual(mockDistpatch.getCall(1).args, [ - { type: SET_BASIC_API_ESTIMATES_LAST_RETRIEVED, value: 2000000 }, - ]) - - assert.deepEqual(mockDistpatch.getCall(2).args, [ - { - type: SET_BASIC_GAS_ESTIMATE_DATA, - value: { - average: 2, - avgWait: 'mockAvgWait', - blockTime: 'mockBlock_time', - blockNum: 'mockBlockNum', - fast: 3, - fastest: 4, - fastestWait: 'mockFastestWait', - fastWait: 'mockFastWait', - safeLow: 1, - safeLowWait: 'mockSafeLowWait', - speed: 'mockSpeed', + safeLow: 10, + average: 20, + fast: 30, }, }, ]) @@ -644,127 +291,6 @@ describe('Gas Duck', function () { }) }) - describe('fetchGasEstimates', function () { - it('should call fetch with the expected params', async function () { - const mockDistpatch = sinon.spy() - - await fetchGasEstimates(5)(mockDistpatch, () => ({ - gas: { - ...initState, - priceAndTimeEstimatesLastRetrieved: 1000000, - }, - metamask: { provider: { type: 'ropsten' } }, - })) - assert.deepEqual(mockDistpatch.getCall(0).args, [ - { type: GAS_ESTIMATE_LOADING_STARTED }, - ]) - assert.ok( - window.fetch - .getCall(0) - .args[0].startsWith( - 'https://ethgasstation.info/json/predictTable.json', - ), - 'should fetch ETH Gas Station', - ) - - assert.deepEqual(mockDistpatch.getCall(1).args, [ - { type: SET_API_ESTIMATES_LAST_RETRIEVED, value: 2000000 }, - ]) - - const { - type: thirdDispatchCallType, - value: priceAndTimeEstimateResult, - } = mockDistpatch.getCall(2).args[0] - assert.equal(thirdDispatchCallType, SET_PRICE_AND_TIME_ESTIMATES) - assert( - priceAndTimeEstimateResult.length < - mockPredictTableResponse.length * 3 - 2, - ) - assert(!priceAndTimeEstimateResult.find((d) => d.expectedTime > 100)) - assert( - !priceAndTimeEstimateResult.find( - (d, _, a) => a[a + 1] && d.expectedTime > a[a + 1].expectedTime, - ), - ) - assert( - !priceAndTimeEstimateResult.find( - (d, _, a) => a[a + 1] && d.gasprice > a[a + 1].gasprice, - ), - ) - - assert.deepEqual(mockDistpatch.getCall(3).args, [ - { type: GAS_ESTIMATE_LOADING_FINISHED }, - ]) - }) - - it('should not call fetch if the estimates were retrieved < 75000 ms ago', async function () { - const mockDistpatch = sinon.spy() - - await fetchGasEstimates(5)(mockDistpatch, () => ({ - gas: { - ...initState, - priceAndTimeEstimatesLastRetrieved: Date.now(), - priceAndTimeEstimates: [ - { - expectedTime: '10', - expectedWait: 2, - gasprice: 50, - }, - ], - }, - metamask: { provider: { type: 'ropsten' } }, - })) - assert.deepEqual(mockDistpatch.getCall(0).args, [ - { type: GAS_ESTIMATE_LOADING_STARTED }, - ]) - assert.equal(window.fetch.callCount, 0) - - assert.deepEqual(mockDistpatch.getCall(1).args, [ - { - type: SET_PRICE_AND_TIME_ESTIMATES, - value: [ - { - expectedTime: '10', - expectedWait: 2, - gasprice: 50, - }, - ], - }, - ]) - assert.deepEqual(mockDistpatch.getCall(2).args, [ - { type: GAS_ESTIMATE_LOADING_FINISHED }, - ]) - }) - }) - - describe('gasEstimatesLoadingStarted', function () { - it('should create the correct action', function () { - assert.deepEqual(gasEstimatesLoadingStarted(), { - type: GAS_ESTIMATE_LOADING_STARTED, - }) - }) - }) - - describe('gasEstimatesLoadingFinished', function () { - it('should create the correct action', function () { - assert.deepEqual(gasEstimatesLoadingFinished(), { - type: GAS_ESTIMATE_LOADING_FINISHED, - }) - }) - }) - - describe('setPricesAndTimeEstimates', function () { - it('should create the correct action', function () { - assert.deepEqual( - setPricesAndTimeEstimates('mockPricesAndTimeEstimates'), - { - type: SET_PRICE_AND_TIME_ESTIMATES, - value: 'mockPricesAndTimeEstimates', - }, - ) - }) - }) - describe('setBasicGasEstimateData', function () { it('should create the correct action', function () { assert.deepEqual(setBasicGasEstimateData('mockBasicEstimatData'), { @@ -810,15 +336,6 @@ describe('Gas Duck', function () { }) }) - describe('setApiEstimatesLastRetrieved', function () { - it('should create the correct action', function () { - assert.deepEqual(setApiEstimatesLastRetrieved(1234), { - type: SET_API_ESTIMATES_LAST_RETRIEVED, - value: 1234, - }) - }) - }) - describe('resetCustomGasState', function () { it('should create the correct action', function () { assert.deepEqual(resetCustomGasState(), { type: RESET_CUSTOM_GAS_STATE }) diff --git a/ui/app/ducks/gas/gas.duck.js b/ui/app/ducks/gas/gas.duck.js index a1a8cce4d..751b4304b 100644 --- a/ui/app/ducks/gas/gas.duck.js +++ b/ui/app/ducks/gas/gas.duck.js @@ -1,18 +1,14 @@ -import { uniqBy, cloneDeep, flatten } from 'lodash' +import { cloneDeep } from 'lodash' import BigNumber from 'bignumber.js' import { getStorageItem, setStorageItem } from '../../../lib/storage-helpers' import { decGWEIToHexWEI } from '../../helpers/utils/conversions.util' -import { isEthereumNetwork } from '../../selectors' // Actions const BASIC_GAS_ESTIMATE_LOADING_FINISHED = 'metamask/gas/BASIC_GAS_ESTIMATE_LOADING_FINISHED' const BASIC_GAS_ESTIMATE_LOADING_STARTED = 'metamask/gas/BASIC_GAS_ESTIMATE_LOADING_STARTED' -const GAS_ESTIMATE_LOADING_FINISHED = - 'metamask/gas/GAS_ESTIMATE_LOADING_FINISHED' -const GAS_ESTIMATE_LOADING_STARTED = 'metamask/gas/GAS_ESTIMATE_LOADING_STARTED' const RESET_CUSTOM_GAS_STATE = 'metamask/gas/RESET_CUSTOM_GAS_STATE' const RESET_CUSTOM_DATA = 'metamask/gas/RESET_CUSTOM_DATA' const SET_BASIC_GAS_ESTIMATE_DATA = 'metamask/gas/SET_BASIC_GAS_ESTIMATE_DATA' @@ -20,11 +16,6 @@ const SET_CUSTOM_GAS_ERRORS = 'metamask/gas/SET_CUSTOM_GAS_ERRORS' const SET_CUSTOM_GAS_LIMIT = 'metamask/gas/SET_CUSTOM_GAS_LIMIT' const SET_CUSTOM_GAS_PRICE = 'metamask/gas/SET_CUSTOM_GAS_PRICE' const SET_CUSTOM_GAS_TOTAL = 'metamask/gas/SET_CUSTOM_GAS_TOTAL' -const SET_PRICE_AND_TIME_ESTIMATES = 'metamask/gas/SET_PRICE_AND_TIME_ESTIMATES' -const SET_API_ESTIMATES_LAST_RETRIEVED = - 'metamask/gas/SET_API_ESTIMATES_LAST_RETRIEVED' -const SET_BASIC_API_ESTIMATES_LAST_RETRIEVED = - 'metamask/gas/SET_BASIC_API_ESTIMATES_LAST_RETRIEVED' const SET_BASIC_PRICE_ESTIMATES_LAST_RETRIEVED = 'metamask/gas/SET_BASIC_PRICE_ESTIMATES_LAST_RETRIEVED' @@ -34,23 +25,11 @@ const initState = { limit: null, }, basicEstimates: { + safeLow: null, average: null, - fastestWait: null, - fastWait: null, fast: null, - safeLowWait: null, - blockNum: null, - avgWait: null, - blockTime: null, - speed: null, - fastest: null, - safeLow: null, }, basicEstimateIsLoading: true, - gasEstimatesLoading: true, - priceAndTimeEstimates: [], - priceAndTimeEstimatesLastRetrieved: 0, - basicPriceAndTimeEstimatesLastRetrieved: 0, basicPriceEstimatesLastRetrieved: 0, errors: {}, } @@ -68,16 +47,6 @@ export default function reducer(state = initState, action) { ...state, basicEstimateIsLoading: false, } - case GAS_ESTIMATE_LOADING_STARTED: - return { - ...state, - gasEstimatesLoading: true, - } - case GAS_ESTIMATE_LOADING_FINISHED: - return { - ...state, - gasEstimatesLoading: false, - } case SET_BASIC_GAS_ESTIMATE_DATA: return { ...state, @@ -107,11 +76,6 @@ export default function reducer(state = initState, action) { total: action.value, }, } - case SET_PRICE_AND_TIME_ESTIMATES: - return { - ...state, - priceAndTimeEstimates: action.value, - } case SET_CUSTOM_GAS_ERRORS: return { ...state, @@ -120,16 +84,6 @@ export default function reducer(state = initState, action) { ...action.value, }, } - case SET_API_ESTIMATES_LAST_RETRIEVED: - return { - ...state, - priceAndTimeEstimatesLastRetrieved: action.value, - } - case SET_BASIC_API_ESTIMATES_LAST_RETRIEVED: - return { - ...state, - basicPriceAndTimeEstimatesLastRetrieved: action.value, - } case SET_BASIC_PRICE_ESTIMATES_LAST_RETRIEVED: return { ...state, @@ -160,41 +114,11 @@ export function basicGasEstimatesLoadingFinished() { } } -export function gasEstimatesLoadingStarted() { - return { - type: GAS_ESTIMATE_LOADING_STARTED, - } -} - -export function gasEstimatesLoadingFinished() { - return { - type: GAS_ESTIMATE_LOADING_FINISHED, - } -} - -async function queryEthGasStationBasic() { - const apiKey = process.env.ETH_GAS_STATION_API_KEY - ? `?api-key=${process.env.ETH_GAS_STATION_API_KEY}` - : '' - const url = `https://ethgasstation.info/json/ethgasAPI.json${apiKey}` - return await window.fetch(url, { - headers: {}, - referrer: 'http://ethgasstation.info/json/', - referrerPolicy: 'no-referrer-when-downgrade', - body: null, - method: 'GET', - mode: 'cors', - }) -} - -async function queryEthGasStationPredictionTable() { - const apiKey = process.env.ETH_GAS_STATION_API_KEY - ? `?api-key=${process.env.ETH_GAS_STATION_API_KEY}` - : '' - const url = `https://ethgasstation.info/json/predictTable.json${apiKey}` +async function basicGasPriceQuery() { + const url = `https://api.metaswap.codefi.network/gasPrices` return await window.fetch(url, { headers: {}, - referrer: 'http://ethgasstation.info/json/', + referrer: 'https://api.metaswap.codefi.network/gasPrices', referrerPolicy: 'no-referrer-when-downgrade', body: null, method: 'GET', @@ -229,31 +153,20 @@ export function fetchBasicGasEstimates() { } async function fetchExternalBasicGasEstimates(dispatch) { - const response = await queryEthGasStationBasic() + const response = await basicGasPriceQuery() - const { - safeLow: safeLowTimes10, - average: averageTimes10, - fast: fastTimes10, - fastest: fastestTimes10, - block_time: blockTime, - blockNum, - } = await response.json() + const { SafeGasPrice, ProposeGasPrice, FastGasPrice } = await response.json() - const [average, fast, fastest, safeLow] = [ - averageTimes10, - fastTimes10, - fastestTimes10, - safeLowTimes10, - ].map((price) => new BigNumber(price).div(10).toNumber()) + const [safeLow, average, fast] = [ + SafeGasPrice, + ProposeGasPrice, + FastGasPrice, + ].map((price) => new BigNumber(price, 10).toNumber()) const basicEstimates = { safeLow, average, fast, - fastest, - blockTime, - blockNum, } const timeRetrieved = Date.now() @@ -266,262 +179,6 @@ async function fetchExternalBasicGasEstimates(dispatch) { return basicEstimates } -export function fetchBasicGasAndTimeEstimates() { - return async (dispatch, getState) => { - const { basicPriceAndTimeEstimatesLastRetrieved } = getState().gas - const timeLastRetrieved = - basicPriceAndTimeEstimatesLastRetrieved || - (await getStorageItem( - 'BASIC_GAS_AND_TIME_API_ESTIMATES_LAST_RETRIEVED', - )) || - 0 - - dispatch(basicGasEstimatesLoadingStarted()) - - let basicEstimates - if (Date.now() - timeLastRetrieved > 75000) { - basicEstimates = await fetchExternalBasicGasAndTimeEstimates(dispatch) - } else { - const cachedBasicEstimates = await getStorageItem( - 'BASIC_GAS_AND_TIME_API_ESTIMATES', - ) - basicEstimates = - cachedBasicEstimates || - (await fetchExternalBasicGasAndTimeEstimates(dispatch)) - } - - dispatch(setBasicGasEstimateData(basicEstimates)) - dispatch(basicGasEstimatesLoadingFinished()) - return basicEstimates - } -} - -async function fetchExternalBasicGasAndTimeEstimates(dispatch) { - const response = await queryEthGasStationBasic() - - const { - average: averageTimes10, - avgWait, - block_time: blockTime, - blockNum, - fast: fastTimes10, - fastest: fastestTimes10, - fastestWait, - fastWait, - safeLow: safeLowTimes10, - safeLowWait, - speed, - } = await response.json() - const [average, fast, fastest, safeLow] = [ - averageTimes10, - fastTimes10, - fastestTimes10, - safeLowTimes10, - ].map((price) => new BigNumber(price).div(10).toNumber()) - - const basicEstimates = { - average, - avgWait, - blockTime, - blockNum, - fast, - fastest, - fastestWait, - fastWait, - safeLow, - safeLowWait, - speed, - } - - const timeRetrieved = Date.now() - await Promise.all([ - setStorageItem('BASIC_GAS_AND_TIME_API_ESTIMATES', basicEstimates), - setStorageItem( - 'BASIC_GAS_AND_TIME_API_ESTIMATES_LAST_RETRIEVED', - timeRetrieved, - ), - ]) - dispatch(setBasicApiEstimatesLastRetrieved(timeRetrieved)) - - return basicEstimates -} - -function extrapolateY({ higherY, lowerY, higherX, lowerX, xForExtrapolation }) { - /* eslint-disable no-param-reassign */ - higherY = new BigNumber(higherY, 10) - lowerY = new BigNumber(lowerY, 10) - higherX = new BigNumber(higherX, 10) - lowerX = new BigNumber(lowerX, 10) - xForExtrapolation = new BigNumber(xForExtrapolation, 10) - /* eslint-enable no-param-reassign */ - const slope = higherY.minus(lowerY).div(higherX.minus(lowerX)) - const newTimeEstimate = slope - .times(higherX.minus(xForExtrapolation)) - .minus(higherY) - .negated() - - return Number(newTimeEstimate.toPrecision(10)) -} - -function getRandomArbitrary(minStr, maxStr) { - const min = new BigNumber(minStr, 10) - const max = new BigNumber(maxStr, 10) - const random = new BigNumber(String(Math.random()), 10) - return new BigNumber(random.times(max.minus(min)).plus(min)).toPrecision(10) -} - -function calcMedian(list) { - const medianPos = - (Math.floor(list.length / 2) + Math.ceil(list.length / 2)) / 2 - return medianPos === Math.floor(medianPos) - ? (list[medianPos - 1] + list[medianPos]) / 2 - : list[Math.floor(medianPos)] -} - -function quartiles(data) { - const lowerHalf = data.slice(0, Math.floor(data.length / 2)) - const upperHalf = data.slice( - Math.floor(data.length / 2) + (data.length % 2 === 0 ? 0 : 1), - ) - const median = calcMedian(data) - const lowerQuartile = calcMedian(lowerHalf) - const upperQuartile = calcMedian(upperHalf) - return { - median, - lowerQuartile, - upperQuartile, - } -} - -function inliersByIQR(data, prop) { - const { lowerQuartile, upperQuartile } = quartiles( - data.map((d) => (prop ? d[prop] : d)), - ) - const IQR = upperQuartile - lowerQuartile - const lowerBound = lowerQuartile - 1.5 * IQR - const upperBound = upperQuartile + 1.5 * IQR - return data.filter((d) => { - const value = prop ? d[prop] : d - return value >= lowerBound && value <= upperBound - }) -} - -export function fetchGasEstimates(blockTime) { - return async (dispatch, getState) => { - const state = getState() - - if (!isEthereumNetwork(state)) { - return - } - - const { - priceAndTimeEstimatesLastRetrieved, - priceAndTimeEstimates, - } = state.gas - const timeLastRetrieved = - priceAndTimeEstimatesLastRetrieved || - (await getStorageItem('GAS_API_ESTIMATES_LAST_RETRIEVED')) || - 0 - - dispatch(gasEstimatesLoadingStarted()) - - const shouldGetFreshGasQuote = Date.now() - timeLastRetrieved > 75000 - let estimates - if (shouldGetFreshGasQuote) { - const response = await queryEthGasStationPredictionTable() - const tableJson = await response.json() - - const estimatedPricesAndTimes = tableJson.map( - ({ expectedTime, expectedWait, gasprice }) => ({ - expectedTime, - expectedWait, - gasprice, - }), - ) - const estimatedTimeWithUniquePrices = uniqBy( - estimatedPricesAndTimes, - ({ expectedTime }) => expectedTime, - ) - - const withSupplementalTimeEstimates = flatten( - estimatedTimeWithUniquePrices.map( - ({ expectedWait, gasprice }, i, arr) => { - const next = arr[i + 1] - if (!next) { - return [{ expectedWait, gasprice }] - } - const supplementalPrice = getRandomArbitrary( - gasprice, - next.gasprice, - ) - const supplementalTime = extrapolateY({ - higherY: next.expectedWait, - lowerY: expectedWait, - higherX: next.gasprice, - lowerX: gasprice, - xForExtrapolation: supplementalPrice, - }) - const supplementalPrice2 = getRandomArbitrary( - supplementalPrice, - next.gasprice, - ) - const supplementalTime2 = extrapolateY({ - higherY: next.expectedWait, - lowerY: supplementalTime, - higherX: next.gasprice, - lowerX: supplementalPrice, - xForExtrapolation: supplementalPrice2, - }) - return [ - { expectedWait, gasprice }, - { - expectedWait: supplementalTime, - gasprice: supplementalPrice, - }, - { - expectedWait: supplementalTime2, - gasprice: supplementalPrice2, - }, - ] - }, - ), - ) - const withOutliersRemoved = inliersByIQR( - withSupplementalTimeEstimates.slice(0).reverse(), - 'expectedWait', - ).reverse() - const timeMappedToSeconds = withOutliersRemoved.map( - ({ expectedWait, gasprice }) => { - const expectedTime = new BigNumber(expectedWait) - .times(Number(blockTime), 10) - .toNumber() - return { - expectedTime, - gasprice: new BigNumber(gasprice, 10).toNumber(), - } - }, - ) - - const timeRetrieved = Date.now() - dispatch(setApiEstimatesLastRetrieved(timeRetrieved)) - - await Promise.all([ - setStorageItem('GAS_API_ESTIMATES_LAST_RETRIEVED', timeRetrieved), - setStorageItem('GAS_API_ESTIMATES', timeMappedToSeconds), - ]) - - estimates = timeMappedToSeconds - } else if (priceAndTimeEstimates.length) { - estimates = priceAndTimeEstimates - } else { - estimates = await getStorageItem('GAS_API_ESTIMATES') - } - - dispatch(setPricesAndTimeEstimates(estimates)) - dispatch(gasEstimatesLoadingFinished()) - } -} - export function setCustomGasPriceForRetry(newPrice) { return async (dispatch) => { if (newPrice === '0x0') { @@ -540,13 +197,6 @@ export function setBasicGasEstimateData(basicGasEstimateData) { } } -export function setPricesAndTimeEstimates(estimatedPricesAndTimes) { - return { - type: SET_PRICE_AND_TIME_ESTIMATES, - value: estimatedPricesAndTimes, - } -} - export function setCustomGasPrice(newPrice) { return { type: SET_CUSTOM_GAS_PRICE, @@ -575,20 +225,6 @@ export function setCustomGasErrors(newErrors) { } } -export function setApiEstimatesLastRetrieved(retrievalTime) { - return { - type: SET_API_ESTIMATES_LAST_RETRIEVED, - value: retrievalTime, - } -} - -export function setBasicApiEstimatesLastRetrieved(retrievalTime) { - return { - type: SET_BASIC_API_ESTIMATES_LAST_RETRIEVED, - value: retrievalTime, - } -} - export function setBasicPriceEstimatesLastRetrieved(retrievalTime) { return { type: SET_BASIC_PRICE_ESTIMATES_LAST_RETRIEVED, diff --git a/ui/app/helpers/utils/gas-time-estimates.util.js b/ui/app/helpers/utils/gas-time-estimates.util.js deleted file mode 100644 index 7757f69ff..000000000 --- a/ui/app/helpers/utils/gas-time-estimates.util.js +++ /dev/null @@ -1,125 +0,0 @@ -import BigNumber from 'bignumber.js' - -export function newBigSigDig(n) { - return new BigNumber(new BigNumber(String(n)).toPrecision(15)) -} - -const createOp = (a, b, op) => newBigSigDig(a)[op](newBigSigDig(b)) - -export function bigNumMinus(a = 0, b = 0) { - return createOp(a, b, 'minus') -} - -export function bigNumDiv(a = 0, b = 1) { - return createOp(a, b, 'div') -} - -export function extrapolateY({ - higherY = 0, - lowerY = 0, - higherX = 0, - lowerX = 0, - xForExtrapolation = 0, -}) { - const slope = bigNumMinus(higherY, lowerY).div(bigNumMinus(higherX, lowerX)) - const newTimeEstimate = slope - .times(bigNumMinus(higherX, xForExtrapolation)) - .minus(newBigSigDig(higherY)) - .negated() - - return newTimeEstimate.toNumber() -} - -export function getAdjacentGasPrices({ gasPrices, priceToPosition }) { - const closestLowerValueIndex = gasPrices.findIndex( - (e, i, a) => e <= priceToPosition && a[i + 1] >= priceToPosition, - ) - const closestHigherValueIndex = gasPrices.findIndex( - (e) => e > priceToPosition, - ) - return { - closestLowerValueIndex, - closestHigherValueIndex, - closestHigherValue: gasPrices[closestHigherValueIndex], - closestLowerValue: gasPrices[closestLowerValueIndex], - } -} - -export function formatTimeEstimate(totalSeconds, greaterThanMax, lessThanMin) { - const minutes = Math.floor(totalSeconds / 60) - const seconds = Math.floor(totalSeconds % 60) - - if (!minutes && !seconds) { - return '...' - } - - let symbol = '~' - if (greaterThanMax) { - symbol = '< ' - } else if (lessThanMin) { - symbol = '> ' - } - - const formattedMin = `${minutes ? `${minutes} min` : ''}` - const formattedSec = `${seconds ? `${seconds} sec` : ''}` - const formattedCombined = - formattedMin && formattedSec - ? `${symbol}${formattedMin} ${formattedSec}` - : symbol + (formattedMin || formattedSec) - - return formattedCombined -} - -export function getRawTimeEstimateData( - currentGasPrice, - gasPrices, - estimatedTimes, -) { - const minGasPrice = gasPrices[0] - const maxGasPrice = gasPrices[gasPrices.length - 1] - let priceForEstimation = currentGasPrice - if (currentGasPrice < minGasPrice) { - priceForEstimation = minGasPrice - } else if (currentGasPrice > maxGasPrice) { - priceForEstimation = maxGasPrice - } - - const { - closestLowerValueIndex, - closestHigherValueIndex, - closestHigherValue, - closestLowerValue, - } = getAdjacentGasPrices({ gasPrices, priceToPosition: priceForEstimation }) - - const newTimeEstimate = extrapolateY({ - higherY: estimatedTimes[closestHigherValueIndex], - lowerY: estimatedTimes[closestLowerValueIndex], - higherX: closestHigherValue, - lowerX: closestLowerValue, - xForExtrapolation: priceForEstimation, - }) - - return { - newTimeEstimate, - minGasPrice, - maxGasPrice, - } -} - -export function getRenderableTimeEstimate( - currentGasPrice, - gasPrices, - estimatedTimes, -) { - const { newTimeEstimate, minGasPrice, maxGasPrice } = getRawTimeEstimateData( - currentGasPrice, - gasPrices, - estimatedTimes, - ) - - return formatTimeEstimate( - newTimeEstimate, - currentGasPrice > maxGasPrice, - currentGasPrice < minGasPrice, - ) -} diff --git a/ui/app/hooks/tests/useRetryTransaction.test.js b/ui/app/hooks/tests/useRetryTransaction.test.js index d1e1fb541..30f62ed56 100644 --- a/ui/app/hooks/tests/useRetryTransaction.test.js +++ b/ui/app/hooks/tests/useRetryTransaction.test.js @@ -52,8 +52,6 @@ describe('useRetryTransaction', function () { ) const retry = result.current await retry(event) - const calls = dispatch.getCalls() - assert.equal(calls.length, 5) assert.equal( dispatch.calledWith( showSidebar({ diff --git a/ui/app/hooks/useRetryTransaction.js b/ui/app/hooks/useRetryTransaction.js index 154e99853..63bd6f283 100644 --- a/ui/app/hooks/useRetryTransaction.js +++ b/ui/app/hooks/useRetryTransaction.js @@ -2,8 +2,7 @@ import { useDispatch } from 'react-redux' import { useCallback } from 'react' import { showSidebar } from '../store/actions' import { - fetchBasicGasAndTimeEstimates, - fetchGasEstimates, + fetchBasicGasEstimates, setCustomGasPriceForRetry, setCustomGasLimit, } from '../ducks/gas/gas.duck' @@ -34,8 +33,7 @@ export function useRetryTransaction(transactionGroup) { event.stopPropagation() trackMetricsEvent() - const basicEstimates = await dispatch(fetchBasicGasAndTimeEstimates) - await dispatch(fetchGasEstimates(basicEstimates.blockTime)) + await dispatch(fetchBasicGasEstimates) const transaction = initialTransaction const increasedGasPrice = increaseLastGasPrice(gasPrice) await dispatch( diff --git a/ui/app/hooks/useTransactionTimeRemaining.js b/ui/app/hooks/useTransactionTimeRemaining.js deleted file mode 100644 index 96deadf07..000000000 --- a/ui/app/hooks/useTransactionTimeRemaining.js +++ /dev/null @@ -1,126 +0,0 @@ -import { useSelector } from 'react-redux' -import { useRef, useEffect, useState, useMemo } from 'react' -import { isEqual } from 'lodash' -import { captureException } from '@sentry/browser' -import { hexWEIToDecGWEI } from '../helpers/utils/conversions.util' -import { - getEstimatedGasPrices, - getEstimatedGasTimes, - getFeatureFlags, - getIsMainnet, -} from '../selectors' -import { getRawTimeEstimateData } from '../helpers/utils/gas-time-estimates.util' -import { getCurrentLocale } from '../ducks/metamask/metamask' - -/** - * Calculate the number of minutes remaining until the transaction completes. - * @param {number} initialTimeEstimate - timestamp for the projected completion time - * @param {number} submittedTime - timestamp of when the tx was submitted - * @return {number} minutes remaining - */ -function calcTransactionTimeRemaining(initialTimeEstimate, submittedTime) { - const currentTime = new Date().getTime() - const timeElapsedSinceSubmission = (currentTime - submittedTime) / 1000 - const timeRemainingOnEstimate = - initialTimeEstimate - timeElapsedSinceSubmission - - const renderingTimeRemainingEstimate = Math.round( - timeRemainingOnEstimate / 60, - ) - return renderingTimeRemainingEstimate -} - -/** - * returns a string representing the number of minutes predicted for the transaction to be - * completed. Only returns this prediction if the transaction is the earliest pending - * transaction, and the feature flag for showing timing is enabled. - * @param {bool} isSubmitted - is the transaction currently in the 'submitted' state - * @param {bool} isEarliestNonce - is this transaction the earliest nonce in list - * @param {number} submittedTime - the timestamp for when the transaction was submitted - * @param {number} currentGasPrice - gas price to use for calculation of time - * @param {boolean} dontFormat - Whether the result should be be formatted, or just a number of minutes - * @returns {string | undefined} i18n formatted string if applicable - */ -export function useTransactionTimeRemaining( - isSubmitted, - isEarliestNonce, - submittedTime, - currentGasPrice, - forceAllow, - dontFormat, -) { - // the following two selectors return the result of mapping over an array, as such they - // will always be new objects and trigger effects. To avoid this, we use isEqual as the - // equalityFn to only update when the data is new. - const gasPrices = useSelector(getEstimatedGasPrices, isEqual) - const estimatedTimes = useSelector(getEstimatedGasTimes, isEqual) - const locale = useSelector(getCurrentLocale) - const isMainNet = useSelector(getIsMainnet) - const interval = useRef() - const [timeRemaining, setTimeRemaining] = useState(null) - const featureFlags = useSelector(getFeatureFlags) - const transactionTimeFeatureActive = featureFlags?.transactionTime - - const rtf = new Intl.RelativeTimeFormat(locale.replace('_', '-'), { - numeric: 'auto', - style: 'narrow', - }) - - // Memoize this value so it can be used as a dependency in the effect below - const initialTimeEstimate = useMemo(() => { - const customGasPrice = Number(hexWEIToDecGWEI(currentGasPrice)) - try { - const { newTimeEstimate } = getRawTimeEstimateData( - customGasPrice, - gasPrices, - estimatedTimes, - ) - return newTimeEstimate - } catch (error) { - captureException(error) - return NaN - } - }, [currentGasPrice, gasPrices, estimatedTimes]) - - useEffect(() => { - if ( - isMainNet && - (transactionTimeFeatureActive || forceAllow) && - isSubmitted && - isEarliestNonce && - !isNaN(initialTimeEstimate) - ) { - clearInterval(interval.current) - setTimeRemaining( - calcTransactionTimeRemaining(initialTimeEstimate, submittedTime), - ) - interval.current = setInterval(() => { - setTimeRemaining( - calcTransactionTimeRemaining(initialTimeEstimate, submittedTime), - ) - }, 10000) - return () => clearInterval(interval.current) - } - return undefined - }, [ - isMainNet, - transactionTimeFeatureActive, - isEarliestNonce, - submittedTime, - initialTimeEstimate, - forceAllow, - isSubmitted, - ]) - - // there are numerous checks to determine if time should be displayed. - // if any of the following are true, the timeRemaining will be null - // User is currently not on the mainnet - // User does not have the transactionTime feature flag enabled - // The transaction is not pending, or isn't the earliest nonce - if (timeRemaining && dontFormat) { - return timeRemaining - } else if (timeRemaining) { - return rtf.format(timeRemaining, 'minute') - } - return undefined -} diff --git a/ui/app/pages/confirm-transaction/confirm-transaction.component.js b/ui/app/pages/confirm-transaction/confirm-transaction.component.js index 92f073d9d..d794717ae 100644 --- a/ui/app/pages/confirm-transaction/confirm-transaction.component.js +++ b/ui/app/pages/confirm-transaction/confirm-transaction.component.js @@ -37,7 +37,7 @@ export default class ConfirmTransaction extends Component { send: PropTypes.object, setTransactionToConfirm: PropTypes.func, clearConfirmTransaction: PropTypes.func, - fetchBasicGasAndTimeEstimates: PropTypes.func, + fetchBasicGasEstimates: PropTypes.func, mostRecentOverviewPage: PropTypes.string.isRequired, transaction: PropTypes.object, getContractMethodData: PropTypes.func, @@ -54,7 +54,7 @@ export default class ConfirmTransaction extends Component { history, mostRecentOverviewPage, transaction: { txParams: { data, to } = {} } = {}, - fetchBasicGasAndTimeEstimates, + fetchBasicGasEstimates, getContractMethodData, transactionId, paramsTransactionId, @@ -67,7 +67,7 @@ export default class ConfirmTransaction extends Component { return } - fetchBasicGasAndTimeEstimates() + fetchBasicGasEstimates() getContractMethodData(data) if (isTokenMethodAction) { getTokenParams(to) diff --git a/ui/app/pages/confirm-transaction/confirm-transaction.container.js b/ui/app/pages/confirm-transaction/confirm-transaction.container.js index 61c4bc445..8dc56236d 100644 --- a/ui/app/pages/confirm-transaction/confirm-transaction.container.js +++ b/ui/app/pages/confirm-transaction/confirm-transaction.container.js @@ -6,7 +6,7 @@ import { clearConfirmTransaction, } from '../../ducks/confirm-transaction/confirm-transaction.duck' import { isTokenMethodAction } from '../../helpers/utils/transactions.util' -import { fetchBasicGasAndTimeEstimates } from '../../ducks/gas/gas.duck' +import { fetchBasicGasEstimates } from '../../ducks/gas/gas.duck' import { getContractMethodData, getTokenParams } from '../../store/actions' import { unconfirmedTransactionsListSelector } from '../../selectors' @@ -48,8 +48,7 @@ const mapDispatchToProps = (dispatch) => { dispatch(setTransactionToConfirm(transactionId)) }, clearConfirmTransaction: () => dispatch(clearConfirmTransaction()), - fetchBasicGasAndTimeEstimates: () => - dispatch(fetchBasicGasAndTimeEstimates()), + fetchBasicGasEstimates: () => dispatch(fetchBasicGasEstimates()), getContractMethodData: (data) => dispatch(getContractMethodData(data)), getTokenParams: (tokenAddress) => dispatch(getTokenParams(tokenAddress)), } diff --git a/ui/app/pages/settings/advanced-tab/advanced-tab.component.js b/ui/app/pages/settings/advanced-tab/advanced-tab.component.js index 0b3a17491..25aefece0 100644 --- a/ui/app/pages/settings/advanced-tab/advanced-tab.component.js +++ b/ui/app/pages/settings/advanced-tab/advanced-tab.component.js @@ -24,8 +24,6 @@ export default class AdvancedTab extends PureComponent { sendHexData: PropTypes.bool, setAdvancedInlineGasFeatureFlag: PropTypes.func, advancedInlineGas: PropTypes.bool, - setTransactionTimeFeatureFlag: PropTypes.func, - transactionTime: PropTypes.bool, showFiatInTestnets: PropTypes.bool, autoLockTimeLimit: PropTypes.number, setAutoLockTimeLimit: PropTypes.func.isRequired, @@ -211,35 +209,6 @@ export default class AdvancedTab extends PureComponent { ) } - renderTransactionTimeEstimates() { - const { t } = this.context - const { transactionTime, setTransactionTimeFeatureFlag } = this.props - - return ( -
-
- {t('transactionTime')} -
- {t('showTransactionTimeDescription')} -
-
-
-
- setTransactionTimeFeatureFlag(!value)} - offLabel={t('off')} - onLabel={t('on')} - /> -
-
-
- ) - } - renderShowConversionInTestnets() { const { t } = this.context const { @@ -503,7 +472,6 @@ export default class AdvancedTab extends PureComponent { {this.renderMobileSync()} {this.renderResetAccount()} {this.renderAdvancedGasInputInline()} - {this.renderTransactionTimeEstimates()} {this.renderHexDataOptIn()} {this.renderShowConversionInTestnets()} {this.renderUseNonceOptIn()} diff --git a/ui/app/pages/settings/advanced-tab/advanced-tab.container.js b/ui/app/pages/settings/advanced-tab/advanced-tab.container.js index 704af8312..fc4fd8db1 100644 --- a/ui/app/pages/settings/advanced-tab/advanced-tab.container.js +++ b/ui/app/pages/settings/advanced-tab/advanced-tab.container.js @@ -21,7 +21,7 @@ export const mapStateToProps = (state) => { metamask, } = state const { - featureFlags: { sendHexData, transactionTime, advancedInlineGas } = {}, + featureFlags: { sendHexData, advancedInlineGas } = {}, threeBoxSyncingAllowed, threeBoxDisabled, useNonceField, @@ -33,7 +33,6 @@ export const mapStateToProps = (state) => { warning, sendHexData, advancedInlineGas, - transactionTime, showFiatInTestnets, autoLockTimeLimit, threeBoxSyncingAllowed, @@ -52,8 +51,6 @@ export const mapDispatchToProps = (dispatch) => { dispatch(showModal({ name: 'CONFIRM_RESET_ACCOUNT' })), setAdvancedInlineGasFeatureFlag: (shouldShow) => dispatch(setFeatureFlag('advancedInlineGas', shouldShow)), - setTransactionTimeFeatureFlag: (shouldShow) => - dispatch(setFeatureFlag('transactionTime', shouldShow)), setUseNonceField: (value) => dispatch(setUseNonceField(value)), setShowFiatConversionOnTestnetsPreference: (value) => { return dispatch(setShowFiatConversionOnTestnetsPreference(value)) diff --git a/ui/app/pages/settings/advanced-tab/tests/advanced-tab-component.test.js b/ui/app/pages/settings/advanced-tab/tests/advanced-tab-component.test.js index 548623187..c86d50ab1 100644 --- a/ui/app/pages/settings/advanced-tab/tests/advanced-tab-component.test.js +++ b/ui/app/pages/settings/advanced-tab/tests/advanced-tab-component.test.js @@ -24,7 +24,7 @@ describe('AdvancedTab Component', function () { }, ) - assert.equal(root.find('.settings-page__content-row').length, 11) + assert.equal(root.find('.settings-page__content-row').length, 10) }) it('should update autoLockTimeLimit', function () { @@ -46,7 +46,7 @@ describe('AdvancedTab Component', function () { }, ) - const autoTimeout = root.find('.settings-page__content-row').at(8) + const autoTimeout = root.find('.settings-page__content-row').at(7) const textField = autoTimeout.find(TextField) textField.props().onChange({ target: { value: 1440 } }) diff --git a/ui/app/pages/swaps/awaiting-swap/awaiting-swap.js b/ui/app/pages/swaps/awaiting-swap/awaiting-swap.js index 573bce37a..5a35c724e 100644 --- a/ui/app/pages/swaps/awaiting-swap/awaiting-swap.js +++ b/ui/app/pages/swaps/awaiting-swap/awaiting-swap.js @@ -1,8 +1,7 @@ import EventEmitter from 'events' -import React, { useContext, useRef, useState, useEffect } from 'react' +import React, { useContext, useRef, useState } from 'react' import { useDispatch, useSelector } from 'react-redux' import PropTypes from 'prop-types' -import classnames from 'classnames' import { useHistory } from 'react-router-dom' import { I18nContext } from '../../../contexts/i18n' import { useNewMetricEvent } from '../../../hooks/useMetricEvent' @@ -18,15 +17,9 @@ import { prepareForRetryGetQuotes, prepareToLeaveSwaps, } from '../../../ducks/swaps/swaps' -import { useTransactionTimeRemaining } from '../../../hooks/useTransactionTimeRemaining' -import { usePrevious } from '../../../hooks/usePrevious' import Mascot from '../../../components/ui/mascot' import PulseLoader from '../../../components/ui/pulse-loader' -import { - getBlockExplorerUrlForTx, - getStatusKey, -} from '../../../helpers/utils/transactions.util' -import CountdownTimer from '../countdown-timer' +import { getBlockExplorerUrlForTx } from '../../../helpers/utils/transactions.util' import { QUOTES_EXPIRED_ERROR, SWAP_FAILED_ERROR, @@ -38,7 +31,6 @@ import { ASSET_ROUTE, DEFAULT_ROUTE } from '../../../helpers/constants/routes' import { getRenderableNetworkFeesForQuote } from '../swaps.util' import SwapsFooter from '../swaps-footer' -import { TRANSACTION_STATUSES } from '../../../../../shared/constants/transaction' import SwapFailureIcon from './swap-failure-icon' import SwapSuccessIcon from './swap-success-icon' import QuotesTimeoutIcon from './quotes-timeout-icon' @@ -52,8 +44,6 @@ export default function AwaitingSwap({ tokensReceived, rpcPrefs, submittingSwap, - tradeTxData, - usedGasPrice, inputValue, maxSlippage, }) { @@ -71,7 +61,6 @@ export default function AwaitingSwap({ const currentCurrency = useSelector(getCurrentCurrency) const usdConversionRate = useSelector(getUSDConversionRate) - const [timeRemainingExpired, setTimeRemainingExpired] = useState(false) const [trackedQuotesExpiredEvent, setTrackedQuotesExpiredEvent] = useState( false, ) @@ -109,56 +98,6 @@ export default function AwaitingSwap({ const blockExplorerUrl = txHash && getBlockExplorerUrlForTx(networkId, txHash, rpcPrefs) - const statusKey = tradeTxData && getStatusKey(tradeTxData) - const timeRemaining = useTransactionTimeRemaining( - statusKey === TRANSACTION_STATUSES.SUBMITTED, - true, - tradeTxData?.submittedTime, - usedGasPrice, - true, - true, - ) - const previousTimeRemaining = usePrevious(timeRemaining) - const timeRemainingIsNumber = - typeof timeRemaining === 'number' && !isNaN(timeRemaining) - const previousTimeRemainingIsNumber = - typeof previousTimeRemaining === 'number' && !isNaN(previousTimeRemaining) - const estimatedTransactionWaitTime = timeRemaining * 1000 * 60 - - useEffect(() => { - if ( - !timeRemainingIsNumber && - previousTimeRemainingIsNumber && - !timeRemainingExpired - ) { - setTimeRemainingExpired(true) - } - }, [ - timeRemainingIsNumber, - previousTimeRemainingIsNumber, - timeRemainingExpired, - ]) - - let countdownText - if ( - timeRemainingIsNumber && - !timeRemainingExpired && - tradeTxData?.submittedTime - ) { - countdownText = ( - - ) - } else if (tradeTxData?.submittedTime) { - countdownText = t('swapsAlmostDone') - } else { - countdownText = t('swapEstimatedTimeCalculating') - } - let headerText let statusImage let descriptionText @@ -203,13 +142,6 @@ export default function AwaitingSwap({ submitText = t('tryAgain') statusImage = } else if (!errorKey && !swapComplete) { - /** - * only show estimated time if the transaction has a submitted time, the swap has - * not yet completed and there isn't an error. If the swap has not completed and - * there is no error, but also has no submitted time (has not yet been published), - * then we apply the invisible class to the time estimate div. This creates consistent - * spacing before and after display of the time estimate. - */ headerText = t('swapProcessing') statusImage = submitText = t('swapsViewInActivity') @@ -221,31 +153,12 @@ export default function AwaitingSwap({ {destinationTokenInfo.symbol} , ]) - content = ( - <> -
- {t('swapEstimatedTimeFull', [ - - {t('swapEstimatedTime')} - , - countdownText, - ])} -
- {blockExplorerUrl && ( - - )} - + content = blockExplorerUrl && ( + ) } else if (!errorKey && swapComplete) { headerText = t('swapTransactionComplete') @@ -329,8 +242,6 @@ AwaitingSwap.propTypes = { OFFLINE_FOR_MAINTENANCE, ]), submittingSwap: PropTypes.bool, - tradeTxData: PropTypes.object, - usedGasPrice: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), inputValue: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), maxSlippage: PropTypes.number, } diff --git a/ui/app/pages/swaps/index.js b/ui/app/pages/swaps/index.js index f41aef9d6..1d340a61e 100644 --- a/ui/app/pages/swaps/index.js +++ b/ui/app/pages/swaps/index.js @@ -22,7 +22,6 @@ import { getFetchingQuotes, setBalanceError, setTopAssets, - getUsedSwapsGasPrice, getFetchParams, setAggregatorMetadata, getAggregatorMetadata, @@ -94,7 +93,6 @@ export default function Swap() { const [maxSlippage, setMaxSlippage] = useState(fetchParams?.slippage || 2) const routeState = useSelector(getBackgroundSwapRouteState) - const usedGasPrice = useSelector(getUsedSwapsGasPrice) const selectedAccount = useSelector(getSelectedAccount) const quotes = useSelector(getQuotes) const txList = useSelector(currentNetworkTxListSelector) @@ -397,8 +395,6 @@ export default function Swap() { networkId={networkId} txHash={tradeTxData?.hash} tokensReceived={tokensReceived} - tradeTxData={tradeTxData} - usedGasPrice={usedGasPrice} submittingSwap={ routeState === 'awaiting' && !(approveTxId || tradeTxId) } diff --git a/ui/app/selectors/custom-gas.js b/ui/app/selectors/custom-gas.js index 6f5096700..44e2af494 100644 --- a/ui/app/selectors/custom-gas.js +++ b/ui/app/selectors/custom-gas.js @@ -1,7 +1,6 @@ import { addHexPrefix } from '../../../app/scripts/lib/util' import { conversionUtil, - multiplyCurrencies, conversionGreaterThan, } from '../helpers/utils/conversion-util' import { formatCurrency } from '../helpers/utils/confirm-tx.util' @@ -34,22 +33,6 @@ export function getBasicGasEstimateLoadingStatus(state) { return state.gas.basicEstimateIsLoading } -export function getGasEstimatesLoadingStatus(state) { - return state.gas.gasEstimatesLoading -} - -export function getPriceAndTimeEstimates(state) { - return state.gas.priceAndTimeEstimates -} - -export function getEstimatedGasPrices(state) { - return getPriceAndTimeEstimates(state).map(({ gasprice }) => gasprice) -} - -export function getEstimatedGasTimes(state) { - return getPriceAndTimeEstimates(state).map(({ expectedTime }) => expectedTime) -} - export function getAveragePriceEstimateInHexWEI(state) { const averagePriceEstimate = state.gas.basicEstimates.average return getGasPriceInHexWei(averagePriceEstimate || '0x0') @@ -106,10 +89,6 @@ export function isCustomPriceSafe(state) { return customPriceSafe } -export function getBasicGasEstimateBlockTime(state) { - return state.gas.basicEstimates.blockTime -} - export function basicPriceEstimateToETHTotal( estimate, gasLimit, @@ -151,44 +130,6 @@ export function getRenderableConvertedCurrencyFee( return formatCurrency(feeInCurrency, convertedCurrency) } -export function getTimeEstimateInSeconds(blockWaitEstimate) { - return multiplyCurrencies(blockWaitEstimate, 60, { - toNumericBase: 'dec', - multiplicandBase: 10, - multiplierBase: 10, - numberOfDecimals: 1, - }) -} - -export function formatTimeEstimate(totalSeconds, greaterThanMax, lessThanMin) { - const minutes = Math.floor(totalSeconds / 60) - const seconds = Math.floor(totalSeconds % 60) - - if (!minutes && !seconds) { - return '...' - } - - let symbol = '~' - if (greaterThanMax) { - symbol = '< ' - } else if (lessThanMin) { - symbol = '> ' - } - - const formattedMin = `${minutes ? `${minutes} min` : ''}` - const formattedSec = `${seconds ? `${seconds} sec` : ''}` - const formattedCombined = - formattedMin && formattedSec - ? `${symbol}${formattedMin} ${formattedSec}` - : symbol + [formattedMin, formattedSec].find((t) => t) - - return formattedCombined -} - -export function getRenderableTimeEstimate(blockWaitEstimate) { - return formatTimeEstimate(getTimeEstimateInSeconds(blockWaitEstimate)) -} - export function priceEstimateToWei(priceEstimate) { return conversionUtil(priceEstimate, { fromNumericBase: 'hex', @@ -214,16 +155,7 @@ export function getRenderableGasButtonData( conversionRate, currentCurrency, ) { - const { - safeLow, - average, - fast, - safeLowWait, - avgWait, - fastWait, - fastest, - fastestWait, - } = estimates + const { safeLow, average, fast } = estimates const slowEstimateData = { gasEstimateType: GAS_ESTIMATE_TYPES.SLOW, @@ -236,7 +168,6 @@ export function getRenderableGasButtonData( conversionRate, ) : '', - timeEstimate: safeLowWait && getRenderableTimeEstimate(safeLowWait), priceInHexWei: getGasPriceInHexWei(safeLow), } const averageEstimateData = { @@ -250,7 +181,6 @@ export function getRenderableGasButtonData( conversionRate, ) : '', - timeEstimate: avgWait && getRenderableTimeEstimate(avgWait), priceInHexWei: getGasPriceInHexWei(average), } const fastEstimateData = { @@ -264,29 +194,13 @@ export function getRenderableGasButtonData( conversionRate, ) : '', - timeEstimate: fastWait && getRenderableTimeEstimate(fastWait), priceInHexWei: getGasPriceInHexWei(fast), } - const fastestEstimateData = { - gasEstimateType: GAS_ESTIMATE_TYPES.FASTEST, - feeInPrimaryCurrency: getRenderableEthFee(fastest, gasLimit), - feeInSecondaryCurrency: showFiat - ? getRenderableConvertedCurrencyFee( - fastest, - gasLimit, - currentCurrency, - conversionRate, - ) - : '', - timeEstimate: fastestWait && getRenderableTimeEstimate(fastestWait), - priceInHexWei: getGasPriceInHexWei(fastest), - } return { slowEstimateData, averageEstimateData, fastEstimateData, - fastestEstimateData, } } diff --git a/ui/app/selectors/selectors.js b/ui/app/selectors/selectors.js index 8eff1b6e6..d9fd7129a 100644 --- a/ui/app/selectors/selectors.js +++ b/ui/app/selectors/selectors.js @@ -284,13 +284,6 @@ export function getIsMainnet(state) { return networkType === NETWORK_TYPES.MAINNET } -export function isEthereumNetwork(state) { - const networkType = getNetworkIdentifier(state) - const { KOVAN, MAINNET, RINKEBY, ROPSTEN, GOERLI } = NETWORK_TYPES - - return [KOVAN, MAINNET, RINKEBY, ROPSTEN, GOERLI].includes(networkType) -} - export function getPreferences({ metamask }) { return metamask.preferences } diff --git a/ui/app/selectors/tests/custom-gas.test.js b/ui/app/selectors/tests/custom-gas.test.js index 71c89ffe0..e51d3a4a1 100644 --- a/ui/app/selectors/tests/custom-gas.test.js +++ b/ui/app/selectors/tests/custom-gas.test.js @@ -6,9 +6,6 @@ const { getCustomGasLimit, getCustomGasPrice, getCustomGasTotal, - getEstimatedGasPrices, - getEstimatedGasTimes, - getPriceAndTimeEstimates, getRenderableBasicEstimateData, getRenderableEstimateDataForSmallButtonsFromGWEI, } = proxyquire('../custom-gas', {}) @@ -42,48 +39,6 @@ describe('custom-gas selectors', function () { }) }) - describe('getPriceAndTimeEstimates', function () { - it('should return price and time estimates', function () { - const mockState = { - gas: { priceAndTimeEstimates: 'mockPriceAndTimeEstimates' }, - } - assert.equal( - getPriceAndTimeEstimates(mockState), - 'mockPriceAndTimeEstimates', - ) - }) - }) - - describe('getEstimatedGasPrices', function () { - it('should return price and time estimates', function () { - const mockState = { - gas: { - priceAndTimeEstimates: [ - { gasprice: 12, somethingElse: 20 }, - { gasprice: 22, expectedTime: 30 }, - { gasprice: 32, somethingElse: 40 }, - ], - }, - } - assert.deepEqual(getEstimatedGasPrices(mockState), [12, 22, 32]) - }) - }) - - describe('getEstimatedGasTimes', function () { - it('should return price and time estimates', function () { - const mockState = { - gas: { - priceAndTimeEstimates: [ - { somethingElse: 12, expectedTime: 20 }, - { gasPrice: 22, expectedTime: 30 }, - { somethingElse: 32, expectedTime: 40 }, - ], - }, - } - assert.deepEqual(getEstimatedGasTimes(mockState), [20, 30, 40]) - }) - }) - describe('getRenderableBasicEstimateData()', function () { const tests = [ { @@ -92,7 +47,6 @@ describe('custom-gas selectors', function () { gasEstimateType: 'SLOW', feeInSecondaryCurrency: '$0.01', feeInPrimaryCurrency: '0.0000525 ETH', - timeEstimate: '~6 min 36 sec', priceInHexWei: '0x9502f900', }, { @@ -100,13 +54,11 @@ describe('custom-gas selectors', function () { feeInPrimaryCurrency: '0.000084 ETH', feeInSecondaryCurrency: '$0.02', priceInHexWei: '0xee6b2800', - timeEstimate: '~5 min 18 sec', }, { gasEstimateType: 'FAST', feeInSecondaryCurrency: '$0.03', feeInPrimaryCurrency: '0.000105 ETH', - timeEstimate: '~3 min 18 sec', priceInHexWei: '0x12a05f200', }, ], @@ -142,7 +94,6 @@ describe('custom-gas selectors', function () { gasEstimateType: 'SLOW', feeInSecondaryCurrency: '$0.27', feeInPrimaryCurrency: '0.000105 ETH', - timeEstimate: '~13 min 12 sec', priceInHexWei: '0x12a05f200', }, { @@ -150,13 +101,11 @@ describe('custom-gas selectors', function () { feeInSecondaryCurrency: '$0.38', gasEstimateType: 'AVERAGE', priceInHexWei: '0x1a13b8600', - timeEstimate: '~10 min 6 sec', }, { gasEstimateType: 'FAST', feeInSecondaryCurrency: '$0.54', feeInPrimaryCurrency: '0.00021 ETH', - timeEstimate: '~6 min 36 sec', priceInHexWei: '0x2540be400', }, ], @@ -195,21 +144,18 @@ describe('custom-gas selectors', function () { gasEstimateType: 'SLOW', feeInSecondaryCurrency: '', feeInPrimaryCurrency: '0.000105 ETH', - timeEstimate: '~13 min 12 sec', priceInHexWei: '0x12a05f200', }, { gasEstimateType: 'AVERAGE', feeInPrimaryCurrency: '0.000147 ETH', feeInSecondaryCurrency: '', - timeEstimate: '~10 min 6 sec', priceInHexWei: '0x1a13b8600', }, { gasEstimateType: 'FAST', feeInSecondaryCurrency: '', feeInPrimaryCurrency: '0.00021 ETH', - timeEstimate: '~6 min 36 sec', priceInHexWei: '0x2540be400', }, ], @@ -248,7 +194,6 @@ describe('custom-gas selectors', function () { gasEstimateType: 'SLOW', feeInSecondaryCurrency: '$0.27', feeInPrimaryCurrency: '0.000105 ETH', - timeEstimate: '~13 min 12 sec', priceInHexWei: '0x12a05f200', }, { @@ -256,13 +201,11 @@ describe('custom-gas selectors', function () { feeInPrimaryCurrency: '0.000147 ETH', feeInSecondaryCurrency: '$0.38', priceInHexWei: '0x1a13b8600', - timeEstimate: '~10 min 6 sec', }, { gasEstimateType: 'FAST', feeInSecondaryCurrency: '$0.54', feeInPrimaryCurrency: '0.00021 ETH', - timeEstimate: '~6 min 36 sec', priceInHexWei: '0x2540be400', }, ], @@ -282,15 +225,9 @@ describe('custom-gas selectors', function () { }, gas: { basicEstimates: { - blockTime: 14.16326530612245, safeLow: 5, - safeLowWait: 13.2, average: 7, - avgWait: 10.1, fast: 10, - fastWait: 6.6, - fastest: 20, - fastestWait: 1.0, }, }, }, @@ -301,7 +238,6 @@ describe('custom-gas selectors', function () { gasEstimateType: 'SLOW', feeInSecondaryCurrency: '$0.27', feeInPrimaryCurrency: '0.000105 ETH', - timeEstimate: '~13 min 12 sec', priceInHexWei: '0x12a05f200', }, { @@ -309,13 +245,11 @@ describe('custom-gas selectors', function () { feeInPrimaryCurrency: '0.000147 ETH', feeInSecondaryCurrency: '$0.38', priceInHexWei: '0x1a13b8600', - timeEstimate: '~10 min 6 sec', }, { gasEstimateType: 'FAST', feeInSecondaryCurrency: '$0.54', feeInPrimaryCurrency: '0.00021 ETH', - timeEstimate: '~6 min 36 sec', priceInHexWei: '0x2540be400', }, ], @@ -335,15 +269,9 @@ describe('custom-gas selectors', function () { }, gas: { basicEstimates: { - blockTime: 14.16326530612245, safeLow: 5, - safeLowWait: 13.2, average: 7, - avgWait: 10.1, fast: 10, - fastWait: 6.6, - fastest: 20, - fastestWait: 1.0, }, }, }, @@ -402,15 +330,9 @@ describe('custom-gas selectors', function () { }, gas: { basicEstimates: { - blockTime: 14.16326530612245, safeLow: 25, - safeLowWait: 6.6, average: 30, - avgWait: 5.5, fast: 50, - fastWait: 3.3, - fastest: 100, - fastestWait: 0.5, }, }, }, @@ -552,15 +474,9 @@ describe('custom-gas selectors', function () { }, gas: { basicEstimates: { - blockTime: 14.16326530612245, safeLow: 50, - safeLowWait: 13.2, average: 75, - avgWait: 9.6, fast: 100, - fastWait: 6.6, - fastest: 200, - fastestWait: 1.0, }, }, }, @@ -602,15 +518,9 @@ describe('custom-gas selectors', function () { }, gas: { basicEstimates: { - blockTime: 14.16326530612245, safeLow: 50, - safeLowWait: 13.2, average: 75, - avgWait: 9.6, fast: 100, - fastWait: 6.6, - fastest: 200, - fastestWait: 1.0, }, }, }, diff --git a/yarn.lock b/yarn.lock index 03b749ecb..f328d7c05 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6290,13 +6290,6 @@ bytewise@~1.1.0: bytewise-core "^1.2.2" typewise "^1.0.3" -c3@^0.7.10: - version "0.7.12" - resolved "https://registry.yarnpkg.com/c3/-/c3-0.7.12.tgz#ad6205703bab9c2cbedc0223ba7fb2aabc31e94b" - integrity sha512-8gXyKMr9oM171aRGCOqezwEbWwEtIKmEkyvdfgH4oIunSsiTVWyw9Cz6os78LkYPRLMbHDgKcjkQh4EPCrRupQ== - dependencies: - d3 "^5.8.0" - cacache@^12.0.2: version "12.0.3" resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.3.tgz#be99abba4e1bf5df461cd5a2c1071fc432573390" @@ -7152,7 +7145,7 @@ comma-separated-tokens@^1.0.0: resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-1.0.7.tgz#419cd7fb3258b1ed838dc0953167a25e152f5b59" integrity sha512-Jrx3xsP4pPv4AwJUDWY9wOXGtwPXARej6Xd99h4TUGotmf8APuquKMpK+dnD3UgyxK7OEWaisjZz+3b5jtL6xQ== -commander@2, commander@^2.15.0, commander@^2.15.1, commander@^2.16.0, commander@^2.19.0, commander@^2.20.0, commander@^2.6.0: +commander@^2.15.0, commander@^2.15.1, commander@^2.16.0, commander@^2.19.0, commander@^2.20.0, commander@^2.6.0: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== @@ -7835,254 +7828,6 @@ cyclist@~0.2.2: resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-0.2.2.tgz#1b33792e11e914a2fd6d6ed6447464444e5fa640" integrity sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA= -d3-array@1, d3-array@^1.1.1, d3-array@^1.2.0: - version "1.2.4" - resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-1.2.4.tgz#635ce4d5eea759f6f605863dbcfc30edc737f71f" - integrity sha512-KHW6M86R+FUPYGb3R5XiYjXPq7VzwxZ22buHhAEVG5ztoEcZZMLov530mmccaqA1GghZArjQV46fuc8kUqhhHw== - -d3-axis@1: - version "1.0.12" - resolved "https://registry.yarnpkg.com/d3-axis/-/d3-axis-1.0.12.tgz#cdf20ba210cfbb43795af33756886fb3638daac9" - integrity sha512-ejINPfPSNdGFKEOAtnBtdkpr24c4d4jsei6Lg98mxf424ivoDP2956/5HDpIAtmHo85lqT4pruy+zEgvRUBqaQ== - -d3-brush@1: - version "1.0.6" - resolved "https://registry.yarnpkg.com/d3-brush/-/d3-brush-1.0.6.tgz#33691f2032d9db6c5d8cb684ff255a9883629e21" - integrity sha512-lGSiF5SoSqO5/mYGD5FAeGKKS62JdA1EV7HPrU2b5rTX4qEJJtpjaGLJngjnkewQy7UnGstnFd3168wpf5z76w== - dependencies: - d3-dispatch "1" - d3-drag "1" - d3-interpolate "1" - d3-selection "1" - d3-transition "1" - -d3-chord@1: - version "1.0.6" - resolved "https://registry.yarnpkg.com/d3-chord/-/d3-chord-1.0.6.tgz#309157e3f2db2c752f0280fedd35f2067ccbb15f" - integrity sha512-JXA2Dro1Fxw9rJe33Uv+Ckr5IrAa74TlfDEhE/jfLOaXegMQFQTAgAw9WnZL8+HxVBRXaRGCkrNU7pJeylRIuA== - dependencies: - d3-array "1" - d3-path "1" - -d3-collection@1: - version "1.0.7" - resolved "https://registry.yarnpkg.com/d3-collection/-/d3-collection-1.0.7.tgz#349bd2aa9977db071091c13144d5e4f16b5b310e" - integrity sha512-ii0/r5f4sjKNTfh84Di+DpztYwqKhEyUlKoPrzUFfeSkWxjW49xU2QzO9qrPrNkpdI0XJkfzvmTu8V2Zylln6A== - -d3-color@1: - version "1.2.3" - resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-1.2.3.tgz#6c67bb2af6df3cc8d79efcc4d3a3e83e28c8048f" - integrity sha512-x37qq3ChOTLd26hnps36lexMRhNXEtVxZ4B25rL0DVdDsGQIJGB18S7y9XDwlDD6MD/ZBzITCf4JjGMM10TZkw== - -d3-contour@1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/d3-contour/-/d3-contour-1.3.2.tgz#652aacd500d2264cb3423cee10db69f6f59bead3" - integrity sha512-hoPp4K/rJCu0ladiH6zmJUEz6+u3lgR+GSm/QdM2BBvDraU39Vr7YdDCicJcxP1z8i9B/2dJLgDC1NcvlF8WCg== - dependencies: - d3-array "^1.1.1" - -d3-dispatch@1: - version "1.0.5" - resolved "https://registry.yarnpkg.com/d3-dispatch/-/d3-dispatch-1.0.5.tgz#e25c10a186517cd6c82dd19ea018f07e01e39015" - integrity sha512-vwKx+lAqB1UuCeklr6Jh1bvC4SZgbSqbkGBLClItFBIYH4vqDJCA7qfoy14lXmJdnBOdxndAMxjCbImJYW7e6g== - -d3-drag@1: - version "1.2.3" - resolved "https://registry.yarnpkg.com/d3-drag/-/d3-drag-1.2.3.tgz#46e206ad863ec465d88c588098a1df444cd33c64" - integrity sha512-8S3HWCAg+ilzjJsNtWW1Mutl74Nmzhb9yU6igspilaJzeZVFktmY6oO9xOh5TDk+BM2KrNFjttZNoJJmDnkjkg== - dependencies: - d3-dispatch "1" - d3-selection "1" - -d3-dsv@1: - version "1.0.10" - resolved "https://registry.yarnpkg.com/d3-dsv/-/d3-dsv-1.0.10.tgz#4371c489a2a654a297aca16fcaf605a6f31a6f51" - integrity sha512-vqklfpxmtO2ZER3fq/B33R/BIz3A1PV0FaZRuFM8w6jLo7sUX1BZDh73fPlr0s327rzq4H6EN1q9U+eCBCSN8g== - dependencies: - commander "2" - iconv-lite "0.4" - rw "1" - -d3-ease@1: - version "1.0.5" - resolved "https://registry.yarnpkg.com/d3-ease/-/d3-ease-1.0.5.tgz#8ce59276d81241b1b72042d6af2d40e76d936ffb" - integrity sha512-Ct1O//ly5y5lFM9YTdu+ygq7LleSgSE4oj7vUt9tPLHUi8VCV7QoizGpdWRWAwCO9LdYzIrQDg97+hGVdsSGPQ== - -d3-fetch@1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/d3-fetch/-/d3-fetch-1.1.2.tgz#957c8fbc6d4480599ba191b1b2518bf86b3e1be2" - integrity sha512-S2loaQCV/ZeyTyIF2oP8D1K9Z4QizUzW7cWeAOAS4U88qOt3Ucf6GsmgthuYSdyB2HyEm4CeGvkQxWsmInsIVA== - dependencies: - d3-dsv "1" - -d3-force@1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/d3-force/-/d3-force-1.1.2.tgz#16664d0ac71d8727ef5effe0b374feac8050d6cd" - integrity sha512-p1vcHAUF1qH7yR+e8ip7Bs61AHjLeKkIn8Z2gzwU2lwEf2wkSpWdjXG0axudTHsVFnYGlMkFaEsVy2l8tAg1Gw== - dependencies: - d3-collection "1" - d3-dispatch "1" - d3-quadtree "1" - d3-timer "1" - -d3-format@1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/d3-format/-/d3-format-1.3.2.tgz#6a96b5e31bcb98122a30863f7d92365c00603562" - integrity sha512-Z18Dprj96ExragQ0DeGi+SYPQ7pPfRMtUXtsg/ChVIKNBCzjO8XYJvRTC1usblx52lqge56V5ect+frYTQc8WQ== - -d3-geo@1: - version "1.11.3" - resolved "https://registry.yarnpkg.com/d3-geo/-/d3-geo-1.11.3.tgz#5bb08388f45e4b281491faa72d3abd43215dbd1c" - integrity sha512-n30yN9qSKREvV2fxcrhmHUdXP9TNH7ZZj3C/qnaoU0cVf/Ea85+yT7HY7i8ySPwkwjCNYtmKqQFTvLFngfkItQ== - dependencies: - d3-array "1" - -d3-hierarchy@1: - version "1.1.8" - resolved "https://registry.yarnpkg.com/d3-hierarchy/-/d3-hierarchy-1.1.8.tgz#7a6317bd3ed24e324641b6f1e76e978836b008cc" - integrity sha512-L+GHMSZNwTpiq4rt9GEsNcpLa4M96lXMR8M/nMG9p5hBE0jy6C+3hWtyZMenPQdwla249iJy7Nx0uKt3n+u9+w== - -d3-interpolate@1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-1.3.2.tgz#417d3ebdeb4bc4efcc8fd4361c55e4040211fd68" - integrity sha512-NlNKGopqaz9qM1PXh9gBF1KSCVh+jSFErrSlD/4hybwoNX/gt1d8CDbDW+3i+5UOHhjC6s6nMvRxcuoMVNgL2w== - dependencies: - d3-color "1" - -d3-path@1: - version "1.0.7" - resolved "https://registry.yarnpkg.com/d3-path/-/d3-path-1.0.7.tgz#8de7cd693a75ac0b5480d3abaccd94793e58aae8" - integrity sha512-q0cW1RpvA5c5ma2rch62mX8AYaiLX0+bdaSM2wxSU9tXjU4DNvkx9qiUvjkuWCj3p22UO/hlPivujqMiR9PDzA== - -d3-polygon@1: - version "1.0.5" - resolved "https://registry.yarnpkg.com/d3-polygon/-/d3-polygon-1.0.5.tgz#9a645a0a64ff6cbf9efda96ee0b4a6909184c363" - integrity sha512-RHhh1ZUJZfhgoqzWWuRhzQJvO7LavchhitSTHGu9oj6uuLFzYZVeBzaWTQ2qSO6bz2w55RMoOCf0MsLCDB6e0w== - -d3-quadtree@1: - version "1.0.5" - resolved "https://registry.yarnpkg.com/d3-quadtree/-/d3-quadtree-1.0.5.tgz#305394840b01f51a341a0da5008585e837fe7e9b" - integrity sha512-U2tjwDFbZ75JRAg8A+cqMvqPg1G3BE7UTJn3h8DHjY/pnsAfWdbJKgyfcy7zKjqGtLAmI0q8aDSeG1TVIKRaHQ== - -d3-random@1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/d3-random/-/d3-random-1.1.2.tgz#2833be7c124360bf9e2d3fd4f33847cfe6cab291" - integrity sha512-6AK5BNpIFqP+cx/sreKzNjWbwZQCSUatxq+pPRmFIQaWuoD+NrbVWw7YWpHiXpCQ/NanKdtGDuB+VQcZDaEmYQ== - -d3-scale-chromatic@1: - version "1.3.3" - resolved "https://registry.yarnpkg.com/d3-scale-chromatic/-/d3-scale-chromatic-1.3.3.tgz#dad4366f0edcb288f490128979c3c793583ed3c0" - integrity sha512-BWTipif1CimXcYfT02LKjAyItX5gKiwxuPRgr4xM58JwlLocWbjPLI7aMEjkcoOQXMkYsmNsvv3d2yl/OKuHHw== - dependencies: - d3-color "1" - d3-interpolate "1" - -d3-scale@2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/d3-scale/-/d3-scale-2.1.2.tgz#4e932b7b60182aee9073ede8764c98423e5f9a94" - integrity sha512-bESpd64ylaKzCDzvULcmHKZTlzA/6DGSVwx7QSDj/EnX9cpSevsdiwdHFYI9ouo9tNBbV3v5xztHS2uFeOzh8Q== - dependencies: - d3-array "^1.2.0" - d3-collection "1" - d3-format "1" - d3-interpolate "1" - d3-time "1" - d3-time-format "2" - -d3-selection@1, d3-selection@^1.1.0: - version "1.3.2" - resolved "https://registry.yarnpkg.com/d3-selection/-/d3-selection-1.3.2.tgz#6e70a9df60801c8af28ac24d10072d82cbfdf652" - integrity sha512-OoXdv1nZ7h2aKMVg3kaUFbLLK5jXUFAMLD/Tu5JA96mjf8f2a9ZUESGY+C36t8R1WFeWk/e55hy54Ml2I62CRQ== - -d3-shape@1: - version "1.2.2" - resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-1.2.2.tgz#f9dba3777a5825f9a8ce8bc928da08c17679e9a7" - integrity sha512-hUGEozlKecFZ2bOSNt7ENex+4Tk9uc/m0TtTEHBvitCBxUNjhzm5hS2GrrVRD/ae4IylSmxGeqX5tWC2rASMlQ== - dependencies: - d3-path "1" - -d3-time-format@2: - version "2.1.3" - resolved "https://registry.yarnpkg.com/d3-time-format/-/d3-time-format-2.1.3.tgz#ae06f8e0126a9d60d6364eac5b1533ae1bac826b" - integrity sha512-6k0a2rZryzGm5Ihx+aFMuO1GgelgIz+7HhB4PH4OEndD5q2zGn1mDfRdNrulspOfR6JXkb2sThhDK41CSK85QA== - dependencies: - d3-time "1" - -d3-time@1: - version "1.0.10" - resolved "https://registry.yarnpkg.com/d3-time/-/d3-time-1.0.10.tgz#8259dd71288d72eeacfd8de281c4bf5c7393053c" - integrity sha512-hF+NTLCaJHF/JqHN5hE8HVGAXPStEq6/omumPE/SxyHVrR7/qQxusFDo0t0c/44+sCGHthC7yNGFZIEgju0P8g== - -d3-timer@1: - version "1.0.9" - resolved "https://registry.yarnpkg.com/d3-timer/-/d3-timer-1.0.9.tgz#f7bb8c0d597d792ff7131e1c24a36dd471a471ba" - integrity sha512-rT34J5HnQUHhcLvhSB9GjCkN0Ddd5Y8nCwDBG2u6wQEeYxT/Lf51fTFFkldeib/sE/J0clIe0pnCfs6g/lRbyg== - -d3-transition@1: - version "1.1.3" - resolved "https://registry.yarnpkg.com/d3-transition/-/d3-transition-1.1.3.tgz#3a435b05ce9cef9524fe0d38121cfb6905331ca6" - integrity sha512-tEvo3qOXL6pZ1EzcXxFcPNxC/Ygivu5NoBY6mbzidATAeML86da+JfVIUzon3dNM6UX6zjDx+xbYDmMVtTSjuA== - dependencies: - d3-color "1" - d3-dispatch "1" - d3-ease "1" - d3-interpolate "1" - d3-selection "^1.1.0" - d3-timer "1" - -d3-voronoi@1: - version "1.1.4" - resolved "https://registry.yarnpkg.com/d3-voronoi/-/d3-voronoi-1.1.4.tgz#dd3c78d7653d2bb359284ae478645d95944c8297" - integrity sha512-dArJ32hchFsrQ8uMiTBLq256MpnZjeuBtdHpaDlYuQyjU0CVzCJl/BVW+SkszaAeH95D/8gxqAhgx0ouAWAfRg== - -d3-zoom@1: - version "1.7.3" - resolved "https://registry.yarnpkg.com/d3-zoom/-/d3-zoom-1.7.3.tgz#f444effdc9055c38077c4299b4df999eb1d47ccb" - integrity sha512-xEBSwFx5Z9T3/VrwDkMt+mr0HCzv7XjpGURJ8lWmIC8wxe32L39eWHIasEe/e7Ox8MPU4p1hvH8PKN2olLzIBg== - dependencies: - d3-dispatch "1" - d3-drag "1" - d3-interpolate "1" - d3-selection "1" - d3-transition "1" - -d3@^5.15.0, d3@^5.8.0: - version "5.15.0" - resolved "https://registry.yarnpkg.com/d3/-/d3-5.15.0.tgz#ffd44958e6a3cb8a59a84429c45429b8bca5677a" - integrity sha512-C+E80SL2nLLtmykZ6klwYj5rPqB5nlfN5LdWEAVdWPppqTD8taoJi2PxLZjPeYT8FFRR2yucXq+kBlOnnvZeLg== - dependencies: - d3-array "1" - d3-axis "1" - d3-brush "1" - d3-chord "1" - d3-collection "1" - d3-color "1" - d3-contour "1" - d3-dispatch "1" - d3-drag "1" - d3-dsv "1" - d3-ease "1" - d3-fetch "1" - d3-force "1" - d3-format "1" - d3-geo "1" - d3-hierarchy "1" - d3-interpolate "1" - d3-path "1" - d3-polygon "1" - d3-quadtree "1" - d3-random "1" - d3-scale "2" - d3-scale-chromatic "1" - d3-selection "1" - d3-shape "1" - d3-time "1" - d3-time-format "2" - d3-timer "1" - d3-transition "1" - d3-voronoi "1" - d3-zoom "1" - d64@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/d64/-/d64-1.0.0.tgz#4002a87e850cbfc9f9d9706b60fca613a3336e90" @@ -13469,18 +13214,18 @@ hyphenate-style-name@^1.0.3: resolved "https://registry.yarnpkg.com/hyphenate-style-name/-/hyphenate-style-name-1.0.3.tgz#097bb7fa0b8f1a9cf0bd5c734cf95899981a9b48" integrity sha512-EcuixamT82oplpoJ2XU4pDtKGWQ7b00CD9f1ug9IaQ3p1bkHMiKCZ9ut9QDI6qsa6cpUuB+A/I+zLtdNK4n2DQ== -iconv-lite@0.4, iconv-lite@0.4.24, iconv-lite@^0.4.17, iconv-lite@^0.4.24, iconv-lite@^0.4.4, iconv-lite@~0.4.13: +iconv-lite@0.4.19: + version "0.4.19" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b" + integrity sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ== + +iconv-lite@0.4.24, iconv-lite@^0.4.17, iconv-lite@^0.4.24, iconv-lite@^0.4.4, iconv-lite@~0.4.13: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== dependencies: safer-buffer ">= 2.1.2 < 3" -iconv-lite@0.4.19: - version "0.4.19" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b" - integrity sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ== - icss-replace-symbols@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz#06ea6f83679a7749e386cfe1fe812ae5db223ded" @@ -22614,11 +22359,6 @@ rustbn.js@~0.2.0: resolved "https://registry.yarnpkg.com/rustbn.js/-/rustbn.js-0.2.0.tgz#8082cb886e707155fd1cb6f23bd591ab8d55d0ca" integrity sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA== -rw@1: - version "1.3.3" - resolved "https://registry.yarnpkg.com/rw/-/rw-1.3.3.tgz#3f862dfa91ab766b14885ef4d01124bfda074fb4" - integrity sha1-P4Yt+pGrdmsUiF700BEkv9oHT7Q= - rx-lite@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-3.1.2.tgz#19ce502ca572665f3b647b10939f97fd1615f102" From dd3f728e82af160781e1e6c1cb424f6e09659f41 Mon Sep 17 00:00:00 2001 From: Etienne Dusseault Date: Thu, 3 Dec 2020 12:23:02 +0800 Subject: [PATCH 21/32] Remove redundant babelify (#9945) --- development/build/scripts.js | 8 -------- 1 file changed, 8 deletions(-) diff --git a/development/build/scripts.js b/development/build/scripts.js index 86f6e9eb3..2f6b577e4 100644 --- a/development/build/scripts.js +++ b/development/build/scripts.js @@ -333,14 +333,6 @@ function createScriptTasks({ browserPlatforms, livereload }) { let bundler = browserify(browserifyOpts) .transform('babelify') - // Transpile any dependencies using the object spread/rest operator - // because it is incompatible with `esprima`, which is used by `envify` - // See https://github.com/jquery/esprima/issues/1927 - .transform('babelify', { - only: ['./**/node_modules/libp2p'], - global: true, - plugins: ['@babel/plugin-proposal-object-rest-spread'], - }) .transform('brfs') if (opts.buildLib) { From 42fd8b0ff0fb3a395c8cca3d53981ddb74fa116e Mon Sep 17 00:00:00 2001 From: David Walsh Date: Thu, 3 Dec 2020 09:46:22 -0600 Subject: [PATCH 22/32] Use strict equality in unit tests (#9966) --- .../tests/account-list-item-component.test.js | 37 ++-- .../account-menu/tests/account-menu.test.js | 36 ++-- .../tests/unconnected-account-alert.test.js | 13 +- .../app/app-header/tests/app-header.test.js | 4 +- .../confirm-detail-row.component.test.js | 14 +- .../app/dropdowns/tests/dropdown.test.js | 8 +- .../tests/network-dropdown-icon.test.js | 8 +- .../dropdowns/tests/network-dropdown.test.js | 20 +-- .../advanced-gas-input-component.test.js | 28 +-- .../advanced-tab-content-component.test.js | 11 +- .../tests/basic-tab-content-component.test.js | 20 +-- ...gas-modal-page-container-component.test.js | 68 +++++--- .../app/info-box/tests/info-box.test.js | 4 +- .../tests/modal-content.component.test.js | 26 +-- .../app/modal/tests/modal.component.test.js | 52 +++--- ...ncel-transaction-gas-fee.component.test.js | 10 +- .../cancel-transaction.component.test.js | 28 +-- .../tests/confirm-delete-network.test.js | 2 +- .../tests/confirm-remove-account.test.js | 5 +- .../tests/metametrics-opt-in-modal.test.js | 10 +- .../tests/account-details-modal.test.js | 4 +- .../tests/selected-account-component.test.js | 7 +- .../sidebars/tests/sidebars-component.test.js | 14 +- .../tests/signature-request.test.js | 2 +- .../app/token-cell/token-cell.test.js | 22 ++- ...transaction-activity-log.component.test.js | 4 +- ...transaction-activity-log.container.test.js | 2 +- .../transaction-activity-log.util.test.js | 11 +- ...ransaction-breakdown-row.component.test.js | 6 +- ...action-list-item-details.component.test.js | 10 +- .../transaction-status.component.test.js | 12 +- ...erenced-currency-display.component.test.js | 10 +- ...eferenced-currency-input.component.test.js | 8 +- ...eferenced-currency-input.container.test.js | 2 +- ...-preferenced-token-input.component.test.js | 8 +- ...-preferenced-token-input.container.test.js | 2 +- ...cccount-mismatch-warning.component.test.js | 4 +- .../components/ui/alert/tests/alert.test.js | 6 +- .../tests/breadcrumbs.component.test.js | 10 +- .../tests/button-group-component.test.js | 41 ++--- .../ui/card/tests/card.component.test.js | 4 +- .../tests/currency-display.component.test.js | 4 +- .../tests/currency-input.component.test.js | 136 ++++++++------- .../tests/currency-input.container.test.js | 4 +- .../tests/error-message.component.test.js | 12 +- .../tests/hex-to-decimal.component.test.js | 4 +- .../tests/identicon.component.test.js | 8 +- .../ui/list-item/tests/list-item.test.js | 14 +- .../tests/metafox-logo.component.test.js | 12 +- .../page-container-footer.component.test.js | 23 +-- .../page-container-header.component.test.js | 31 ++-- .../tests/token-input.component.test.js | 111 ++++++------ .../tests/unit-input.component.test.js | 34 ++-- .../confirm-transaction.duck.test.js | 83 +++++---- ui/app/ducks/gas/gas-duck.test.js | 60 +++---- ui/app/ducks/send/send-duck.test.js | 30 ++-- .../tests/with-modal-props.test.js | 12 +- ui/app/helpers/utils/common.util.test.js | 2 +- ui/app/helpers/utils/confirm-tx.util.test.js | 34 ++-- ui/app/helpers/utils/conversion-util.test.js | 58 +++---- ui/app/helpers/utils/conversions.util.test.js | 12 +- ui/app/helpers/utils/fetch-with-cache.test.js | 6 +- ui/app/helpers/utils/i18n-helper.test.js | 18 +- .../helpers/utils/transactions.util.test.js | 10 +- ui/app/helpers/utils/util.test.js | 57 ++++--- .../hooks/tests/useCancelTransaction.test.js | 12 +- ui/app/hooks/tests/useCurrencyDisplay.test.js | 6 +- .../hooks/tests/useRetryTransaction.test.js | 4 +- ui/app/hooks/tests/useTokenData.test.js | 6 +- .../hooks/tests/useTokenDisplayValue.test.js | 2 +- .../tests/useTransactionDisplayData.test.js | 24 ++- .../tests/useUserPreferencedCurrency.test.js | 4 +- .../pages/add-token/tests/add-token.test.js | 15 +- ...confirm-transaction-base.component.test.js | 10 +- .../tests/create-account.test.js | 12 +- .../import-with-seed-phrase.component.test.js | 21 ++- .../end-of-flow/tests/end-of-flow.test.js | 2 +- .../tests/first-time-flow-switch.test.js | 14 +- .../tests/reveal-seed-phrase.test.js | 10 +- .../confirm-seed-phrase-component.test.js | 20 +-- .../select-action/tests/select-action.test.js | 4 +- .../welcome/tests/welcome.test.js | 4 +- ui/app/pages/lock/tests/lock.test.js | 4 +- .../tests/add-recipient-component.test.js | 47 +++--- .../tests/add-recipient-container.test.js | 4 +- .../tests/add-recipient-utils.test.js | 16 +- .../tests/amount-max-button-component.test.js | 20 ++- .../tests/amount-max-button-container.test.js | 18 +- .../tests/amount-max-button-utils.test.js | 4 +- .../tests/send-amount-row-component.test.js | 30 ++-- .../tests/send-amount-row-container.test.js | 29 ++-- .../tests/gas-fee-display.component.test.js | 14 +- .../tests/send-gas-row-component.test.js | 34 ++-- .../send-row-error-message-component.test.js | 8 +- .../send-row-error-message-container.test.js | 2 +- .../tests/send-row-wrapper-component.test.js | 20 +-- .../tests/send-content-component.test.js | 14 +- .../tests/send-footer-component.test.js | 44 ++--- .../tests/send-footer-container.test.js | 79 +++++---- .../tests/send-footer-utils.test.js | 16 +- .../tests/send-header-component.test.js | 18 +- .../pages/send/tests/send-component.test.js | 113 +++++++------ .../pages/send/tests/send-container.test.js | 13 +- ui/app/pages/send/tests/send-utils.test.js | 159 ++++++++++-------- .../tests/advanced-tab-component.test.js | 6 +- .../security-tab/tests/security-tab.test.js | 2 +- ui/app/pages/swaps/swaps.util.test.js | 24 +-- .../unlock-page/tests/unlock-page.test.js | 6 +- .../tests/confirm-transaction.test.js | 8 +- ui/app/selectors/tests/custom-gas.test.js | 12 +- ui/app/selectors/tests/permissions.test.js | 69 ++++---- ui/app/selectors/tests/selectors.test.js | 40 +++-- ui/app/selectors/tests/send.test.js | 83 ++++----- ui/app/selectors/tests/transactions.test.js | 19 ++- 114 files changed, 1359 insertions(+), 1154 deletions(-) diff --git a/ui/app/components/app/account-list-item/tests/account-list-item-component.test.js b/ui/app/components/app/account-list-item/tests/account-list-item-component.test.js index 4c65e3b70..5b329d1ac 100644 --- a/ui/app/components/app/account-list-item/tests/account-list-item-component.test.js +++ b/ui/app/components/app/account-list-item/tests/account-list-item-component.test.js @@ -45,23 +45,23 @@ describe('AccountListItem Component', function () { }) it('should render a div with the passed className', function () { - assert.equal(wrapper.find('.mockClassName').length, 1) + assert.strictEqual(wrapper.find('.mockClassName').length, 1) assert(wrapper.find('.mockClassName').is('div')) assert(wrapper.find('.mockClassName').hasClass('account-list-item')) }) it('should call handleClick with the expected props when the root div is clicked', function () { const { onClick } = wrapper.find('.mockClassName').props() - assert.equal(propsMethodSpies.handleClick.callCount, 0) + assert.strictEqual(propsMethodSpies.handleClick.callCount, 0) onClick() - assert.equal(propsMethodSpies.handleClick.callCount, 1) - assert.deepEqual(propsMethodSpies.handleClick.getCall(0).args, [ + assert.strictEqual(propsMethodSpies.handleClick.callCount, 1) + assert.deepStrictEqual(propsMethodSpies.handleClick.getCall(0).args, [ { address: 'mockAddress', name: 'mockName', balance: 'mockBalance' }, ]) }) it('should have a top row div', function () { - assert.equal( + assert.strictEqual( wrapper.find('.mockClassName > .account-list-item__top-row').length, 1, ) @@ -74,16 +74,19 @@ describe('AccountListItem Component', function () { const topRow = wrapper.find( '.mockClassName > .account-list-item__top-row', ) - assert.equal(topRow.find(Identicon).length, 1) - assert.equal(topRow.find('.account-list-item__account-name').length, 1) - assert.equal(topRow.find('.account-list-item__icon').length, 1) + assert.strictEqual(topRow.find(Identicon).length, 1) + assert.strictEqual( + topRow.find('.account-list-item__account-name').length, + 1, + ) + assert.strictEqual(topRow.find('.account-list-item__icon').length, 1) }) it('should show the account name if it exists', function () { const topRow = wrapper.find( '.mockClassName > .account-list-item__top-row', ) - assert.equal( + assert.strictEqual( topRow.find('.account-list-item__account-name').text(), 'mockName', ) @@ -94,7 +97,7 @@ describe('AccountListItem Component', function () { const topRow = wrapper.find( '.mockClassName > .account-list-item__top-row', ) - assert.equal( + assert.strictEqual( topRow.find('.account-list-item__account-name').text(), 'addressButNoName', ) @@ -115,25 +118,27 @@ describe('AccountListItem Component', function () { const topRow = wrapper.find( '.mockClassName > .account-list-item__top-row', ) - assert.equal(topRow.find('.account-list-item__icon').length, 0) + assert.strictEqual(topRow.find('.account-list-item__icon').length, 0) }) it('should render the account address as a checksumAddress if displayAddress is true and name is provided', function () { wrapper.setProps({ displayAddress: true }) - assert.equal( + assert.strictEqual( wrapper.find('.account-list-item__account-address').length, 1, ) - assert.equal( + assert.strictEqual( wrapper.find('.account-list-item__account-address').text(), 'mockCheckSumAddress', ) - assert.deepEqual(checksumAddressStub.getCall(0).args, ['mockAddress']) + assert.deepStrictEqual(checksumAddressStub.getCall(0).args, [ + 'mockAddress', + ]) }) it('should not render the account address as a checksumAddress if displayAddress is false', function () { wrapper.setProps({ displayAddress: false }) - assert.equal( + assert.strictEqual( wrapper.find('.account-list-item__account-address').length, 0, ) @@ -141,7 +146,7 @@ describe('AccountListItem Component', function () { it('should not render the account address as a checksumAddress if name is not provided', function () { wrapper.setProps({ account: { address: 'someAddressButNoName' } }) - assert.equal( + assert.strictEqual( wrapper.find('.account-list-item__account-address').length, 0, ) diff --git a/ui/app/components/app/account-menu/tests/account-menu.test.js b/ui/app/components/app/account-menu/tests/account-menu.test.js index 70dba281f..eb35b1c3b 100644 --- a/ui/app/components/app/account-menu/tests/account-menu.test.js +++ b/ui/app/components/app/account-menu/tests/account-menu.test.js @@ -74,14 +74,14 @@ describe('Account Menu', function () { describe('Render Content', function () { it('returns account name from identities', function () { const accountName = wrapper.find('.account-menu__name') - assert.equal(accountName.length, 2) + assert.strictEqual(accountName.length, 2) }) it('renders user preference currency display balance from account balance', function () { const accountBalance = wrapper.find( '.currency-display-component.account-menu__balance', ) - assert.equal(accountBalance.length, 2) + assert.strictEqual(accountBalance.length, 2) }) it('simulate click', function () { @@ -91,12 +91,15 @@ describe('Account Menu', function () { click.first().simulate('click') assert(props.showAccountDetail.calledOnce) - assert.equal(props.showAccountDetail.getCall(0).args[0], '0xAddress') + assert.strictEqual( + props.showAccountDetail.getCall(0).args[0], + '0xAddress', + ) }) it('render imported account label', function () { const importedAccount = wrapper.find('.keyring-label.allcaps') - assert.equal(importedAccount.text(), 'imported') + assert.strictEqual(importedAccount.text(), 'imported') }) }) @@ -105,13 +108,13 @@ describe('Account Menu', function () { it('logout', function () { logout = wrapper.find('.account-menu__lock-button') - assert.equal(logout.length, 1) + assert.strictEqual(logout.length, 1) }) it('simulate click', function () { logout.simulate('click') assert(props.lockMetamask.calledOnce) - assert.equal(props.history.push.getCall(0).args[0], '/') + assert.strictEqual(props.history.push.getCall(0).args[0], '/') }) }) @@ -120,13 +123,13 @@ describe('Account Menu', function () { it('renders create account item', function () { createAccount = wrapper.find({ text: 'createAccount' }) - assert.equal(createAccount.length, 1) + assert.strictEqual(createAccount.length, 1) }) it('calls toggle menu and push new-account route to history', function () { createAccount.simulate('click') assert(props.toggleAccountMenu.calledOnce) - assert.equal(props.history.push.getCall(0).args[0], '/new-account') + assert.strictEqual(props.history.push.getCall(0).args[0], '/new-account') }) }) @@ -135,7 +138,7 @@ describe('Account Menu', function () { it('renders import account item', function () { importAccount = wrapper.find({ text: 'importAccount' }) - assert.equal(importAccount.length, 1) + assert.strictEqual(importAccount.length, 1) }) it('calls toggle menu and push /new-account/import route to history', function () { @@ -150,13 +153,13 @@ describe('Account Menu', function () { it('renders import account item', function () { connectHardwareWallet = wrapper.find({ text: 'connectHardwareWallet' }) - assert.equal(connectHardwareWallet.length, 1) + assert.strictEqual(connectHardwareWallet.length, 1) }) it('calls toggle menu and push /new-account/connect route to history', function () { connectHardwareWallet.simulate('click') assert(props.toggleAccountMenu.calledOnce) - assert.equal( + assert.strictEqual( props.history.push.getCall(0).args[0], '/new-account/connect', ) @@ -168,13 +171,16 @@ describe('Account Menu', function () { it('renders import account item', function () { infoHelp = wrapper.find({ text: 'infoHelp' }) - assert.equal(infoHelp.length, 1) + assert.strictEqual(infoHelp.length, 1) }) it('calls toggle menu and push /new-account/connect route to history', function () { infoHelp.simulate('click') assert(props.toggleAccountMenu.calledOnce) - assert.equal(props.history.push.getCall(0).args[0], '/settings/about-us') + assert.strictEqual( + props.history.push.getCall(0).args[0], + '/settings/about-us', + ) }) }) @@ -183,13 +189,13 @@ describe('Account Menu', function () { it('renders import account item', function () { settings = wrapper.find({ text: 'settings' }) - assert.equal(settings.length, 1) + assert.strictEqual(settings.length, 1) }) it('calls toggle menu and push /new-account/connect route to history', function () { settings.simulate('click') assert(props.toggleAccountMenu.calledOnce) - assert.equal(props.history.push.getCall(0).args[0], '/settings') + assert.strictEqual(props.history.push.getCall(0).args[0], '/settings') }) }) }) diff --git a/ui/app/components/app/alerts/unconnected-account-alert/tests/unconnected-account-alert.test.js b/ui/app/components/app/alerts/unconnected-account-alert/tests/unconnected-account-alert.test.js index fff6504bb..d16ec36c0 100644 --- a/ui/app/components/app/alerts/unconnected-account-alert/tests/unconnected-account-alert.test.js +++ b/ui/app/components/app/alerts/unconnected-account-alert/tests/unconnected-account-alert.test.js @@ -115,9 +115,9 @@ describe('Unconnected Account Alert', function () { const dontShowCheckbox = getByRole('checkbox') - assert.equal(dontShowCheckbox.checked, false) + assert.strictEqual(dontShowCheckbox.checked, false) fireEvent.click(dontShowCheckbox) - assert.equal(dontShowCheckbox.checked, true) + assert.strictEqual(dontShowCheckbox.checked, true) }) it('clicks dismiss button and calls dismissAlert action', function () { @@ -128,7 +128,10 @@ describe('Unconnected Account Alert', function () { const dismissButton = getByText(/dismiss/u) fireEvent.click(dismissButton) - assert.equal(store.getActions()[0].type, 'unconnectedAccount/dismissAlert') + assert.strictEqual( + store.getActions()[0].type, + 'unconnectedAccount/dismissAlert', + ) }) it('clicks Dont Show checkbox and dismiss to call disable alert request action', async function () { @@ -148,11 +151,11 @@ describe('Unconnected Account Alert', function () { fireEvent.click(dismissButton) setImmediate(() => { - assert.equal( + assert.strictEqual( store.getActions()[0].type, 'unconnectedAccount/disableAlertRequested', ) - assert.equal( + assert.strictEqual( store.getActions()[1].type, 'unconnectedAccount/disableAlertSucceeded', ) diff --git a/ui/app/components/app/app-header/tests/app-header.test.js b/ui/app/components/app/app-header/tests/app-header.test.js index 0bb9ed9df..7a1b43ee7 100644 --- a/ui/app/components/app/app-header/tests/app-header.test.js +++ b/ui/app/components/app/app-header/tests/app-header.test.js @@ -43,7 +43,7 @@ describe('App Header', function () { const appLogo = wrapper.find(MetaFoxLogo) appLogo.simulate('click') assert(props.history.push.calledOnce) - assert.equal(props.history.push.getCall(0).args[0], '/') + assert.strictEqual(props.history.push.getCall(0).args[0], '/') }) }) @@ -74,7 +74,7 @@ describe('App Header', function () { it('hides network indicator', function () { wrapper.setProps({ hideNetworkIndicator: true }) const network = wrapper.find({ network: 'test' }) - assert.equal(network.length, 0) + assert.strictEqual(network.length, 0) }) }) diff --git a/ui/app/components/app/confirm-page-container/confirm-detail-row/tests/confirm-detail-row.component.test.js b/ui/app/components/app/confirm-page-container/confirm-detail-row/tests/confirm-detail-row.component.test.js index add78407c..ed6ac21f8 100644 --- a/ui/app/components/app/confirm-page-container/confirm-detail-row/tests/confirm-detail-row.component.test.js +++ b/ui/app/components/app/confirm-page-container/confirm-detail-row/tests/confirm-detail-row.component.test.js @@ -29,11 +29,11 @@ describe('Confirm Detail Row Component', function () { }) it('should render a div with a confirm-detail-row class', function () { - assert.equal(wrapper.find('div.confirm-detail-row').length, 1) + assert.strictEqual(wrapper.find('div.confirm-detail-row').length, 1) }) it('should render the label as a child of the confirm-detail-row__label', function () { - assert.equal( + assert.strictEqual( wrapper .find('.confirm-detail-row > .confirm-detail-row__label') .childAt(0) @@ -43,7 +43,7 @@ describe('Confirm Detail Row Component', function () { }) it('should render the headerText as a child of the confirm-detail-row__header-text', function () { - assert.equal( + assert.strictEqual( wrapper .find( '.confirm-detail-row__details > .confirm-detail-row__header-text', @@ -55,7 +55,7 @@ describe('Confirm Detail Row Component', function () { }) it('should render the primaryText as a child of the confirm-detail-row__primary', function () { - assert.equal( + assert.strictEqual( wrapper .find('.confirm-detail-row__details > .confirm-detail-row__primary') .childAt(0) @@ -65,7 +65,7 @@ describe('Confirm Detail Row Component', function () { }) it('should render the ethText as a child of the confirm-detail-row__secondary', function () { - assert.equal( + assert.strictEqual( wrapper .find('.confirm-detail-row__details > .confirm-detail-row__secondary') .childAt(0) @@ -75,14 +75,14 @@ describe('Confirm Detail Row Component', function () { }) it('should set the fiatTextColor on confirm-detail-row__primary', function () { - assert.equal( + assert.strictEqual( wrapper.find('.confirm-detail-row__primary').props().style.color, 'mockColor', ) }) it('should assure the confirm-detail-row__header-text classname is correct', function () { - assert.equal( + assert.strictEqual( wrapper.find('.confirm-detail-row__header-text').props().className, 'confirm-detail-row__header-text mockHeaderClass', ) diff --git a/ui/app/components/app/dropdowns/tests/dropdown.test.js b/ui/app/components/app/dropdowns/tests/dropdown.test.js index e362104ba..7ceb8227c 100644 --- a/ui/app/components/app/dropdowns/tests/dropdown.test.js +++ b/ui/app/components/app/dropdowns/tests/dropdown.test.js @@ -20,16 +20,16 @@ describe('Dropdown', function () { }) it('renders li with dropdown-menu-item class', function () { - assert.equal(wrapper.find('li.dropdown-menu-item').length, 1) + assert.strictEqual(wrapper.find('li.dropdown-menu-item').length, 1) }) it('adds style based on props passed', function () { - assert.equal(wrapper.prop('style').test, 'style') + assert.strictEqual(wrapper.prop('style').test, 'style') }) it('simulates click event and calls onClick and closeMenu', function () { wrapper.prop('onClick')() - assert.equal(onClickSpy.callCount, 1) - assert.equal(closeMenuSpy.callCount, 1) + assert.strictEqual(onClickSpy.callCount, 1) + assert.strictEqual(closeMenuSpy.callCount, 1) }) }) diff --git a/ui/app/components/app/dropdowns/tests/network-dropdown-icon.test.js b/ui/app/components/app/dropdowns/tests/network-dropdown-icon.test.js index f0370b148..01210b49d 100644 --- a/ui/app/components/app/dropdowns/tests/network-dropdown-icon.test.js +++ b/ui/app/components/app/dropdowns/tests/network-dropdown-icon.test.js @@ -14,9 +14,9 @@ describe('Network Dropdown Icon', function () { />, ) const styleProp = wrapper.find('.menu-icon-circle').children().prop('style') - assert.equal(styleProp.background, 'red') - assert.equal(styleProp.border, 'none') - assert.equal(styleProp.height, '12px') - assert.equal(styleProp.width, '12px') + assert.strictEqual(styleProp.background, 'red') + assert.strictEqual(styleProp.border, 'none') + assert.strictEqual(styleProp.height, '12px') + assert.strictEqual(styleProp.width, '12px') }) }) diff --git a/ui/app/components/app/dropdowns/tests/network-dropdown.test.js b/ui/app/components/app/dropdowns/tests/network-dropdown.test.js index 09bec2615..2df87f956 100644 --- a/ui/app/components/app/dropdowns/tests/network-dropdown.test.js +++ b/ui/app/components/app/dropdowns/tests/network-dropdown.test.js @@ -31,11 +31,11 @@ describe('Network Dropdown', function () { }) it('checks for network droppo class', function () { - assert.equal(wrapper.find('.network-droppo').length, 1) + assert.strictEqual(wrapper.find('.network-droppo').length, 1) }) it('renders only one child when networkDropdown is false in state', function () { - assert.equal(wrapper.children().length, 1) + assert.strictEqual(wrapper.children().length, 1) }) }) @@ -62,53 +62,53 @@ describe('Network Dropdown', function () { }) it('renders 8 DropDownMenuItems ', function () { - assert.equal(wrapper.find(DropdownMenuItem).length, 8) + assert.strictEqual(wrapper.find(DropdownMenuItem).length, 8) }) it('checks background color for first NetworkDropdownIcon', function () { - assert.equal( + assert.strictEqual( wrapper.find(NetworkDropdownIcon).at(0).prop('backgroundColor'), '#29B6AF', ) // Ethereum Mainnet Teal }) it('checks background color for second NetworkDropdownIcon', function () { - assert.equal( + assert.strictEqual( wrapper.find(NetworkDropdownIcon).at(1).prop('backgroundColor'), '#ff4a8d', ) // Ropsten Red }) it('checks background color for third NetworkDropdownIcon', function () { - assert.equal( + assert.strictEqual( wrapper.find(NetworkDropdownIcon).at(2).prop('backgroundColor'), '#7057ff', ) // Kovan Purple }) it('checks background color for fourth NetworkDropdownIcon', function () { - assert.equal( + assert.strictEqual( wrapper.find(NetworkDropdownIcon).at(3).prop('backgroundColor'), '#f6c343', ) // Rinkeby Yellow }) it('checks background color for fifth NetworkDropdownIcon', function () { - assert.equal( + assert.strictEqual( wrapper.find(NetworkDropdownIcon).at(4).prop('backgroundColor'), '#3099f2', ) // Goerli Blue }) it('checks background color for sixth NetworkDropdownIcon', function () { - assert.equal( + assert.strictEqual( wrapper.find(NetworkDropdownIcon).at(5).prop('backgroundColor'), '#d6d9dc', ) // "Custom network grey" }) it('checks dropdown for frequestRPCList from state', function () { - assert.equal( + assert.strictEqual( wrapper.find(DropdownMenuItem).at(6).text(), '✓http://localhost:7545', ) diff --git a/ui/app/components/app/gas-customization/advanced-gas-inputs/tests/advanced-gas-input-component.test.js b/ui/app/components/app/gas-customization/advanced-gas-inputs/tests/advanced-gas-input-component.test.js index 161237c90..8c17f4d52 100644 --- a/ui/app/components/app/gas-customization/advanced-gas-inputs/tests/advanced-gas-input-component.test.js +++ b/ui/app/components/app/gas-customization/advanced-gas-inputs/tests/advanced-gas-input-component.test.js @@ -40,7 +40,7 @@ describe('Advanced Gas Inputs', function () { wrapper.find('input').at(0).simulate('change', event) clock.tick(499) - assert.equal(props.updateCustomGasPrice.callCount, 0) + assert.strictEqual(props.updateCustomGasPrice.callCount, 0) }) it('simulates onChange on gas price after debounce', function () { @@ -49,8 +49,8 @@ describe('Advanced Gas Inputs', function () { wrapper.find('input').at(0).simulate('change', event) clock.tick(500) - assert.equal(props.updateCustomGasPrice.calledOnce, true) - assert.equal(props.updateCustomGasPrice.calledWith(1), true) + assert.strictEqual(props.updateCustomGasPrice.calledOnce, true) + assert.strictEqual(props.updateCustomGasPrice.calledWith(1), true) }) it('wont update gasLimit in props before debounce', function () { @@ -59,7 +59,7 @@ describe('Advanced Gas Inputs', function () { wrapper.find('input').at(1).simulate('change', event) clock.tick(499) - assert.equal(props.updateCustomGasLimit.callCount, 0) + assert.strictEqual(props.updateCustomGasLimit.callCount, 0) }) it('simulates onChange on gas limit after debounce', function () { @@ -68,8 +68,8 @@ describe('Advanced Gas Inputs', function () { wrapper.find('input').at(1).simulate('change', event) clock.tick(500) - assert.equal(props.updateCustomGasLimit.calledOnce, true) - assert.equal(props.updateCustomGasLimit.calledWith(21000), true) + assert.strictEqual(props.updateCustomGasLimit.calledOnce, true) + assert.strictEqual(props.updateCustomGasLimit.calledWith(21000), true) }) it('errors when insufficientBalance under gas price and gas limit', function () { @@ -77,10 +77,10 @@ describe('Advanced Gas Inputs', function () { const renderError = wrapper.find( '.advanced-gas-inputs__gas-edit-row__error-text', ) - assert.equal(renderError.length, 2) + assert.strictEqual(renderError.length, 2) - assert.equal(renderError.at(0).text(), 'insufficientBalance') - assert.equal(renderError.at(1).text(), 'insufficientBalance') + assert.strictEqual(renderError.at(0).text(), 'insufficientBalance') + assert.strictEqual(renderError.at(1).text(), 'insufficientBalance') }) it('errors zero gas price / speed up', function () { @@ -89,10 +89,10 @@ describe('Advanced Gas Inputs', function () { const renderError = wrapper.find( '.advanced-gas-inputs__gas-edit-row__error-text', ) - assert.equal(renderError.length, 2) + assert.strictEqual(renderError.length, 2) - assert.equal(renderError.at(0).text(), 'zeroGasPriceOnSpeedUpError') - assert.equal(renderError.at(1).text(), 'gasLimitTooLowWithDynamicFee') + assert.strictEqual(renderError.at(0).text(), 'zeroGasPriceOnSpeedUpError') + assert.strictEqual(renderError.at(1).text(), 'gasLimitTooLowWithDynamicFee') }) it('warns when custom gas price is too low', function () { @@ -101,8 +101,8 @@ describe('Advanced Gas Inputs', function () { const renderWarning = wrapper.find( '.advanced-gas-inputs__gas-edit-row__warning-text', ) - assert.equal(renderWarning.length, 1) + assert.strictEqual(renderWarning.length, 1) - assert.equal(renderWarning.text(), 'gasPriceExtremelyLow') + assert.strictEqual(renderWarning.text(), 'gasPriceExtremelyLow') }) }) diff --git a/ui/app/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js b/ui/app/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js index 0e632a92a..b33dcadee 100644 --- a/ui/app/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js +++ b/ui/app/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js @@ -39,7 +39,7 @@ describe('AdvancedTabContent Component', function () { it('should render the expected child of the advanced-tab div', function () { const advancedTabChildren = wrapper.children() - assert.equal(advancedTabChildren.length, 2) + assert.strictEqual(advancedTabChildren.length, 2) assert( advancedTabChildren @@ -52,7 +52,7 @@ describe('AdvancedTabContent Component', function () { const renderDataSummaryArgs = AdvancedTabContent.prototype.renderDataSummary.getCall( 0, ).args - assert.deepEqual(renderDataSummaryArgs, ['$0.25']) + assert.deepStrictEqual(renderDataSummaryArgs, ['$0.25']) }) }) @@ -74,7 +74,10 @@ describe('AdvancedTabContent Component', function () { assert( titlesNode.hasClass('advanced-tab__transaction-data-summary__titles'), ) - assert.equal(titlesNode.children().at(0).text(), 'newTransactionFee') + assert.strictEqual( + titlesNode.children().at(0).text(), + 'newTransactionFee', + ) }) it('should render the data', function () { @@ -82,7 +85,7 @@ describe('AdvancedTabContent Component', function () { assert( dataNode.hasClass('advanced-tab__transaction-data-summary__container'), ) - assert.equal(dataNode.children().at(0).text(), 'mockTotalFee') + assert.strictEqual(dataNode.children().at(0).text(), 'mockTotalFee') }) }) }) diff --git a/ui/app/components/app/gas-customization/gas-modal-page-container/basic-tab-content/tests/basic-tab-content-component.test.js b/ui/app/components/app/gas-customization/gas-modal-page-container/basic-tab-content/tests/basic-tab-content-component.test.js index 2c28fc556..ae0829db0 100644 --- a/ui/app/components/app/gas-customization/gas-modal-page-container/basic-tab-content/tests/basic-tab-content-component.test.js +++ b/ui/app/components/app/gas-customization/gas-modal-page-container/basic-tab-content/tests/basic-tab-content-component.test.js @@ -60,7 +60,7 @@ describe('BasicTabContent Component', function () { }) it('should render a GasPriceButtonGroup compenent', function () { - assert.equal(wrapper.find(GasPriceButtonGroup).length, 1) + assert.strictEqual(wrapper.find(GasPriceButtonGroup).length, 1) }) it('should pass correct props to GasPriceButtonGroup', function () { @@ -72,22 +72,22 @@ describe('BasicTabContent Component', function () { noButtonActiveByDefault, showCheck, } = wrapper.find(GasPriceButtonGroup).props() - assert.equal(wrapper.find(GasPriceButtonGroup).length, 1) - assert.equal( + assert.strictEqual(wrapper.find(GasPriceButtonGroup).length, 1) + assert.strictEqual( buttonDataLoading, mockGasPriceButtonGroupProps.buttonDataLoading, ) - assert.equal(className, mockGasPriceButtonGroupProps.className) - assert.equal( + assert.strictEqual(className, mockGasPriceButtonGroupProps.className) + assert.strictEqual( noButtonActiveByDefault, mockGasPriceButtonGroupProps.noButtonActiveByDefault, ) - assert.equal(showCheck, mockGasPriceButtonGroupProps.showCheck) - assert.deepEqual( + assert.strictEqual(showCheck, mockGasPriceButtonGroupProps.showCheck) + assert.deepStrictEqual( gasButtonInfo, mockGasPriceButtonGroupProps.gasButtonInfo, ) - assert.equal( + assert.strictEqual( JSON.stringify(handleGasPriceSelection), JSON.stringify(mockGasPriceButtonGroupProps.handleGasPriceSelection), ) @@ -101,8 +101,8 @@ describe('BasicTabContent Component', function () { }, }) - assert.equal(wrapper.find(GasPriceButtonGroup).length, 0) - assert.equal(wrapper.find(Loading).length, 1) + assert.strictEqual(wrapper.find(GasPriceButtonGroup).length, 0) + assert.strictEqual(wrapper.find(Loading).length, 1) }) }) }) diff --git a/ui/app/components/app/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js b/ui/app/components/app/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js index 74bd8ee90..8ae08274c 100644 --- a/ui/app/components/app/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js +++ b/ui/app/components/app/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js @@ -88,31 +88,31 @@ describe('GasModalPageContainer Component', function () { describe('componentDidMount', function () { it('should call props.fetchBasicGasEstimates', function () { propsMethodSpies.fetchBasicGasEstimates.resetHistory() - assert.equal(propsMethodSpies.fetchBasicGasEstimates.callCount, 0) + assert.strictEqual(propsMethodSpies.fetchBasicGasEstimates.callCount, 0) wrapper.instance().componentDidMount() - assert.equal(propsMethodSpies.fetchBasicGasEstimates.callCount, 1) + assert.strictEqual(propsMethodSpies.fetchBasicGasEstimates.callCount, 1) }) }) describe('render', function () { it('should render a PageContainer compenent', function () { - assert.equal(wrapper.find(PageContainer).length, 1) + assert.strictEqual(wrapper.find(PageContainer).length, 1) }) it('should pass correct props to PageContainer', function () { const { title, subtitle, disabled } = wrapper.find(PageContainer).props() - assert.equal(title, 'customGas') - assert.equal(subtitle, 'customGasSubTitle') - assert.equal(disabled, false) + assert.strictEqual(title, 'customGas') + assert.strictEqual(subtitle, 'customGasSubTitle') + assert.strictEqual(disabled, false) }) it('should pass the correct onCancel and onClose methods to PageContainer', function () { const { onCancel, onClose } = wrapper.find(PageContainer).props() - assert.equal(propsMethodSpies.cancelAndClose.callCount, 0) + assert.strictEqual(propsMethodSpies.cancelAndClose.callCount, 0) onCancel() - assert.equal(propsMethodSpies.cancelAndClose.callCount, 1) + assert.strictEqual(propsMethodSpies.cancelAndClose.callCount, 1) onClose() - assert.equal(propsMethodSpies.cancelAndClose.callCount, 2) + assert.strictEqual(propsMethodSpies.cancelAndClose.callCount, 2) }) it('should pass the correct renderTabs property to PageContainer', function () { @@ -127,7 +127,7 @@ describe('GasModalPageContainer Component', function () { const { tabsComponent } = renderTabsWrapperTester .find(PageContainer) .props() - assert.equal(tabsComponent, 'mockTabs') + assert.strictEqual(tabsComponent, 'mockTabs') GasModalPageContainer.prototype.renderTabs.restore() }) }) @@ -148,32 +148,38 @@ describe('GasModalPageContainer Component', function () { it('should render a Tabs component with "Basic" and "Advanced" tabs', function () { const renderTabsResult = wrapper.instance().renderTabs() const renderedTabs = shallow(renderTabsResult) - assert.equal(renderedTabs.props().className, 'tabs') + assert.strictEqual(renderedTabs.props().className, 'tabs') const tabs = renderedTabs.find(Tab) - assert.equal(tabs.length, 2) + assert.strictEqual(tabs.length, 2) - assert.equal(tabs.at(0).props().name, 'basic') - assert.equal(tabs.at(1).props().name, 'advanced') + assert.strictEqual(tabs.at(0).props().name, 'basic') + assert.strictEqual(tabs.at(1).props().name, 'advanced') - assert.equal(tabs.at(0).childAt(0).props().className, 'gas-modal-content') - assert.equal(tabs.at(1).childAt(0).props().className, 'gas-modal-content') + assert.strictEqual( + tabs.at(0).childAt(0).props().className, + 'gas-modal-content', + ) + assert.strictEqual( + tabs.at(1).childAt(0).props().className, + 'gas-modal-content', + ) }) it('should call renderInfoRows with the expected props', function () { - assert.equal(GP.renderInfoRows.callCount, 0) + assert.strictEqual(GP.renderInfoRows.callCount, 0) wrapper.instance().renderTabs() - assert.equal(GP.renderInfoRows.callCount, 2) + assert.strictEqual(GP.renderInfoRows.callCount, 2) - assert.deepEqual(GP.renderInfoRows.getCall(0).args, [ + assert.deepStrictEqual(GP.renderInfoRows.getCall(0).args, [ 'mockNewTotalFiat', 'mockNewTotalEth', 'mockSendAmount', 'mockTransactionFee', ]) - assert.deepEqual(GP.renderInfoRows.getCall(1).args, [ + assert.deepStrictEqual(GP.renderInfoRows.getCall(1).args, [ 'mockNewTotalFiat', 'mockNewTotalEth', 'mockSendAmount', @@ -202,8 +208,8 @@ describe('GasModalPageContainer Component', function () { const renderedTabs = shallow(renderTabsResult) const tabs = renderedTabs.find(Tab) - assert.equal(tabs.length, 1) - assert.equal(tabs.at(0).props().name, 'advanced') + assert.strictEqual(tabs.length, 1) + assert.strictEqual(tabs.at(0).props().name, 'advanced') }) }) @@ -213,7 +219,7 @@ describe('GasModalPageContainer Component', function () { .instance() .renderBasicTabContent(mockGasPriceButtonGroupProps) - assert.deepEqual( + assert.deepStrictEqual( renderBasicTabContentResult.props.gasPriceButtonGroupProps, mockGasPriceButtonGroupProps, ) @@ -237,7 +243,7 @@ describe('GasModalPageContainer Component', function () { assert(renderedInfoRowsContainer.childAt(0).hasClass(baseClassName)) const renderedInfoRows = renderedInfoRowsContainer.childAt(0).children() - assert.equal(renderedInfoRows.length, 4) + assert.strictEqual(renderedInfoRows.length, 4) assert(renderedInfoRows.at(0).hasClass(`${baseClassName}__send-info`)) assert( renderedInfoRows.at(1).hasClass(`${baseClassName}__transaction-info`), @@ -247,13 +253,19 @@ describe('GasModalPageContainer Component', function () { renderedInfoRows.at(3).hasClass(`${baseClassName}__fiat-total-info`), ) - assert.equal(renderedInfoRows.at(0).text(), 'sendAmount mockSendAmount') - assert.equal( + assert.strictEqual( + renderedInfoRows.at(0).text(), + 'sendAmount mockSendAmount', + ) + assert.strictEqual( renderedInfoRows.at(1).text(), 'transactionFee mockTransactionFee', ) - assert.equal(renderedInfoRows.at(2).text(), 'newTotal mockNewTotalEth') - assert.equal(renderedInfoRows.at(3).text(), 'mockNewTotalFiat') + assert.strictEqual( + renderedInfoRows.at(2).text(), + 'newTotal mockNewTotalEth', + ) + assert.strictEqual(renderedInfoRows.at(3).text(), 'mockNewTotalFiat') }) }) }) diff --git a/ui/app/components/app/info-box/tests/info-box.test.js b/ui/app/components/app/info-box/tests/info-box.test.js index 031ac62f4..82f019e01 100644 --- a/ui/app/components/app/info-box/tests/info-box.test.js +++ b/ui/app/components/app/info-box/tests/info-box.test.js @@ -20,12 +20,12 @@ describe('InfoBox', function () { it('renders title from props', function () { const title = wrapper.find('.info-box__title') - assert.equal(title.text(), props.title) + assert.strictEqual(title.text(), props.title) }) it('renders description from props', function () { const description = wrapper.find('.info-box__description') - assert.equal(description.text(), props.description) + assert.strictEqual(description.text(), props.description) }) it('closes info box', function () { diff --git a/ui/app/components/app/modal/modal-content/tests/modal-content.component.test.js b/ui/app/components/app/modal/modal-content/tests/modal-content.component.test.js index de40a39bd..8056563f6 100644 --- a/ui/app/components/app/modal/modal-content/tests/modal-content.component.test.js +++ b/ui/app/components/app/modal/modal-content/tests/modal-content.component.test.js @@ -7,17 +7,20 @@ describe('ModalContent Component', function () { it('should render a title', function () { const wrapper = shallow() - assert.equal(wrapper.find('.modal-content__title').length, 1) - assert.equal(wrapper.find('.modal-content__title').text(), 'Modal Title') - assert.equal(wrapper.find('.modal-content__description').length, 0) + assert.strictEqual(wrapper.find('.modal-content__title').length, 1) + assert.strictEqual( + wrapper.find('.modal-content__title').text(), + 'Modal Title', + ) + assert.strictEqual(wrapper.find('.modal-content__description').length, 0) }) it('should render a description', function () { const wrapper = shallow() - assert.equal(wrapper.find('.modal-content__title').length, 0) - assert.equal(wrapper.find('.modal-content__description').length, 1) - assert.equal( + assert.strictEqual(wrapper.find('.modal-content__title').length, 0) + assert.strictEqual(wrapper.find('.modal-content__description').length, 1) + assert.strictEqual( wrapper.find('.modal-content__description').text(), 'Modal Description', ) @@ -28,10 +31,13 @@ describe('ModalContent Component', function () { , ) - assert.equal(wrapper.find('.modal-content__title').length, 1) - assert.equal(wrapper.find('.modal-content__title').text(), 'Modal Title') - assert.equal(wrapper.find('.modal-content__description').length, 1) - assert.equal( + assert.strictEqual(wrapper.find('.modal-content__title').length, 1) + assert.strictEqual( + wrapper.find('.modal-content__title').text(), + 'Modal Title', + ) + assert.strictEqual(wrapper.find('.modal-content__description').length, 1) + assert.strictEqual( wrapper.find('.modal-content__description').text(), 'Modal Description', ) diff --git a/ui/app/components/app/modal/tests/modal.component.test.js b/ui/app/components/app/modal/tests/modal.component.test.js index fe55b61bd..a0ad195ae 100644 --- a/ui/app/components/app/modal/tests/modal.component.test.js +++ b/ui/app/components/app/modal/tests/modal.component.test.js @@ -9,10 +9,10 @@ describe('Modal Component', function () { it('should render a modal with a submit button', function () { const wrapper = shallow() - assert.equal(wrapper.find('.modal-container').length, 1) + assert.strictEqual(wrapper.find('.modal-container').length, 1) const buttons = wrapper.find(Button) - assert.equal(buttons.length, 1) - assert.equal(buttons.at(0).props().type, 'secondary') + assert.strictEqual(buttons.length, 1) + assert.strictEqual(buttons.at(0).props().type, 'secondary') }) it('should render a modal with a cancel and a submit button', function () { @@ -28,21 +28,21 @@ describe('Modal Component', function () { ) const buttons = wrapper.find(Button) - assert.equal(buttons.length, 2) + assert.strictEqual(buttons.length, 2) const cancelButton = buttons.at(0) const submitButton = buttons.at(1) - assert.equal(cancelButton.props().type, 'default') - assert.equal(cancelButton.props().children, 'Cancel') - assert.equal(handleCancel.callCount, 0) + assert.strictEqual(cancelButton.props().type, 'default') + assert.strictEqual(cancelButton.props().children, 'Cancel') + assert.strictEqual(handleCancel.callCount, 0) cancelButton.simulate('click') - assert.equal(handleCancel.callCount, 1) + assert.strictEqual(handleCancel.callCount, 1) - assert.equal(submitButton.props().type, 'secondary') - assert.equal(submitButton.props().children, 'Submit') - assert.equal(handleSubmit.callCount, 0) + assert.strictEqual(submitButton.props().type, 'secondary') + assert.strictEqual(submitButton.props().children, 'Submit') + assert.strictEqual(handleSubmit.callCount, 0) submitButton.simulate('click') - assert.equal(handleSubmit.callCount, 1) + assert.strictEqual(handleSubmit.callCount, 1) }) it('should render a modal with different button types', function () { @@ -58,9 +58,9 @@ describe('Modal Component', function () { ) const buttons = wrapper.find(Button) - assert.equal(buttons.length, 2) - assert.equal(buttons.at(0).props().type, 'secondary') - assert.equal(buttons.at(1).props().type, 'confirm') + assert.strictEqual(buttons.length, 2) + assert.strictEqual(buttons.at(0).props().type, 'secondary') + assert.strictEqual(buttons.at(1).props().type, 'confirm') }) it('should render a modal with children', function () { @@ -93,15 +93,15 @@ describe('Modal Component', function () { ) assert.ok(wrapper.find('.modal-container__header')) - assert.equal( + assert.strictEqual( wrapper.find('.modal-container__header-text').text(), 'My Header', ) - assert.equal(handleCancel.callCount, 0) - assert.equal(handleSubmit.callCount, 0) + assert.strictEqual(handleCancel.callCount, 0) + assert.strictEqual(handleSubmit.callCount, 0) wrapper.find('.modal-container__header-close').simulate('click') - assert.equal(handleCancel.callCount, 1) - assert.equal(handleSubmit.callCount, 0) + assert.strictEqual(handleCancel.callCount, 1) + assert.strictEqual(handleSubmit.callCount, 0) }) it('should disable the submit button if submitDisabled is true', function () { @@ -120,17 +120,17 @@ describe('Modal Component', function () { ) const buttons = wrapper.find(Button) - assert.equal(buttons.length, 2) + assert.strictEqual(buttons.length, 2) const cancelButton = buttons.at(0) const submitButton = buttons.at(1) - assert.equal(handleCancel.callCount, 0) + assert.strictEqual(handleCancel.callCount, 0) cancelButton.simulate('click') - assert.equal(handleCancel.callCount, 1) + assert.strictEqual(handleCancel.callCount, 1) - assert.equal(submitButton.props().disabled, true) - assert.equal(handleSubmit.callCount, 0) + assert.strictEqual(submitButton.props().disabled, true) + assert.strictEqual(handleSubmit.callCount, 0) submitButton.simulate('click') - assert.equal(handleSubmit.callCount, 0) + assert.strictEqual(handleSubmit.callCount, 0) }) }) diff --git a/ui/app/components/app/modals/cancel-transaction/cancel-transaction-gas-fee/tests/cancel-transaction-gas-fee.component.test.js b/ui/app/components/app/modals/cancel-transaction/cancel-transaction-gas-fee/tests/cancel-transaction-gas-fee.component.test.js index 12b1bae06..c10971110 100644 --- a/ui/app/components/app/modals/cancel-transaction/cancel-transaction-gas-fee/tests/cancel-transaction-gas-fee.component.test.js +++ b/ui/app/components/app/modals/cancel-transaction/cancel-transaction-gas-fee/tests/cancel-transaction-gas-fee.component.test.js @@ -9,18 +9,18 @@ describe('CancelTransactionGasFee Component', function () { const wrapper = shallow() assert.ok(wrapper) - assert.equal(wrapper.find(UserPreferencedCurrencyDisplay).length, 2) + assert.strictEqual(wrapper.find(UserPreferencedCurrencyDisplay).length, 2) const ethDisplay = wrapper.find(UserPreferencedCurrencyDisplay).at(0) const fiatDisplay = wrapper.find(UserPreferencedCurrencyDisplay).at(1) - assert.equal(ethDisplay.props().value, '0x3b9aca00') - assert.equal( + assert.strictEqual(ethDisplay.props().value, '0x3b9aca00') + assert.strictEqual( ethDisplay.props().className, 'cancel-transaction-gas-fee__eth', ) - assert.equal(fiatDisplay.props().value, '0x3b9aca00') - assert.equal( + assert.strictEqual(fiatDisplay.props().value, '0x3b9aca00') + assert.strictEqual( fiatDisplay.props().className, 'cancel-transaction-gas-fee__fiat', ) diff --git a/ui/app/components/app/modals/cancel-transaction/tests/cancel-transaction.component.test.js b/ui/app/components/app/modals/cancel-transaction/tests/cancel-transaction.component.test.js index 411cc8b27..64e08944a 100644 --- a/ui/app/components/app/modals/cancel-transaction/tests/cancel-transaction.component.test.js +++ b/ui/app/components/app/modals/cancel-transaction/tests/cancel-transaction.component.test.js @@ -15,17 +15,17 @@ describe('CancelTransaction Component', function () { }) assert.ok(wrapper) - assert.equal(wrapper.find(Modal).length, 1) - assert.equal(wrapper.find(CancelTransactionGasFee).length, 1) - assert.equal( + assert.strictEqual(wrapper.find(Modal).length, 1) + assert.strictEqual(wrapper.find(CancelTransactionGasFee).length, 1) + assert.strictEqual( wrapper.find(CancelTransactionGasFee).props().value, '0x1319718a5000', ) - assert.equal( + assert.strictEqual( wrapper.find('.cancel-transaction__title').text(), 'cancellationGasFee', ) - assert.equal( + assert.strictEqual( wrapper.find('.cancel-transaction__description').text(), 'attemptToCancelDescription', ) @@ -47,19 +47,19 @@ describe('CancelTransaction Component', function () { { context: { t } }, ) - assert.equal(wrapper.find(Modal).length, 1) + assert.strictEqual(wrapper.find(Modal).length, 1) const modalProps = wrapper.find(Modal).props() - assert.equal(modalProps.headerText, 'attemptToCancel') - assert.equal(modalProps.submitText, 'yesLetsTry') - assert.equal(modalProps.cancelText, 'nevermind') + assert.strictEqual(modalProps.headerText, 'attemptToCancel') + assert.strictEqual(modalProps.submitText, 'yesLetsTry') + assert.strictEqual(modalProps.cancelText, 'nevermind') - assert.equal(createCancelTransactionSpy.callCount, 0) - assert.equal(hideModalSpy.callCount, 0) + assert.strictEqual(createCancelTransactionSpy.callCount, 0) + assert.strictEqual(hideModalSpy.callCount, 0) await modalProps.onSubmit() - assert.equal(createCancelTransactionSpy.callCount, 1) - assert.equal(hideModalSpy.callCount, 1) + assert.strictEqual(createCancelTransactionSpy.callCount, 1) + assert.strictEqual(hideModalSpy.callCount, 1) modalProps.onCancel() - assert.equal(hideModalSpy.callCount, 2) + assert.strictEqual(hideModalSpy.callCount, 2) }) }) diff --git a/ui/app/components/app/modals/confirm-delete-network/tests/confirm-delete-network.test.js b/ui/app/components/app/modals/confirm-delete-network/tests/confirm-delete-network.test.js index 86329ec88..7d06ef459 100644 --- a/ui/app/components/app/modals/confirm-delete-network/tests/confirm-delete-network.test.js +++ b/ui/app/components/app/modals/confirm-delete-network/tests/confirm-delete-network.test.js @@ -30,7 +30,7 @@ describe('Confirm Delete Network', function () { it('renders delete network modal title', function () { const modalTitle = wrapper.find('.modal-content__title') - assert.equal(modalTitle.text(), 'deleteNetwork') + assert.strictEqual(modalTitle.text(), 'deleteNetwork') }) it('clicks cancel to hide modal', function () { diff --git a/ui/app/components/app/modals/confirm-remove-account/tests/confirm-remove-account.test.js b/ui/app/components/app/modals/confirm-remove-account/tests/confirm-remove-account.test.js index 5f239e665..e50b87308 100644 --- a/ui/app/components/app/modals/confirm-remove-account/tests/confirm-remove-account.test.js +++ b/ui/app/components/app/modals/confirm-remove-account/tests/confirm-remove-account.test.js @@ -61,7 +61,10 @@ describe('Confirm Remove Account', function () { remove.simulate('click') assert(props.removeAccount.calledOnce) - assert.equal(props.removeAccount.getCall(0).args[0], props.identity.address) + assert.strictEqual( + props.removeAccount.getCall(0).args[0], + props.identity.address, + ) setImmediate(() => { assert(props.hideModal.calledOnce) diff --git a/ui/app/components/app/modals/metametrics-opt-in-modal/tests/metametrics-opt-in-modal.test.js b/ui/app/components/app/modals/metametrics-opt-in-modal/tests/metametrics-opt-in-modal.test.js index ec113f108..5b9f4798d 100644 --- a/ui/app/components/app/modals/metametrics-opt-in-modal/tests/metametrics-opt-in-modal.test.js +++ b/ui/app/components/app/modals/metametrics-opt-in-modal/tests/metametrics-opt-in-modal.test.js @@ -34,7 +34,10 @@ describe('MetaMetrics Opt In', function () { setImmediate(() => { assert(props.setParticipateInMetaMetrics.calledOnce) - assert.equal(props.setParticipateInMetaMetrics.getCall(0).args[0], false) + assert.strictEqual( + props.setParticipateInMetaMetrics.getCall(0).args[0], + false, + ) assert(props.hideModal.calledOnce) done() }) @@ -48,7 +51,10 @@ describe('MetaMetrics Opt In', function () { setImmediate(() => { assert(props.setParticipateInMetaMetrics.calledOnce) - assert.equal(props.setParticipateInMetaMetrics.getCall(0).args[0], true) + assert.strictEqual( + props.setParticipateInMetaMetrics.getCall(0).args[0], + true, + ) assert(props.hideModal.calledOnce) done() }) diff --git a/ui/app/components/app/modals/tests/account-details-modal.test.js b/ui/app/components/app/modals/tests/account-details-modal.test.js index 55b8b1b0a..62da1c56e 100644 --- a/ui/app/components/app/modals/tests/account-details-modal.test.js +++ b/ui/app/components/app/modals/tests/account-details-modal.test.js @@ -46,7 +46,7 @@ describe('Account Details Modal', function () { accountLabel.simulate('submit', 'New Label') assert(props.setAccountLabel.calledOnce) - assert.equal(props.setAccountLabel.getCall(0).args[1], 'New Label') + assert.strictEqual(props.setAccountLabel.getCall(0).args[1], 'New Label') }) it('opens new tab when view block explorer is clicked', function () { @@ -72,7 +72,7 @@ describe('Account Details Modal', function () { const modalButton = wrapper.find('.account-details-modal__button') const blockExplorerLink = modalButton.first() - assert.equal( + assert.strictEqual( blockExplorerLink.html(), '', ) diff --git a/ui/app/components/app/selected-account/tests/selected-account-component.test.js b/ui/app/components/app/selected-account/tests/selected-account-component.test.js index d0a608f3e..fcb924c25 100644 --- a/ui/app/components/app/selected-account/tests/selected-account-component.test.js +++ b/ui/app/components/app/selected-account/tests/selected-account-component.test.js @@ -15,10 +15,13 @@ describe('SelectedAccount Component', function () { { context: { t: () => undefined } }, ) // Checksummed version of address is displayed - assert.equal( + assert.strictEqual( wrapper.find('.selected-account__address').text(), '0x1B82...5C9D', ) - assert.equal(wrapper.find('.selected-account__name').text(), 'testName') + assert.strictEqual( + wrapper.find('.selected-account__name').text(), + 'testName', + ) }) }) diff --git a/ui/app/components/app/sidebars/tests/sidebars-component.test.js b/ui/app/components/app/sidebars/tests/sidebars-component.test.js index 22a7cbc2c..87d9377c0 100644 --- a/ui/app/components/app/sidebars/tests/sidebars-component.test.js +++ b/ui/app/components/app/sidebars/tests/sidebars-component.test.js @@ -41,9 +41,9 @@ describe('Sidebar Component', function () { }) it('should pass the correct onClick function to the element', function () { - assert.equal(propsMethodSpies.hideSidebar.callCount, 0) + assert.strictEqual(propsMethodSpies.hideSidebar.callCount, 0) renderOverlay.props().onClick() - assert.equal(propsMethodSpies.hideSidebar.callCount, 1) + assert.strictEqual(propsMethodSpies.hideSidebar.callCount, 1) }) }) @@ -64,26 +64,26 @@ describe('Sidebar Component', function () { it('should not render with an unrecognized type', function () { wrapper.setProps({ type: 'foobar' }) renderSidebarContent = wrapper.instance().renderSidebarContent() - assert.equal(renderSidebarContent, undefined) + assert.strictEqual(renderSidebarContent, null) }) }) describe('render', function () { it('should render a div with one child', function () { assert(wrapper.is('div')) - assert.equal(wrapper.children().length, 1) + assert.strictEqual(wrapper.children().length, 1) }) it('should render the ReactCSSTransitionGroup without any children', function () { assert(wrapper.children().at(0).is(ReactCSSTransitionGroup)) - assert.equal(wrapper.children().at(0).children().length, 0) + assert.strictEqual(wrapper.children().at(0).children().length, 0) }) it('should render sidebar content and the overlay if sidebarOpen is true', function () { wrapper.setProps({ sidebarOpen: true }) - assert.equal(wrapper.children().length, 2) + assert.strictEqual(wrapper.children().length, 2) assert(wrapper.children().at(1).hasClass('sidebar-overlay')) - assert.equal(wrapper.children().at(0).children().length, 1) + assert.strictEqual(wrapper.children().at(0).children().length, 1) assert(wrapper.children().at(0).children().at(0).hasClass('sidebar-left')) assert( wrapper diff --git a/ui/app/components/app/signature-request/tests/signature-request.test.js b/ui/app/components/app/signature-request/tests/signature-request.test.js index 331abac04..8966c014e 100644 --- a/ui/app/components/app/signature-request/tests/signature-request.test.js +++ b/ui/app/components/app/signature-request/tests/signature-request.test.js @@ -23,7 +23,7 @@ describe('Signature Request Component', function () { ) assert(wrapper.is('div')) - assert.equal(wrapper.length, 1) + assert.strictEqual(wrapper.length, 1) assert(wrapper.hasClass('signature-request')) }) }) diff --git a/ui/app/components/app/token-cell/token-cell.test.js b/ui/app/components/app/token-cell/token-cell.test.js index 1e876cfb3..08b4e545d 100644 --- a/ui/app/components/app/token-cell/token-cell.test.js +++ b/ui/app/components/app/token-cell/token-cell.test.js @@ -64,20 +64,32 @@ describe('Token Cell', function () { }) it('renders Identicon with props from token cell', function () { - assert.equal(wrapper.find(Identicon).prop('address'), '0xAnotherToken') - assert.equal(wrapper.find(Identicon).prop('image'), './test-image') + assert.strictEqual( + wrapper.find(Identicon).prop('address'), + '0xAnotherToken', + ) + assert.strictEqual(wrapper.find(Identicon).prop('image'), './test-image') }) it('renders token balance', function () { - assert.equal(wrapper.find('.asset-list-item__token-value').text(), '5.000') + assert.strictEqual( + wrapper.find('.asset-list-item__token-value').text(), + '5.000', + ) }) it('renders token symbol', function () { - assert.equal(wrapper.find('.asset-list-item__token-symbol').text(), 'TEST') + assert.strictEqual( + wrapper.find('.asset-list-item__token-symbol').text(), + 'TEST', + ) }) it('renders converted fiat amount', function () { - assert.equal(wrapper.find('.list-item__subheading').text(), '$0.52 USD') + assert.strictEqual( + wrapper.find('.list-item__subheading').text(), + '$0.52 USD', + ) }) it('calls onClick when clicked', function () { diff --git a/ui/app/components/app/transaction-activity-log/tests/transaction-activity-log.component.test.js b/ui/app/components/app/transaction-activity-log/tests/transaction-activity-log.component.test.js index ec5cbb3df..d07f98764 100644 --- a/ui/app/components/app/transaction-activity-log/tests/transaction-activity-log.component.test.js +++ b/ui/app/components/app/transaction-activity-log/tests/transaction-activity-log.component.test.js @@ -109,7 +109,7 @@ describe('TransactionActivityLog Component', function () { assert.ok(wrapper.hasClass('transaction-activity-log')) assert.ok(wrapper.hasClass('test-class')) - assert.equal( + assert.strictEqual( wrapper.find('.transaction-activity-log__action-link').length, 2, ) @@ -166,7 +166,7 @@ describe('TransactionActivityLog Component', function () { assert.ok(wrapper.hasClass('transaction-activity-log')) assert.ok(wrapper.hasClass('test-class')) - assert.equal( + assert.strictEqual( wrapper.find('.transaction-activity-log__action-link').length, 0, ) diff --git a/ui/app/components/app/transaction-activity-log/tests/transaction-activity-log.container.test.js b/ui/app/components/app/transaction-activity-log/tests/transaction-activity-log.container.test.js index b756a5962..f54f2ce94 100644 --- a/ui/app/components/app/transaction-activity-log/tests/transaction-activity-log.container.test.js +++ b/ui/app/components/app/transaction-activity-log/tests/transaction-activity-log.container.test.js @@ -22,7 +22,7 @@ describe('TransactionActivityLog container', function () { }, } - assert.deepEqual(mapStateToProps(mockState), { + assert.deepStrictEqual(mapStateToProps(mockState), { conversionRate: 280.45, nativeCurrency: 'ETH', }) diff --git a/ui/app/components/app/transaction-activity-log/tests/transaction-activity-log.util.test.js b/ui/app/components/app/transaction-activity-log/tests/transaction-activity-log.util.test.js index 5b9ab0662..8b03326db 100644 --- a/ui/app/components/app/transaction-activity-log/tests/transaction-activity-log.util.test.js +++ b/ui/app/components/app/transaction-activity-log/tests/transaction-activity-log.util.test.js @@ -11,7 +11,7 @@ import { describe('TransactionActivityLog utils', function () { describe('combineTransactionHistories', function () { it('should return no activities for an empty list of transactions', function () { - assert.deepEqual(combineTransactionHistories([]), []) + assert.deepStrictEqual(combineTransactionHistories([]), []) }) it('should return activities for an array of transactions', function () { @@ -217,7 +217,10 @@ describe('TransactionActivityLog utils', function () { }, ] - assert.deepEqual(combineTransactionHistories(transactions), expected) + assert.deepStrictEqual( + combineTransactionHistories(transactions), + expected, + ) }) }) @@ -237,7 +240,7 @@ describe('TransactionActivityLog utils', function () { }, } - assert.deepEqual(getActivities(transaction), []) + assert.deepStrictEqual(getActivities(transaction), []) }) it("should return activities for a transaction's history", function () { @@ -412,7 +415,7 @@ describe('TransactionActivityLog utils', function () { }, ] - assert.deepEqual(getActivities(transaction, true), expectedResult) + assert.deepStrictEqual(getActivities(transaction, true), expectedResult) }) }) }) diff --git a/ui/app/components/app/transaction-breakdown/transaction-breakdown-row/tests/transaction-breakdown-row.component.test.js b/ui/app/components/app/transaction-breakdown/transaction-breakdown-row/tests/transaction-breakdown-row.component.test.js index e3083e504..db5ebef70 100644 --- a/ui/app/components/app/transaction-breakdown/transaction-breakdown-row/tests/transaction-breakdown-row.component.test.js +++ b/ui/app/components/app/transaction-breakdown/transaction-breakdown-row/tests/transaction-breakdown-row.component.test.js @@ -14,11 +14,11 @@ describe('TransactionBreakdownRow Component', function () { ) assert.ok(wrapper.hasClass('transaction-breakdown-row')) - assert.equal( + assert.strictEqual( wrapper.find('.transaction-breakdown-row__title').text(), 'test', ) - assert.equal( + assert.strictEqual( wrapper.find('.transaction-breakdown-row__value').text(), 'Test', ) @@ -33,7 +33,7 @@ describe('TransactionBreakdownRow Component', function () { ) assert.ok(wrapper.hasClass('transaction-breakdown-row')) - assert.equal( + assert.strictEqual( wrapper.find('.transaction-breakdown-row__title').text(), 'test', ) diff --git a/ui/app/components/app/transaction-list-item-details/tests/transaction-list-item-details.component.test.js b/ui/app/components/app/transaction-list-item-details/tests/transaction-list-item-details.component.test.js index 9d1e8c18b..5027cc05b 100644 --- a/ui/app/components/app/transaction-list-item-details/tests/transaction-list-item-details.component.test.js +++ b/ui/app/components/app/transaction-list-item-details/tests/transaction-list-item-details.component.test.js @@ -44,10 +44,10 @@ describe('TransactionListItemDetails Component', function () { ) const child = wrapper.childAt(0) assert.ok(child.hasClass('transaction-list-item-details')) - assert.equal(child.find(Button).length, 2) - assert.equal(child.find(SenderToRecipient).length, 1) - assert.equal(child.find(TransactionBreakdown).length, 1) - assert.equal(child.find(TransactionActivityLog).length, 1) + assert.strictEqual(child.find(Button).length, 2) + assert.strictEqual(child.find(SenderToRecipient).length, 1) + assert.strictEqual(child.find(TransactionBreakdown).length, 1) + assert.strictEqual(child.find(TransactionActivityLog).length, 1) }) it('should render a retry button', function () { @@ -90,7 +90,7 @@ describe('TransactionListItemDetails Component', function () { const child = wrapper.childAt(0) assert.ok(child.hasClass('transaction-list-item-details')) - assert.equal(child.find(Button).length, 3) + assert.strictEqual(child.find(Button).length, 3) }) it('should disable the Copy Tx ID and View In Etherscan buttons when tx hash is missing', function () { diff --git a/ui/app/components/app/transaction-status/tests/transaction-status.component.test.js b/ui/app/components/app/transaction-status/tests/transaction-status.component.test.js index d468d8d5f..016d4d5a9 100644 --- a/ui/app/components/app/transaction-status/tests/transaction-status.component.test.js +++ b/ui/app/components/app/transaction-status/tests/transaction-status.component.test.js @@ -17,7 +17,7 @@ describe('TransactionStatus Component', function () { ) assert.ok(wrapper) - assert.equal(wrapper.text(), 'June 1') + assert.strictEqual(wrapper.text(), 'June 1') }) it('should render PENDING properly when status is APPROVED', function () { @@ -30,8 +30,8 @@ describe('TransactionStatus Component', function () { ) assert.ok(wrapper) - assert.equal(wrapper.text(), 'PENDING') - assert.equal(wrapper.find(Tooltip).props().title, 'test-title') + assert.strictEqual(wrapper.text(), 'PENDING') + assert.strictEqual(wrapper.find(Tooltip).props().title, 'test-title') }) it('should render PENDING properly', function () { @@ -40,7 +40,7 @@ describe('TransactionStatus Component', function () { ) assert.ok(wrapper) - assert.equal(wrapper.text(), 'PENDING') + assert.strictEqual(wrapper.text(), 'PENDING') }) it('should render QUEUED properly', function () { @@ -51,7 +51,7 @@ describe('TransactionStatus Component', function () { wrapper.find('.transaction-status--queued').length, 'queued className not found', ) - assert.equal(wrapper.text(), 'QUEUED') + assert.strictEqual(wrapper.text(), 'QUEUED') }) it('should render UNAPPROVED properly', function () { @@ -62,7 +62,7 @@ describe('TransactionStatus Component', function () { wrapper.find('.transaction-status--unapproved').length, 'unapproved className not found', ) - assert.equal(wrapper.text(), 'UNAPPROVED') + assert.strictEqual(wrapper.text(), 'UNAPPROVED') }) after(function () { diff --git a/ui/app/components/app/user-preferenced-currency-display/tests/user-preferenced-currency-display.component.test.js b/ui/app/components/app/user-preferenced-currency-display/tests/user-preferenced-currency-display.component.test.js index 41b8ac862..4c2533de5 100644 --- a/ui/app/components/app/user-preferenced-currency-display/tests/user-preferenced-currency-display.component.test.js +++ b/ui/app/components/app/user-preferenced-currency-display/tests/user-preferenced-currency-display.component.test.js @@ -19,7 +19,7 @@ describe('UserPreferencedCurrencyDisplay Component', function () { const wrapper = shallow() assert.ok(wrapper) - assert.equal(wrapper.find(CurrencyDisplay).length, 1) + assert.strictEqual(wrapper.find(CurrencyDisplay).length, 1) }) it('should pass all props to the CurrencyDisplay child component', function () { @@ -28,10 +28,10 @@ describe('UserPreferencedCurrencyDisplay Component', function () { ) assert.ok(wrapper) - assert.equal(wrapper.find(CurrencyDisplay).length, 1) - assert.equal(wrapper.find(CurrencyDisplay).props().prop1, true) - assert.equal(wrapper.find(CurrencyDisplay).props().prop2, 'test') - assert.equal(wrapper.find(CurrencyDisplay).props().prop3, 1) + assert.strictEqual(wrapper.find(CurrencyDisplay).length, 1) + assert.strictEqual(wrapper.find(CurrencyDisplay).props().prop1, true) + assert.strictEqual(wrapper.find(CurrencyDisplay).props().prop2, 'test') + assert.strictEqual(wrapper.find(CurrencyDisplay).props().prop3, 1) }) afterEach(function () { sinon.restore() diff --git a/ui/app/components/app/user-preferenced-currency-input/tests/user-preferenced-currency-input.component.test.js b/ui/app/components/app/user-preferenced-currency-input/tests/user-preferenced-currency-input.component.test.js index 63b9d42a5..30052e039 100644 --- a/ui/app/components/app/user-preferenced-currency-input/tests/user-preferenced-currency-input.component.test.js +++ b/ui/app/components/app/user-preferenced-currency-input/tests/user-preferenced-currency-input.component.test.js @@ -10,7 +10,7 @@ describe('UserPreferencedCurrencyInput Component', function () { const wrapper = shallow() assert.ok(wrapper) - assert.equal(wrapper.find(CurrencyInput).length, 1) + assert.strictEqual(wrapper.find(CurrencyInput).length, 1) }) it('should render useFiat for CurrencyInput based on preferences.useNativeCurrencyAsPrimaryCurrency', function () { @@ -19,10 +19,10 @@ describe('UserPreferencedCurrencyInput Component', function () { ) assert.ok(wrapper) - assert.equal(wrapper.find(CurrencyInput).length, 1) - assert.equal(wrapper.find(CurrencyInput).props().useFiat, false) + assert.strictEqual(wrapper.find(CurrencyInput).length, 1) + assert.strictEqual(wrapper.find(CurrencyInput).props().useFiat, false) wrapper.setProps({ useNativeCurrencyAsPrimaryCurrency: false }) - assert.equal(wrapper.find(CurrencyInput).props().useFiat, true) + assert.strictEqual(wrapper.find(CurrencyInput).props().useFiat, true) }) }) }) diff --git a/ui/app/components/app/user-preferenced-currency-input/tests/user-preferenced-currency-input.container.test.js b/ui/app/components/app/user-preferenced-currency-input/tests/user-preferenced-currency-input.container.test.js index 84c67f453..a687d469d 100644 --- a/ui/app/components/app/user-preferenced-currency-input/tests/user-preferenced-currency-input.container.test.js +++ b/ui/app/components/app/user-preferenced-currency-input/tests/user-preferenced-currency-input.container.test.js @@ -23,7 +23,7 @@ describe('UserPreferencedCurrencyInput container', function () { }, } - assert.deepEqual(mapStateToProps(mockState), { + assert.deepStrictEqual(mapStateToProps(mockState), { useNativeCurrencyAsPrimaryCurrency: true, }) }) diff --git a/ui/app/components/app/user-preferenced-token-input/tests/user-preferenced-token-input.component.test.js b/ui/app/components/app/user-preferenced-token-input/tests/user-preferenced-token-input.component.test.js index ce882f6e5..dcc5b6874 100644 --- a/ui/app/components/app/user-preferenced-token-input/tests/user-preferenced-token-input.component.test.js +++ b/ui/app/components/app/user-preferenced-token-input/tests/user-preferenced-token-input.component.test.js @@ -12,7 +12,7 @@ describe('UserPreferencedCurrencyInput Component', function () { ) assert.ok(wrapper) - assert.equal(wrapper.find(TokenInput).length, 1) + assert.strictEqual(wrapper.find(TokenInput).length, 1) }) it('should render showFiat for TokenInput based on preferences.useNativeCurrencyAsPrimaryCurrency', function () { @@ -24,10 +24,10 @@ describe('UserPreferencedCurrencyInput Component', function () { ) assert.ok(wrapper) - assert.equal(wrapper.find(TokenInput).length, 1) - assert.equal(wrapper.find(TokenInput).props().showFiat, false) + assert.strictEqual(wrapper.find(TokenInput).length, 1) + assert.strictEqual(wrapper.find(TokenInput).props().showFiat, false) wrapper.setProps({ useNativeCurrencyAsPrimaryCurrency: false }) - assert.equal(wrapper.find(TokenInput).props().showFiat, true) + assert.strictEqual(wrapper.find(TokenInput).props().showFiat, true) }) }) }) diff --git a/ui/app/components/app/user-preferenced-token-input/tests/user-preferenced-token-input.container.test.js b/ui/app/components/app/user-preferenced-token-input/tests/user-preferenced-token-input.container.test.js index f7bef30e4..8011f4885 100644 --- a/ui/app/components/app/user-preferenced-token-input/tests/user-preferenced-token-input.container.test.js +++ b/ui/app/components/app/user-preferenced-token-input/tests/user-preferenced-token-input.container.test.js @@ -23,7 +23,7 @@ describe('UserPreferencedTokenInput container', function () { }, } - assert.deepEqual(mapStateToProps(mockState), { + assert.deepStrictEqual(mapStateToProps(mockState), { useNativeCurrencyAsPrimaryCurrency: true, }) }) diff --git a/ui/app/components/ui/account-mismatch-warning/tests/acccount-mismatch-warning.component.test.js b/ui/app/components/ui/account-mismatch-warning/tests/acccount-mismatch-warning.component.test.js index f49935770..733d81241 100644 --- a/ui/app/components/ui/account-mismatch-warning/tests/acccount-mismatch-warning.component.test.js +++ b/ui/app/components/ui/account-mismatch-warning/tests/acccount-mismatch-warning.component.test.js @@ -20,11 +20,11 @@ describe('AccountMismatchWarning', function () { }) it('renders nothing when the addresses match', function () { const wrapper = shallow() - assert.equal(wrapper.find(InfoIcon).length, 0) + assert.strictEqual(wrapper.find(InfoIcon).length, 0) }) it('renders a warning info icon when addresses do not match', function () { const wrapper = shallow() - assert.equal(wrapper.find(InfoIcon).length, 1) + assert.strictEqual(wrapper.find(InfoIcon).length, 1) }) after(function () { sinon.restore() diff --git a/ui/app/components/ui/alert/tests/alert.test.js b/ui/app/components/ui/alert/tests/alert.test.js index f69a59b06..c8d36528b 100644 --- a/ui/app/components/ui/alert/tests/alert.test.js +++ b/ui/app/components/ui/alert/tests/alert.test.js @@ -13,7 +13,7 @@ describe('Alert', function () { it('renders nothing with no visible boolean in state', function () { const alert = wrapper.find('.global-alert') - assert.equal(alert.length, 0) + assert.strictEqual(alert.length, 0) }) it('renders when visible in state is true, and message', function () { @@ -22,10 +22,10 @@ describe('Alert', function () { wrapper.setState({ visible: true, msg: errorMessage }) const alert = wrapper.find('.global-alert') - assert.equal(alert.length, 1) + assert.strictEqual(alert.length, 1) const errorText = wrapper.find('.msg') - assert.equal(errorText.text(), errorMessage) + assert.strictEqual(errorText.text(), errorMessage) }) it('calls component method when componentWillReceiveProps is called', function () { diff --git a/ui/app/components/ui/breadcrumbs/tests/breadcrumbs.component.test.js b/ui/app/components/ui/breadcrumbs/tests/breadcrumbs.component.test.js index cbbbfd8e2..9d9abbdc6 100644 --- a/ui/app/components/ui/breadcrumbs/tests/breadcrumbs.component.test.js +++ b/ui/app/components/ui/breadcrumbs/tests/breadcrumbs.component.test.js @@ -8,17 +8,17 @@ describe('Breadcrumbs Component', function () { const wrapper = shallow() assert.ok(wrapper) - assert.equal(wrapper.find('.breadcrumbs').length, 1) - assert.equal(wrapper.find('.breadcrumb').length, 3) - assert.equal( + assert.strictEqual(wrapper.find('.breadcrumbs').length, 1) + assert.strictEqual(wrapper.find('.breadcrumb').length, 3) + assert.strictEqual( wrapper.find('.breadcrumb').at(0).props().style.backgroundColor, '#FFFFFF', ) - assert.equal( + assert.strictEqual( wrapper.find('.breadcrumb').at(1).props().style.backgroundColor, '#D8D8D8', ) - assert.equal( + assert.strictEqual( wrapper.find('.breadcrumb').at(2).props().style.backgroundColor, '#FFFFFF', ) diff --git a/ui/app/components/ui/button-group/tests/button-group-component.test.js b/ui/app/components/ui/button-group/tests/button-group-component.test.js index 28f54cf57..e64c866fa 100644 --- a/ui/app/components/ui/button-group/tests/button-group-component.test.js +++ b/ui/app/components/ui/button-group/tests/button-group-component.test.js @@ -49,77 +49,80 @@ describe('ButtonGroup Component', function () { describe('componentDidUpdate', function () { it('should set the activeButtonIndex to the updated newActiveButtonIndex', function () { - assert.equal(wrapper.state('activeButtonIndex'), 1) + assert.strictEqual(wrapper.state('activeButtonIndex'), 1) wrapper.setProps({ newActiveButtonIndex: 2 }) - assert.equal(wrapper.state('activeButtonIndex'), 2) + assert.strictEqual(wrapper.state('activeButtonIndex'), 2) }) it('should not set the activeButtonIndex to an updated newActiveButtonIndex that is not a number', function () { - assert.equal(wrapper.state('activeButtonIndex'), 1) + assert.strictEqual(wrapper.state('activeButtonIndex'), 1) wrapper.setProps({ newActiveButtonIndex: null }) - assert.equal(wrapper.state('activeButtonIndex'), 1) + assert.strictEqual(wrapper.state('activeButtonIndex'), 1) }) }) describe('handleButtonClick', function () { it('should set the activeButtonIndex', function () { - assert.equal(wrapper.state('activeButtonIndex'), 1) + assert.strictEqual(wrapper.state('activeButtonIndex'), 1) wrapper.instance().handleButtonClick(2) - assert.equal(wrapper.state('activeButtonIndex'), 2) + assert.strictEqual(wrapper.state('activeButtonIndex'), 2) }) }) describe('renderButtons', function () { it('should render a button for each child', function () { const childButtons = wrapper.find('.button-group__button') - assert.equal(childButtons.length, 3) + assert.strictEqual(childButtons.length, 3) }) it('should render the correct button with an active state', function () { const childButtons = wrapper.find('.button-group__button') const activeChildButton = wrapper.find('.button-group__button--active') - assert.deepEqual(childButtons.get(1), activeChildButton.get(0)) + assert.deepStrictEqual(childButtons.get(1), activeChildButton.get(0)) }) it("should call handleButtonClick and the respective button's onClick method when a button is clicked", function () { - assert.equal(ButtonGroup.prototype.handleButtonClick.callCount, 0) - assert.equal(childButtonSpies.onClick.callCount, 0) + assert.strictEqual(ButtonGroup.prototype.handleButtonClick.callCount, 0) + assert.strictEqual(childButtonSpies.onClick.callCount, 0) const childButtons = wrapper.find('.button-group__button') childButtons.at(0).props().onClick() childButtons.at(1).props().onClick() childButtons.at(2).props().onClick() - assert.equal(ButtonGroup.prototype.handleButtonClick.callCount, 3) - assert.equal(childButtonSpies.onClick.callCount, 3) + assert.strictEqual(ButtonGroup.prototype.handleButtonClick.callCount, 3) + assert.strictEqual(childButtonSpies.onClick.callCount, 3) }) it('should render all child buttons as disabled if props.disabled is true', function () { const childButtons = wrapper.find('.button-group__button') childButtons.forEach((button) => { - assert.equal(button.props().disabled, undefined) + assert.strictEqual(button.props().disabled, undefined) }) wrapper.setProps({ disabled: true }) const disabledChildButtons = wrapper.find('[disabled=true]') - assert.equal(disabledChildButtons.length, 3) + assert.strictEqual(disabledChildButtons.length, 3) }) it('should render the children of the button', function () { const mockClass = wrapper.find('.mockClass') - assert.equal(mockClass.length, 1) + assert.strictEqual(mockClass.length, 1) }) }) describe('render', function () { it('should render a div with the expected class and style', function () { - assert.equal(wrapper.find('div').at(0).props().className, 'someClassName') - assert.deepEqual(wrapper.find('div').at(0).props().style, { + assert.strictEqual( + wrapper.find('div').at(0).props().className, + 'someClassName', + ) + assert.deepStrictEqual(wrapper.find('div').at(0).props().style, { color: 'red', }) }) it('should call renderButtons when rendering', function () { - assert.equal(ButtonGroup.prototype.renderButtons.callCount, 1) + assert.strictEqual(ButtonGroup.prototype.renderButtons.callCount, 1) wrapper.instance().render() - assert.equal(ButtonGroup.prototype.renderButtons.callCount, 2) + assert.strictEqual(ButtonGroup.prototype.renderButtons.callCount, 2) }) }) }) diff --git a/ui/app/components/ui/card/tests/card.component.test.js b/ui/app/components/ui/card/tests/card.component.test.js index 4fc92252a..efd05e727 100644 --- a/ui/app/components/ui/card/tests/card.component.test.js +++ b/ui/app/components/ui/card/tests/card.component.test.js @@ -14,9 +14,9 @@ describe('Card Component', function () { assert.ok(wrapper.hasClass('card-test-class')) const title = wrapper.find('.card__title') assert.ok(title) - assert.equal(title.text(), 'Test') + assert.strictEqual(title.text(), 'Test') const child = wrapper.find('.child-test-class') assert.ok(child) - assert.equal(child.text(), 'Child') + assert.strictEqual(child.text(), 'Child') }) }) diff --git a/ui/app/components/ui/currency-display/tests/currency-display.component.test.js b/ui/app/components/ui/currency-display/tests/currency-display.component.test.js index 9e023aef3..8fd0bb4ba 100644 --- a/ui/app/components/ui/currency-display/tests/currency-display.component.test.js +++ b/ui/app/components/ui/currency-display/tests/currency-display.component.test.js @@ -24,7 +24,7 @@ describe('CurrencyDisplay Component', function () { ) assert.ok(wrapper.hasClass('currency-display')) - assert.equal(wrapper.text(), '$123.45') + assert.strictEqual(wrapper.text(), '$123.45') }) it('should render text with a prefix', function () { @@ -38,7 +38,7 @@ describe('CurrencyDisplay Component', function () { ) assert.ok(wrapper.hasClass('currency-display')) - assert.equal(wrapper.text(), '-$123.45') + assert.strictEqual(wrapper.text(), '-$123.45') }) afterEach(function () { sinon.restore() diff --git a/ui/app/components/ui/currency-input/tests/currency-input.component.test.js b/ui/app/components/ui/currency-input/tests/currency-input.component.test.js index d4d88be02..e6e05a33b 100644 --- a/ui/app/components/ui/currency-input/tests/currency-input.component.test.js +++ b/ui/app/components/ui/currency-input/tests/currency-input.component.test.js @@ -15,7 +15,7 @@ describe('CurrencyInput Component', function () { const wrapper = shallow() assert.ok(wrapper) - assert.equal(wrapper.find(UnitInput).length, 1) + assert.strictEqual(wrapper.find(UnitInput).length, 1) }) it('should render properly with a suffix', function () { @@ -39,9 +39,9 @@ describe('CurrencyInput Component', function () { ) assert.ok(wrapper) - assert.equal(wrapper.find('.unit-input__suffix').length, 1) - assert.equal(wrapper.find('.unit-input__suffix').text(), 'ETH') - assert.equal(wrapper.find(CurrencyDisplay).length, 1) + assert.strictEqual(wrapper.find('.unit-input__suffix').length, 1) + assert.strictEqual(wrapper.find('.unit-input__suffix').text(), 'ETH') + assert.strictEqual(wrapper.find(CurrencyDisplay).length, 1) }) it('should render properly with an ETH value', function () { @@ -69,12 +69,15 @@ describe('CurrencyInput Component', function () { assert.ok(wrapper) const currencyInputInstance = wrapper.find(CurrencyInput).at(0).instance() - assert.equal(currencyInputInstance.state.decimalValue, 1) - assert.equal(currencyInputInstance.state.hexValue, 'de0b6b3a7640000') - assert.equal(wrapper.find('.unit-input__suffix').length, 1) - assert.equal(wrapper.find('.unit-input__suffix').text(), 'ETH') - assert.equal(wrapper.find('.unit-input__input').props().value, '1') - assert.equal( + assert.strictEqual(currencyInputInstance.state.decimalValue, 1) + assert.strictEqual( + currencyInputInstance.state.hexValue, + 'de0b6b3a7640000', + ) + assert.strictEqual(wrapper.find('.unit-input__suffix').length, 1) + assert.strictEqual(wrapper.find('.unit-input__suffix').text(), 'ETH') + assert.strictEqual(wrapper.find('.unit-input__input').props().value, 1) + assert.strictEqual( wrapper.find('.currency-display-component').text(), '$231.06USD', ) @@ -106,12 +109,12 @@ describe('CurrencyInput Component', function () { assert.ok(wrapper) const currencyInputInstance = wrapper.find(CurrencyInput).at(0).instance() - assert.equal(currencyInputInstance.state.decimalValue, 1) - assert.equal(currencyInputInstance.state.hexValue, 'f602f2234d0ea') - assert.equal(wrapper.find('.unit-input__suffix').length, 1) - assert.equal(wrapper.find('.unit-input__suffix').text(), 'USD') - assert.equal(wrapper.find('.unit-input__input').props().value, '1') - assert.equal( + assert.strictEqual(currencyInputInstance.state.decimalValue, 1) + assert.strictEqual(currencyInputInstance.state.hexValue, 'f602f2234d0ea') + assert.strictEqual(wrapper.find('.unit-input__suffix').length, 1) + assert.strictEqual(wrapper.find('.unit-input__suffix').text(), 'USD') + assert.strictEqual(wrapper.find('.unit-input__input').props().value, 1) + assert.strictEqual( wrapper.find('.currency-display-component').text(), '0.004328ETH', ) @@ -148,12 +151,15 @@ describe('CurrencyInput Component', function () { assert.ok(wrapper) const currencyInputInstance = wrapper.find(CurrencyInput).at(0).instance() - assert.equal(currencyInputInstance.state.decimalValue, 0.004328) - assert.equal(currencyInputInstance.state.hexValue, 'f602f2234d0ea') - assert.equal(wrapper.find('.unit-input__suffix').length, 1) - assert.equal(wrapper.find('.unit-input__suffix').text(), 'ETH') - assert.equal(wrapper.find('.unit-input__input').props().value, '0.004328') - assert.equal( + assert.strictEqual(currencyInputInstance.state.decimalValue, 0.004328) + assert.strictEqual(currencyInputInstance.state.hexValue, 'f602f2234d0ea') + assert.strictEqual(wrapper.find('.unit-input__suffix').length, 1) + assert.strictEqual(wrapper.find('.unit-input__suffix').text(), 'ETH') + assert.strictEqual( + wrapper.find('.unit-input__input').props().value, + 0.004328, + ) + assert.strictEqual( wrapper.find('.currency-input__conversion-component').text(), 'noConversionRateAvailable_t', ) @@ -191,28 +197,31 @@ describe('CurrencyInput Component', function () { ) assert.ok(wrapper) - assert.equal(handleChangeSpy.callCount, 0) - assert.equal(handleBlurSpy.callCount, 0) + assert.strictEqual(handleChangeSpy.callCount, 0) + assert.strictEqual(handleBlurSpy.callCount, 0) const currencyInputInstance = wrapper.find(CurrencyInput).at(0).instance() - assert.equal(currencyInputInstance.state.decimalValue, 0) - assert.equal(currencyInputInstance.state.hexValue, undefined) - assert.equal( + assert.strictEqual(currencyInputInstance.state.decimalValue, 0) + assert.strictEqual(currencyInputInstance.state.hexValue, undefined) + assert.strictEqual( wrapper.find('.currency-display-component').text(), '$0.00USD', ) const input = wrapper.find('input') - assert.equal(input.props().value, 0) + assert.strictEqual(input.props().value, 0) input.simulate('change', { target: { value: 1 } }) - assert.equal(handleChangeSpy.callCount, 1) + assert.strictEqual(handleChangeSpy.callCount, 1) assert.ok(handleChangeSpy.calledWith('de0b6b3a7640000')) - assert.equal( + assert.strictEqual( wrapper.find('.currency-display-component').text(), '$231.06USD', ) - assert.equal(currencyInputInstance.state.decimalValue, 1) - assert.equal(currencyInputInstance.state.hexValue, 'de0b6b3a7640000') + assert.strictEqual(currencyInputInstance.state.decimalValue, 1) + assert.strictEqual( + currencyInputInstance.state.hexValue, + 'de0b6b3a7640000', + ) }) it('should call onChange on input changes with the hex value for fiat', function () { @@ -238,25 +247,28 @@ describe('CurrencyInput Component', function () { ) assert.ok(wrapper) - assert.equal(handleChangeSpy.callCount, 0) - assert.equal(handleBlurSpy.callCount, 0) + assert.strictEqual(handleChangeSpy.callCount, 0) + assert.strictEqual(handleBlurSpy.callCount, 0) const currencyInputInstance = wrapper.find(CurrencyInput).at(0).instance() - assert.equal(currencyInputInstance.state.decimalValue, 0) - assert.equal(currencyInputInstance.state.hexValue, undefined) - assert.equal(wrapper.find('.currency-display-component').text(), '0ETH') + assert.strictEqual(currencyInputInstance.state.decimalValue, 0) + assert.strictEqual(currencyInputInstance.state.hexValue, undefined) + assert.strictEqual( + wrapper.find('.currency-display-component').text(), + '0ETH', + ) const input = wrapper.find('input') - assert.equal(input.props().value, 0) + assert.strictEqual(input.props().value, 0) input.simulate('change', { target: { value: 1 } }) - assert.equal(handleChangeSpy.callCount, 1) + assert.strictEqual(handleChangeSpy.callCount, 1) assert.ok(handleChangeSpy.calledWith('f602f2234d0ea')) - assert.equal( + assert.strictEqual( wrapper.find('.currency-display-component').text(), '0.004328ETH', ) - assert.equal(currencyInputInstance.state.decimalValue, 1) - assert.equal(currencyInputInstance.state.hexValue, 'f602f2234d0ea') + assert.strictEqual(currencyInputInstance.state.decimalValue, 1) + assert.strictEqual(currencyInputInstance.state.hexValue, 'f602f2234d0ea') }) it('should change the state and pass in a new decimalValue when props.value changes', function () { @@ -283,15 +295,18 @@ describe('CurrencyInput Component', function () { assert.ok(wrapper) const currencyInputInstance = wrapper.find(CurrencyInput).dive() - assert.equal(currencyInputInstance.state('decimalValue'), 0) - assert.equal(currencyInputInstance.state('hexValue'), undefined) - assert.equal(currencyInputInstance.find(UnitInput).props().value, 0) + assert.strictEqual(currencyInputInstance.state('decimalValue'), 0) + assert.strictEqual(currencyInputInstance.state('hexValue'), undefined) + assert.strictEqual(currencyInputInstance.find(UnitInput).props().value, 0) currencyInputInstance.setProps({ value: '1ec05e43e72400' }) currencyInputInstance.update() - assert.equal(currencyInputInstance.state('decimalValue'), 2) - assert.equal(currencyInputInstance.state('hexValue'), '1ec05e43e72400') - assert.equal(currencyInputInstance.find(UnitInput).props().value, 2) + assert.strictEqual(currencyInputInstance.state('decimalValue'), 2) + assert.strictEqual( + currencyInputInstance.state('hexValue'), + '1ec05e43e72400', + ) + assert.strictEqual(currencyInputInstance.find(UnitInput).props().value, 2) }) it('should swap selected currency when swap icon is clicked', function () { @@ -317,32 +332,35 @@ describe('CurrencyInput Component', function () { ) assert.ok(wrapper) - assert.equal(handleChangeSpy.callCount, 0) - assert.equal(handleBlurSpy.callCount, 0) + assert.strictEqual(handleChangeSpy.callCount, 0) + assert.strictEqual(handleBlurSpy.callCount, 0) const currencyInputInstance = wrapper.find(CurrencyInput).at(0).instance() - assert.equal(currencyInputInstance.state.decimalValue, 0) - assert.equal(currencyInputInstance.state.hexValue, undefined) - assert.equal( + assert.strictEqual(currencyInputInstance.state.decimalValue, 0) + assert.strictEqual(currencyInputInstance.state.hexValue, undefined) + assert.strictEqual( wrapper.find('.currency-display-component').text(), '$0.00USD', ) const input = wrapper.find('input') - assert.equal(input.props().value, 0) + assert.strictEqual(input.props().value, 0) input.simulate('change', { target: { value: 1 } }) - assert.equal(handleChangeSpy.callCount, 1) + assert.strictEqual(handleChangeSpy.callCount, 1) assert.ok(handleChangeSpy.calledWith('de0b6b3a7640000')) - assert.equal( + assert.strictEqual( wrapper.find('.currency-display-component').text(), '$231.06USD', ) - assert.equal(currencyInputInstance.state.decimalValue, 1) - assert.equal(currencyInputInstance.state.hexValue, 'de0b6b3a7640000') + assert.strictEqual(currencyInputInstance.state.decimalValue, 1) + assert.strictEqual( + currencyInputInstance.state.hexValue, + 'de0b6b3a7640000', + ) const swap = wrapper.find('.currency-input__swap-component') swap.simulate('click') - assert.equal( + assert.strictEqual( wrapper.find('.currency-display-component').text(), '0.004328ETH', ) diff --git a/ui/app/components/ui/currency-input/tests/currency-input.container.test.js b/ui/app/components/ui/currency-input/tests/currency-input.container.test.js index 3dac9add0..1ce9eb559 100644 --- a/ui/app/components/ui/currency-input/tests/currency-input.container.test.js +++ b/ui/app/components/ui/currency-input/tests/currency-input.container.test.js @@ -131,7 +131,7 @@ describe('CurrencyInput container', function () { tests.forEach(({ mockState, expected, comment }) => { it(comment, function () { - return assert.deepEqual(mapStateToProps(mockState), expected) + return assert.deepStrictEqual(mapStateToProps(mockState), expected) }) }) }) @@ -189,7 +189,7 @@ describe('CurrencyInput container', function () { comment, }) => { it(comment, function () { - assert.deepEqual( + assert.deepStrictEqual( mergeProps(stateProps, dispatchProps, ownProps), expected, ) diff --git a/ui/app/components/ui/error-message/tests/error-message.component.test.js b/ui/app/components/ui/error-message/tests/error-message.component.test.js index 5bf05d876..884fe6565 100644 --- a/ui/app/components/ui/error-message/tests/error-message.component.test.js +++ b/ui/app/components/ui/error-message/tests/error-message.component.test.js @@ -12,9 +12,9 @@ describe('ErrorMessage Component', function () { }) assert.ok(wrapper) - assert.equal(wrapper.find('.error-message').length, 1) - assert.equal(wrapper.find('.error-message__icon').length, 1) - assert.equal( + assert.strictEqual(wrapper.find('.error-message').length, 1) + assert.strictEqual(wrapper.find('.error-message__icon').length, 1) + assert.strictEqual( wrapper.find('.error-message__text').text(), 'ALERT: This is an error.', ) @@ -26,9 +26,9 @@ describe('ErrorMessage Component', function () { }) assert.ok(wrapper) - assert.equal(wrapper.find('.error-message').length, 1) - assert.equal(wrapper.find('.error-message__icon').length, 1) - assert.equal( + assert.strictEqual(wrapper.find('.error-message').length, 1) + assert.strictEqual(wrapper.find('.error-message__icon').length, 1) + assert.strictEqual( wrapper.find('.error-message__text').text(), 'ALERT: translate testKey', ) diff --git a/ui/app/components/ui/hex-to-decimal/tests/hex-to-decimal.component.test.js b/ui/app/components/ui/hex-to-decimal/tests/hex-to-decimal.component.test.js index 3d8086630..cb75bfd63 100644 --- a/ui/app/components/ui/hex-to-decimal/tests/hex-to-decimal.component.test.js +++ b/ui/app/components/ui/hex-to-decimal/tests/hex-to-decimal.component.test.js @@ -10,7 +10,7 @@ describe('HexToDecimal Component', function () { ) assert.ok(wrapper.hasClass('hex-to-decimal')) - assert.equal(wrapper.text(), '12345') + assert.strictEqual(wrapper.text(), '12345') }) it('should render an unprefixed hex as a decimal with a className', function () { @@ -19,6 +19,6 @@ describe('HexToDecimal Component', function () { ) assert.ok(wrapper.hasClass('hex-to-decimal')) - assert.equal(wrapper.text(), '6789') + assert.strictEqual(wrapper.text(), '6789') }) }) diff --git a/ui/app/components/ui/identicon/tests/identicon.component.test.js b/ui/app/components/ui/identicon/tests/identicon.component.test.js index f07fb2d96..c938657ab 100644 --- a/ui/app/components/ui/identicon/tests/identicon.component.test.js +++ b/ui/app/components/ui/identicon/tests/identicon.component.test.js @@ -19,7 +19,7 @@ describe('Identicon', function () { it('renders default eth_logo identicon with no props', function () { const wrapper = mount() - assert.equal( + assert.strictEqual( wrapper.find('img.identicon__eth-logo').prop('src'), './images/eth_logo.svg', ) @@ -30,11 +30,11 @@ describe('Identicon', function () { , ) - assert.equal( + assert.strictEqual( wrapper.find('img.test-image').prop('className'), 'identicon test-image', ) - assert.equal(wrapper.find('img.test-image').prop('src'), 'test-image') + assert.strictEqual(wrapper.find('img.test-image').prop('src'), 'test-image') }) it('renders div with address prop', function () { @@ -42,7 +42,7 @@ describe('Identicon', function () { , ) - assert.equal( + assert.strictEqual( wrapper.find('div.test-address').prop('className'), 'identicon test-address', ) diff --git a/ui/app/components/ui/list-item/tests/list-item.test.js b/ui/app/components/ui/list-item/tests/list-item.test.js index 94d42ea3c..6f9e132cd 100644 --- a/ui/app/components/ui/list-item/tests/list-item.test.js +++ b/ui/app/components/ui/list-item/tests/list-item.test.js @@ -35,13 +35,13 @@ describe('ListItem', function () { ) }) it('includes the data-testid', function () { - assert.equal(wrapper.props()['data-testid'], 'test-id') + assert.strictEqual(wrapper.props()['data-testid'], 'test-id') }) it(`renders "${TITLE}" title`, function () { - assert.equal(wrapper.find('.list-item__heading h2').text(), TITLE) + assert.strictEqual(wrapper.find('.list-item__heading h2').text(), TITLE) }) it(`renders "I am a list item" subtitle`, function () { - assert.equal( + assert.strictEqual( wrapper.find('.list-item__subheading').text(), 'I am a list item', ) @@ -50,19 +50,19 @@ describe('ListItem', function () { assert(wrapper.props().className.includes(CLASSNAME)) }) it('renders content on the right side of the list item', function () { - assert.equal( + assert.strictEqual( wrapper.find('.list-item__right-content p').text(), 'Content rendered to the right', ) }) it('renders content in the middle of the list item', function () { - assert.equal( + assert.strictEqual( wrapper.find('.list-item__mid-content p').text(), 'Content rendered in the middle', ) }) it('renders list item actions', function () { - assert.equal( + assert.strictEqual( wrapper.find('.list-item__actions button').text(), 'I am a button', ) @@ -75,7 +75,7 @@ describe('ListItem', function () { }) it('handles click action and fires onClick', function () { wrapper.simulate('click') - assert.equal(clickHandler.callCount, 1) + assert.strictEqual(clickHandler.callCount, 1) }) after(function () { diff --git a/ui/app/components/ui/metafox-logo/tests/metafox-logo.component.test.js b/ui/app/components/ui/metafox-logo/tests/metafox-logo.component.test.js index ab2fd753b..5ea89c620 100644 --- a/ui/app/components/ui/metafox-logo/tests/metafox-logo.component.test.js +++ b/ui/app/components/ui/metafox-logo/tests/metafox-logo.component.test.js @@ -7,11 +7,11 @@ describe('MetaFoxLogo', function () { it('sets icon height and width to 42 by default', function () { const wrapper = mount() - assert.equal( + assert.strictEqual( wrapper.find('img.app-header__metafox-logo--icon').prop('width'), 42, ) - assert.equal( + assert.strictEqual( wrapper.find('img.app-header__metafox-logo--icon').prop('height'), 42, ) @@ -20,13 +20,13 @@ describe('MetaFoxLogo', function () { it('does not set icon height and width when unsetIconHeight is true', function () { const wrapper = mount() - assert.equal( + assert.strictEqual( wrapper.find('img.app-header__metafox-logo--icon').prop('width'), - null, + undefined, ) - assert.equal( + assert.strictEqual( wrapper.find('img.app-header__metafox-logo--icon').prop('height'), - null, + undefined, ) }) }) diff --git a/ui/app/components/ui/page-container/page-container-footer/tests/page-container-footer.component.test.js b/ui/app/components/ui/page-container/page-container-footer/tests/page-container-footer.component.test.js index ff41417a3..4fd9b039c 100644 --- a/ui/app/components/ui/page-container/page-container-footer/tests/page-container-footer.component.test.js +++ b/ui/app/components/ui/page-container/page-container-footer/tests/page-container-footer.component.test.js @@ -24,7 +24,7 @@ describe('Page Footer', function () { }) it('renders page container footer', function () { - assert.equal(wrapper.find('.page-container__footer').length, 1) + assert.strictEqual(wrapper.find('.page-container__footer').length, 1) }) it('should render a secondary footer inside page-container__footer when given children', function () { @@ -35,23 +35,26 @@ describe('Page Footer', function () { { context: { t: sinon.spy((k) => `[${k}]`) } }, ) - assert.equal(wrapper.find('.page-container__footer-secondary').length, 1) + assert.strictEqual( + wrapper.find('.page-container__footer-secondary').length, + 1, + ) }) it('renders two button components', function () { - assert.equal(wrapper.find(Button).length, 2) + assert.strictEqual(wrapper.find(Button).length, 2) }) describe('Cancel Button', function () { it('has button type of default', function () { - assert.equal( + assert.strictEqual( wrapper.find('.page-container__footer-button').first().prop('type'), 'default', ) }) it('has children text of Cancel', function () { - assert.equal( + assert.strictEqual( wrapper.find('.page-container__footer-button').first().prop('children'), 'Cancel', ) @@ -59,27 +62,27 @@ describe('Page Footer', function () { it('should call cancel when click is simulated', function () { wrapper.find('.page-container__footer-button').first().prop('onClick')() - assert.equal(onCancel.callCount, 1) + assert.strictEqual(onCancel.callCount, 1) }) }) describe('Submit Button', function () { it('assigns button type based on props', function () { - assert.equal( + assert.strictEqual( wrapper.find('.page-container__footer-button').last().prop('type'), 'Test Type', ) }) it('has disabled prop', function () { - assert.equal( + assert.strictEqual( wrapper.find('.page-container__footer-button').last().prop('disabled'), false, ) }) it('has children text when submitText prop exists', function () { - assert.equal( + assert.strictEqual( wrapper.find('.page-container__footer-button').last().prop('children'), 'Submit', ) @@ -87,7 +90,7 @@ describe('Page Footer', function () { it('should call submit when click is simulated', function () { wrapper.find('.page-container__footer-button').last().prop('onClick')() - assert.equal(onSubmit.callCount, 1) + assert.strictEqual(onSubmit.callCount, 1) }) }) }) diff --git a/ui/app/components/ui/page-container/page-container-header/tests/page-container-header.component.test.js b/ui/app/components/ui/page-container/page-container-header/tests/page-container-header.component.test.js index ab035c641..c686e3490 100644 --- a/ui/app/components/ui/page-container/page-container-header/tests/page-container-header.component.test.js +++ b/ui/app/components/ui/page-container/page-container-header/tests/page-container-header.component.test.js @@ -27,12 +27,15 @@ describe('Page Container Header', function () { describe('Render Header Row', function () { it('renders back button', function () { - assert.equal(wrapper.find('.page-container__back-button').length, 1) - assert.equal(wrapper.find('.page-container__back-button').text(), 'Back') + assert.strictEqual(wrapper.find('.page-container__back-button').length, 1) + assert.strictEqual( + wrapper.find('.page-container__back-button').text(), + 'Back', + ) }) it('ensures style prop', function () { - assert.equal( + assert.strictEqual( wrapper.find('.page-container__back-button').props().style, style, ) @@ -40,7 +43,7 @@ describe('Page Container Header', function () { it('should call back button when click is simulated', function () { wrapper.find('.page-container__back-button').prop('onClick')() - assert.equal(onBackButtonClick.callCount, 1) + assert.strictEqual(onBackButtonClick.callCount, 1) }) }) @@ -57,29 +60,29 @@ describe('Page Container Header', function () { }) it('renders page container', function () { - assert.equal(header.length, 1) - assert.equal(headerRow.length, 1) - assert.equal(pageTitle.length, 1) - assert.equal(pageSubtitle.length, 1) - assert.equal(pageClose.length, 1) - assert.equal(pageTab.length, 1) + assert.strictEqual(header.length, 1) + assert.strictEqual(headerRow.length, 1) + assert.strictEqual(pageTitle.length, 1) + assert.strictEqual(pageSubtitle.length, 1) + assert.strictEqual(pageClose.length, 1) + assert.strictEqual(pageTab.length, 1) }) it('renders title', function () { - assert.equal(pageTitle.text(), 'Test Title') + assert.strictEqual(pageTitle.text(), 'Test Title') }) it('renders subtitle', function () { - assert.equal(pageSubtitle.text(), 'Test Subtitle') + assert.strictEqual(pageSubtitle.text(), 'Test Subtitle') }) it('renders tabs', function () { - assert.equal(pageTab.text(), 'Test Tab') + assert.strictEqual(pageTab.text(), 'Test Tab') }) it('should call close when click is simulated', function () { pageClose.prop('onClick')() - assert.equal(onClose.callCount, 1) + assert.strictEqual(onClose.callCount, 1) }) }) }) diff --git a/ui/app/components/ui/token-input/tests/token-input.component.test.js b/ui/app/components/ui/token-input/tests/token-input.component.test.js index 52668a1cc..e6542b3e2 100644 --- a/ui/app/components/ui/token-input/tests/token-input.component.test.js +++ b/ui/app/components/ui/token-input/tests/token-input.component.test.js @@ -41,13 +41,13 @@ describe('TokenInput Component', function () { ) assert.ok(wrapper) - assert.equal(wrapper.find('.unit-input__suffix').length, 1) - assert.equal(wrapper.find('.unit-input__suffix').text(), 'ABC') - assert.equal( + assert.strictEqual(wrapper.find('.unit-input__suffix').length, 1) + assert.strictEqual(wrapper.find('.unit-input__suffix').text(), 'ABC') + assert.strictEqual( wrapper.find('.currency-input__conversion-component').length, 1, ) - assert.equal( + assert.strictEqual( wrapper.find('.currency-input__conversion-component').text(), 'translate noConversionRateAvailable', ) @@ -82,9 +82,9 @@ describe('TokenInput Component', function () { ) assert.ok(wrapper) - assert.equal(wrapper.find('.unit-input__suffix').length, 1) - assert.equal(wrapper.find('.unit-input__suffix').text(), 'ABC') - assert.equal(wrapper.find(CurrencyDisplay).length, 1) + assert.strictEqual(wrapper.find('.unit-input__suffix').length, 1) + assert.strictEqual(wrapper.find('.unit-input__suffix').text(), 'ABC') + assert.strictEqual(wrapper.find(CurrencyDisplay).length, 1) }) it('should render properly with a token value for ETH', function () { @@ -112,12 +112,15 @@ describe('TokenInput Component', function () { assert.ok(wrapper) const tokenInputInstance = wrapper.find(TokenInput).at(0).instance() - assert.equal(tokenInputInstance.state.decimalValue, 1) - assert.equal(tokenInputInstance.state.hexValue, '2710') - assert.equal(wrapper.find('.unit-input__suffix').length, 1) - assert.equal(wrapper.find('.unit-input__suffix').text(), 'ABC') - assert.equal(wrapper.find('.unit-input__input').props().value, '1') - assert.equal(wrapper.find('.currency-display-component').text(), '2ETH') + assert.strictEqual(tokenInputInstance.state.decimalValue, '1') + assert.strictEqual(tokenInputInstance.state.hexValue, '2710') + assert.strictEqual(wrapper.find('.unit-input__suffix').length, 1) + assert.strictEqual(wrapper.find('.unit-input__suffix').text(), 'ABC') + assert.strictEqual(wrapper.find('.unit-input__input').props().value, '1') + assert.strictEqual( + wrapper.find('.currency-display-component').text(), + '2ETH', + ) }) it('should render properly with a token value for fiat', function () { @@ -146,12 +149,12 @@ describe('TokenInput Component', function () { assert.ok(wrapper) const tokenInputInstance = wrapper.find(TokenInput).at(0).instance() - assert.equal(tokenInputInstance.state.decimalValue, 1) - assert.equal(tokenInputInstance.state.hexValue, '2710') - assert.equal(wrapper.find('.unit-input__suffix').length, 1) - assert.equal(wrapper.find('.unit-input__suffix').text(), 'ABC') - assert.equal(wrapper.find('.unit-input__input').props().value, '1') - assert.equal( + assert.strictEqual(tokenInputInstance.state.decimalValue, '1') + assert.strictEqual(tokenInputInstance.state.hexValue, '2710') + assert.strictEqual(wrapper.find('.unit-input__suffix').length, 1) + assert.strictEqual(wrapper.find('.unit-input__suffix').text(), 'ABC') + assert.strictEqual(wrapper.find('.unit-input__input').props().value, '1') + assert.strictEqual( wrapper.find('.currency-display-component').text(), '$462.12USD', ) @@ -190,12 +193,12 @@ describe('TokenInput Component', function () { assert.ok(wrapper) const tokenInputInstance = wrapper.find(TokenInput).at(0).instance() - assert.equal(tokenInputInstance.state.decimalValue, 1) - assert.equal(tokenInputInstance.state.hexValue, '2710') - assert.equal(wrapper.find('.unit-input__suffix').length, 1) - assert.equal(wrapper.find('.unit-input__suffix').text(), 'ABC') - assert.equal(wrapper.find('.unit-input__input').props().value, '1') - assert.equal( + assert.strictEqual(tokenInputInstance.state.decimalValue, '1') + assert.strictEqual(tokenInputInstance.state.hexValue, '2710') + assert.strictEqual(wrapper.find('.unit-input__suffix').length, 1) + assert.strictEqual(wrapper.find('.unit-input__suffix').text(), 'ABC') + assert.strictEqual(wrapper.find('.unit-input__input').props().value, '1') + assert.strictEqual( wrapper.find('.currency-input__conversion-component').text(), 'translate noConversionRateAvailable', ) @@ -234,22 +237,28 @@ describe('TokenInput Component', function () { ) assert.ok(wrapper) - assert.equal(handleChangeSpy.callCount, 0) - assert.equal(handleBlurSpy.callCount, 0) + assert.strictEqual(handleChangeSpy.callCount, 0) + assert.strictEqual(handleBlurSpy.callCount, 0) const tokenInputInstance = wrapper.find(TokenInput).at(0).instance() - assert.equal(tokenInputInstance.state.decimalValue, 0) - assert.equal(tokenInputInstance.state.hexValue, undefined) - assert.equal(wrapper.find('.currency-display-component').text(), '0ETH') + assert.strictEqual(tokenInputInstance.state.decimalValue, 0) + assert.strictEqual(tokenInputInstance.state.hexValue, undefined) + assert.strictEqual( + wrapper.find('.currency-display-component').text(), + '0ETH', + ) const input = wrapper.find('input') - assert.equal(input.props().value, 0) + assert.strictEqual(input.props().value, 0) input.simulate('change', { target: { value: 1 } }) - assert.equal(handleChangeSpy.callCount, 1) + assert.strictEqual(handleChangeSpy.callCount, 1) assert.ok(handleChangeSpy.calledWith('2710')) - assert.equal(wrapper.find('.currency-display-component').text(), '2ETH') - assert.equal(tokenInputInstance.state.decimalValue, 1) - assert.equal(tokenInputInstance.state.hexValue, '2710') + assert.strictEqual( + wrapper.find('.currency-display-component').text(), + '2ETH', + ) + assert.strictEqual(tokenInputInstance.state.decimalValue, 1) + assert.strictEqual(tokenInputInstance.state.hexValue, '2710') }) it('should call onChange on input changes with the hex value for fiat', function () { @@ -276,28 +285,28 @@ describe('TokenInput Component', function () { ) assert.ok(wrapper) - assert.equal(handleChangeSpy.callCount, 0) - assert.equal(handleBlurSpy.callCount, 0) + assert.strictEqual(handleChangeSpy.callCount, 0) + assert.strictEqual(handleBlurSpy.callCount, 0) const tokenInputInstance = wrapper.find(TokenInput).at(0).instance() - assert.equal(tokenInputInstance.state.decimalValue, 0) - assert.equal(tokenInputInstance.state.hexValue, undefined) - assert.equal( + assert.strictEqual(tokenInputInstance.state.decimalValue, 0) + assert.strictEqual(tokenInputInstance.state.hexValue, undefined) + assert.strictEqual( wrapper.find('.currency-display-component').text(), '$0.00USD', ) const input = wrapper.find('input') - assert.equal(input.props().value, 0) + assert.strictEqual(input.props().value, 0) input.simulate('change', { target: { value: 1 } }) - assert.equal(handleChangeSpy.callCount, 1) + assert.strictEqual(handleChangeSpy.callCount, 1) assert.ok(handleChangeSpy.calledWith('2710')) - assert.equal( + assert.strictEqual( wrapper.find('.currency-display-component').text(), '$462.12USD', ) - assert.equal(tokenInputInstance.state.decimalValue, 1) - assert.equal(tokenInputInstance.state.hexValue, '2710') + assert.strictEqual(tokenInputInstance.state.decimalValue, 1) + assert.strictEqual(tokenInputInstance.state.hexValue, '2710') }) it('should change the state and pass in a new decimalValue when props.value changes', function () { @@ -325,15 +334,15 @@ describe('TokenInput Component', function () { assert.ok(wrapper) const tokenInputInstance = wrapper.find(TokenInput).dive() - assert.equal(tokenInputInstance.state('decimalValue'), 0) - assert.equal(tokenInputInstance.state('hexValue'), undefined) - assert.equal(tokenInputInstance.find(UnitInput).props().value, 0) + assert.strictEqual(tokenInputInstance.state('decimalValue'), 0) + assert.strictEqual(tokenInputInstance.state('hexValue'), undefined) + assert.strictEqual(tokenInputInstance.find(UnitInput).props().value, 0) tokenInputInstance.setProps({ value: '2710' }) tokenInputInstance.update() - assert.equal(tokenInputInstance.state('decimalValue'), 1) - assert.equal(tokenInputInstance.state('hexValue'), '2710') - assert.equal(tokenInputInstance.find(UnitInput).props().value, 1) + assert.strictEqual(tokenInputInstance.state('decimalValue'), '1') + assert.strictEqual(tokenInputInstance.state('hexValue'), '2710') + assert.strictEqual(tokenInputInstance.find(UnitInput).props().value, '1') }) }) }) diff --git a/ui/app/components/ui/unit-input/tests/unit-input.component.test.js b/ui/app/components/ui/unit-input/tests/unit-input.component.test.js index c759f496f..47fdfafde 100644 --- a/ui/app/components/ui/unit-input/tests/unit-input.component.test.js +++ b/ui/app/components/ui/unit-input/tests/unit-input.component.test.js @@ -10,15 +10,15 @@ describe('UnitInput Component', function () { const wrapper = shallow() assert.ok(wrapper) - assert.equal(wrapper.find('.unit-input__suffix').length, 0) + assert.strictEqual(wrapper.find('.unit-input__suffix').length, 0) }) it('should render properly with a suffix', function () { const wrapper = shallow() assert.ok(wrapper) - assert.equal(wrapper.find('.unit-input__suffix').length, 1) - assert.equal(wrapper.find('.unit-input__suffix').text(), 'ETH') + assert.strictEqual(wrapper.find('.unit-input__suffix').length, 1) + assert.strictEqual(wrapper.find('.unit-input__suffix').text(), 'ETH') }) it('should render properly with a child component', function () { @@ -29,15 +29,15 @@ describe('UnitInput Component', function () { ) assert.ok(wrapper) - assert.equal(wrapper.find('.testing').length, 1) - assert.equal(wrapper.find('.testing').text(), 'TESTCOMPONENT') + assert.strictEqual(wrapper.find('.testing').length, 1) + assert.strictEqual(wrapper.find('.testing').text(), 'TESTCOMPONENT') }) it('should render with an error class when props.error === true', function () { const wrapper = shallow() assert.ok(wrapper) - assert.equal(wrapper.find('.unit-input--error').length, 1) + assert.strictEqual(wrapper.find('.unit-input--error').length, 1) }) }) @@ -57,43 +57,43 @@ describe('UnitInput Component', function () { const handleFocusSpy = sinon.spy(wrapper.instance(), 'handleFocus') wrapper.instance().forceUpdate() wrapper.update() - assert.equal(handleFocusSpy.callCount, 0) + assert.strictEqual(handleFocusSpy.callCount, 0) wrapper.find('.unit-input').simulate('click') - assert.equal(handleFocusSpy.callCount, 1) + assert.strictEqual(handleFocusSpy.callCount, 1) }) it('should call onChange on input changes with the value', function () { const wrapper = mount() assert.ok(wrapper) - assert.equal(handleChangeSpy.callCount, 0) + assert.strictEqual(handleChangeSpy.callCount, 0) const input = wrapper.find('input') input.simulate('change', { target: { value: 123 } }) - assert.equal(handleChangeSpy.callCount, 1) + assert.strictEqual(handleChangeSpy.callCount, 1) assert.ok(handleChangeSpy.calledWith(123)) - assert.equal(wrapper.state('value'), 123) + assert.strictEqual(wrapper.state('value'), 123) }) it('should set the component state value with props.value', function () { const wrapper = mount() assert.ok(wrapper) - assert.equal(wrapper.state('value'), 123) + assert.strictEqual(wrapper.state('value'), 123) }) it('should update the component state value with props.value', function () { const wrapper = mount() assert.ok(wrapper) - assert.equal(handleChangeSpy.callCount, 0) + assert.strictEqual(handleChangeSpy.callCount, 0) const input = wrapper.find('input') input.simulate('change', { target: { value: 123 } }) - assert.equal(wrapper.state('value'), 123) - assert.equal(handleChangeSpy.callCount, 1) + assert.strictEqual(wrapper.state('value'), 123) + assert.strictEqual(handleChangeSpy.callCount, 1) assert.ok(handleChangeSpy.calledWith(123)) wrapper.setProps({ value: 456 }) - assert.equal(wrapper.state('value'), 456) - assert.equal(handleChangeSpy.callCount, 1) + assert.strictEqual(wrapper.state('value'), 456) + assert.strictEqual(handleChangeSpy.callCount, 1) }) }) }) diff --git a/ui/app/ducks/confirm-transaction/confirm-transaction.duck.test.js b/ui/app/ducks/confirm-transaction/confirm-transaction.duck.test.js index 4d2d56544..f5edaa67f 100644 --- a/ui/app/ducks/confirm-transaction/confirm-transaction.duck.test.js +++ b/ui/app/ducks/confirm-transaction/confirm-transaction.duck.test.js @@ -83,11 +83,14 @@ describe('Confirm Transaction Duck', function () { } it('should initialize state', function () { - assert.deepEqual(ConfirmTransactionReducer(undefined, {}), initialState) + assert.deepStrictEqual( + ConfirmTransactionReducer(undefined, {}), + initialState, + ) }) it('should return state unchanged if it does not match a dispatched actions type', function () { - assert.deepEqual( + assert.deepStrictEqual( ConfirmTransactionReducer(mockState, { type: 'someOtherAction', value: 'someValue', @@ -97,7 +100,7 @@ describe('Confirm Transaction Duck', function () { }) it('should set txData when receiving a UPDATE_TX_DATA action', function () { - assert.deepEqual( + assert.deepStrictEqual( ConfirmTransactionReducer(mockState, { type: UPDATE_TX_DATA, payload: { @@ -115,7 +118,7 @@ describe('Confirm Transaction Duck', function () { }) it('should clear txData when receiving a CLEAR_TX_DATA action', function () { - assert.deepEqual( + assert.deepStrictEqual( ConfirmTransactionReducer(mockState, { type: CLEAR_TX_DATA, }), @@ -127,7 +130,7 @@ describe('Confirm Transaction Duck', function () { }) it('should set tokenData when receiving a UPDATE_TOKEN_DATA action', function () { - assert.deepEqual( + assert.deepStrictEqual( ConfirmTransactionReducer(mockState, { type: UPDATE_TOKEN_DATA, payload: { @@ -145,7 +148,7 @@ describe('Confirm Transaction Duck', function () { }) it('should clear tokenData when receiving a CLEAR_TOKEN_DATA action', function () { - assert.deepEqual( + assert.deepStrictEqual( ConfirmTransactionReducer(mockState, { type: CLEAR_TOKEN_DATA, }), @@ -157,7 +160,7 @@ describe('Confirm Transaction Duck', function () { }) it('should set methodData when receiving a UPDATE_METHOD_DATA action', function () { - assert.deepEqual( + assert.deepStrictEqual( ConfirmTransactionReducer(mockState, { type: UPDATE_METHOD_DATA, payload: { @@ -175,7 +178,7 @@ describe('Confirm Transaction Duck', function () { }) it('should clear methodData when receiving a CLEAR_METHOD_DATA action', function () { - assert.deepEqual( + assert.deepStrictEqual( ConfirmTransactionReducer(mockState, { type: CLEAR_METHOD_DATA, }), @@ -187,7 +190,7 @@ describe('Confirm Transaction Duck', function () { }) it('should update transaction amounts when receiving an UPDATE_TRANSACTION_AMOUNTS action', function () { - assert.deepEqual( + assert.deepStrictEqual( ConfirmTransactionReducer(mockState, { type: UPDATE_TRANSACTION_AMOUNTS, payload: { @@ -206,7 +209,7 @@ describe('Confirm Transaction Duck', function () { }) it('should update transaction fees when receiving an UPDATE_TRANSACTION_FEES action', function () { - assert.deepEqual( + assert.deepStrictEqual( ConfirmTransactionReducer(mockState, { type: UPDATE_TRANSACTION_FEES, payload: { @@ -225,7 +228,7 @@ describe('Confirm Transaction Duck', function () { }) it('should update transaction totals when receiving an UPDATE_TRANSACTION_TOTALS action', function () { - assert.deepEqual( + assert.deepStrictEqual( ConfirmTransactionReducer(mockState, { type: UPDATE_TRANSACTION_TOTALS, payload: { @@ -244,7 +247,7 @@ describe('Confirm Transaction Duck', function () { }) it('should update tokenProps when receiving an UPDATE_TOKEN_PROPS action', function () { - assert.deepEqual( + assert.deepStrictEqual( ConfirmTransactionReducer(mockState, { type: UPDATE_TOKEN_PROPS, payload: { @@ -263,7 +266,7 @@ describe('Confirm Transaction Duck', function () { }) it('should update nonce when receiving an UPDATE_NONCE action', function () { - assert.deepEqual( + assert.deepStrictEqual( ConfirmTransactionReducer(mockState, { type: UPDATE_NONCE, payload: '0x1', @@ -276,7 +279,7 @@ describe('Confirm Transaction Duck', function () { }) it('should update nonce when receiving an UPDATE_TO_SMART_CONTRACT action', function () { - assert.deepEqual( + assert.deepStrictEqual( ConfirmTransactionReducer(mockState, { type: UPDATE_TO_SMART_CONTRACT, payload: true, @@ -289,7 +292,7 @@ describe('Confirm Transaction Duck', function () { }) it('should set fetchingData to true when receiving a FETCH_DATA_START action', function () { - assert.deepEqual( + assert.deepStrictEqual( ConfirmTransactionReducer(mockState, { type: FETCH_DATA_START, }), @@ -301,7 +304,7 @@ describe('Confirm Transaction Duck', function () { }) it('should set fetchingData to false when receiving a FETCH_DATA_END action', function () { - assert.deepEqual( + assert.deepStrictEqual( ConfirmTransactionReducer( { fetchingData: true }, { type: FETCH_DATA_END }, @@ -311,7 +314,7 @@ describe('Confirm Transaction Duck', function () { }) it('should clear confirmTransaction when receiving a FETCH_DATA_END action', function () { - assert.deepEqual( + assert.deepStrictEqual( ConfirmTransactionReducer(mockState, { type: CLEAR_CONFIRM_TRANSACTION, }), @@ -328,7 +331,7 @@ describe('Confirm Transaction Duck', function () { payload: txData, } - assert.deepEqual(actions.updateTxData(txData), expectedAction) + assert.deepStrictEqual(actions.updateTxData(txData), expectedAction) }) it('should create an action to clear txData', function () { @@ -336,7 +339,7 @@ describe('Confirm Transaction Duck', function () { type: CLEAR_TX_DATA, } - assert.deepEqual(actions.clearTxData(), expectedAction) + assert.deepStrictEqual(actions.clearTxData(), expectedAction) }) it('should create an action to update tokenData', function () { @@ -346,7 +349,7 @@ describe('Confirm Transaction Duck', function () { payload: tokenData, } - assert.deepEqual(actions.updateTokenData(tokenData), expectedAction) + assert.deepStrictEqual(actions.updateTokenData(tokenData), expectedAction) }) it('should create an action to clear tokenData', function () { @@ -354,7 +357,7 @@ describe('Confirm Transaction Duck', function () { type: CLEAR_TOKEN_DATA, } - assert.deepEqual(actions.clearTokenData(), expectedAction) + assert.deepStrictEqual(actions.clearTokenData(), expectedAction) }) it('should create an action to update methodData', function () { @@ -364,7 +367,10 @@ describe('Confirm Transaction Duck', function () { payload: methodData, } - assert.deepEqual(actions.updateMethodData(methodData), expectedAction) + assert.deepStrictEqual( + actions.updateMethodData(methodData), + expectedAction, + ) }) it('should create an action to clear methodData', function () { @@ -372,7 +378,7 @@ describe('Confirm Transaction Duck', function () { type: CLEAR_METHOD_DATA, } - assert.deepEqual(actions.clearMethodData(), expectedAction) + assert.deepStrictEqual(actions.clearMethodData(), expectedAction) }) it('should create an action to update transaction amounts', function () { @@ -382,7 +388,7 @@ describe('Confirm Transaction Duck', function () { payload: transactionAmounts, } - assert.deepEqual( + assert.deepStrictEqual( actions.updateTransactionAmounts(transactionAmounts), expectedAction, ) @@ -395,7 +401,7 @@ describe('Confirm Transaction Duck', function () { payload: transactionFees, } - assert.deepEqual( + assert.deepStrictEqual( actions.updateTransactionFees(transactionFees), expectedAction, ) @@ -408,7 +414,7 @@ describe('Confirm Transaction Duck', function () { payload: transactionTotals, } - assert.deepEqual( + assert.deepStrictEqual( actions.updateTransactionTotals(transactionTotals), expectedAction, ) @@ -424,7 +430,10 @@ describe('Confirm Transaction Duck', function () { payload: tokenProps, } - assert.deepEqual(actions.updateTokenProps(tokenProps), expectedAction) + assert.deepStrictEqual( + actions.updateTokenProps(tokenProps), + expectedAction, + ) }) it('should create an action to update nonce', function () { @@ -434,7 +443,7 @@ describe('Confirm Transaction Duck', function () { payload: nonce, } - assert.deepEqual(actions.updateNonce(nonce), expectedAction) + assert.deepStrictEqual(actions.updateNonce(nonce), expectedAction) }) it('should create an action to set fetchingData to true', function () { @@ -442,7 +451,7 @@ describe('Confirm Transaction Duck', function () { type: FETCH_DATA_START, } - assert.deepEqual(actions.setFetchingData(true), expectedAction) + assert.deepStrictEqual(actions.setFetchingData(true), expectedAction) }) it('should create an action to set fetchingData to false', function () { @@ -450,7 +459,7 @@ describe('Confirm Transaction Duck', function () { type: FETCH_DATA_END, } - assert.deepEqual(actions.setFetchingData(false), expectedAction) + assert.deepStrictEqual(actions.setFetchingData(false), expectedAction) }) it('should create an action to clear confirmTransaction', function () { @@ -458,7 +467,7 @@ describe('Confirm Transaction Duck', function () { type: CLEAR_CONFIRM_TRANSACTION, } - assert.deepEqual(actions.clearConfirmTransaction(), expectedAction) + assert.deepStrictEqual(actions.clearConfirmTransaction(), expectedAction) }) }) @@ -526,9 +535,9 @@ describe('Confirm Transaction Duck', function () { ) const storeActions = store.getActions() - assert.equal(storeActions.length, expectedActions.length) + assert.strictEqual(storeActions.length, expectedActions.length) storeActions.forEach((action, index) => - assert.equal(action.type, expectedActions[index]), + assert.strictEqual(action.type, expectedActions[index]), ) }) @@ -592,9 +601,9 @@ describe('Confirm Transaction Duck', function () { store.dispatch(actions.updateTxDataAndCalculate(txData)) const storeActions = store.getActions() - assert.equal(storeActions.length, expectedActions.length) + assert.strictEqual(storeActions.length, expectedActions.length) storeActions.forEach((action, index) => - assert.equal(action.type, expectedActions[index]), + assert.strictEqual(action.type, expectedActions[index]), ) }) @@ -638,10 +647,10 @@ describe('Confirm Transaction Duck', function () { store.dispatch(actions.setTransactionToConfirm(2603411941761054)) const storeActions = store.getActions() - assert.equal(storeActions.length, expectedActions.length) + assert.strictEqual(storeActions.length, expectedActions.length) storeActions.forEach((action, index) => - assert.equal(action.type, expectedActions[index]), + assert.strictEqual(action.type, expectedActions[index]), ) }) }) diff --git a/ui/app/ducks/gas/gas-duck.test.js b/ui/app/ducks/gas/gas-duck.test.js index b9935af5c..aceea5efb 100644 --- a/ui/app/ducks/gas/gas-duck.test.js +++ b/ui/app/ducks/gas/gas-duck.test.js @@ -86,11 +86,11 @@ describe('Gas Duck', function () { describe('GasReducer()', function () { it('should initialize state', function () { - assert.deepEqual(GasReducer(undefined, {}), initState) + assert.deepStrictEqual(GasReducer(undefined, {}), initState) }) it('should return state unchanged if it does not match a dispatched actions type', function () { - assert.deepEqual( + assert.deepStrictEqual( GasReducer(mockState, { type: 'someOtherAction', value: 'someValue', @@ -100,21 +100,21 @@ describe('Gas Duck', function () { }) it('should set basicEstimateIsLoading to true when receiving a BASIC_GAS_ESTIMATE_LOADING_STARTED action', function () { - assert.deepEqual( + assert.deepStrictEqual( GasReducer(mockState, { type: BASIC_GAS_ESTIMATE_LOADING_STARTED }), { basicEstimateIsLoading: true, ...mockState }, ) }) it('should set basicEstimateIsLoading to false when receiving a BASIC_GAS_ESTIMATE_LOADING_FINISHED action', function () { - assert.deepEqual( + assert.deepStrictEqual( GasReducer(mockState, { type: BASIC_GAS_ESTIMATE_LOADING_FINISHED }), { basicEstimateIsLoading: false, ...mockState }, ) }) it('should set basicEstimates when receiving a SET_BASIC_GAS_ESTIMATE_DATA action', function () { - assert.deepEqual( + assert.deepStrictEqual( GasReducer(mockState, { type: SET_BASIC_GAS_ESTIMATE_DATA, value: { someProp: 'someData123' }, @@ -124,7 +124,7 @@ describe('Gas Duck', function () { }) it('should set customData.price when receiving a SET_CUSTOM_GAS_PRICE action', function () { - assert.deepEqual( + assert.deepStrictEqual( GasReducer(mockState, { type: SET_CUSTOM_GAS_PRICE, value: 4321, @@ -134,7 +134,7 @@ describe('Gas Duck', function () { }) it('should set customData.limit when receiving a SET_CUSTOM_GAS_LIMIT action', function () { - assert.deepEqual( + assert.deepStrictEqual( GasReducer(mockState, { type: SET_CUSTOM_GAS_LIMIT, value: 9876, @@ -144,7 +144,7 @@ describe('Gas Duck', function () { }) it('should set customData.total when receiving a SET_CUSTOM_GAS_TOTAL action', function () { - assert.deepEqual( + assert.deepStrictEqual( GasReducer(mockState, { type: SET_CUSTOM_GAS_TOTAL, value: 10000, @@ -154,7 +154,7 @@ describe('Gas Duck', function () { }) it('should set errors when receiving a SET_CUSTOM_GAS_ERRORS action', function () { - assert.deepEqual( + assert.deepStrictEqual( GasReducer(mockState, { type: SET_CUSTOM_GAS_ERRORS, value: { someError: 'error_error' }, @@ -164,7 +164,7 @@ describe('Gas Duck', function () { }) it('should return the initial state in response to a RESET_CUSTOM_GAS_STATE action', function () { - assert.deepEqual( + assert.deepStrictEqual( GasReducer(mockState, { type: RESET_CUSTOM_GAS_STATE }), initState, ) @@ -173,7 +173,7 @@ describe('Gas Duck', function () { describe('basicGasEstimatesLoadingStarted', function () { it('should create the correct action', function () { - assert.deepEqual(basicGasEstimatesLoadingStarted(), { + assert.deepStrictEqual(basicGasEstimatesLoadingStarted(), { type: BASIC_GAS_ESTIMATE_LOADING_STARTED, }) }) @@ -181,7 +181,7 @@ describe('Gas Duck', function () { describe('basicGasEstimatesLoadingFinished', function () { it('should create the correct action', function () { - assert.deepEqual(basicGasEstimatesLoadingFinished(), { + assert.deepStrictEqual(basicGasEstimatesLoadingFinished(), { type: BASIC_GAS_ESTIMATE_LOADING_FINISHED, }) }) @@ -194,7 +194,7 @@ describe('Gas Duck', function () { await fetchBasicGasEstimates()(mockDistpatch, () => ({ gas: { ...initState, basicPriceAEstimatesLastRetrieved: 1000000 }, })) - assert.deepEqual(mockDistpatch.getCall(0).args, [ + assert.deepStrictEqual(mockDistpatch.getCall(0).args, [ { type: BASIC_GAS_ESTIMATE_LOADING_STARTED }, ]) assert.ok( @@ -203,10 +203,10 @@ describe('Gas Duck', function () { .args[0].startsWith('https://api.metaswap.codefi.network/gasPrices'), 'should fetch metaswap /gasPrices', ) - assert.deepEqual(mockDistpatch.getCall(1).args, [ + assert.deepStrictEqual(mockDistpatch.getCall(1).args, [ { type: SET_BASIC_PRICE_ESTIMATES_LAST_RETRIEVED, value: 2000000 }, ]) - assert.deepEqual(mockDistpatch.getCall(2).args, [ + assert.deepStrictEqual(mockDistpatch.getCall(2).args, [ { type: SET_BASIC_GAS_ESTIMATE_DATA, value: { @@ -216,7 +216,7 @@ describe('Gas Duck', function () { }, }, ]) - assert.deepEqual(mockDistpatch.getCall(3).args, [ + assert.deepStrictEqual(mockDistpatch.getCall(3).args, [ { type: BASIC_GAS_ESTIMATE_LOADING_FINISHED }, ]) }) @@ -235,11 +235,11 @@ describe('Gas Duck', function () { await fetchBasicGasEstimates()(mockDistpatch, () => ({ gas: { ...initState }, })) - assert.deepEqual(mockDistpatch.getCall(0).args, [ + assert.deepStrictEqual(mockDistpatch.getCall(0).args, [ { type: BASIC_GAS_ESTIMATE_LOADING_STARTED }, ]) assert.ok(window.fetch.notCalled) - assert.deepEqual(mockDistpatch.getCall(1).args, [ + assert.deepStrictEqual(mockDistpatch.getCall(1).args, [ { type: SET_BASIC_GAS_ESTIMATE_DATA, value: { @@ -249,7 +249,7 @@ describe('Gas Duck', function () { }, }, ]) - assert.deepEqual(mockDistpatch.getCall(2).args, [ + assert.deepStrictEqual(mockDistpatch.getCall(2).args, [ { type: BASIC_GAS_ESTIMATE_LOADING_FINISHED }, ]) }) @@ -263,7 +263,7 @@ describe('Gas Duck', function () { await fetchBasicGasEstimates()(mockDistpatch, () => ({ gas: { ...initState }, })) - assert.deepEqual(mockDistpatch.getCall(0).args, [ + assert.deepStrictEqual(mockDistpatch.getCall(0).args, [ { type: BASIC_GAS_ESTIMATE_LOADING_STARTED }, ]) assert.ok( @@ -272,10 +272,10 @@ describe('Gas Duck', function () { .args[0].startsWith('https://api.metaswap.codefi.network/gasPrices'), 'should fetch metaswap /gasPrices', ) - assert.deepEqual(mockDistpatch.getCall(1).args, [ + assert.deepStrictEqual(mockDistpatch.getCall(1).args, [ { type: SET_BASIC_PRICE_ESTIMATES_LAST_RETRIEVED, value: 2000000 }, ]) - assert.deepEqual(mockDistpatch.getCall(2).args, [ + assert.deepStrictEqual(mockDistpatch.getCall(2).args, [ { type: SET_BASIC_GAS_ESTIMATE_DATA, value: { @@ -285,7 +285,7 @@ describe('Gas Duck', function () { }, }, ]) - assert.deepEqual(mockDistpatch.getCall(3).args, [ + assert.deepStrictEqual(mockDistpatch.getCall(3).args, [ { type: BASIC_GAS_ESTIMATE_LOADING_FINISHED }, ]) }) @@ -293,7 +293,7 @@ describe('Gas Duck', function () { describe('setBasicGasEstimateData', function () { it('should create the correct action', function () { - assert.deepEqual(setBasicGasEstimateData('mockBasicEstimatData'), { + assert.deepStrictEqual(setBasicGasEstimateData('mockBasicEstimatData'), { type: SET_BASIC_GAS_ESTIMATE_DATA, value: 'mockBasicEstimatData', }) @@ -302,7 +302,7 @@ describe('Gas Duck', function () { describe('setCustomGasPrice', function () { it('should create the correct action', function () { - assert.deepEqual(setCustomGasPrice('mockCustomGasPrice'), { + assert.deepStrictEqual(setCustomGasPrice('mockCustomGasPrice'), { type: SET_CUSTOM_GAS_PRICE, value: 'mockCustomGasPrice', }) @@ -311,7 +311,7 @@ describe('Gas Duck', function () { describe('setCustomGasLimit', function () { it('should create the correct action', function () { - assert.deepEqual(setCustomGasLimit('mockCustomGasLimit'), { + assert.deepStrictEqual(setCustomGasLimit('mockCustomGasLimit'), { type: SET_CUSTOM_GAS_LIMIT, value: 'mockCustomGasLimit', }) @@ -320,7 +320,7 @@ describe('Gas Duck', function () { describe('setCustomGasTotal', function () { it('should create the correct action', function () { - assert.deepEqual(setCustomGasTotal('mockCustomGasTotal'), { + assert.deepStrictEqual(setCustomGasTotal('mockCustomGasTotal'), { type: SET_CUSTOM_GAS_TOTAL, value: 'mockCustomGasTotal', }) @@ -329,7 +329,7 @@ describe('Gas Duck', function () { describe('setCustomGasErrors', function () { it('should create the correct action', function () { - assert.deepEqual(setCustomGasErrors('mockErrorObject'), { + assert.deepStrictEqual(setCustomGasErrors('mockErrorObject'), { type: SET_CUSTOM_GAS_ERRORS, value: 'mockErrorObject', }) @@ -338,7 +338,9 @@ describe('Gas Duck', function () { describe('resetCustomGasState', function () { it('should create the correct action', function () { - assert.deepEqual(resetCustomGasState(), { type: RESET_CUSTOM_GAS_STATE }) + assert.deepStrictEqual(resetCustomGasState(), { + type: RESET_CUSTOM_GAS_STATE, + }) }) }) }) diff --git a/ui/app/ducks/send/send-duck.test.js b/ui/app/ducks/send/send-duck.test.js index 3c7ca415a..2d123fb01 100644 --- a/ui/app/ducks/send/send-duck.test.js +++ b/ui/app/ducks/send/send-duck.test.js @@ -26,11 +26,11 @@ describe('Send Duck', function () { describe('SendReducer()', function () { it('should initialize state', function () { - assert.deepEqual(SendReducer(undefined, {}), initState) + assert.deepStrictEqual(SendReducer(undefined, {}), initState) }) it('should return state unchanged if it does not match a dispatched actions type', function () { - assert.deepEqual( + assert.deepStrictEqual( SendReducer(mockState, { type: 'someOtherAction', value: 'someValue', @@ -40,7 +40,7 @@ describe('Send Duck', function () { }) it('should set toDropdownOpen to true when receiving a OPEN_TO_DROPDOWN action', function () { - assert.deepEqual( + assert.deepStrictEqual( SendReducer(mockState, { type: OPEN_TO_DROPDOWN, }), @@ -49,7 +49,7 @@ describe('Send Duck', function () { }) it('should set toDropdownOpen to false when receiving a CLOSE_TO_DROPDOWN action', function () { - assert.deepEqual( + assert.deepStrictEqual( SendReducer(mockState, { type: CLOSE_TO_DROPDOWN, }), @@ -58,7 +58,7 @@ describe('Send Duck', function () { }) it('should set gasButtonGroupShown to true when receiving a SHOW_GAS_BUTTON_GROUP action', function () { - assert.deepEqual( + assert.deepStrictEqual( SendReducer( { ...mockState, gasButtonGroupShown: false }, { type: SHOW_GAS_BUTTON_GROUP }, @@ -68,7 +68,7 @@ describe('Send Duck', function () { }) it('should set gasButtonGroupShown to false when receiving a HIDE_GAS_BUTTON_GROUP action', function () { - assert.deepEqual( + assert.deepStrictEqual( SendReducer(mockState, { type: HIDE_GAS_BUTTON_GROUP }), { gasButtonGroupShown: false, ...mockState }, ) @@ -81,7 +81,7 @@ describe('Send Duck', function () { someError: false, }, } - assert.deepEqual( + assert.deepStrictEqual( SendReducer(modifiedMockState, { type: UPDATE_SEND_ERRORS, value: { someOtherError: true }, @@ -97,7 +97,7 @@ describe('Send Duck', function () { }) it('should return the initial state in response to a RESET_SEND_STATE action', function () { - assert.deepEqual( + assert.deepStrictEqual( SendReducer(mockState, { type: RESET_SEND_STATE, }), @@ -107,23 +107,27 @@ describe('Send Duck', function () { }) describe('openToDropdown', function () { - assert.deepEqual(openToDropdown(), { type: OPEN_TO_DROPDOWN }) + assert.deepStrictEqual(openToDropdown(), { type: OPEN_TO_DROPDOWN }) }) describe('closeToDropdown', function () { - assert.deepEqual(closeToDropdown(), { type: CLOSE_TO_DROPDOWN }) + assert.deepStrictEqual(closeToDropdown(), { type: CLOSE_TO_DROPDOWN }) }) describe('showGasButtonGroup', function () { - assert.deepEqual(showGasButtonGroup(), { type: SHOW_GAS_BUTTON_GROUP }) + assert.deepStrictEqual(showGasButtonGroup(), { + type: SHOW_GAS_BUTTON_GROUP, + }) }) describe('hideGasButtonGroup', function () { - assert.deepEqual(hideGasButtonGroup(), { type: HIDE_GAS_BUTTON_GROUP }) + assert.deepStrictEqual(hideGasButtonGroup(), { + type: HIDE_GAS_BUTTON_GROUP, + }) }) describe('updateSendErrors', function () { - assert.deepEqual(updateSendErrors('mockErrorObject'), { + assert.deepStrictEqual(updateSendErrors('mockErrorObject'), { type: UPDATE_SEND_ERRORS, value: 'mockErrorObject', }) diff --git a/ui/app/helpers/higher-order-components/with-modal-props/tests/with-modal-props.test.js b/ui/app/helpers/higher-order-components/with-modal-props/tests/with-modal-props.test.js index df1b20cb4..06f95129a 100644 --- a/ui/app/helpers/higher-order-components/with-modal-props/tests/with-modal-props.test.js +++ b/ui/app/helpers/higher-order-components/with-modal-props/tests/with-modal-props.test.js @@ -27,12 +27,12 @@ describe('withModalProps', function () { assert.ok(wrapper) const testComponent = wrapper.find(TestComponent).at(0) - assert.equal(testComponent.length, 1) - assert.equal(testComponent.find('.test').text(), 'Testing') + assert.strictEqual(testComponent.length, 1) + assert.strictEqual(testComponent.find('.test').text(), 'Testing') const testComponentProps = testComponent.props() - assert.equal(testComponentProps.prop1, 'prop1') - assert.equal(testComponentProps.prop2, 2) - assert.equal(testComponentProps.prop3, true) - assert.equal(typeof testComponentProps.hideModal, 'function') + assert.strictEqual(testComponentProps.prop1, 'prop1') + assert.strictEqual(testComponentProps.prop2, 2) + assert.strictEqual(testComponentProps.prop3, true) + assert.strictEqual(typeof testComponentProps.hideModal, 'function') }) }) diff --git a/ui/app/helpers/utils/common.util.test.js b/ui/app/helpers/utils/common.util.test.js index cd2d71b03..2e083322d 100644 --- a/ui/app/helpers/utils/common.util.test.js +++ b/ui/app/helpers/utils/common.util.test.js @@ -20,7 +20,7 @@ describe('Common utils', function () { ] tests.forEach(({ test, expected }) => { - assert.equal(utils.camelCaseToCapitalize(test), expected) + assert.strictEqual(utils.camelCaseToCapitalize(test), expected) }) }) }) diff --git a/ui/app/helpers/utils/confirm-tx.util.test.js b/ui/app/helpers/utils/confirm-tx.util.test.js index 0db49ef89..a05090648 100644 --- a/ui/app/helpers/utils/confirm-tx.util.test.js +++ b/ui/app/helpers/utils/confirm-tx.util.test.js @@ -5,43 +5,43 @@ describe('Confirm Transaction utils', function () { describe('increaseLastGasPrice', function () { it('should increase the gasPrice by 10%', function () { const increasedGasPrice = utils.increaseLastGasPrice('0xa') - assert.equal(increasedGasPrice, '0xb') + assert.strictEqual(increasedGasPrice, '0xb') }) it('should prefix the result with 0x', function () { const increasedGasPrice = utils.increaseLastGasPrice('a') - assert.equal(increasedGasPrice, '0xb') + assert.strictEqual(increasedGasPrice, '0xb') }) }) describe('hexGreaterThan', function () { it('should return true if the first value is greater than the second value', function () { - assert.equal(utils.hexGreaterThan('0xb', '0xa'), true) + assert.strictEqual(utils.hexGreaterThan('0xb', '0xa'), true) }) it('should return false if the first value is less than the second value', function () { - assert.equal(utils.hexGreaterThan('0xa', '0xb'), false) + assert.strictEqual(utils.hexGreaterThan('0xa', '0xb'), false) }) it('should return false if the first value is equal to the second value', function () { - assert.equal(utils.hexGreaterThan('0xa', '0xa'), false) + assert.strictEqual(utils.hexGreaterThan('0xa', '0xa'), false) }) it('should correctly compare prefixed and non-prefixed hex values', function () { - assert.equal(utils.hexGreaterThan('0xb', 'a'), true) + assert.strictEqual(utils.hexGreaterThan('0xb', 'a'), true) }) }) describe('getHexGasTotal', function () { it('should multiply the hex gasLimit and hex gasPrice values together', function () { - assert.equal( + assert.strictEqual( utils.getHexGasTotal({ gasLimit: '0x5208', gasPrice: '0x3b9aca00' }), '0x1319718a5000', ) }) it('should prefix the result with 0x', function () { - assert.equal( + assert.strictEqual( utils.getHexGasTotal({ gasLimit: '5208', gasPrice: '3b9aca00' }), '0x1319718a5000', ) @@ -50,11 +50,11 @@ describe('Confirm Transaction utils', function () { describe('addEth', function () { it('should add two values together rounding to 6 decimal places', function () { - assert.equal(utils.addEth('0.12345678', '0'), '0.123457') + assert.strictEqual(utils.addEth('0.12345678', '0'), '0.123457') }) it('should add any number of values together rounding to 6 decimal places', function () { - assert.equal( + assert.strictEqual( utils.addEth( '0.1', '0.02', @@ -71,11 +71,11 @@ describe('Confirm Transaction utils', function () { describe('addFiat', function () { it('should add two values together rounding to 2 decimal places', function () { - assert.equal(utils.addFiat('0.12345678', '0'), '0.12') + assert.strictEqual(utils.addFiat('0.12345678', '0'), '0.12') }) it('should add any number of values together rounding to 2 decimal places', function () { - assert.equal( + assert.strictEqual( utils.addFiat( '0.1', '0.02', @@ -99,7 +99,7 @@ describe('Confirm Transaction utils', function () { numberOfDecimals: 6, }) - assert.equal(ethTransactionAmount, '1') + assert.strictEqual(ethTransactionAmount, '1') }) it('should get the transaction amount in fiat', function () { @@ -110,7 +110,7 @@ describe('Confirm Transaction utils', function () { numberOfDecimals: 2, }) - assert.equal(fiatTransactionAmount, '468.58') + assert.strictEqual(fiatTransactionAmount, '468.58') }) }) @@ -123,7 +123,7 @@ describe('Confirm Transaction utils', function () { numberOfDecimals: 6, }) - assert.equal(ethTransactionFee, '0.000021') + assert.strictEqual(ethTransactionFee, '0.000021') }) it('should get the transaction fee in fiat', function () { @@ -134,14 +134,14 @@ describe('Confirm Transaction utils', function () { numberOfDecimals: 2, }) - assert.equal(fiatTransactionFee, '0.01') + assert.strictEqual(fiatTransactionFee, '0.01') }) }) describe('formatCurrency', function () { it('should format USD values', function () { const value = utils.formatCurrency('123.45', 'usd') - assert.equal(value, '$123.45') + assert.strictEqual(value, '$123.45') }) }) }) diff --git a/ui/app/helpers/utils/conversion-util.test.js b/ui/app/helpers/utils/conversion-util.test.js index 34a7a5308..5e05f6727 100644 --- a/ui/app/helpers/utils/conversion-util.test.js +++ b/ui/app/helpers/utils/conversion-util.test.js @@ -9,7 +9,7 @@ describe('conversion utils', function () { aBase: 10, bBase: 10, }) - assert.equal(result.toNumber(), 12) + assert.strictEqual(result.toNumber(), 12) }) it('add decimals', function () { @@ -17,7 +17,7 @@ describe('conversion utils', function () { aBase: 10, bBase: 10, }) - assert.equal(result.toNumber(), 3.2) + assert.strictEqual(result.toNumber(), 3.2) }) it('add repeating decimals', function () { @@ -25,7 +25,7 @@ describe('conversion utils', function () { aBase: 10, bBase: 10, }) - assert.equal(result.toNumber(), 0.4444444444444444) + assert.strictEqual(result.toNumber(), 0.4444444444444444) }) }) @@ -47,14 +47,14 @@ describe('conversion utils', function () { assert(conv2 instanceof BigNumber, 'conversion 2 should be a BigNumber') }) it('Converts from dec to hex', function () { - assert.equal( + assert.strictEqual( conversionUtil('1000000000000000000', { fromNumericBase: 'dec', toNumericBase: 'hex', }), 'de0b6b3a7640000', ) - assert.equal( + assert.strictEqual( conversionUtil('1500000000000000000', { fromNumericBase: 'dec', toNumericBase: 'hex', @@ -63,79 +63,79 @@ describe('conversion utils', function () { ) }) it('Converts hex formatted numbers to dec', function () { - assert.equal( + assert.strictEqual( conversionUtil('0xde0b6b3a7640000', { fromNumericBase: 'hex', toNumericBase: 'dec', }), - 1000000000000000000, + '1000000000000000000', ) - assert.equal( + assert.strictEqual( conversionUtil('0x14d1120d7b160000', { fromNumericBase: 'hex', toNumericBase: 'dec', }), - 1500000000000000000, + '1500000000000000000', ) }) it('Converts WEI to ETH', function () { - assert.equal( + assert.strictEqual( conversionUtil('0xde0b6b3a7640000', { fromNumericBase: 'hex', toNumericBase: 'dec', fromDenomination: 'WEI', toDenomination: 'ETH', }), - 1, + '1', ) - assert.equal( + assert.strictEqual( conversionUtil('0x14d1120d7b160000', { fromNumericBase: 'hex', toNumericBase: 'dec', fromDenomination: 'WEI', toDenomination: 'ETH', }), - 1.5, + '1.5', ) }) it('Converts ETH to WEI', function () { - assert.equal( + assert.strictEqual( conversionUtil('1', { fromNumericBase: 'dec', fromDenomination: 'ETH', toDenomination: 'WEI', - }), + }).toNumber(), 1000000000000000000, ) - assert.equal( + assert.strictEqual( conversionUtil('1.5', { fromNumericBase: 'dec', fromDenomination: 'ETH', toDenomination: 'WEI', - }), + }).toNumber(), 1500000000000000000, ) }) it('Converts ETH to GWEI', function () { - assert.equal( + assert.strictEqual( conversionUtil('1', { fromNumericBase: 'dec', fromDenomination: 'ETH', toDenomination: 'GWEI', - }), + }).toNumber(), 1000000000, ) - assert.equal( + assert.strictEqual( conversionUtil('1.5', { fromNumericBase: 'dec', fromDenomination: 'ETH', toDenomination: 'GWEI', - }), + }).toNumber(), 1500000000, ) }) it('Converts ETH to USD', function () { - assert.equal( + assert.strictEqual( conversionUtil('1', { fromNumericBase: 'dec', toNumericBase: 'dec', @@ -143,9 +143,9 @@ describe('conversion utils', function () { conversionRate: 468.58, numberOfDecimals: 2, }), - 468.58, + '468.58', ) - assert.equal( + assert.strictEqual( conversionUtil('1.5', { fromNumericBase: 'dec', toNumericBase: 'dec', @@ -153,11 +153,11 @@ describe('conversion utils', function () { conversionRate: 468.58, numberOfDecimals: 2, }), - 702.87, + '702.87', ) }) it('Converts USD to ETH', function () { - assert.equal( + assert.strictEqual( conversionUtil('468.58', { fromNumericBase: 'dec', toNumericBase: 'dec', @@ -166,9 +166,9 @@ describe('conversion utils', function () { numberOfDecimals: 2, invertConversionRate: true, }), - 1, + '1', ) - assert.equal( + assert.strictEqual( conversionUtil('702.87', { fromNumericBase: 'dec', toNumericBase: 'dec', @@ -177,7 +177,7 @@ describe('conversion utils', function () { numberOfDecimals: 2, invertConversionRate: true, }), - 1.5, + '1.5', ) }) }) diff --git a/ui/app/helpers/utils/conversions.util.test.js b/ui/app/helpers/utils/conversions.util.test.js index 5a32ceff4..6ae58ca83 100644 --- a/ui/app/helpers/utils/conversions.util.test.js +++ b/ui/app/helpers/utils/conversions.util.test.js @@ -10,34 +10,34 @@ describe('conversion utils', function () { fromCurrency: ETH, fromDenomination: ETH, }) - assert.equal(weiValue, '0') + assert.strictEqual(weiValue, '0') }) }) describe('decETHToDecWEI', function () { it('should correctly convert 1 ETH to WEI', function () { const weiValue = utils.decETHToDecWEI('1') - assert.equal(weiValue, '1000000000000000000') + assert.strictEqual(weiValue, '1000000000000000000') }) it('should correctly convert 0.000000000000000001 ETH to WEI', function () { const weiValue = utils.decETHToDecWEI('0.000000000000000001') - assert.equal(weiValue, '1') + assert.strictEqual(weiValue, '1') }) it('should correctly convert 1000000.000000000000000001 ETH to WEI', function () { const weiValue = utils.decETHToDecWEI('1000000.000000000000000001') - assert.equal(weiValue, '1000000000000000000000001') + assert.strictEqual(weiValue, '1000000000000000000000001') }) it('should correctly convert 9876.543210 ETH to WEI', function () { const weiValue = utils.decETHToDecWEI('9876.543210') - assert.equal(weiValue, '9876543210000000000000') + assert.strictEqual(weiValue, '9876543210000000000000') }) it('should correctly convert 1.0000000000000000 ETH to WEI', function () { const weiValue = utils.decETHToDecWEI('1.0000000000000000') - assert.equal(weiValue, '1000000000000000000') + assert.strictEqual(weiValue, '1000000000000000000') }) }) }) diff --git a/ui/app/helpers/utils/fetch-with-cache.test.js b/ui/app/helpers/utils/fetch-with-cache.test.js index c0fcda3fc..43336a85e 100644 --- a/ui/app/helpers/utils/fetch-with-cache.test.js +++ b/ui/app/helpers/utils/fetch-with-cache.test.js @@ -26,7 +26,7 @@ describe('Fetch with cache', function () { const response = await fetchWithCache( 'https://fetchwithcache.metamask.io/price', ) - assert.deepEqual(response, { + assert.deepStrictEqual(response, { average: 1, }) }) @@ -46,7 +46,7 @@ describe('Fetch with cache', function () { const response = await fetchWithCache( 'https://fetchwithcache.metamask.io/price', ) - assert.deepEqual(response, { + assert.deepStrictEqual(response, { average: 1, }) }) @@ -68,7 +68,7 @@ describe('Fetch with cache', function () { {}, { cacheRefreshTime: 123 }, ) - assert.deepEqual(response, { + assert.deepStrictEqual(response, { average: 3, }) }) diff --git a/ui/app/helpers/utils/i18n-helper.test.js b/ui/app/helpers/utils/i18n-helper.test.js index 3c0cca220..1c908f7f3 100644 --- a/ui/app/helpers/utils/i18n-helper.test.js +++ b/ui/app/helpers/utils/i18n-helper.test.js @@ -100,12 +100,12 @@ describe('i18n helper', function () { describe('getMessage', function () { it('should return the exact message paired with key if there are no substitutions', function () { const result = t(TEST_KEY_1) - assert.equal(result, 'This is a simple message.') + assert.strictEqual(result, 'This is a simple message.') }) it('should return the correct message when a single non-react substitution is made', function () { const result = t(TEST_KEY_2, [TEST_SUBSTITUTION_1]) - assert.equal( + assert.strictEqual( result, `This is a message with a single non-react substitution ${TEST_SUBSTITUTION_1}.`, ) @@ -113,7 +113,7 @@ describe('i18n helper', function () { it('should return the correct message when two non-react substitutions are made', function () { const result = t(TEST_KEY_3, [TEST_SUBSTITUTION_1, TEST_SUBSTITUTION_2]) - assert.equal( + assert.strictEqual( result, `This is a message with two non-react substitutions ${TEST_SUBSTITUTION_1} and ${TEST_SUBSTITUTION_2}.`, ) @@ -127,7 +127,7 @@ describe('i18n helper', function () { TEST_SUBSTITUTION_4, TEST_SUBSTITUTION_5, ]) - assert.equal( + assert.strictEqual( result, `${TEST_SUBSTITUTION_1} - ${TEST_SUBSTITUTION_2} - ${TEST_SUBSTITUTION_3} - ${TEST_SUBSTITUTION_4} - ${TEST_SUBSTITUTION_5}`, ) @@ -135,17 +135,17 @@ describe('i18n helper', function () { it('should correctly render falsey substitutions', function () { const result = t(TEST_KEY_4, [0, -0, '', false, NaN]) - assert.equal(result, '0 - 0 - - false - NaN') + assert.strictEqual(result, '0 - 0 - - false - NaN') }) it('should render nothing for "null" and "undefined" substitutions', function () { const result = t(TEST_KEY_5, [null, TEST_SUBSTITUTION_2]) - assert.equal(result, ` - ${TEST_SUBSTITUTION_2} - `) + assert.strictEqual(result, ` - ${TEST_SUBSTITUTION_2} - `) }) it('should return the correct message when a single react substitution is made', function () { const result = t(TEST_KEY_6, [TEST_SUBSTITUTION_6]) - assert.equal( + assert.strictEqual( shallow(result).html(), ' Testing a react substitution
TEST_SUBSTITUTION_1
.
', ) @@ -156,7 +156,7 @@ describe('i18n helper', function () { TEST_SUBSTITUTION_7_1, TEST_SUBSTITUTION_7_2, ]) - assert.equal( + assert.strictEqual( shallow(result).html(), ' Testing a react substitution
TEST_SUBSTITUTION_1
and another
TEST_SUBSTITUTION_2
.
', ) @@ -169,7 +169,7 @@ describe('i18n helper', function () { TEST_SUBSTITUTION_2, TEST_SUBSTITUTION_8_2, ]) - assert.equal( + assert.strictEqual( shallow(result).html(), ' Testing a mix TEST_SUBSTITUTION_1 of react substitutions
TEST_SUBSTITUTION_3
and string substitutions TEST_SUBSTITUTION_2 +
TEST_SUBSTITUTION_4
.
', ) diff --git a/ui/app/helpers/utils/transactions.util.test.js b/ui/app/helpers/utils/transactions.util.test.js index 80de38846..9079028dd 100644 --- a/ui/app/helpers/utils/transactions.util.test.js +++ b/ui/app/helpers/utils/transactions.util.test.js @@ -14,11 +14,11 @@ describe('Transactions utils', function () { ) assert.ok(tokenData) const { name, args } = tokenData - assert.equal(name, TRANSACTION_CATEGORIES.TOKEN_METHOD_TRANSFER) + assert.strictEqual(name, TRANSACTION_CATEGORIES.TOKEN_METHOD_TRANSFER) const to = args._to const value = args._value.toString() - assert.equal(to, '0x50A9D56C2B8BA9A5c7f2C08C3d26E0499F23a706') - assert.equal(value, '20000') + assert.strictEqual(to, '0x50A9D56C2B8BA9A5c7f2C08C3d26E0499F23a706') + assert.strictEqual(value, '20000') }) it('should not throw errors when called without arguments', function () { @@ -56,7 +56,7 @@ describe('Transactions utils', function () { ] tests.forEach(({ transaction, expected }) => { - assert.equal(utils.getStatusKey(transaction), expected) + assert.strictEqual(utils.getStatusKey(transaction), expected) }) }) }) @@ -96,7 +96,7 @@ describe('Transactions utils', function () { ] tests.forEach(({ expected, networkId, hash, rpcPrefs }) => { - assert.equal( + assert.strictEqual( utils.getBlockExplorerUrlForTx(networkId, hash, rpcPrefs), expected, ) diff --git a/ui/app/helpers/utils/util.test.js b/ui/app/helpers/utils/util.test.js index 15c8e722f..9f319c362 100644 --- a/ui/app/helpers/utils/util.test.js +++ b/ui/app/helpers/utils/util.test.js @@ -12,25 +12,25 @@ describe('util', function () { it('should render 0.01 eth correctly', function () { const input = '0x2386F26FC10000' const output = util.parseBalance(input) - assert.deepEqual(output, ['0', '01']) + assert.deepStrictEqual(output, ['0', '01']) }) it('should render 12.023 eth correctly', function () { const input = 'A6DA46CCA6858000' const output = util.parseBalance(input) - assert.deepEqual(output, ['12', '023']) + assert.deepStrictEqual(output, ['12', '023']) }) it('should render 0.0000000342422 eth correctly', function () { const input = '0x7F8FE81C0' const output = util.parseBalance(input) - assert.deepEqual(output, ['0', '0000000342422']) + assert.deepStrictEqual(output, ['0', '0000000342422']) }) it('should render 0 eth correctly', function () { const input = '0x0' const output = util.parseBalance(input) - assert.deepEqual(output, ['0', '0']) + assert.deepStrictEqual(output, ['0', '0']) }) }) @@ -38,13 +38,13 @@ describe('util', function () { it('should add case-sensitive checksum', function () { const address = '0xfdea65c8e26263f6d9a1b5de9555d2931a33b825' const result = util.addressSummary(address) - assert.equal(result, '0xFDEa65C8...b825') + assert.strictEqual(result, '0xFDEa65C8...b825') }) it('should accept arguments for firstseg, lastseg, and keepPrefix', function () { const address = '0xfdea65c8e26263f6d9a1b5de9555d2931a33b825' const result = util.addressSummary(address, 4, 4, false) - assert.equal(result, 'FDEa...b825') + assert.strictEqual(result, 'FDEa...b825') }) }) @@ -89,7 +89,7 @@ describe('util', function () { const address = '0x5Fda30Bb72B8Dfe20e48A00dFc108d0915BE9Bb0' const result = util.isValidAddress(address) const hashed = ethUtil.toChecksumAddress(address.toLowerCase()) - assert.equal(hashed, address, 'example is hashed correctly') + assert.strictEqual(hashed, address, 'example is hashed correctly') assert.ok(result, 'is valid by our check') }) }) @@ -155,30 +155,30 @@ describe('util', function () { describe('#numericBalance', function () { it('should return a BN 0 if given nothing', function () { const result = util.numericBalance() - assert.equal(result.toString(10), 0) + assert.strictEqual(result.toString(10), '0') }) it('should work with hex prefix', function () { const result = util.numericBalance('0x012') - assert.equal(result.toString(10), '18') + assert.strictEqual(result.toString(10), '18') }) it('should work with no hex prefix', function () { const result = util.numericBalance('012') - assert.equal(result.toString(10), '18') + assert.strictEqual(result.toString(10), '18') }) }) describe('#formatBalance', function () { it('should return None when given nothing', function () { const result = util.formatBalance() - assert.equal(result, 'None', 'should return "None"') + assert.strictEqual(result, 'None', 'should return "None"') }) it('should return 1.0000 ETH', function () { const input = new ethUtil.BN(ethInWei, 10).toJSON() const result = util.formatBalance(input, 4) - assert.equal(result, '1.0000 ETH') + assert.strictEqual(result, '1.0000 ETH') }) it('should return 0.500 ETH', function () { @@ -186,29 +186,29 @@ describe('util', function () { .div(new ethUtil.BN('2', 10)) .toJSON() const result = util.formatBalance(input, 3) - assert.equal(result, '0.500 ETH') + assert.strictEqual(result, '0.500 ETH') }) it('should display specified decimal points', function () { const input = '0x128dfa6a90b28000' const result = util.formatBalance(input, 2) - assert.equal(result, '1.33 ETH') + assert.strictEqual(result, '1.33 ETH') }) it('should default to 3 decimal points', function () { const input = '0x128dfa6a90b28000' const result = util.formatBalance(input) - assert.equal(result, '1.337 ETH') + assert.strictEqual(result, '1.337 ETH') }) it('should show 2 significant digits for tiny balances', function () { const input = '0x1230fa6a90b28' const result = util.formatBalance(input) - assert.equal(result, '0.00032 ETH') + assert.strictEqual(result, '0.00032 ETH') }) it('should not parse the balance and return value with 2 decimal points with ETH at the end', function () { const value = '1.2456789' const needsParse = false const result = util.formatBalance(value, 2, needsParse) - assert.equal(result, '1.24 ETH') + assert.strictEqual(result, '1.24 ETH') }) }) @@ -235,7 +235,7 @@ describe('util', function () { Object.keys(valueTable).forEach((currency) => { const value = new ethUtil.BN(valueTable[currency], 10) const output = util.normalizeToWei(value, currency) - assert.equal( + assert.strictEqual( output.toString(10), valueTable.wei, `value of ${output.toString( @@ -250,25 +250,25 @@ describe('util', function () { it('should convert decimal eth to pure wei BN', function () { const input = '1.23456789' const output = util.normalizeEthStringToWei(input) - assert.equal(output.toString(10), '1234567890000000000') + assert.strictEqual(output.toString(10), '1234567890000000000') }) it('should convert 1 to expected wei', function () { const input = '1' const output = util.normalizeEthStringToWei(input) - assert.equal(output.toString(10), ethInWei) + assert.strictEqual(output.toString(10), ethInWei) }) it('should account for overflow numbers gracefully by dropping extra precision.', function () { const input = '1.11111111111111111111' const output = util.normalizeEthStringToWei(input) - assert.equal(output.toString(10), '1111111111111111111') + assert.strictEqual(output.toString(10), '1111111111111111111') }) it('should not truncate very exact wei values that do not have extra precision.', function () { const input = '1.100000000000000001' const output = util.normalizeEthStringToWei(input) - assert.equal(output.toString(10), '1100000000000000001') + assert.strictEqual(output.toString(10), '1100000000000000001') }) }) @@ -277,17 +277,17 @@ describe('util', function () { const input = 0.0002 const output = util.normalizeNumberToWei(input, 'ether') const str = output.toString(10) - assert.equal(str, '200000000000000') + assert.strictEqual(str, '200000000000000') }) it('should convert a kwei number to the appropriate equivalent wei', function () { const result = util.normalizeNumberToWei(1.111, 'kwei') - assert.equal(result.toString(10), '1111', 'accepts decimals') + assert.strictEqual(result.toString(10), '1111', 'accepts decimals') }) it('should convert a ether number to the appropriate equivalent wei', function () { const result = util.normalizeNumberToWei(1.111, 'ether') - assert.equal( + assert.strictEqual( result.toString(10), '1111000000000000000', 'accepts decimals', @@ -408,14 +408,17 @@ describe('util', function () { testData.forEach(({ args, result }) => { it(`should return ${result} when passed number ${args[0]} and precision ${args[1]}`, function () { - assert.equal(util.toPrecisionWithoutTrailingZeros(...args), result) + assert.strictEqual( + util.toPrecisionWithoutTrailingZeros(...args), + result, + ) }) }) }) describe('addHexPrefixToObjectValues()', function () { it('should return a new object with the same properties with a 0x prefix', function () { - assert.deepEqual( + assert.deepStrictEqual( util.addHexPrefixToObjectValues({ prop1: '0x123', prop2: '456', diff --git a/ui/app/hooks/tests/useCancelTransaction.test.js b/ui/app/hooks/tests/useCancelTransaction.test.js index 903e861d0..0d3d590f3 100644 --- a/ui/app/hooks/tests/useCancelTransaction.test.js +++ b/ui/app/hooks/tests/useCancelTransaction.test.js @@ -44,18 +44,18 @@ describe('useCancelTransaction', function () { const { result } = renderHook(() => useCancelTransaction(transactionGroup), ) - assert.equal(result.current[0], false) + assert.strictEqual(result.current[0], false) }) it(`should return a function that kicks off cancellation for id ${transactionId}`, function () { const { result } = renderHook(() => useCancelTransaction(transactionGroup), ) - assert.equal(typeof result.current[1], 'function') + assert.strictEqual(typeof result.current[1], 'function') result.current[1]({ preventDefault: () => undefined, stopPropagation: () => undefined, }) - assert.equal( + assert.strictEqual( dispatch.calledWith( showModal({ name: 'CANCEL_TRANSACTION', @@ -96,18 +96,18 @@ describe('useCancelTransaction', function () { const { result } = renderHook(() => useCancelTransaction(transactionGroup), ) - assert.equal(result.current[0], true) + assert.strictEqual(result.current[0], true) }) it(`should return a function that kicks off cancellation for id ${transactionId}`, function () { const { result } = renderHook(() => useCancelTransaction(transactionGroup), ) - assert.equal(typeof result.current[1], 'function') + assert.strictEqual(typeof result.current[1], 'function') result.current[1]({ preventDefault: () => undefined, stopPropagation: () => undefined, }) - assert.equal( + assert.strictEqual( dispatch.calledWith( showModal({ name: 'CANCEL_TRANSACTION', diff --git a/ui/app/hooks/tests/useCurrencyDisplay.test.js b/ui/app/hooks/tests/useCurrencyDisplay.test.js index bacaa6ff0..4b90e9a79 100644 --- a/ui/app/hooks/tests/useCurrencyDisplay.test.js +++ b/ui/app/hooks/tests/useCurrencyDisplay.test.js @@ -117,13 +117,13 @@ describe('useCurrencyDisplay', function () { const [displayValue, parts] = hookReturn.result.current stub.restore() it(`should return ${result.displayValue} as displayValue`, function () { - assert.equal(displayValue, result.displayValue) + assert.strictEqual(displayValue, result.displayValue) }) it(`should return ${result.value} as value`, function () { - assert.equal(parts.value, result.value) + assert.strictEqual(parts.value, result.value) }) it(`should return ${result.suffix} as suffix`, function () { - assert.equal(parts.suffix, result.suffix) + assert.strictEqual(parts.suffix, result.suffix) }) }) }) diff --git a/ui/app/hooks/tests/useRetryTransaction.test.js b/ui/app/hooks/tests/useRetryTransaction.test.js index 30f62ed56..91d99026d 100644 --- a/ui/app/hooks/tests/useRetryTransaction.test.js +++ b/ui/app/hooks/tests/useRetryTransaction.test.js @@ -43,7 +43,7 @@ describe('useRetryTransaction', function () { ) const retry = result.current retry(event) - assert.equal(trackEvent.calledOnce, true) + assert.strictEqual(trackEvent.calledOnce, true) }) it('retryTransaction function should show retry sidebar', async function () { @@ -52,7 +52,7 @@ describe('useRetryTransaction', function () { ) const retry = result.current await retry(event) - assert.equal( + assert.strictEqual( dispatch.calledWith( showSidebar({ transitionName: 'sidebar-left', diff --git a/ui/app/hooks/tests/useTokenData.test.js b/ui/app/hooks/tests/useTokenData.test.js index 373c84eb5..ec473300d 100644 --- a/ui/app/hooks/tests/useTokenData.test.js +++ b/ui/app/hooks/tests/useTokenData.test.js @@ -53,14 +53,14 @@ describe('useTokenData', function () { it(testTitle, function () { const { result } = renderHook(() => useTokenData(test.data)) if (test.tokenData) { - assert.equal(result.current.name, test.tokenData.name) - assert.equal( + assert.strictEqual(result.current.name, test.tokenData.name) + assert.strictEqual( result.current.args[0].toLowerCase(), test.tokenData.args[0], ) assert.ok(test.tokenData.args[1].eq(result.current.args[1])) } else { - assert.equal(result.current, test.tokenData) + assert.strictEqual(result.current, test.tokenData) } }) }) diff --git a/ui/app/hooks/tests/useTokenDisplayValue.test.js b/ui/app/hooks/tests/useTokenDisplayValue.test.js index e9ba328bd..bc77bd6c7 100644 --- a/ui/app/hooks/tests/useTokenDisplayValue.test.js +++ b/ui/app/hooks/tests/useTokenDisplayValue.test.js @@ -130,7 +130,7 @@ describe('useTokenDisplayValue', function () { useTokenDisplayValue(`${idx}-fakestring`, test.token), ) sinon.restore() - assert.equal(result.current, test.displayValue) + assert.strictEqual(result.current, test.displayValue) }) }) }) diff --git a/ui/app/hooks/tests/useTransactionDisplayData.test.js b/ui/app/hooks/tests/useTransactionDisplayData.test.js index cb7784620..00b2f5bb8 100644 --- a/ui/app/hooks/tests/useTransactionDisplayData.test.js +++ b/ui/app/hooks/tests/useTransactionDisplayData.test.js @@ -178,35 +178,38 @@ describe('useTransactionDisplayData', function () { () => useTransactionDisplayData(transactionGroup), tokenAddress, ) - assert.equal(result.current.title, expected.title) + assert.strictEqual(result.current.title, expected.title) }) it(`should return a subtitle of ${expected.subtitle}`, function () { const { result } = renderHookWithRouter( () => useTransactionDisplayData(transactionGroup), tokenAddress, ) - assert.equal(result.current.subtitle, expected.subtitle) + assert.strictEqual(result.current.subtitle, expected.subtitle) }) it(`should return a category of ${expected.category}`, function () { const { result } = renderHookWithRouter( () => useTransactionDisplayData(transactionGroup), tokenAddress, ) - assert.equal(result.current.category, expected.category) + assert.strictEqual(result.current.category, expected.category) }) it(`should return a primaryCurrency of ${expected.primaryCurrency}`, function () { const { result } = renderHookWithRouter( () => useTransactionDisplayData(transactionGroup), tokenAddress, ) - assert.equal(result.current.primaryCurrency, expected.primaryCurrency) + assert.strictEqual( + result.current.primaryCurrency, + expected.primaryCurrency, + ) }) it(`should return a secondaryCurrency of ${expected.secondaryCurrency}`, function () { const { result } = renderHookWithRouter( () => useTransactionDisplayData(transactionGroup), tokenAddress, ) - assert.equal( + assert.strictEqual( result.current.secondaryCurrency, expected.secondaryCurrency, ) @@ -216,7 +219,7 @@ describe('useTransactionDisplayData', function () { () => useTransactionDisplayData(transactionGroup), tokenAddress, ) - assert.equal( + assert.strictEqual( result.current.displayedStatusKey, expected.displayedStatusKey, ) @@ -226,14 +229,17 @@ describe('useTransactionDisplayData', function () { () => useTransactionDisplayData(transactionGroup), tokenAddress, ) - assert.equal(result.current.recipientAddress, expected.recipientAddress) + assert.strictEqual( + result.current.recipientAddress, + expected.recipientAddress, + ) }) it(`should return a senderAddress of ${expected.senderAddress}`, function () { const { result } = renderHookWithRouter( () => useTransactionDisplayData(transactionGroup), tokenAddress, ) - assert.equal(result.current.senderAddress, expected.senderAddress) + assert.strictEqual(result.current.senderAddress, expected.senderAddress) }) }) }) @@ -241,7 +247,7 @@ describe('useTransactionDisplayData', function () { const { result } = renderHookWithRouter(() => useTransactionDisplayData(transactions[0]), ) - assert.deepEqual(result.current, expectedResults[0]) + assert.deepStrictEqual(result.current, expectedResults[0]) }) after(function () { useSelector.restore() diff --git a/ui/app/hooks/tests/useUserPreferencedCurrency.test.js b/ui/app/hooks/tests/useUserPreferencedCurrency.test.js index 0b5534fdb..0386e6ec4 100644 --- a/ui/app/hooks/tests/useUserPreferencedCurrency.test.js +++ b/ui/app/hooks/tests/useUserPreferencedCurrency.test.js @@ -135,12 +135,12 @@ describe('useUserPreferencedCurrency', function () { it(`should return currency as ${ result.currency || 'not modified by user preferences' }`, function () { - assert.equal(hookResult.current.currency, result.currency) + assert.strictEqual(hookResult.current.currency, result.currency) }) it(`should return decimals as ${ result.numberOfDecimals || 'not modified by user preferences' }`, function () { - assert.equal( + assert.strictEqual( hookResult.current.numberOfDecimals, result.numberOfDecimals, ) diff --git a/ui/app/pages/add-token/tests/add-token.test.js b/ui/app/pages/add-token/tests/add-token.test.js index 300a6b019..697724dd7 100644 --- a/ui/app/pages/add-token/tests/add-token.test.js +++ b/ui/app/pages/add-token/tests/add-token.test.js @@ -49,7 +49,7 @@ describe('Add Token', function () { '.button.btn-secondary.page-container__footer-button', ) - assert.equal(nextButton.props().disabled, true) + assert.strictEqual(nextButton.props().disabled, true) }) it('edits token address', function () { @@ -58,7 +58,7 @@ describe('Add Token', function () { const customAddress = wrapper.find('input#custom-address') customAddress.simulate('change', event) - assert.equal( + assert.strictEqual( wrapper.find('AddToken').instance().state.customAddress, tokenAddress, ) @@ -70,7 +70,7 @@ describe('Add Token', function () { const customAddress = wrapper.find('#custom-symbol') customAddress.last().simulate('change', event) - assert.equal( + assert.strictEqual( wrapper.find('AddToken').instance().state.customSymbol, tokenSymbol, ) @@ -82,7 +82,7 @@ describe('Add Token', function () { const customAddress = wrapper.find('#custom-decimals') customAddress.last().simulate('change', event) - assert.equal( + assert.strictEqual( wrapper.find('AddToken').instance().state.customDecimals, tokenPrecision, ) @@ -96,7 +96,10 @@ describe('Add Token', function () { assert(props.setPendingTokens.calledOnce) assert(props.history.push.calledOnce) - assert.equal(props.history.push.getCall(0).args[0], '/confirm-add-token') + assert.strictEqual( + props.history.push.getCall(0).args[0], + '/confirm-add-token', + ) }) it('cancels', function () { @@ -106,7 +109,7 @@ describe('Add Token', function () { cancelButton.simulate('click') assert(props.clearPendingTokens.calledOnce) - assert.equal(props.history.push.getCall(0).args[0], '/') + assert.strictEqual(props.history.push.getCall(0).args[0], '/') }) }) }) diff --git a/ui/app/pages/confirm-transaction-base/tests/confirm-transaction-base.component.test.js b/ui/app/pages/confirm-transaction-base/tests/confirm-transaction-base.component.test.js index 3add429b6..96ddc2ff4 100644 --- a/ui/app/pages/confirm-transaction-base/tests/confirm-transaction-base.component.test.js +++ b/ui/app/pages/confirm-transaction-base/tests/confirm-transaction-base.component.test.js @@ -4,11 +4,11 @@ import { getMethodName } from '../confirm-transaction-base.component' describe('ConfirmTransactionBase Component', function () { describe('getMethodName', function () { it('should get correct method names', function () { - assert.equal(getMethodName(undefined), '') - assert.equal(getMethodName({}), '') - assert.equal(getMethodName('confirm'), 'confirm') - assert.equal(getMethodName('balanceOf'), 'balance Of') - assert.equal( + assert.strictEqual(getMethodName(undefined), '') + assert.strictEqual(getMethodName({}), '') + assert.strictEqual(getMethodName('confirm'), 'confirm') + assert.strictEqual(getMethodName('balanceOf'), 'balance Of') + assert.strictEqual( getMethodName('ethToTokenSwapInput'), 'eth To Token Swap Input', ) diff --git a/ui/app/pages/create-account/tests/create-account.test.js b/ui/app/pages/create-account/tests/create-account.test.js index a99ffa47f..335d3c5ba 100644 --- a/ui/app/pages/create-account/tests/create-account.test.js +++ b/ui/app/pages/create-account/tests/create-account.test.js @@ -27,18 +27,24 @@ describe('Create Account Page', function () { it('clicks create account and routes to new-account path', function () { const createAccount = wrapper.find('.new-account__tabs__tab').at(0) createAccount.simulate('click') - assert.equal(props.history.push.getCall(0).args[0], '/new-account') + assert.strictEqual(props.history.push.getCall(0).args[0], '/new-account') }) it('clicks import account and routes to import new account path', function () { const importAccount = wrapper.find('.new-account__tabs__tab').at(1) importAccount.simulate('click') - assert.equal(props.history.push.getCall(0).args[0], '/new-account/import') + assert.strictEqual( + props.history.push.getCall(0).args[0], + '/new-account/import', + ) }) it('clicks connect HD Wallet and routes to connect new account path', function () { const connectHdWallet = wrapper.find('.new-account__tabs__tab').at(2) connectHdWallet.simulate('click') - assert.equal(props.history.push.getCall(0).args[0], '/new-account/connect') + assert.strictEqual( + props.history.push.getCall(0).args[0], + '/new-account/connect', + ) }) }) diff --git a/ui/app/pages/first-time-flow/create-password/import-with-seed-phrase/tests/import-with-seed-phrase.component.test.js b/ui/app/pages/first-time-flow/create-password/import-with-seed-phrase/tests/import-with-seed-phrase.component.test.js index 2ec3b97dc..7aea35494 100644 --- a/ui/app/pages/first-time-flow/create-password/import-with-seed-phrase/tests/import-with-seed-phrase.component.test.js +++ b/ui/app/pages/first-time-flow/create-password/import-with-seed-phrase/tests/import-with-seed-phrase.component.test.js @@ -20,7 +20,7 @@ describe('ImportWithSeedPhrase Component', function () { onSubmit: sinon.spy(), }) const textareaCount = root.find('.first-time-flow__textarea').length - assert.equal(textareaCount, 1, 'should render 12 seed phrases') + assert.strictEqual(textareaCount, 1, 'should render 12 seed phrases') }) describe('parseSeedPhrase', function () { @@ -31,7 +31,7 @@ describe('ImportWithSeedPhrase Component', function () { const { parseSeedPhrase } = root.instance() - assert.deepEqual(parseSeedPhrase('foo bar baz'), 'foo bar baz') + assert.deepStrictEqual(parseSeedPhrase('foo bar baz'), 'foo bar baz') }) it('should handle a mixed-case seed phrase', function () { @@ -41,7 +41,7 @@ describe('ImportWithSeedPhrase Component', function () { const { parseSeedPhrase } = root.instance() - assert.deepEqual(parseSeedPhrase('FOO bAr baZ'), 'foo bar baz') + assert.deepStrictEqual(parseSeedPhrase('FOO bAr baZ'), 'foo bar baz') }) it('should handle an upper-case seed phrase', function () { @@ -51,7 +51,7 @@ describe('ImportWithSeedPhrase Component', function () { const { parseSeedPhrase } = root.instance() - assert.deepEqual(parseSeedPhrase('FOO BAR BAZ'), 'foo bar baz') + assert.deepStrictEqual(parseSeedPhrase('FOO BAR BAZ'), 'foo bar baz') }) it('should trim extraneous whitespace from the given seed phrase', function () { @@ -61,7 +61,10 @@ describe('ImportWithSeedPhrase Component', function () { const { parseSeedPhrase } = root.instance() - assert.deepEqual(parseSeedPhrase(' foo bar baz '), 'foo bar baz') + assert.deepStrictEqual( + parseSeedPhrase(' foo bar baz '), + 'foo bar baz', + ) }) it('should return an empty string when given a whitespace-only string', function () { @@ -71,7 +74,7 @@ describe('ImportWithSeedPhrase Component', function () { const { parseSeedPhrase } = root.instance() - assert.deepEqual(parseSeedPhrase(' '), '') + assert.deepStrictEqual(parseSeedPhrase(' '), '') }) it('should return an empty string when given a string with only symbols', function () { @@ -81,7 +84,7 @@ describe('ImportWithSeedPhrase Component', function () { const { parseSeedPhrase } = root.instance() - assert.deepEqual(parseSeedPhrase('$'), '') + assert.deepStrictEqual(parseSeedPhrase('$'), '') }) it('should return an empty string for both null and undefined', function () { @@ -91,8 +94,8 @@ describe('ImportWithSeedPhrase Component', function () { const { parseSeedPhrase } = root.instance() - assert.deepEqual(parseSeedPhrase(undefined), '') - assert.deepEqual(parseSeedPhrase(null), '') + assert.deepStrictEqual(parseSeedPhrase(undefined), '') + assert.deepStrictEqual(parseSeedPhrase(null), '') }) }) }) diff --git a/ui/app/pages/first-time-flow/end-of-flow/tests/end-of-flow.test.js b/ui/app/pages/first-time-flow/end-of-flow/tests/end-of-flow.test.js index ad7b0e7e1..aef4ef6a1 100644 --- a/ui/app/pages/first-time-flow/end-of-flow/tests/end-of-flow.test.js +++ b/ui/app/pages/first-time-flow/end-of-flow/tests/end-of-flow.test.js @@ -20,7 +20,7 @@ describe('End of Flow Screen', function () { }) it('renders', function () { - assert.equal(wrapper.length, 1) + assert.strictEqual(wrapper.length, 1) }) it('should navigate to the default route on click', function (done) { diff --git a/ui/app/pages/first-time-flow/first-time-flow-switch/tests/first-time-flow-switch.test.js b/ui/app/pages/first-time-flow/first-time-flow-switch/tests/first-time-flow-switch.test.js index 3ec0d1a61..fa3b9788f 100644 --- a/ui/app/pages/first-time-flow/first-time-flow-switch/tests/first-time-flow-switch.test.js +++ b/ui/app/pages/first-time-flow/first-time-flow-switch/tests/first-time-flow-switch.test.js @@ -21,7 +21,7 @@ describe('FirstTimeFlowSwitch', function () { const wrapper = mountWithRouter( , ) - assert.equal( + assert.strictEqual( wrapper .find('Lifecycle') .find({ to: { pathname: INITIALIZE_WELCOME_ROUTE } }).length, @@ -37,7 +37,7 @@ describe('FirstTimeFlowSwitch', function () { , ) - assert.equal( + assert.strictEqual( wrapper.find('Lifecycle').find({ to: { pathname: DEFAULT_ROUTE } }) .length, 1, @@ -53,7 +53,7 @@ describe('FirstTimeFlowSwitch', function () { , ) - assert.equal( + assert.strictEqual( wrapper .find('Lifecycle') .find({ to: { pathname: INITIALIZE_END_OF_FLOW_ROUTE } }).length, @@ -70,7 +70,7 @@ describe('FirstTimeFlowSwitch', function () { , ) - assert.equal( + assert.strictEqual( wrapper .find('Lifecycle') .find({ to: { pathname: INITIALIZE_END_OF_FLOW_ROUTE } }).length, @@ -89,7 +89,7 @@ describe('FirstTimeFlowSwitch', function () { , ) - assert.equal( + assert.strictEqual( wrapper.find('Lifecycle').find({ to: { pathname: LOCK_ROUTE } }).length, 1, ) @@ -107,7 +107,7 @@ describe('FirstTimeFlowSwitch', function () { , ) - assert.equal( + assert.strictEqual( wrapper .find('Lifecycle') .find({ to: { pathname: INITIALIZE_WELCOME_ROUTE } }).length, @@ -127,7 +127,7 @@ describe('FirstTimeFlowSwitch', function () { , ) - assert.equal( + assert.strictEqual( wrapper .find('Lifecycle') .find({ to: { pathname: INITIALIZE_UNLOCK_ROUTE } }).length, diff --git a/ui/app/pages/first-time-flow/seed-phrase/reveal-seed-phrase/tests/reveal-seed-phrase.test.js b/ui/app/pages/first-time-flow/seed-phrase/reveal-seed-phrase/tests/reveal-seed-phrase.test.js index 1c0950516..f0e561a4b 100644 --- a/ui/app/pages/first-time-flow/seed-phrase/reveal-seed-phrase/tests/reveal-seed-phrase.test.js +++ b/ui/app/pages/first-time-flow/seed-phrase/reveal-seed-phrase/tests/reveal-seed-phrase.test.js @@ -30,18 +30,18 @@ describe('Reveal Seed Phrase', function () { it('seed phrase', function () { const seedPhrase = wrapper.find('.reveal-seed-phrase__secret-words--hidden') - assert.equal(seedPhrase.length, 1) - assert.equal(seedPhrase.text(), TEST_SEED) + assert.strictEqual(seedPhrase.length, 1) + assert.strictEqual(seedPhrase.text(), TEST_SEED) }) it('clicks to reveal', function () { const reveal = wrapper.find('.reveal-seed-phrase__secret-blocker') - assert.equal(wrapper.state().isShowingSeedPhrase, false) + assert.strictEqual(wrapper.state().isShowingSeedPhrase, false) reveal.simulate('click') - assert.equal(wrapper.state().isShowingSeedPhrase, true) + assert.strictEqual(wrapper.state().isShowingSeedPhrase, true) const showSeed = wrapper.find('.reveal-seed-phrase__secret-words') - assert.equal(showSeed.length, 1) + assert.strictEqual(showSeed.length, 1) }) }) diff --git a/ui/app/pages/first-time-flow/seed-phrase/tests/confirm-seed-phrase-component.test.js b/ui/app/pages/first-time-flow/seed-phrase/tests/confirm-seed-phrase-component.test.js index a5a0d1c91..1be3b70d7 100644 --- a/ui/app/pages/first-time-flow/seed-phrase/tests/confirm-seed-phrase-component.test.js +++ b/ui/app/pages/first-time-flow/seed-phrase/tests/confirm-seed-phrase-component.test.js @@ -19,7 +19,7 @@ describe('ConfirmSeedPhrase Component', function () { seedPhrase: '鼠 牛 虎 兔 龍 蛇 馬 羊 猴 雞 狗 豬', }) - assert.equal( + assert.strictEqual( root.find('.confirm-seed-phrase__seed-word--sorted').length, 12, 'should render 12 seed phrases', @@ -46,7 +46,7 @@ describe('ConfirmSeedPhrase Component', function () { seeds.at(1).simulate('click') seeds.at(2).simulate('click') - assert.deepEqual( + assert.deepStrictEqual( root.state().selectedSeedIndices, [0, 1, 2], 'should add seed phrase to selected on click', @@ -57,7 +57,7 @@ describe('ConfirmSeedPhrase Component', function () { root.update() root.state() root.find('.confirm-seed-phrase__seed-word--sorted').at(1).simulate('click') - assert.deepEqual( + assert.deepStrictEqual( root.state().selectedSeedIndices, [0, 2], 'should remove seed phrase from selected when click again', @@ -94,9 +94,9 @@ describe('ConfirmSeedPhrase Component', function () { '.confirm-seed-phrase__selected-seed-words__pending-seed', ) - assert.equal(pendingSeeds.at(0).props().seedIndex, 2) - assert.equal(pendingSeeds.at(1).props().seedIndex, 0) - assert.equal(pendingSeeds.at(2).props().seedIndex, 1) + assert.strictEqual(pendingSeeds.at(0).props().seedIndex, 2) + assert.strictEqual(pendingSeeds.at(1).props().seedIndex, 0) + assert.strictEqual(pendingSeeds.at(2).props().seedIndex, 1) }) it('should insert seed in place on drop', function () { @@ -126,8 +126,8 @@ describe('ConfirmSeedPhrase Component', function () { root.update() - assert.deepEqual(root.state().selectedSeedIndices, [2, 0, 1]) - assert.deepEqual(root.state().pendingSeedIndices, [2, 0, 1]) + assert.deepStrictEqual(root.state().selectedSeedIndices, [2, 0, 1]) + assert.deepStrictEqual(root.state().pendingSeedIndices, [2, 0, 1]) }) it('should submit correctly', async function () { @@ -174,7 +174,7 @@ describe('ConfirmSeedPhrase Component', function () { await new Promise((resolve) => setTimeout(resolve, 100)) - assert.deepEqual(metricsEventSpy.args[0][0], { + assert.deepStrictEqual(metricsEventSpy.args[0][0], { eventOpts: { category: 'Onboarding', action: 'Seed Phrase Setup', @@ -182,6 +182,6 @@ describe('ConfirmSeedPhrase Component', function () { }, }) assert(initialize3BoxSpy.calledOnce) - assert.equal(pushSpy.args[0][0], '/initialize/end-of-flow') + assert.strictEqual(pushSpy.args[0][0], '/initialize/end-of-flow') }) }) diff --git a/ui/app/pages/first-time-flow/select-action/tests/select-action.test.js b/ui/app/pages/first-time-flow/select-action/tests/select-action.test.js index d8abdd135..447c20602 100644 --- a/ui/app/pages/first-time-flow/select-action/tests/select-action.test.js +++ b/ui/app/pages/first-time-flow/select-action/tests/select-action.test.js @@ -31,7 +31,7 @@ describe('Selection Action', function () { importWalletButton.simulate('click') assert(props.setFirstTimeFlowType.calledOnce) - assert.equal(props.setFirstTimeFlowType.getCall(0).args[0], 'import') + assert.strictEqual(props.setFirstTimeFlowType.getCall(0).args[0], 'import') assert(props.history.push.calledOnce) }) @@ -42,7 +42,7 @@ describe('Selection Action', function () { createWalletButton.simulate('click') assert(props.setFirstTimeFlowType.calledOnce) - assert.equal(props.setFirstTimeFlowType.getCall(0).args[0], 'create') + assert.strictEqual(props.setFirstTimeFlowType.getCall(0).args[0], 'create') assert(props.history.push.calledOnce) }) }) diff --git a/ui/app/pages/first-time-flow/welcome/tests/welcome.test.js b/ui/app/pages/first-time-flow/welcome/tests/welcome.test.js index 67df69c14..4c35d8c0d 100644 --- a/ui/app/pages/first-time-flow/welcome/tests/welcome.test.js +++ b/ui/app/pages/first-time-flow/welcome/tests/welcome.test.js @@ -32,7 +32,7 @@ describe('Welcome', function () { '.btn-primary.first-time-flow__button', ) getStartedButton.simulate('click') - assert.equal( + assert.strictEqual( props.history.push.getCall(0).args[0], '/initialize/select-action', ) @@ -56,7 +56,7 @@ describe('Welcome', function () { '.btn-primary.first-time-flow__button', ) getStartedButton.simulate('click') - assert.equal( + assert.strictEqual( props.history.push.getCall(0).args[0], '/initialize/create-password', ) diff --git a/ui/app/pages/lock/tests/lock.test.js b/ui/app/pages/lock/tests/lock.test.js index 92a46af6e..688fe062a 100644 --- a/ui/app/pages/lock/tests/lock.test.js +++ b/ui/app/pages/lock/tests/lock.test.js @@ -15,7 +15,7 @@ describe('Lock', function () { mountWithRouter() - assert.equal(props.history.replace.getCall(0).args[0], '/') + assert.strictEqual(props.history.replace.getCall(0).args[0], '/') }) it('locks and pushes history with default route when isUnlocked true', function (done) { @@ -33,7 +33,7 @@ describe('Lock', function () { assert(props.lockMetamask.calledOnce) setImmediate(() => { - assert.equal(props.history.push.getCall(0).args[0], '/') + assert.strictEqual(props.history.push.getCall(0).args[0], '/') done() }) }) diff --git a/ui/app/pages/send/send-content/add-recipient/tests/add-recipient-component.test.js b/ui/app/pages/send/send-content/add-recipient/tests/add-recipient-component.test.js index 40f3b6a9c..fddaf3da7 100644 --- a/ui/app/pages/send/send-content/add-recipient/tests/add-recipient-component.test.js +++ b/ui/app/pages/send/send-content/add-recipient/tests/add-recipient-component.test.js @@ -68,25 +68,28 @@ describe('AddRecipient Component', function () { describe('selectRecipient', function () { it('should call updateSendTo', function () { - assert.equal(propsMethodSpies.updateSendTo.callCount, 0) + assert.strictEqual(propsMethodSpies.updateSendTo.callCount, 0) instance.selectRecipient('mockTo2', 'mockNickname') - assert.equal(propsMethodSpies.updateSendTo.callCount, 1) - assert.deepEqual(propsMethodSpies.updateSendTo.getCall(0).args, [ + assert.strictEqual(propsMethodSpies.updateSendTo.callCount, 1) + assert.deepStrictEqual(propsMethodSpies.updateSendTo.getCall(0).args, [ 'mockTo2', 'mockNickname', ]) }) it('should call updateGas if there is no to error', function () { - assert.equal(propsMethodSpies.updateGas.callCount, 0) + assert.strictEqual(propsMethodSpies.updateGas.callCount, 0) instance.selectRecipient(false) - assert.equal(propsMethodSpies.updateGas.callCount, 1) + assert.strictEqual(propsMethodSpies.updateGas.callCount, 1) }) }) describe('render', function () { it('should render a component', function () { - assert.equal(wrapper.find('.send__select-recipient-wrapper').length, 1) + assert.strictEqual( + wrapper.find('.send__select-recipient-wrapper').length, + 1, + ) }) it('should render no content if there are no recents, transfers, and contacts', function () { @@ -95,11 +98,11 @@ describe('AddRecipient Component', function () { addressBook: [], }) - assert.equal( + assert.strictEqual( wrapper.find('.send__select-recipient-wrapper__list__link').length, 0, ) - assert.equal( + assert.strictEqual( wrapper.find('.send__select-recipient-wrapper__group').length, 0, ) @@ -118,10 +121,10 @@ describe('AddRecipient Component', function () { const xferLink = wrapper.find( '.send__select-recipient-wrapper__list__link', ) - assert.equal(xferLink.length, 1) + assert.strictEqual(xferLink.length, 1) const groups = wrapper.find('RecipientGroup') - assert.equal( + assert.strictEqual( groups.shallow().find('.send__select-recipient-wrapper__group').length, 1, ) @@ -138,7 +141,7 @@ describe('AddRecipient Component', function () { const contactList = wrapper.find('ContactList') - assert.equal(contactList.length, 1) + assert.strictEqual(contactList.length, 1) }) it('should render contacts', function () { @@ -154,12 +157,12 @@ describe('AddRecipient Component', function () { const xferLink = wrapper.find( '.send__select-recipient-wrapper__list__link', ) - assert.equal(xferLink.length, 0) + assert.strictEqual(xferLink.length, 0) const groups = wrapper.find('ContactList') - assert.equal(groups.length, 1) + assert.strictEqual(groups.length, 1) - assert.equal( + assert.strictEqual( groups.find('.send__select-recipient-wrapper__group-item').length, 0, ) @@ -175,9 +178,9 @@ describe('AddRecipient Component', function () { const dialog = wrapper.find(Dialog) - assert.equal(dialog.props().type, 'error') - assert.equal(dialog.props().children, 'bad_t') - assert.equal(dialog.length, 1) + assert.strictEqual(dialog.props().type, 'error') + assert.strictEqual(dialog.props().children, 'bad_t') + assert.strictEqual(dialog.length, 1) }) it('should render error when query has ens does not resolve', function () { @@ -191,9 +194,9 @@ describe('AddRecipient Component', function () { const dialog = wrapper.find(Dialog) - assert.equal(dialog.props().type, 'error') - assert.equal(dialog.props().children, 'very bad') - assert.equal(dialog.length, 1) + assert.strictEqual(dialog.props().type, 'error') + assert.strictEqual(dialog.props().children, 'very bad') + assert.strictEqual(dialog.length, 1) }) it('should not render error when ens resolved', function () { @@ -205,7 +208,7 @@ describe('AddRecipient Component', function () { const dialog = wrapper.find(Dialog) - assert.equal(dialog.length, 0) + assert.strictEqual(dialog.length, 0) }) it('should not render error when query has results', function () { @@ -220,7 +223,7 @@ describe('AddRecipient Component', function () { const dialog = wrapper.find(Dialog) - assert.equal(dialog.length, 0) + assert.strictEqual(dialog.length, 0) }) }) }) diff --git a/ui/app/pages/send/send-content/add-recipient/tests/add-recipient-container.test.js b/ui/app/pages/send/send-content/add-recipient/tests/add-recipient-container.test.js index b7502bf52..f488b2f4e 100644 --- a/ui/app/pages/send/send-content/add-recipient/tests/add-recipient-container.test.js +++ b/ui/app/pages/send/send-content/add-recipient/tests/add-recipient-container.test.js @@ -33,7 +33,7 @@ proxyquire('../add-recipient.container.js', { describe('add-recipient container', function () { describe('mapStateToProps()', function () { it('should map the correct properties to props', function () { - assert.deepEqual(mapStateToProps('mockState'), { + assert.deepStrictEqual(mapStateToProps('mockState'), { addressBook: [{ name: 'mockAddressBook:mockState' }], contacts: [{ name: 'mockAddressBook:mockState' }], ensResolution: 'mockSendEnsResolution:mockState', @@ -57,7 +57,7 @@ describe('add-recipient container', function () { mapDispatchToPropsObject.updateSendTo('mockTo', 'mockNickname') assert(dispatchSpy.calledOnce) assert(actionSpies.updateSendTo.calledOnce) - assert.deepEqual(actionSpies.updateSendTo.getCall(0).args, [ + assert.deepStrictEqual(actionSpies.updateSendTo.getCall(0).args, [ 'mockTo', 'mockNickname', ]) diff --git a/ui/app/pages/send/send-content/add-recipient/tests/add-recipient-utils.test.js b/ui/app/pages/send/send-content/add-recipient/tests/add-recipient-utils.test.js index e0972b36c..bfd83cbd7 100644 --- a/ui/app/pages/send/send-content/add-recipient/tests/add-recipient-utils.test.js +++ b/ui/app/pages/send/send-content/add-recipient/tests/add-recipient-utils.test.js @@ -24,25 +24,25 @@ const { getToErrorObject, getToWarningObject } = toRowUtils describe('add-recipient utils', function () { describe('getToErrorObject()', function () { it('should return a required error if "to" is falsy', function () { - assert.deepEqual(getToErrorObject(null), { + assert.deepStrictEqual(getToErrorObject(null), { to: REQUIRED_ERROR, }) }) it('should return null if "to" is falsy and hexData is truthy', function () { - assert.deepEqual(getToErrorObject(null, true), { + assert.deepStrictEqual(getToErrorObject(null, true), { to: null, }) }) it('should return an invalid recipient error if "to" is truthy but invalid', function () { - assert.deepEqual(getToErrorObject('mockInvalidTo'), { + assert.deepStrictEqual(getToErrorObject('mockInvalidTo'), { to: INVALID_RECIPIENT_ADDRESS_ERROR, }) }) it('should return null if "to" is truthy and valid', function () { - assert.deepEqual(getToErrorObject('0xabc123'), { + assert.deepStrictEqual(getToErrorObject('0xabc123'), { to: null, }) }) @@ -50,7 +50,7 @@ describe('add-recipient utils', function () { describe('getToWarningObject()', function () { it('should return a known address recipient error if "to" is a token address', function () { - assert.deepEqual( + assert.deepStrictEqual( getToWarningObject('0xabc123', [{ address: '0xabc123' }], { address: '0xabc123', }), @@ -61,7 +61,7 @@ describe('add-recipient utils', function () { }) it('should null if "to" is a token address but sendToken is falsy', function () { - assert.deepEqual( + assert.deepStrictEqual( getToWarningObject('0xabc123', [{ address: '0xabc123' }]), { to: null, @@ -70,7 +70,7 @@ describe('add-recipient utils', function () { }) it('should return a known address recipient error if "to" is part of contract metadata', function () { - assert.deepEqual( + assert.deepStrictEqual( getToWarningObject( '0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359', [{ address: '0xabc123' }], @@ -82,7 +82,7 @@ describe('add-recipient utils', function () { ) }) it('should null if "to" is part of contract metadata but sendToken is falsy', function () { - assert.deepEqual( + assert.deepStrictEqual( getToWarningObject( '0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359', [{ address: '0xabc123' }], diff --git a/ui/app/pages/send/send-content/send-amount-row/amount-max-button/tests/amount-max-button-component.test.js b/ui/app/pages/send/send-content/send-amount-row/amount-max-button/tests/amount-max-button-component.test.js index f56aa6e12..fb040de64 100644 --- a/ui/app/pages/send/send-content/send-amount-row/amount-max-button/tests/amount-max-button-component.test.js +++ b/ui/app/pages/send/send-content/send-amount-row/amount-max-button/tests/amount-max-button-component.test.js @@ -52,10 +52,10 @@ describe('AmountMaxButton Component', function () { describe('setMaxAmount', function () { it('should call setAmountToMax with the correct params', function () { - assert.equal(propsMethodSpies.setAmountToMax.callCount, 0) + assert.strictEqual(propsMethodSpies.setAmountToMax.callCount, 0) instance.setMaxAmount() - assert.equal(propsMethodSpies.setAmountToMax.callCount, 1) - assert.deepEqual(propsMethodSpies.setAmountToMax.getCall(0).args, [ + assert.strictEqual(propsMethodSpies.setAmountToMax.callCount, 1) + assert.deepStrictEqual(propsMethodSpies.setAmountToMax.getCall(0).args, [ { balance: 'mockBalance', gasTotal: 'mockGasTotal', @@ -74,17 +74,19 @@ describe('AmountMaxButton Component', function () { it('should call setMaxModeTo and setMaxAmount when the checkbox is checked', function () { const { onClick } = wrapper.find('.send-v2__amount-max').props() - assert.equal(AmountMaxButton.prototype.setMaxAmount.callCount, 0) - assert.equal(propsMethodSpies.setMaxModeTo.callCount, 0) + assert.strictEqual(AmountMaxButton.prototype.setMaxAmount.callCount, 0) + assert.strictEqual(propsMethodSpies.setMaxModeTo.callCount, 0) onClick(MOCK_EVENT) - assert.equal(AmountMaxButton.prototype.setMaxAmount.callCount, 1) - assert.equal(propsMethodSpies.setMaxModeTo.callCount, 1) - assert.deepEqual(propsMethodSpies.setMaxModeTo.getCall(0).args, [true]) + assert.strictEqual(AmountMaxButton.prototype.setMaxAmount.callCount, 1) + assert.strictEqual(propsMethodSpies.setMaxModeTo.callCount, 1) + assert.deepStrictEqual(propsMethodSpies.setMaxModeTo.getCall(0).args, [ + true, + ]) }) it('should render the expected text when maxModeOn is false', function () { wrapper.setProps({ maxModeOn: false }) - assert.equal(wrapper.find('.send-v2__amount-max').text(), 'max_t') + assert.strictEqual(wrapper.find('.send-v2__amount-max').text(), 'max_t') }) }) }) diff --git a/ui/app/pages/send/send-content/send-amount-row/amount-max-button/tests/amount-max-button-container.test.js b/ui/app/pages/send/send-content/send-amount-row/amount-max-button/tests/amount-max-button-container.test.js index ac49eea81..ba5325a43 100644 --- a/ui/app/pages/send/send-content/send-amount-row/amount-max-button/tests/amount-max-button-container.test.js +++ b/ui/app/pages/send/send-content/send-amount-row/amount-max-button/tests/amount-max-button-container.test.js @@ -39,7 +39,7 @@ proxyquire('../amount-max-button.container.js', { describe('amount-max-button container', function () { describe('mapStateToProps()', function () { it('should map the correct properties to props', function () { - assert.deepEqual(mapStateToProps('mockState'), { + assert.deepStrictEqual(mapStateToProps('mockState'), { balance: 'mockBalance:mockState', buttonDataLoading: 'mockButtonDataLoading:mockState', gasTotal: 'mockGasTotal:mockState', @@ -64,11 +64,14 @@ describe('amount-max-button container', function () { mapDispatchToPropsObject.setAmountToMax({ val: 11, foo: 'bar' }) assert(dispatchSpy.calledTwice) assert(duckActionSpies.updateSendErrors.calledOnce) - assert.deepEqual(duckActionSpies.updateSendErrors.getCall(0).args[0], { - amount: null, - }) + assert.deepStrictEqual( + duckActionSpies.updateSendErrors.getCall(0).args[0], + { + amount: null, + }, + ) assert(actionSpies.updateSendAmount.calledOnce) - assert.equal(actionSpies.updateSendAmount.getCall(0).args[0], 12) + assert.strictEqual(actionSpies.updateSendAmount.getCall(0).args[0], 12) }) }) @@ -76,7 +79,10 @@ describe('amount-max-button container', function () { it('should dispatch an action', function () { mapDispatchToPropsObject.setMaxModeTo('mockVal') assert(dispatchSpy.calledOnce) - assert.equal(actionSpies.setMaxModeTo.getCall(0).args[0], 'mockVal') + assert.strictEqual( + actionSpies.setMaxModeTo.getCall(0).args[0], + 'mockVal', + ) }) }) }) diff --git a/ui/app/pages/send/send-content/send-amount-row/amount-max-button/tests/amount-max-button-utils.test.js b/ui/app/pages/send/send-content/send-amount-row/amount-max-button/tests/amount-max-button-utils.test.js index d103525f3..c99f0449c 100644 --- a/ui/app/pages/send/send-content/send-amount-row/amount-max-button/tests/amount-max-button-utils.test.js +++ b/ui/app/pages/send/send-content/send-amount-row/amount-max-button/tests/amount-max-button-utils.test.js @@ -4,7 +4,7 @@ import { calcMaxAmount } from '../amount-max-button.utils' describe('amount-max-button utils', function () { describe('calcMaxAmount()', function () { it('should calculate the correct amount when no sendToken defined', function () { - assert.deepEqual( + assert.deepStrictEqual( calcMaxAmount({ balance: 'ffffff', gasTotal: 'ff', @@ -15,7 +15,7 @@ describe('amount-max-button utils', function () { }) it('should calculate the correct amount when a sendToken is defined', function () { - assert.deepEqual( + assert.deepStrictEqual( calcMaxAmount({ sendToken: { decimals: 10, diff --git a/ui/app/pages/send/send-content/send-amount-row/tests/send-amount-row-component.test.js b/ui/app/pages/send/send-content/send-amount-row/tests/send-amount-row-component.test.js index 80e7b45a2..27c4b3bd9 100644 --- a/ui/app/pages/send/send-content/send-amount-row/tests/send-amount-row-component.test.js +++ b/ui/app/pages/send/send-content/send-amount-row/tests/send-amount-row-component.test.js @@ -16,7 +16,7 @@ describe('SendAmountRow Component', function () { propsMethodSpies: { updateSendAmountError }, } = shallowRenderSendAmountRow() - assert.equal(updateSendAmountError.callCount, 0) + assert.strictEqual(updateSendAmountError.callCount, 0) instance.validateAmount('someAmount') @@ -39,7 +39,7 @@ describe('SendAmountRow Component', function () { propsMethodSpies: { updateGasFeeError }, } = shallowRenderSendAmountRow() - assert.equal(updateGasFeeError.callCount, 0) + assert.strictEqual(updateGasFeeError.callCount, 0) instance.validateAmount('someAmount') @@ -64,11 +64,11 @@ describe('SendAmountRow Component', function () { wrapper.setProps({ sendToken: null }) - assert.equal(updateGasFeeError.callCount, 0) + assert.strictEqual(updateGasFeeError.callCount, 0) instance.validateAmount('someAmount') - assert.equal(updateGasFeeError.callCount, 0) + assert.strictEqual(updateGasFeeError.callCount, 0) }) }) @@ -79,7 +79,7 @@ describe('SendAmountRow Component', function () { propsMethodSpies: { setMaxModeTo }, } = shallowRenderSendAmountRow() - assert.equal(setMaxModeTo.callCount, 0) + assert.strictEqual(setMaxModeTo.callCount, 0) instance.updateAmount('someAmount') @@ -92,7 +92,7 @@ describe('SendAmountRow Component', function () { propsMethodSpies: { updateSendAmount }, } = shallowRenderSendAmountRow() - assert.equal(updateSendAmount.callCount, 0) + assert.strictEqual(updateSendAmount.callCount, 0) instance.updateAmount('someAmount') @@ -104,7 +104,7 @@ describe('SendAmountRow Component', function () { it('should render a SendRowWrapper component', function () { const { wrapper } = shallowRenderSendAmountRow() - assert.equal(wrapper.find(SendRowWrapper).length, 1) + assert.strictEqual(wrapper.find(SendRowWrapper).length, 1) }) it('should pass the correct props to SendRowWrapper', function () { @@ -113,9 +113,9 @@ describe('SendAmountRow Component', function () { .find(SendRowWrapper) .props() - assert.equal(errorType, 'amount') - assert.equal(label, 'amount_t:') - assert.equal(showError, false) + assert.strictEqual(errorType, 'amount') + assert.strictEqual(label, 'amount_t:') + assert.strictEqual(showError, false) }) it('should render an AmountMaxButton as the first child of the SendRowWrapper', function () { @@ -142,11 +142,11 @@ describe('SendAmountRow Component', function () { .childAt(1) .props() - assert.equal(error, false) - assert.equal(value, 'mockAmount') - assert.equal(updateGas.callCount, 0) - assert.equal(updateAmount.callCount, 0) - assert.equal(validateAmount.callCount, 0) + assert.strictEqual(error, false) + assert.strictEqual(value, 'mockAmount') + assert.strictEqual(updateGas.callCount, 0) + assert.strictEqual(updateAmount.callCount, 0) + assert.strictEqual(validateAmount.callCount, 0) onChange('mockNewAmount') diff --git a/ui/app/pages/send/send-content/send-amount-row/tests/send-amount-row-container.test.js b/ui/app/pages/send/send-content/send-amount-row/tests/send-amount-row-container.test.js index 8b7dc5b8e..3137ef1b4 100644 --- a/ui/app/pages/send/send-content/send-amount-row/tests/send-amount-row-container.test.js +++ b/ui/app/pages/send/send-content/send-amount-row/tests/send-amount-row-container.test.js @@ -50,7 +50,10 @@ describe('send-amount-row container', function () { mapDispatchToPropsObject.setMaxModeTo('mockBool') assert(dispatchSpy.calledOnce) assert(actionSpies.setMaxModeTo.calledOnce) - assert.equal(actionSpies.setMaxModeTo.getCall(0).args[0], 'mockBool') + assert.strictEqual( + actionSpies.setMaxModeTo.getCall(0).args[0], + 'mockBool', + ) }) }) @@ -59,7 +62,7 @@ describe('send-amount-row container', function () { mapDispatchToPropsObject.updateSendAmount('mockAmount') assert(dispatchSpy.calledOnce) assert(actionSpies.updateSendAmount.calledOnce) - assert.equal( + assert.strictEqual( actionSpies.updateSendAmount.getCall(0).args[0], 'mockAmount', ) @@ -71,10 +74,13 @@ describe('send-amount-row container', function () { mapDispatchToPropsObject.updateGasFeeError({ some: 'data' }) assert(dispatchSpy.calledOnce) assert(duckActionSpies.updateSendErrors.calledOnce) - assert.deepEqual(duckActionSpies.updateSendErrors.getCall(0).args[0], { - some: 'data', - mockGasFeeErrorChange: true, - }) + assert.deepStrictEqual( + duckActionSpies.updateSendErrors.getCall(0).args[0], + { + some: 'data', + mockGasFeeErrorChange: true, + }, + ) }) }) @@ -83,10 +89,13 @@ describe('send-amount-row container', function () { mapDispatchToPropsObject.updateSendAmountError({ some: 'data' }) assert(dispatchSpy.calledOnce) assert(duckActionSpies.updateSendErrors.calledOnce) - assert.deepEqual(duckActionSpies.updateSendErrors.getCall(0).args[0], { - some: 'data', - mockChange: true, - }) + assert.deepStrictEqual( + duckActionSpies.updateSendErrors.getCall(0).args[0], + { + some: 'data', + mockChange: true, + }, + ) }) }) }) diff --git a/ui/app/pages/send/send-content/send-gas-row/gas-fee-display/tests/gas-fee-display.component.test.js b/ui/app/pages/send/send-content/send-gas-row/gas-fee-display/tests/gas-fee-display.component.test.js index 2dd085a38..817c324ea 100644 --- a/ui/app/pages/send/send-content/send-gas-row/gas-fee-display/tests/gas-fee-display.component.test.js +++ b/ui/app/pages/send/send-content/send-gas-row/gas-fee-display/tests/gas-fee-display.component.test.js @@ -33,7 +33,7 @@ describe('GasFeeDisplay Component', function () { }) it('should render a CurrencyDisplay component', function () { - assert.equal(wrapper.find(UserPreferencedCurrencyDisplay).length, 2) + assert.strictEqual(wrapper.find(UserPreferencedCurrencyDisplay).length, 2) }) it('should render the CurrencyDisplay with the correct props', function () { @@ -41,20 +41,20 @@ describe('GasFeeDisplay Component', function () { .find(UserPreferencedCurrencyDisplay) .at(0) .props() - assert.equal(type, 'PRIMARY') - assert.equal(value, 'mockGasTotal') + assert.strictEqual(type, 'PRIMARY') + assert.strictEqual(value, 'mockGasTotal') }) it('should render the reset button with the correct props', function () { const { onClick, className } = wrapper.find('button').props() - assert.equal(className, 'gas-fee-reset') - assert.equal(propsMethodSpies.onReset.callCount, 0) + assert.strictEqual(className, 'gas-fee-reset') + assert.strictEqual(propsMethodSpies.onReset.callCount, 0) onClick() - assert.equal(propsMethodSpies.onReset.callCount, 1) + assert.strictEqual(propsMethodSpies.onReset.callCount, 1) }) it('should render the reset button with the correct text', function () { - assert.equal(wrapper.find('button').text(), 'reset_t') + assert.strictEqual(wrapper.find('button').text(), 'reset_t') }) }) }) diff --git a/ui/app/pages/send/send-content/send-gas-row/tests/send-gas-row-component.test.js b/ui/app/pages/send/send-content/send-gas-row/tests/send-gas-row-component.test.js index a80671c5f..926e9ae02 100644 --- a/ui/app/pages/send/send-content/send-gas-row/tests/send-gas-row-component.test.js +++ b/ui/app/pages/send/send-content/send-gas-row/tests/send-gas-row-component.test.js @@ -43,8 +43,8 @@ describe('SendGasRow Component', function () { }) it('should render a SendRowWrapper component', function () { - assert.equal(wrapper.name(), 'Fragment') - assert.equal(wrapper.at(0).find(SendRowWrapper).length, 1) + assert.strictEqual(wrapper.name(), 'Fragment') + assert.strictEqual(wrapper.at(0).find(SendRowWrapper).length, 1) }) it('should pass the correct props to SendRowWrapper', function () { @@ -53,9 +53,9 @@ describe('SendGasRow Component', function () { .first() .props() - assert.equal(label, 'transactionFee_t:') - assert.equal(showError, true) - assert.equal(errorType, 'gasFee') + assert.strictEqual(label, 'transactionFee_t:') + assert.strictEqual(showError, true) + assert.strictEqual(errorType, 'gasFee') }) it('should render a GasFeeDisplay as a child of the SendRowWrapper', function () { @@ -68,27 +68,27 @@ describe('SendGasRow Component', function () { .first() .childAt(0) .props() - assert.equal(gasLoadingError, false) - assert.equal(gasTotal, 'mockGasTotal') - assert.equal(propsMethodSpies.resetGasButtons.callCount, 0) + assert.strictEqual(gasLoadingError, false) + assert.strictEqual(gasTotal, 'mockGasTotal') + assert.strictEqual(propsMethodSpies.resetGasButtons.callCount, 0) onReset() - assert.equal(propsMethodSpies.resetGasButtons.callCount, 1) + assert.strictEqual(propsMethodSpies.resetGasButtons.callCount, 1) }) it('should render the GasPriceButtonGroup if gasButtonGroupShown is true', function () { wrapper.setProps({ gasButtonGroupShown: true }) const rendered = wrapper.find(SendRowWrapper).first().childAt(0) - assert.equal(wrapper.children().length, 2) + assert.strictEqual(wrapper.children().length, 2) const gasPriceButtonGroup = rendered.childAt(0) assert(gasPriceButtonGroup.is(GasPriceButtonGroup)) assert(gasPriceButtonGroup.hasClass('gas-price-button-group--small')) - assert.equal(gasPriceButtonGroup.props().showCheck, false) - assert.equal( + assert.strictEqual(gasPriceButtonGroup.props().showCheck, false) + assert.strictEqual( gasPriceButtonGroup.props().someGasPriceButtonGroupProp, 'foo', ) - assert.equal( + assert.strictEqual( gasPriceButtonGroup.props().anotherGasPriceButtonGroupProp, 'bar', ) @@ -97,14 +97,14 @@ describe('SendGasRow Component', function () { it('should render an advanced options button if gasButtonGroupShown is true', function () { wrapper.setProps({ gasButtonGroupShown: true }) const rendered = wrapper.find(SendRowWrapper).last() - assert.equal(wrapper.children().length, 2) + assert.strictEqual(wrapper.children().length, 2) const advancedOptionsButton = rendered.childAt(0) - assert.equal(advancedOptionsButton.text(), 'advancedOptions_t') + assert.strictEqual(advancedOptionsButton.text(), 'advancedOptions_t') - assert.equal(propsMethodSpies.showCustomizeGasModal.callCount, 0) + assert.strictEqual(propsMethodSpies.showCustomizeGasModal.callCount, 0) advancedOptionsButton.props().onClick() - assert.equal(propsMethodSpies.showCustomizeGasModal.callCount, 1) + assert.strictEqual(propsMethodSpies.showCustomizeGasModal.callCount, 1) }) }) }) diff --git a/ui/app/pages/send/send-content/send-row-wrapper/send-row-error-message/tests/send-row-error-message-component.test.js b/ui/app/pages/send/send-content/send-row-wrapper/send-row-error-message/tests/send-row-error-message-component.test.js index 975b26748..41d318ffd 100644 --- a/ui/app/pages/send/send-content/send-row-wrapper/send-row-error-message/tests/send-row-error-message-component.test.js +++ b/ui/app/pages/send/send-content/send-row-wrapper/send-row-error-message/tests/send-row-error-message-component.test.js @@ -18,16 +18,16 @@ describe('SendRowErrorMessage Component', function () { }) it('should render null if the passed errors do not contain an error of errorType', function () { - assert.equal(wrapper.find('.send-v2__error').length, 0) - assert.equal(wrapper.html(), null) + assert.strictEqual(wrapper.find('.send-v2__error').length, 0) + assert.strictEqual(wrapper.html(), null) }) it('should render an error message if the passed errors contain an error of errorType', function () { wrapper.setProps({ errors: { error1: 'abc', error2: 'def', error3: 'xyz' }, }) - assert.equal(wrapper.find('.send-v2__error').length, 1) - assert.equal(wrapper.find('.send-v2__error').text(), 'xyz_t') + assert.strictEqual(wrapper.find('.send-v2__error').length, 1) + assert.strictEqual(wrapper.find('.send-v2__error').text(), 'xyz_t') }) }) }) diff --git a/ui/app/pages/send/send-content/send-row-wrapper/send-row-error-message/tests/send-row-error-message-container.test.js b/ui/app/pages/send/send-content/send-row-wrapper/send-row-error-message/tests/send-row-error-message-container.test.js index c85b50bfd..dd3a4da8f 100644 --- a/ui/app/pages/send/send-content/send-row-wrapper/send-row-error-message/tests/send-row-error-message-container.test.js +++ b/ui/app/pages/send/send-content/send-row-wrapper/send-row-error-message/tests/send-row-error-message-container.test.js @@ -16,7 +16,7 @@ proxyquire('../send-row-error-message.container.js', { describe('send-row-error-message container', function () { describe('mapStateToProps()', function () { it('should map the correct properties to props', function () { - assert.deepEqual( + assert.deepStrictEqual( mapStateToProps('mockState', { errorType: 'someType' }), { errors: 'mockErrors:mockState', diff --git a/ui/app/pages/send/send-content/send-row-wrapper/tests/send-row-wrapper-component.test.js b/ui/app/pages/send/send-content/send-row-wrapper/tests/send-row-wrapper-component.test.js index c2aa7c1f1..4a4b3189a 100644 --- a/ui/app/pages/send/send-content/send-row-wrapper/tests/send-row-wrapper-component.test.js +++ b/ui/app/pages/send/send-content/send-row-wrapper/tests/send-row-wrapper-component.test.js @@ -22,22 +22,22 @@ describe('SendContent Component', function () { }) it('should render a div with a send-v2__form-row class', function () { - assert.equal(wrapper.find('div.send-v2__form-row').length, 1) + assert.strictEqual(wrapper.find('div.send-v2__form-row').length, 1) }) it('should render two children of the root div, with send-v2_form label and field classes', function () { - assert.equal( + assert.strictEqual( wrapper.find('.send-v2__form-row > .send-v2__form-label').length, 1, ) - assert.equal( + assert.strictEqual( wrapper.find('.send-v2__form-row > .send-v2__form-field').length, 1, ) }) it('should render the label as a child of the send-v2__form-label', function () { - assert.equal( + assert.strictEqual( wrapper .find('.send-v2__form-row > .send-v2__form-label') .childAt(0) @@ -47,7 +47,7 @@ describe('SendContent Component', function () { }) it('should render its first child as a child of the send-v2__form-field', function () { - assert.equal( + assert.strictEqual( wrapper .find('.send-v2__form-row > .send-v2__form-field') .childAt(0) @@ -57,18 +57,18 @@ describe('SendContent Component', function () { }) it('should not render a SendRowErrorMessage if showError is false', function () { - assert.equal(wrapper.find(SendRowErrorMessage).length, 0) + assert.strictEqual(wrapper.find(SendRowErrorMessage).length, 0) }) it('should render a SendRowErrorMessage with and errorType props if showError is true', function () { wrapper.setProps({ showError: true }) - assert.equal(wrapper.find(SendRowErrorMessage).length, 1) + assert.strictEqual(wrapper.find(SendRowErrorMessage).length, 1) const expectedSendRowErrorMessage = wrapper .find('.send-v2__form-row > .send-v2__form-label') .childAt(1) assert(expectedSendRowErrorMessage.is(SendRowErrorMessage)) - assert.deepEqual(expectedSendRowErrorMessage.props(), { + assert.deepStrictEqual(expectedSendRowErrorMessage.props(), { errorType: 'mockErrorType', }) }) @@ -84,7 +84,7 @@ describe('SendContent Component', function () { Mock Form Field , ) - assert.equal( + assert.strictEqual( wrapper .find('.send-v2__form-row > .send-v2__form-field') .childAt(0) @@ -104,7 +104,7 @@ describe('SendContent Component', function () { Mock Form Field , ) - assert.equal( + assert.strictEqual( wrapper .find('.send-v2__form-row > .send-v2__form-label') .childAt(1) diff --git a/ui/app/pages/send/send-content/tests/send-content-component.test.js b/ui/app/pages/send/send-content/tests/send-content-component.test.js index 30a9fba69..2628c516a 100644 --- a/ui/app/pages/send/send-content/tests/send-content-component.test.js +++ b/ui/app/pages/send/send-content/tests/send-content-component.test.js @@ -21,7 +21,7 @@ describe('SendContent Component', function () { describe('render', function () { it('should render a PageContainerContent component', function () { - assert.equal(wrapper.find(PageContainerContent).length, 1) + assert.strictEqual(wrapper.find(PageContainerContent).length, 1) }) it('should render a div with a .send-v2__form class as a child of PageContainerContent', function () { @@ -79,7 +79,7 @@ describe('SendContent Component', function () { PageContainerContentChild.childAt(3).is(SendGasRow), 'row[3] should be SendGasRow', ) - assert.equal(PageContainerContentChild.childAt(4).exists(), false) + assert.strictEqual(PageContainerContentChild.childAt(4).exists(), false) }) it('should not render the Dialog if contact has a name', function () { @@ -102,7 +102,7 @@ describe('SendContent Component', function () { PageContainerContentChild.childAt(2).is(SendGasRow), 'row[3] should be SendGasRow', ) - assert.equal(PageContainerContentChild.childAt(3).exists(), false) + assert.strictEqual(PageContainerContentChild.childAt(3).exists(), false) }) it('should not render the Dialog if it is an ownedAccount', function () { @@ -125,7 +125,7 @@ describe('SendContent Component', function () { PageContainerContentChild.childAt(2).is(SendGasRow), 'row[3] should be SendGasRow', ) - assert.equal(PageContainerContentChild.childAt(3).exists(), false) + assert.strictEqual(PageContainerContentChild.childAt(3).exists(), false) }) }) @@ -150,8 +150,8 @@ describe('SendContent Component', function () { const dialog = wrapper.find(Dialog).at(0) - assert.equal(dialog.props().type, 'warning') - assert.equal(dialog.props().children, 'watchout_t') - assert.equal(dialog.length, 1) + assert.strictEqual(dialog.props().type, 'warning') + assert.strictEqual(dialog.props().children, 'watchout_t') + assert.strictEqual(dialog.length, 1) }) }) diff --git a/ui/app/pages/send/send-footer/tests/send-footer-component.test.js b/ui/app/pages/send/send-footer/tests/send-footer-component.test.js index 87a0e2d9a..d77b7fe87 100644 --- a/ui/app/pages/send/send-footer/tests/send-footer-component.test.js +++ b/ui/app/pages/send/send-footer/tests/send-footer-component.test.js @@ -71,16 +71,16 @@ describe('SendFooter Component', function () { describe('onCancel', function () { it('should call clearSend', function () { - assert.equal(propsMethodSpies.clearSend.callCount, 0) + assert.strictEqual(propsMethodSpies.clearSend.callCount, 0) wrapper.instance().onCancel() - assert.equal(propsMethodSpies.clearSend.callCount, 1) + assert.strictEqual(propsMethodSpies.clearSend.callCount, 1) }) it('should call history.push', function () { - assert.equal(historySpies.push.callCount, 0) + assert.strictEqual(historySpies.push.callCount, 0) wrapper.instance().onCancel() - assert.equal(historySpies.push.callCount, 1) - assert.equal( + assert.strictEqual(historySpies.push.callCount, 1) + assert.strictEqual( historySpies.push.getCall(0).args[0], 'mostRecentOverviewPage', ) @@ -133,7 +133,7 @@ describe('SendFooter Component', function () { Object.entries(config).forEach(([description, obj]) => { it(description, function () { wrapper.setProps(obj) - assert.equal( + assert.strictEqual( wrapper.instance().formShouldBeDisabled(), obj.expectedResult, ) @@ -145,16 +145,16 @@ describe('SendFooter Component', function () { it('should call addToAddressBookIfNew with the correct params', function () { wrapper.instance().onSubmit(MOCK_EVENT) assert(propsMethodSpies.addToAddressBookIfNew.calledOnce) - assert.deepEqual(propsMethodSpies.addToAddressBookIfNew.getCall(0).args, [ - 'mockTo', - ['mockAccount'], - ]) + assert.deepStrictEqual( + propsMethodSpies.addToAddressBookIfNew.getCall(0).args, + ['mockTo', ['mockAccount']], + ) }) it('should call props.update if editingTransactionId is truthy', async function () { await wrapper.instance().onSubmit(MOCK_EVENT) assert(propsMethodSpies.update.calledOnce) - assert.deepEqual(propsMethodSpies.update.getCall(0).args[0], { + assert.deepStrictEqual(propsMethodSpies.update.getCall(0).args[0], { data: undefined, amount: 'mockAmount', editingTransactionId: 'mockEditingTransactionId', @@ -168,14 +168,14 @@ describe('SendFooter Component', function () { }) it('should not call props.sign if editingTransactionId is truthy', function () { - assert.equal(propsMethodSpies.sign.callCount, 0) + assert.strictEqual(propsMethodSpies.sign.callCount, 0) }) it('should call props.sign if editingTransactionId is falsy', async function () { wrapper.setProps({ editingTransactionId: null }) await wrapper.instance().onSubmit(MOCK_EVENT) assert(propsMethodSpies.sign.calledOnce) - assert.deepEqual(propsMethodSpies.sign.getCall(0).args[0], { + assert.deepStrictEqual(propsMethodSpies.sign.getCall(0).args[0], { data: undefined, amount: 'mockAmount', from: 'mockAddress', @@ -187,13 +187,13 @@ describe('SendFooter Component', function () { }) it('should not call props.update if editingTransactionId is falsy', function () { - assert.equal(propsMethodSpies.update.callCount, 0) + assert.strictEqual(propsMethodSpies.update.callCount, 0) }) it('should call history.push', async function () { await wrapper.instance().onSubmit(MOCK_EVENT) - assert.equal(historySpies.push.callCount, 1) - assert.equal( + assert.strictEqual(historySpies.push.callCount, 1) + assert.strictEqual( historySpies.push.getCall(0).args[0], CONFIRM_TRANSACTION_ROUTE, ) @@ -234,22 +234,22 @@ describe('SendFooter Component', function () { }) it('should render a PageContainerFooter component', function () { - assert.equal(wrapper.find(PageContainerFooter).length, 1) + assert.strictEqual(wrapper.find(PageContainerFooter).length, 1) }) it('should pass the correct props to PageContainerFooter', function () { const { onCancel, onSubmit, disabled } = wrapper .find(PageContainerFooter) .props() - assert.equal(disabled, true) + assert.strictEqual(disabled, true) - assert.equal(SendFooter.prototype.onSubmit.callCount, 0) + assert.strictEqual(SendFooter.prototype.onSubmit.callCount, 0) onSubmit(MOCK_EVENT) - assert.equal(SendFooter.prototype.onSubmit.callCount, 1) + assert.strictEqual(SendFooter.prototype.onSubmit.callCount, 1) - assert.equal(SendFooter.prototype.onCancel.callCount, 0) + assert.strictEqual(SendFooter.prototype.onCancel.callCount, 0) onCancel() - assert.equal(SendFooter.prototype.onCancel.callCount, 1) + assert.strictEqual(SendFooter.prototype.onCancel.callCount, 1) }) }) }) diff --git a/ui/app/pages/send/send-footer/tests/send-footer-container.test.js b/ui/app/pages/send/send-footer/tests/send-footer-container.test.js index 74fe608c8..e037fe7cc 100644 --- a/ui/app/pages/send/send-footer/tests/send-footer-container.test.js +++ b/ui/app/pages/send/send-footer/tests/send-footer-container.test.js @@ -82,18 +82,21 @@ describe('send-footer container', function () { gasPrice: 'mockGasPrice', }) assert(dispatchSpy.calledOnce) - assert.deepEqual(utilsStubs.constructTxParams.getCall(0).args[0], { - data: undefined, - sendToken: { - address: '0xabc', + assert.deepStrictEqual( + utilsStubs.constructTxParams.getCall(0).args[0], + { + data: undefined, + sendToken: { + address: '0xabc', + }, + to: 'mockTo', + amount: 'mockAmount', + from: 'mockFrom', + gas: 'mockGas', + gasPrice: 'mockGasPrice', }, - to: 'mockTo', - amount: 'mockAmount', - from: 'mockFrom', - gas: 'mockGas', - gasPrice: 'mockGasPrice', - }) - assert.deepEqual(actionSpies.signTokenTx.getCall(0).args, [ + ) + assert.deepStrictEqual(actionSpies.signTokenTx.getCall(0).args, [ '0xabc', 'mockTo', 'mockAmount', @@ -111,16 +114,19 @@ describe('send-footer container', function () { gasPrice: 'mockGasPrice', }) assert(dispatchSpy.calledOnce) - assert.deepEqual(utilsStubs.constructTxParams.getCall(0).args[0], { - data: undefined, - sendToken: undefined, - to: 'mockTo', - amount: 'mockAmount', - from: 'mockFrom', - gas: 'mockGas', - gasPrice: 'mockGasPrice', - }) - assert.deepEqual(actionSpies.signTx.getCall(0).args, [ + assert.deepStrictEqual( + utilsStubs.constructTxParams.getCall(0).args[0], + { + data: undefined, + sendToken: undefined, + to: 'mockTo', + amount: 'mockAmount', + from: 'mockFrom', + gas: 'mockGas', + gasPrice: 'mockGasPrice', + }, + ) + assert.deepStrictEqual(actionSpies.signTx.getCall(0).args, [ { value: 'mockAmount' }, ]) }) @@ -139,18 +145,21 @@ describe('send-footer container', function () { unapprovedTxs: 'mockUnapprovedTxs', }) assert(dispatchSpy.calledOnce) - assert.deepEqual(utilsStubs.constructUpdatedTx.getCall(0).args[0], { - data: undefined, - to: 'mockTo', - amount: 'mockAmount', - from: 'mockFrom', - gas: 'mockGas', - gasPrice: 'mockGasPrice', - editingTransactionId: 'mockEditingTransactionId', - sendToken: { address: 'mockAddress' }, - unapprovedTxs: 'mockUnapprovedTxs', - }) - assert.equal( + assert.deepStrictEqual( + utilsStubs.constructUpdatedTx.getCall(0).args[0], + { + data: undefined, + to: 'mockTo', + amount: 'mockAmount', + from: 'mockFrom', + gas: 'mockGas', + gasPrice: 'mockGasPrice', + editingTransactionId: 'mockEditingTransactionId', + sendToken: { address: 'mockAddress' }, + unapprovedTxs: 'mockUnapprovedTxs', + }, + ) + assert.strictEqual( actionSpies.updateTransaction.getCall(0).args[0], 'mockConstructedUpdatedTxParams', ) @@ -165,11 +174,11 @@ describe('send-footer container', function () { 'mockNickname', ) assert(dispatchSpy.calledOnce) - assert.equal( + assert.strictEqual( utilsStubs.addressIsNew.getCall(0).args[0], 'mockToAccounts', ) - assert.deepEqual(actionSpies.addToAddressBook.getCall(0).args, [ + assert.deepStrictEqual(actionSpies.addToAddressBook.getCall(0).args, [ '0xmockNewAddress', 'mockNickname', ]) diff --git a/ui/app/pages/send/send-footer/tests/send-footer-utils.test.js b/ui/app/pages/send/send-footer/tests/send-footer-utils.test.js index f462ff22f..52a84a993 100644 --- a/ui/app/pages/send/send-footer/tests/send-footer-utils.test.js +++ b/ui/app/pages/send/send-footer/tests/send-footer-utils.test.js @@ -19,7 +19,7 @@ const { addressIsNew, constructTxParams, constructUpdatedTx } = sendUtils describe('send-footer utils', function () { describe('addressIsNew()', function () { it('should return false if the address exists in toAccounts', function () { - assert.equal( + assert.strictEqual( addressIsNew( [{ address: '0xabc' }, { address: '0xdef' }, { address: '0xghi' }], '0xdef', @@ -29,7 +29,7 @@ describe('send-footer utils', function () { }) it('should return true if the address does not exists in toAccounts', function () { - assert.equal( + assert.strictEqual( addressIsNew( [{ address: '0xabc' }, { address: '0xdef' }, { address: '0xghi' }], '0xxyz', @@ -41,7 +41,7 @@ describe('send-footer utils', function () { describe('constructTxParams()', function () { it('should return a new txParams object with data if there data is given', function () { - assert.deepEqual( + assert.deepStrictEqual( constructTxParams({ data: 'someData', sendToken: undefined, @@ -63,7 +63,7 @@ describe('send-footer utils', function () { }) it('should return a new txParams object with value and to properties if there is no sendToken', function () { - assert.deepEqual( + assert.deepStrictEqual( constructTxParams({ sendToken: undefined, to: 'mockTo', @@ -84,7 +84,7 @@ describe('send-footer utils', function () { }) it('should return a new txParams object without a to property and a 0 value if there is a sendToken', function () { - assert.deepEqual( + assert.deepStrictEqual( constructTxParams({ sendToken: { address: '0x0' }, to: 'mockTo', @@ -124,7 +124,7 @@ describe('send-footer utils', function () { }, }, }) - assert.deepEqual(result, { + assert.deepStrictEqual(result, { unapprovedTxParam: 'someOtherParam', txParams: { from: '0xmockFrom', @@ -159,7 +159,7 @@ describe('send-footer utils', function () { }, }) - assert.deepEqual(result, { + assert.deepStrictEqual(result, { unapprovedTxParam: 'someOtherParam', txParams: { from: '0xmockFrom', @@ -191,7 +191,7 @@ describe('send-footer utils', function () { }, }) - assert.deepEqual(result, { + assert.deepStrictEqual(result, { unapprovedTxParam: 'someOtherParam', txParams: { from: '0xmockFrom', diff --git a/ui/app/pages/send/send-header/tests/send-header-component.test.js b/ui/app/pages/send/send-header/tests/send-header-component.test.js index e7abd308d..03168bed1 100644 --- a/ui/app/pages/send/send-header/tests/send-header-component.test.js +++ b/ui/app/pages/send/send-header/tests/send-header-component.test.js @@ -43,16 +43,16 @@ describe('SendHeader Component', function () { describe('onClose', function () { it('should call clearSend', function () { - assert.equal(propsMethodSpies.clearSend.callCount, 0) + assert.strictEqual(propsMethodSpies.clearSend.callCount, 0) wrapper.instance().onClose() - assert.equal(propsMethodSpies.clearSend.callCount, 1) + assert.strictEqual(propsMethodSpies.clearSend.callCount, 1) }) it('should call history.push', function () { - assert.equal(historySpies.push.callCount, 0) + assert.strictEqual(historySpies.push.callCount, 0) wrapper.instance().onClose() - assert.equal(historySpies.push.callCount, 1) - assert.equal( + assert.strictEqual(historySpies.push.callCount, 1) + assert.strictEqual( historySpies.push.getCall(0).args[0], 'mostRecentOverviewPage', ) @@ -61,15 +61,15 @@ describe('SendHeader Component', function () { describe('render', function () { it('should render a PageContainerHeader component', function () { - assert.equal(wrapper.find(PageContainerHeader).length, 1) + assert.strictEqual(wrapper.find(PageContainerHeader).length, 1) }) it('should pass the correct props to PageContainerHeader', function () { const { onClose, title } = wrapper.find(PageContainerHeader).props() - assert.equal(title, 'mockTitleKey') - assert.equal(SendHeader.prototype.onClose.callCount, 0) + assert.strictEqual(title, 'mockTitleKey') + assert.strictEqual(SendHeader.prototype.onClose.callCount, 0) onClose() - assert.equal(SendHeader.prototype.onClose.callCount, 1) + assert.strictEqual(SendHeader.prototype.onClose.callCount, 1) }) }) }) diff --git a/ui/app/pages/send/tests/send-component.test.js b/ui/app/pages/send/tests/send-component.test.js index 4c5cd04e3..458082e7d 100644 --- a/ui/app/pages/send/tests/send-component.test.js +++ b/ui/app/pages/send/tests/send-component.test.js @@ -106,27 +106,27 @@ describe('Send Component', function () { describe('componentDidMount', function () { it('should call props.fetchBasicGasAndTimeEstimates', function () { propsMethodSpies.fetchBasicGasEstimates.resetHistory() - assert.equal(propsMethodSpies.fetchBasicGasEstimates.callCount, 0) + assert.strictEqual(propsMethodSpies.fetchBasicGasEstimates.callCount, 0) wrapper.instance().componentDidMount() - assert.equal(propsMethodSpies.fetchBasicGasEstimates.callCount, 1) + assert.strictEqual(propsMethodSpies.fetchBasicGasEstimates.callCount, 1) }) it('should call this.updateGas', async function () { SendTransactionScreen.prototype.updateGas.resetHistory() propsMethodSpies.updateSendErrors.resetHistory() - assert.equal(SendTransactionScreen.prototype.updateGas.callCount, 0) + assert.strictEqual(SendTransactionScreen.prototype.updateGas.callCount, 0) wrapper.instance().componentDidMount() await timeout(250) - assert.equal(SendTransactionScreen.prototype.updateGas.callCount, 1) + assert.strictEqual(SendTransactionScreen.prototype.updateGas.callCount, 1) }) }) describe('componentWillUnmount', function () { it('should call this.props.resetSendState', function () { propsMethodSpies.resetSendState.resetHistory() - assert.equal(propsMethodSpies.resetSendState.callCount, 0) + assert.strictEqual(propsMethodSpies.resetSendState.callCount, 0) wrapper.instance().componentWillUnmount() - assert.equal(propsMethodSpies.resetSendState.callCount, 1) + assert.strictEqual(propsMethodSpies.resetSendState.callCount, 1) }) }) @@ -139,7 +139,7 @@ describe('Send Component', function () { }, }) assert(utilsMethodStubs.doesAmountErrorRequireUpdate.calledTwice) - assert.deepEqual( + assert.deepStrictEqual( utilsMethodStubs.doesAmountErrorRequireUpdate.getCall(0).args[0], { balance: 'mockBalance', @@ -164,7 +164,7 @@ describe('Send Component', function () { balance: 'mockBalance', }, }) - assert.equal(utilsMethodStubs.getAmountErrorObject.callCount, 0) + assert.strictEqual(utilsMethodStubs.getAmountErrorObject.callCount, 0) }) it('should call getAmountErrorObject if doesAmountErrorRequireUpdate returns true', function () { @@ -174,8 +174,8 @@ describe('Send Component', function () { balance: 'balanceChanged', }, }) - assert.equal(utilsMethodStubs.getAmountErrorObject.callCount, 1) - assert.deepEqual( + assert.strictEqual(utilsMethodStubs.getAmountErrorObject.callCount, 1) + assert.deepStrictEqual( utilsMethodStubs.getAmountErrorObject.getCall(0).args[0], { amount: 'mockAmount', @@ -200,8 +200,8 @@ describe('Send Component', function () { balance: 'balanceChanged', }, }) - assert.equal(utilsMethodStubs.getGasFeeErrorObject.callCount, 1) - assert.deepEqual( + assert.strictEqual(utilsMethodStubs.getGasFeeErrorObject.callCount, 1) + assert.deepStrictEqual( utilsMethodStubs.getGasFeeErrorObject.getCall(0).args[0], { balance: 'mockBalance', @@ -222,7 +222,7 @@ describe('Send Component', function () { wrapper.instance().componentDidUpdate({ from: { address: 'mockAddress', balance: 'mockBalance' }, }) - assert.equal(utilsMethodStubs.getGasFeeErrorObject.callCount, 0) + assert.strictEqual(utilsMethodStubs.getGasFeeErrorObject.callCount, 0) }) it('should not call getGasFeeErrorObject if doesAmountErrorRequireUpdate returns true but sendToken is falsy', function () { @@ -233,7 +233,7 @@ describe('Send Component', function () { balance: 'balanceChanged', }, }) - assert.equal(utilsMethodStubs.getGasFeeErrorObject.callCount, 0) + assert.strictEqual(utilsMethodStubs.getGasFeeErrorObject.callCount, 0) }) it('should call updateSendErrors with the expected params if sendToken is falsy', function () { @@ -244,11 +244,14 @@ describe('Send Component', function () { balance: 'balanceChanged', }, }) - assert.equal(propsMethodSpies.updateSendErrors.callCount, 1) - assert.deepEqual(propsMethodSpies.updateSendErrors.getCall(0).args[0], { - amount: 'mockAmountError', - gasFee: null, - }) + assert.strictEqual(propsMethodSpies.updateSendErrors.callCount, 1) + assert.deepStrictEqual( + propsMethodSpies.updateSendErrors.getCall(0).args[0], + { + amount: 'mockAmountError', + gasFee: null, + }, + ) }) it('should call updateSendErrors with the expected params if sendToken is truthy', function () { @@ -261,11 +264,14 @@ describe('Send Component', function () { balance: 'balanceChanged', }, }) - assert.equal(propsMethodSpies.updateSendErrors.callCount, 1) - assert.deepEqual(propsMethodSpies.updateSendErrors.getCall(0).args[0], { - amount: 'mockAmountError', - gasFee: 'mockGasFeeError', - }) + assert.strictEqual(propsMethodSpies.updateSendErrors.callCount, 1) + assert.deepStrictEqual( + propsMethodSpies.updateSendErrors.getCall(0).args[0], + { + amount: 'mockAmountError', + gasFee: 'mockGasFeeError', + }, + ) }) it('should not call updateSendTokenBalance or this.updateGas if network === prevNetwork', function () { @@ -278,8 +284,8 @@ describe('Send Component', function () { network: '3', sendToken: { address: 'mockTokenAddress', decimals: 18, symbol: 'TST' }, // Make sure not to hit updateGas when changing asset }) - assert.equal(propsMethodSpies.updateSendTokenBalance.callCount, 0) - assert.equal(SendTransactionScreen.prototype.updateGas.callCount, 0) + assert.strictEqual(propsMethodSpies.updateSendTokenBalance.callCount, 0) + assert.strictEqual(SendTransactionScreen.prototype.updateGas.callCount, 0) }) it('should not call updateSendTokenBalance or this.updateGas if network === loading', function () { @@ -293,8 +299,8 @@ describe('Send Component', function () { network: '3', sendToken: { address: 'mockTokenAddress', decimals: 18, symbol: 'TST' }, // Make sure not to hit updateGas when changing asset }) - assert.equal(propsMethodSpies.updateSendTokenBalance.callCount, 0) - assert.equal(SendTransactionScreen.prototype.updateGas.callCount, 0) + assert.strictEqual(propsMethodSpies.updateSendTokenBalance.callCount, 0) + assert.strictEqual(SendTransactionScreen.prototype.updateGas.callCount, 0) }) it('should call updateSendTokenBalance and this.updateGas with the correct params', function () { @@ -307,8 +313,8 @@ describe('Send Component', function () { network: '2', sendToken: { address: 'mockTokenAddress', decimals: 18, symbol: 'TST' }, // Make sure not to hit updateGas when changing asset }) - assert.equal(propsMethodSpies.updateSendTokenBalance.callCount, 1) - assert.deepEqual( + assert.strictEqual(propsMethodSpies.updateSendTokenBalance.callCount, 1) + assert.deepStrictEqual( propsMethodSpies.updateSendTokenBalance.getCall(0).args[0], { sendToken: { @@ -320,8 +326,8 @@ describe('Send Component', function () { address: 'mockAddress', }, ) - assert.equal(SendTransactionScreen.prototype.updateGas.callCount, 1) - assert.deepEqual( + assert.strictEqual(SendTransactionScreen.prototype.updateGas.callCount, 1) + assert.deepStrictEqual( SendTransactionScreen.prototype.updateGas.getCall(0).args, [], ) @@ -337,8 +343,11 @@ describe('Send Component', function () { network: '3', // Make sure not to hit updateGas when changing network sendToken: { address: 'newSelectedToken' }, }) - assert.equal(propsMethodSpies.updateToNicknameIfNecessary.callCount, 0) // Network did not change - assert.equal(propsMethodSpies.updateAndSetGasLimit.callCount, 1) + assert.strictEqual( + propsMethodSpies.updateToNicknameIfNecessary.callCount, + 0, + ) // Network did not change + assert.strictEqual(propsMethodSpies.updateAndSetGasLimit.callCount, 1) }) }) @@ -346,8 +355,8 @@ describe('Send Component', function () { it('should call updateAndSetGasLimit with the correct params if no to prop is passed', function () { propsMethodSpies.updateAndSetGasLimit.resetHistory() wrapper.instance().updateGas() - assert.equal(propsMethodSpies.updateAndSetGasLimit.callCount, 1) - assert.deepEqual( + assert.strictEqual(propsMethodSpies.updateAndSetGasLimit.callCount, 1) + assert.deepStrictEqual( propsMethodSpies.updateAndSetGasLimit.getCall(0).args[0], { blockGasLimit: 'mockBlockGasLimit', @@ -371,7 +380,7 @@ describe('Send Component', function () { propsMethodSpies.updateAndSetGasLimit.resetHistory() wrapper.setProps({ to: 'someAddress' }) wrapper.instance().updateGas() - assert.equal( + assert.strictEqual( propsMethodSpies.updateAndSetGasLimit.getCall(0).args[0].to, 'someaddress', ) @@ -380,7 +389,7 @@ describe('Send Component', function () { it('should call updateAndSetGasLimit with to set to lowercase if passed', function () { propsMethodSpies.updateAndSetGasLimit.resetHistory() wrapper.instance().updateGas({ to: '0xABC' }) - assert.equal( + assert.strictEqual( propsMethodSpies.updateAndSetGasLimit.getCall(0).args[0].to, '0xabc', ) @@ -389,22 +398,22 @@ describe('Send Component', function () { describe('render', function () { it('should render a page-container class', function () { - assert.equal(wrapper.find('.page-container').length, 1) + assert.strictEqual(wrapper.find('.page-container').length, 1) }) it('should render SendHeader and AddRecipient', function () { - assert.equal(wrapper.find(SendHeader).length, 1) - assert.equal(wrapper.find(AddRecipient).length, 1) + assert.strictEqual(wrapper.find(SendHeader).length, 1) + assert.strictEqual(wrapper.find(AddRecipient).length, 1) }) it('should pass the history prop to SendHeader and SendFooter', function () { wrapper.setProps({ to: '0x80F061544cC398520615B5d3e7A3BedD70cd4510', }) - assert.equal(wrapper.find(SendHeader).length, 1) - assert.equal(wrapper.find(SendContent).length, 1) - assert.equal(wrapper.find(SendFooter).length, 1) - assert.deepEqual(wrapper.find(SendFooter).props(), { + assert.strictEqual(wrapper.find(SendHeader).length, 1) + assert.strictEqual(wrapper.find(SendContent).length, 1) + assert.strictEqual(wrapper.find(SendFooter).length, 1) + assert.deepStrictEqual(wrapper.find(SendFooter).props(), { history: { mockProp: 'history-abc' }, }) }) @@ -413,7 +422,7 @@ describe('Send Component', function () { wrapper.setProps({ to: '0x80F061544cC398520615B5d3e7A3BedD70cd4510', }) - assert.equal(wrapper.find(SendContent).props().showHexData, true) + assert.strictEqual(wrapper.find(SendContent).props().showHexData, true) }) }) @@ -434,7 +443,7 @@ describe('Send Component', function () { '0x80F061544cC398520615B5d3e7A3BedD70cd4510', ) - assert.deepEqual(instance.state, { + assert.deepStrictEqual(instance.state, { internalSearch: false, query: '0x80F061544cC398520615B5d3e7A3BedD70cd4510', toError: null, @@ -449,7 +458,7 @@ describe('Send Component', function () { ) clock.tick(1001) - assert.deepEqual(instance.state, { + assert.deepStrictEqual(instance.state, { internalSearch: false, query: '0x80F061544cC398520615B5d3e7a3BedD70cd4510', toError: 'invalidAddressRecipient', @@ -465,7 +474,7 @@ describe('Send Component', function () { ) clock.tick(1001) - assert.deepEqual(instance.state, { + assert.deepStrictEqual(instance.state, { internalSearch: false, query: '0x80F061544cC398520615B5d3e7a3BedD70cd4510', toError: 'invalidAddressRecipientNotEthNetwork', @@ -481,7 +490,7 @@ describe('Send Component', function () { ) clock.tick(1001) - assert.deepEqual(instance.state, { + assert.deepStrictEqual(instance.state, { internalSearch: false, query: '0x80F061544cC398520615B5d3e7a3BedD70cd4510', toError: 'invalidAddressRecipientNotEthNetwork', @@ -489,7 +498,7 @@ describe('Send Component', function () { }) instance.onRecipientInputChange('') - assert.deepEqual(instance.state, { + assert.deepStrictEqual(instance.state, { internalSearch: false, query: '', toError: '', @@ -505,7 +514,7 @@ describe('Send Component', function () { ) clock.tick(1001) - assert.deepEqual(instance.state, { + assert.deepStrictEqual(instance.state, { internalSearch: false, query: '0x13cb85823f78Cff38f0B0E90D3e975b8CB3AAd64', toError: null, diff --git a/ui/app/pages/send/tests/send-container.test.js b/ui/app/pages/send/tests/send-container.test.js index d6af26758..3a9f4a807 100644 --- a/ui/app/pages/send/tests/send-container.test.js +++ b/ui/app/pages/send/tests/send-container.test.js @@ -56,7 +56,7 @@ describe('send container', function () { it('should dispatch a setGasTotal action when editingTransactionId is truthy', function () { mapDispatchToPropsObject.updateAndSetGasLimit(mockProps) assert(dispatchSpy.calledOnce) - assert.equal(actionSpies.setGasTotal.getCall(0).args[0], '0x30x4') + assert.strictEqual(actionSpies.setGasTotal.getCall(0).args[0], '0x30x4') }) it('should dispatch an updateGasData action when editingTransactionId is falsy', function () { @@ -74,7 +74,7 @@ describe('send container', function () { editingTransactionId: false, }) assert(dispatchSpy.calledOnce) - assert.deepEqual(actionSpies.updateGasData.getCall(0).args[0], { + assert.deepStrictEqual(actionSpies.updateGasData.getCall(0).args[0], { gasPrice, selectedAddress, sendToken, @@ -96,7 +96,7 @@ describe('send container', function () { it('should dispatch an action', function () { mapDispatchToPropsObject.updateSendTokenBalance({ ...mockProps }) assert(dispatchSpy.calledOnce) - assert.deepEqual( + assert.deepStrictEqual( actionSpies.updateSendTokenBalance.getCall(0).args[0], mockProps, ) @@ -107,7 +107,7 @@ describe('send container', function () { it('should dispatch an action', function () { mapDispatchToPropsObject.updateSendErrors('mockError') assert(dispatchSpy.calledOnce) - assert.equal( + assert.strictEqual( duckActionSpies.updateSendErrors.getCall(0).args[0], 'mockError', ) @@ -118,7 +118,10 @@ describe('send container', function () { it('should dispatch an action', function () { mapDispatchToPropsObject.resetSendState() assert(dispatchSpy.calledOnce) - assert.equal(duckActionSpies.resetSendState.getCall(0).args.length, 0) + assert.strictEqual( + duckActionSpies.resetSendState.getCall(0).args.length, + 0, + ) }) }) }) diff --git a/ui/app/pages/send/tests/send-utils.test.js b/ui/app/pages/send/tests/send-utils.test.js index 9107dba46..853581e96 100644 --- a/ui/app/pages/send/tests/send-utils.test.js +++ b/ui/app/pages/send/tests/send-utils.test.js @@ -67,9 +67,9 @@ describe('send utils', function () { describe('calcGasTotal()', function () { it('should call multiplyCurrencies with the correct params and return the multiplyCurrencies return', function () { const result = calcGasTotal(12, 15) - assert.equal(result, '12x15') + assert.strictEqual(result, '12x15') const call_ = stubs.multiplyCurrencies.getCall(0).args - assert.deepEqual(call_, [ + assert.deepStrictEqual(call_, [ 12, 15, { @@ -112,14 +112,17 @@ describe('send utils', function () { } Object.entries(config).forEach(([description, obj]) => { it(description, function () { - assert.equal(doesAmountErrorRequireUpdate(obj), obj.expectedResult) + assert.strictEqual( + doesAmountErrorRequireUpdate(obj), + obj.expectedResult, + ) }) }) }) describe('generateTokenTransferData()', function () { it('should return undefined if not passed a send token', function () { - assert.equal( + assert.strictEqual( generateTokenTransferData({ toAddress: 'mockAddress', amount: '0xa', @@ -136,14 +139,14 @@ describe('send utils', function () { amount: 'ab', sendToken: { address: '0x0' }, }) - assert.deepEqual(stubs.rawEncode.getCall(0).args, [ + assert.deepStrictEqual(stubs.rawEncode.getCall(0).args, [ ['address', 'uint256'], ['mockAddress', '0xab'], ]) }) it('should return encoded token transfer data', function () { - assert.equal( + assert.strictEqual( generateTokenTransferData({ toAddress: 'mockAddress', amount: '0xa', @@ -189,7 +192,7 @@ describe('send utils', function () { } Object.entries(config).forEach(([description, obj]) => { it(description, function () { - assert.deepEqual(getAmountErrorObject(obj), obj.expectedResult) + assert.deepStrictEqual(getAmountErrorObject(obj), obj.expectedResult) }) }) }) @@ -213,14 +216,14 @@ describe('send utils', function () { } Object.entries(config).forEach(([description, obj]) => { it(description, function () { - assert.deepEqual(getGasFeeErrorObject(obj), obj.expectedResult) + assert.deepStrictEqual(getGasFeeErrorObject(obj), obj.expectedResult) }) }) }) describe('calcTokenBalance()', function () { it('should return the calculated token balance', function () { - assert.equal( + assert.strictEqual( calcTokenBalance({ sendToken: { address: '0x0', @@ -245,7 +248,7 @@ describe('send utils', function () { gasTotal: 17, primaryCurrency: 'ABC', }) - assert.deepEqual(stubs.addCurrencies.getCall(0).args, [ + assert.deepStrictEqual(stubs.addCurrencies.getCall(0).args, [ 15, 17, { @@ -254,7 +257,7 @@ describe('send utils', function () { toNumericBase: 'hex', }, ]) - assert.deepEqual(stubs.conversionGTE.getCall(0).args, [ + assert.deepStrictEqual(stubs.conversionGTE.getCall(0).args, [ { value: 100, fromNumericBase: 'hex', @@ -269,7 +272,7 @@ describe('send utils', function () { }, ]) - assert.equal(result, true) + assert.strictEqual(result, true) }) }) @@ -282,13 +285,13 @@ describe('send utils', function () { tokenBalance: 123, decimals: 10, }) - assert.deepEqual(stubs.conversionUtil.getCall(0).args, [ + assert.deepStrictEqual(stubs.conversionUtil.getCall(0).args, [ '0x10', { fromNumericBase: 'hex', }, ]) - assert.deepEqual(stubs.conversionGTE.getCall(0).args, [ + assert.deepStrictEqual(stubs.conversionGTE.getCall(0).args, [ { value: 123, fromNumericBase: 'hex', @@ -298,7 +301,7 @@ describe('send utils', function () { }, ]) - assert.equal(result, false) + assert.strictEqual(result, false) }) }) @@ -338,13 +341,16 @@ describe('send utils', function () { it('should call ethQuery.estimateGasForSend with the expected params', async function () { const result = await estimateGasForSend(baseMockParams) - assert.equal(baseMockParams.estimateGasMethod.callCount, 1) - assert.deepEqual(baseMockParams.estimateGasMethod.getCall(0).args[0], { - gasPrice: undefined, - value: undefined, - ...baseExpectedCall, - }) - assert.equal(result, '0xabc16') + assert.strictEqual(baseMockParams.estimateGasMethod.callCount, 1) + assert.deepStrictEqual( + baseMockParams.estimateGasMethod.getCall(0).args[0], + { + gasPrice: undefined, + value: undefined, + ...baseExpectedCall, + }, + ) + assert.strictEqual(result, '0xabc16') }) it('should call ethQuery.estimateGasForSend with the expected params when initialGasLimitHex is lower than the upperGasLimit', async function () { @@ -352,14 +358,17 @@ describe('send utils', function () { ...baseMockParams, blockGasLimit: '0xbcd', }) - assert.equal(baseMockParams.estimateGasMethod.callCount, 1) - assert.deepEqual(baseMockParams.estimateGasMethod.getCall(0).args[0], { - gasPrice: undefined, - value: undefined, - ...baseExpectedCall, - gas: '0xbcdx0.95', - }) - assert.equal(result, '0xabc16x1.5') + assert.strictEqual(baseMockParams.estimateGasMethod.callCount, 1) + assert.deepStrictEqual( + baseMockParams.estimateGasMethod.getCall(0).args[0], + { + gasPrice: undefined, + value: undefined, + ...baseExpectedCall, + gas: '0xbcdx0.95', + }, + ) + assert.strictEqual(result, '0xabc16x1.5') }) it('should call ethQuery.estimateGasForSend with a value of 0x0 and the expected data and to if passed a sendToken', async function () { @@ -368,55 +377,61 @@ describe('send utils', function () { sendToken: { address: 'mockAddress' }, ...baseMockParams, }) - assert.equal(baseMockParams.estimateGasMethod.callCount, 1) - assert.deepEqual(baseMockParams.estimateGasMethod.getCall(0).args[0], { - ...baseExpectedCall, - gasPrice: undefined, - value: '0x0', - data: '0xa9059cbb104c', - to: 'mockAddress', - }) - assert.equal(result, '0xabc16') + assert.strictEqual(baseMockParams.estimateGasMethod.callCount, 1) + assert.deepStrictEqual( + baseMockParams.estimateGasMethod.getCall(0).args[0], + { + ...baseExpectedCall, + gasPrice: undefined, + value: '0x0', + data: '0xa9059cbb104c', + to: 'mockAddress', + }, + ) + assert.strictEqual(result, '0xabc16') }) it('should call ethQuery.estimateGasForSend without a recipient if the recipient is empty and data passed', async function () { const data = 'mockData' const to = '' const result = await estimateGasForSend({ ...baseMockParams, data, to }) - assert.equal(baseMockParams.estimateGasMethod.callCount, 1) - assert.deepEqual(baseMockParams.estimateGasMethod.getCall(0).args[0], { - gasPrice: undefined, - value: '0xff', - data, - from: baseExpectedCall.from, - gas: baseExpectedCall.gas, - }) - assert.equal(result, '0xabc16') + assert.strictEqual(baseMockParams.estimateGasMethod.callCount, 1) + assert.deepStrictEqual( + baseMockParams.estimateGasMethod.getCall(0).args[0], + { + gasPrice: undefined, + value: '0xff', + data, + from: baseExpectedCall.from, + gas: baseExpectedCall.gas, + }, + ) + assert.strictEqual(result, '0xabc16') }) it(`should return ${SIMPLE_GAS_COST} if ethQuery.getCode does not return '0x'`, async function () { - assert.equal(baseMockParams.estimateGasMethod.callCount, 0) + assert.strictEqual(baseMockParams.estimateGasMethod.callCount, 0) const result = await estimateGasForSend({ ...baseMockParams, to: '0x123', }) - assert.equal(result, SIMPLE_GAS_COST) + assert.strictEqual(result, SIMPLE_GAS_COST) }) it(`should return ${SIMPLE_GAS_COST} if not passed a sendToken or truthy to address`, async function () { - assert.equal(baseMockParams.estimateGasMethod.callCount, 0) + assert.strictEqual(baseMockParams.estimateGasMethod.callCount, 0) const result = await estimateGasForSend({ ...baseMockParams, to: null }) - assert.equal(result, SIMPLE_GAS_COST) + assert.strictEqual(result, SIMPLE_GAS_COST) }) it(`should not return ${SIMPLE_GAS_COST} if passed a sendToken`, async function () { - assert.equal(baseMockParams.estimateGasMethod.callCount, 0) + assert.strictEqual(baseMockParams.estimateGasMethod.callCount, 0) const result = await estimateGasForSend({ ...baseMockParams, to: '0x123', sendToken: { address: '0x0' }, }) - assert.notEqual(result, SIMPLE_GAS_COST) + assert.notStrictEqual(result, SIMPLE_GAS_COST) }) it(`should return ${BASE_TOKEN_GAS_COST} if passed a sendToken but no to address`, async function () { @@ -425,7 +440,7 @@ describe('send utils', function () { to: null, sendToken: { address: '0x0' }, }) - assert.equal(result, BASE_TOKEN_GAS_COST) + assert.strictEqual(result, BASE_TOKEN_GAS_COST) }) it(`should return the adjusted blockGasLimit if it fails with a 'Transaction execution error.'`, async function () { @@ -433,7 +448,7 @@ describe('send utils', function () { ...baseMockParams, to: 'isContract willFailBecauseOf:Transaction execution error.', }) - assert.equal(result, '0x64x0.95') + assert.strictEqual(result, '0x64x0.95') }) it(`should return the adjusted blockGasLimit if it fails with a 'gas required exceeds allowance or always failing transaction.'`, async function () { @@ -442,7 +457,7 @@ describe('send utils', function () { to: 'isContract willFailBecauseOf:gas required exceeds allowance or always failing transaction.', }) - assert.equal(result, '0x64x0.95') + assert.strictEqual(result, '0x64x0.95') }) it(`should reject other errors`, async function () { @@ -452,44 +467,44 @@ describe('send utils', function () { to: 'isContract willFailBecauseOf:some other error', }) } catch (err) { - assert.equal(err.message, 'some other error') + assert.strictEqual(err.message, 'some other error') } }) }) describe('getToAddressForGasUpdate()', function () { it('should return empty string if all params are undefined or null', function () { - assert.equal(getToAddressForGasUpdate(undefined, null), '') + assert.strictEqual(getToAddressForGasUpdate(undefined, null), '') }) it('should return the first string that is not defined or null in lower case', function () { - assert.equal(getToAddressForGasUpdate('A', null), 'a') - assert.equal(getToAddressForGasUpdate(undefined, 'B'), 'b') + assert.strictEqual(getToAddressForGasUpdate('A', null), 'a') + assert.strictEqual(getToAddressForGasUpdate(undefined, 'B'), 'b') }) }) describe('removeLeadingZeroes()', function () { it('should remove leading zeroes from int when user types', function () { - assert.equal(removeLeadingZeroes('0'), '0') - assert.equal(removeLeadingZeroes('1'), '1') - assert.equal(removeLeadingZeroes('00'), '0') - assert.equal(removeLeadingZeroes('01'), '1') + assert.strictEqual(removeLeadingZeroes('0'), '0') + assert.strictEqual(removeLeadingZeroes('1'), '1') + assert.strictEqual(removeLeadingZeroes('00'), '0') + assert.strictEqual(removeLeadingZeroes('01'), '1') }) it('should remove leading zeroes from int when user copy/paste', function () { - assert.equal(removeLeadingZeroes('001'), '1') + assert.strictEqual(removeLeadingZeroes('001'), '1') }) it('should remove leading zeroes from float when user types', function () { - assert.equal(removeLeadingZeroes('0.'), '0.') - assert.equal(removeLeadingZeroes('0.0'), '0.0') - assert.equal(removeLeadingZeroes('0.00'), '0.00') - assert.equal(removeLeadingZeroes('0.001'), '0.001') - assert.equal(removeLeadingZeroes('0.10'), '0.10') + assert.strictEqual(removeLeadingZeroes('0.'), '0.') + assert.strictEqual(removeLeadingZeroes('0.0'), '0.0') + assert.strictEqual(removeLeadingZeroes('0.00'), '0.00') + assert.strictEqual(removeLeadingZeroes('0.001'), '0.001') + assert.strictEqual(removeLeadingZeroes('0.10'), '0.10') }) it('should remove leading zeroes from float when user copy/paste', function () { - assert.equal(removeLeadingZeroes('00.1'), '0.1') + assert.strictEqual(removeLeadingZeroes('00.1'), '0.1') }) }) }) diff --git a/ui/app/pages/settings/advanced-tab/tests/advanced-tab-component.test.js b/ui/app/pages/settings/advanced-tab/tests/advanced-tab-component.test.js index c86d50ab1..024702ae3 100644 --- a/ui/app/pages/settings/advanced-tab/tests/advanced-tab-component.test.js +++ b/ui/app/pages/settings/advanced-tab/tests/advanced-tab-component.test.js @@ -24,7 +24,7 @@ describe('AdvancedTab Component', function () { }, ) - assert.equal(root.find('.settings-page__content-row').length, 10) + assert.strictEqual(root.find('.settings-page__content-row').length, 10) }) it('should update autoLockTimeLimit', function () { @@ -50,9 +50,9 @@ describe('AdvancedTab Component', function () { const textField = autoTimeout.find(TextField) textField.props().onChange({ target: { value: 1440 } }) - assert.equal(root.state().autoLockTimeLimit, 1440) + assert.strictEqual(root.state().autoLockTimeLimit, 1440) autoTimeout.find('.settings-tab__rpc-save-button').simulate('click') - assert.equal(setAutoLockTimeLimitSpy.args[0][0], 1440) + assert.strictEqual(setAutoLockTimeLimitSpy.args[0][0], 1440) }) }) diff --git a/ui/app/pages/settings/security-tab/tests/security-tab.test.js b/ui/app/pages/settings/security-tab/tests/security-tab.test.js index d15328d85..d45a47d35 100644 --- a/ui/app/pages/settings/security-tab/tests/security-tab.test.js +++ b/ui/app/pages/settings/security-tab/tests/security-tab.test.js @@ -37,7 +37,7 @@ describe('Security Tab', function () { seedWords.simulate('click') assert(props.history.push.calledOnce) - assert.equal(props.history.push.getCall(0).args[0], '/seed') + assert.strictEqual(props.history.push.getCall(0).args[0], '/seed') }) it('toggles incoming txs', function () { diff --git a/ui/app/pages/swaps/swaps.util.test.js b/ui/app/pages/swaps/swaps.util.test.js index edb9bcd2c..77bab1905 100644 --- a/ui/app/pages/swaps/swaps.util.test.js +++ b/ui/app/pages/swaps/swaps.util.test.js @@ -14,24 +14,24 @@ import { const swapsUtils = proxyquire('./swaps.util.js', { '../../helpers/utils/fetch-with-cache': { default: (url, fetchObject) => { - assert.equal(fetchObject.method, 'GET') + assert.strictEqual(fetchObject.method, 'GET') if (url.match(TRADES_BASE_PROD_URL)) { - assert.equal( + assert.strictEqual( url, 'https://api.metaswap.codefi.network/trades?destinationToken=0xE41d2489571d322189246DaFA5ebDe1F4699F498&sourceToken=0x617b3f8050a0BD94b6b1da02B4384eE5B4DF13F4&sourceAmount=2000000000000000000000000000000000000&slippage=3&timeout=10000&walletAddress=0xmockAddress', ) return Promise.resolve(MOCK_TRADE_RESPONSE_2) } if (url.match(TOKENS_BASE_PROD_URL)) { - assert.equal(url, TOKENS_BASE_PROD_URL) + assert.strictEqual(url, TOKENS_BASE_PROD_URL) return Promise.resolve(TOKENS) } if (url.match(AGGREGATOR_METADATA_BASE_PROD_URL)) { - assert.equal(url, AGGREGATOR_METADATA_BASE_PROD_URL) + assert.strictEqual(url, AGGREGATOR_METADATA_BASE_PROD_URL) return Promise.resolve(AGGREGATOR_METADATA) } if (url.match(TOP_ASSET_BASE_PROD_URL)) { - assert.equal(url, TOP_ASSET_BASE_PROD_URL) + assert.strictEqual(url, TOP_ASSET_BASE_PROD_URL) return Promise.resolve(TOP_ASSETS) } return Promise.resolve() @@ -100,31 +100,31 @@ describe('Swaps Util', function () { sourceTokenInfo: { ...TOKENS[0] }, destinationTokenInfo: { ...TOKENS[1] }, }) - assert.deepEqual(result, expectedResult2) + assert.deepStrictEqual(result, expectedResult2) }) }) describe('fetchTokens', function () { it('should fetch tokens', async function () { const result = await fetchTokens(true) - assert.deepEqual(result, TOKENS) + assert.deepStrictEqual(result, TOKENS) }) it('should fetch tokens on prod', async function () { const result = await fetchTokens(false) - assert.deepEqual(result, TOKENS) + assert.deepStrictEqual(result, TOKENS) }) }) describe('fetchAggregatorMetadata', function () { it('should fetch aggregator metadata', async function () { const result = await fetchAggregatorMetadata(true) - assert.deepEqual(result, AGGREGATOR_METADATA) + assert.deepStrictEqual(result, AGGREGATOR_METADATA) }) it('should fetch aggregator metadata on prod', async function () { const result = await fetchAggregatorMetadata(false) - assert.deepEqual(result, AGGREGATOR_METADATA) + assert.deepStrictEqual(result, AGGREGATOR_METADATA) }) }) @@ -148,12 +148,12 @@ describe('Swaps Util', function () { } it('should fetch top assets', async function () { const result = await fetchTopAssets(true) - assert.deepEqual(result, expectedResult) + assert.deepStrictEqual(result, expectedResult) }) it('should fetch top assets on prod', async function () { const result = await fetchTopAssets(false) - assert.deepEqual(result, expectedResult) + assert.deepStrictEqual(result, expectedResult) }) }) }) diff --git a/ui/app/pages/unlock-page/tests/unlock-page.test.js b/ui/app/pages/unlock-page/tests/unlock-page.test.js index 9e5d4266b..34b258469 100644 --- a/ui/app/pages/unlock-page/tests/unlock-page.test.js +++ b/ui/app/pages/unlock-page/tests/unlock-page.test.js @@ -32,7 +32,7 @@ describe('Unlock Page', function () { }) it('renders', function () { - assert.equal(wrapper.length, 1) + assert.strictEqual(wrapper.length, 1) }) it('changes password and submits', function () { @@ -40,9 +40,9 @@ describe('Unlock Page', function () { const loginButton = wrapper.find({ type: 'submit' }).last() const event = { target: { value: 'password' } } - assert.equal(wrapper.instance().state.password, '') + assert.strictEqual(wrapper.instance().state.password, '') passwordField.last().simulate('change', event) - assert.equal(wrapper.instance().state.password, 'password') + assert.strictEqual(wrapper.instance().state.password, 'password') loginButton.simulate('click') assert(props.onSubmit.calledOnce) diff --git a/ui/app/selectors/tests/confirm-transaction.test.js b/ui/app/selectors/tests/confirm-transaction.test.js index 53ab202ec..df8b3ae86 100644 --- a/ui/app/selectors/tests/confirm-transaction.test.js +++ b/ui/app/selectors/tests/confirm-transaction.test.js @@ -36,7 +36,7 @@ describe('Confirm Transaction Selector', function () { } it('returns number of txs in unapprovedTxs state with the same network plus unapproved signing method counts', function () { - assert.equal(unconfirmedTransactionsCountSelector(state), 4) + assert.strictEqual(unconfirmedTransactionsCountSelector(state), 4) }) }) @@ -58,7 +58,7 @@ describe('Confirm Transaction Selector', function () { } it('returns token address and calculated token amount', function () { - assert.deepEqual(sendTokenTokenAmountAndToAddressSelector(state), { + assert.deepStrictEqual(sendTokenTokenAmountAndToAddressSelector(state), { toAddress: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc', tokenAmount: '0.01', }) @@ -82,7 +82,7 @@ describe('Confirm Transaction Selector', function () { } it('returns contract exchange rate in metamask state based on confirm transaction txParams token recipient', function () { - assert.equal(contractExchangeRateSelector(state), 10) + assert.strictEqual(contractExchangeRateSelector(state), '10') }) }) @@ -91,7 +91,7 @@ describe('Confirm Transaction Selector', function () { const state = { metamask: { conversionRate: 556.12 }, } - assert.equal(conversionRateSelector(state), 556.12) + assert.strictEqual(conversionRateSelector(state), 556.12) }) }) }) diff --git a/ui/app/selectors/tests/custom-gas.test.js b/ui/app/selectors/tests/custom-gas.test.js index e51d3a4a1..9cbbf5c0d 100644 --- a/ui/app/selectors/tests/custom-gas.test.js +++ b/ui/app/selectors/tests/custom-gas.test.js @@ -14,28 +14,28 @@ describe('custom-gas selectors', function () { describe('getCustomGasPrice()', function () { it('should return gas.customData.price', function () { const mockState = { gas: { customData: { price: 'mockPrice' } } } - assert.equal(getCustomGasPrice(mockState), 'mockPrice') + assert.strictEqual(getCustomGasPrice(mockState), 'mockPrice') }) }) describe('getCustomGasLimit()', function () { it('should return gas.customData.limit', function () { const mockState = { gas: { customData: { limit: 'mockLimit' } } } - assert.equal(getCustomGasLimit(mockState), 'mockLimit') + assert.strictEqual(getCustomGasLimit(mockState), 'mockLimit') }) }) describe('getCustomGasTotal()', function () { it('should return gas.customData.total', function () { const mockState = { gas: { customData: { total: 'mockTotal' } } } - assert.equal(getCustomGasTotal(mockState), 'mockTotal') + assert.strictEqual(getCustomGasTotal(mockState), 'mockTotal') }) }) describe('getCustomGasErrors()', function () { it('should return gas.errors', function () { const mockState = { gas: { errors: 'mockErrors' } } - assert.equal(getCustomGasErrors(mockState), 'mockErrors') + assert.strictEqual(getCustomGasErrors(mockState), 'mockErrors') }) }) @@ -279,7 +279,7 @@ describe('custom-gas selectors', function () { ] it('should return renderable data about basic estimates', function () { tests.forEach((test) => { - assert.deepEqual( + assert.deepStrictEqual( getRenderableBasicEstimateData( test.mockState, '0x5208', @@ -528,7 +528,7 @@ describe('custom-gas selectors', function () { ] it('should return renderable data about basic estimates appropriate for buttons with less info', function () { tests.forEach((test) => { - assert.deepEqual( + assert.deepStrictEqual( getRenderableEstimateDataForSmallButtonsFromGWEI(test.mockState), test.expectedResult, ) diff --git a/ui/app/selectors/tests/permissions.test.js b/ui/app/selectors/tests/permissions.test.js index 39646f4d0..4750afa60 100644 --- a/ui/app/selectors/tests/permissions.test.js +++ b/ui/app/selectors/tests/permissions.test.js @@ -64,7 +64,7 @@ describe('selectors', function () { }, } const extensionId = undefined - assert.deepEqual(getConnectedDomainsForSelectedAddress(mockState), [ + assert.deepStrictEqual(getConnectedDomainsForSelectedAddress(mockState), [ { extensionId, icon: 'https://peepeth.com/favicon-32x32.png', @@ -142,7 +142,7 @@ describe('selectors', function () { }, } const extensionId = undefined - assert.deepEqual(getConnectedDomainsForSelectedAddress(mockState), [ + assert.deepStrictEqual(getConnectedDomainsForSelectedAddress(mockState), [ { extensionId, name: 'Remix - Ethereum IDE', @@ -279,36 +279,39 @@ describe('selectors', function () { } it('should return connected accounts sorted by last selected, then by keyring controller order', function () { - assert.deepEqual(getOrderedConnectedAccountsForActiveTab(mockState), [ - { - address: '0xb3958fb96c8201486ae20be1d5c9f58083df343a', - name: 'Account 2', - lastActive: 1586359844192, - lastSelected: 1586359844193, - }, - { - address: '0x8e5d75d60224ea0c33d0041e75de68b1c3cb6dd5', - name: 'Account 1', - lastActive: 1586359844192, - lastSelected: 1586359844192, - }, - { - address: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc', - name: 'Account 3', - lastActive: 1586359844192, - lastSelected: 1586359844192, - }, - { - address: '0x7250739de134d33ec7ab1ee592711e15098c9d2d', - name: 'Really Long Name That Should Be Truncated', - lastActive: 1586359844192, - }, - { - address: '0x617b3f8050a0bd94b6b1da02b4384ee5b4df13f4', - name: 'Account 4', - lastActive: 1586359844192, - }, - ]) + assert.deepStrictEqual( + getOrderedConnectedAccountsForActiveTab(mockState), + [ + { + address: '0xb3958fb96c8201486ae20be1d5c9f58083df343a', + name: 'Account 2', + lastActive: 1586359844192, + lastSelected: 1586359844193, + }, + { + address: '0x8e5d75d60224ea0c33d0041e75de68b1c3cb6dd5', + name: 'Account 1', + lastActive: 1586359844192, + lastSelected: 1586359844192, + }, + { + address: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc', + name: 'Account 3', + lastActive: 1586359844192, + lastSelected: 1586359844192, + }, + { + address: '0x7250739de134d33ec7ab1ee592711e15098c9d2d', + name: 'Really Long Name That Should Be Truncated', + lastActive: 1586359844192, + }, + { + address: '0x617b3f8050a0bd94b6b1da02b4384ee5b4df13f4', + name: 'Account 4', + lastActive: 1586359844192, + }, + ], + ) }) }) @@ -415,7 +418,7 @@ describe('selectors', function () { } it('should return a list of permissions strings', function () { - assert.deepEqual(getPermissionsForActiveTab(mockState), [ + assert.deepStrictEqual(getPermissionsForActiveTab(mockState), [ { key: 'eth_accounts', }, diff --git a/ui/app/selectors/tests/selectors.test.js b/ui/app/selectors/tests/selectors.test.js index ed76b7305..be03752a9 100644 --- a/ui/app/selectors/tests/selectors.test.js +++ b/ui/app/selectors/tests/selectors.test.js @@ -5,12 +5,15 @@ import mockState from '../../../../test/data/mock-state.json' describe('Selectors', function () { describe('#getSelectedAddress', function () { it('returns undefined if selectedAddress is undefined', function () { - assert.equal(selectors.getSelectedAddress({ metamask: {} }), undefined) + assert.strictEqual( + selectors.getSelectedAddress({ metamask: {} }), + undefined, + ) }) it('returns selectedAddress', function () { const selectedAddress = '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc' - assert.equal( + assert.strictEqual( selectors.getSelectedAddress({ metamask: { selectedAddress } }), selectedAddress, ) @@ -18,7 +21,7 @@ describe('Selectors', function () { }) it('returns selected identity', function () { - assert.deepEqual(selectors.getSelectedIdentity(mockState), { + assert.deepStrictEqual(selectors.getSelectedIdentity(mockState), { address: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc', name: 'Test Account', }) @@ -26,14 +29,17 @@ describe('Selectors', function () { it('returns selected account', function () { const account = selectors.getSelectedAccount(mockState) - assert.equal(account.balance, '0x0') - assert.equal(account.address, '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc') + assert.strictEqual(account.balance, '0x0') + assert.strictEqual( + account.address, + '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc', + ) }) describe('#getTokenExchangeRates', function () { it('returns token exchange rates', function () { const tokenExchangeRates = selectors.getTokenExchangeRates(mockState) - assert.deepEqual(tokenExchangeRates, { + assert.deepStrictEqual(tokenExchangeRates, { '0x108cf70c7d384c552f42c07c41c0e1e46d77ea0d': 0.00039345803819379796, '0xd8f6a2ffb0fc5952d16c9768b71cfd35b6399aa5': 0.00008189274407698049, }) @@ -42,7 +48,7 @@ describe('Selectors', function () { describe('#getAddressBook', function () { it('should return the address book', function () { - assert.deepEqual(selectors.getAddressBook(mockState), [ + assert.deepStrictEqual(selectors.getAddressBook(mockState), [ { address: '0xc42edfcc21ed14dda456aa0756c153f7985d8813', chainId: '0x4', @@ -58,39 +64,39 @@ describe('Selectors', function () { const accountsWithSendEther = selectors.accountsWithSendEtherInfoSelector( mockState, ) - assert.equal(accountsWithSendEther.length, 2) - assert.equal(accountsWithSendEther[0].balance, '0x0') - assert.equal( + assert.strictEqual(accountsWithSendEther.length, 2) + assert.strictEqual(accountsWithSendEther[0].balance, '0x0') + assert.strictEqual( accountsWithSendEther[0].address, '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc', ) - assert.equal(accountsWithSendEther[0].name, 'Test Account') + assert.strictEqual(accountsWithSendEther[0].name, 'Test Account') }) it('returns selected account with balance, address, and name from accountsWithSendEtherInfoSelector', function () { const currentAccountwithSendEther = selectors.getCurrentAccountWithSendEtherInfo( mockState, ) - assert.equal(currentAccountwithSendEther.balance, '0x0') - assert.equal( + assert.strictEqual(currentAccountwithSendEther.balance, '0x0') + assert.strictEqual( currentAccountwithSendEther.address, '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc', ) - assert.equal(currentAccountwithSendEther.name, 'Test Account') + assert.strictEqual(currentAccountwithSendEther.name, 'Test Account') }) it('#getGasIsLoading', function () { const gasIsLoading = selectors.getGasIsLoading(mockState) - assert.equal(gasIsLoading, false) + assert.strictEqual(gasIsLoading, false) }) it('#getCurrentCurrency', function () { const currentCurrency = selectors.getCurrentCurrency(mockState) - assert.equal(currentCurrency, 'usd') + assert.strictEqual(currentCurrency, 'usd') }) it('#getTotalUnapprovedCount', function () { const totalUnapprovedCount = selectors.getTotalUnapprovedCount(mockState) - assert.equal(totalUnapprovedCount, 1) + assert.strictEqual(totalUnapprovedCount, 1) }) }) diff --git a/ui/app/selectors/tests/send.test.js b/ui/app/selectors/tests/send.test.js index 8af4fb430..eeb080e3b 100644 --- a/ui/app/selectors/tests/send.test.js +++ b/ui/app/selectors/tests/send.test.js @@ -53,7 +53,7 @@ describe('send selectors', function () { describe('accountsWithSendEtherInfoSelector()', function () { it('should return an array of account objects with name info from identities', function () { - assert.deepEqual(accountsWithSendEtherInfoSelector(mockState), [ + assert.deepStrictEqual(accountsWithSendEtherInfoSelector(mockState), [ { code: '0x', balance: '0x47c9d71831c76efe', @@ -88,19 +88,19 @@ describe('send selectors', function () { describe('getBlockGasLimit', function () { it('should return the current block gas limit', function () { - assert.deepEqual(getBlockGasLimit(mockState), '0x4c1878') + assert.deepStrictEqual(getBlockGasLimit(mockState), '0x4c1878') }) }) describe('getConversionRate()', function () { it('should return the eth conversion rate', function () { - assert.deepEqual(getConversionRate(mockState), 1200.88200327) + assert.deepStrictEqual(getConversionRate(mockState), 1200.88200327) }) }) describe('getCurrentAccountWithSendEtherInfo()', function () { it('should return the currently selected account with identity info', function () { - assert.deepEqual(getCurrentAccountWithSendEtherInfo(mockState), { + assert.deepStrictEqual(getCurrentAccountWithSendEtherInfo(mockState), { code: '0x', balance: '0x0', nonce: '0x0', @@ -112,37 +112,37 @@ describe('send selectors', function () { describe('getNativeCurrency()', function () { it('should return the ticker symbol of the selected network', function () { - assert.equal(getNativeCurrency(mockState), 'ETH') + assert.strictEqual(getNativeCurrency(mockState), 'ETH') }) }) describe('getCurrentNetwork()', function () { it('should return the id of the currently selected network', function () { - assert.equal(getCurrentNetwork(mockState), '3') + assert.strictEqual(getCurrentNetwork(mockState), '3') }) }) describe('getGasLimit()', function () { it('should return the send.gasLimit', function () { - assert.equal(getGasLimit(mockState), '0xFFFF') + assert.strictEqual(getGasLimit(mockState), '0xFFFF') }) }) describe('getGasPrice()', function () { it('should return the send.gasPrice', function () { - assert.equal(getGasPrice(mockState), '0xaa') + assert.strictEqual(getGasPrice(mockState), '0xaa') }) }) describe('getGasTotal()', function () { it('should return the send.gasTotal', function () { - assert.equal(getGasTotal(mockState), 'a9ff56') + assert.strictEqual(getGasTotal(mockState), 'a9ff56') }) }) describe('getPrimaryCurrency()', function () { it('should return the symbol of the send token', function () { - assert.equal( + assert.strictEqual( getPrimaryCurrency({ metamask: { send: { token: { symbol: 'DEF' } } }, }), @@ -153,7 +153,7 @@ describe('send selectors', function () { describe('getSendToken()', function () { it('should return the current send token if set', function () { - assert.deepEqual( + assert.deepStrictEqual( getSendToken({ metamask: { send: { @@ -176,7 +176,7 @@ describe('send selectors', function () { describe('getSendTokenContract()', function () { it('should return the contract at the send token address', function () { - assert.equal( + assert.strictEqual( getSendTokenContract({ metamask: { send: { @@ -194,7 +194,7 @@ describe('send selectors', function () { it('should return null if send token is not set', function () { const modifiedMetamaskState = { ...mockState.metamask, send: {} } - assert.equal( + assert.strictEqual( getSendTokenContract({ ...mockState, metamask: modifiedMetamaskState }), null, ) @@ -203,31 +203,31 @@ describe('send selectors', function () { describe('getSendAmount()', function () { it('should return the send.amount', function () { - assert.equal(getSendAmount(mockState), '0x080') + assert.strictEqual(getSendAmount(mockState), '0x080') }) }) describe('getSendEditingTransactionId()', function () { it('should return the send.editingTransactionId', function () { - assert.equal(getSendEditingTransactionId(mockState), 97531) + assert.strictEqual(getSendEditingTransactionId(mockState), 97531) }) }) describe('getSendErrors()', function () { it('should return the send.errors', function () { - assert.deepEqual(getSendErrors(mockState), { someError: null }) + assert.deepStrictEqual(getSendErrors(mockState), { someError: null }) }) }) describe('getSendHexDataFeatureFlagState()', function () { it('should return the sendHexData feature flag state', function () { - assert.deepEqual(getSendHexDataFeatureFlagState(mockState), true) + assert.deepStrictEqual(getSendHexDataFeatureFlagState(mockState), true) }) }) describe('getSendFrom()', function () { it('should return the send.from', function () { - assert.deepEqual( + assert.deepStrictEqual( getSendFrom(mockState), '0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb', ) @@ -236,7 +236,7 @@ describe('send selectors', function () { describe('getSendFromBalance()', function () { it('should get the send.from balance if it exists', function () { - assert.equal(getSendFromBalance(mockState), '0x37452b1315889f80') + assert.strictEqual(getSendFromBalance(mockState), '0x37452b1315889f80') }) it('should get the selected account balance if the send.from does not exist', function () { @@ -248,13 +248,13 @@ describe('send selectors', function () { }, }, } - assert.equal(getSendFromBalance(editedMockState), '0x0') + assert.strictEqual(getSendFromBalance(editedMockState), '0x0') }) }) describe('getSendFromObject()', function () { it('should return send.from if it exists', function () { - assert.deepEqual(getSendFromObject(mockState), { + assert.deepStrictEqual(getSendFromObject(mockState), { address: '0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb', balance: '0x37452b1315889f80', code: '0x', @@ -271,7 +271,7 @@ describe('send selectors', function () { }, }, } - assert.deepEqual(getSendFromObject(editedMockState), { + assert.deepStrictEqual(getSendFromObject(editedMockState), { code: '0x', balance: '0x0', nonce: '0x0', @@ -282,19 +282,19 @@ describe('send selectors', function () { describe('getSendMaxModeState()', function () { it('should return send.maxModeOn', function () { - assert.equal(getSendMaxModeState(mockState), false) + assert.strictEqual(getSendMaxModeState(mockState), false) }) }) describe('getSendTo()', function () { it('should return send.to', function () { - assert.equal(getSendTo(mockState), '0x987fedabc') + assert.strictEqual(getSendTo(mockState), '0x987fedabc') }) }) describe('getSendToAccounts()', function () { it('should return an array including all the users accounts and the address book', function () { - assert.deepEqual(getSendToAccounts(mockState), [ + assert.deepStrictEqual(getSendToAccounts(mockState), [ { code: '0x', balance: '0x47c9d71831c76efe', @@ -334,13 +334,13 @@ describe('send selectors', function () { describe('getTokenBalance()', function () { it('should', function () { - assert.equal(getTokenBalance(mockState), 3434) + assert.strictEqual(getTokenBalance(mockState), 3434) }) }) describe('getUnapprovedTxs()', function () { it('should return the unapproved txs', function () { - assert.deepEqual(getUnapprovedTxs(mockState), { + assert.deepStrictEqual(getUnapprovedTxs(mockState), { 4768706228115573: { id: 4768706228115573, time: 1487363153561, @@ -375,7 +375,7 @@ describe('send selectors', function () { }, } - assert.equal(sendAmountIsInError(state), true) + assert.strictEqual(sendAmountIsInError(state), true) }) it('should return false if send.errors.amount is falsy', function () { @@ -387,7 +387,7 @@ describe('send selectors', function () { }, } - assert.equal(sendAmountIsInError(state), false) + assert.strictEqual(sendAmountIsInError(state), false) }) }) }) @@ -403,7 +403,7 @@ describe('send selectors', function () { }, } - assert.equal(getGasLoadingError(state), 'abc') + assert.strictEqual(getGasLoadingError(state), 'abc') }) }) @@ -417,7 +417,7 @@ describe('send selectors', function () { }, } - assert.equal(gasFeeIsInError(state), true) + assert.strictEqual(gasFeeIsInError(state), true) }) it('should return false send.errors.gasFee is falsely', function () { @@ -429,7 +429,7 @@ describe('send selectors', function () { }, } - assert.equal(gasFeeIsInError(state), false) + assert.strictEqual(gasFeeIsInError(state), false) }) }) @@ -441,7 +441,7 @@ describe('send selectors', function () { }, } - assert.equal(getGasButtonGroupShown(state), 'foobar') + assert.strictEqual(getGasButtonGroupShown(state), 'foobar') }) }) }) @@ -457,11 +457,14 @@ describe('send selectors', function () { describe('getTitleKey()', function () { it('should return the correct key when "to" is empty', function () { - assert.equal(getTitleKey(getMetamaskSendMockState({})), 'addRecipient') + assert.strictEqual( + getTitleKey(getMetamaskSendMockState({})), + 'addRecipient', + ) }) it('should return the correct key when getSendEditingTransactionId is truthy', function () { - assert.equal( + assert.strictEqual( getTitleKey( getMetamaskSendMockState({ to: true, @@ -474,7 +477,7 @@ describe('send selectors', function () { }) it('should return the correct key when getSendEditingTransactionId is falsy and getSendToken is truthy', function () { - assert.equal( + assert.strictEqual( getTitleKey( getMetamaskSendMockState({ to: true, @@ -487,7 +490,7 @@ describe('send selectors', function () { }) it('should return the correct key when getSendEditingTransactionId is falsy and getSendToken is falsy', function () { - assert.equal( + assert.strictEqual( getTitleKey( getMetamaskSendMockState({ to: true, @@ -510,7 +513,7 @@ describe('send selectors', function () { describe('isSendFormInError()', function () { it('should return true if any of the values of the object returned by getSendErrors are truthy', function () { - assert.equal( + assert.strictEqual( isSendFormInError( getSendMockState({ errors: [true], @@ -521,7 +524,7 @@ describe('send selectors', function () { }) it('should return false if all of the values of the object returned by getSendErrors are falsy', function () { - assert.equal( + assert.strictEqual( isSendFormInError( getSendMockState({ errors: [], @@ -529,7 +532,7 @@ describe('send selectors', function () { ), false, ) - assert.equal( + assert.strictEqual( isSendFormInError( getSendMockState({ errors: [false], diff --git a/ui/app/selectors/tests/transactions.test.js b/ui/app/selectors/tests/transactions.test.js index 6964ad161..593055392 100644 --- a/ui/app/selectors/tests/transactions.test.js +++ b/ui/app/selectors/tests/transactions.test.js @@ -35,7 +35,7 @@ describe('Transaction Selectors', function () { const msgSelector = unapprovedMessagesSelector(state) assert(Array.isArray(msgSelector)) - assert.deepEqual(msgSelector, [msg]) + assert.deepStrictEqual(msgSelector, [msg]) }) it('returns personal sign from unapprovedPersonalMsgsSelector', function () { @@ -62,7 +62,7 @@ describe('Transaction Selectors', function () { const msgSelector = unapprovedMessagesSelector(state) assert(Array.isArray(msgSelector)) - assert.deepEqual(msgSelector, [msg]) + assert.deepStrictEqual(msgSelector, [msg]) }) it('returns typed message from unapprovedTypedMessagesSelector', function () { @@ -90,7 +90,7 @@ describe('Transaction Selectors', function () { const msgSelector = unapprovedMessagesSelector(state) assert(Array.isArray(msgSelector)) - assert.deepEqual(msgSelector, [msg]) + assert.deepStrictEqual(msgSelector, [msg]) }) }) @@ -133,7 +133,7 @@ describe('Transaction Selectors', function () { const selectedTx = transactionsSelector(state) assert(Array.isArray(selectedTx)) - assert.deepEqual(selectedTx, orderedTxList) + assert.deepStrictEqual(selectedTx, orderedTxList) }) }) @@ -191,7 +191,10 @@ describe('Transaction Selectors', function () { }, ] - assert.deepEqual(nonceSortedTransactionsSelector(state), expectedResult) + assert.deepStrictEqual( + nonceSortedTransactionsSelector(state), + expectedResult, + ) }) }) @@ -286,7 +289,7 @@ describe('Transaction Selectors', function () { }, ] - assert.deepEqual( + assert.deepStrictEqual( nonceSortedPendingTransactionsSelector(state), expectedResult, ) @@ -304,7 +307,7 @@ describe('Transaction Selectors', function () { }, ] - assert.deepEqual( + assert.deepStrictEqual( nonceSortedCompletedTransactionsSelector(state), expectedResult, ) @@ -312,7 +315,7 @@ describe('Transaction Selectors', function () { it('submittedPendingTransactionsSelector', function () { const expectedResult = [submittedTx] - assert.deepEqual( + assert.deepStrictEqual( submittedPendingTransactionsSelector(state), expectedResult, ) From 52d25f0df864d6cd62ff1bead02e919969b32bff Mon Sep 17 00:00:00 2001 From: Mark Stacey Date: Thu, 3 Dec 2020 13:55:42 -0330 Subject: [PATCH 23/32] Fix inflated gas estimates (#9984) If a `gasPrice` was specified in a transaction sent via a dapp, we would include it in our `eth_estimateGas` call, causing it to fail if the user had insufficient balance (for either the transaction amount or the gas fee). This resulted in the fallback gas estimate being used; the block gas limit. The block gas limit is quite a bit larger than most transactions need, so this resulted in wildly inflated gas costs being shown on our confirmation screen. The `gasPrice` has been removed from the `txParams` object we pass to `eth_estimateGas`, so now it won't perform any balance checks anymore. This ensures that we'll get a valid gas estimate, as long as geth is able to simulate the contract execution properly. Fixes #9967 --- app/scripts/controllers/transactions/tx-gas-utils.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/app/scripts/controllers/transactions/tx-gas-utils.js b/app/scripts/controllers/transactions/tx-gas-utils.js index 71d8d27fb..cf75d8919 100644 --- a/app/scripts/controllers/transactions/tx-gas-utils.js +++ b/app/scripts/controllers/transactions/tx-gas-utils.js @@ -1,6 +1,7 @@ import EthQuery from 'ethjs-query' import log from 'loglevel' import ethUtil from 'ethereumjs-util' +import { cloneDeep } from 'lodash' import { hexToBn, BnMultiplyByFraction, bnToHex } from '../../lib/util' /** @@ -56,7 +57,13 @@ export default class TxGasUtil { @returns {string} the estimated gas limit as a hex string */ async estimateTxGas(txMeta) { - const { txParams } = txMeta + const txParams = cloneDeep(txMeta.txParams) + + // `eth_estimateGas` can fail if the user has insufficient balance for the + // value being sent, or for the gas cost. We don't want to check their + // balance here, we just want the gas estimate. The gas price is removed + // to skip those balance checks. We check balance elsewhere. + delete txParams.gasPrice // estimate tx gas requirements return await this.query.estimateGas(txParams) From 7a2b3b908a58c4ef7e0d26eff5c58712696d4b5a Mon Sep 17 00:00:00 2001 From: Mark Stacey Date: Thu, 3 Dec 2020 14:00:51 -0330 Subject: [PATCH 24/32] Move initial e2e navitation into individual tests (#9979) The e2e test driver used to perform the initial navigation automatically within the `buildWebDriver` function, so that that step wouldn't need to be repeated at the beginning of each test. However this prevented you from doing any setup in the test before the first navigation. The navigation has now been moved into each individual test. It should be functionally equivalent, except now it's possible to control exactly when the first navigation occurs. A 1 second delay was also removed, as it didn't seem to be necessary when testing this. It was initially added as an attempted fix to an intermittent failure. It did not fix that failure. --- test/e2e/address-book.spec.js | 1 + test/e2e/benchmark.js | 1 + test/e2e/ethereum-on.spec.js | 1 + test/e2e/from-import-ui.spec.js | 1 + test/e2e/incremental-security.spec.js | 1 + test/e2e/metamask-responsive-ui.spec.js | 1 + test/e2e/metamask-ui.spec.js | 1 + test/e2e/metrics.spec.js | 1 + test/e2e/permissions.spec.js | 1 + test/e2e/send-edit.spec.js | 1 + test/e2e/signature-request.spec.js | 1 + test/e2e/tests/localization.spec.js | 1 + test/e2e/tests/personal-sign.spec.js | 1 + test/e2e/tests/simple-send.spec.js | 1 + test/e2e/threebox.spec.js | 2 ++ test/e2e/webdriver/index.js | 3 --- 16 files changed, 16 insertions(+), 3 deletions(-) diff --git a/test/e2e/address-book.spec.js b/test/e2e/address-book.spec.js index 6ed55b22b..3d0e2712b 100644 --- a/test/e2e/address-book.spec.js +++ b/test/e2e/address-book.spec.js @@ -29,6 +29,7 @@ describe('MetaMask', function () { }) const result = await buildWebDriver() driver = result.driver + await driver.navigate() }) afterEach(async function () { diff --git a/test/e2e/benchmark.js b/test/e2e/benchmark.js index 442533c04..a364ed62a 100644 --- a/test/e2e/benchmark.js +++ b/test/e2e/benchmark.js @@ -13,6 +13,7 @@ const ALL_PAGES = Object.values(PAGES) async function measurePage(pageName) { let metrics await withFixtures({ fixtures: 'imported-account' }, async ({ driver }) => { + await driver.navigate() const passwordField = await driver.findElement(By.css('#password')) await passwordField.sendKeys('correct horse battery staple') await passwordField.sendKeys(Key.ENTER) diff --git a/test/e2e/ethereum-on.spec.js b/test/e2e/ethereum-on.spec.js index 2d90f23d7..81f178c9d 100644 --- a/test/e2e/ethereum-on.spec.js +++ b/test/e2e/ethereum-on.spec.js @@ -28,6 +28,7 @@ describe('MetaMask', function () { }) const result = await buildWebDriver() driver = result.driver + await driver.navigate() }) afterEach(async function () { diff --git a/test/e2e/from-import-ui.spec.js b/test/e2e/from-import-ui.spec.js index ec3f68d42..dc5457f7d 100644 --- a/test/e2e/from-import-ui.spec.js +++ b/test/e2e/from-import-ui.spec.js @@ -35,6 +35,7 @@ describe('Using MetaMask with an existing account', function () { }) const result = await buildWebDriver() driver = result.driver + await driver.navigate() }) afterEach(async function () { diff --git a/test/e2e/incremental-security.spec.js b/test/e2e/incremental-security.spec.js index ca204baaf..cb0c67e3c 100644 --- a/test/e2e/incremental-security.spec.js +++ b/test/e2e/incremental-security.spec.js @@ -33,6 +33,7 @@ describe('MetaMask', function () { }) const result = await buildWebDriver() driver = result.driver + await driver.navigate() }) afterEach(async function () { diff --git a/test/e2e/metamask-responsive-ui.spec.js b/test/e2e/metamask-responsive-ui.spec.js index a3cc26db4..1474960ef 100644 --- a/test/e2e/metamask-responsive-ui.spec.js +++ b/test/e2e/metamask-responsive-ui.spec.js @@ -22,6 +22,7 @@ describe('MetaMask', function () { await ganacheServer.start() const result = await buildWebDriver({ responsive: true }) driver = result.driver + await driver.navigate() }) afterEach(async function () { diff --git a/test/e2e/metamask-ui.spec.js b/test/e2e/metamask-ui.spec.js index b98cf9f0b..f7a558ba9 100644 --- a/test/e2e/metamask-ui.spec.js +++ b/test/e2e/metamask-ui.spec.js @@ -23,6 +23,7 @@ describe('MetaMask', function () { await ganacheServer.start() const result = await buildWebDriver() driver = result.driver + await driver.navigate() }) afterEach(async function () { diff --git a/test/e2e/metrics.spec.js b/test/e2e/metrics.spec.js index ceca2cb64..9c32df14b 100644 --- a/test/e2e/metrics.spec.js +++ b/test/e2e/metrics.spec.js @@ -27,6 +27,7 @@ describe('Segment metrics', function () { mockSegment: true, }, async ({ driver, segmentSpy }) => { + await driver.navigate() const passwordField = await driver.findElement(By.css('#password')) await passwordField.sendKeys('correct horse battery staple') await passwordField.sendKeys(Key.ENTER) diff --git a/test/e2e/permissions.spec.js b/test/e2e/permissions.spec.js index 133bade16..4f15b625f 100644 --- a/test/e2e/permissions.spec.js +++ b/test/e2e/permissions.spec.js @@ -28,6 +28,7 @@ describe('MetaMask', function () { }) const result = await buildWebDriver() driver = result.driver + await driver.navigate() }) afterEach(async function () { diff --git a/test/e2e/send-edit.spec.js b/test/e2e/send-edit.spec.js index b11dde556..3c70d67e0 100644 --- a/test/e2e/send-edit.spec.js +++ b/test/e2e/send-edit.spec.js @@ -30,6 +30,7 @@ describe('Using MetaMask with an existing account', function () { }) const result = await buildWebDriver() driver = result.driver + await driver.navigate() }) afterEach(async function () { diff --git a/test/e2e/signature-request.spec.js b/test/e2e/signature-request.spec.js index 5857f175b..3e4307ffa 100644 --- a/test/e2e/signature-request.spec.js +++ b/test/e2e/signature-request.spec.js @@ -28,6 +28,7 @@ describe('MetaMask', function () { publicAddress = '0x5cfe73b6021e818b776b421b1c4db2474086a7e1' const result = await buildWebDriver() driver = result.driver + await driver.navigate() }) afterEach(async function () { diff --git a/test/e2e/tests/localization.spec.js b/test/e2e/tests/localization.spec.js index 7b17b95cc..5ba5558f7 100644 --- a/test/e2e/tests/localization.spec.js +++ b/test/e2e/tests/localization.spec.js @@ -16,6 +16,7 @@ describe('Localization', function () { await withFixtures( { fixtures: 'localization', ganacheOptions, title: this.test.title }, async ({ driver }) => { + await driver.navigate() const passwordField = await driver.findElement(By.css('#password')) await passwordField.sendKeys('correct horse battery staple') await passwordField.sendKeys(Key.ENTER) diff --git a/test/e2e/tests/personal-sign.spec.js b/test/e2e/tests/personal-sign.spec.js index dbead3dbd..462eab11b 100644 --- a/test/e2e/tests/personal-sign.spec.js +++ b/test/e2e/tests/personal-sign.spec.js @@ -21,6 +21,7 @@ describe('Personal sign', function () { title: this.test.title, }, async ({ driver }) => { + await driver.navigate() const passwordField = await driver.findElement(By.css('#password')) await passwordField.sendKeys('correct horse battery staple') await passwordField.sendKeys(Key.ENTER) diff --git a/test/e2e/tests/simple-send.spec.js b/test/e2e/tests/simple-send.spec.js index 68128dab7..332117951 100644 --- a/test/e2e/tests/simple-send.spec.js +++ b/test/e2e/tests/simple-send.spec.js @@ -15,6 +15,7 @@ describe('Simple send', function () { await withFixtures( { fixtures: 'imported-account', ganacheOptions, title: this.test.title }, async ({ driver }) => { + await driver.navigate() const passwordField = await driver.findElement(By.css('#password')) await passwordField.sendKeys('correct horse battery staple') await passwordField.sendKeys(Key.ENTER) diff --git a/test/e2e/threebox.spec.js b/test/e2e/threebox.spec.js index 107531bff..55f771a44 100644 --- a/test/e2e/threebox.spec.js +++ b/test/e2e/threebox.spec.js @@ -31,6 +31,7 @@ describe('MetaMask', function () { }) const result = await buildWebDriver({ port: await getPort() }) driver = result.driver + await driver.navigate() }) afterEach(async function () { @@ -189,6 +190,7 @@ describe('MetaMask', function () { before(async function () { const result = await buildWebDriver({ port: await getPort() }) driver2 = result.driver + await driver2.navigate() }) after(async function () { diff --git a/test/e2e/webdriver/index.js b/test/e2e/webdriver/index.js index 093883a1a..024478065 100644 --- a/test/e2e/webdriver/index.js +++ b/test/e2e/webdriver/index.js @@ -15,9 +15,6 @@ async function buildWebDriver({ responsive, port } = {}) { } = await buildBrowserWebDriver(browser, { extensionPath, responsive, port }) await setupFetchMocking(seleniumDriver) const driver = new Driver(seleniumDriver, browser, extensionUrl) - await driver.navigate() - - await driver.delay(1000) return { driver, From b1b6d7ae382eab41baa682f4504fcbed40500f63 Mon Sep 17 00:00:00 2001 From: Mark Stacey Date: Thu, 3 Dec 2020 14:30:50 -0330 Subject: [PATCH 25/32] Fix intermittent metrics e2e test failure (#9980) The metrics e2e test would fail if the segment events still weren't dispatched when the page loaded. The Segment events are sent on a set interval, so it isn't abnormal for them to lag behind the page load itself. The `waitUntilCalled` utility has been used to wait until all required events have been dispatched. The `wait-until-called` module was converted to an ES5 module, so that it could be used from an e2e test. The optional `callCount` parameter has also been added, to allow waiting for more than one call. The `segmentSpy` had to be converted to a `segmentStub`, to allow the `waitUntilCalled` utility to be used. --- .eslintrc.js | 1 + test/e2e/helpers.js | 8 ++++---- test/e2e/metrics.spec.js | 16 +++++++++------- test/lib/wait-until-called.js | 26 +++++++++++++++++++------- 4 files changed, 33 insertions(+), 18 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 35541a9ba..184f6ce89 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -197,6 +197,7 @@ module.exports = { 'stylelint.config.js', 'development/**/*.js', 'test/e2e/**/*.js', + 'test/lib/wait-until-called.js', 'test/env.js', 'test/setup.js', ], diff --git a/test/e2e/helpers.js b/test/e2e/helpers.js index de5986546..926f67177 100644 --- a/test/e2e/helpers.js +++ b/test/e2e/helpers.js @@ -27,7 +27,7 @@ async function withFixtures(options, testSuite) { const ganacheServer = new Ganache() let dappServer let segmentServer - let segmentSpy + let segmentStub let webDriver try { @@ -52,10 +52,10 @@ async function withFixtures(options, testSuite) { }) } if (mockSegment) { - segmentSpy = sinon.spy() + segmentStub = sinon.stub() segmentServer = createSegmentServer((_request, response, events) => { for (const event of events) { - segmentSpy(event) + segmentStub(event) } response.statusCode = 200 response.end() @@ -67,7 +67,7 @@ async function withFixtures(options, testSuite) { await testSuite({ driver, - segmentSpy, + segmentStub, }) if (process.env.SELENIUM_BROWSER === 'chrome') { diff --git a/test/e2e/metrics.spec.js b/test/e2e/metrics.spec.js index 9c32df14b..585a44e35 100644 --- a/test/e2e/metrics.spec.js +++ b/test/e2e/metrics.spec.js @@ -1,5 +1,6 @@ const { strict: assert } = require('assert') const { By, Key } = require('selenium-webdriver') +const waitUntilCalled = require('../lib/wait-until-called') const { withFixtures } = require('./helpers') /** @@ -26,26 +27,27 @@ describe('Segment metrics', function () { title: this.test.title, mockSegment: true, }, - async ({ driver, segmentSpy }) => { + async ({ driver, segmentStub }) => { + const threeSegmentEventsReceived = waitUntilCalled(segmentStub, null, 3) await driver.navigate() + const passwordField = await driver.findElement(By.css('#password')) await passwordField.sendKeys('correct horse battery staple') await passwordField.sendKeys(Key.ENTER) - // find arbitary element to ensure Home page has loaded - await driver.findElement(By.css('[data-testid="eth-overview-send"]')) + await threeSegmentEventsReceived - assert.ok(segmentSpy.called, 'Segment should receive metrics') + assert.ok(segmentStub.called, 'Segment should receive metrics') - const firstSegmentEvent = segmentSpy.getCall(0).args[0] + const firstSegmentEvent = segmentStub.getCall(0).args[0] assert.equal(firstSegmentEvent.name, 'Home') assert.equal(firstSegmentEvent.context.page.path, '/') - const secondSegmentEvent = segmentSpy.getCall(1).args[0] + const secondSegmentEvent = segmentStub.getCall(1).args[0] assert.equal(secondSegmentEvent.name, 'Unlock Page') assert.equal(secondSegmentEvent.context.page.path, '/unlock') - const thirdSegmentEvent = segmentSpy.getCall(2).args[0] + const thirdSegmentEvent = segmentStub.getCall(2).args[0] assert.equal(thirdSegmentEvent.name, 'Home') assert.equal(thirdSegmentEvent.context.page.path, '/') }, diff --git a/test/lib/wait-until-called.js b/test/lib/wait-until-called.js index 7a2eb2704..752ee7675 100644 --- a/test/lib/wait-until-called.js +++ b/test/lib/wait-until-called.js @@ -9,18 +9,30 @@ * * @param {import('sinon').stub} stub - A sinon stub of a function * @param {unknown} [wrappedThis] - The object the stubbed function was called on, if any (i.e. the `this` value) + * @param {number} [callCount] - The number of calls to wait for. Defaults to 1. * @returns {Promise} A Promise that resolves when the stub has been called */ -export default function waitUntilCalled(stub, wrappedThis = null) { - let wasCalled - const stubHasBeenCalled = new Promise((resolve) => { - wasCalled = resolve +function waitUntilCalled(stub, wrappedThis = null, callCount = 1) { + let numCalls = 0 + let resolve + const stubHasBeenCalled = new Promise((_resolve) => { + resolve = _resolve }) stub.callsFake((...args) => { - if (stub.wrappedMethod) { - stub.wrappedMethod.call(wrappedThis, ...args) + try { + if (stub.wrappedMethod) { + stub.wrappedMethod.call(wrappedThis, ...args) + } + } finally { + if (numCalls < callCount) { + numCalls += 1 + if (numCalls === callCount) { + resolve() + } + } } - wasCalled() }) return stubHasBeenCalled } + +module.exports = waitUntilCalled From 703a063ad19bc26f080a50afefab8ead302b790d Mon Sep 17 00:00:00 2001 From: Mark Stacey Date: Thu, 3 Dec 2020 15:35:11 -0330 Subject: [PATCH 26/32] Fix metrics error when options are not used (#9985) Attempts to send metrics would fail when no `options` were used. This was because when the options parameter was not set, it was often sent over our RPC connection as `undefined`, which gets serialized to `null` when the message is converted to JSON. This `null` parameter didn't trigger the default parameter set in the metametrics controller, as default parameters are only used for `undefined`. Instead the `options` parameter is now treated as fully optional, with no default value set. The optional chaining operator is used to ensure it won't blow up if it's not set. A fallback of `{}` was used for the one destructure case as well. --- app/scripts/controllers/metametrics.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/app/scripts/controllers/metametrics.js b/app/scripts/controllers/metametrics.js index 810b55276..23e6dfcf2 100644 --- a/app/scripts/controllers/metametrics.js +++ b/app/scripts/controllers/metametrics.js @@ -215,7 +215,7 @@ export default class MetaMetricsController { * event appropriately. * @private * @param {SegmentEventPayload} payload - properties to attach to event - * @param {MetaMetricsEventOptions} options - options for routing and + * @param {MetaMetricsEventOptions} [options] - options for routing and * handling the event * @returns {Promise} */ @@ -225,10 +225,10 @@ export default class MetaMetricsController { metaMetricsId: metaMetricsIdOverride, matomoEvent, flushImmediately, - } = options + } = options || {} let idType = 'userId' let idValue = this.state.metaMetricsId - let excludeMetaMetricsId = options.excludeMetaMetricsId ?? false + let excludeMetaMetricsId = options?.excludeMetaMetricsId ?? false // This is carried over from the old implementation, and will likely need // to be updated to work with the new tracking plan. I think we should use // a config setting for this instead of trying to match the event name @@ -282,15 +282,15 @@ export default class MetaMetricsController { /** * track a page view with Segment * @param {MetaMetricsPagePayload} payload - details of the page viewed - * @param {MetaMetricsPageOptions} options - options for handling the page + * @param {MetaMetricsPageOptions} [options] - options for handling the page * view */ - trackPage({ name, params, environmentType, page, referrer }, options = {}) { + trackPage({ name, params, environmentType, page, referrer }, options) { if (this.state.participateInMetaMetrics === false) { return } - if (this.state.participateInMetaMetrics === null && !options.isOptInPath) { + if (this.state.participateInMetaMetrics === null && !options?.isOptInPath) { return } const { metaMetricsId } = this.state @@ -316,16 +316,16 @@ export default class MetaMetricsController { * with sensitiveProperties into two events, tracking the sensitiveProperties * with the anonymousId only. * @param {MetaMetricsEventPayload} payload - details of the event - * @param {MetaMetricsEventOptions} options - options for handling/routing the event + * @param {MetaMetricsEventOptions} [options] - options for handling/routing the event * @returns {Promise} */ - async trackEvent(payload, options = {}) { + async trackEvent(payload, options) { // event and category are required fields for all payloads if (!payload.event || !payload.category) { throw new Error('Must specify event and category.') } - if (!this.state.participateInMetaMetrics && !options.isOptIn) { + if (!this.state.participateInMetaMetrics && !options?.isOptIn) { return } @@ -337,7 +337,7 @@ export default class MetaMetricsController { // sensitiveProperties will only be tracked using the anonymousId property and generic id // If the event options already specify to exclude the metaMetricsId we throw an error as // a signal to the developer that the event was implemented incorrectly - if (options.excludeMetaMetricsId === true) { + if (options?.excludeMetaMetricsId === true) { throw new Error( 'sensitiveProperties was specified in an event payload that also set the excludeMetaMetricsId flag', ) From cce690c3d8b536927f2a1f56f8cfff2ec221410d Mon Sep 17 00:00:00 2001 From: Mark Stacey Date: Thu, 3 Dec 2020 16:23:36 -0330 Subject: [PATCH 27/32] Remove unused state from Redux `gas` slice (#9975) The `errors` and `total` state has been removed from the `gas` slice, along with related functions. It appears to have been unused for a long time, though I'm not exactly sure as of when. --- ui/app/ducks/gas/gas-duck.test.js | 43 ----------------------- ui/app/ducks/gas/gas.duck.js | 33 ----------------- ui/app/selectors/custom-gas.js | 8 ----- ui/app/selectors/tests/custom-gas.test.js | 16 --------- 4 files changed, 100 deletions(-) diff --git a/ui/app/ducks/gas/gas-duck.test.js b/ui/app/ducks/gas/gas-duck.test.js index aceea5efb..519741f25 100644 --- a/ui/app/ducks/gas/gas-duck.test.js +++ b/ui/app/ducks/gas/gas-duck.test.js @@ -14,8 +14,6 @@ const { setBasicGasEstimateData, setCustomGasPrice, setCustomGasLimit, - setCustomGasTotal, - setCustomGasErrors, resetCustomGasState, fetchBasicGasEstimates, } = GasDuck @@ -68,7 +66,6 @@ describe('Gas Duck', function () { safeLow: null, }, basicEstimateIsLoading: true, - errors: {}, basicPriceEstimatesLastRetrieved: 0, } const BASIC_GAS_ESTIMATE_LOADING_FINISHED = @@ -77,10 +74,8 @@ describe('Gas Duck', function () { 'metamask/gas/BASIC_GAS_ESTIMATE_LOADING_STARTED' const RESET_CUSTOM_GAS_STATE = 'metamask/gas/RESET_CUSTOM_GAS_STATE' const SET_BASIC_GAS_ESTIMATE_DATA = 'metamask/gas/SET_BASIC_GAS_ESTIMATE_DATA' - const SET_CUSTOM_GAS_ERRORS = 'metamask/gas/SET_CUSTOM_GAS_ERRORS' const SET_CUSTOM_GAS_LIMIT = 'metamask/gas/SET_CUSTOM_GAS_LIMIT' const SET_CUSTOM_GAS_PRICE = 'metamask/gas/SET_CUSTOM_GAS_PRICE' - const SET_CUSTOM_GAS_TOTAL = 'metamask/gas/SET_CUSTOM_GAS_TOTAL' const SET_BASIC_PRICE_ESTIMATES_LAST_RETRIEVED = 'metamask/gas/SET_BASIC_PRICE_ESTIMATES_LAST_RETRIEVED' @@ -143,26 +138,6 @@ describe('Gas Duck', function () { ) }) - it('should set customData.total when receiving a SET_CUSTOM_GAS_TOTAL action', function () { - assert.deepStrictEqual( - GasReducer(mockState, { - type: SET_CUSTOM_GAS_TOTAL, - value: 10000, - }), - { customData: { total: 10000 }, ...mockState }, - ) - }) - - it('should set errors when receiving a SET_CUSTOM_GAS_ERRORS action', function () { - assert.deepStrictEqual( - GasReducer(mockState, { - type: SET_CUSTOM_GAS_ERRORS, - value: { someError: 'error_error' }, - }), - { errors: { someError: 'error_error' }, ...mockState }, - ) - }) - it('should return the initial state in response to a RESET_CUSTOM_GAS_STATE action', function () { assert.deepStrictEqual( GasReducer(mockState, { type: RESET_CUSTOM_GAS_STATE }), @@ -318,24 +293,6 @@ describe('Gas Duck', function () { }) }) - describe('setCustomGasTotal', function () { - it('should create the correct action', function () { - assert.deepStrictEqual(setCustomGasTotal('mockCustomGasTotal'), { - type: SET_CUSTOM_GAS_TOTAL, - value: 'mockCustomGasTotal', - }) - }) - }) - - describe('setCustomGasErrors', function () { - it('should create the correct action', function () { - assert.deepStrictEqual(setCustomGasErrors('mockErrorObject'), { - type: SET_CUSTOM_GAS_ERRORS, - value: 'mockErrorObject', - }) - }) - }) - describe('resetCustomGasState', function () { it('should create the correct action', function () { assert.deepStrictEqual(resetCustomGasState(), { diff --git a/ui/app/ducks/gas/gas.duck.js b/ui/app/ducks/gas/gas.duck.js index 751b4304b..83b15ecf1 100644 --- a/ui/app/ducks/gas/gas.duck.js +++ b/ui/app/ducks/gas/gas.duck.js @@ -12,10 +12,8 @@ const BASIC_GAS_ESTIMATE_LOADING_STARTED = const RESET_CUSTOM_GAS_STATE = 'metamask/gas/RESET_CUSTOM_GAS_STATE' const RESET_CUSTOM_DATA = 'metamask/gas/RESET_CUSTOM_DATA' const SET_BASIC_GAS_ESTIMATE_DATA = 'metamask/gas/SET_BASIC_GAS_ESTIMATE_DATA' -const SET_CUSTOM_GAS_ERRORS = 'metamask/gas/SET_CUSTOM_GAS_ERRORS' const SET_CUSTOM_GAS_LIMIT = 'metamask/gas/SET_CUSTOM_GAS_LIMIT' const SET_CUSTOM_GAS_PRICE = 'metamask/gas/SET_CUSTOM_GAS_PRICE' -const SET_CUSTOM_GAS_TOTAL = 'metamask/gas/SET_CUSTOM_GAS_TOTAL' const SET_BASIC_PRICE_ESTIMATES_LAST_RETRIEVED = 'metamask/gas/SET_BASIC_PRICE_ESTIMATES_LAST_RETRIEVED' @@ -31,7 +29,6 @@ const initState = { }, basicEstimateIsLoading: true, basicPriceEstimatesLastRetrieved: 0, - errors: {}, } // Reducer @@ -68,22 +65,6 @@ export default function reducer(state = initState, action) { limit: action.value, }, } - case SET_CUSTOM_GAS_TOTAL: - return { - ...state, - customData: { - ...state.customData, - total: action.value, - }, - } - case SET_CUSTOM_GAS_ERRORS: - return { - ...state, - errors: { - ...state.errors, - ...action.value, - }, - } case SET_BASIC_PRICE_ESTIMATES_LAST_RETRIEVED: return { ...state, @@ -211,20 +192,6 @@ export function setCustomGasLimit(newLimit) { } } -export function setCustomGasTotal(newTotal) { - return { - type: SET_CUSTOM_GAS_TOTAL, - value: newTotal, - } -} - -export function setCustomGasErrors(newErrors) { - return { - type: SET_CUSTOM_GAS_ERRORS, - value: newErrors, - } -} - export function setBasicPriceEstimatesLastRetrieved(retrievalTime) { return { type: SET_BASIC_PRICE_ESTIMATES_LAST_RETRIEVED, diff --git a/ui/app/selectors/custom-gas.js b/ui/app/selectors/custom-gas.js index 44e2af494..8b1df8b89 100644 --- a/ui/app/selectors/custom-gas.js +++ b/ui/app/selectors/custom-gas.js @@ -13,10 +13,6 @@ import { getCurrentCurrency, getIsMainnet, getPreferences } from '.' const NUMBER_OF_DECIMALS_SM_BTNS = 5 -export function getCustomGasErrors(state) { - return state.gas.errors -} - export function getCustomGasLimit(state) { return state.gas.customData.limit } @@ -25,10 +21,6 @@ export function getCustomGasPrice(state) { return state.gas.customData.price } -export function getCustomGasTotal(state) { - return state.gas.customData.total -} - export function getBasicGasEstimateLoadingStatus(state) { return state.gas.basicEstimateIsLoading } diff --git a/ui/app/selectors/tests/custom-gas.test.js b/ui/app/selectors/tests/custom-gas.test.js index 9cbbf5c0d..cd5d9686e 100644 --- a/ui/app/selectors/tests/custom-gas.test.js +++ b/ui/app/selectors/tests/custom-gas.test.js @@ -2,10 +2,8 @@ import assert from 'assert' import proxyquire from 'proxyquire' const { - getCustomGasErrors, getCustomGasLimit, getCustomGasPrice, - getCustomGasTotal, getRenderableBasicEstimateData, getRenderableEstimateDataForSmallButtonsFromGWEI, } = proxyquire('../custom-gas', {}) @@ -25,20 +23,6 @@ describe('custom-gas selectors', function () { }) }) - describe('getCustomGasTotal()', function () { - it('should return gas.customData.total', function () { - const mockState = { gas: { customData: { total: 'mockTotal' } } } - assert.strictEqual(getCustomGasTotal(mockState), 'mockTotal') - }) - }) - - describe('getCustomGasErrors()', function () { - it('should return gas.errors', function () { - const mockState = { gas: { errors: 'mockErrors' } } - assert.strictEqual(getCustomGasErrors(mockState), 'mockErrors') - }) - }) - describe('getRenderableBasicEstimateData()', function () { const tests = [ { From c515591e7b67794031a0327fb981d0f8b871300a Mon Sep 17 00:00:00 2001 From: Erik Marks <25517051+rekmarks@users.noreply.github.com> Date: Thu, 3 Dec 2020 13:14:21 -0800 Subject: [PATCH 28/32] Add 48x48 icon (#9993) --- app/images/icon-48.png | Bin 0 -> 2416 bytes app/manifest/_base.json | 1 + 2 files changed, 1 insertion(+) create mode 100644 app/images/icon-48.png diff --git a/app/images/icon-48.png b/app/images/icon-48.png new file mode 100644 index 0000000000000000000000000000000000000000..91d0467a13d59225e44dbeb79ba654f302eee8c9 GIT binary patch literal 2416 zcmV-$36J)PP)2H?e*I0{IqtO#A~R9TL}^#(nca_*E|pj31L4J!2`1M00>?ZsZH|IDnX$S zHHt`{kU$XksVYT^0}_2e;599O2~yLbq=CkG{nxs6YOlS!-rf1RmvioVyni#ZySBwo z)lV9acjlg%bI$$F&%Fcialz?$Gz$NR(42qv2E%Xt@*5q=qX+b{{iFYU8UDvGeL5C} zP+;)R`{wXp=gh+wf4|U4*BSje7w?J-u1wJXhq?oByeF6f0pqqJUhaMAeggiBm_FAZ zSHK=DSTKBZ-iW^azA3NUoDW=jb1|V6f3Oi{Lx2YSYuSnpJsuiq*OigkvwcYhY|LT? z8k0=Ie*oldEf_q-8Jq^-(R2a5c_#;Jcy^#EY!FWgIRj^(+Bc1-SouSAmBADHgE%8v z>7syy!q}K;7}t9*CsVM4kV@j|Wr;@Yxu?3v6kx;PgNV)mDFsL= zx7*2}#uMQda|W6~Iv0qVwmMv{w1Wrh9A3XyNf|dV5LcKReY`-FdSZW|_CYu~yCMcO zgXK&RxL`Hci85~_3(z1^MDT|5KXH+~bF3#&F&hFMWm*gZnrP@brlr&o=9~fJckA=r4GM#|HOwZrp#FPZL6o8y`SNFUNht$q6bkq&Qb6Se z8k#O}_}%?N(_XKD;1i0X+6mYOC?;q&-dVE1FqFFE3#KZKe)V>4d&(oY%4eKHwgOEA zvll2!op_9<)_oSR;=`}+2yohgZ9*0@=`sw4Td)HlN=<*nJ?|%1_)aOmsk1Zyd!22! z1yrf2*mXxV&oSL?8hrh8Ef_Cb47xHnI zu#)4jB?vL}!#{qIkk#i{to<5JY8Nz#LtPr2=nGM6yLnAhg{J|O|H%M34rTgw7wNXJ zwgn>?>p#+~zAD|OD0~P{O~nB&df<3WuemOKSixQN^y;tbAjJ$mbUBfdy%2C)jWZ^E z(`X1s9@?isY?lI&fCeGey>$>mN616nhfF?KR{_OF6 z*D$mP%SZKeGO2J(o{K{ZSgbO6?@Xg$ch%YEo+?vW4Q$)H*tNHsn+@S&T0nAH6b)Lb z@(M1{M&EdkSW{Zm8*1=mR5456r{?Ix)g?si;F4&~e zMhx&lXmD9Zc{-qR=x77@Qr8-E?zP}ovmJ2rL93jFQ+q!0lntWnYaevLKFs%D>`uc# zcLw@9@*s?2i_wVp9c<93xHFf1v1b~28*5aUb|A8O6{2lc#r0LJ5e)CqELHDNkW2@XAJEoc%M)TFJ&s=1!UT0x4q8DL-y3A@OU zVQsAzGz%{50Y&io*~blDd{tHNOcT)DWm-d9TN^8&#I;l=K&u7iW?5`pRoN-Ofgwzr>jeeOe92HM zSVSYvZOQqPlEQU=h>BqK?5txPr&xCuU;~4%HEslNH0<_9%Z>w~x zwlN#j+|exBWsREZ;^}hb$-^W=$`{918WwKluFt5(BQH%|SL8lFZEn?p9u)F$P~P*9 z@@p7~6sUxSv<>sP%BnsHG-fU9ZE#2z&=RV@sKD8|PG?Cz?C`E*VT#uiYL9Suuu|-2 zs=Y?sT?zHW&;Fi=pZxZ&tNfW0z3|MZ1Sn#q;(Bp*n50fP+*m5bPG4?BNZYw(jWr@f zUU#Te-ig|~J`L+neor1Z7Q8dcpO&MLjXy8Pk&FW;xErMo!DNQq)0HzoG@3ormp~`P z>j^qk(zK%Dg}xIN%4D+Zp0ZQPS$TF0R+pzBFn<%2slPQ$9RiNJ<$SNxN*Bc>gZeZ= zq#|wht(DIX$ASkB#j0=KpPBO%TwJPbGsqA#+6(!8Ur6rx%jG0qibEq{d~-*A(*Rsl zB#;*8-NwspJVi`$Ou3Y`XvQX9*&hq0mVXq`^}$dugp^Wg96a}(Z(_9#xxP1>%fnhG zi!==5`#5fLy#v?Gc|(Llv>R71W$@XWU^c#XvmfHB-M ziDSX~DymAx#PCQS9DTRf)qv@9kH!I8lHN Date: Thu, 3 Dec 2020 20:25:23 -0330 Subject: [PATCH 29/32] Migration to remove legacy local storage keys from localStorage (#9986) * Migration to remove legacy local storage keys from localStorage * Update app/scripts/migrations/050.js Co-authored-by: Mark Stacey * Update app/scripts/migrations/050.js Co-authored-by: Mark Stacey * Fix unit tests for migration 50 * Fixing stubbing and localstorage reference in migration 50 * Update test/helper.js Co-authored-by: Mark Stacey Co-authored-by: Mark Stacey --- app/scripts/migrations/050.js | 32 ++++++++++++ app/scripts/migrations/index.js | 1 + test/helper.js | 5 +- test/unit/migrations/050-test.js | 89 ++++++++++++++++++++++++++++++++ 4 files changed, 125 insertions(+), 2 deletions(-) create mode 100644 app/scripts/migrations/050.js create mode 100644 test/unit/migrations/050-test.js diff --git a/app/scripts/migrations/050.js b/app/scripts/migrations/050.js new file mode 100644 index 000000000..af2873873 --- /dev/null +++ b/app/scripts/migrations/050.js @@ -0,0 +1,32 @@ +import { cloneDeep } from 'lodash' + +const version = 50 + +const LEGACY_LOCAL_STORAGE_KEYS = [ + 'METASWAP_GAS_PRICE_ESTIMATES_LAST_RETRIEVED', + 'METASWAP_GAS_PRICE_ESTIMATES', + 'cachedFetch', + 'BASIC_PRICE_ESTIMATES_LAST_RETRIEVED', + 'BASIC_PRICE_ESTIMATES', + 'BASIC_GAS_AND_TIME_API_ESTIMATES', + 'BASIC_GAS_AND_TIME_API_ESTIMATES_LAST_RETRIEVED', + 'GAS_API_ESTIMATES_LAST_RETRIEVED', + 'GAS_API_ESTIMATES', +] + +/** + * Migrate metaMetrics state to the new MetaMetrics controller + */ +export default { + version, + async migrate(originalVersionedData) { + const versionedData = cloneDeep(originalVersionedData) + versionedData.meta.version = version + + LEGACY_LOCAL_STORAGE_KEYS.forEach((key) => + window.localStorage.removeItem(key), + ) + + return versionedData + }, +} diff --git a/app/scripts/migrations/index.js b/app/scripts/migrations/index.js index 007a5ae06..32424673e 100644 --- a/app/scripts/migrations/index.js +++ b/app/scripts/migrations/index.js @@ -54,6 +54,7 @@ const migrations = [ require('./047').default, require('./048').default, require('./049').default, + require('./050').default, ] export default migrations diff --git a/test/helper.js b/test/helper.js index cbd47c312..38462c6ca 100644 --- a/test/helper.js +++ b/test/helper.js @@ -76,8 +76,9 @@ Object.assign(window, { fetch, Headers, Request, Response }) require('abortcontroller-polyfill/dist/polyfill-patch-fetch') // localStorage -window.localStorage = {} - +window.localStorage = { + removeItem: () => null, +} // override @metamask/logo window.requestAnimationFrame = () => undefined diff --git a/test/unit/migrations/050-test.js b/test/unit/migrations/050-test.js new file mode 100644 index 000000000..fea2f1b06 --- /dev/null +++ b/test/unit/migrations/050-test.js @@ -0,0 +1,89 @@ +import { strict as assert } from 'assert' +import sinon from 'sinon' +import migration50 from '../../../app/scripts/migrations/050' + +const LEGACY_LOCAL_STORAGE_KEYS = [ + 'METASWAP_GAS_PRICE_ESTIMATES_LAST_RETRIEVED', + 'METASWAP_GAS_PRICE_ESTIMATES', + 'cachedFetch', + 'BASIC_PRICE_ESTIMATES_LAST_RETRIEVED', + 'BASIC_PRICE_ESTIMATES', + 'BASIC_GAS_AND_TIME_API_ESTIMATES', + 'BASIC_GAS_AND_TIME_API_ESTIMATES_LAST_RETRIEVED', + 'GAS_API_ESTIMATES_LAST_RETRIEVED', + 'GAS_API_ESTIMATES', +] + +describe('migration #50', function () { + let mockLocalStorageRemoveItem + + beforeEach(function () { + mockLocalStorageRemoveItem = sinon.stub(window.localStorage, 'removeItem') + }) + + afterEach(function () { + sinon.restore() + }) + + it('should update the version metadata', async function () { + const oldStorage = { + meta: { + version: 49, + }, + data: {}, + } + + const newStorage = await migration50.migrate(oldStorage) + assert.deepEqual(newStorage.meta, { + version: 50, + }) + }) + + it('should call window.localStorage.removeItem for each legacy key', async function () { + const oldStorage = { + meta: { + version: 49, + }, + data: {}, + } + + await migration50.migrate(oldStorage) + assert.equal(mockLocalStorageRemoveItem.callCount, 9) + assert.equal( + mockLocalStorageRemoveItem.getCall(0).args[0], + LEGACY_LOCAL_STORAGE_KEYS[0], + ) + assert.equal( + mockLocalStorageRemoveItem.getCall(1).args[0], + LEGACY_LOCAL_STORAGE_KEYS[1], + ) + assert.equal( + mockLocalStorageRemoveItem.getCall(2).args[0], + LEGACY_LOCAL_STORAGE_KEYS[2], + ) + assert.equal( + mockLocalStorageRemoveItem.getCall(3).args[0], + LEGACY_LOCAL_STORAGE_KEYS[3], + ) + assert.equal( + mockLocalStorageRemoveItem.getCall(4).args[0], + LEGACY_LOCAL_STORAGE_KEYS[4], + ) + assert.equal( + mockLocalStorageRemoveItem.getCall(5).args[0], + LEGACY_LOCAL_STORAGE_KEYS[5], + ) + assert.equal( + mockLocalStorageRemoveItem.getCall(6).args[0], + LEGACY_LOCAL_STORAGE_KEYS[6], + ) + assert.equal( + mockLocalStorageRemoveItem.getCall(7).args[0], + LEGACY_LOCAL_STORAGE_KEYS[7], + ) + assert.equal( + mockLocalStorageRemoveItem.getCall(8).args[0], + LEGACY_LOCAL_STORAGE_KEYS[8], + ) + }) +}) From 9fab240c7203c7d127ad7bc862400fb812927ef1 Mon Sep 17 00:00:00 2001 From: MetaMask Bot Date: Wed, 2 Dec 2020 23:48:03 +0000 Subject: [PATCH 30/32] Version v8.1.6 --- CHANGELOG.md | 2 ++ app/manifest/_base.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d4e86a996..ba1ce5b2b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Current Develop Branch +## 8.1.6 Wed Dec 02 2020 + ## 8.1.5 Wed Nov 18 2020 - [#9871](https://github.com/MetaMask/metamask-extension/pull/9871): Show send text upon hover in main asset list - [#9855](https://github.com/MetaMask/metamask-extension/pull/9855): Make edit icon and account name in account details modal focusable diff --git a/app/manifest/_base.json b/app/manifest/_base.json index 53948ce89..e27c3285f 100644 --- a/app/manifest/_base.json +++ b/app/manifest/_base.json @@ -71,6 +71,6 @@ "notifications" ], "short_name": "__MSG_appName__", - "version": "8.1.5", + "version": "8.1.6", "web_accessible_resources": ["inpage.js", "phishing.html"] } From 9bd1de608346bf2047a690921d51ffd59d945ca5 Mon Sep 17 00:00:00 2001 From: Dan J Miller Date: Thu, 3 Dec 2020 09:36:15 -0330 Subject: [PATCH 31/32] Update changelog for v8.1.6 (#9977) --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ba1ce5b2b..7134343d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,13 @@ ## Current Develop Branch ## 8.1.6 Wed Dec 02 2020 +- [#9916](https://github.com/MetaMask/metamask-extension/pull/9916): Fix QR code scans interpretting payment requests as token addresses +- [#9847](https://github.com/MetaMask/metamask-extension/pull/9847): Add alt text for images in list items +- [#9960](https://github.com/MetaMask/metamask-extension/pull/9960): Ensure watchAsset returns errors for invalid token symbols +- [#9968](https://github.com/MetaMask/metamask-extension/pull/9968): Adds tokens from v1.19.0 of metamask/contract-metadata to add token lists +- [#9970](https://github.com/MetaMask/metamask-extension/pull/9970): Etherscan links support Goerli network +- [#9899](https://github.com/MetaMask/metamask-extension/pull/9899): Show price impact warnings on swaps quote screen +- [#9867](https://github.com/MetaMask/metamask-extension/pull/9867): Replace use of ethgasstation ## 8.1.5 Wed Nov 18 2020 - [#9871](https://github.com/MetaMask/metamask-extension/pull/9871): Show send text upon hover in main asset list From fe4430155259ef7a72c8e46a1cd87e19304ca78d Mon Sep 17 00:00:00 2001 From: Dan J Miller Date: Fri, 4 Dec 2020 04:11:11 -0330 Subject: [PATCH 32/32] Update changelog for v8.1.6 (#9998) --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7134343d7..a716a51ee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ - [#9970](https://github.com/MetaMask/metamask-extension/pull/9970): Etherscan links support Goerli network - [#9899](https://github.com/MetaMask/metamask-extension/pull/9899): Show price impact warnings on swaps quote screen - [#9867](https://github.com/MetaMask/metamask-extension/pull/9867): Replace use of ethgasstation +- [#9984](https://github.com/MetaMask/metamask-extension/pull/9984): Show correct gas estimates when users don't have sufficient balance for contract transaction +- [#9993](https://github.com/MetaMask/metamask-extension/pull/9993): Add 48x48 MetaMask icon for use by browsers ## 8.1.5 Wed Nov 18 2020 - [#9871](https://github.com/MetaMask/metamask-extension/pull/9871): Show send text upon hover in main asset list